Overview

Sayay can be used as a plugin/middleware in Strands Agents to enforce per-user budgets before each LLM call.

Strands Plugin

import { Agent } from '@ strands/agent';
import { SayayGuard, MemoryStorage } from '@carloscortezcloud/sayay-guard';

const guard = new SayayGuard({
  storage: new MemoryStorage(),
  budget: { dailyUsd: 5.0 },
});

const agent = new Agent({
  model: 'gpt-4o-mini',
  hooks: {
    beforeModelCall: async (context) => {
      const userId = context.session?.userId || 'anonymous';
      const estimatedCost = estimateCost(context.messages);

      const decision = await guard.check(userId, estimatedCost);

      if (decision.action === 'block') {
        throw new Error('Budget exceeded');
      }

      if (decision.action === 'degrade') {
        // Switch to cheaper model
        context.model = 'gpt-4o-mini';
      }

      return context;
    },
    afterModelCall: async (context) => {
      const userId = context.session?.userId || 'anonymous';
      await guard.record(userId, context.actualCost);
    },
  },
});

With Tinkuy Agent

If you’re using the Tinkuy Agent framework, Sayay integrates natively — no plugin needed:

const agent = new Agent({
  router,
  guard: new SayayGuard({ storage: new MemoryStorage(), budget: { dailyUsd: 5.0 } }),
  tools: [myTool],
  systemPrompt: 'You are a helpful assistant.',
});

The guard is automatically called before each LLM iteration and recorded after.