@tollgateai/sdk 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/instrument.ts"],"names":["event"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n Provider,\n RunOutcome,\n TrackEventInput,\n TrackResult,\n UpsertCustomerInput,\n UpsertCustomerResult,\n} from './types';\n\nexport interface TollgateClientOptions {\n /** Account API key (`tg_live_…`). Falls back to `process.env.TOLLGATE_API_KEY`. */\n apiKey?: string;\n /** Base URL of your Tollgate deployment. Defaults to `TOLLGATE_BASE_URL` or production. */\n baseUrl?: string;\n /** Per-request timeout in ms. Default 10_000. */\n timeoutMs?: number;\n /** Retry attempts on network error / 5xx / 429. Default 2. */\n maxRetries?: number;\n /** Custom fetch (for testing or non-standard runtimes). Defaults to global fetch. */\n fetch?: typeof fetch;\n}\n\nexport class TollgateError extends Error {\n constructor(\n message: string,\n readonly status?: number,\n readonly body?: unknown,\n ) {\n super(message);\n this.name = 'TollgateError';\n }\n}\n\nconst DEFAULT_BASE_URL = 'https://tollgateai.vercel.app';\n\n/** Close out a run with its outcome (and, if resolved, the revenue it earns).\n * A resolution carries no provider usage, so `provider`/`model` are optional. */\nexport interface ResolveInput {\n /** The run being closed (must match the runId your usage events used). */\n runId: string;\n customerId: string;\n /** 'resolved' books revenue; 'escalated'/'failed' book none (cost still counts). */\n outcome: RunOutcome;\n /** Revenue in cents for a resolved run (e.g. 50 for $0.50). Ignored if not resolved. */\n revenueUnitCents?: number;\n agentId?: string;\n /** Idempotency key for the closing event. Defaults to `${runId}#resolve`. */\n idempotencyKey?: string;\n ts?: string;\n /** Rarely needed — a resolution isn't a provider call. Default 'anthropic'/'resolution'. */\n provider?: Provider;\n model?: string;\n}\n\nexport interface TollgateClient {\n /** Report a single usage event. Idempotent on `idempotencyKey`. */\n track(event: TrackEventInput): Promise<TrackResult>;\n /** Close a run with its outcome — book revenue once, only if resolved.\n * Convenience over `track()`: sends a zero-usage terminal event. */\n resolve(input: ResolveInput): Promise<TrackResult>;\n /** Create/update a customer and (optionally) its plan, in code. Call this\n * BEFORE sending usage so plan-priced revenue (esp. usage_based, which is\n * computed at ingest) is recognized from the first event. Idempotent. */\n upsertCustomer(input: UpsertCustomerInput): Promise<UpsertCustomerResult>;\n}\n\nfunction getEnv(key: string): string | undefined {\n // Guarded so the SDK works in browsers/edge runtimes without `process`.\n return typeof process !== 'undefined' ? process.env?.[key] : undefined;\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport function createTollgateClient(opts: TollgateClientOptions = {}): TollgateClient {\n const apiKey = opts.apiKey ?? getEnv('TOLLGATE_API_KEY');\n const baseUrl = (opts.baseUrl ?? getEnv('TOLLGATE_BASE_URL') ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n const timeoutMs = opts.timeoutMs ?? 10_000;\n const maxRetries = opts.maxRetries ?? 2;\n const doFetch = opts.fetch ?? globalThis.fetch;\n\n if (typeof doFetch !== 'function') {\n throw new TollgateError('No fetch implementation available — pass `fetch` in options.');\n }\n\n // Shared POST with timeout + retry (transient 5xx/429/network only). 200 and\n // 201 both count as success; deterministic 4xx fail fast.\n async function postJson<T>(path: string, body: unknown): Promise<T> {\n if (!apiKey) {\n throw new TollgateError('Missing API key — set opts.apiKey or TOLLGATE_API_KEY.');\n }\n\n let lastErr: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await doFetch(`${baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n if (res.ok) {\n return (await res.json()) as T;\n }\n\n if (res.status >= 500 || res.status === 429) {\n lastErr = new TollgateError(`Tollgate request failed (${res.status})`, res.status);\n } else {\n const errBody = await res.json().catch(() => ({}));\n throw new TollgateError(`Tollgate request failed (${res.status})`, res.status, errBody);\n }\n } catch (err) {\n if (err instanceof TollgateError && err.status && err.status < 500 && err.status !== 429) {\n throw err;\n }\n lastErr = err;\n } finally {\n clearTimeout(timer);\n }\n\n if (attempt < maxRetries) {\n await sleep(2 ** attempt * 200); // 200ms, 400ms, …\n }\n }\n\n throw lastErr instanceof Error\n ? lastErr\n : new TollgateError('Tollgate request failed after retries');\n }\n\n function track(event: TrackEventInput): Promise<TrackResult> {\n return postJson<TrackResult>('/api/track', event);\n }\n\n function upsertCustomer(input: UpsertCustomerInput): Promise<UpsertCustomerResult> {\n return postJson<UpsertCustomerResult>('/api/sdk/customer', input);\n }\n\n function resolve(input: ResolveInput): Promise<TrackResult> {\n return track({\n customerId: input.customerId,\n runId: input.runId,\n agentId: input.agentId,\n // A resolution isn't a provider call; zero usage ⇒ zero cost.\n provider: input.provider ?? 'anthropic',\n model: input.model ?? 'resolution',\n tokensIn: 0,\n tokensOut: 0,\n outcome: input.outcome,\n revenueUnitCents: input.revenueUnitCents,\n idempotencyKey: input.idempotencyKey ?? `${input.runId}#resolve`,\n ts: input.ts,\n });\n }\n\n return { track, resolve, upsertCustomer };\n}\n","// Auto-instrumentation: wrap a provider client so every completion reports its\n// REAL usage to Tollgate — no manual token counting. Wrappers are structurally\n// typed, so this package never has to depend on the provider SDKs.\n//\n// Coverage is universal: OpenAI + Anthropic native, every OpenAI-compatible\n// gateway (set `provider: 'openai_compatible'`), and AWS Bedrock — each in both\n// non-streaming and streaming modes. Cost is always derived server-side from the\n// token counts these wrappers capture, so no provider needs to return a dollar\n// figure (pass `providerCostCents` only if you already have one).\n\nimport type { TollgateClient } from './client';\nimport type { Provider, TrackEventInput } from './types';\n\nexport interface InstrumentOptions {\n /** Your end customer's stable id. Required for margin attribution. */\n customerId: string;\n /** Optional agent/workflow id. */\n agentId?: string;\n /** Override the reported provider. Defaults per wrapper ('openai' /\n * 'anthropic' / 'bedrock'). Set to 'openai_compatible' when the client points\n * at an OpenAI-shaped gateway (Vercel AI Gateway, OpenRouter, Groq, Together,\n * Nebius, local vLLM, …) so the server prices it by the gateway-echoed model. */\n provider?: Provider;\n /** Revenue per call in cents (or a function of the response). */\n revenueUnitCents?: number | ((response: unknown) => number | undefined);\n /** Provider/gateway-reported cost in cents (or a function of the response).\n * When present and > 0, the server uses it verbatim and skips the rate card —\n * the authoritative escape hatch when you already have an exact cost. */\n providerCostCents?: number | ((response: unknown) => number | undefined);\n /** Override the run id; defaults to the provider response id. */\n runId?: string | (() => string);\n /** Called if a background track() fails. Defaults to console.warn. */\n onError?: (err: unknown) => void;\n}\n\nfunction randomId(): string {\n const c = (globalThis as { crypto?: Crypto }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\nfunction resolveRunId(opts: InstrumentOptions, responseId?: string): string {\n if (typeof opts.runId === 'function') return opts.runId();\n return opts.runId ?? responseId ?? randomId();\n}\n\nfunction resolveRevenue(opts: InstrumentOptions, response: unknown): number | undefined {\n return typeof opts.revenueUnitCents === 'function'\n ? opts.revenueUnitCents(response)\n : opts.revenueUnitCents;\n}\n\nfunction resolveCost(opts: InstrumentOptions, response: unknown): number | undefined {\n return typeof opts.providerCostCents === 'function'\n ? opts.providerCostCents(response)\n : opts.providerCostCents;\n}\n\n/** Attach providerCostCents to an event only when a (non-undefined) value resolves. */\nfunction withCost(\n event: TrackEventInput,\n opts: InstrumentOptions,\n response: unknown,\n): TrackEventInput {\n const cost = resolveCost(opts, response);\n if (cost !== undefined) event.providerCostCents = cost;\n return event;\n}\n\nfunction fireAndForget(p: Promise<unknown>, onError?: InstrumentOptions['onError']): void {\n p.catch((err) => (onError ?? ((e) => console.warn('[tollgate] track failed:', e)))(err));\n}\n\nfunction isAsyncIterable(x: unknown): x is AsyncIterable<unknown> {\n return x != null && typeof (x as Record<symbol, unknown>)[Symbol.asyncIterator] === 'function';\n}\n\n/**\n * Wrap an async iterable (a provider stream) so each chunk is observed and a\n * finalizer runs once the stream is exhausted — without disturbing the stream's\n * other methods (`.tee()`, `.controller`, …), which are proxied through. If the\n * consumer abandons the stream early the finalizer still fires on `.return()`.\n */\nfunction instrumentStream<TChunk>(\n stream: AsyncIterable<TChunk>,\n onChunk: (chunk: TChunk) => void,\n onDone: () => void,\n): AsyncIterable<TChunk> {\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n onDone();\n };\n return new Proxy(stream, {\n get(target, prop, recv) {\n if (prop === Symbol.asyncIterator) {\n return function instrumentedIterator() {\n const inner = (target as AsyncIterable<TChunk>)[Symbol.asyncIterator]();\n return {\n async next(...a: []) {\n const r = await inner.next(...a);\n if (r.done) finish();\n else onChunk(r.value);\n return r;\n },\n async return(v?: unknown) {\n finish();\n return inner.return ? inner.return(v) : { done: true, value: v as TChunk };\n },\n async throw(e?: unknown) {\n finish();\n if (inner.throw) return inner.throw(e);\n throw e;\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n };\n }\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- Anthropic ------------------------------------------------------------\n\ninterface AnthropicUsage {\n input_tokens?: number;\n output_tokens?: number;\n output_tokens_details?: {\n thinking_tokens?: number;\n };\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_creation?: {\n ephemeral_5m_input_tokens?: number;\n ephemeral_1h_input_tokens?: number;\n };\n server_tool_use?: {\n web_search_requests?: number;\n };\n}\ninterface AnthropicContentBlock {\n type?: string;\n}\ninterface AnthropicMessage {\n id?: string;\n model?: string;\n usage?: AnthropicUsage;\n content?: AnthropicContentBlock[];\n}\n// Streaming event shapes we read usage from (message_start carries inputs +\n// cache, message_delta carries the cumulative output token count).\ninterface AnthropicStreamEvent {\n type?: string;\n message?: AnthropicMessage;\n usage?: AnthropicUsage;\n content_block?: AnthropicContentBlock;\n}\n\n/** Map a non-streaming Anthropic message to a track payload (or null if no usage). */\nexport function anthropicEventFrom(\n msg: AnthropicMessage,\n opts: InstrumentOptions,\n): TrackEventInput | null {\n const usage = msg?.usage;\n if (!usage) return null;\n const runId = resolveRunId(opts, msg.id);\n // Split cache-creation tokens by TTL when the response provides the breakdown;\n // otherwise attribute the whole cache_creation total to the default 5-minute TTL.\n const fivem = usage.cache_creation?.ephemeral_5m_input_tokens;\n const oneh = usage.cache_creation?.ephemeral_1h_input_tokens;\n const hasSplit = fivem !== undefined || oneh !== undefined;\n const toolCalls = Array.isArray(msg.content)\n ? msg.content.filter((b) => b.type === 'tool_use').length\n : 0;\n // Anthropic's output_tokens includes thinking tokens; subtract them so each\n // token is costed at exactly one rate (thinking at reasoningRate, text at outRate).\n const thinkingTokens = usage.output_tokens_details?.thinking_tokens ?? 0;\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'anthropic',\n model: msg.model ?? 'unknown',\n tokensIn: usage.input_tokens ?? 0,\n tokensOut: (usage.output_tokens ?? 0) - thinkingTokens,\n reasoningTokens: thinkingTokens,\n cachedTokens: usage.cache_read_input_tokens ?? 0,\n cacheWrite5mTokens: hasSplit ? fivem ?? 0 : usage.cache_creation_input_tokens ?? 0,\n cacheWrite1hTokens: hasSplit ? oneh ?? 0 : 0,\n webSearchRequests: usage.server_tool_use?.web_search_requests ?? 0,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, msg),\n idempotencyKey: msg.id ?? `${runId}#${randomId()}`,\n };\n return withCost(event, opts, msg);\n}\n\ninterface AnthropicLike {\n messages: { create: (...args: never[]) => Promise<unknown> };\n}\n\n/** Wrap an Anthropic client so `messages.create` auto-reports usage (streaming\n * and non-streaming). */\nexport function wrapAnthropic<T extends AnthropicLike>(\n client: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const messages = client.messages;\n const original = messages.create.bind(messages) as (...a: never[]) => Promise<unknown>;\n\n const create = async (...args: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = await original(...args);\n if (isAsyncIterable(result)) {\n const msg: AnthropicMessage = {};\n const toolUseBlocks: AnthropicContentBlock[] = [];\n return instrumentStream(\n result as AsyncIterable<AnthropicStreamEvent>,\n (ev) => {\n if (ev.type === 'message_start' && ev.message) {\n msg.id = ev.message.id;\n msg.model = ev.message.model;\n msg.usage = { ...ev.message.usage };\n } else if (ev.type === 'message_delta' && ev.usage) {\n msg.usage = {\n ...(msg.usage ?? {}),\n output_tokens: ev.usage.output_tokens,\n output_tokens_details: ev.usage.output_tokens_details,\n };\n } else if (ev.type === 'content_block_start' && ev.content_block?.type === 'tool_use') {\n toolUseBlocks.push(ev.content_block);\n }\n },\n () => {\n msg.content = toolUseBlocks;\n const event = anthropicEventFrom(msg, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n }\n const event = anthropicEventFrom(result as AnthropicMessage, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n return result;\n };\n\n return new Proxy(client, {\n get(target, prop, recv) {\n if (prop === 'messages') {\n return new Proxy(messages, {\n get: (m, p, r) => (p === 'create' ? create : Reflect.get(m, p, r)),\n });\n }\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- OpenAI (and OpenAI-compatible gateways) ------------------------------\n\ninterface OpenAIUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: {\n reasoning_tokens?: number;\n audio_tokens?: number;\n accepted_prediction_tokens?: number;\n rejected_prediction_tokens?: number;\n text_tokens?: number;\n };\n prompt_tokens_details?: {\n cached_tokens?: number;\n audio_tokens?: number;\n text_tokens?: number;\n };\n}\ninterface OpenAIToolCall {\n index?: number;\n}\ninterface OpenAIDelta {\n tool_calls?: OpenAIToolCall[];\n}\ninterface OpenAIChoice {\n message?: { tool_calls?: unknown[] };\n delta?: OpenAIDelta;\n}\ninterface OpenAICompletion {\n id?: string;\n model?: string;\n usage?: OpenAIUsage;\n choices?: OpenAIChoice[];\n service_tier?: string;\n}\n\n/** Map a non-streaming OpenAI chat completion to a track payload (or null). */\nexport function openAIEventFrom(\n completion: OpenAICompletion,\n opts: InstrumentOptions,\n): TrackEventInput | null {\n const usage = completion?.usage;\n if (!usage) return null;\n const runId = resolveRunId(opts, completion.id);\n const toolCalls = completion.choices?.[0]?.message?.tool_calls?.length ?? 0;\n const ptd = usage.prompt_tokens_details;\n const ctd = usage.completion_tokens_details;\n // OpenAI's prompt_tokens/completion_tokens are totals that INCLUDE sub-category\n // tokens (cached, audio, reasoning). Subtract them so each token is costed at\n // exactly one rate — otherwise they'd be double-billed at both the base rate and\n // their specific rate.\n const cachedIn = ptd?.cached_tokens ?? 0;\n const audioIn = ptd?.audio_tokens ?? 0;\n const reasoningOut = ctd?.reasoning_tokens ?? 0;\n const audioOut = ctd?.audio_tokens ?? 0;\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'openai',\n model: completion.model ?? 'unknown',\n tokensIn: (usage.prompt_tokens ?? 0) - cachedIn - audioIn,\n tokensOut: (usage.completion_tokens ?? 0) - reasoningOut - audioOut,\n reasoningTokens: reasoningOut,\n cachedTokens: cachedIn,\n audioTokensIn: audioIn,\n audioTokensOut: audioOut,\n textTokensIn: ptd?.text_tokens ?? 0,\n textTokensOut: ctd?.text_tokens ?? 0,\n acceptedPredictionTokens: ctd?.accepted_prediction_tokens ?? 0,\n rejectedPredictionTokens: ctd?.rejected_prediction_tokens ?? 0,\n serviceTier: completion.service_tier,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, completion),\n idempotencyKey: completion.id ?? `${runId}#${randomId()}`,\n };\n return withCost(event, opts, completion);\n}\n\ninterface OpenAILike {\n chat: { completions: { create: (...args: never[]) => Promise<unknown> } };\n}\n\n/** Wrap an OpenAI (or OpenAI-compatible) client so `chat.completions.create`\n * auto-reports usage. Streaming works when the caller sets\n * `stream_options: { include_usage: true }` (required for OpenAI to emit a final\n * usage chunk); without it there are no token counts to report and the call is\n * passed through untouched. */\nexport function wrapOpenAI<T extends OpenAILike>(\n client: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const completions = client.chat.completions;\n const original = completions.create.bind(completions) as (...a: never[]) => Promise<unknown>;\n\n const create = async (...args: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = await original(...args);\n if (isAsyncIterable(result)) {\n let id: string | undefined;\n let model: string | undefined;\n let usage: OpenAIUsage | undefined;\n let serviceTier: string | undefined;\n const toolCallIndices = new Set<number>();\n return instrumentStream(\n result as AsyncIterable<OpenAICompletion>,\n (chunk) => {\n if (chunk.id) id = chunk.id;\n if (chunk.model) model = chunk.model;\n if (chunk.usage) usage = chunk.usage;\n if (chunk.service_tier) serviceTier = chunk.service_tier;\n for (const c of chunk.choices ?? []) {\n for (const tc of c.delta?.tool_calls ?? []) {\n if (tc.index !== undefined) toolCallIndices.add(tc.index);\n }\n }\n },\n () => {\n if (!usage) return;\n const synth: OpenAICompletion = { id, model, usage, service_tier: serviceTier };\n if (toolCallIndices.size > 0) {\n synth.choices = [{ message: { tool_calls: new Array(toolCallIndices.size) } }];\n }\n const event = openAIEventFrom(synth, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n }\n const event = openAIEventFrom(result as OpenAICompletion, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n return result;\n };\n\n return new Proxy(client, {\n get(target, prop, recv) {\n if (prop === 'chat') {\n const chat = Reflect.get(target, prop, recv) as OpenAILike['chat'];\n return new Proxy(chat, {\n get: (c, p, r) =>\n p === 'completions'\n ? new Proxy(completions, {\n get: (co, pp, rr) => (pp === 'create' ? create : Reflect.get(co, pp, rr)),\n })\n : Reflect.get(c, p, r),\n });\n }\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- AWS Bedrock ----------------------------------------------------------\n// Bedrock's Converse API is command-based: the model id lives on the REQUEST,\n// not the response, so we read it from the command input. Usage is reported in\n// camelCase (inputTokens/outputTokens) plus optional cache token counts.\n\ninterface BedrockUsage {\n inputTokens?: number;\n outputTokens?: number;\n cacheReadInputTokens?: number;\n cacheWriteInputTokens?: number;\n}\ninterface BedrockContentBlock {\n toolUse?: unknown;\n}\ninterface BedrockConverseResponse {\n usage?: BedrockUsage;\n output?: { message?: { content?: BedrockContentBlock[] } };\n // ConverseStream returns an async-iterable `stream` of events; the final\n // `metadata` event carries the usage totals.\n stream?: AsyncIterable<{\n metadata?: { usage?: BedrockUsage };\n contentBlockStart?: { start?: { toolUse?: unknown } };\n }>;\n}\n\n/** Map a Bedrock Converse response (model from the request) to a track payload. */\nexport function bedrockEventFrom(\n usage: BedrockUsage | undefined,\n model: string,\n opts: InstrumentOptions,\n response: unknown = undefined,\n toolCalls = 0,\n): TrackEventInput | null {\n if (!usage) return null;\n const runId = resolveRunId(opts, undefined);\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'bedrock',\n model,\n tokensIn: usage.inputTokens ?? 0,\n tokensOut: usage.outputTokens ?? 0,\n cachedTokens: usage.cacheReadInputTokens ?? 0,\n cacheWrite5mTokens: usage.cacheWriteInputTokens ?? 0,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, response),\n idempotencyKey: `${runId}#${randomId()}`,\n };\n return withCost(event, opts, response);\n}\n\ninterface BedrockLike {\n send: (command: unknown, ...rest: never[]) => Promise<unknown>;\n}\n\n/** Wrap a Bedrock Runtime client so `send(ConverseCommand)` /\n * `send(ConverseStreamCommand)` auto-report usage. Non-Converse commands (no\n * usage in the response) pass through untouched. */\nexport function wrapBedrock<T extends BedrockLike>(\n client: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const originalSend = client.send.bind(client) as BedrockLike['send'];\n\n const send = async (command: unknown, ...rest: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = (await originalSend(command, ...rest)) as BedrockConverseResponse;\n const model =\n ((command as { input?: { modelId?: string } })?.input?.modelId) ?? 'unknown';\n\n if (result?.stream && isAsyncIterable(result.stream)) {\n let usage: BedrockUsage | undefined;\n let streamToolCalls = 0;\n result.stream = instrumentStream(\n result.stream,\n (ev) => {\n if (ev.metadata?.usage) usage = ev.metadata.usage;\n if (ev.contentBlockStart?.start?.toolUse) streamToolCalls++;\n },\n () => {\n const event = bedrockEventFrom(usage, model, opts, result, streamToolCalls);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n return result;\n }\n\n if (result?.usage) {\n const tc = result.output?.message?.content?.filter((b) => b.toolUse != null).length ?? 0;\n const event = bedrockEventFrom(result.usage, model, opts, result, tc);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n }\n return result;\n };\n\n return new Proxy(client, {\n get(target, prop, recv) {\n if (prop === 'send') return send;\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- Google Gemini / Vertex AI -----------------------------------------------\n// The Google Generative AI SDK uses `generateContent` on a model instance.\n// Usage metadata comes back as `usageMetadata` with per-modality breakdowns.\n\ninterface GeminiModalityDetail {\n modality?: string;\n tokenCount?: number;\n}\n\ninterface GeminiUsageMetadata {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n cachedContentTokenCount?: number;\n thoughtsTokenCount?: number;\n promptTokensDetails?: GeminiModalityDetail[];\n candidatesTokensDetails?: GeminiModalityDetail[];\n}\n\ninterface GeminiResponse {\n usageMetadata?: GeminiUsageMetadata;\n candidates?: Array<{\n content?: { parts?: Array<{ functionCall?: unknown }> };\n groundingMetadata?: { webSearchQueries?: unknown[] };\n }>;\n}\n\ninterface GeminiStreamChunk {\n usageMetadata?: GeminiUsageMetadata;\n candidates?: GeminiResponse['candidates'];\n}\n\nfunction modalityTokens(details: GeminiModalityDetail[] | undefined, modality: string): number {\n if (!details) return 0;\n return details\n .filter((d) => d.modality === modality)\n .reduce((sum, d) => sum + (d.tokenCount ?? 0), 0);\n}\n\n/** Map a Gemini generateContent response to a track payload (or null). */\nexport function geminiEventFrom(\n response: GeminiResponse,\n opts: InstrumentOptions,\n): TrackEventInput | null {\n const usage = response?.usageMetadata;\n if (!usage) return null;\n const runId = resolveRunId(opts, undefined);\n\n const candidates = response.candidates ?? [];\n const toolCalls = candidates.reduce((sum, c) => {\n const parts = c.content?.parts ?? [];\n return sum + parts.filter((p) => p.functionCall != null).length;\n }, 0);\n const webSearchRequests = candidates.reduce((sum, c) => {\n return sum + (c.groundingMetadata?.webSearchQueries?.length ?? 0);\n }, 0);\n\n const promptDetails = usage.promptTokensDetails;\n const candidateDetails = usage.candidatesTokensDetails;\n\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'google',\n model: 'unknown',\n tokensIn: usage.promptTokenCount ?? 0,\n tokensOut: usage.candidatesTokenCount ?? 0,\n reasoningTokens: usage.thoughtsTokenCount ?? 0,\n cachedTokens: usage.cachedContentTokenCount ?? 0,\n audioTokensIn: modalityTokens(promptDetails, 'AUDIO'),\n audioTokensOut: modalityTokens(candidateDetails, 'AUDIO'),\n imageTokensIn: modalityTokens(promptDetails, 'IMAGE'),\n imageTokensOut: modalityTokens(candidateDetails, 'IMAGE'),\n videoTokensIn: modalityTokens(promptDetails, 'VIDEO'),\n textTokensIn: modalityTokens(promptDetails, 'TEXT'),\n textTokensOut: modalityTokens(candidateDetails, 'TEXT'),\n webSearchRequests,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, response),\n idempotencyKey: `${runId}#${randomId()}`,\n };\n return withCost(event, opts, response);\n}\n\ninterface GeminiModelLike {\n generateContent: (...args: never[]) => Promise<unknown>;\n model?: string;\n}\n\n/** Wrap a Google Generative AI model so `generateContent` auto-reports usage\n * (streaming and non-streaming). */\nexport function wrapGemini<T extends GeminiModelLike>(\n model: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const original = model.generateContent.bind(model) as (...a: never[]) => Promise<unknown>;\n const modelName = model.model ?? 'unknown';\n\n const generateContent = async (...args: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = await original(...args);\n\n if (isAsyncIterable(result)) {\n const accumulated: GeminiUsageMetadata = {};\n let toolCallCount = 0;\n let searchCount = 0;\n\n return instrumentStream(\n result as AsyncIterable<GeminiStreamChunk>,\n (chunk) => {\n if (chunk.usageMetadata) {\n Object.assign(accumulated, chunk.usageMetadata);\n }\n for (const c of chunk.candidates ?? []) {\n for (const p of c.content?.parts ?? []) {\n if (p.functionCall != null) toolCallCount++;\n }\n searchCount += c.groundingMetadata?.webSearchQueries?.length ?? 0;\n }\n },\n () => {\n const synth: GeminiResponse = {\n usageMetadata: accumulated,\n candidates: searchCount > 0 || toolCallCount > 0\n ? [{ content: { parts: new Array(toolCallCount).fill({ functionCall: {} }) }, groundingMetadata: { webSearchQueries: new Array(searchCount) } }]\n : [],\n };\n const event = geminiEventFrom(synth, opts);\n if (event) {\n event.model = modelName;\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n }\n\n const event = geminiEventFrom(result as GeminiResponse, opts);\n if (event) {\n event.model = modelName;\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n return result;\n };\n\n return new Proxy(model, {\n get(target, prop, recv) {\n if (prop === 'generateContent') return generateContent;\n return Reflect.get(target, prop, recv);\n },\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/instrument.ts"],"names":["event"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n Provider,\n RunOutcome,\n TrackEventInput,\n TrackResult,\n UpsertCustomerInput,\n UpsertCustomerResult,\n} from './types';\n\nexport interface TollgateClientOptions {\n /** Account API key (`tg_live_…`). Falls back to `process.env.TOLLGATE_API_KEY`. */\n apiKey?: string;\n /** Base URL of your Tollgate deployment. Defaults to `TOLLGATE_BASE_URL` or production. */\n baseUrl?: string;\n /** Per-request timeout in ms. Default 10_000. */\n timeoutMs?: number;\n /** Retry attempts on network error / 5xx / 429. Default 2. */\n maxRetries?: number;\n /** Custom fetch (for testing or non-standard runtimes). Defaults to global fetch. */\n fetch?: typeof fetch;\n}\n\nexport class TollgateError extends Error {\n constructor(\n message: string,\n readonly status?: number,\n readonly body?: unknown,\n ) {\n super(message);\n this.name = 'TollgateError';\n }\n}\n\nconst DEFAULT_BASE_URL = 'https://tollgateai.vercel.app';\n\n/** Close out a run with its outcome (and, if resolved, the revenue it earns).\n * A resolution carries no provider usage, so `provider`/`model` are optional. */\nexport interface ResolveInput {\n /** The run being closed (must match the runId your usage events used). */\n runId: string;\n customerId: string;\n /** 'resolved' books revenue; 'escalated'/'failed' book none (cost still counts). */\n outcome: RunOutcome;\n /** Revenue in cents for a resolved run (e.g. 50 for $0.50). Ignored if not resolved. */\n revenueUnitCents?: number;\n agentId?: string;\n /** Idempotency key for the closing event. Defaults to `${runId}#resolve`. */\n idempotencyKey?: string;\n ts?: string;\n /** Rarely needed — a resolution isn't a provider call. Default 'anthropic'/'resolution'. */\n provider?: Provider;\n model?: string;\n}\n\nexport interface TollgateClient {\n /** Report a single usage event. Idempotent on `idempotencyKey`. */\n track(event: TrackEventInput): Promise<TrackResult>;\n /** Close a run with its outcome — book revenue once, only if resolved.\n * Convenience over `track()`: sends a zero-usage terminal event. */\n resolve(input: ResolveInput): Promise<TrackResult>;\n /** Create/update a customer and (optionally) its plan, in code. Call this\n * BEFORE sending usage so plan-priced revenue (esp. usage_based, which is\n * computed at ingest) is recognized from the first event. Idempotent. */\n upsertCustomer(input: UpsertCustomerInput): Promise<UpsertCustomerResult>;\n}\n\nfunction getEnv(key: string): string | undefined {\n // Guarded so the SDK works in browsers/edge runtimes without `process`.\n return typeof process !== 'undefined' ? process.env?.[key] : undefined;\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport function createTollgateClient(opts: TollgateClientOptions = {}): TollgateClient {\n const apiKey = opts.apiKey ?? getEnv('TOLLGATE_API_KEY');\n const baseUrl = (opts.baseUrl ?? getEnv('TOLLGATE_BASE_URL') ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n const timeoutMs = opts.timeoutMs ?? 10_000;\n const maxRetries = opts.maxRetries ?? 2;\n const doFetch = opts.fetch ?? globalThis.fetch;\n\n if (typeof doFetch !== 'function') {\n throw new TollgateError('No fetch implementation available — pass `fetch` in options.');\n }\n\n // Shared POST with timeout + retry (transient 5xx/429/network only). 200 and\n // 201 both count as success; deterministic 4xx fail fast.\n async function postJson<T>(path: string, body: unknown): Promise<T> {\n if (!apiKey) {\n throw new TollgateError('Missing API key — set opts.apiKey or TOLLGATE_API_KEY.');\n }\n\n let lastErr: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await doFetch(`${baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n if (res.ok) {\n return (await res.json()) as T;\n }\n\n if (res.status >= 500 || res.status === 429) {\n lastErr = new TollgateError(`Tollgate request failed (${res.status})`, res.status);\n } else {\n const errBody = await res.json().catch(() => ({}));\n throw new TollgateError(`Tollgate request failed (${res.status})`, res.status, errBody);\n }\n } catch (err) {\n if (err instanceof TollgateError && err.status && err.status < 500 && err.status !== 429) {\n throw err;\n }\n lastErr = err;\n } finally {\n clearTimeout(timer);\n }\n\n if (attempt < maxRetries) {\n await sleep(2 ** attempt * 200); // 200ms, 400ms, …\n }\n }\n\n throw lastErr instanceof Error\n ? lastErr\n : new TollgateError('Tollgate request failed after retries');\n }\n\n function track(event: TrackEventInput): Promise<TrackResult> {\n return postJson<TrackResult>('/api/track', event);\n }\n\n function upsertCustomer(input: UpsertCustomerInput): Promise<UpsertCustomerResult> {\n return postJson<UpsertCustomerResult>('/api/sdk/customer', input);\n }\n\n function resolve(input: ResolveInput): Promise<TrackResult> {\n return track({\n customerId: input.customerId,\n runId: input.runId,\n agentId: input.agentId,\n // A resolution isn't a provider call; zero usage ⇒ zero cost.\n provider: input.provider ?? 'anthropic',\n model: input.model ?? 'resolution',\n tokensIn: 0,\n tokensOut: 0,\n outcome: input.outcome,\n revenueUnitCents: input.revenueUnitCents,\n idempotencyKey: input.idempotencyKey ?? `${input.runId}#resolve`,\n ts: input.ts,\n });\n }\n\n return { track, resolve, upsertCustomer };\n}\n","// Auto-instrumentation: wrap a provider client so every completion reports its\n// REAL usage to Tollgate — no manual token counting. Wrappers are structurally\n// typed, so this package never has to depend on the provider SDKs.\n//\n// Coverage is universal: OpenAI + Anthropic native, every OpenAI-compatible\n// gateway (set `provider: 'openai_compatible'`), and AWS Bedrock — each in both\n// non-streaming and streaming modes. Cost is always derived server-side from the\n// token counts these wrappers capture, so no provider needs to return a dollar\n// figure (pass `providerCostCents` only if you already have one).\n\nimport type { TollgateClient } from './client';\nimport type { Provider, TrackEventInput } from './types';\n\nexport interface InstrumentOptions {\n /** Your end customer's stable id. Required for margin attribution. */\n customerId: string;\n /** Optional agent/workflow id. */\n agentId?: string;\n /** Override the reported provider. Defaults per wrapper ('openai' /\n * 'anthropic' / 'bedrock'). Set to 'openai_compatible' when the client points\n * at an OpenAI-shaped gateway (Vercel AI Gateway, OpenRouter, Groq, Together,\n * Nebius, local vLLM, …) so the server prices it by the gateway-echoed model. */\n provider?: Provider;\n /** Revenue per call in cents (or a function of the response). */\n revenueUnitCents?: number | ((response: unknown) => number | undefined);\n /** Provider/gateway-reported cost in cents (or a function of the response).\n * When present and > 0, the server uses it verbatim and skips the rate card —\n * the authoritative escape hatch when you already have an exact cost. */\n providerCostCents?: number | ((response: unknown) => number | undefined);\n /** Override the run id; defaults to the provider response id. */\n runId?: string | (() => string);\n /** Called if a background track() fails. Defaults to console.warn. */\n onError?: (err: unknown) => void;\n}\n\nfunction randomId(): string {\n const c = (globalThis as { crypto?: Crypto }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\nfunction resolveRunId(opts: InstrumentOptions, responseId?: string): string {\n if (typeof opts.runId === 'function') return opts.runId();\n return opts.runId ?? responseId ?? randomId();\n}\n\nfunction resolveRevenue(opts: InstrumentOptions, response: unknown): number | undefined {\n return typeof opts.revenueUnitCents === 'function'\n ? opts.revenueUnitCents(response)\n : opts.revenueUnitCents;\n}\n\nfunction resolveCost(opts: InstrumentOptions, response: unknown): number | undefined {\n return typeof opts.providerCostCents === 'function'\n ? opts.providerCostCents(response)\n : opts.providerCostCents;\n}\n\n/** Attach providerCostCents to an event only when a (non-undefined) value resolves. */\nfunction withCost(\n event: TrackEventInput,\n opts: InstrumentOptions,\n response: unknown,\n): TrackEventInput {\n const cost = resolveCost(opts, response);\n if (cost !== undefined) event.providerCostCents = cost;\n return event;\n}\n\nfunction fireAndForget(p: Promise<unknown>, onError?: InstrumentOptions['onError']): void {\n p.catch((err) => (onError ?? ((e) => console.warn('[tollgate] track failed:', e)))(err));\n}\n\nfunction isAsyncIterable(x: unknown): x is AsyncIterable<unknown> {\n return x != null && typeof (x as Record<symbol, unknown>)[Symbol.asyncIterator] === 'function';\n}\n\n/**\n * Wrap an async iterable (a provider stream) so each chunk is observed and a\n * finalizer runs once the stream is exhausted — without disturbing the stream's\n * other methods (`.tee()`, `.controller`, …), which are proxied through. If the\n * consumer abandons the stream early the finalizer still fires on `.return()`.\n */\nfunction instrumentStream<TChunk>(\n stream: AsyncIterable<TChunk>,\n onChunk: (chunk: TChunk) => void,\n onDone: () => void,\n): AsyncIterable<TChunk> {\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n onDone();\n };\n return new Proxy(stream, {\n get(target, prop, recv) {\n if (prop === Symbol.asyncIterator) {\n return function instrumentedIterator() {\n const inner = (target as AsyncIterable<TChunk>)[Symbol.asyncIterator]();\n return {\n async next(...a: []) {\n const r = await inner.next(...a);\n if (r.done) finish();\n else onChunk(r.value);\n return r;\n },\n async return(v?: unknown) {\n finish();\n return inner.return ? inner.return(v) : { done: true, value: v as TChunk };\n },\n async throw(e?: unknown) {\n finish();\n if (inner.throw) return inner.throw(e);\n throw e;\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n };\n }\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- Anthropic ------------------------------------------------------------\n\n// Only fields the Anthropic Messages API actually returns today.\n// Anthropic does NOT return a reasoning/thinking token breakdown in usage —\n// thinking tokens are included in output_tokens. Anthropic also does NOT\n// split cache_creation_input_tokens by TTL (5-min vs 1-hour).\n// Since Anthropic bills reasoning at the output rate, cost is correct\n// without the split — tokensOut already carries the full amount.\ninterface AnthropicUsage {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n server_tool_use?: {\n web_search_requests?: number;\n };\n}\ninterface AnthropicContentBlock {\n type?: string;\n}\ninterface AnthropicMessage {\n id?: string;\n model?: string;\n usage?: AnthropicUsage;\n content?: AnthropicContentBlock[];\n}\n// Streaming event shapes we read usage from (message_start carries inputs +\n// cache, message_delta carries the cumulative output token count).\ninterface AnthropicStreamEvent {\n type?: string;\n message?: AnthropicMessage;\n usage?: AnthropicUsage;\n content_block?: AnthropicContentBlock;\n}\n\n/** Map a non-streaming Anthropic message to a track payload (or null if no usage). */\nexport function anthropicEventFrom(\n msg: AnthropicMessage,\n opts: InstrumentOptions,\n): TrackEventInput | null {\n const usage = msg?.usage;\n if (!usage) return null;\n const runId = resolveRunId(opts, msg.id);\n const toolCalls = Array.isArray(msg.content)\n ? msg.content.filter((b) => b.type === 'tool_use').length\n : 0;\n // Anthropic's output_tokens includes thinking/reasoning tokens and the API\n // does not break them out. Since Anthropic bills reasoning at the output\n // rate, costing everything as tokensOut is correct — no need to split.\n // Cache creation tokens all go to the 5-min bucket because the API does not\n // indicate which TTL was used.\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'anthropic',\n model: msg.model ?? 'unknown',\n tokensIn: usage.input_tokens ?? 0,\n tokensOut: usage.output_tokens ?? 0,\n cachedTokens: usage.cache_read_input_tokens ?? 0,\n cacheWrite5mTokens: usage.cache_creation_input_tokens ?? 0,\n webSearchRequests: usage.server_tool_use?.web_search_requests ?? 0,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, msg),\n idempotencyKey: msg.id ?? `${runId}#${randomId()}`,\n };\n return withCost(event, opts, msg);\n}\n\ninterface AnthropicLike {\n messages: { create: (...args: never[]) => Promise<unknown> };\n}\n\n/** Wrap an Anthropic client so `messages.create` auto-reports usage (streaming\n * and non-streaming). */\nexport function wrapAnthropic<T extends AnthropicLike>(\n client: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const messages = client.messages;\n const original = messages.create.bind(messages) as (...a: never[]) => Promise<unknown>;\n\n const create = async (...args: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = await original(...args);\n if (isAsyncIterable(result)) {\n const msg: AnthropicMessage = {};\n const toolUseBlocks: AnthropicContentBlock[] = [];\n return instrumentStream(\n result as AsyncIterable<AnthropicStreamEvent>,\n (ev) => {\n if (ev.type === 'message_start' && ev.message) {\n msg.id = ev.message.id;\n msg.model = ev.message.model;\n msg.usage = { ...ev.message.usage };\n } else if (ev.type === 'message_delta' && ev.usage) {\n msg.usage = {\n ...(msg.usage ?? {}),\n output_tokens: ev.usage.output_tokens,\n };\n } else if (ev.type === 'content_block_start' && ev.content_block?.type === 'tool_use') {\n toolUseBlocks.push(ev.content_block);\n }\n },\n () => {\n msg.content = toolUseBlocks;\n const event = anthropicEventFrom(msg, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n }\n const event = anthropicEventFrom(result as AnthropicMessage, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n return result;\n };\n\n return new Proxy(client, {\n get(target, prop, recv) {\n if (prop === 'messages') {\n return new Proxy(messages, {\n get: (m, p, r) => (p === 'create' ? create : Reflect.get(m, p, r)),\n });\n }\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- OpenAI (and OpenAI-compatible gateways) ------------------------------\n\ninterface OpenAIUsage {\n prompt_tokens?: number;\n completion_tokens?: number;\n completion_tokens_details?: {\n reasoning_tokens?: number;\n audio_tokens?: number;\n accepted_prediction_tokens?: number;\n rejected_prediction_tokens?: number;\n text_tokens?: number;\n };\n prompt_tokens_details?: {\n cached_tokens?: number;\n audio_tokens?: number;\n text_tokens?: number;\n };\n /** Gateway-reported cost in USD (OpenRouter returns this inline). */\n cost?: number;\n}\ninterface OpenAIToolCall {\n index?: number;\n}\ninterface OpenAIDelta {\n tool_calls?: OpenAIToolCall[];\n}\ninterface OpenAIChoice {\n message?: { tool_calls?: unknown[] };\n delta?: OpenAIDelta;\n}\ninterface OpenAICompletion {\n id?: string;\n model?: string;\n usage?: OpenAIUsage;\n choices?: OpenAIChoice[];\n service_tier?: string;\n}\n\n/** Map a non-streaming OpenAI chat completion to a track payload (or null). */\nexport function openAIEventFrom(\n completion: OpenAICompletion,\n opts: InstrumentOptions,\n): TrackEventInput | null {\n const usage = completion?.usage;\n if (!usage) return null;\n const runId = resolveRunId(opts, completion.id);\n const toolCalls = completion.choices?.[0]?.message?.tool_calls?.length ?? 0;\n const ptd = usage.prompt_tokens_details;\n const ctd = usage.completion_tokens_details;\n // OpenAI's prompt_tokens/completion_tokens are totals that INCLUDE sub-category\n // tokens (cached, audio, reasoning). Subtract them so each token is costed at\n // exactly one rate — otherwise they'd be double-billed at both the base rate and\n // their specific rate.\n const cachedIn = ptd?.cached_tokens ?? 0;\n const audioIn = ptd?.audio_tokens ?? 0;\n const reasoningOut = ctd?.reasoning_tokens ?? 0;\n const audioOut = ctd?.audio_tokens ?? 0;\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'openai',\n model: completion.model ?? 'unknown',\n tokensIn: (usage.prompt_tokens ?? 0) - cachedIn - audioIn,\n tokensOut: (usage.completion_tokens ?? 0) - reasoningOut - audioOut,\n reasoningTokens: reasoningOut,\n cachedTokens: cachedIn,\n audioTokensIn: audioIn,\n audioTokensOut: audioOut,\n textTokensIn: ptd?.text_tokens ?? 0,\n textTokensOut: ctd?.text_tokens ?? 0,\n acceptedPredictionTokens: ctd?.accepted_prediction_tokens ?? 0,\n rejectedPredictionTokens: ctd?.rejected_prediction_tokens ?? 0,\n serviceTier: completion.service_tier,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, completion),\n idempotencyKey: completion.id ?? `${runId}#${randomId()}`,\n };\n // If the gateway returns cost inline (e.g. OpenRouter's usage.cost in USD)\n // and the caller hasn't explicitly set providerCostCents, use it. Gateways\n // that don't return this field (Groq, Nebius, direct OpenAI) are unaffected.\n const gatewayCostUsd = usage.cost;\n if (gatewayCostUsd != null && gatewayCostUsd > 0 && resolveCost(opts, completion) === undefined) {\n event.providerCostCents = gatewayCostUsd * 100;\n }\n return withCost(event, opts, completion);\n}\n\ninterface OpenAILike {\n chat: { completions: { create: (...args: never[]) => Promise<unknown> } };\n}\n\n/** Wrap an OpenAI (or OpenAI-compatible) client so `chat.completions.create`\n * auto-reports usage. Streaming works when the caller sets\n * `stream_options: { include_usage: true }` (required for OpenAI to emit a final\n * usage chunk); without it there are no token counts to report and the call is\n * passed through untouched. */\nexport function wrapOpenAI<T extends OpenAILike>(\n client: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const completions = client.chat.completions;\n const original = completions.create.bind(completions) as (...a: never[]) => Promise<unknown>;\n\n const create = async (...args: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = await original(...args);\n if (isAsyncIterable(result)) {\n let id: string | undefined;\n let model: string | undefined;\n let usage: OpenAIUsage | undefined;\n let serviceTier: string | undefined;\n const toolCallIndices = new Set<number>();\n return instrumentStream(\n result as AsyncIterable<OpenAICompletion>,\n (chunk) => {\n if (chunk.id) id = chunk.id;\n if (chunk.model) model = chunk.model;\n if (chunk.usage) usage = chunk.usage;\n if (chunk.service_tier) serviceTier = chunk.service_tier;\n for (const c of chunk.choices ?? []) {\n for (const tc of c.delta?.tool_calls ?? []) {\n if (tc.index !== undefined) toolCallIndices.add(tc.index);\n }\n }\n },\n () => {\n if (!usage) return;\n const synth: OpenAICompletion = { id, model, usage, service_tier: serviceTier };\n if (toolCallIndices.size > 0) {\n synth.choices = [{ message: { tool_calls: new Array(toolCallIndices.size) } }];\n }\n const event = openAIEventFrom(synth, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n }\n const event = openAIEventFrom(result as OpenAICompletion, opts);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n return result;\n };\n\n return new Proxy(client, {\n get(target, prop, recv) {\n if (prop === 'chat') {\n const chat = Reflect.get(target, prop, recv) as OpenAILike['chat'];\n return new Proxy(chat, {\n get: (c, p, r) =>\n p === 'completions'\n ? new Proxy(completions, {\n get: (co, pp, rr) => (pp === 'create' ? create : Reflect.get(co, pp, rr)),\n })\n : Reflect.get(c, p, r),\n });\n }\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- AWS Bedrock ----------------------------------------------------------\n// Bedrock's Converse API is command-based: the model id lives on the REQUEST,\n// not the response, so we read it from the command input. Usage is reported in\n// camelCase (inputTokens/outputTokens) plus optional cache token counts.\n\ninterface BedrockCacheDetail {\n ttl?: string;\n inputTokens?: number;\n}\ninterface BedrockUsage {\n inputTokens?: number;\n outputTokens?: number;\n cacheReadInputTokens?: number;\n cacheWriteInputTokens?: number;\n cacheDetails?: BedrockCacheDetail[];\n}\ninterface BedrockContentBlock {\n toolUse?: unknown;\n}\ninterface BedrockConverseResponse {\n usage?: BedrockUsage;\n output?: { message?: { content?: BedrockContentBlock[] } };\n // ConverseStream returns an async-iterable `stream` of events; the final\n // `metadata` event carries the usage totals.\n stream?: AsyncIterable<{\n metadata?: { usage?: BedrockUsage };\n contentBlockStart?: { start?: { toolUse?: unknown } };\n }>;\n}\n\n/** Map a Bedrock Converse response (model from the request) to a track payload. */\nexport function bedrockEventFrom(\n usage: BedrockUsage | undefined,\n model: string,\n opts: InstrumentOptions,\n response: unknown = undefined,\n toolCalls = 0,\n): TrackEventInput | null {\n if (!usage) return null;\n const runId = resolveRunId(opts, undefined);\n // Bedrock returns per-TTL cache write breakdown in cacheDetails (sorted 1h\n // before 5m). Use it when present; fall back to lumping cacheWriteInputTokens\n // into the 5m bucket for backward compatibility.\n let cacheWrite5m = 0;\n let cacheWrite1h = 0;\n if (usage.cacheDetails?.length) {\n for (const d of usage.cacheDetails) {\n if (d.ttl === '1h') cacheWrite1h += d.inputTokens ?? 0;\n else cacheWrite5m += d.inputTokens ?? 0;\n }\n } else {\n cacheWrite5m = usage.cacheWriteInputTokens ?? 0;\n }\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'bedrock',\n model,\n tokensIn: usage.inputTokens ?? 0,\n tokensOut: usage.outputTokens ?? 0,\n cachedTokens: usage.cacheReadInputTokens ?? 0,\n cacheWrite5mTokens: cacheWrite5m,\n cacheWrite1hTokens: cacheWrite1h,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, response),\n idempotencyKey: `${runId}#${randomId()}`,\n };\n return withCost(event, opts, response);\n}\n\ninterface BedrockLike {\n send: (command: unknown, ...rest: never[]) => Promise<unknown>;\n}\n\n/** Wrap a Bedrock Runtime client so `send(ConverseCommand)` /\n * `send(ConverseStreamCommand)` auto-report usage. Non-Converse commands (no\n * usage in the response) pass through untouched. */\nexport function wrapBedrock<T extends BedrockLike>(\n client: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const originalSend = client.send.bind(client) as BedrockLike['send'];\n\n const send = async (command: unknown, ...rest: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = (await originalSend(command, ...rest)) as BedrockConverseResponse;\n const model =\n ((command as { input?: { modelId?: string } })?.input?.modelId) ?? 'unknown';\n\n if (result?.stream && isAsyncIterable(result.stream)) {\n let usage: BedrockUsage | undefined;\n let streamToolCalls = 0;\n result.stream = instrumentStream(\n result.stream,\n (ev) => {\n if (ev.metadata?.usage) usage = ev.metadata.usage;\n if (ev.contentBlockStart?.start?.toolUse) streamToolCalls++;\n },\n () => {\n const event = bedrockEventFrom(usage, model, opts, result, streamToolCalls);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n return result;\n }\n\n if (result?.usage) {\n const tc = result.output?.message?.content?.filter((b) => b.toolUse != null).length ?? 0;\n const event = bedrockEventFrom(result.usage, model, opts, result, tc);\n if (event) {\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n }\n return result;\n };\n\n return new Proxy(client, {\n get(target, prop, recv) {\n if (prop === 'send') return send;\n return Reflect.get(target, prop, recv);\n },\n });\n}\n\n// --- Google Gemini / Vertex AI -----------------------------------------------\n// The Google Generative AI SDK uses `generateContent` on a model instance.\n// Usage metadata comes back as `usageMetadata` with per-modality breakdowns.\n\ninterface GeminiModalityDetail {\n modality?: string;\n tokenCount?: number;\n}\n\ninterface GeminiUsageMetadata {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n totalTokenCount?: number;\n cachedContentTokenCount?: number;\n thoughtsTokenCount?: number;\n promptTokensDetails?: GeminiModalityDetail[];\n candidatesTokensDetails?: GeminiModalityDetail[];\n}\n\ninterface GeminiResponse {\n usageMetadata?: GeminiUsageMetadata;\n candidates?: Array<{\n content?: { parts?: Array<{ functionCall?: unknown }> };\n groundingMetadata?: { webSearchQueries?: unknown[] };\n }>;\n}\n\ninterface GeminiStreamChunk {\n usageMetadata?: GeminiUsageMetadata;\n candidates?: GeminiResponse['candidates'];\n}\n\nfunction modalityTokens(details: GeminiModalityDetail[] | undefined, modality: string): number {\n if (!details) return 0;\n return details\n .filter((d) => d.modality === modality)\n .reduce((sum, d) => sum + (d.tokenCount ?? 0), 0);\n}\n\n/** Map a Gemini generateContent response to a track payload (or null). */\nexport function geminiEventFrom(\n response: GeminiResponse,\n opts: InstrumentOptions,\n): TrackEventInput | null {\n const usage = response?.usageMetadata;\n if (!usage) return null;\n const runId = resolveRunId(opts, undefined);\n\n const candidates = response.candidates ?? [];\n const toolCalls = candidates.reduce((sum, c) => {\n const parts = c.content?.parts ?? [];\n return sum + parts.filter((p) => p.functionCall != null).length;\n }, 0);\n const webSearchRequests = candidates.reduce((sum, c) => {\n return sum + (c.groundingMetadata?.webSearchQueries?.length ?? 0);\n }, 0);\n\n const promptDetails = usage.promptTokensDetails;\n const candidateDetails = usage.candidatesTokensDetails;\n\n // Google's promptTokenCount / candidatesTokenCount are TOTALS that include\n // sub-category tokens (cached, audio, image, video). Subtract them so each\n // token is costed at exactly one rate — matching the OpenAI approach.\n // NOTE: thoughtsTokenCount is NOT included in candidatesTokenCount (confirmed\n // via live API testing), so it is not subtracted from tokensOut.\n const cachedIn = usage.cachedContentTokenCount ?? 0;\n const audioIn = modalityTokens(promptDetails, 'AUDIO');\n const imageIn = modalityTokens(promptDetails, 'IMAGE');\n const videoIn = modalityTokens(promptDetails, 'VIDEO');\n const audioOut = modalityTokens(candidateDetails, 'AUDIO');\n const imageOut = modalityTokens(candidateDetails, 'IMAGE');\n const event: TrackEventInput = {\n customerId: opts.customerId,\n agentId: opts.agentId,\n runId,\n provider: opts.provider ?? 'google',\n model: 'unknown',\n tokensIn: (usage.promptTokenCount ?? 0) - cachedIn - audioIn - imageIn - videoIn,\n tokensOut: (usage.candidatesTokenCount ?? 0) - audioOut - imageOut,\n reasoningTokens: usage.thoughtsTokenCount ?? 0,\n cachedTokens: cachedIn,\n audioTokensIn: audioIn,\n audioTokensOut: audioOut,\n imageTokensIn: imageIn,\n imageTokensOut: imageOut,\n videoTokensIn: videoIn,\n textTokensIn: modalityTokens(promptDetails, 'TEXT'),\n textTokensOut: modalityTokens(candidateDetails, 'TEXT'),\n webSearchRequests,\n toolCalls,\n revenueUnitCents: resolveRevenue(opts, response),\n idempotencyKey: `${runId}#${randomId()}`,\n };\n return withCost(event, opts, response);\n}\n\ninterface GeminiModelLike {\n generateContent: (...args: never[]) => Promise<unknown>;\n model?: string;\n}\n\n/** Wrap a Google Generative AI model so `generateContent` auto-reports usage\n * (streaming and non-streaming). */\nexport function wrapGemini<T extends GeminiModelLike>(\n model: T,\n tollgate: TollgateClient,\n opts: InstrumentOptions,\n): T {\n const original = model.generateContent.bind(model) as (...a: never[]) => Promise<unknown>;\n const modelName = model.model ?? 'unknown';\n\n const generateContent = async (...args: never[]): Promise<unknown> => {\n const t0 = Date.now();\n const result = await original(...args);\n\n if (isAsyncIterable(result)) {\n const accumulated: GeminiUsageMetadata = {};\n let toolCallCount = 0;\n let searchCount = 0;\n\n return instrumentStream(\n result as AsyncIterable<GeminiStreamChunk>,\n (chunk) => {\n if (chunk.usageMetadata) {\n Object.assign(accumulated, chunk.usageMetadata);\n }\n for (const c of chunk.candidates ?? []) {\n for (const p of c.content?.parts ?? []) {\n if (p.functionCall != null) toolCallCount++;\n }\n searchCount += c.groundingMetadata?.webSearchQueries?.length ?? 0;\n }\n },\n () => {\n const synth: GeminiResponse = {\n usageMetadata: accumulated,\n candidates: searchCount > 0 || toolCallCount > 0\n ? [{ content: { parts: new Array(toolCallCount).fill({ functionCall: {} }) }, groundingMetadata: { webSearchQueries: new Array(searchCount) } }]\n : [],\n };\n const event = geminiEventFrom(synth, opts);\n if (event) {\n event.model = modelName;\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n },\n );\n }\n\n const event = geminiEventFrom(result as GeminiResponse, opts);\n if (event) {\n event.model = modelName;\n event.latencyMs = Date.now() - t0;\n fireAndForget(tollgate.track(event), opts.onError);\n }\n return result;\n };\n\n return new Proxy(model, {\n get(target, prop, recv) {\n if (prop === 'generateContent') return generateContent;\n return Reflect.get(target, prop, recv);\n },\n });\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -179,15 +179,8 @@ interface InstrumentOptions {
179
179
  interface AnthropicUsage {
180
180
  input_tokens?: number;
181
181
  output_tokens?: number;
182
- output_tokens_details?: {
183
- thinking_tokens?: number;
184
- };
185
182
  cache_read_input_tokens?: number;
186
183
  cache_creation_input_tokens?: number;
187
- cache_creation?: {
188
- ephemeral_5m_input_tokens?: number;
189
- ephemeral_1h_input_tokens?: number;
190
- };
191
184
  server_tool_use?: {
192
185
  web_search_requests?: number;
193
186
  };
@@ -226,6 +219,8 @@ interface OpenAIUsage {
226
219
  audio_tokens?: number;
227
220
  text_tokens?: number;
228
221
  };
222
+ /** Gateway-reported cost in USD (OpenRouter returns this inline). */
223
+ cost?: number;
229
224
  }
230
225
  interface OpenAIToolCall {
231
226
  index?: number;
@@ -261,11 +256,16 @@ interface OpenAILike {
261
256
  * usage chunk); without it there are no token counts to report and the call is
262
257
  * passed through untouched. */
263
258
  declare function wrapOpenAI<T extends OpenAILike>(client: T, tollgate: TollgateClient, opts: InstrumentOptions): T;
259
+ interface BedrockCacheDetail {
260
+ ttl?: string;
261
+ inputTokens?: number;
262
+ }
264
263
  interface BedrockUsage {
265
264
  inputTokens?: number;
266
265
  outputTokens?: number;
267
266
  cacheReadInputTokens?: number;
268
267
  cacheWriteInputTokens?: number;
268
+ cacheDetails?: BedrockCacheDetail[];
269
269
  }
270
270
  /** Map a Bedrock Converse response (model from the request) to a track payload. */
271
271
  declare function bedrockEventFrom(usage: BedrockUsage | undefined, model: string, opts: InstrumentOptions, response?: unknown, toolCalls?: number): TrackEventInput | null;
package/dist/index.d.ts CHANGED
@@ -179,15 +179,8 @@ interface InstrumentOptions {
179
179
  interface AnthropicUsage {
180
180
  input_tokens?: number;
181
181
  output_tokens?: number;
182
- output_tokens_details?: {
183
- thinking_tokens?: number;
184
- };
185
182
  cache_read_input_tokens?: number;
186
183
  cache_creation_input_tokens?: number;
187
- cache_creation?: {
188
- ephemeral_5m_input_tokens?: number;
189
- ephemeral_1h_input_tokens?: number;
190
- };
191
184
  server_tool_use?: {
192
185
  web_search_requests?: number;
193
186
  };
@@ -226,6 +219,8 @@ interface OpenAIUsage {
226
219
  audio_tokens?: number;
227
220
  text_tokens?: number;
228
221
  };
222
+ /** Gateway-reported cost in USD (OpenRouter returns this inline). */
223
+ cost?: number;
229
224
  }
230
225
  interface OpenAIToolCall {
231
226
  index?: number;
@@ -261,11 +256,16 @@ interface OpenAILike {
261
256
  * usage chunk); without it there are no token counts to report and the call is
262
257
  * passed through untouched. */
263
258
  declare function wrapOpenAI<T extends OpenAILike>(client: T, tollgate: TollgateClient, opts: InstrumentOptions): T;
259
+ interface BedrockCacheDetail {
260
+ ttl?: string;
261
+ inputTokens?: number;
262
+ }
264
263
  interface BedrockUsage {
265
264
  inputTokens?: number;
266
265
  outputTokens?: number;
267
266
  cacheReadInputTokens?: number;
268
267
  cacheWriteInputTokens?: number;
268
+ cacheDetails?: BedrockCacheDetail[];
269
269
  }
270
270
  /** Map a Bedrock Converse response (model from the request) to a track payload. */
271
271
  declare function bedrockEventFrom(usage: BedrockUsage | undefined, model: string, opts: InstrumentOptions, response?: unknown, toolCalls?: number): TrackEventInput | null;
package/dist/index.js CHANGED
@@ -156,11 +156,7 @@ function anthropicEventFrom(msg, opts) {
156
156
  const usage = msg?.usage;
157
157
  if (!usage) return null;
158
158
  const runId = resolveRunId(opts, msg.id);
159
- const fivem = usage.cache_creation?.ephemeral_5m_input_tokens;
160
- const oneh = usage.cache_creation?.ephemeral_1h_input_tokens;
161
- const hasSplit = fivem !== void 0 || oneh !== void 0;
162
159
  const toolCalls = Array.isArray(msg.content) ? msg.content.filter((b) => b.type === "tool_use").length : 0;
163
- const thinkingTokens = usage.output_tokens_details?.thinking_tokens ?? 0;
164
160
  const event = {
165
161
  customerId: opts.customerId,
166
162
  agentId: opts.agentId,
@@ -168,11 +164,9 @@ function anthropicEventFrom(msg, opts) {
168
164
  provider: opts.provider ?? "anthropic",
169
165
  model: msg.model ?? "unknown",
170
166
  tokensIn: usage.input_tokens ?? 0,
171
- tokensOut: (usage.output_tokens ?? 0) - thinkingTokens,
172
- reasoningTokens: thinkingTokens,
167
+ tokensOut: usage.output_tokens ?? 0,
173
168
  cachedTokens: usage.cache_read_input_tokens ?? 0,
174
- cacheWrite5mTokens: hasSplit ? fivem ?? 0 : usage.cache_creation_input_tokens ?? 0,
175
- cacheWrite1hTokens: hasSplit ? oneh ?? 0 : 0,
169
+ cacheWrite5mTokens: usage.cache_creation_input_tokens ?? 0,
176
170
  webSearchRequests: usage.server_tool_use?.web_search_requests ?? 0,
177
171
  toolCalls,
178
172
  revenueUnitCents: resolveRevenue(opts, msg),
@@ -199,8 +193,7 @@ function wrapAnthropic(client, tollgate, opts) {
199
193
  } else if (ev.type === "message_delta" && ev.usage) {
200
194
  msg.usage = {
201
195
  ...msg.usage ?? {},
202
- output_tokens: ev.usage.output_tokens,
203
- output_tokens_details: ev.usage.output_tokens_details
196
+ output_tokens: ev.usage.output_tokens
204
197
  };
205
198
  } else if (ev.type === "content_block_start" && ev.content_block?.type === "tool_use") {
206
199
  toolUseBlocks.push(ev.content_block);
@@ -266,6 +259,10 @@ function openAIEventFrom(completion, opts) {
266
259
  revenueUnitCents: resolveRevenue(opts, completion),
267
260
  idempotencyKey: completion.id ?? `${runId}#${randomId()}`
268
261
  };
262
+ const gatewayCostUsd = usage.cost;
263
+ if (gatewayCostUsd != null && gatewayCostUsd > 0 && resolveCost(opts, completion) === void 0) {
264
+ event.providerCostCents = gatewayCostUsd * 100;
265
+ }
269
266
  return withCost(event, opts, completion);
270
267
  }
271
268
  function wrapOpenAI(client, tollgate, opts) {
@@ -331,6 +328,16 @@ function wrapOpenAI(client, tollgate, opts) {
331
328
  function bedrockEventFrom(usage, model, opts, response = void 0, toolCalls = 0) {
332
329
  if (!usage) return null;
333
330
  const runId = resolveRunId(opts, void 0);
331
+ let cacheWrite5m = 0;
332
+ let cacheWrite1h = 0;
333
+ if (usage.cacheDetails?.length) {
334
+ for (const d of usage.cacheDetails) {
335
+ if (d.ttl === "1h") cacheWrite1h += d.inputTokens ?? 0;
336
+ else cacheWrite5m += d.inputTokens ?? 0;
337
+ }
338
+ } else {
339
+ cacheWrite5m = usage.cacheWriteInputTokens ?? 0;
340
+ }
334
341
  const event = {
335
342
  customerId: opts.customerId,
336
343
  agentId: opts.agentId,
@@ -340,7 +347,8 @@ function bedrockEventFrom(usage, model, opts, response = void 0, toolCalls = 0)
340
347
  tokensIn: usage.inputTokens ?? 0,
341
348
  tokensOut: usage.outputTokens ?? 0,
342
349
  cachedTokens: usage.cacheReadInputTokens ?? 0,
343
- cacheWrite5mTokens: usage.cacheWriteInputTokens ?? 0,
350
+ cacheWrite5mTokens: cacheWrite5m,
351
+ cacheWrite1hTokens: cacheWrite1h,
344
352
  toolCalls,
345
353
  revenueUnitCents: resolveRevenue(opts, response),
346
354
  idempotencyKey: `${runId}#${randomId()}`
@@ -407,21 +415,27 @@ function geminiEventFrom(response, opts) {
407
415
  }, 0);
408
416
  const promptDetails = usage.promptTokensDetails;
409
417
  const candidateDetails = usage.candidatesTokensDetails;
418
+ const cachedIn = usage.cachedContentTokenCount ?? 0;
419
+ const audioIn = modalityTokens(promptDetails, "AUDIO");
420
+ const imageIn = modalityTokens(promptDetails, "IMAGE");
421
+ const videoIn = modalityTokens(promptDetails, "VIDEO");
422
+ const audioOut = modalityTokens(candidateDetails, "AUDIO");
423
+ const imageOut = modalityTokens(candidateDetails, "IMAGE");
410
424
  const event = {
411
425
  customerId: opts.customerId,
412
426
  agentId: opts.agentId,
413
427
  runId,
414
428
  provider: opts.provider ?? "google",
415
429
  model: "unknown",
416
- tokensIn: usage.promptTokenCount ?? 0,
417
- tokensOut: usage.candidatesTokenCount ?? 0,
430
+ tokensIn: (usage.promptTokenCount ?? 0) - cachedIn - audioIn - imageIn - videoIn,
431
+ tokensOut: (usage.candidatesTokenCount ?? 0) - audioOut - imageOut,
418
432
  reasoningTokens: usage.thoughtsTokenCount ?? 0,
419
- cachedTokens: usage.cachedContentTokenCount ?? 0,
420
- audioTokensIn: modalityTokens(promptDetails, "AUDIO"),
421
- audioTokensOut: modalityTokens(candidateDetails, "AUDIO"),
422
- imageTokensIn: modalityTokens(promptDetails, "IMAGE"),
423
- imageTokensOut: modalityTokens(candidateDetails, "IMAGE"),
424
- videoTokensIn: modalityTokens(promptDetails, "VIDEO"),
433
+ cachedTokens: cachedIn,
434
+ audioTokensIn: audioIn,
435
+ audioTokensOut: audioOut,
436
+ imageTokensIn: imageIn,
437
+ imageTokensOut: imageOut,
438
+ videoTokensIn: videoIn,
425
439
  textTokensIn: modalityTokens(promptDetails, "TEXT"),
426
440
  textTokensOut: modalityTokens(candidateDetails, "TEXT"),
427
441
  webSearchRequests,