samai-sdk
Ops & reliability

Usage tracking

createBudgetGuardrail() answers 'has this client exceeded its budget' with one running total. createUsageLedger() answers 'how much has each session/user cost so far' — cumulative tokens and estimated cost, broken down per key and per model.

usage-ledger.ts
import { createClient, anthropic, createUsageLedger } from "samai-sdk";

const ledger = createUsageLedger();
const provider = ledger.wrapProvider(
  anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }),
  (options) => options.metadata?.sessionId as string | undefined
);
const client = createClient({ provider });

await client.generate({
  model: "claude-sonnet-4-6",
  messages: [{ role: "user", content: "hi" }],
  metadata: { sessionId: "session-123" },
});

console.log(ledger.getStats("session-123"));
// { totalTokens, totalCostUsd, callCount, byModel: { "claude-sonnet-4-6": { ... } } }
console.log(ledger.getAllStats()); // every key seen so far
console.log(ledger.toJSON());      // JSON snapshot — feed this to a dashboard or log periodically

Nothing is dropped silently

Calls where keyFn returns undefined are recorded under "_unattributed" rather than silently dropped. Pass { onRecord } to fire on every recorded call, and { pricing } to override the built-in per-model pricing table — provider pricing changes over time, so treat the defaults as illustrative. The ledger tracks numbers; rendering a dashboard from toJSON() is on you.