Skip to content

Budget & Cost Control

Control AI spending with hooks, cost tracking, and model selection constraints.

Budget Enforcement

Use beforeRequest to block expensive requests:

typescript
interface AppContext {
  user: {
    id: string;
    budgetRemaining: number;
    totalSpent: number;
    save: () => Promise<void>;
  };
}

const ai = AI.with<AppContext>()
  .providers({ openai })
  .create()
  .withHooks({
    beforeRequest: async (ctx, request, selected, estimatedUsage, estimatedCost) => {
      if (estimatedCost > ctx.user.budgetRemaining) {
        throw new Error(
          `Estimated cost $${estimatedCost.toFixed(4)} exceeds ` +
          `remaining budget $${ctx.user.budgetRemaining.toFixed(4)}`
        );
      }
      console.log(
        `[${ctx.user.id}] ${selected.model.id}, est: $${estimatedCost.toFixed(4)}`
      );
    },

    afterRequest: async (ctx, request, response, complete, selected, usage, cost) => {
      ctx.user.budgetRemaining -= cost;
      ctx.user.totalSpent += cost;
      await ctx.user.save();
    },
  });

Price Constraints

Limit model selection to cheap models:

typescript
const response = await ai.chat.get(
  { messages },
  {
    metadata: {
      pricing: {
        max: {
          text: { input: 1, output: 2 }, // max $/M tokens
        },
      },
    },
  }
);

Weight-Based Cost Control

Prioritize cost in model selection:

typescript
const response = await ai.chat.get(
  { messages },
  { metadata: { weights: { cost: 0.9, speed: 0.05, accuracy: 0.05 } } }
);

Or use a named profile:

typescript
const ai = AI.with()
  .providers({ openai, openrouter })
  .create({
    weightProfiles: {
      budget: { cost: 0.9, speed: 0.05, accuracy: 0.05 },
    },
  });

await ai.chat.get(
  { messages },
  { metadata: { weightProfile: 'budget' } }
);

Per-User Budgets in Agents

typescript
const budgetAgent = ai.agent({
  name: 'smartAgent',
  refs: [expensivePrompt, cheapPrompt] as const,
  call: async (input, [expensive, cheap], ctx) => {
    if (ctx.user.budgetRemaining > 0.10) {
      return expensive.get('result', input, ctx);
    }
    return cheap.get('result', input, ctx);
  },
});

Monitoring Costs

typescript
const stats = ai.stats();
console.log(`Total requests: ${stats.totalRequests}`);
console.log(`Average cost: $${stats.averageCost.toFixed(4)}`);
console.log(`Average latency: ${stats.averageLatency.toFixed(0)}ms`);

Released under the GPL-3.0 License.