@tollgateai/sdk 0.4.0 → 0.6.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.
- package/LICENSE +21 -0
- package/README.md +104 -105
- package/dist/index.cjs +152 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -2
- package/dist/index.d.ts +74 -2
- package/dist/index.js +151 -14
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -160,6 +160,7 @@ function anthropicEventFrom(msg, opts) {
|
|
|
160
160
|
const oneh = usage.cache_creation?.ephemeral_1h_input_tokens;
|
|
161
161
|
const hasSplit = fivem !== void 0 || oneh !== void 0;
|
|
162
162
|
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;
|
|
163
164
|
const event = {
|
|
164
165
|
customerId: opts.customerId,
|
|
165
166
|
agentId: opts.agentId,
|
|
@@ -167,10 +168,12 @@ function anthropicEventFrom(msg, opts) {
|
|
|
167
168
|
provider: opts.provider ?? "anthropic",
|
|
168
169
|
model: msg.model ?? "unknown",
|
|
169
170
|
tokensIn: usage.input_tokens ?? 0,
|
|
170
|
-
tokensOut: usage.output_tokens ?? 0,
|
|
171
|
+
tokensOut: (usage.output_tokens ?? 0) - thinkingTokens,
|
|
172
|
+
reasoningTokens: thinkingTokens,
|
|
171
173
|
cachedTokens: usage.cache_read_input_tokens ?? 0,
|
|
172
174
|
cacheWrite5mTokens: hasSplit ? fivem ?? 0 : usage.cache_creation_input_tokens ?? 0,
|
|
173
175
|
cacheWrite1hTokens: hasSplit ? oneh ?? 0 : 0,
|
|
176
|
+
webSearchRequests: usage.server_tool_use?.web_search_requests ?? 0,
|
|
174
177
|
toolCalls,
|
|
175
178
|
revenueUnitCents: resolveRevenue(opts, msg),
|
|
176
179
|
idempotencyKey: msg.id ?? `${runId}#${randomId()}`
|
|
@@ -181,6 +184,7 @@ function wrapAnthropic(client, tollgate, opts) {
|
|
|
181
184
|
const messages = client.messages;
|
|
182
185
|
const original = messages.create.bind(messages);
|
|
183
186
|
const create = async (...args) => {
|
|
187
|
+
const t0 = Date.now();
|
|
184
188
|
const result = await original(...args);
|
|
185
189
|
if (isAsyncIterable(result)) {
|
|
186
190
|
const msg = {};
|
|
@@ -193,7 +197,11 @@ function wrapAnthropic(client, tollgate, opts) {
|
|
|
193
197
|
msg.model = ev.message.model;
|
|
194
198
|
msg.usage = { ...ev.message.usage };
|
|
195
199
|
} else if (ev.type === "message_delta" && ev.usage) {
|
|
196
|
-
msg.usage = {
|
|
200
|
+
msg.usage = {
|
|
201
|
+
...msg.usage ?? {},
|
|
202
|
+
output_tokens: ev.usage.output_tokens,
|
|
203
|
+
output_tokens_details: ev.usage.output_tokens_details
|
|
204
|
+
};
|
|
197
205
|
} else if (ev.type === "content_block_start" && ev.content_block?.type === "tool_use") {
|
|
198
206
|
toolUseBlocks.push(ev.content_block);
|
|
199
207
|
}
|
|
@@ -201,12 +209,18 @@ function wrapAnthropic(client, tollgate, opts) {
|
|
|
201
209
|
() => {
|
|
202
210
|
msg.content = toolUseBlocks;
|
|
203
211
|
const event2 = anthropicEventFrom(msg, opts);
|
|
204
|
-
if (event2)
|
|
212
|
+
if (event2) {
|
|
213
|
+
event2.latencyMs = Date.now() - t0;
|
|
214
|
+
fireAndForget(tollgate.track(event2), opts.onError);
|
|
215
|
+
}
|
|
205
216
|
}
|
|
206
217
|
);
|
|
207
218
|
}
|
|
208
219
|
const event = anthropicEventFrom(result, opts);
|
|
209
|
-
if (event)
|
|
220
|
+
if (event) {
|
|
221
|
+
event.latencyMs = Date.now() - t0;
|
|
222
|
+
fireAndForget(tollgate.track(event), opts.onError);
|
|
223
|
+
}
|
|
210
224
|
return result;
|
|
211
225
|
};
|
|
212
226
|
return new Proxy(client, {
|
|
@@ -225,16 +239,29 @@ function openAIEventFrom(completion, opts) {
|
|
|
225
239
|
if (!usage) return null;
|
|
226
240
|
const runId = resolveRunId(opts, completion.id);
|
|
227
241
|
const toolCalls = completion.choices?.[0]?.message?.tool_calls?.length ?? 0;
|
|
242
|
+
const ptd = usage.prompt_tokens_details;
|
|
243
|
+
const ctd = usage.completion_tokens_details;
|
|
244
|
+
const cachedIn = ptd?.cached_tokens ?? 0;
|
|
245
|
+
const audioIn = ptd?.audio_tokens ?? 0;
|
|
246
|
+
const reasoningOut = ctd?.reasoning_tokens ?? 0;
|
|
247
|
+
const audioOut = ctd?.audio_tokens ?? 0;
|
|
228
248
|
const event = {
|
|
229
249
|
customerId: opts.customerId,
|
|
230
250
|
agentId: opts.agentId,
|
|
231
251
|
runId,
|
|
232
252
|
provider: opts.provider ?? "openai",
|
|
233
253
|
model: completion.model ?? "unknown",
|
|
234
|
-
tokensIn: usage.prompt_tokens ?? 0,
|
|
235
|
-
tokensOut: usage.completion_tokens ?? 0,
|
|
236
|
-
reasoningTokens:
|
|
237
|
-
cachedTokens:
|
|
254
|
+
tokensIn: (usage.prompt_tokens ?? 0) - cachedIn - audioIn,
|
|
255
|
+
tokensOut: (usage.completion_tokens ?? 0) - reasoningOut - audioOut,
|
|
256
|
+
reasoningTokens: reasoningOut,
|
|
257
|
+
cachedTokens: cachedIn,
|
|
258
|
+
audioTokensIn: audioIn,
|
|
259
|
+
audioTokensOut: audioOut,
|
|
260
|
+
textTokensIn: ptd?.text_tokens ?? 0,
|
|
261
|
+
textTokensOut: ctd?.text_tokens ?? 0,
|
|
262
|
+
acceptedPredictionTokens: ctd?.accepted_prediction_tokens ?? 0,
|
|
263
|
+
rejectedPredictionTokens: ctd?.rejected_prediction_tokens ?? 0,
|
|
264
|
+
serviceTier: completion.service_tier,
|
|
238
265
|
toolCalls,
|
|
239
266
|
revenueUnitCents: resolveRevenue(opts, completion),
|
|
240
267
|
idempotencyKey: completion.id ?? `${runId}#${randomId()}`
|
|
@@ -245,11 +272,13 @@ function wrapOpenAI(client, tollgate, opts) {
|
|
|
245
272
|
const completions = client.chat.completions;
|
|
246
273
|
const original = completions.create.bind(completions);
|
|
247
274
|
const create = async (...args) => {
|
|
275
|
+
const t0 = Date.now();
|
|
248
276
|
const result = await original(...args);
|
|
249
277
|
if (isAsyncIterable(result)) {
|
|
250
278
|
let id;
|
|
251
279
|
let model;
|
|
252
280
|
let usage;
|
|
281
|
+
let serviceTier;
|
|
253
282
|
const toolCallIndices = /* @__PURE__ */ new Set();
|
|
254
283
|
return instrumentStream(
|
|
255
284
|
result,
|
|
@@ -257,6 +286,7 @@ function wrapOpenAI(client, tollgate, opts) {
|
|
|
257
286
|
if (chunk.id) id = chunk.id;
|
|
258
287
|
if (chunk.model) model = chunk.model;
|
|
259
288
|
if (chunk.usage) usage = chunk.usage;
|
|
289
|
+
if (chunk.service_tier) serviceTier = chunk.service_tier;
|
|
260
290
|
for (const c of chunk.choices ?? []) {
|
|
261
291
|
for (const tc of c.delta?.tool_calls ?? []) {
|
|
262
292
|
if (tc.index !== void 0) toolCallIndices.add(tc.index);
|
|
@@ -265,17 +295,23 @@ function wrapOpenAI(client, tollgate, opts) {
|
|
|
265
295
|
},
|
|
266
296
|
() => {
|
|
267
297
|
if (!usage) return;
|
|
268
|
-
const synth = { id, model, usage };
|
|
298
|
+
const synth = { id, model, usage, service_tier: serviceTier };
|
|
269
299
|
if (toolCallIndices.size > 0) {
|
|
270
300
|
synth.choices = [{ message: { tool_calls: new Array(toolCallIndices.size) } }];
|
|
271
301
|
}
|
|
272
302
|
const event2 = openAIEventFrom(synth, opts);
|
|
273
|
-
if (event2)
|
|
303
|
+
if (event2) {
|
|
304
|
+
event2.latencyMs = Date.now() - t0;
|
|
305
|
+
fireAndForget(tollgate.track(event2), opts.onError);
|
|
306
|
+
}
|
|
274
307
|
}
|
|
275
308
|
);
|
|
276
309
|
}
|
|
277
310
|
const event = openAIEventFrom(result, opts);
|
|
278
|
-
if (event)
|
|
311
|
+
if (event) {
|
|
312
|
+
event.latencyMs = Date.now() - t0;
|
|
313
|
+
fireAndForget(tollgate.track(event), opts.onError);
|
|
314
|
+
}
|
|
279
315
|
return result;
|
|
280
316
|
};
|
|
281
317
|
return new Proxy(client, {
|
|
@@ -314,6 +350,7 @@ function bedrockEventFrom(usage, model, opts, response = void 0, toolCalls = 0)
|
|
|
314
350
|
function wrapBedrock(client, tollgate, opts) {
|
|
315
351
|
const originalSend = client.send.bind(client);
|
|
316
352
|
const send = async (command, ...rest) => {
|
|
353
|
+
const t0 = Date.now();
|
|
317
354
|
const result = await originalSend(command, ...rest);
|
|
318
355
|
const model = command?.input?.modelId ?? "unknown";
|
|
319
356
|
if (result?.stream && isAsyncIterable(result.stream)) {
|
|
@@ -327,7 +364,10 @@ function wrapBedrock(client, tollgate, opts) {
|
|
|
327
364
|
},
|
|
328
365
|
() => {
|
|
329
366
|
const event = bedrockEventFrom(usage, model, opts, result, streamToolCalls);
|
|
330
|
-
if (event)
|
|
367
|
+
if (event) {
|
|
368
|
+
event.latencyMs = Date.now() - t0;
|
|
369
|
+
fireAndForget(tollgate.track(event), opts.onError);
|
|
370
|
+
}
|
|
331
371
|
}
|
|
332
372
|
);
|
|
333
373
|
return result;
|
|
@@ -335,7 +375,10 @@ function wrapBedrock(client, tollgate, opts) {
|
|
|
335
375
|
if (result?.usage) {
|
|
336
376
|
const tc = result.output?.message?.content?.filter((b) => b.toolUse != null).length ?? 0;
|
|
337
377
|
const event = bedrockEventFrom(result.usage, model, opts, result, tc);
|
|
338
|
-
if (event)
|
|
378
|
+
if (event) {
|
|
379
|
+
event.latencyMs = Date.now() - t0;
|
|
380
|
+
fireAndForget(tollgate.track(event), opts.onError);
|
|
381
|
+
}
|
|
339
382
|
}
|
|
340
383
|
return result;
|
|
341
384
|
};
|
|
@@ -346,7 +389,101 @@ function wrapBedrock(client, tollgate, opts) {
|
|
|
346
389
|
}
|
|
347
390
|
});
|
|
348
391
|
}
|
|
392
|
+
function modalityTokens(details, modality) {
|
|
393
|
+
if (!details) return 0;
|
|
394
|
+
return details.filter((d) => d.modality === modality).reduce((sum, d) => sum + (d.tokenCount ?? 0), 0);
|
|
395
|
+
}
|
|
396
|
+
function geminiEventFrom(response, opts) {
|
|
397
|
+
const usage = response?.usageMetadata;
|
|
398
|
+
if (!usage) return null;
|
|
399
|
+
const runId = resolveRunId(opts, void 0);
|
|
400
|
+
const candidates = response.candidates ?? [];
|
|
401
|
+
const toolCalls = candidates.reduce((sum, c) => {
|
|
402
|
+
const parts = c.content?.parts ?? [];
|
|
403
|
+
return sum + parts.filter((p) => p.functionCall != null).length;
|
|
404
|
+
}, 0);
|
|
405
|
+
const webSearchRequests = candidates.reduce((sum, c) => {
|
|
406
|
+
return sum + (c.groundingMetadata?.webSearchQueries?.length ?? 0);
|
|
407
|
+
}, 0);
|
|
408
|
+
const promptDetails = usage.promptTokensDetails;
|
|
409
|
+
const candidateDetails = usage.candidatesTokensDetails;
|
|
410
|
+
const event = {
|
|
411
|
+
customerId: opts.customerId,
|
|
412
|
+
agentId: opts.agentId,
|
|
413
|
+
runId,
|
|
414
|
+
provider: opts.provider ?? "google",
|
|
415
|
+
model: "unknown",
|
|
416
|
+
tokensIn: usage.promptTokenCount ?? 0,
|
|
417
|
+
tokensOut: usage.candidatesTokenCount ?? 0,
|
|
418
|
+
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"),
|
|
425
|
+
textTokensIn: modalityTokens(promptDetails, "TEXT"),
|
|
426
|
+
textTokensOut: modalityTokens(candidateDetails, "TEXT"),
|
|
427
|
+
webSearchRequests,
|
|
428
|
+
toolCalls,
|
|
429
|
+
revenueUnitCents: resolveRevenue(opts, response),
|
|
430
|
+
idempotencyKey: `${runId}#${randomId()}`
|
|
431
|
+
};
|
|
432
|
+
return withCost(event, opts, response);
|
|
433
|
+
}
|
|
434
|
+
function wrapGemini(model, tollgate, opts) {
|
|
435
|
+
const original = model.generateContent.bind(model);
|
|
436
|
+
const modelName = model.model ?? "unknown";
|
|
437
|
+
const generateContent = async (...args) => {
|
|
438
|
+
const t0 = Date.now();
|
|
439
|
+
const result = await original(...args);
|
|
440
|
+
if (isAsyncIterable(result)) {
|
|
441
|
+
const accumulated = {};
|
|
442
|
+
let toolCallCount = 0;
|
|
443
|
+
let searchCount = 0;
|
|
444
|
+
return instrumentStream(
|
|
445
|
+
result,
|
|
446
|
+
(chunk) => {
|
|
447
|
+
if (chunk.usageMetadata) {
|
|
448
|
+
Object.assign(accumulated, chunk.usageMetadata);
|
|
449
|
+
}
|
|
450
|
+
for (const c of chunk.candidates ?? []) {
|
|
451
|
+
for (const p of c.content?.parts ?? []) {
|
|
452
|
+
if (p.functionCall != null) toolCallCount++;
|
|
453
|
+
}
|
|
454
|
+
searchCount += c.groundingMetadata?.webSearchQueries?.length ?? 0;
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
() => {
|
|
458
|
+
const synth = {
|
|
459
|
+
usageMetadata: accumulated,
|
|
460
|
+
candidates: searchCount > 0 || toolCallCount > 0 ? [{ content: { parts: new Array(toolCallCount).fill({ functionCall: {} }) }, groundingMetadata: { webSearchQueries: new Array(searchCount) } }] : []
|
|
461
|
+
};
|
|
462
|
+
const event2 = geminiEventFrom(synth, opts);
|
|
463
|
+
if (event2) {
|
|
464
|
+
event2.model = modelName;
|
|
465
|
+
event2.latencyMs = Date.now() - t0;
|
|
466
|
+
fireAndForget(tollgate.track(event2), opts.onError);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
const event = geminiEventFrom(result, opts);
|
|
472
|
+
if (event) {
|
|
473
|
+
event.model = modelName;
|
|
474
|
+
event.latencyMs = Date.now() - t0;
|
|
475
|
+
fireAndForget(tollgate.track(event), opts.onError);
|
|
476
|
+
}
|
|
477
|
+
return result;
|
|
478
|
+
};
|
|
479
|
+
return new Proxy(model, {
|
|
480
|
+
get(target, prop, recv) {
|
|
481
|
+
if (prop === "generateContent") return generateContent;
|
|
482
|
+
return Reflect.get(target, prop, recv);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
}
|
|
349
486
|
|
|
350
|
-
export { TollgateError, anthropicEventFrom, bedrockEventFrom, createTollgateClient, openAIEventFrom, wrapAnthropic, wrapBedrock, wrapOpenAI };
|
|
487
|
+
export { TollgateError, anthropicEventFrom, bedrockEventFrom, createTollgateClient, geminiEventFrom, openAIEventFrom, wrapAnthropic, wrapBedrock, wrapGemini, wrapOpenAI };
|
|
351
488
|
//# sourceMappingURL=index.js.map
|
|
352
489
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/instrument.ts"],"names":["event"],"mappings":"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","file":"index.js","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"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/instrument.ts"],"names":["event"],"mappings":"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","file":"index.js","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"]}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tollgateai/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Track
|
|
5
|
-
"license": "
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Track LLM model usage and compute live gross margin with Tollgate.",
|
|
5
|
+
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.cjs",
|
|
8
8
|
"module": "./dist/index.js",
|
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
"observability",
|
|
33
33
|
"anthropic",
|
|
34
34
|
"openai",
|
|
35
|
+
"gemini",
|
|
36
|
+
"bedrock",
|
|
35
37
|
"tollgate"
|
|
36
38
|
],
|
|
37
39
|
"engines": {
|