@tollgateai/sdk 0.2.0 → 0.3.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 { Provider, RunOutcome, TrackEventInput, TrackResult } 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}\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 async function track(event: TrackEventInput): Promise<TrackResult> {\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}/api/track`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(event),\n signal: controller.signal,\n });\n\n // 200 = idempotent duplicate, 201 = created. Both are success.\n if (res.ok) {\n return (await res.json()) as TrackResult;\n }\n\n // Retry transient failures; fail fast on 4xx (except 429).\n if (res.status >= 500 || res.status === 429) {\n lastErr = new TollgateError(`Tollgate track failed (${res.status})`, res.status);\n } else {\n const body = await res.json().catch(() => ({}));\n throw new TollgateError(`Tollgate track failed (${res.status})`, res.status, body);\n }\n } catch (err) {\n // Don't retry deterministic client errors.\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 track failed after retries');\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 };\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 cache_read_input_tokens?: number;\n // Cache CREATION (writes) bill above the input rate. Newer responses break the\n // total down by TTL; older ones only return the aggregate cache_creation count.\n cache_creation_input_tokens?: number;\n cache_creation?: {\n ephemeral_5m_input_tokens?: number;\n ephemeral_1h_input_tokens?: number;\n };\n}\ninterface AnthropicMessage {\n id?: string;\n model?: string;\n usage?: AnthropicUsage;\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}\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 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: hasSplit ? fivem ?? 0 : usage.cache_creation_input_tokens ?? 0,\n cacheWrite1hTokens: hasSplit ? oneh ?? 0 : 0,\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 result = await original(...args);\n if (isAsyncIterable(result)) {\n // Reconstruct a message from the event stream, then reuse the non-stream\n // mapper. input/cache tokens arrive in message_start; the final cumulative\n // output token count arrives in the last message_delta.\n const msg: AnthropicMessage = {};\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 = { ...(msg.usage ?? {}), output_tokens: ev.usage.output_tokens };\n }\n },\n () => {\n const event = anthropicEventFrom(msg, opts);\n if (event) fireAndForget(tollgate.track(event), opts.onError);\n },\n );\n }\n const event = anthropicEventFrom(result as AnthropicMessage, opts);\n if (event) fireAndForget(tollgate.track(event), opts.onError);\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?: { reasoning_tokens?: number };\n prompt_tokens_details?: { cached_tokens?: number };\n}\ninterface OpenAICompletion {\n id?: string;\n model?: string;\n usage?: OpenAIUsage;\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 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,\n tokensOut: usage.completion_tokens ?? 0,\n reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,\n cachedTokens: usage.prompt_tokens_details?.cached_tokens ?? 0,\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 result = await original(...args);\n if (isAsyncIterable(result)) {\n let id: string | undefined;\n let model: string | undefined;\n let usage: OpenAIUsage | undefined;\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; // only the final chunk carries it\n },\n () => {\n if (!usage) return; // caller didn't request include_usage — nothing to report\n const event = openAIEventFrom({ id, model, usage }, opts);\n if (event) fireAndForget(tollgate.track(event), opts.onError);\n },\n );\n }\n const event = openAIEventFrom(result as OpenAICompletion, opts);\n if (event) fireAndForget(tollgate.track(event), opts.onError);\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 BedrockConverseResponse {\n usage?: BedrockUsage;\n // ConverseStream returns an async-iterable `stream` of events; the final\n // `metadata` event carries the usage totals.\n stream?: AsyncIterable<{ metadata?: { usage?: BedrockUsage } }>;\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): 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 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 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 result.stream = instrumentStream(\n result.stream,\n (ev) => {\n if (ev.metadata?.usage) usage = ev.metadata.usage;\n },\n () => {\n const event = bedrockEventFrom(usage, model, opts, result);\n if (event) fireAndForget(tollgate.track(event), opts.onError);\n },\n );\n return result;\n }\n\n if (result?.usage) {\n const event = bedrockEventFrom(result.usage, model, opts, result);\n if (event) 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 === 'send') return send;\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\ninterface AnthropicUsage {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n // Cache CREATION (writes) bill above the input rate. Newer responses break the\n // total down by TTL; older ones only return the aggregate cache_creation count.\n cache_creation_input_tokens?: number;\n cache_creation?: {\n ephemeral_5m_input_tokens?: number;\n ephemeral_1h_input_tokens?: 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 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: hasSplit ? fivem ?? 0 : usage.cache_creation_input_tokens ?? 0,\n cacheWrite1hTokens: hasSplit ? oneh ?? 0 : 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 result = await original(...args);\n if (isAsyncIterable(result)) {\n // Reconstruct a message from the event stream, then reuse the non-stream\n // mapper. input/cache tokens arrive in message_start; the final cumulative\n // output token count arrives in the last message_delta.\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 = { ...(msg.usage ?? {}), output_tokens: ev.usage.output_tokens };\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) fireAndForget(tollgate.track(event), opts.onError);\n },\n );\n }\n const event = anthropicEventFrom(result as AnthropicMessage, opts);\n if (event) fireAndForget(tollgate.track(event), opts.onError);\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?: { reasoning_tokens?: number };\n prompt_tokens_details?: { cached_tokens?: 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}\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 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,\n tokensOut: usage.completion_tokens ?? 0,\n reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,\n cachedTokens: usage.prompt_tokens_details?.cached_tokens ?? 0,\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 result = await original(...args);\n if (isAsyncIterable(result)) {\n let id: string | undefined;\n let model: string | undefined;\n let usage: OpenAIUsage | 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 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 };\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) fireAndForget(tollgate.track(event), opts.onError);\n },\n );\n }\n const event = openAIEventFrom(result as OpenAICompletion, opts);\n if (event) fireAndForget(tollgate.track(event), opts.onError);\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 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) fireAndForget(tollgate.track(event), opts.onError);\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) 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 === 'send') return send;\n return Reflect.get(target, prop, recv);\n },\n });\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -45,6 +45,38 @@ interface TrackResult {
45
45
  status: 'created' | 'duplicate' | string;
46
46
  eventId: string;
47
47
  }
48
+ /** Revenue model for a plan (mirrors the server). */
49
+ type PricingModel = 'per_unit' | 'per_resolution' | 'usage_based' | 'per_seat' | 'flat' | 'hybrid';
50
+ /** Declare a plan inline (upserted by name) when setting up a customer. */
51
+ interface PlanInput {
52
+ name: string;
53
+ pricingModel: PricingModel;
54
+ /** Per-unit / per-1k-token / per-seat amount in cents (meaning depends on model). */
55
+ unitRevenueCents?: number;
56
+ /** Flat/subscription base in cents per month (flat & hybrid). */
57
+ baseRevenueCents?: number;
58
+ }
59
+ /** Input for `upsertCustomer` — create/update a customer and (optionally) its plan. */
60
+ interface UpsertCustomerInput {
61
+ /** Your end customer's stable external id (same value you pass to track). */
62
+ customerId: string;
63
+ name?: string;
64
+ company?: string;
65
+ useCase?: string;
66
+ /** Seat count for per_seat plans. */
67
+ seats?: number;
68
+ /** Assign an existing plan by id … */
69
+ planId?: string;
70
+ /** … or declare one inline (upserted by name). */
71
+ plan?: PlanInput;
72
+ }
73
+ interface UpsertCustomerResult {
74
+ status: string;
75
+ customerId: string;
76
+ /** Account-namespaced internal id. */
77
+ id: string;
78
+ planId: string | null;
79
+ }
48
80
 
49
81
  interface TollgateClientOptions {
50
82
  /** Account API key (`tg_live_…`). Falls back to `process.env.TOLLGATE_API_KEY`. */
@@ -87,6 +119,10 @@ interface TollgateClient {
87
119
  /** Close a run with its outcome — book revenue once, only if resolved.
88
120
  * Convenience over `track()`: sends a zero-usage terminal event. */
89
121
  resolve(input: ResolveInput): Promise<TrackResult>;
122
+ /** Create/update a customer and (optionally) its plan, in code. Call this
123
+ * BEFORE sending usage so plan-priced revenue (esp. usage_based, which is
124
+ * computed at ingest) is recognized from the first event. Idempotent. */
125
+ upsertCustomer(input: UpsertCustomerInput): Promise<UpsertCustomerResult>;
90
126
  }
91
127
  declare function createTollgateClient(opts?: TollgateClientOptions): TollgateClient;
92
128
 
@@ -121,10 +157,14 @@ interface AnthropicUsage {
121
157
  ephemeral_1h_input_tokens?: number;
122
158
  };
123
159
  }
160
+ interface AnthropicContentBlock {
161
+ type?: string;
162
+ }
124
163
  interface AnthropicMessage {
125
164
  id?: string;
126
165
  model?: string;
127
166
  usage?: AnthropicUsage;
167
+ content?: AnthropicContentBlock[];
128
168
  }
129
169
  /** Map a non-streaming Anthropic message to a track payload (or null if no usage). */
130
170
  declare function anthropicEventFrom(msg: AnthropicMessage, opts: InstrumentOptions): TrackEventInput | null;
@@ -146,10 +186,23 @@ interface OpenAIUsage {
146
186
  cached_tokens?: number;
147
187
  };
148
188
  }
189
+ interface OpenAIToolCall {
190
+ index?: number;
191
+ }
192
+ interface OpenAIDelta {
193
+ tool_calls?: OpenAIToolCall[];
194
+ }
195
+ interface OpenAIChoice {
196
+ message?: {
197
+ tool_calls?: unknown[];
198
+ };
199
+ delta?: OpenAIDelta;
200
+ }
149
201
  interface OpenAICompletion {
150
202
  id?: string;
151
203
  model?: string;
152
204
  usage?: OpenAIUsage;
205
+ choices?: OpenAIChoice[];
153
206
  }
154
207
  /** Map a non-streaming OpenAI chat completion to a track payload (or null). */
155
208
  declare function openAIEventFrom(completion: OpenAICompletion, opts: InstrumentOptions): TrackEventInput | null;
@@ -173,7 +226,7 @@ interface BedrockUsage {
173
226
  cacheWriteInputTokens?: number;
174
227
  }
175
228
  /** Map a Bedrock Converse response (model from the request) to a track payload. */
176
- declare function bedrockEventFrom(usage: BedrockUsage | undefined, model: string, opts: InstrumentOptions, response?: unknown): TrackEventInput | null;
229
+ declare function bedrockEventFrom(usage: BedrockUsage | undefined, model: string, opts: InstrumentOptions, response?: unknown, toolCalls?: number): TrackEventInput | null;
177
230
  interface BedrockLike {
178
231
  send: (command: unknown, ...rest: never[]) => Promise<unknown>;
179
232
  }
@@ -182,4 +235,4 @@ interface BedrockLike {
182
235
  * usage in the response) pass through untouched. */
183
236
  declare function wrapBedrock<T extends BedrockLike>(client: T, tollgate: TollgateClient, opts: InstrumentOptions): T;
184
237
 
185
- export { type EventType, type InstrumentOptions, type Provider, type ResolveInput, type RunOutcome, type TollgateClient, type TollgateClientOptions, TollgateError, type TrackEventInput, type TrackResult, anthropicEventFrom, bedrockEventFrom, createTollgateClient, openAIEventFrom, wrapAnthropic, wrapBedrock, wrapOpenAI };
238
+ export { type EventType, type InstrumentOptions, type PlanInput, type PricingModel, type Provider, type ResolveInput, type RunOutcome, type TollgateClient, type TollgateClientOptions, TollgateError, type TrackEventInput, type TrackResult, type UpsertCustomerInput, type UpsertCustomerResult, anthropicEventFrom, bedrockEventFrom, createTollgateClient, openAIEventFrom, wrapAnthropic, wrapBedrock, wrapOpenAI };
package/dist/index.d.ts CHANGED
@@ -45,6 +45,38 @@ interface TrackResult {
45
45
  status: 'created' | 'duplicate' | string;
46
46
  eventId: string;
47
47
  }
48
+ /** Revenue model for a plan (mirrors the server). */
49
+ type PricingModel = 'per_unit' | 'per_resolution' | 'usage_based' | 'per_seat' | 'flat' | 'hybrid';
50
+ /** Declare a plan inline (upserted by name) when setting up a customer. */
51
+ interface PlanInput {
52
+ name: string;
53
+ pricingModel: PricingModel;
54
+ /** Per-unit / per-1k-token / per-seat amount in cents (meaning depends on model). */
55
+ unitRevenueCents?: number;
56
+ /** Flat/subscription base in cents per month (flat & hybrid). */
57
+ baseRevenueCents?: number;
58
+ }
59
+ /** Input for `upsertCustomer` — create/update a customer and (optionally) its plan. */
60
+ interface UpsertCustomerInput {
61
+ /** Your end customer's stable external id (same value you pass to track). */
62
+ customerId: string;
63
+ name?: string;
64
+ company?: string;
65
+ useCase?: string;
66
+ /** Seat count for per_seat plans. */
67
+ seats?: number;
68
+ /** Assign an existing plan by id … */
69
+ planId?: string;
70
+ /** … or declare one inline (upserted by name). */
71
+ plan?: PlanInput;
72
+ }
73
+ interface UpsertCustomerResult {
74
+ status: string;
75
+ customerId: string;
76
+ /** Account-namespaced internal id. */
77
+ id: string;
78
+ planId: string | null;
79
+ }
48
80
 
49
81
  interface TollgateClientOptions {
50
82
  /** Account API key (`tg_live_…`). Falls back to `process.env.TOLLGATE_API_KEY`. */
@@ -87,6 +119,10 @@ interface TollgateClient {
87
119
  /** Close a run with its outcome — book revenue once, only if resolved.
88
120
  * Convenience over `track()`: sends a zero-usage terminal event. */
89
121
  resolve(input: ResolveInput): Promise<TrackResult>;
122
+ /** Create/update a customer and (optionally) its plan, in code. Call this
123
+ * BEFORE sending usage so plan-priced revenue (esp. usage_based, which is
124
+ * computed at ingest) is recognized from the first event. Idempotent. */
125
+ upsertCustomer(input: UpsertCustomerInput): Promise<UpsertCustomerResult>;
90
126
  }
91
127
  declare function createTollgateClient(opts?: TollgateClientOptions): TollgateClient;
92
128
 
@@ -121,10 +157,14 @@ interface AnthropicUsage {
121
157
  ephemeral_1h_input_tokens?: number;
122
158
  };
123
159
  }
160
+ interface AnthropicContentBlock {
161
+ type?: string;
162
+ }
124
163
  interface AnthropicMessage {
125
164
  id?: string;
126
165
  model?: string;
127
166
  usage?: AnthropicUsage;
167
+ content?: AnthropicContentBlock[];
128
168
  }
129
169
  /** Map a non-streaming Anthropic message to a track payload (or null if no usage). */
130
170
  declare function anthropicEventFrom(msg: AnthropicMessage, opts: InstrumentOptions): TrackEventInput | null;
@@ -146,10 +186,23 @@ interface OpenAIUsage {
146
186
  cached_tokens?: number;
147
187
  };
148
188
  }
189
+ interface OpenAIToolCall {
190
+ index?: number;
191
+ }
192
+ interface OpenAIDelta {
193
+ tool_calls?: OpenAIToolCall[];
194
+ }
195
+ interface OpenAIChoice {
196
+ message?: {
197
+ tool_calls?: unknown[];
198
+ };
199
+ delta?: OpenAIDelta;
200
+ }
149
201
  interface OpenAICompletion {
150
202
  id?: string;
151
203
  model?: string;
152
204
  usage?: OpenAIUsage;
205
+ choices?: OpenAIChoice[];
153
206
  }
154
207
  /** Map a non-streaming OpenAI chat completion to a track payload (or null). */
155
208
  declare function openAIEventFrom(completion: OpenAICompletion, opts: InstrumentOptions): TrackEventInput | null;
@@ -173,7 +226,7 @@ interface BedrockUsage {
173
226
  cacheWriteInputTokens?: number;
174
227
  }
175
228
  /** Map a Bedrock Converse response (model from the request) to a track payload. */
176
- declare function bedrockEventFrom(usage: BedrockUsage | undefined, model: string, opts: InstrumentOptions, response?: unknown): TrackEventInput | null;
229
+ declare function bedrockEventFrom(usage: BedrockUsage | undefined, model: string, opts: InstrumentOptions, response?: unknown, toolCalls?: number): TrackEventInput | null;
177
230
  interface BedrockLike {
178
231
  send: (command: unknown, ...rest: never[]) => Promise<unknown>;
179
232
  }
@@ -182,4 +235,4 @@ interface BedrockLike {
182
235
  * usage in the response) pass through untouched. */
183
236
  declare function wrapBedrock<T extends BedrockLike>(client: T, tollgate: TollgateClient, opts: InstrumentOptions): T;
184
237
 
185
- export { type EventType, type InstrumentOptions, type Provider, type ResolveInput, type RunOutcome, type TollgateClient, type TollgateClientOptions, TollgateError, type TrackEventInput, type TrackResult, anthropicEventFrom, bedrockEventFrom, createTollgateClient, openAIEventFrom, wrapAnthropic, wrapBedrock, wrapOpenAI };
238
+ export { type EventType, type InstrumentOptions, type PlanInput, type PricingModel, type Provider, type ResolveInput, type RunOutcome, type TollgateClient, type TollgateClientOptions, TollgateError, type TrackEventInput, type TrackResult, type UpsertCustomerInput, type UpsertCustomerResult, anthropicEventFrom, bedrockEventFrom, createTollgateClient, openAIEventFrom, wrapAnthropic, wrapBedrock, wrapOpenAI };
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ function createTollgateClient(opts = {}) {
21
21
  if (typeof doFetch !== "function") {
22
22
  throw new TollgateError("No fetch implementation available \u2014 pass `fetch` in options.");
23
23
  }
24
- async function track(event) {
24
+ async function postJson(path, body) {
25
25
  if (!apiKey) {
26
26
  throw new TollgateError("Missing API key \u2014 set opts.apiKey or TOLLGATE_API_KEY.");
27
27
  }
@@ -30,23 +30,23 @@ function createTollgateClient(opts = {}) {
30
30
  const controller = new AbortController();
31
31
  const timer = setTimeout(() => controller.abort(), timeoutMs);
32
32
  try {
33
- const res = await doFetch(`${baseUrl}/api/track`, {
33
+ const res = await doFetch(`${baseUrl}${path}`, {
34
34
  method: "POST",
35
35
  headers: {
36
36
  "Content-Type": "application/json",
37
37
  Authorization: `Bearer ${apiKey}`
38
38
  },
39
- body: JSON.stringify(event),
39
+ body: JSON.stringify(body),
40
40
  signal: controller.signal
41
41
  });
42
42
  if (res.ok) {
43
43
  return await res.json();
44
44
  }
45
45
  if (res.status >= 500 || res.status === 429) {
46
- lastErr = new TollgateError(`Tollgate track failed (${res.status})`, res.status);
46
+ lastErr = new TollgateError(`Tollgate request failed (${res.status})`, res.status);
47
47
  } else {
48
- const body = await res.json().catch(() => ({}));
49
- throw new TollgateError(`Tollgate track failed (${res.status})`, res.status, body);
48
+ const errBody = await res.json().catch(() => ({}));
49
+ throw new TollgateError(`Tollgate request failed (${res.status})`, res.status, errBody);
50
50
  }
51
51
  } catch (err) {
52
52
  if (err instanceof TollgateError && err.status && err.status < 500 && err.status !== 429) {
@@ -60,7 +60,13 @@ function createTollgateClient(opts = {}) {
60
60
  await sleep(2 ** attempt * 200);
61
61
  }
62
62
  }
63
- throw lastErr instanceof Error ? lastErr : new TollgateError("Tollgate track failed after retries");
63
+ throw lastErr instanceof Error ? lastErr : new TollgateError("Tollgate request failed after retries");
64
+ }
65
+ function track(event) {
66
+ return postJson("/api/track", event);
67
+ }
68
+ function upsertCustomer(input) {
69
+ return postJson("/api/sdk/customer", input);
64
70
  }
65
71
  function resolve(input) {
66
72
  return track({
@@ -78,7 +84,7 @@ function createTollgateClient(opts = {}) {
78
84
  ts: input.ts
79
85
  });
80
86
  }
81
- return { track, resolve };
87
+ return { track, resolve, upsertCustomer };
82
88
  }
83
89
 
84
90
  // src/instrument.ts
@@ -153,6 +159,7 @@ function anthropicEventFrom(msg, opts) {
153
159
  const fivem = usage.cache_creation?.ephemeral_5m_input_tokens;
154
160
  const oneh = usage.cache_creation?.ephemeral_1h_input_tokens;
155
161
  const hasSplit = fivem !== void 0 || oneh !== void 0;
162
+ const toolCalls = Array.isArray(msg.content) ? msg.content.filter((b) => b.type === "tool_use").length : 0;
156
163
  const event = {
157
164
  customerId: opts.customerId,
158
165
  agentId: opts.agentId,
@@ -164,6 +171,7 @@ function anthropicEventFrom(msg, opts) {
164
171
  cachedTokens: usage.cache_read_input_tokens ?? 0,
165
172
  cacheWrite5mTokens: hasSplit ? fivem ?? 0 : usage.cache_creation_input_tokens ?? 0,
166
173
  cacheWrite1hTokens: hasSplit ? oneh ?? 0 : 0,
174
+ toolCalls,
167
175
  revenueUnitCents: resolveRevenue(opts, msg),
168
176
  idempotencyKey: msg.id ?? `${runId}#${randomId()}`
