braintrust 0.4.8 → 0.4.9

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/dist/index.js CHANGED
@@ -2933,7 +2933,7 @@ var init_stream = __esm({
2933
2933
  /**
2934
2934
  * Get the underlying ReadableStream.
2935
2935
  *
2936
- * @returns The underlying ReadableStream<BraintrustStreamChunk>.
2936
+ * @returns The underlying `ReadableStream<BraintrustStreamChunk>`.
2937
2937
  */
2938
2938
  toReadableStream() {
2939
2939
  return this.stream;
@@ -12815,6 +12815,11 @@ function proxyCreate(target, hooks) {
12815
12815
  } else {
12816
12816
  const event = hooks.resultToEventFunc(result);
12817
12817
  const span = timedSpan.span;
12818
+ const ttft = getCurrentUnixTimestamp() - timedSpan.start;
12819
+ if (!event.metrics) {
12820
+ event.metrics = {};
12821
+ }
12822
+ event.metrics.time_to_first_token = ttft;
12818
12823
  span.log(event);
12819
12824
  span.end();
12820
12825
  return result;
@@ -13298,194 +13303,9 @@ var WrapperStream = class {
13298
13303
  }
13299
13304
  };
13300
13305
 
13301
- // src/wrappers/ai-sdk-5/middleware.ts
13302
- init_util();
13303
- init_logger();
13304
-
13305
- // src/wrappers/anthropic-tokens-util.ts
13306
- function finalizeAnthropicTokens(metrics2) {
13307
- const prompt_tokens = (metrics2.prompt_tokens || 0) + (metrics2.prompt_cached_tokens || 0) + (metrics2.prompt_cache_creation_tokens || 0);
13308
- return {
13309
- ...metrics2,
13310
- prompt_tokens,
13311
- tokens: prompt_tokens + (metrics2.completion_tokens || 0)
13312
- };
13313
- }
13314
- function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens = 0) {
13315
- const cacheTokens = {};
13316
- if (cacheReadTokens > 0) {
13317
- cacheTokens.prompt_cached_tokens = cacheReadTokens;
13318
- }
13319
- if (cacheCreationTokens > 0) {
13320
- cacheTokens.prompt_cache_creation_tokens = cacheCreationTokens;
13321
- }
13322
- return cacheTokens;
13323
- }
13324
-
13325
- // src/wrappers/ai-sdk-shared/utils.ts
13306
+ // src/wrappers/ai-sdk/ai-sdk.ts
13326
13307
  init_logger();
13327
- function detectProviderFromResult(result) {
13328
- if (!_optionalChain([result, 'optionalAccess', _157 => _157.providerMetadata])) {
13329
- return void 0;
13330
- }
13331
- const keys = Object.keys(result.providerMetadata);
13332
- return _optionalChain([keys, 'optionalAccess', _158 => _158.at, 'call', _159 => _159(0)]);
13333
- }
13334
- function extractModelFromResult(result) {
13335
- if (_optionalChain([result, 'optionalAccess', _160 => _160.response, 'optionalAccess', _161 => _161.modelId])) {
13336
- return result.response.modelId;
13337
- }
13338
- if (_optionalChain([result, 'optionalAccess', _162 => _162.request, 'optionalAccess', _163 => _163.body, 'optionalAccess', _164 => _164.model])) {
13339
- return result.request.body.model;
13340
- }
13341
- return void 0;
13342
- }
13343
- function extractModelFromWrapGenerateCallback(model) {
13344
- return _optionalChain([model, 'optionalAccess', _165 => _165.modelId]);
13345
- }
13346
- function camelToSnake(str) {
13347
- return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
13348
- }
13349
- function extractModelParameters(params, excludeKeys) {
13350
- const modelParams = {};
13351
- for (const [key, value] of Object.entries(params)) {
13352
- if (value !== void 0 && !excludeKeys.has(key)) {
13353
- const snakeKey = camelToSnake(key);
13354
- modelParams[snakeKey] = value;
13355
- }
13356
- }
13357
- return modelParams;
13358
- }
13359
- function getNumberProperty(obj, key) {
13360
- if (!obj || typeof obj !== "object" || !(key in obj)) {
13361
- return void 0;
13362
- }
13363
- const value = Reflect.get(obj, key);
13364
- return typeof value === "number" ? value : void 0;
13365
- }
13366
- function normalizeUsageMetrics(usage, provider, providerMetadata) {
13367
- const metrics2 = {};
13368
- const inputTokens = getNumberProperty(usage, "inputTokens");
13369
- if (inputTokens !== void 0) {
13370
- metrics2.prompt_tokens = inputTokens;
13371
- }
13372
- const outputTokens = getNumberProperty(usage, "outputTokens");
13373
- if (outputTokens !== void 0) {
13374
- metrics2.completion_tokens = outputTokens;
13375
- }
13376
- const totalTokens = getNumberProperty(usage, "totalTokens");
13377
- if (totalTokens !== void 0) {
13378
- metrics2.tokens = totalTokens;
13379
- }
13380
- const reasoningTokens = getNumberProperty(usage, "reasoningTokens");
13381
- if (reasoningTokens !== void 0) {
13382
- metrics2.completion_reasoning_tokens = reasoningTokens;
13383
- }
13384
- const cachedInputTokens = getNumberProperty(usage, "cachedInputTokens");
13385
- if (cachedInputTokens !== void 0) {
13386
- metrics2.prompt_cached_tokens = cachedInputTokens;
13387
- }
13388
- if (provider === "anthropic") {
13389
- const anthropicMetadata = _optionalChain([providerMetadata, 'optionalAccess', _166 => _166.anthropic]);
13390
- if (anthropicMetadata) {
13391
- const cacheReadTokens = getNumberProperty(anthropicMetadata.usage, "cache_read_input_tokens") || 0;
13392
- const cacheCreationTokens = getNumberProperty(
13393
- anthropicMetadata.usage,
13394
- "cache_creation_input_tokens"
13395
- ) || 0;
13396
- const cacheTokens = extractAnthropicCacheTokens(
13397
- cacheReadTokens,
13398
- cacheCreationTokens
13399
- );
13400
- Object.assign(metrics2, cacheTokens);
13401
- Object.assign(metrics2, finalizeAnthropicTokens(metrics2));
13402
- }
13403
- }
13404
- return metrics2;
13405
- }
13406
- function normalizeFinishReason(reason) {
13407
- if (typeof reason !== "string") return void 0;
13408
- return reason.replace(/-/g, "_");
13409
- }
13410
- function extractToolCallsFromSteps(steps) {
13411
- const toolCalls = [];
13412
- if (!Array.isArray(steps)) return toolCalls;
13413
- let idx = 0;
13414
- for (const step of steps) {
13415
- const blocks = _optionalChain([step, 'optionalAccess', _167 => _167.content]);
13416
- if (!Array.isArray(blocks)) continue;
13417
- for (const block of blocks) {
13418
- if (block && typeof block === "object" && block.type === "tool-call") {
13419
- toolCalls.push({
13420
- id: block.toolCallId,
13421
- type: "function",
13422
- index: idx++,
13423
- function: {
13424
- name: block.toolName,
13425
- arguments: typeof block.input === "string" ? block.input : JSON.stringify(_nullishCoalesce(block.input, () => ( {})))
13426
- }
13427
- });
13428
- }
13429
- }
13430
- }
13431
- return toolCalls;
13432
- }
13433
- function buildAssistantOutputWithToolCalls(result, toolCalls) {
13434
- return [
13435
- {
13436
- index: 0,
13437
- logprobs: null,
13438
- finish_reason: _nullishCoalesce(normalizeFinishReason(_optionalChain([result, 'optionalAccess', _168 => _168.finishReason])), () => ( (toolCalls.length ? "tool_calls" : void 0))),
13439
- message: {
13440
- role: "assistant",
13441
- tool_calls: toolCalls.length > 0 ? toolCalls : void 0
13442
- }
13443
- }
13444
- ];
13445
- }
13446
- function extractToolCallsFromBlocks(blocks) {
13447
- if (!Array.isArray(blocks)) return [];
13448
- return extractToolCallsFromSteps([{ content: blocks }]);
13449
- }
13450
- function wrapTools(tools) {
13451
- if (!tools) return tools;
13452
- const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
13453
- if (Array.isArray(tools)) {
13454
- const arr = tools;
13455
- const out = arr.map((tool, idx) => {
13456
- if (tool != null && typeof tool === "object" && "execute" in tool && typeof tool.execute === "function") {
13457
- const name = inferName(tool, `tool[${idx}]`);
13458
- return {
13459
- ...tool,
13460
- execute: wrapTraced(tool.execute.bind(tool), {
13461
- name,
13462
- type: "tool"
13463
- })
13464
- };
13465
- }
13466
- return tool;
13467
- });
13468
- return out;
13469
- }
13470
- const wrappedTools = {};
13471
- for (const [key, tool] of Object.entries(tools)) {
13472
- if (tool != null && typeof tool === "object" && "execute" in tool && typeof tool.execute === "function") {
13473
- wrappedTools[key] = {
13474
- ...tool,
13475
- execute: wrapTraced(tool.execute.bind(tool), {
13476
- name: key,
13477
- type: "tool"
13478
- })
13479
- };
13480
- } else {
13481
- wrappedTools[key] = tool;
13482
- }
13483
- }
13484
- return wrappedTools;
13485
- }
13486
- function extractInput(params) {
13487
- return _nullishCoalesce(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _169 => _169.prompt]), () => ( _optionalChain([params, 'optionalAccess', _170 => _170.messages]))), () => ( _optionalChain([params, 'optionalAccess', _171 => _171.system])));
13488
- }
13308
+ init_util();
13489
13309
 
13490
13310
  // src/wrappers/attachment-utils.ts
13491
13311
  init_logger();
@@ -13550,7 +13370,7 @@ function processInputAttachments(input) {
13550
13370
  return input;
13551
13371
  }
13552
13372
  let attachmentIndex = 0;