169
177
  };
@@ -176,6 +184,7 @@ function wrapAnthropic(client, tollgate, opts) {
176
184
  const result = await original(...args);
177
185
  if (isAsyncIterable(result)) {
178
186
  const msg = {};
187
+ const toolUseBlocks = [];
179
188
  return instrumentStream(
180
189
  result,
181
190
  (ev) => {
@@ -185,9 +194,12 @@ function wrapAnthropic(client, tollgate, opts) {
185
194
  msg.usage = { ...ev.message.usage };
186
195
  } else if (ev.type === "message_delta" && ev.usage) {
187
196
  msg.usage = { ...msg.usage ?? {}, output_tokens: ev.usage.output_tokens };
197
+ } else if (ev.type === "content_block_start" && ev.content_block?.type === "tool_use") {
198
+ toolUseBlocks.push(ev.content_block);
188
199
  }
189
200
  },
190
201
  () => {
202
+ msg.content = toolUseBlocks;
191
203
  const event2 = anthropicEventFrom(msg, opts);
192
204
  if (event2) fireAndForget(tollgate.track(event2), opts.onError);
193
205
  }
@@ -212,6 +224,7 @@ function openAIEventFrom(completion, opts) {
212
224
  const usage = completion?.usage;
213
225
  if (!usage) return null;
214
226
  const runId = resolveRunId(opts, completion.id);
227
+ const toolCalls = completion.choices?.[0]?.message?.tool_calls?.length ?? 0;
215
228
  const event = {
216
229
  customerId: opts.customerId,
217
230
  agentId: opts.agentId,
@@ -222,6 +235,7 @@ function openAIEventFrom(completion, opts) {
222
235
  tokensOut: usage.completion_tokens ?? 0,
223
236
  reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,
224
237
  cachedTokens: usage.prompt_tokens_details?.cached_tokens ?? 0,
238
+ toolCalls,
225
239
  revenueUnitCents: resolveRevenue(opts, completion),
226
240
  idempotencyKey: completion.id ?? `${runId}#${randomId()}`
227
241
  };
@@ -236,16 +250,26 @@ function wrapOpenAI(client, tollgate, opts) {
236
250
  let id;
237
251
  let model;
238
252
  let usage;
253
+ const toolCallIndices = /* @__PURE__ */ new Set();
239
254
  return instrumentStream(
240
255
  result,
241
256
  (chunk) => {
242
257
  if (chunk.id) id = chunk.id;
243
258
  if (chunk.model) model = chunk.model;
244
259
  if (chunk.usage) usage = chunk.usage;
260
+ for (const c of chunk.choices ?? []) {
261
+ for (const tc of c.delta?.tool_calls ?? []) {
262
+ if (tc.index !== void 0) toolCallIndices.add(tc.index);
263
+ }
264
+ }
245
265
  },
246
266
  () => {
247
267
  if (!usage) return;
248
- const event2 = openAIEventFrom({ id, model, usage }, opts);
268
+ const synth = { id, model, usage };
269
+ if (toolCallIndices.size > 0) {
270
+ synth.choices = [{ message: { tool_calls: new Array(toolCallIndices.size) } }];
271
+ }
272
+ const event2 = openAIEventFrom(synth, opts);
249
273
  if (event2) fireAndForget(tollgate.track(event2), opts.onError);
250
274
  }
251
275
  );
@@ -268,7 +292,7 @@ function wrapOpenAI(client, tollgate, opts) {
268
292
  }
269
293
  });
270
294
  }
271
- function bedrockEventFrom(usage, model, opts, response = void 0) {
295
+ function bedrockEventFrom(usage, model, opts, response = void 0, toolCalls = 0) {
272
296
  if (!usage) return null;
273
297
  const runId = resolveRunId(opts, void 0);
274
298
  const event = {
@@ -281,6 +305,7 @@ function bedrockEventFrom(usage, model, opts, response = void 0) {
281
305
  tokensOut: usage.outputTokens ?? 0,
282
306
  cachedTokens: usage.cacheReadInputTokens ?? 0,
283
307
  cacheWrite5mTokens: usage.cacheWriteInputTokens ?? 0,
308
+ toolCalls,
284
309
  revenueUnitCents: resolveRevenue(opts, response),
285
310
  idempotencyKey: `${runId}#${randomId()}`
286
311
  };
@@ -293,20 +318,23 @@ function wrapBedrock(client, tollgate, opts) {
293
318
  const model = command?.input?.modelId ?? "unknown";
294
319
  if (result?.stream && isAsyncIterable(result.stream)) {
295
320
  let usage;
321
+ let streamToolCalls = 0;
296
322
  result.stream = instrumentStream(
297
323
  result.stream,
298
324
  (ev) => {
299
325
  if (ev.metadata?.usage) usage = ev.metadata.usage;
326
+ if (ev.contentBlockStart?.start?.toolUse) streamToolCalls++;
300
327
  },
301
328
  () => {
302
- const event = bedrockEventFrom(usage, model, opts, result);
329
+ const event = bedrockEventFrom(usage, model, opts, result, streamToolCalls);
303
330
  if (event) fireAndForget(tollgate.track(event), opts.onError);
304
331
  }
305
332
  );
306
333
  return result;
307
334
  }
308
335
  if (result?.usage) {
309
- const event = bedrockEventFrom(result.usage, model, opts, result);
336
+ const tc = result.output?.message?.content?.filter((b) => b.toolUse != null).length ?? 0;
337
+ const event = bedrockEventFrom(result.usage, model, opts, result, tc);
310
338
  if (event) fireAndForget(tollgate.track(event), opts.onError);
311
339
  }
312
340
  return result;