13553
- const processContentPart = (part) => {
13373
+ const processContentPart2 = (part) => {
13554
13374
  if (!part || typeof part !== "object") {
13555
13375
  return part;
13556
13376
  }
@@ -13598,229 +13418,825 @@ function processInputAttachments(input) {
13598
13418
  }
13599
13419
  return part;
13600
13420
  };
13601
- const processMessage = (message) => {
13421
+ const processMessage2 = (message) => {
13602
13422
  if (!message || typeof message !== "object") {
13603
13423
  return message;
13604
13424
  }
13605
13425
  if (Array.isArray(message.content)) {
13606
13426
  return {
13607
13427
  ...message,
13608
- content: message.content.map(processContentPart)
13428
+ content: message.content.map(processContentPart2)
13609
13429
  };
13610
13430
  }
13611
13431
  return message;
13612
13432
  };
13613
13433
  if (Array.isArray(input)) {
13614
- return input.map(processMessage);
13434
+ return input.map(processMessage2);
13615
13435
  } else if (typeof input === "object" && input.content) {
13616
- return processMessage(input);
13436
+ return processMessage2(input);
13617
13437
  }
13618
13438
  return input;
13619
13439
  }
13620
13440
 
13621
- // src/wrappers/ai-sdk-5/middleware.ts
13622
- var V2_EXCLUDE_KEYS = /* @__PURE__ */ new Set([
13623
- "prompt",
13624
- // Already captured as input
13625
- "system",
13626
- // Already captured as input
13627
- "messages",
13628
- // Already captured as input
13629
- "model",
13630
- // Already captured in metadata.model
13631
- "providerOptions"
13632
- // Internal AI SDK configuration
13633
- ]);
13634
- function BraintrustMiddleware(config = {}) {
13635
- return {
13636
- wrapGenerate: async ({
13637
- doGenerate,
13638
- params,
13639
- model: modelFromWrapGenerate
13640
- }) => {
13641
- const rawInput = extractInput(params);
13642
- const processedInput = processInputAttachments(rawInput);
13643
- const spanArgs = {
13644
- name: _optionalChain([config, 'access', _172 => _172.spanInfo, 'optionalAccess', _173 => _173.name]) || "ai-sdk.doGenerate",
13441
+ // src/wrappers/ai-sdk/ai-sdk.ts
13442
+ var _zodtojsonschema = require('zod-to-json-schema');
13443
+ var DENY_OUTPUT_PATHS = [
13444
+ // v3
13445
+ "roundtrips[].request.body",
13446
+ "roundtrips[].response.headers",
13447
+ "rawResponse.headers",
13448
+ "responseMessages",
13449
+ // v5
13450
+ "request.body",
13451
+ "response.body",
13452
+ "response.headers",
13453
+ "steps[].request.body",
13454
+ "steps[].response.body",
13455
+ "steps[].response.headers"
13456
+ ];
13457
+ function wrapAISDK(aiSDK, options = {}) {
13458
+ return new Proxy(aiSDK, {
13459
+ get(target, prop, receiver) {
13460
+ const original = Reflect.get(target, prop, receiver);
13461
+ switch (prop) {
13462
+ case "generateText":
13463
+ return wrapGenerateText(original, options);
13464
+ case "streamText":
13465
+ return wrapStreamText(original, options);
13466
+ case "generateObject":
13467
+ return wrapGenerateObject(original, options);
13468
+ case "streamObject":
13469
+ return wrapStreamObject(original, options);
13470
+ }
13471
+ return original;
13472
+ }
13473
+ });
13474
+ }
13475
+ var wrapGenerateText = (generateText, options = {}) => {
13476
+ return async function wrappedGenerateText(params) {
13477
+ return traced(
13478
+ async (span) => {
13479
+ const result = await generateText({
13480
+ ...params,
13481
+ tools: wrapTools(params.tools)
13482
+ });
13483
+ span.log({
13484
+ output: await processOutput(result, options.denyOutputPaths),
13485
+ metrics: extractTokenMetrics(result)
13486
+ });
13487
+ return result;
13488
+ },
13489
+ {
13490
+ name: "generateText",
13645
13491
  spanAttributes: {
13646
- type: "llm" /* LLM */,
13647
- ..._optionalChain([config, 'access', _174 => _174.spanInfo, 'optionalAccess', _175 => _175.spanAttributes]) || {}
13492
+ type: "llm" /* LLM */
13648
13493
  },
13649
13494
  event: {
13650
- input: processedInput,
13495
+ input: processInputAttachments2(params),
13651
13496
  metadata: {
13652
- ...extractModelParameters(params, V2_EXCLUDE_KEYS),
13653
- ..._optionalChain([config, 'access', _176 => _176.spanInfo, 'optionalAccess', _177 => _177.metadata]) || {}
13654
- }
13655
- }
13656
- };
13657
- const span = startSpan(spanArgs);
13658
- try {
13659
- const result = await doGenerate();
13660
- const metadata = {};
13661
- const provider = detectProviderFromResult(result);
13662
- if (provider !== void 0) {
13663
- metadata.provider = provider;
13664
- }
13665
- if (result.finishReason !== void 0) {
13666
- metadata.finish_reason = result.finishReason;
13667
- }
13668
- const model = extractModelFromResult(result);
13669
- if (model !== void 0) {
13670
- metadata.model = model;
13671
- } else if (modelFromWrapGenerate) {
13672
- const modelId = extractModelFromWrapGenerateCallback(
13673
- modelFromWrapGenerate
13674
- );
13675
- if (modelId) {
13676
- metadata.model = modelId;
13497
+ model: serializeModel(params.model),
13498
+ braintrust: {
13499
+ integration_name: "ai-sdk",
13500
+ sdk_language: "typescript"
13501
+ }
13677
13502
  }
13678
13503
  }
13679
- let toolCalls = extractToolCallsFromSteps(_optionalChain([result, 'optionalAccess', _178 => _178.steps]));
13680
- if (!toolCalls || toolCalls.length === 0) {
13681
- toolCalls = extractToolCallsFromBlocks(_optionalChain([result, 'optionalAccess', _179 => _179.content]));
13682
- }
13504
+ }
13505
+ );
13506
+ };
13507
+ };
13508
+ var wrapGenerateObject = (generateObject, options = {}) => {
13509
+ return async function wrappedGenerateObject(params) {
13510
+ return traced(
13511
+ async (span) => {
13512
+ const result = await generateObject({
13513
+ ...params,
13514
+ tools: wrapTools(params.tools)
13515
+ });
13683
13516
  span.log({
13684
- output: toolCalls.length > 0 ? buildAssistantOutputWithToolCalls(result, toolCalls) : _optionalChain([result, 'optionalAccess', _180 => _180.content]),
13685
- metadata,
13686
- metrics: normalizeUsageMetrics(
13687
- result.usage,
13688
- provider,
13689
- result.providerMetadata
13690
- )
13517
+ output: processOutput(result, options.denyOutputPaths),
13518
+ metrics: extractTokenMetrics(result)
13691
13519
  });
13692
13520
  return result;
13693
- } catch (error2) {
13694
- span.log({
13695
- error: error2 instanceof Error ? error2.message : String(error2)
13696
- });
13697
- throw error2;
13698
- } finally {
13699
- span.end();
13700
- }
13701
- },
13702
- wrapStream: async ({ doStream, params }) => {
13703
- const rawInput = extractInput(params);
13704
- const processedInput = processInputAttachments(rawInput);
13705
- const spanArgs = {
13706
- name: _optionalChain([config, 'access', _181 => _181.spanInfo, 'optionalAccess', _182 => _182.name]) || "ai-sdk.doStream",
13521
+ },
13522
+ {
13523
+ name: "generateObject",
13707
13524
  spanAttributes: {
13708
- type: "llm" /* LLM */,
13709
- ..._optionalChain([config, 'access', _183 => _183.spanInfo, 'optionalAccess', _184 => _184.spanAttributes]) || {}
13525
+ type: "llm" /* LLM */
13710
13526
  },
13711
13527
  event: {
13712
- input: processedInput,
13528
+ input: processInputAttachments2(params),
13713
13529
  metadata: {
13714
- ...extractModelParameters(params, V2_EXCLUDE_KEYS),
13715
- ..._optionalChain([config, 'access', _185 => _185.spanInfo, 'optionalAccess', _186 => _186.metadata]) || {}
13530
+ model: serializeModel(params.model),
13531
+ braintrust: {
13532
+ integration_name: "ai-sdk",
13533
+ sdk_language: "typescript"
13534
+ }
13716
13535
  }
13717
13536
  }
13718
- };
13719
- const span = startSpan(spanArgs);
13720
- try {
13721
- const { stream, ...rest } = await doStream();
13722
- const textChunks = [];
13723
- const toolBlocks = [];
13724
- let finalUsage = {};
13725
- let finalFinishReason = void 0;
13726
- let providerMetadata = {};
13727
- const transformStream = new TransformStream({
13728
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
13729
- transform(chunk, controller) {
13730
- try {
13731
- if (chunk.type === "text-delta" && chunk.delta) {
13732
- textChunks.push(chunk.delta);
13733
- }
13734
- if (chunk.type === "tool-call" || chunk.type === "tool-result") {
13735
- toolBlocks.push(chunk);
13736
- }
13737
- if (chunk.type === "finish") {
13738
- finalFinishReason = chunk.finishReason;
13739
- finalUsage = chunk.usage || {};
13740
- providerMetadata = chunk.providerMetadata || {};
13741
- }
13742
- controller.enqueue(chunk);
13743
- } catch (error2) {
13537
+ }
13538
+ );
13539
+ };
13540
+ };
13541
+ var wrapStreamText = (streamText, options = {}) => {
13542
+ return function wrappedStreamText(params) {
13543
+ const span = startSpan({
13544
+ name: "streamText",
13545
+ spanAttributes: {
13546
+ type: "llm" /* LLM */
13547
+ },
13548
+ event: {
13549
+ input: processInputAttachments2(params),
13550
+ metadata: {
13551
+ model: serializeModel(params.model),
13552
+ braintrust: {
13553
+ integration_name: "ai-sdk",
13554
+ sdk_language: "typescript"
13555
+ }
13556
+ }
13557
+ }
13558
+ });
13559
+ try {
13560
+ const startTime = Date.now();
13561
+ let receivedFirst = false;
13562
+ const result = withCurrent(
13563
+ span,
13564
+ () => streamText({
13565
+ ...params,
13566
+ tools: wrapTools(params.tools),
13567
+ onChunk: (chunk) => {
13568
+ if (!receivedFirst) {
13569
+ receivedFirst = true;
13744
13570
  span.log({
13745
- error: error2 instanceof Error ? error2.message : String(error2)
13571
+ metrics: {
13572
+ time_to_first_token: (Date.now() - startTime) / 1e3
13573
+ }
13746
13574
  });
13747
- span.end();
13748
- controller.error(error2);
13749
13575
  }
13576
+ _optionalChain([params, 'access', _157 => _157.onChunk, 'optionalCall', _158 => _158(chunk)]);
13750
13577
  },
13751
- flush() {
13752
- try {
13753
- const generatedText = textChunks.join("");
13754
- let output = generatedText ? [{ type: "text", text: generatedText }] : [];
13755
- const resultForDetection = {
13756
- providerMetadata,
13757
- response: rest.response,
13758
- ...rest,
13759
- finishReason: finalFinishReason
13760
- };
13761
- const metadata = {};
13762
- const provider = detectProviderFromResult(resultForDetection);
13763
- if (provider !== void 0) {
13764
- metadata.provider = provider;
13765
- }
13766
- if (finalFinishReason !== void 0) {
13767
- metadata.finish_reason = finalFinishReason;
13768
- }
13769
- const model = extractModelFromResult(resultForDetection);
13770
- if (model !== void 0) {
13771
- metadata.model = model;
13772
- }
13773
- if (toolBlocks.length > 0) {
13774
- const toolCalls = extractToolCallsFromSteps([
13775
- { content: toolBlocks }
13776
- ]);
13777
- if (toolCalls.length > 0) {
13778
- output = buildAssistantOutputWithToolCalls(
13779
- resultForDetection,
13780
- toolCalls
13781
- );
13782
- }
13783
- }
13784
- span.log({
13785
- output,
13786
- metadata,
13787
- metrics: normalizeUsageMetrics(
13788
- finalUsage,
13789
- provider,
13790
- providerMetadata
13791
- )
13792
- });
13793
- span.end();
13794
- } catch (error2) {
13578
+ onFinish: async (event) => {
13579
+ _optionalChain([params, 'access', _159 => _159.onFinish, 'optionalCall', _160 => _160(event)]);
13580
+ span.log({
13581
+ output: await processOutput(event, options.denyOutputPaths),
13582
+ metrics: extractTokenMetrics(event)
13583
+ });
13584
+ span.end();
13585
+ },
13586
+ onError: async (err) => {
13587
+ _optionalChain([params, 'access', _161 => _161.onError, 'optionalCall', _162 => _162(err)]);
13588
+ span.log({
13589
+ error: serializeError(err)
13590
+ });
13591
+ span.end();
13592
+ }
13593
+ })
13594
+ );
13595
+ const trackFirstToken = () => {
13596
+ if (!receivedFirst) {
13597
+ receivedFirst = true;
13598
+ span.log({
13599
+ metrics: {
13600
+ time_to_first_token: (Date.now() - startTime) / 1e3
13601
+ }
13602
+ });
13603
+ }
13604
+ };
13605
+ if (result && result.baseStream) {
13606
+ const [stream1, stream2] = result.baseStream.tee();
13607
+ result.baseStream = stream2;
13608
+ stream1.pipeThrough(
13609
+ new TransformStream({
13610
+ transform(chunk, controller) {
13611
+ trackFirstToken();
13612
+ controller.enqueue(chunk);
13613
+ }
13614
+ })
13615
+ ).pipeTo(
13616
+ new WritableStream({
13617
+ write() {
13618
+ }
13619
+ })
13620
+ ).catch(() => {
13621
+ });
13622
+ }
13623
+ return result;
13624
+ } catch (error2) {
13625
+ span.log({
13626
+ error: serializeError(error2)
13627
+ });
13628
+ span.end();
13629
+ throw error2;
13630
+ }
13631
+ };
13632
+ };
13633
+ var wrapStreamObject = (streamObject, options = {}) => {
13634
+ return function wrappedStreamObject(params) {
13635
+ const span = startSpan({
13636
+ name: "streamObject",
13637
+ spanAttributes: {
13638
+ type: "llm" /* LLM */
13639
+ },
13640
+ event: {
13641
+ input: processInputAttachments2(params),
13642
+ metadata: {
13643
+ model: serializeModel(params.model),
13644
+ braintrust: {
13645
+ integration_name: "ai-sdk",
13646
+ sdk_language: "typescript"
13647
+ }
13648
+ }
13649
+ }
13650
+ });
13651
+ try {
13652
+ const startTime = Date.now();
13653
+ let receivedFirst = false;
13654
+ const result = withCurrent(
13655
+ span,
13656
+ () => streamObject({
13657
+ ...params,
13658
+ tools: wrapTools(params.tools),
13659
+ onChunk: (chunk) => {
13660
+ if (!receivedFirst) {
13661
+ receivedFirst = true;
13795
13662
  span.log({
13796
- error: error2 instanceof Error ? error2.message : String(error2)
13663
+ metrics: {
13664
+ time_to_first_token: (Date.now() - startTime) / 1e3
13665
+ }
13797
13666
  });
13798
- span.end();
13799
- throw error2;
13800
13667
  }
13668
+ _optionalChain([params, 'access', _163 => _163.onChunk, 'optionalCall', _164 => _164(chunk)]);
13669
+ },
13670
+ onFinish: async (event) => {
13671
+ _optionalChain([params, 'access', _165 => _165.onFinish, 'optionalCall', _166 => _166(event)]);
13672
+ span.log({
13673
+ output: await processOutput(event, options.denyOutputPaths),
13674
+ metrics: extractTokenMetrics(event)
13675
+ });
13676
+ span.end();
13677
+ },
13678
+ onError: async (err) => {
13679
+ _optionalChain([params, 'access', _167 => _167.onError, 'optionalCall', _168 => _168(err)]);
13680
+ span.log({
13681
+ error: serializeError(err)
13682
+ });
13683
+ span.end();
13801
13684
  }
13685
+ })
13686
+ );
13687
+ const trackFirstToken = () => {
13688
+ if (!receivedFirst) {
13689
+ receivedFirst = true;
13690
+ span.log({
13691
+ metrics: {
13692
+ time_to_first_token: (Date.now() - startTime) / 1e3
13693
+ }
13694
+ });
13695
+ }
13696
+ };
13697
+ if (result && result.baseStream) {
13698
+ const [stream1, stream2] = result.baseStream.tee();
13699
+ result.baseStream = stream2;
13700
+ stream1.pipeThrough(
13701
+ new TransformStream({
13702
+ transform(chunk, controller) {
13703
+ trackFirstToken();
13704
+ controller.enqueue(chunk);
13705
+ }
13706
+ })
13707
+ ).pipeTo(
13708
+ new WritableStream({
13709
+ write() {
13710
+ }
13711
+ })
13712
+ ).catch(() => {
13802
13713
  });
13714
+ }
13715
+ return result;
13716
+ } catch (error2) {
13717
+ span.log({
13718
+ error: serializeError(error2)
13719
+ });
13720
+ span.end();
13721
+ throw error2;
13722
+ }
13723
+ };
13724
+ };
13725
+ var wrapTools = (tools) => {
13726
+ if (!tools) return tools;
13727
+ const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
13728
+ if (Array.isArray(tools)) {
13729
+ return tools.map((tool, idx) => {
13730
+ const name = inferName(tool, `tool[${idx}]`);
13731
+ return wrapToolExecute(tool, name);
13732
+ });
13733
+ }
13734
+ const wrappedTools = {};
13735
+ for (const [key, tool] of Object.entries(tools)) {
13736
+ wrappedTools[key] = wrapToolExecute(tool, key);
13737
+ }
13738
+ return wrappedTools;
13739
+ };
13740
+ var wrapToolExecute = (tool, name) => {
13741
+ if (tool != null && typeof tool === "object" && "execute" in tool && typeof tool.execute === "function") {
13742
+ const originalExecute = tool.execute;
13743
+ return new Proxy(tool, {
13744
+ get(target, prop) {
13745
+ if (prop === "execute") {
13746
+ return (...args) => traced(
13747
+ async (span) => {
13748
+ span.log({ input: args.length === 1 ? args[0] : args });
13749
+ const result = await originalExecute.apply(target, args);
13750
+ span.log({ output: result });
13751
+ return result;
13752
+ },
13753
+ {
13754
+ name,
13755
+ spanAttributes: {
13756
+ type: "tool" /* TOOL */
13757
+ }
13758
+ }
13759
+ );
13760
+ }
13761
+ return target[prop];
13762
+ },
13763
+ // Implement additional traps for full transparency
13764
+ has(target, prop) {
13765
+ return prop in target;
13766
+ },
13767
+ ownKeys(target) {
13768
+ return Reflect.ownKeys(target);
13769
+ },
13770
+ getOwnPropertyDescriptor(target, prop) {
13771
+ return Object.getOwnPropertyDescriptor(target, prop);
13772
+ },
13773
+ set(target, prop, value) {
13774
+ target[prop] = value;
13775
+ return true;
13776
+ },
13777
+ deleteProperty(target, prop) {
13778
+ delete target[prop];
13779
+ return true;
13780
+ },
13781
+ defineProperty(target, prop, descriptor) {
13782
+ Object.defineProperty(target, prop, descriptor);
13783
+ return true;
13784
+ },
13785
+ getPrototypeOf(target) {
13786
+ return Object.getPrototypeOf(target);
13787
+ },
13788
+ setPrototypeOf(target, proto) {
13789
+ Object.setPrototypeOf(target, proto);
13790
+ return true;
13791
+ },
13792
+ isExtensible(target) {
13793
+ return Object.isExtensible(target);
13794
+ },
13795
+ preventExtensions(target) {
13796
+ Object.preventExtensions(target);
13797
+ return true;
13798
+ }
13799
+ });
13800
+ }
13801
+ return tool;
13802
+ };
13803
+ var serializeError = (error2) => {
13804
+ if (error2 instanceof Error) {
13805
+ return error2;
13806
+ }
13807
+ if (typeof error2 === "object" && error2 !== null) {
13808
+ try {
13809
+ return JSON.stringify(error2);
13810
+ } catch (e11) {
13811
+ }
13812
+ }
13813
+ return String(error2);
13814
+ };
13815
+ var serializeModel = (model) => {
13816
+ return typeof model === "string" ? model : _optionalChain([model, 'optionalAccess', _169 => _169.modelId]);
13817
+ };
13818
+ var isZodSchema = (value) => {
13819
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
13820
+ };
13821
+ var serializeZodSchema = (schema) => {
13822
+ try {
13823
+ return _zodtojsonschema.zodToJsonSchema.call(void 0, schema);
13824
+ } catch (e12) {
13825
+ return {
13826
+ type: "object",
13827
+ description: "Zod schema (conversion failed)"
13828
+ };
13829
+ }
13830
+ };
13831
+ var processTools = (tools) => {
13832
+ if (!tools || typeof tools !== "object") return tools;
13833
+ if (Array.isArray(tools)) {
13834
+ return tools.map(processTool);
13835
+ }
13836
+ const processed = {};
13837
+ for (const [key, tool] of Object.entries(tools)) {
13838
+ processed[key] = processTool(tool);
13839
+ }
13840
+ return processed;
13841
+ };
13842
+ var processTool = (tool) => {
13843
+ if (!tool || typeof tool !== "object") return tool;
13844
+ const processed = { ...tool };
13845
+ if (isZodSchema(processed.inputSchema)) {
13846
+ processed.inputSchema = serializeZodSchema(processed.inputSchema);
13847
+ }
13848
+ if (isZodSchema(processed.parameters)) {
13849
+ processed.parameters = serializeZodSchema(processed.parameters);
13850
+ }
13851
+ if ("execute" in processed) {
13852
+ processed.execute = "[Function]";
13853
+ }
13854
+ if ("render" in processed) {
13855
+ processed.render = "[Function]";
13856
+ }
13857
+ return processed;
13858
+ };
13859
+ var processInputAttachments2 = (input) => {
13860
+ if (!input) return input;
13861
+ const processed = { ...input };
13862
+ if (input.messages && Array.isArray(input.messages)) {
13863
+ processed.messages = input.messages.map(processMessage);
13864
+ }
13865
+ if (input.prompt && typeof input.prompt === "object" && !Array.isArray(input.prompt)) {
13866
+ processed.prompt = processPromptContent(input.prompt);
13867
+ }
13868
+ if (input.tools) {
13869
+ processed.tools = processTools(input.tools);
13870
+ }
13871
+ return processed;
13872
+ };
13873
+ var processMessage = (message) => {
13874
+ if (!message || typeof message !== "object") return message;
13875
+ if (Array.isArray(message.content)) {
13876
+ return {
13877
+ ...message,
13878
+ content: message.content.map(processContentPart)
13879
+ };
13880
+ }
13881
+ if (typeof message.content === "object" && message.content !== null) {
13882
+ return {
13883
+ ...message,
13884
+ content: processContentPart(message.content)
13885
+ };
13886
+ }
13887
+ return message;
13888
+ };
13889
+ var processPromptContent = (prompt) => {
13890
+ if (Array.isArray(prompt)) {
13891
+ return prompt.map(processContentPart);
13892
+ }
13893
+ if (prompt.content) {
13894
+ if (Array.isArray(prompt.content)) {
13895
+ return {
13896
+ ...prompt,
13897
+ content: prompt.content.map(processContentPart)
13898
+ };
13899
+ } else if (typeof prompt.content === "object") {
13900
+ return {
13901
+ ...prompt,
13902
+ content: processContentPart(prompt.content)
13903
+ };
13904
+ }
13905
+ }
13906
+ return prompt;
13907
+ };
13908
+ var processContentPart = (part) => {
13909
+ if (!part || typeof part !== "object") return part;
13910
+ try {
13911
+ if (part.type === "image" && part.image) {
13912
+ const imageAttachment = convertImageToAttachment(
13913
+ part.image,
13914
+ part.mimeType || part.mediaType
13915
+ );
13916
+ if (imageAttachment) {
13803
13917
  return {
13804
- stream: stream.pipeThrough(transformStream),
13805
- ...rest
13918
+ ...part,
13919
+ image: imageAttachment
13806
13920
  };
13807
- } catch (error2) {
13808
- span.log({
13809
- error: error2 instanceof Error ? error2.message : String(error2)
13921
+ }
13922
+ }
13923
+ if (part.type === "file" && part.data && (part.mimeType || part.mediaType)) {
13924
+ const fileAttachment = convertDataToAttachment(
13925
+ part.data,
13926
+ part.mimeType || part.mediaType,
13927
+ part.name || part.filename
13928
+ );
13929
+ if (fileAttachment) {
13930
+ return {
13931
+ ...part,
13932
+ data: fileAttachment
13933
+ };
13934
+ }
13935
+ }
13936
+ if (part.type === "image_url" && part.image_url) {
13937
+ if (typeof part.image_url === "object" && part.image_url.url) {
13938
+ const imageAttachment = convertImageToAttachment(part.image_url.url);
13939
+ if (imageAttachment) {
13940
+ return {
13941
+ ...part,
13942
+ image_url: {
13943
+ ...part.image_url,
13944
+ url: imageAttachment
13945
+ }
13946
+ };
13947
+ }
13948
+ }
13949
+ }
13950
+ } catch (error2) {
13951
+ console.warn("Error processing content part:", error2);
13952
+ }
13953
+ return part;
13954
+ };
13955
+ var convertImageToAttachment = (image, explicitMimeType) => {
13956
+ try {
13957
+ if (typeof image === "string" && image.startsWith("data:")) {
13958
+ const [mimeTypeSection, base64Data] = image.split(",");
13959
+ const mimeType = _optionalChain([mimeTypeSection, 'access', _170 => _170.match, 'call', _171 => _171(/data:(.*?);/), 'optionalAccess', _172 => _172[1]]);
13960
+ if (mimeType && base64Data) {
13961
+ const blob = convertDataToBlob(base64Data, mimeType);
13962
+ if (blob) {
13963
+ return new Attachment({
13964
+ data: blob,
13965
+ filename: `image.${getExtensionFromMediaType(mimeType)}`,
13966
+ contentType: mimeType
13967
+ });
13968
+ }
13969
+ }
13970
+ }
13971
+ if (explicitMimeType) {
13972
+ if (image instanceof Uint8Array) {
13973
+ return new Attachment({
13974
+ data: new Blob([image], { type: explicitMimeType }),
13975
+ filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
13976
+ contentType: explicitMimeType
13977
+ });
13978
+ }
13979
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(image)) {
13980
+ return new Attachment({
13981
+ data: new Blob([image], { type: explicitMimeType }),
13982
+ filename: `image.${getExtensionFromMediaType(explicitMimeType)}`,
13983
+ contentType: explicitMimeType
13810
13984
  });
13811
- span.end();
13812
- throw error2;
13813
13985
  }
13814
13986
  }
13815
- };
13987
+ if (image instanceof Blob && image.type) {
13988
+ return new Attachment({
13989
+ data: image,
13990
+ filename: `image.${getExtensionFromMediaType(image.type)}`,
13991
+ contentType: image.type
13992
+ });
13993
+ }
13994
+ if (image instanceof Attachment) {
13995
+ return image;
13996
+ }
13997
+ } catch (error2) {
13998
+ console.warn("Error converting image to attachment:", error2);
13999
+ }
14000
+ return null;
14001
+ };
14002
+ var convertDataToAttachment = (data, mimeType, filename) => {
14003
+ if (!mimeType) return null;
14004
+ try {
14005
+ let blob = null;
14006
+ if (typeof data === "string" && data.startsWith("data:")) {
14007
+ const [, base64Data] = data.split(",");
14008
+ if (base64Data) {
14009
+ blob = convertDataToBlob(base64Data, mimeType);
14010
+ }
14011
+ } else if (typeof data === "string" && data.length > 0) {
14012
+ blob = convertDataToBlob(data, mimeType);
14013
+ } else if (data instanceof Uint8Array) {
14014
+ blob = new Blob([data], { type: mimeType });
14015
+ } else if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) {
14016
+ blob = new Blob([data], { type: mimeType });
14017
+ } else if (data instanceof Blob) {
14018
+ blob = data;
14019
+ }
14020
+ if (blob) {
14021
+ return new Attachment({
14022
+ data: blob,
14023
+ filename: filename || `file.${getExtensionFromMediaType(mimeType)}`,
14024
+ contentType: mimeType
14025
+ });
14026
+ }
14027
+ } catch (error2) {
14028
+ console.warn("Error converting data to attachment:", error2);
14029
+ }
14030
+ return null;
14031
+ };
14032
+ var extractGetterValues = (obj) => {
14033
+ const getterValues = {};
14034
+ const getterNames = [
14035
+ "text",
14036
+ "finishReason",
14037
+ "usage",
14038
+ "toolCalls",
14039
+ "toolResults",
14040
+ "warnings",
14041
+ "experimental_providerMetadata",
14042
+ "rawResponse",
14043
+ "response"
14044
+ ];
14045
+ for (const name of getterNames) {
14046
+ try {
14047
+ if (obj && name in obj && typeof obj[name] !== "function") {
14048
+ getterValues[name] = obj[name];
14049
+ }
14050
+ } catch (e13) {
14051
+ }
14052
+ }
14053
+ return getterValues;
14054
+ };
14055
+ var processOutput = async (output, denyOutputPaths) => {
14056
+ const getterValues = extractGetterValues(output);
14057
+ const processed = await processOutputAttachments(output);
14058
+ const merged = { ...processed, ...getterValues };
14059
+ return omit(merged, _nullishCoalesce(denyOutputPaths, () => ( DENY_OUTPUT_PATHS)));
14060
+ };
14061
+ var processOutputAttachments = async (output) => {
14062
+ try {
14063
+ return await doProcessOutputAttachments(output);
14064
+ } catch (error2) {
14065
+ console.error("Error processing output attachments:", error2);
14066
+ return output;
14067
+ }
14068
+ };
14069
+ var doProcessOutputAttachments = async (output) => {
14070
+ if (!output || !("files" in output)) {
14071
+ return output;
14072
+ }
14073
+ if (output.files && typeof output.files.then === "function") {
14074
+ return {
14075
+ ...output,
14076
+ files: output.files.then(async (files) => {
14077
+ if (!files || !Array.isArray(files) || files.length === 0) {
14078
+ return files;
14079
+ }
14080
+ return files.map(convertFileToAttachment);
14081
+ })
14082
+ };
14083
+ } else if (output.files && Array.isArray(output.files) && output.files.length > 0) {
14084
+ return {
14085
+ ...output,
14086
+ files: output.files.map(convertFileToAttachment)
14087
+ };
14088
+ }
14089
+ return output;
14090
+ };
14091
+ var convertFileToAttachment = (file, index) => {
14092
+ try {
14093
+ const mediaType = file.mediaType || "application/octet-stream";
14094
+ const filename = `generated_file_${index}.${getExtensionFromMediaType(mediaType)}`;
14095
+ let blob = null;
14096
+ if (file.base64) {
14097
+ blob = convertDataToBlob(file.base64, mediaType);
14098
+ } else if (file.uint8Array) {
14099
+ blob = new Blob([file.uint8Array], { type: mediaType });
14100
+ }
14101
+ if (!blob) {
14102
+ console.warn(`Failed to convert file at index ${index} to Blob`);
14103
+ return file;
14104
+ }
14105
+ return new Attachment({
14106
+ data: blob,
14107
+ filename,
14108
+ contentType: mediaType
14109
+ });
14110
+ } catch (error2) {
14111
+ console.warn(`Error processing file at index ${index}:`, error2);
14112
+ return file;
14113
+ }
14114
+ };
14115
+ function extractTokenMetrics(result) {
14116
+ const metrics2 = {};
14117
+ const usage = _optionalChain([result, 'optionalAccess', _173 => _173.usage]);
14118
+ if (!usage) {
14119
+ return metrics2;
14120
+ }
14121
+ if (usage.inputTokens !== void 0) {
14122
+ metrics2.prompt_tokens = usage.inputTokens;
14123
+ } else if (usage.promptTokens !== void 0) {
14124
+ metrics2.prompt_tokens = usage.promptTokens;
14125
+ } else if (usage.prompt_tokens !== void 0) {
14126
+ metrics2.prompt_tokens = usage.prompt_tokens;
14127
+ }
14128
+ if (usage.outputTokens !== void 0) {
14129
+ metrics2.completion_tokens = usage.outputTokens;
14130
+ } else if (usage.completionTokens !== void 0) {
14131
+ metrics2.completion_tokens = usage.completionTokens;
14132
+ } else if (usage.completion_tokens !== void 0) {
14133
+ metrics2.completion_tokens = usage.completion_tokens;
14134
+ }
14135
+ if (usage.totalTokens !== void 0) {
14136
+ metrics2.tokens = usage.totalTokens;
14137
+ } else if (usage.tokens !== void 0) {
14138
+ metrics2.tokens = usage.tokens;
14139
+ } else if (usage.total_tokens !== void 0) {
14140
+ metrics2.tokens = usage.total_tokens;
14141
+ }
14142
+ if (usage.cachedInputTokens !== void 0 || usage.promptCachedTokens !== void 0 || usage.prompt_cached_tokens !== void 0) {
14143
+ metrics2.prompt_cached_tokens = usage.cachedInputTokens || usage.promptCachedTokens || usage.prompt_cached_tokens;
14144
+ }
14145
+ if (usage.promptCacheCreationTokens !== void 0 || usage.prompt_cache_creation_tokens !== void 0) {
14146
+ metrics2.prompt_cache_creation_tokens = usage.promptCacheCreationTokens || usage.prompt_cache_creation_tokens;
14147
+ }
14148
+ if (usage.promptReasoningTokens !== void 0 || usage.prompt_reasoning_tokens !== void 0) {
14149
+ metrics2.prompt_reasoning_tokens = usage.promptReasoningTokens || usage.prompt_reasoning_tokens;
14150
+ }
14151
+ if (usage.completionCachedTokens !== void 0 || usage.completion_cached_tokens !== void 0) {
14152
+ metrics2.completion_cached_tokens = usage.completionCachedTokens || usage.completion_cached_tokens;
14153
+ }
14154
+ if (usage.reasoningTokens !== void 0 || usage.completionReasoningTokens !== void 0 || usage.completion_reasoning_tokens !== void 0 || usage.reasoning_tokens !== void 0 || usage.thinkingTokens !== void 0 || usage.thinking_tokens !== void 0) {
14155
+ const reasoningTokenCount = usage.reasoningTokens || usage.completionReasoningTokens || usage.completion_reasoning_tokens || usage.reasoning_tokens || usage.thinkingTokens || usage.thinking_tokens;
14156
+ metrics2.completion_reasoning_tokens = reasoningTokenCount;
14157
+ metrics2.reasoning_tokens = reasoningTokenCount;
14158
+ }
14159
+ if (usage.completionAudioTokens !== void 0 || usage.completion_audio_tokens !== void 0) {
14160
+ metrics2.completion_audio_tokens = usage.completionAudioTokens || usage.completion_audio_tokens;
14161
+ }
14162
+ return metrics2;
13816
14163
  }
14164
+ var deepCopy = (obj) => {
14165
+ return JSON.parse(JSON.stringify(obj));
14166
+ };
14167
+ var parsePath = (path3) => {
14168
+ const keys = [];
14169
+ let current = "";
14170
+ for (let i = 0; i < path3.length; i++) {
14171
+ const char = path3[i];
14172
+ if (char === ".") {
14173
+ if (current) {
14174
+ keys.push(current);
14175
+ current = "";
14176
+ }
14177
+ } else if (char === "[") {
14178
+ if (current) {
14179
+ keys.push(current);
14180
+ current = "";
14181
+ }
14182
+ let bracketContent = "";
14183
+ i++;
14184
+ while (i < path3.length && path3[i] !== "]") {
14185
+ bracketContent += path3[i];
14186
+ i++;
14187
+ }
14188
+ if (bracketContent === "") {
14189
+ keys.push("[]");
14190
+ } else {
14191
+ const index = parseInt(bracketContent, 10);
14192
+ keys.push(isNaN(index) ? bracketContent : index);
14193
+ }
14194
+ } else {
14195
+ current += char;
14196
+ }
14197
+ }
14198
+ if (current) {
14199
+ keys.push(current);
14200
+ }
14201
+ return keys;
14202
+ };
14203
+ var omitAtPath = (obj, keys) => {
14204
+ if (keys.length === 0) return;
14205
+ const firstKey = keys[0];
14206
+ const remainingKeys = keys.slice(1);
14207
+ if (firstKey === "[]") {
14208
+ if (Array.isArray(obj)) {
14209
+ obj.forEach((item) => {
14210
+ if (remainingKeys.length > 0) {
14211
+ omitAtPath(item, remainingKeys);
14212
+ }
14213
+ });
14214
+ }
14215
+ } else if (remainingKeys.length === 0) {
14216
+ if (obj && typeof obj === "object" && firstKey in obj) {
14217
+ obj[firstKey] = "<omitted>";
14218
+ }
14219
+ } else {
14220
+ if (obj && typeof obj === "object" && firstKey in obj) {
14221
+ omitAtPath(obj[firstKey], remainingKeys);
14222
+ }
14223
+ }
14224
+ };
14225
+ var omit = (obj, paths) => {
14226
+ const result = deepCopy(obj);
14227
+ for (const path3 of paths) {
14228
+ const keys = parsePath(path3);
14229
+ omitAtPath(result, keys);
14230
+ }
14231
+ return result;
14232
+ };
13817
14233
 
13818
- // src/wrappers/ai-sdk-4/ai-sdk.ts
14234
+ // src/wrappers/ai-sdk/deprecated/wrapAISDKModel.ts
13819
14235
  init_logger();
13820
14236
  init_util2();
13821
14237
  function wrapAISDKModel(model) {
13822
14238
  const m = model;
13823
- if (_optionalChain([m, 'optionalAccess', _187 => _187.specificationVersion]) === "v1" && typeof _optionalChain([m, 'optionalAccess', _188 => _188.provider]) === "string" && typeof _optionalChain([m, 'optionalAccess', _189 => _189.modelId]) === "string") {
14239
+ if (_optionalChain([m, 'optionalAccess', _174 => _174.specificationVersion]) === "v1" && typeof _optionalChain([m, 'optionalAccess', _175 => _175.provider]) === "string" && typeof _optionalChain([m, 'optionalAccess', _176 => _176.modelId]) === "string") {
13824
14240
  return new BraintrustLanguageModelWrapper(m);
13825
14241
  } else {
13826
14242
  console.warn("Unsupported AI SDK model. Not wrapping.");
@@ -13877,10 +14293,10 @@ var BraintrustLanguageModelWrapper = class {
13877
14293
  metrics: {
13878
14294
  time_to_first_token: getCurrentUnixTimestamp() - startTime,
13879
14295
  tokens: !isEmpty(ret.usage) ? ret.usage.promptTokens + ret.usage.completionTokens : void 0,
13880
- prompt_tokens: _optionalChain([ret, 'access', _190 => _190.usage, 'optionalAccess', _191 => _191.promptTokens]),
13881
- completion_tokens: _optionalChain([ret, 'access', _192 => _192.usage, 'optionalAccess', _193 => _193.completionTokens]),
14296
+ prompt_tokens: _optionalChain([ret, 'access', _177 => _177.usage, 'optionalAccess', _178 => _178.promptTokens]),
14297
+ completion_tokens: _optionalChain([ret, 'access', _179 => _179.usage, 'optionalAccess', _180 => _180.completionTokens]),
13882
14298
  cached: parseCachedHeader(
13883
- _nullishCoalesce(_optionalChain([ret, 'access', _194 => _194.rawResponse, 'optionalAccess', _195 => _195.headers, 'optionalAccess', _196 => _196[X_CACHED_HEADER]]), () => ( _optionalChain([ret, 'access', _197 => _197.rawResponse, 'optionalAccess', _198 => _198.headers, 'optionalAccess', _199 => _199[LEGACY_CACHED_HEADER]])))
14299
+ _nullishCoalesce(_optionalChain([ret, 'access', _181 => _181.rawResponse, 'optionalAccess', _182 => _182.headers, 'optionalAccess', _183 => _183[X_CACHED_HEADER]]), () => ( _optionalChain([ret, 'access', _184 => _184.rawResponse, 'optionalAccess', _185 => _185.headers, 'optionalAccess', _186 => _186[LEGACY_CACHED_HEADER]])))
13884
14300
  )
13885
14301
  }
13886
14302
  });
@@ -13972,10 +14388,10 @@ var BraintrustLanguageModelWrapper = class {
13972
14388
  metrics: {
13973
14389
  time_to_first_token,
13974
14390
  tokens: !isEmpty(usage) ? usage.promptTokens + usage.completionTokens : void 0,
13975
- prompt_tokens: _optionalChain([usage, 'optionalAccess', _200 => _200.promptTokens]),
13976
- completion_tokens: _optionalChain([usage, 'optionalAccess', _201 => _201.completionTokens]),
14391
+ prompt_tokens: _optionalChain([usage, 'optionalAccess', _187 => _187.promptTokens]),
14392
+ completion_tokens: _optionalChain([usage, 'optionalAccess', _188 => _188.completionTokens]),
13977
14393
  cached: parseCachedHeader(
13978
- _nullishCoalesce(_optionalChain([ret, 'access', _202 => _202.rawResponse, 'optionalAccess', _203 => _203.headers, 'optionalAccess', _204 => _204[X_CACHED_HEADER]]), () => ( _optionalChain([ret, 'access', _205 => _205.rawResponse, 'optionalAccess', _206 => _206.headers, 'optionalAccess', _207 => _207[LEGACY_CACHED_HEADER]])))
14394
+ _nullishCoalesce(_optionalChain([ret, 'access', _189 => _189.rawResponse, 'optionalAccess', _190 => _190.headers, 'optionalAccess', _191 => _191[X_CACHED_HEADER]]), () => ( _optionalChain([ret, 'access', _192 => _192.rawResponse, 'optionalAccess', _193 => _193.headers, 'optionalAccess', _194 => _194[LEGACY_CACHED_HEADER]])))
13979
14395
  )
13980
14396
  }
13981
14397
  });
@@ -14013,16 +14429,13 @@ function postProcessPrompt(prompt) {
14013
14429
  const textPart = message.content.find(
14014
14430
  (part) => part.type === "text"
14015
14431
  );
14016
- const toolCallParts = (
14017
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
14018
- message.content.filter(
14019
- (part) => part.type === "tool-call"
14020
- )
14432
+ const toolCallParts = message.content.filter(
14433
+ (part) => part.type === "tool-call"
14021
14434
  );
14022
14435
  return [
14023
14436
  {
14024
14437
  role: "assistant",
14025
- content: _optionalChain([textPart, 'optionalAccess', _208 => _208.text]),
14438
+ content: _optionalChain([textPart, 'optionalAccess', _195 => _195.text]),
14026
14439
  ...toolCallParts.length > 0 ? {
14027
14440
  tool_calls: toolCallParts.map((part) => ({
14028
14441
  id: part.toolCallId,
@@ -14068,34 +14481,183 @@ function postProcessPrompt(prompt) {
14068
14481
  content: JSON.stringify(part.result)
14069
14482
  }));
14070
14483
  }
14071
- });
14484
+ });
14485
+ }
14486
+ function postProcessOutput(text, toolCalls, finishReason) {
14487
+ return [
14488
+ {
14489
+ index: 0,
14490
+ message: {
14491
+ role: "assistant",
14492
+ content: _nullishCoalesce(text, () => ( "")),
14493
+ ...toolCalls && toolCalls.length > 0 ? {
14494
+ tool_calls: toolCalls.map((toolCall) => ({
14495
+ id: toolCall.toolCallId,
14496
+ function: {
14497
+ name: toolCall.toolName,
14498
+ arguments: toolCall.args
14499
+ },
14500
+ type: "function"
14501
+ }))
14502
+ } : {}
14503
+ },
14504
+ finish_reason: finishReason
14505
+ }
14506
+ ];
14507
+ }
14508
+
14509
+ // src/wrappers/ai-sdk/deprecated/BraintrustMiddleware.ts
14510
+ init_util();
14511
+ init_logger();
14512
+
14513
+ // src/wrappers/anthropic-tokens-util.ts
14514
+ function finalizeAnthropicTokens(metrics2) {
14515
+ const prompt_tokens = (metrics2.prompt_tokens || 0) + (metrics2.prompt_cached_tokens || 0) + (metrics2.prompt_cache_creation_tokens || 0);
14516
+ return {
14517
+ ...metrics2,
14518
+ prompt_tokens,
14519
+ tokens: prompt_tokens + (metrics2.completion_tokens || 0)
14520
+ };
14521
+ }
14522
+ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens = 0) {
14523
+ const cacheTokens = {};
14524
+ if (cacheReadTokens > 0) {
14525
+ cacheTokens.prompt_cached_tokens = cacheReadTokens;
14526
+ }
14527
+ if (cacheCreationTokens > 0) {
14528
+ cacheTokens.prompt_cache_creation_tokens = cacheCreationTokens;
14529
+ }
14530
+ return cacheTokens;
14531
+ }
14532
+
14533
+ // src/wrappers/ai-sdk/deprecated/BraintrustMiddleware.ts
14534
+ function detectProviderFromResult(result) {
14535
+ if (!_optionalChain([result, 'optionalAccess', _196 => _196.providerMetadata])) {
14536
+ return void 0;
14537
+ }
14538
+ const keys = Object.keys(result.providerMetadata);
14539
+ return _optionalChain([keys, 'optionalAccess', _197 => _197.at, 'call', _198 => _198(0)]);
14540
+ }
14541
+ function extractModelFromResult(result) {
14542
+ if (_optionalChain([result, 'optionalAccess', _199 => _199.response, 'optionalAccess', _200 => _200.modelId])) {
14543
+ return result.response.modelId;
14544
+ }
14545
+ if (_optionalChain([result, 'optionalAccess', _201 => _201.request, 'optionalAccess', _202 => _202.body, 'optionalAccess', _203 => _203.model])) {
14546
+ return result.request.body.model;
14547
+ }
14548
+ return void 0;
14549
+ }
14550
+ function extractModelFromWrapGenerateCallback(model) {
14551
+ return _optionalChain([model, 'optionalAccess', _204 => _204.modelId]);
14552
+ }
14553
+ function camelToSnake(str) {
14554
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
14555
+ }
14556
+ function extractModelParameters(params, excludeKeys) {
14557
+ const modelParams = {};
14558
+ for (const [key, value] of Object.entries(params)) {
14559
+ if (value !== void 0 && !excludeKeys.has(key)) {
14560
+ const snakeKey = camelToSnake(key);
14561
+ modelParams[snakeKey] = value;
14562
+ }
14563
+ }
14564
+ return modelParams;
14072
14565
  }
14073
- function postProcessOutput(text, toolCalls, finishReason) {
14566
+ function getNumberProperty(obj, key) {
14567
+ if (!obj || typeof obj !== "object" || !(key in obj)) {
14568
+ return void 0;
14569
+ }
14570
+ const value = Reflect.get(obj, key);
14571
+ return typeof value === "number" ? value : void 0;
14572
+ }
14573
+ function normalizeUsageMetrics(usage, provider, providerMetadata) {
14574
+ const metrics2 = {};
14575
+ const inputTokens = getNumberProperty(usage, "inputTokens");
14576
+ if (inputTokens !== void 0) {
14577
+ metrics2.prompt_tokens = inputTokens;
14578
+ }
14579
+ const outputTokens = getNumberProperty(usage, "outputTokens");
14580
+ if (outputTokens !== void 0) {
14581
+ metrics2.completion_tokens = outputTokens;
14582
+ }
14583
+ const totalTokens = getNumberProperty(usage, "totalTokens");
14584
+ if (totalTokens !== void 0) {
14585
+ metrics2.tokens = totalTokens;
14586
+ }
14587
+ const reasoningTokens = getNumberProperty(usage, "reasoningTokens");
14588
+ if (reasoningTokens !== void 0) {
14589
+ metrics2.completion_reasoning_tokens = reasoningTokens;
14590
+ }
14591
+ const cachedInputTokens = getNumberProperty(usage, "cachedInputTokens");
14592
+ if (cachedInputTokens !== void 0) {
14593
+ metrics2.prompt_cached_tokens = cachedInputTokens;
14594
+ }
14595
+ if (provider === "anthropic") {
14596
+ const anthropicMetadata = _optionalChain([providerMetadata, 'optionalAccess', _205 => _205.anthropic]);
14597
+ if (anthropicMetadata) {
14598
+ const cacheReadTokens = getNumberProperty(anthropicMetadata.usage, "cache_read_input_tokens") || 0;
14599
+ const cacheCreationTokens = getNumberProperty(
14600
+ anthropicMetadata.usage,
14601
+ "cache_creation_input_tokens"
14602
+ ) || 0;
14603
+ const cacheTokens = extractAnthropicCacheTokens(
14604
+ cacheReadTokens,
14605
+ cacheCreationTokens
14606
+ );
14607
+ Object.assign(metrics2, cacheTokens);
14608
+ Object.assign(metrics2, finalizeAnthropicTokens(metrics2));
14609
+ }
14610
+ }
14611
+ return metrics2;
14612
+ }
14613
+ function normalizeFinishReason(reason) {
14614
+ if (typeof reason !== "string") return void 0;
14615
+ return reason.replace(/-/g, "_");
14616
+ }
14617
+ function buildAssistantOutputWithToolCalls(result, toolCalls) {
14074
14618
  return [
14075
14619
  {
14076
14620
  index: 0,
14621
+ logprobs: null,
14622
+ finish_reason: _nullishCoalesce(normalizeFinishReason(_optionalChain([result, 'optionalAccess', _206 => _206.finishReason])), () => ( (toolCalls.length ? "tool_calls" : void 0))),
14077
14623
  message: {
14078
14624
  role: "assistant",
14079
- content: _nullishCoalesce(text, () => ( "")),
14080
- ...toolCalls && toolCalls.length > 0 ? {
14081
- tool_calls: toolCalls.map((toolCall) => ({
14082
- id: toolCall.toolCallId,
14083
- function: {
14084
- name: toolCall.toolName,
14085
- arguments: toolCall.args
14086
- },
14087
- type: "function"
14088
- }))
14089
- } : {}
14090
- },
14091
- finish_reason: finishReason
14625
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0
14626
+ }
14092
14627
  }
14093
14628
  ];
14094
14629
  }
14095
-
14096
- // src/wrappers/ai-sdk-5/ai-sdk.ts
14097
- init_logger();
14098
- var V3_EXCLUDE_KEYS = /* @__PURE__ */ new Set([
14630
+ function extractToolCallsFromSteps(steps) {
14631
+ const toolCalls = [];
14632
+ if (!Array.isArray(steps)) return toolCalls;
14633
+ let idx = 0;
14634
+ for (const step of steps) {
14635
+ const blocks = _optionalChain([step, 'optionalAccess', _207 => _207.content]);
14636
+ if (!Array.isArray(blocks)) continue;
14637
+ for (const block of blocks) {
14638
+ if (block && typeof block === "object" && block.type === "tool-call") {
14639
+ toolCalls.push({
14640
+ id: block.toolCallId,
14641
+ type: "function",
14642
+ index: idx++,
14643
+ function: {
14644
+ name: block.toolName,
14645
+ arguments: typeof block.input === "string" ? block.input : JSON.stringify(_nullishCoalesce(block.input, () => ( {})))
14646
+ }
14647
+ });
14648
+ }
14649
+ }
14650
+ }
14651
+ return toolCalls;
14652
+ }
14653
+ function extractToolCallsFromBlocks(blocks) {
14654
+ if (!Array.isArray(blocks)) return [];
14655
+ return extractToolCallsFromSteps([{ content: blocks }]);
14656
+ }
14657
+ function extractInput(params) {
14658
+ return _nullishCoalesce(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _208 => _208.prompt]), () => ( _optionalChain([params, 'optionalAccess', _209 => _209.messages]))), () => ( _optionalChain([params, 'optionalAccess', _210 => _210.system])));
14659
+ }
14660
+ var V2_EXCLUDE_KEYS = /* @__PURE__ */ new Set([
14099
14661
  "prompt",
14100
14662
  // Already captured as input
14101
14663
  "system",
@@ -14104,306 +14666,202 @@ var V3_EXCLUDE_KEYS = /* @__PURE__ */ new Set([
14104
14666
  // Already captured as input
14105
14667
  "model",
14106
14668
  // Already captured in metadata.model
14107
- "providerOptions",
14669
+ "providerOptions"
14108
14670
  // Internal AI SDK configuration
14109
- "tools",
14110
- // Already captured in metadata.tools
14111
- "span_info"
14112
- // Extracted separately for prompt linking
14113
14671
  ]);
14114
- function extractSpanInfo(params) {
14115
- const { span_info } = params;
14116
- return { spanInfo: span_info };
14117
- }
14118
- function processFilesAsAttachments(files) {
14119
- if (!files || !Array.isArray(files) || files.length === 0) {
14120
- return void 0;
14121
- }
14122
- return files.map((file, index) => {
14123
- const mediaType = file.mediaType || "application/octet-stream";
14124
- const filename = `generated_file_${index}.${getExtensionFromMediaType(mediaType)}`;
14125
- const blob = convertDataToBlob(file.data, mediaType);
14126
- if (!blob) {
14127
- return null;
14128
- }
14129
- return new Attachment({
14130
- data: blob,
14131
- filename,
14132
- contentType: mediaType
14133
- });
14134
- }).filter((attachment) => attachment !== null);
14135
- }
14136
- function wrapAISDK(ai) {
14137
- const {
14138
- wrapLanguageModel,
14139
- generateText,
14140
- streamText,
14141
- generateObject,
14142
- streamObject
14143
- } = ai;
14144
- const wrappedGenerateText = (params) => {
14145
- const { spanInfo } = extractSpanInfo(params);
14146
- return traced(
14147
- async (span) => {
14148
- const wrappedModel = wrapLanguageModel({
14149
- model: params.model,
14150
- middleware: BraintrustMiddleware({ spanInfo })
14151
- });
14152
- const result = await generateText({
14153
- ...params,
14154
- tools: params.tools ? wrapTools(params.tools) : void 0,
14155
- model: wrappedModel
14156
- });
14157
- const provider = detectProviderFromResult(result);
14158
- const model = extractModelFromResult(result);
14159
- const finishReason = normalizeFinishReason(_optionalChain([result, 'optionalAccess', _209 => _209.finishReason]));
14160
- const input = processInputAttachments(extractInput(params));
14161
- const outputAttachments = processFilesAsAttachments(result.files);
14162
- const output = outputAttachments ? { text: result.text || result.content, files: outputAttachments } : result.text || result.content;
14163
- span.log({
14164
- input,
14165
- output,
14672
+ function BraintrustMiddleware(config = {}) {
14673
+ return {
14674
+ wrapGenerate: async ({
14675
+ doGenerate,
14676
+ params,
14677
+ model: modelFromWrapGenerate
14678
+ }) => {
14679
+ const rawInput = extractInput(params);
14680
+ const processedInput = processInputAttachments(rawInput);
14681
+ const spanArgs = {
14682
+ name: _optionalChain([config, 'access', _211 => _211.spanInfo, 'optionalAccess', _212 => _212.name]) || "ai-sdk.doGenerate",
14683
+ spanAttributes: {
14684
+ type: "llm" /* LLM */,
14685
+ ..._optionalChain([config, 'access', _213 => _213.spanInfo, 'optionalAccess', _214 => _214.spanAttributes]) || {}
14686
+ },
14687
+ event: {
14688
+ input: processedInput,
14166
14689
  metadata: {
14167
- ...extractModelParameters(params, V3_EXCLUDE_KEYS),
14168
- ...provider ? { provider } : {},
14169
- ...model ? { model } : {},
14170
- ...finishReason ? { finish_reason: finishReason } : {}
14690
+ ...extractModelParameters(params, V2_EXCLUDE_KEYS),
14691
+ ..._optionalChain([config, 'access', _215 => _215.spanInfo, 'optionalAccess', _216 => _216.metadata]) || {}
14171
14692
  }
14172
- });
14173
- return result;
14174
- },
14175
- {
14176
- name: "ai-sdk.generateText"
14177
- }
14178
- );
14179
- };
14180
- const wrappedGenerateObject = (params) => {
14181
- const { spanInfo } = extractSpanInfo(params);
14182
- return traced(
14183
- async (span) => {
14184
- const wrappedModel = wrapLanguageModel({
14185
- model: params.model,
14186
- middleware: BraintrustMiddleware({ spanInfo })
14187
- });
14188
- const result = await generateObject({
14189
- ...params,
14190
- tools: params.tools ? wrapTools(params.tools) : void 0,
14191
- model: wrappedModel
14192
- });
14693
+ }
14694
+ };
14695
+ const span = startSpan(spanArgs);
14696
+ try {
14697
+ const result = await doGenerate();
14698
+ const metadata = {};
14193
14699
  const provider = detectProviderFromResult(result);
14700
+ if (provider !== void 0) {
14701
+ metadata.provider = provider;
14702
+ }
14703
+ if (result.finishReason !== void 0) {
14704
+ metadata.finish_reason = result.finishReason;
14705
+ }
14194
14706
  const model = extractModelFromResult(result);
14195
- const finishReason = normalizeFinishReason(result.finishReason);
14196
- const input = processInputAttachments(extractInput(params));
14197
- const outputAttachments = processFilesAsAttachments(result.files);
14198
- const output = outputAttachments ? { object: result.object, files: outputAttachments } : result.object;
14199
- span.log({
14200
- input,
14201
- output,
14202
- metadata: {
14203
- ...extractModelParameters(params, V3_EXCLUDE_KEYS),
14204
- ...provider ? { provider } : {},
14205
- ...model ? { model } : {},
14206
- ...finishReason ? { finish_reason: finishReason } : {}
14707
+ if (model !== void 0) {
14708
+ metadata.model = model;
14709
+ } else if (modelFromWrapGenerate) {
14710
+ const modelId = extractModelFromWrapGenerateCallback(
14711
+ modelFromWrapGenerate
14712
+ );
14713
+ if (modelId) {
14714
+ metadata.model = modelId;
14207
14715
  }
14716
+ }
14717
+ let toolCalls = extractToolCallsFromSteps(_optionalChain([result, 'optionalAccess', _217 => _217.steps]));
14718
+ if (!toolCalls || toolCalls.length === 0) {
14719
+ toolCalls = extractToolCallsFromBlocks(_optionalChain([result, 'optionalAccess', _218 => _218.content]));
14720
+ }
14721
+ span.log({
14722
+ output: toolCalls.length > 0 ? buildAssistantOutputWithToolCalls(result, toolCalls) : _optionalChain([result, 'optionalAccess', _219 => _219.content]),
14723
+ metadata,
14724
+ metrics: normalizeUsageMetrics(
14725
+ result.usage,
14726
+ provider,
14727
+ result.providerMetadata
14728
+ )
14208
14729
  });
14209
14730
  return result;
14210
- },
14211
- {
14212
- name: "ai-sdk.generateObject"
14213
- }
14214
- );
14215
- };
14216
- const wrappedStreamText = (params) => {
14217
- const { spanInfo } = extractSpanInfo(params);
14218
- const input = processInputAttachments(extractInput(params));
14219
- const span = startSpan({
14220
- name: "ai-sdk.streamText",
14221
- event: {
14222
- input,
14223
- metadata: extractModelParameters(params, V3_EXCLUDE_KEYS)
14731
+ } catch (error2) {
14732
+ span.log({
14733
+ error: error2 instanceof Error ? error2.message : String(error2)
14734
+ });
14735
+ throw error2;
14736
+ } finally {
14737
+ span.end();
14224
14738
  }
14225
- });
14226
- const userOnFinish = params.onFinish;
14227
- const userOnError = params.onError;
14228
- const userOnChunk = params.onChunk;
14229
- try {
14230
- const wrappedModel = wrapLanguageModel({
14231
- model: params.model,
14232
- middleware: BraintrustMiddleware({ spanInfo })
14233
- });
14234
- const startTime = Date.now();
14235
- let receivedFirst = false;
14236
- const result = withCurrent(
14237
- span,
14238
- () => streamText({
14239
- ...params,
14240
- tools: params.tools ? wrapTools(params.tools) : void 0,
14241
- model: wrappedModel,
14242
- onChunk: (chunk) => {
14243
- if (!receivedFirst) {
14244
- receivedFirst = true;
14739
+ },
14740
+ wrapStream: async ({ doStream, params }) => {
14741
+ const rawInput = extractInput(params);
14742
+ const processedInput = processInputAttachments(rawInput);
14743
+ const spanArgs = {
14744
+ name: _optionalChain([config, 'access', _220 => _220.spanInfo, 'optionalAccess', _221 => _221.name]) || "ai-sdk.doStream",
14745
+ spanAttributes: {
14746
+ type: "llm" /* LLM */,
14747
+ ..._optionalChain([config, 'access', _222 => _222.spanInfo, 'optionalAccess', _223 => _223.spanAttributes]) || {}
14748
+ },
14749
+ event: {
14750
+ input: processedInput,
14751
+ metadata: {
14752
+ ...extractModelParameters(params, V2_EXCLUDE_KEYS),
14753
+ ..._optionalChain([config, 'access', _224 => _224.spanInfo, 'optionalAccess', _225 => _225.metadata]) || {}
14754
+ }
14755
+ }
14756
+ };
14757
+ const span = startSpan(spanArgs);
14758
+ try {
14759
+ const { stream, ...rest } = await doStream();
14760
+ const textChunks = [];
14761
+ const toolBlocks = [];
14762
+ let finalUsage = {};
14763
+ let finalFinishReason = void 0;
14764
+ let providerMetadata = {};
14765
+ const transformStream = new TransformStream({
14766
+ transform(chunk, controller) {
14767
+ try {
14768
+ if (chunk.type === "text-delta" && chunk.delta) {
14769
+ textChunks.push(chunk.delta);
14770
+ }
14771
+ if (chunk.type === "tool-call" || chunk.type === "tool-result") {
14772
+ toolBlocks.push(chunk);
14773
+ }
14774
+ if (chunk.type === "finish") {
14775
+ finalFinishReason = chunk.finishReason;
14776
+ finalUsage = chunk.usage || {};
14777
+ providerMetadata = chunk.providerMetadata || {};
14778
+ }
14779
+ controller.enqueue(chunk);
14780
+ } catch (error2) {
14245
14781
  span.log({
14246
- metrics: {
14247
- time_to_first_token: (Date.now() - startTime) / 1e3
14248
- }
14782
+ error: error2 instanceof Error ? error2.message : String(error2)
14249
14783
  });
14250
- }
14251
- if (typeof userOnChunk === "function") {
14252
- userOnChunk(chunk);
14784
+ span.end();
14785
+ controller.error(error2);
14253
14786
  }
14254
14787
  },
14255
- onFinish: async (event) => {
14256
- if (typeof userOnFinish === "function") {
14257
- await userOnFinish(event);
14258
- }
14259
- const provider = detectProviderFromResult(event);
14260
- const model = extractModelFromResult(event);
14261
- const finishReason = normalizeFinishReason(_optionalChain([event, 'optionalAccess', _210 => _210.finishReason]));
14262
- const outputAttachments = processFilesAsAttachments(event.files);
14263
- const output = outputAttachments ? {
14264
- text: _optionalChain([event, 'optionalAccess', _211 => _211.text]) || _optionalChain([event, 'optionalAccess', _212 => _212.content]),
14265
- files: outputAttachments
14266
- } : _optionalChain([event, 'optionalAccess', _213 => _213.text]) || _optionalChain([event, 'optionalAccess', _214 => _214.content]);
14267
- span.log({
14268
- output,
14269
- metadata: {
14270
- ...extractModelParameters(params, V3_EXCLUDE_KEYS),
14271
- ...provider ? { provider } : {},
14272
- ...model ? { model } : {},
14273
- ...finishReason ? { finish_reason: finishReason } : {}
14788
+ flush() {
14789
+ try {
14790
+ const generatedText = textChunks.join("");
14791
+ let output = generatedText ? [{ type: "text", text: generatedText }] : [];
14792
+ const resultForDetection = {
14793
+ providerMetadata,
14794
+ response: rest.response,
14795
+ ...rest,
14796
+ finishReason: finalFinishReason
14797
+ };
14798
+ const metadata = {};
14799
+ const provider = detectProviderFromResult(resultForDetection);
14800
+ if (provider !== void 0) {
14801
+ metadata.provider = provider;
14274
14802
  }
14275
- });
14276
- span.end();
14277
- },
14278
- onError: async (err) => {
14279
- if (typeof userOnError === "function") {
14280
- await userOnError(err);
14281
- }
14282
- span.log({
14283
- error: err instanceof Error ? err.message : String(err)
14284
- });
14285
- span.end();
14286
- }
14287
- })
14288
- );
14289
- return result;
14290
- } catch (error2) {
14291
- span.log({
14292
- error: error2 instanceof Error ? error2.message : String(error2)
14293
- });
14294
- span.end();
14295
- throw error2;
14296
- }
14297
- };
14298
- const wrappedStreamObject = (params) => {
14299
- const { spanInfo } = extractSpanInfo(params);
14300
- const input = processInputAttachments(extractInput(params));
14301
- const span = startSpan({
14302
- name: "ai-sdk.streamObject",
14303
- event: {
14304
- input,
14305
- metadata: extractModelParameters(params, V3_EXCLUDE_KEYS)
14306
- }
14307
- });
14308
- const userOnFinish = params.onFinish;
14309
- const userOnError = params.onError;
14310
- try {
14311
- const wrappedModel = wrapLanguageModel({
14312
- model: params.model,
14313
- middleware: BraintrustMiddleware({ spanInfo })
14314
- });
14315
- const result = withCurrent(
14316
- span,
14317
- () => streamObject({
14318
- ...params,
14319
- tools: params.tools ? wrapTools(params.tools) : void 0,
14320
- model: wrappedModel,
14321
- onFinish: async (event) => {
14322
- if (typeof userOnFinish === "function") {
14323
- await userOnFinish(event);
14324
- }
14325
- const provider = detectProviderFromResult(event);
14326
- const model = extractModelFromResult(event);
14327
- const finishReason = normalizeFinishReason(_optionalChain([event, 'optionalAccess', _215 => _215.finishReason]));
14328
- const outputAttachments = processFilesAsAttachments(event.files);
14329
- const output = outputAttachments ? { object: _optionalChain([event, 'optionalAccess', _216 => _216.object]), files: outputAttachments } : _optionalChain([event, 'optionalAccess', _217 => _217.object]);
14330
- span.log({
14331
- output,
14332
- metadata: {
14333
- ...extractModelParameters(params, V3_EXCLUDE_KEYS),
14334
- ...provider ? { provider } : {},
14335
- ...model ? { model } : {},
14336
- ...finishReason ? { finish_reason: finishReason } : {}
14803
+ if (finalFinishReason !== void 0) {
14804
+ metadata.finish_reason = finalFinishReason;
14337
14805
  }
14338
- });
14339
- span.end();
14340
- },
14341
- onError: async (err) => {
14342
- if (typeof userOnError === "function") {
14343
- await userOnError(err);
14344
- }
14345
- span.log({
14346
- error: err instanceof Error ? err.message : String(err)
14347
- });
14348
- span.end();
14349
- }
14350
- })
14351
- );
14352
- const startTime = Date.now();
14353
- let receivedFirst = false;
14354
- const trackFirstAccess = () => {
14355
- if (!receivedFirst) {
14356
- receivedFirst = true;
14357
- span.log({
14358
- metrics: {
14359
- time_to_first_token: (Date.now() - startTime) / 1e3
14806
+ const model = extractModelFromResult(resultForDetection);
14807
+ if (model !== void 0) {
14808
+ metadata.model = model;
14809
+ }
14810
+ if (toolBlocks.length > 0) {
14811
+ const toolCalls = extractToolCallsFromSteps([
14812
+ { content: toolBlocks }
14813
+ ]);
14814
+ if (toolCalls.length > 0) {
14815
+ output = buildAssistantOutputWithToolCalls(
14816
+ resultForDetection,
14817
+ toolCalls
14818
+ );
14819
+ }
14820
+ }
14821
+ span.log({
14822
+ output,
14823
+ metadata,
14824
+ metrics: normalizeUsageMetrics(
14825
+ finalUsage,
14826
+ provider,
14827
+ providerMetadata
14828
+ )
14829
+ });
14830
+ span.end();
14831
+ } catch (error2) {
14832
+ span.log({
14833
+ error: error2 instanceof Error ? error2.message : String(error2)
14834
+ });
14835
+ span.end();
14836
+ throw error2;
14360
14837
  }
14361
- });
14362
- }
14363
- };
14364
- const [stream1, stream2] = result.baseStream.tee();
14365
- result.baseStream = stream2;
14366
- stream1.pipeThrough(
14367
- new TransformStream({
14368
- transform(chunk, controller) {
14369
- trackFirstAccess();
14370
- controller.enqueue(chunk);
14371
- }
14372
- })
14373
- ).pipeTo(
14374
- new WritableStream({
14375
- write() {
14376
14838
  }
14377
- })
14378
- ).catch(() => {
14379
- });
14380
- return result;
14381
- } catch (error2) {
14382
- span.log({
14383
- error: error2 instanceof Error ? error2.message : String(error2)
14384
- });
14385
- span.end();
14386
- throw error2;
14839
+ });
14840
+ return {
14841
+ stream: stream.pipeThrough(transformStream),
14842
+ ...rest
14843
+ };
14844
+ } catch (error2) {
14845
+ span.log({
14846
+ error: error2 instanceof Error ? error2.message : String(error2)
14847
+ });
14848
+ span.end();
14849
+ throw error2;
14850
+ }
14387
14851
  }
14388
14852
  };
14389
- return {
14390
- generateText: wrappedGenerateText,
14391
- generateObject: wrappedGenerateObject,
14392
- streamText: wrappedStreamText,
14393
- streamObject: wrappedStreamObject
14394
- };
14395
14853
  }
14396
14854
 
14397
14855
  // src/wrappers/mastra/mastra.ts
14398
14856
  init_logger();
14399
14857
  var aiSDKFormatWarning = false;
14400
14858
  function wrapMastraAgent(agent, options) {
14401
- const prefix = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _218 => _218.name]), () => ( _optionalChain([options, 'optionalAccess', _219 => _219.span_name]))), () => ( agent.name)), () => ( "Agent"));
14859
+ const prefix = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _226 => _226.name]), () => ( _optionalChain([options, 'optionalAccess', _227 => _227.span_name]))), () => ( agent.name)), () => ( "Agent"));
14402
14860
  if (!hasAllMethods(agent)) {
14403
14861
  return agent;
14404
14862
  }
14405
14863
  if (agent.tools) {
14406
- agent.__setTools(wrapTools(agent.tools));
14864
+ agent.__setTools(wrapTools2(agent.tools));
14407
14865
  }
14408
14866
  return new Proxy(agent, {
14409
14867
  get(target, prop, receiver) {
@@ -14430,10 +14888,10 @@ function wrapGenerate(original, target, prefix) {
14430
14888
  return traced(
14431
14889
  async (span) => {
14432
14890
  const result = await original.apply(target, args);
14433
- const provider = detectProviderFromResult(result);
14434
- const model = extractModelFromResult(result);
14435
- const finishReason = normalizeFinishReason(_optionalChain([result, 'optionalAccess', _220 => _220.finishReason]));
14436
- const metrics2 = _optionalChain([result, 'optionalAccess', _221 => _221.usage]) ? normalizeUsageMetrics(
14891
+ const provider = detectProviderFromResult2(result);
14892
+ const model = extractModelFromResult2(result);
14893
+ const finishReason = normalizeFinishReason2(_optionalChain([result, 'optionalAccess', _228 => _228.finishReason]));
14894
+ const metrics2 = _optionalChain([result, 'optionalAccess', _229 => _229.usage]) ? normalizeUsageMetrics2(
14437
14895
  result.usage,
14438
14896
  provider,
14439
14897
  result.providerMetadata
@@ -14481,14 +14939,14 @@ function wrapStream(original, target, prefix) {
14481
14939
  format: baseOpts.format || "aisdk"
14482
14940
  // Default to AI SDK v5 format if not specified
14483
14941
  };
14484
- const userOnChunk = _optionalChain([baseOpts, 'optionalAccess', _222 => _222.onChunk]);
14485
- const userOnFinish = _optionalChain([baseOpts, 'optionalAccess', _223 => _223.onFinish]);
14486
- const userOnError = _optionalChain([baseOpts, 'optionalAccess', _224 => _224.onError]);
14942
+ const userOnChunk = _optionalChain([baseOpts, 'optionalAccess', _230 => _230.onChunk]);
14943
+ const userOnFinish = _optionalChain([baseOpts, 'optionalAccess', _231 => _231.onFinish]);
14944
+ const userOnError = _optionalChain([baseOpts, 'optionalAccess', _232 => _232.onError]);
14487
14945
  const startTime = Date.now();
14488
14946
  let receivedFirst = false;
14489
14947
  wrappedOpts.onChunk = (chunk) => {
14490
14948
  try {
14491
- _optionalChain([userOnChunk, 'optionalCall', _225 => _225(chunk)]);
14949
+ _optionalChain([userOnChunk, 'optionalCall', _233 => _233(chunk)]);
14492
14950
  } finally {
14493
14951
  if (!receivedFirst) {
14494
14952
  receivedFirst = true;
@@ -14500,13 +14958,13 @@ function wrapStream(original, target, prefix) {
14500
14958
  };
14501
14959
  wrappedOpts.onFinish = async (event) => {
14502
14960
  try {
14503
- await _optionalChain([userOnFinish, 'optionalCall', _226 => _226(event)]);
14961
+ await _optionalChain([userOnFinish, 'optionalCall', _234 => _234(event)]);
14504
14962
  } finally {
14505
14963
  const e = event;
14506
- const provider = detectProviderFromResult(e);
14507
- const model = extractModelFromResult(e);
14508
- const finishReason = normalizeFinishReason(_optionalChain([e, 'optionalAccess', _227 => _227.finishReason]));
14509
- const metrics2 = _optionalChain([e, 'optionalAccess', _228 => _228.usage]) ? normalizeUsageMetrics(e.usage, provider, e.providerMetadata) : {};
14964
+ const provider = detectProviderFromResult2(e);
14965
+ const model = extractModelFromResult2(e);
14966
+ const finishReason = normalizeFinishReason2(_optionalChain([e, 'optionalAccess', _235 => _235.finishReason]));
14967
+ const metrics2 = _optionalChain([e, 'optionalAccess', _236 => _236.usage]) ? normalizeUsageMetrics2(e.usage, provider, e.providerMetadata) : {};
14510
14968
  span.log({
14511
14969
  output: _nullishCoalesce(_nullishCoalesce(e.text, () => ( e.content)), () => ( e)),
14512
14970
  metadata: {
@@ -14522,7 +14980,7 @@ function wrapStream(original, target, prefix) {
14522
14980
  };
14523
14981
  wrappedOpts.onError = async (err) => {
14524
14982
  try {
14525
- await _optionalChain([userOnError, 'optionalCall', _229 => _229(err)]);
14983
+ await _optionalChain([userOnError, 'optionalCall', _237 => _237(err)]);
14526
14984
  } finally {
14527
14985
  logError(span, err);
14528
14986
  span.end();
@@ -14534,6 +14992,109 @@ function wrapStream(original, target, prefix) {
14534
14992
  );
14535
14993
  };
14536
14994
  }
14995
+ function detectProviderFromResult2(result) {
14996
+ if (!_optionalChain([result, 'optionalAccess', _238 => _238.providerMetadata])) {
14997
+ return void 0;
14998
+ }
14999
+ const keys = Object.keys(result.providerMetadata);
15000
+ return _optionalChain([keys, 'optionalAccess', _239 => _239.at, 'call', _240 => _240(0)]);
15001
+ }
15002
+ function extractModelFromResult2(result) {
15003
+ if (_optionalChain([result, 'optionalAccess', _241 => _241.response, 'optionalAccess', _242 => _242.modelId])) {
15004
+ return result.response.modelId;
15005
+ }
15006
+ if (_optionalChain([result, 'optionalAccess', _243 => _243.request, 'optionalAccess', _244 => _244.body, 'optionalAccess', _245 => _245.model])) {
15007
+ return result.request.body.model;
15008
+ }
15009
+ return void 0;
15010
+ }
15011
+ function normalizeFinishReason2(reason) {
15012
+ if (typeof reason !== "string") return void 0;
15013
+ return reason.replace(/-/g, "_");
15014
+ }
15015
+ function normalizeUsageMetrics2(usage, provider, providerMetadata) {
15016
+ const metrics2 = {};
15017
+ const inputTokens = getNumberProperty2(usage, "inputTokens");
15018
+ if (inputTokens !== void 0) {
15019
+ metrics2.prompt_tokens = inputTokens;
15020
+ }
15021
+ const outputTokens = getNumberProperty2(usage, "outputTokens");
15022
+ if (outputTokens !== void 0) {
15023
+ metrics2.completion_tokens = outputTokens;
15024
+ }
15025
+ const totalTokens = getNumberProperty2(usage, "totalTokens");
15026
+ if (totalTokens !== void 0) {
15027
+ metrics2.tokens = totalTokens;
15028
+ }
15029
+ const reasoningTokens = getNumberProperty2(usage, "reasoningTokens");
15030
+ if (reasoningTokens !== void 0) {
15031
+ metrics2.completion_reasoning_tokens = reasoningTokens;
15032
+ }
15033
+ const cachedInputTokens = getNumberProperty2(usage, "cachedInputTokens");
15034
+ if (cachedInputTokens !== void 0) {
15035
+ metrics2.prompt_cached_tokens = cachedInputTokens;
15036
+ }
15037
+ if (provider === "anthropic") {
15038
+ const anthropicMetadata = _optionalChain([providerMetadata, 'optionalAccess', _246 => _246.anthropic]);
15039
+ if (anthropicMetadata) {
15040
+ const cacheReadTokens = getNumberProperty2(anthropicMetadata.usage, "cache_read_input_tokens") || 0;
15041
+ const cacheCreationTokens = getNumberProperty2(
15042
+ anthropicMetadata.usage,
15043
+ "cache_creation_input_tokens"
15044
+ ) || 0;
15045
+ const cacheTokens = extractAnthropicCacheTokens(
15046
+ cacheReadTokens,
15047
+ cacheCreationTokens
15048
+ );
15049
+ Object.assign(metrics2, cacheTokens);
15050
+ Object.assign(metrics2, finalizeAnthropicTokens(metrics2));
15051
+ }
15052
+ }
15053
+ return metrics2;
15054
+ }
15055
+ function wrapTools2(tools) {
15056
+ if (!tools) return tools;
15057
+ const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
15058
+ if (Array.isArray(tools)) {
15059
+ const arr = tools;
15060
+ const out = arr.map((tool, idx) => {
15061
+ if (tool != null && typeof tool === "object" && "execute" in tool && typeof tool.execute === "function") {
15062
+ const name = inferName(tool, `tool[${idx}]`);
15063
+ return {
15064
+ ...tool,
15065
+ execute: wrapTraced(tool.execute.bind(tool), {
15066
+ name,
15067
+ type: "tool"
15068
+ })
15069
+ };
15070
+ }
15071
+ return tool;
15072
+ });
15073
+ return out;
15074
+ }
15075
+ const wrappedTools = {};
15076
+ for (const [key, tool] of Object.entries(tools)) {
15077
+ if (tool != null && typeof tool === "object" && "execute" in tool && typeof tool.execute === "function") {
15078
+ wrappedTools[key] = {
15079
+ ...tool,
15080
+ execute: wrapTraced(tool.execute.bind(tool), {
15081
+ name: key,
15082
+ type: "tool"
15083
+ })
15084
+ };
15085
+ } else {
15086
+ wrappedTools[key] = tool;
15087
+ }
15088
+ }
15089
+ return wrappedTools;
15090
+ }
15091
+ function getNumberProperty2(obj, key) {
15092
+ if (!obj || typeof obj !== "object" || !(key in obj)) {
15093
+ return void 0;
15094
+ }
15095
+ const value = Reflect.get(obj, key);
15096
+ return typeof value === "number" ? value : void 0;
15097
+ }
14537
15098
 
14538
15099
  // src/wrappers/anthropic.ts
14539
15100
  init_logger();
@@ -14705,9 +15266,9 @@ function streamNextProxy(stream, sspan) {
14705
15266
  return result;
14706
15267
  }
14707
15268
  const item = result.value;
14708
- switch (_optionalChain([item, 'optionalAccess', _230 => _230.type])) {
15269
+ switch (_optionalChain([item, 'optionalAccess', _247 => _247.type])) {
14709
15270
  case "message_start":
14710
- const msg = _optionalChain([item, 'optionalAccess', _231 => _231.message]);
15271
+ const msg = _optionalChain([item, 'optionalAccess', _248 => _248.message]);
14711
15272
  if (msg) {
14712
15273
  const event = parseEventFromMessage(msg);
14713
15274
  totals = { ...totals, ...event.metrics };
@@ -14720,20 +15281,20 @@ function streamNextProxy(stream, sspan) {
14720
15281
  }
14721
15282
  break;
14722
15283
  case "content_block_delta":
14723
- if (_optionalChain([item, 'access', _232 => _232.delta, 'optionalAccess', _233 => _233.type]) === "text_delta") {
14724
- const text = _optionalChain([item, 'optionalAccess', _234 => _234.delta, 'optionalAccess', _235 => _235.text]);
15284
+ if (_optionalChain([item, 'access', _249 => _249.delta, 'optionalAccess', _250 => _250.type]) === "text_delta") {
15285
+ const text = _optionalChain([item, 'optionalAccess', _251 => _251.delta, 'optionalAccess', _252 => _252.text]);
14725
15286
  if (text) {
14726
15287
  deltas.push(text);
14727
15288
  }
14728
15289
  }
14729
15290
  break;
14730
15291
  case "message_delta":
14731
- const usage = _optionalChain([item, 'optionalAccess', _236 => _236.usage]);
15292
+ const usage = _optionalChain([item, 'optionalAccess', _253 => _253.usage]);
14732
15293
  if (usage) {
14733
15294
  const metrics2 = parseMetricsFromUsage2(usage);
14734
15295
  totals = { ...totals, ...metrics2 };
14735
15296
  }
14736
- const delta = _optionalChain([item, 'optionalAccess', _237 => _237.delta]);
15297
+ const delta = _optionalChain([item, 'optionalAccess', _254 => _254.delta]);
14737
15298
  if (delta) {
14738
15299
  metadata = { ...metadata, ...delta };
14739
15300
  }
@@ -14746,7 +15307,7 @@ function streamNextProxy(stream, sspan) {
14746
15307
  }
14747
15308
  function parseEventFromMessage(message) {
14748
15309
  const output = message ? { role: message.role, content: message.content } : null;
14749
- const metrics2 = parseMetricsFromUsage2(_optionalChain([message, 'optionalAccess', _238 => _238.usage]));
15310
+ const metrics2 = parseMetricsFromUsage2(_optionalChain([message, 'optionalAccess', _255 => _255.usage]));
14750
15311
  const metas = ["stop_reason", "stop_sequence"];
14751
15312
  const metadata = {};
14752
15313
  for (const m of metas) {
@@ -14891,8 +15452,8 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
14891
15452
  finalResults.push(finalMessageContent);
14892
15453
  }
14893
15454
  const lastMessage = currentMessages[currentMessages.length - 1];
14894
- if (_optionalChain([lastMessage, 'optionalAccess', _239 => _239.message, 'optionalAccess', _240 => _240.usage])) {
14895
- const outputTokens = getNumberProperty(lastMessage.message.usage, "output_tokens") || 0;
15455
+ if (_optionalChain([lastMessage, 'optionalAccess', _256 => _256.message, 'optionalAccess', _257 => _257.usage])) {
15456
+ const outputTokens = getNumberProperty3(lastMessage.message.usage, "output_tokens") || 0;
14896
15457
  accumulatedOutputTokens += outputTokens;
14897
15458
  }
14898
15459
  currentMessages.length = 0;
@@ -14906,20 +15467,20 @@ function wrapClaudeAgentQuery(queryFn, defaultThis) {
14906
15467
  );
14907
15468
  for await (const message of generator) {
14908
15469
  const currentTime = getCurrentUnixTimestamp();
14909
- const messageId = _optionalChain([message, 'access', _241 => _241.message, 'optionalAccess', _242 => _242.id]);
15470
+ const messageId = _optionalChain([message, 'access', _258 => _258.message, 'optionalAccess', _259 => _259.id]);
14910
15471
  if (messageId && messageId !== currentMessageId) {
14911
15472
  await createLLMSpan();
14912
15473
  currentMessageId = messageId;
14913
15474
  currentMessageStartTime = currentTime;
14914
15475
  }
14915
- if (message.type === "assistant" && _optionalChain([message, 'access', _243 => _243.message, 'optionalAccess', _244 => _244.usage])) {
15476
+ if (message.type === "assistant" && _optionalChain([message, 'access', _260 => _260.message, 'optionalAccess', _261 => _261.usage])) {
14916
15477
  currentMessages.push(message);
14917
15478
  }
14918
15479
  if (message.type === "result" && message.usage) {
14919
15480
  finalUsageMetrics = _extractUsageFromMessage(message);
14920
15481
  if (currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
14921
15482
  const lastMessage = currentMessages[currentMessages.length - 1];
14922
- if (_optionalChain([lastMessage, 'optionalAccess', _245 => _245.message, 'optionalAccess', _246 => _246.usage])) {
15483
+ if (_optionalChain([lastMessage, 'optionalAccess', _262 => _262.message, 'optionalAccess', _263 => _263.usage])) {
14923
15484
  const adjustedTokens = finalUsageMetrics.completion_tokens - accumulatedOutputTokens;
14924
15485
  if (adjustedTokens >= 0) {
14925
15486
  lastMessage.message.usage.output_tokens = adjustedTokens;
@@ -15000,23 +15561,23 @@ function _extractUsageFromMessage(message) {
15000
15561
  const metrics2 = {};
15001
15562
  let usage;
15002
15563
  if (message.type === "assistant") {
15003
- usage = _optionalChain([message, 'access', _247 => _247.message, 'optionalAccess', _248 => _248.usage]);
15564
+ usage = _optionalChain([message, 'access', _264 => _264.message, 'optionalAccess', _265 => _265.usage]);
15004
15565
  } else if (message.type === "result") {
15005
15566
  usage = message.usage;
15006
15567
  }
15007
15568
  if (!usage || typeof usage !== "object") {
15008
15569
  return metrics2;
15009
15570
  }
15010
- const inputTokens = getNumberProperty(usage, "input_tokens");
15571
+ const inputTokens = getNumberProperty3(usage, "input_tokens");
15011
15572
  if (inputTokens !== void 0) {
15012
15573
  metrics2.prompt_tokens = inputTokens;
15013
15574
  }
15014
- const outputTokens = getNumberProperty(usage, "output_tokens");
15575
+ const outputTokens = getNumberProperty3(usage, "output_tokens");
15015
15576
  if (outputTokens !== void 0) {
15016
15577
  metrics2.completion_tokens = outputTokens;
15017
15578
  }
15018
- const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
15019
- const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
15579
+ const cacheReadTokens = getNumberProperty3(usage, "cache_read_input_tokens") || 0;
15580
+ const cacheCreationTokens = getNumberProperty3(usage, "cache_creation_input_tokens") || 0;
15020
15581
  if (cacheReadTokens > 0 || cacheCreationTokens > 0) {
15021
15582
  const cacheTokens = extractAnthropicCacheTokens(
15022
15583
  cacheReadTokens,
@@ -15032,14 +15593,14 @@ function _extractUsageFromMessage(message) {
15032
15593
  async function _createLLMSpanForMessages(messages, prompt, conversationHistory, options, startTime, parentSpan) {
15033
15594
  if (messages.length === 0) return void 0;
15034
15595
  const lastMessage = messages[messages.length - 1];
15035
- if (lastMessage.type !== "assistant" || !_optionalChain([lastMessage, 'access', _249 => _249.message, 'optionalAccess', _250 => _250.usage])) {
15596
+ if (lastMessage.type !== "assistant" || !_optionalChain([lastMessage, 'access', _266 => _266.message, 'optionalAccess', _267 => _267.usage])) {
15036
15597
  return void 0;
15037
15598
  }
15038
15599
  const model = lastMessage.message.model || options.model;
15039
15600
  const usage = _extractUsageFromMessage(lastMessage);
15040
15601
  const input = _buildLLMInput(prompt, conversationHistory);
15041
15602
  const outputs = messages.map(
15042
- (m) => _optionalChain([m, 'access', _251 => _251.message, 'optionalAccess', _252 => _252.content]) && _optionalChain([m, 'access', _253 => _253.message, 'optionalAccess', _254 => _254.role]) ? { content: m.message.content, role: m.message.role } : void 0
15603
+ (m) => _optionalChain([m, 'access', _268 => _268.message, 'optionalAccess', _269 => _269.content]) && _optionalChain([m, 'access', _270 => _270.message, 'optionalAccess', _271 => _271.role]) ? { content: m.message.content, role: m.message.role } : void 0
15043
15604
  ).filter((c) => c !== void 0);
15044
15605
  await traced(
15045
15606
  (llmSpan) => {
@@ -15059,7 +15620,7 @@ async function _createLLMSpanForMessages(messages, prompt, conversationHistory,
15059
15620
  parent: parentSpan
15060
15621
  }
15061
15622
  );
15062
- return _optionalChain([lastMessage, 'access', _255 => _255.message, 'optionalAccess', _256 => _256.content]) && _optionalChain([lastMessage, 'access', _257 => _257.message, 'optionalAccess', _258 => _258.role]) ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
15623
+ return _optionalChain([lastMessage, 'access', _272 => _272.message, 'optionalAccess', _273 => _273.content]) && _optionalChain([lastMessage, 'access', _274 => _274.message, 'optionalAccess', _275 => _275.role]) ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
15063
15624
  }
15064
15625
  function wrapClaudeAgentSDK(sdk) {
15065
15626
  const cache = /* @__PURE__ */ new Map();
@@ -15107,6 +15668,13 @@ function wrapClaudeAgentSDK(sdk) {
15107
15668
  }
15108
15669
  });
15109
15670
  }
15671
+ function getNumberProperty3(obj, key) {
15672
+ if (!obj || typeof obj !== "object" || !(key in obj)) {
15673
+ return void 0;
15674
+ }
15675
+ const value = Reflect.get(obj, key);
15676
+ return typeof value === "number" ? value : void 0;
15677
+ }
15110
15678
 
15111
15679
  // src/wrappers/google-genai.ts
15112
15680
  init_logger();
@@ -15345,7 +15913,7 @@ function serializePart(part) {
15345
15913
  return part;
15346
15914
  }
15347
15915
  function serializeTools(params) {
15348
- if (!_optionalChain([params, 'access', _259 => _259.config, 'optionalAccess', _260 => _260.tools])) {
15916
+ if (!_optionalChain([params, 'access', _276 => _276.config, 'optionalAccess', _277 => _277.tools])) {
15349
15917
  return null;
15350
15918
  }
15351
15919
  try {
@@ -15355,7 +15923,7 @@ function serializeTools(params) {
15355
15923
  }
15356
15924
  return tool;
15357
15925
  });
15358
- } catch (e11) {
15926
+ } catch (e14) {
15359
15927
  return null;
15360
15928
  }
15361
15929
  }
@@ -15428,7 +15996,7 @@ function aggregateGenerateContentChunks(chunks, start, firstTokenTime) {
15428
15996
  }
15429
15997
  if (chunk.candidates && Array.isArray(chunk.candidates)) {
15430
15998
  for (const candidate of chunk.candidates) {
15431
- if (_optionalChain([candidate, 'access', _261 => _261.content, 'optionalAccess', _262 => _262.parts])) {
15999
+ if (_optionalChain([candidate, 'access', _278 => _278.content, 'optionalAccess', _279 => _279.parts])) {
15432
16000
  for (const part of candidate.content.parts) {
15433
16001
  if (part.text !== void 0) {
15434
16002
  if (part.thought) {
@@ -15459,7 +16027,7 @@ function aggregateGenerateContentChunks(chunks, start, firstTokenTime) {
15459
16027
  parts.push({ text });
15460
16028
  }
15461
16029
  parts.push(...otherParts);
15462
- if (parts.length > 0 && _optionalChain([lastResponse, 'optionalAccess', _263 => _263.candidates])) {
16030
+ if (parts.length > 0 && _optionalChain([lastResponse, 'optionalAccess', _280 => _280.candidates])) {
15463
16031
  const candidates = [];
15464
16032
  for (const candidate of lastResponse.candidates) {
15465
16033
  const candidateDict = {
@@ -15533,7 +16101,7 @@ try {
15533
16101
  otelApi = (init_esm(), __toCommonJS(esm_exports));
15534
16102
  otelSdk = __require("@opentelemetry/sdk-trace-base");
15535
16103
  OTEL_AVAILABLE2 = true;
15536
- } catch (e12) {
16104
+ } catch (e15) {
15537
16105
  console.warn(
15538
16106
  "OpenTelemetry packages are not installed. Install them with: npm install @opentelemetry/api @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-http @opentelemetry/resources @opentelemetry/semantic-conventions"
15539
16107
  );
@@ -15688,8 +16256,8 @@ var BraintrustSpanProcessor = class _BraintrustSpanProcessor {
15688
16256
  span.instrumentationScope = span.instrumentationLibrary;
15689
16257
  }
15690
16258
  if (!span.parentSpanContext && span.parentSpanId) {
15691
- const spanContext = _optionalChain([span, 'access', _264 => _264.spanContext, 'optionalCall', _265 => _265()]);
15692
- if (_optionalChain([spanContext, 'optionalAccess', _266 => _266.traceId])) {
16259
+ const spanContext = _optionalChain([span, 'access', _281 => _281.spanContext, 'optionalCall', _282 => _282()]);
16260
+ if (_optionalChain([spanContext, 'optionalAccess', _283 => _283.traceId])) {
15693
16261
  span.parentSpanContext = {
15694
16262
  spanId: span.parentSpanId,
15695
16263
  traceId: spanContext.traceId
@@ -15732,7 +16300,7 @@ var BraintrustSpanProcessor = class _BraintrustSpanProcessor {
15732
16300
  let parentValue;
15733
16301
  if (otelApi && otelApi.context) {
15734
16302
  const currentContext = otelApi.context.active();
15735
- const contextValue = _optionalChain([currentContext, 'access', _267 => _267.getValue, 'optionalCall', _268 => _268("braintrust.parent")]);
16303
+ const contextValue = _optionalChain([currentContext, 'access', _284 => _284.getValue, 'optionalCall', _285 => _285("braintrust.parent")]);
15736
16304
  if (typeof contextValue === "string") {
15737
16305
  parentValue = contextValue;
15738
16306
  }
@@ -15749,7 +16317,7 @@ var BraintrustSpanProcessor = class _BraintrustSpanProcessor {
15749
16317
  span.setAttributes({ "braintrust.parent": parentValue });
15750
16318
  }
15751
16319
  }
15752
- } catch (e13) {
16320
+ } catch (e16) {
15753
16321
  }
15754
16322
  this.aiSpanProcessor.onStart(span, parentContext);
15755
16323
  }
@@ -15765,7 +16333,7 @@ var BraintrustSpanProcessor = class _BraintrustSpanProcessor {
15765
16333
  return typeof parentAttr === "string" ? parentAttr : void 0;
15766
16334
  }
15767
16335
  return void 0;
15768
- } catch (e14) {
16336
+ } catch (e17) {
15769
16337
  return void 0;
15770
16338
  }
15771
16339
  }
@@ -15796,7 +16364,7 @@ function otelContextFromSpanExport(exportStr) {
15796
16364
  traceId: traceIdHex,
15797
16365
  spanId: spanIdHex,
15798
16366
  isRemote: true,
15799
- traceFlags: _nullishCoalesce(_optionalChain([otelApi, 'access', _269 => _269.TraceFlags, 'optionalAccess', _270 => _270.SAMPLED]), () => ( 1))
16367
+ traceFlags: _nullishCoalesce(_optionalChain([otelApi, 'access', _286 => _286.TraceFlags, 'optionalAccess', _287 => _287.SAMPLED]), () => ( 1))
15800
16368
  // SAMPLED flag
15801
16369
  };
15802
16370
  const nonRecordingSpan = otelTrace2.wrapSpanContext(spanContext);
@@ -15901,7 +16469,7 @@ var BraintrustExporter = (_class21 = class _BraintrustExporter {
15901
16469
  function addParentToBaggage(parent, ctx) {
15902
16470
  if (!OTEL_AVAILABLE2 || !otelApi) {
15903
16471
  console.error("OpenTelemetry not available");
15904
- return ctx || _optionalChain([otelApi, 'optionalAccess', _271 => _271.context, 'access', _272 => _272.active, 'call', _273 => _273()]);
16472
+ return ctx || _optionalChain([otelApi, 'optionalAccess', _288 => _288.context, 'access', _289 => _289.active, 'call', _290 => _290()]);
15905
16473
  }
15906
16474
  try {
15907
16475
  const propagation2 = otelApi.propagation;
@@ -15962,7 +16530,7 @@ function parentFromHeaders(headers) {
15962
16530
  return void 0;
15963
16531
  }
15964
16532
  const baggage = propagation2.getBaggage(ctx);
15965
- const braintrustParent = _optionalChain([baggage, 'optionalAccess', _274 => _274.getEntry, 'call', _275 => _275("braintrust.parent"), 'optionalAccess', _276 => _276.value]);
16533
+ const braintrustParent = _optionalChain([baggage, 'optionalAccess', _291 => _291.getEntry, 'call', _292 => _292("braintrust.parent"), 'optionalAccess', _293 => _293.value]);
15966
16534
  if (!braintrustParent) {
15967
16535
  console.warn(
15968
16536
  "parentFromHeaders: braintrust.parent not found in OTEL baggage. Cannot create Braintrust parent without project information. Ensure the OTEL span sets braintrust.parent in baggage before exporting headers."