braintrust 3.27.0 → 3.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dev/dist/index.d.mts +519 -186
  2. package/dev/dist/index.d.ts +519 -186
  3. package/dev/dist/index.js +1837 -1009
  4. package/dev/dist/index.mjs +1172 -344
  5. package/dist/apply-auto-instrumentation.js +262 -210
  6. package/dist/apply-auto-instrumentation.mjs +54 -2
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +81 -2
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +81 -2
  10. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +81 -2
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +81 -2
  14. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  15. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +81 -2
  16. package/dist/auto-instrumentations/bundler/webpack.cjs +81 -2
  17. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  18. package/dist/auto-instrumentations/{chunk-XEYKUBLY.mjs → chunk-26PKVUKB.mjs} +80 -2
  19. package/dist/auto-instrumentations/{chunk-BW33ULMW.mjs → chunk-HD35AM3M.mjs} +1 -1
  20. package/dist/auto-instrumentations/{chunk-ZNHTSSGI.mjs → chunk-NP7V4XB2.mjs} +2 -1
  21. package/dist/auto-instrumentations/hook.mjs +236 -30
  22. package/dist/auto-instrumentations/index.cjs +2 -1
  23. package/dist/auto-instrumentations/index.mjs +1 -1
  24. package/dist/browser.d.mts +628 -53
  25. package/dist/browser.d.ts +628 -53
  26. package/dist/browser.js +2301 -284
  27. package/dist/browser.mjs +2301 -284
  28. package/dist/{chunk-MF7NU6BT.js → chunk-BBE7SNRV.js} +34 -4
  29. package/dist/{chunk-QRHGVBKU.js → chunk-OBBWQW6K.js} +1799 -1023
  30. package/dist/{chunk-YKD22IMR.mjs → chunk-UPFNQCGB.mjs} +966 -190
  31. package/dist/{chunk-CZM5JIQL.mjs → chunk-ZHUHZWFY.mjs} +33 -3
  32. package/dist/cli.js +1224 -398
  33. package/dist/edge-light.d.mts +1 -1
  34. package/dist/edge-light.d.ts +1 -1
  35. package/dist/edge-light.js +2301 -284
  36. package/dist/edge-light.mjs +2301 -284
  37. package/dist/index.d.mts +1212 -637
  38. package/dist/index.d.ts +1212 -637
  39. package/dist/index.js +1880 -590
  40. package/dist/index.mjs +1450 -160
  41. package/dist/instrumentation/index.d.mts +190 -6
  42. package/dist/instrumentation/index.d.ts +190 -6
  43. package/dist/instrumentation/index.js +823 -116
  44. package/dist/instrumentation/index.mjs +823 -116
  45. package/dist/vitest-evals-reporter.js +16 -16
  46. package/dist/vitest-evals-reporter.mjs +2 -2
  47. package/dist/workerd.d.mts +1 -1
  48. package/dist/workerd.d.ts +1 -1
  49. package/dist/workerd.js +2301 -284
  50. package/dist/workerd.mjs +2301 -284
  51. package/package.json +2 -3
  52. package/util/dist/index.d.mts +1545 -100
  53. package/util/dist/index.d.ts +1545 -100
@@ -45,8 +45,9 @@ import {
45
45
  smithyClientChannels,
46
46
  smithyCoreChannels,
47
47
  strandsAgentSDKChannels,
48
+ voyageAIChannels,
48
49
  withSpanInstrumentationName
49
- } from "./chunk-CZM5JIQL.mjs";
50
+ } from "./chunk-ZHUHZWFY.mjs";
50
51
 
51
52
  // src/id-gen.ts
52
53
  import { v4 as uuidv4 } from "uuid";
@@ -1121,15 +1122,15 @@ function mergeDictsWithPaths({
1121
1122
  function mergeDictsWithPathsHelper({
1122
1123
  mergeInto,
1123
1124
  mergeFrom,
1124
- path: path2,
1125
+ path: path3,
1125
1126
  mergePaths
1126
1127
  }) {
1127
1128
  Object.entries(mergeFrom).forEach(([k, mergeFromV]) => {
1128
1129
  if (FORBIDDEN_MERGE_KEYS.has(k)) return;
1129
- const fullPath = path2.concat([k]);
1130
+ const fullPath = path3.concat([k]);
1130
1131
  const fullPathSerialized = JSON.stringify(fullPath);
1131
1132
  const mergeIntoV = recordFind(mergeInto, k);
1132
- const isSetUnionField = path2.length === 0 && SET_UNION_FIELDS.has(k) && !mergePaths.has(fullPathSerialized);
1133
+ const isSetUnionField = path3.length === 0 && SET_UNION_FIELDS.has(k) && !mergePaths.has(fullPathSerialized);
1133
1134
  if (isSetUnionField && isArray(mergeIntoV) && isArray(mergeFromV)) {
1134
1135
  const seen = /* @__PURE__ */ new Set();
1135
1136
  const combined = [];
@@ -1162,9 +1163,9 @@ function mergeDicts(mergeInto, mergeFrom) {
1162
1163
  function recordFind(m, k) {
1163
1164
  return m[k];
1164
1165
  }
1165
- function getObjValueByPath(row, path2) {
1166
+ function getObjValueByPath(row, path3) {
1166
1167
  let curr = row;
1167
- for (const p of path2) {
1168
+ for (const p of path3) {
1168
1169
  if (!isObjectOrArray(curr)) {
1169
1170
  return null;
1170
1171
  }
@@ -1780,7 +1781,8 @@ var AclObjectType = z6.union([
1780
1781
  "org_member",
1781
1782
  "project_log",
1782
1783
  "org_project",
1783
- "org_audit_logs"
1784
+ "org_audit_logs",
1785
+ "project_group"
1784
1786
  ]),
1785
1787
  z6.null()
1786
1788
  ]);
@@ -1909,7 +1911,8 @@ var AsyncScoringState = z6.union([
1909
1911
  token: z6.string(),
1910
1912
  function_ids: z6.array(z6.unknown()),
1911
1913
  skip_logging: z6.union([z6.boolean(), z6.null()]).optional(),
1912
- triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional()
1914
+ triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional(),
1915
+ last_triggered_xact_id: z6.union([z6.string(), z6.number(), z6.null()]).optional()
1913
1916
  }),
1914
1917
  z6.object({ status: z6.literal("disabled") }),
1915
1918
  z6.null(),
@@ -1978,7 +1981,7 @@ var FunctionTypeEnum = z6.enum([
1978
1981
  "parameters",
1979
1982
  "sandbox"
1980
1983
  ]);
1981
- var NullableSavedFunctionId = z6.union([
1984
+ var FacetPreprocessorId = z6.union([
1982
1985
  z6.object({
1983
1986
  type: z6.literal("function"),
1984
1987
  id: z6.string(),
@@ -1989,10 +1992,23 @@ var NullableSavedFunctionId = z6.union([
1989
1992
  name: z6.string(),
1990
1993
  function_type: FunctionTypeEnum.optional().default("scorer")
1991
1994
  }),
1995
+ z6.object({ type: z6.literal("inline"), code: z6.string().min(1) }),
1992
1996
  z6.null()
1993
1997
  ]);
1998
+ var SavedFunctionId = z6.union([
1999
+ z6.object({
2000
+ type: z6.literal("function"),
2001
+ id: z6.string(),
2002
+ version: z6.string().optional()
2003
+ }),
2004
+ z6.object({
2005
+ type: z6.literal("global"),
2006
+ name: z6.string(),
2007
+ function_type: FunctionTypeEnum.optional().default("scorer")
2008
+ })
2009
+ ]);
1994
2010
  var TopicMapGenerationSettings = z6.object({
1995
- algorithm: z6.enum(["hdbscan", "kmeans"]),
2011
+ algorithm: z6.enum(["hdbscan", "kmeans", "community"]),
1996
2012
  dimension_reduction: z6.enum(["umap", "pca", "none"]),
1997
2013
  sample_size: z6.number().int().gt(0).optional(),
1998
2014
  n_clusters: z6.number().int().gt(0).optional(),
@@ -2004,6 +2020,7 @@ var TopicMapGenerationSettings = z6.object({
2004
2020
  var TopicMapData = z6.object({
2005
2021
  type: z6.literal("topic_map"),
2006
2022
  source_facet: z6.string(),
2023
+ source_facet_function: SavedFunctionId.and(z6.unknown()).optional(),
2007
2024
  embedding_model: z6.string(),
2008
2025
  bundle_key: z6.string().optional(),
2009
2026
  report_key: z6.string().optional(),
@@ -2017,7 +2034,7 @@ var TopicMapData = z6.object({
2017
2034
  });
2018
2035
  var BatchedFacetData = z6.object({
2019
2036
  type: z6.literal("batched_facet"),
2020
- preprocessor: NullableSavedFunctionId.and(z6.unknown()).optional(),
2037
+ preprocessor: FacetPreprocessorId.optional(),
2021
2038
  facets: z6.array(
2022
2039
  z6.object({
2023
2040
  name: z6.string(),
@@ -2278,18 +2295,6 @@ var ObjectReferenceNullish = z6.union([
2278
2295
  }),
2279
2296
  z6.null()
2280
2297
  ]);
2281
- var SavedFunctionId = z6.union([
2282
- z6.object({
2283
- type: z6.literal("function"),
2284
- id: z6.string(),
2285
- version: z6.string().optional()
2286
- }),
2287
- z6.object({
2288
- type: z6.literal("global"),
2289
- name: z6.string(),
2290
- function_type: FunctionTypeEnum.optional().default("scorer")
2291
- })
2292
- ]);
2293
2298
  var DatasetEvent = z6.object({
2294
2299
  id: z6.string(),
2295
2300
  _xact_id: z6.string(),
@@ -2511,7 +2516,7 @@ var ExtendedSavedFunctionId = z6.union([
2511
2516
  ]);
2512
2517
  var FacetData = z6.object({
2513
2518
  type: z6.literal("facet"),
2514
- preprocessor: NullableSavedFunctionId.and(z6.unknown()).optional(),
2519
+ preprocessor: FacetPreprocessorId.optional(),
2515
2520
  prompt: z6.string(),
2516
2521
  model: z6.string().optional(),
2517
2522
  embedding_model: z6.string().optional(),
@@ -3016,6 +3021,19 @@ var MessageRole = z6.enum([
3016
3021
  "model",
3017
3022
  "developer"
3018
3023
  ]);
3024
+ var NullableSavedFunctionId = z6.union([
3025
+ z6.object({
3026
+ type: z6.literal("function"),
3027
+ id: z6.string(),
3028
+ version: z6.string().optional()
3029
+ }),
3030
+ z6.object({
3031
+ type: z6.literal("global"),
3032
+ name: z6.string(),
3033
+ function_type: FunctionTypeEnum.optional().default("scorer")
3034
+ }),
3035
+ z6.null()
3036
+ ]);
3019
3037
  var ObjectReference = z6.object({
3020
3038
  object_type: z6.enum([
3021
3039
  "project_logs",
@@ -3037,6 +3055,7 @@ var TraceScope = z6.object({
3037
3055
  });
3038
3056
  var OnlineScoreConfig = z6.union([
3039
3057
  z6.object({
3058
+ status: AutomationStatus.optional(),
3040
3059
  sampling_rate: z6.number().gte(0).lte(1),
3041
3060
  scorers: z6.array(SavedFunctionId),
3042
3061
  btql_filter: z6.union([z6.string(), z6.null()]).optional(),
@@ -3117,6 +3136,72 @@ var Project = z6.object({
3117
3136
  user_id: z6.union([z6.string(), z6.null()]).optional(),
3118
3137
  settings: ProjectSettings.optional()
3119
3138
  });
3139
+ var WindowedAutomationConfig = z6.object({
3140
+ event_type: z6.literal("windowed"),
3141
+ product_origin: z6.union([z6.literal("patterns"), z6.null()]).optional(),
3142
+ status: AutomationStatus.optional(),
3143
+ threshold: z6.object({
3144
+ calculation: z6.object({
3145
+ type: z6.literal("btql"),
3146
+ btql_query: z6.string().min(1),
3147
+ output: z6.object({
3148
+ type: z6.literal("scalar"),
3149
+ value_column: z6.string().min(1)
3150
+ })
3151
+ }),
3152
+ policy: z6.object({
3153
+ condition: z6.object({
3154
+ type: z6.literal("threshold"),
3155
+ operator: z6.enum(["lt", "lte", "gt", "gte", "eq", "neq"]),
3156
+ threshold: z6.number()
3157
+ }),
3158
+ pending_seconds: z6.number().int().gte(0).lte(2592e3),
3159
+ no_data_behavior: z6.enum(["keep_last", "resolve", "alert"]),
3160
+ renotify_interval_seconds: z6.union([z6.number(), z6.null()]).optional(),
3161
+ notify_on_recovery: z6.boolean().optional().default(true)
3162
+ })
3163
+ }).optional(),
3164
+ window: z6.object({
3165
+ window_seconds: z6.number().int().gte(1).lte(2592e3),
3166
+ schedule: z6.union([
3167
+ z6.object({
3168
+ type: z6.literal("interval"),
3169
+ evaluation_interval_seconds: z6.number().int().gte(1).lte(2592e3)
3170
+ }),
3171
+ z6.object({
3172
+ type: z6.literal("cron"),
3173
+ cron_expression: z6.string().min(1),
3174
+ timezone: z6.union([z6.string(), z6.null()]).optional()
3175
+ })
3176
+ ]),
3177
+ evaluation_delay_seconds: z6.number().int().gte(0).lte(2592e3)
3178
+ }),
3179
+ loop: z6.object({
3180
+ prompt: z6.string().min(1).max(1e4),
3181
+ include_trigger_input: z6.boolean().optional().default(false),
3182
+ agent_slug: z6.string().min(1),
3183
+ auto_approve_tools: z6.array(z6.string().min(1)).optional().default([]),
3184
+ harness: z6.enum(["native", "codex", "claude-code"]).optional(),
3185
+ model: z6.string().min(1).optional(),
3186
+ reasoning_effort: z6.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional()
3187
+ }).optional(),
3188
+ actions: z6.array(
3189
+ z6.union([
3190
+ z6.object({
3191
+ type: z6.literal("webhook"),
3192
+ url: z6.string(),
3193
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3194
+ }),
3195
+ z6.object({
3196
+ type: z6.literal("slack"),
3197
+ workspace_id: z6.string(),
3198
+ channel: z6.string(),
3199
+ message_template: z6.string().optional(),
3200
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3201
+ })
3202
+ ])
3203
+ ).max(20).optional().default([])
3204
+ });
3120
3205
  var TopicAutomationFacetModel = z6.union([
3121
3206
  z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3122
3207
  z6.null()
@@ -3158,7 +3243,8 @@ var TopicDigestAutomationConfig = z6.object({
3158
3243
  type: z6.literal("slack"),
3159
3244
  workspace_id: z6.string(),
3160
3245
  channel: z6.string(),
3161
- message_template: z6.string().optional()
3246
+ message_template: z6.string().optional(),
3247
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3162
3248
  }),
3163
3249
  topic_map_function_ids: z6.array(z6.string()).max(10).optional()
3164
3250
  });
@@ -3172,15 +3258,21 @@ var ProjectAutomation = z6.object({
3172
3258
  config: z6.union([
3173
3259
  z6.object({
3174
3260
  event_type: z6.literal("logs"),
3261
+ status: AutomationStatus.optional(),
3175
3262
  btql_filter: z6.string(),
3176
3263
  interval_seconds: z6.number().gte(1).lte(2592e3),
3177
3264
  action: z6.union([
3178
- z6.object({ type: z6.literal("webhook"), url: z6.string() }),
3265
+ z6.object({
3266
+ type: z6.literal("webhook"),
3267
+ url: z6.string(),
3268
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3269
+ }),
3179
3270
  z6.object({
3180
3271
  type: z6.literal("slack"),
3181
3272
  workspace_id: z6.string(),
3182
3273
  channel: z6.string(),
3183
- message_template: z6.string().optional()
3274
+ message_template: z6.string().optional(),
3275
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3184
3276
  })
3185
3277
  ])
3186
3278
  }),
@@ -3231,21 +3323,38 @@ var ProjectAutomation = z6.object({
3231
3323
  }),
3232
3324
  z6.object({
3233
3325
  event_type: z6.literal("environment_update"),
3326
+ status: AutomationStatus.optional(),
3234
3327
  environment_filter: z6.array(z6.string()).optional(),
3235
3328
  action: z6.union([
3236
- z6.object({ type: z6.literal("webhook"), url: z6.string() }),
3329
+ z6.object({
3330
+ type: z6.literal("webhook"),
3331
+ url: z6.string(),
3332
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3333
+ }),
3237
3334
  z6.object({
3238
3335
  type: z6.literal("slack"),
3239
3336
  workspace_id: z6.string(),
3240
3337
  channel: z6.string(),
3241
- message_template: z6.string().optional()
3338
+ message_template: z6.string().optional(),
3339
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3242
3340
  })
3243
3341
  ])
3244
3342
  }),
3343
+ WindowedAutomationConfig,
3245
3344
  TopicAutomationConfig,
3246
3345
  TopicDigestAutomationConfig
3247
3346
  ])
3248
3347
  });
3348
+ var ProjectGroup = z6.object({
3349
+ id: z6.string().uuid(),
3350
+ org_id: z6.string().uuid(),
3351
+ user_id: z6.union([z6.string(), z6.null()]).optional(),
3352
+ created: z6.union([z6.string(), z6.null()]).optional(),
3353
+ name: z6.string(),
3354
+ description: z6.union([z6.string(), z6.null()]).optional(),
3355
+ deleted_at: z6.union([z6.string(), z6.null()]).optional(),
3356
+ member_projects: z6.array(z6.string().uuid()).max(1e4)
3357
+ });
3249
3358
  var ProjectLogsEvent = z6.object({
3250
3359
  id: z6.string(),
3251
3360
  _xact_id: z6.string(),
@@ -3463,7 +3572,8 @@ var RunEval = z6.object({
3463
3572
  dataset_environment: z6.union([z6.string(), z6.null()]).optional(),
3464
3573
  _internal_btql: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
3465
3574
  }),
3466
- z6.object({ data: z6.array(z6.unknown()) })
3575
+ z6.object({ data: z6.array(z6.unknown()) }),
3576
+ z6.object({ experiment_name: z6.string() })
3467
3577
  ]),
3468
3578
  name: z6.string().optional(),
3469
3579
  parameters: z6.object({}).partial().passthrough().optional(),
@@ -3668,7 +3778,9 @@ var View = z6.object({
3668
3778
  "for_review_datasets"
3669
3779
  ]),
3670
3780
  name: z6.string(),
3781
+ description: z6.union([z6.string(), z6.null()]).optional(),
3671
3782
  created: z6.union([z6.string(), z6.null()]).optional(),
3783
+ updated_at: z6.union([z6.string(), z6.null()]).optional(),
3672
3784
  view_data: ViewData.optional(),
3673
3785
  options: ViewOptions.optional(),
3674
3786
  user_id: z6.union([z6.string(), z6.null()]).optional(),
@@ -4252,10 +4364,10 @@ var DiskCache = class {
4252
4364
  return;
4253
4365
  }
4254
4366
  const stats = await Promise.all(
4255
- paths.map(async (path2) => {
4256
- const stat2 = await isomorph_default.stat(path2);
4367
+ paths.map(async (path3) => {
4368
+ const stat2 = await isomorph_default.stat(path3);
4257
4369
  return {
4258
- path: path2,
4370
+ path: path3,
4259
4371
  mtime: stat2.mtime.getTime()
4260
4372
  };
4261
4373
  })
@@ -4910,6 +5022,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
4910
5022
  var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
4911
5023
  "braintrust.initial-span-write-as-merge"
4912
5024
  );
5025
+ var RESUME_SPAN_WITHOUT_INITIAL_WRITE = /* @__PURE__ */ Symbol(
5026
+ "braintrust.resume-span-without-initial-write"
5027
+ );
4913
5028
  var INTERNAL_SPAN_CONTEXT = /* @__PURE__ */ Symbol("braintrust.internal-span-context");
4914
5029
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
4915
5030
  "braintrust.currentSpanStore"
@@ -5507,9 +5622,9 @@ var HTTPConnection = class _HTTPConnection {
5507
5622
  this.headers["Authorization"] = `Bearer ${this.token}`;
5508
5623
  }
5509
5624
  }
5510
- async get(path2, params = void 0, config) {
5625
+ async get(path3, params = void 0, config) {
5511
5626
  const { headers, ...rest } = config || {};
5512
- const url = new URL(_urljoin(this.base_url, path2));
5627
+ const url = new URL(_urljoin(this.base_url, path3));
5513
5628
  url.search = new URLSearchParams(
5514
5629
  params ? Object.entries(params).filter(([_, v]) => v !== void 0).flatMap(
5515
5630
  ([k, v]) => v !== void 0 ? typeof v === "string" ? [[k, v]] : v.map((x) => [k, x]) : []
@@ -5530,7 +5645,7 @@ var HTTPConnection = class _HTTPConnection {
5530
5645
  })
5531
5646
  );
5532
5647
  }
5533
- async post(path2, params, config, retries = 0) {
5648
+ async post(path3, params, config, retries = 0) {
5534
5649
  const { headers, ...rest } = config || {};
5535
5650
  const this_fetch = this.fetch;
5536
5651
  const this_base_url = this.base_url;
@@ -5539,7 +5654,7 @@ var HTTPConnection = class _HTTPConnection {
5539
5654
  for (let i = 0; i < tries; i++) {
5540
5655
  try {
5541
5656
  return await checkResponse(
5542
- await this_fetch(_urljoin(this_base_url, path2), {
5657
+ await this_fetch(_urljoin(this_base_url, path3), {
5543
5658
  method: "POST",
5544
5659
  headers: {
5545
5660
  Accept: "application/json",
@@ -5560,7 +5675,7 @@ var HTTPConnection = class _HTTPConnection {
5560
5675
  throw error;
5561
5676
  }
5562
5677
  debugLogger.debug(
5563
- `Retrying API request ${path2} after ${formatHTTPError(error)}`
5678
+ `Retrying API request ${path3} after ${formatHTTPError(error)}`
5564
5679
  );
5565
5680
  const sleepTimeMs = HTTP_RETRY_BASE_SLEEP_TIME_S * 1e3 * 2 ** i + Math.random() * HTTP_RETRY_JITTER_MS;
5566
5681
  debugLogger.info(
@@ -6133,6 +6248,30 @@ function updateSpan({
6133
6248
  event
6134
6249
  });
6135
6250
  }
6251
+ function _internalResumeSpan({
6252
+ exported,
6253
+ state
6254
+ }) {
6255
+ const resolvedState = state ?? _globalState;
6256
+ const components = SpanComponentsV4.fromStr(exported);
6257
+ const { row_id, root_span_id, span_id } = components.data;
6258
+ if (!row_id || !root_span_id || !span_id) {
6259
+ throw new Error("Only exported root spans can be resumed");
6260
+ }
6261
+ return new SpanImpl({
6262
+ state: resolvedState,
6263
+ parentObjectType: components.data.object_type,
6264
+ parentObjectId: new LazyValue(
6265
+ spanComponentsToObjectIdLambda(resolvedState, components)
6266
+ ),
6267
+ parentComputeObjectMetadataArgs: void 0,
6268
+ parentSpanIds: { parentSpanIds: [], rootSpanId: root_span_id },
6269
+ spanId: span_id,
6270
+ event: { id: row_id },
6271
+ propagatedEvent: components.data.propagated_event ?? void 0,
6272
+ [RESUME_SPAN_WITHOUT_INITIAL_WRITE]: true
6273
+ });
6274
+ }
6136
6275
  function spanComponentsToObjectIdLambda(state, components) {
6137
6276
  if (components.data.object_id) {
6138
6277
  const ret = components.data.object_id;
@@ -9013,7 +9152,7 @@ var ObjectFetcher = class {
9013
9152
  const objectId = await this.id;
9014
9153
  const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
9015
9154
  const internalLimit = getInternalBtqlLimit(this._internal_btql);
9016
- const limit = batchSize !== void 0 ? batchSize : internalLimit ?? batchLimit;
9155
+ let remainingLimit = internalLimit;
9017
9156
  const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
9018
9157
  Object.entries(this._internal_btql ?? {}).filter(
9019
9158
  ([key]) => key !== "cursor" && key !== "limit" && key !== "select" && key !== "from"
@@ -9022,6 +9161,10 @@ var ObjectFetcher = class {
9022
9161
  let cursor = void 0;
9023
9162
  let iterations = 0;
9024
9163
  while (true) {
9164
+ if (remainingLimit !== void 0 && remainingLimit <= 0) {
9165
+ return;
9166
+ }
9167
+ const limit = remainingLimit === void 0 ? batchLimit : Math.min(batchLimit, remainingLimit);
9025
9168
  const resp = await state.apiConn().post(
9026
9169
  `btql`,
9027
9170
  {
@@ -9061,7 +9204,14 @@ var ObjectFetcher = class {
9061
9204
  const respJson = await resp.json();
9062
9205
  const mutate = this.mutateRecord;
9063
9206
  for (const record of respJson.data ?? []) {
9064
- yield mutate ? mutate(record) : record;
9207
+ if (remainingLimit !== void 0 && remainingLimit <= 0) {
9208
+ return;
9209
+ }
9210
+ const mutatedRecord = mutate ? mutate(record) : record;
9211
+ if (remainingLimit !== void 0) {
9212
+ remainingLimit--;
9213
+ }
9214
+ yield mutatedRecord;
9065
9215
  }
9066
9216
  if (!respJson.cursor) {
9067
9217
  break;
@@ -9581,7 +9731,9 @@ var SpanImpl = class _SpanImpl {
9581
9731
  this._rootSpanId = resolvedIds.rootSpanId;
9582
9732
  this._spanParents = resolvedIds.spanParents;
9583
9733
  this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
9584
- this.logInternal({ event, internalData });
9734
+ if (!args[RESUME_SPAN_WITHOUT_INITIAL_WRITE]) {
9735
+ this.logInternal({ event, internalData });
9736
+ }
9585
9737
  this.isMerge = true;
9586
9738
  }
9587
9739
  getParentInfo() {
@@ -12311,6 +12463,22 @@ function processInputAttachments(input) {
12311
12463
  };
12312
12464
  }
12313
12465
  }
12466
+ const voyageBase64Key = node.type === "image_base64" ? Object.hasOwn(node, "imageBase64") ? "imageBase64" : "image_base64" : node.type === "video_base64" ? Object.hasOwn(node, "videoBase64") ? "videoBase64" : "video_base64" : void 0;
12467
+ const voyageBase64Value = voyageBase64Key ? node[voyageBase64Key] : void 0;
12468
+ if (voyageBase64Key && typeof voyageBase64Value === "string" && voyageBase64Value.startsWith("data:")) {
12469
+ const mediaType = inferMediaTypeFromDataUrl(
12470
+ voyageBase64Value,
12471
+ node.type === "video_base64" ? "video/mp4" : "image/png"
12472
+ );
12473
+ const filename = `${node.type === "video_base64" ? "video" : "image"}.${getExtensionFromMediaType(mediaType)}`;
12474
+ const attachment = toAttachment(voyageBase64Value, mediaType, filename);
12475
+ if (attachment) {
12476
+ return {
12477
+ ...node,
12478
+ [voyageBase64Key]: attachment
12479
+ };
12480
+ }
12481
+ }
12314
12482
  if (node.type === "file" && node.file && typeof node.file === "object" && typeof node.file.file_data === "string" && node.file.file_data.startsWith("data:")) {
12315
12483
  const mediaType = inferMediaTypeFromDataUrl(
12316
12484
  node.file.file_data,
@@ -13493,7 +13661,7 @@ function resolveDenyOutputPaths(event, defaultDenyOutputPaths) {
13493
13661
  return defaultDenyOutputPaths;
13494
13662
  }
13495
13663
  const runtimeDenyOutputPaths = firstArgument2[RUNTIME_DENY_OUTPUT_PATHS];
13496
- if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((path2) => typeof path2 === "string")) {
13664
+ if (Array.isArray(runtimeDenyOutputPaths) && runtimeDenyOutputPaths.every((path3) => typeof path3 === "string")) {
13497
13665
  return runtimeDenyOutputPaths;
13498
13666
  }
13499
13667
  return defaultDenyOutputPaths;
@@ -15255,11 +15423,11 @@ function processAISDKOutput(output, denyOutputPaths) {
15255
15423
  if (!output) return output;
15256
15424
  const merged = extractSerializableOutputFields(output);
15257
15425
  const deleteOutputPaths = denyOutputPaths.filter(
15258
- (path2) => path2.toLowerCase().endsWith("headers")
15426
+ (path3) => path3.toLowerCase().endsWith("headers")
15259
15427
  );
15260
15428
  const sanitized = omit(merged, denyOutputPaths, deleteOutputPaths);
15261
- for (const path2 of TRANSPORT_PAYLOAD_ROOT_PATHS) {
15262
- const stack = [{ obj: sanitized, keys: parsePath(path2) }];
15429
+ for (const path3 of TRANSPORT_PAYLOAD_ROOT_PATHS) {
15430
+ const stack = [{ obj: sanitized, keys: parsePath(path3) }];
15263
15431
  while (stack.length > 0) {
15264
15432
  const entry = stack.pop();
15265
15433
  if (!entry || entry.keys.length === 0) {
@@ -15698,11 +15866,11 @@ function firstNumber(...values) {
15698
15866
  function deepCopy(obj) {
15699
15867
  return JSON.parse(JSON.stringify(obj));
15700
15868
  }
15701
- function parsePath(path2) {
15869
+ function parsePath(path3) {
15702
15870
  const keys = [];
15703
15871
  let current = "";
15704
- for (let i = 0; i < path2.length; i++) {
15705
- const char = path2[i];
15872
+ for (let i = 0; i < path3.length; i++) {
15873
+ const char = path3[i];
15706
15874
  if (char === ".") {
15707
15875
  if (current) {
15708
15876
  keys.push(current);
@@ -15715,8 +15883,8 @@ function parsePath(path2) {
15715
15883
  }
15716
15884
  let bracketContent = "";
15717
15885
  i++;
15718
- while (i < path2.length && path2[i] !== "]") {
15719
- bracketContent += path2[i];
15886
+ while (i < path3.length && path3[i] !== "]") {
15887
+ bracketContent += path3[i];
15720
15888
  i++;
15721
15889
  }
15722
15890
  if (bracketContent === "") {
@@ -15771,9 +15939,9 @@ function omitAtPath(obj, keys, deleteLeaf = false) {
15771
15939
  function omit(obj, paths, deletePaths = []) {
15772
15940
  const result = deepCopy(obj);
15773
15941
  const deletePathSet = new Set(deletePaths);
15774
- for (const path2 of paths) {
15775
- const keys = parsePath(path2);
15776
- omitAtPath(result, keys, deletePathSet.has(path2));
15942
+ for (const path3 of paths) {
15943
+ const keys = parsePath(path3);
15944
+ omitAtPath(result, keys, deletePathSet.has(path3));
15777
15945
  }
15778
15946
  return result;
15779
15947
  }
@@ -16999,17 +17167,20 @@ var FlueObserveBridge = class {
16999
17167
  return;
17000
17168
  }
17001
17169
  const metadata = {
17170
+ ...event.runId ? this.runsById.get(event.runId)?.metadata : {},
17002
17171
  ...extractEventMetadata(event),
17003
17172
  "flue.operation": event.operationKind,
17004
17173
  provider: "flue"
17005
17174
  };
17006
17175
  const parent = this.parentSpanForEvent(event);
17007
- const span = startFlueSpan(parent, {
17176
+ const args = {
17008
17177
  name: `flue.${event.operationKind}`,
17009
17178
  spanAttributes: { type: "task" /* TASK */ },
17010
17179
  startTime: eventTime(event.timestamp),
17011
17180
  event: { metadata }
17012
- });
17181
+ };
17182
+ const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
17183
+ const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
17013
17184
  this.operationsById.set(event.operationId, { metadata, span });
17014
17185
  }
17015
17186
  handleOperation(event) {
@@ -17024,6 +17195,11 @@ var FlueObserveBridge = class {
17024
17195
  ...event.isError !== void 0 ? { "flue.is_error": event.isError } : {},
17025
17196
  ...event.usage ? { "flue.usage": event.usage } : {}
17026
17197
  };
17198
+ const input = flueOperationInput(event);
17199
+ if (!state.loggedInput && input !== void 0) {
17200
+ safeLog(state.span, { input });
17201
+ state.loggedInput = true;
17202
+ }
17027
17203
  this.finishPendingChildrenForOperation(event, output);
17028
17204
  safeLog(state.span, {
17029
17205
  ...event.isError ? { error: toLoggedError(event.errorInfo ?? event.error) } : {},
@@ -17040,6 +17216,8 @@ var FlueObserveBridge = class {
17040
17216
  return;
17041
17217
  }
17042
17218
  const input = flueTurnRequestInput(event);
17219
+ const operation = event.operationId ? this.operationsById.get(event.operationId) : void 0;
17220
+ const turnInput = prepareFlueTurnInput(event, input, operation);
17043
17221
  const model = flueTurnRequestModel(event);
17044
17222
  const provider = flueTurnRequestProvider(event);
17045
17223
  const api = flueTurnRequestApi(event);
@@ -17052,8 +17230,7 @@ var FlueObserveBridge = class {
17052
17230
  ...provider ? { "flue.provider": provider } : {},
17053
17231
  ...event.purpose ? { "flue.turn_purpose": event.purpose } : {},
17054
17232
  ...reasoning ? { reasoning } : {},
17055
- ...input?.systemPrompt ? { "flue.system_prompt": input.systemPrompt } : {},
17056
- ...input?.tools ? { tools: input.tools } : {}
17233
+ ...turnInput.metadata
17057
17234
  };
17058
17235
  const parent = this.parentSpanForTurn(event);
17059
17236
  const span = startFlueSpan(parent, {
@@ -17061,11 +17238,14 @@ var FlueObserveBridge = class {
17061
17238
  spanAttributes: { type: "llm" /* LLM */ },
17062
17239
  startTime: eventTime(event.timestamp),
17063
17240
  event: {
17064
- input: input?.messages,
17241
+ input: turnInput.messages,
17065
17242
  metadata
17066
17243
  }
17067
17244
  });
17068
- this.logOperationInput(event.operationId, input?.messages ?? input);
17245
+ this.logOperationInput(
17246
+ event.operationId,
17247
+ latestUserMessageInput(input?.messages)
17248
+ );
17069
17249
  this.turnsByKey.set(key, { metadata, span });
17070
17250
  }
17071
17251
  handleTurn(event) {
@@ -17312,16 +17492,20 @@ var FlueObserveBridge = class {
17312
17492
  }
17313
17493
  startSyntheticOperation(event) {
17314
17494
  const metadata = {
17495
+ ...event.runId ? this.runsById.get(event.runId)?.metadata : {},
17315
17496
  ...extractEventMetadata(event),
17316
17497
  "flue.operation": event.operationKind,
17317
17498
  provider: "flue"
17318
17499
  };
17319
- const span = startFlueSpan(this.parentSpanForEvent(event), {
17500
+ const args = {
17320
17501
  name: `flue.${event.operationKind}`,
17321
17502
  spanAttributes: { type: "task" /* TASK */ },
17322
17503
  startTime: eventTime(event.timestamp),
17323
17504
  event: { metadata }
17324
- });
17505
+ };
17506
+ const parent = this.parentSpanForEvent(event);
17507
+ const runSpan = event.runId ? this.runsById.get(event.runId)?.span : void 0;
17508
+ const span = event.operationKind === "prompt" && (!parent || parent === runSpan) ? startFlueRootSpan(args) : startFlueSpan(parent, args);
17325
17509
  return { metadata, span };
17326
17510
  }
17327
17511
  startSyntheticTurn(event) {
@@ -17500,6 +17684,71 @@ function flueRunInput(event) {
17500
17684
  function flueTurnRequestInput(event) {
17501
17685
  return event.request?.input ?? event.input;
17502
17686
  }
17687
+ function prepareFlueTurnInput(event, input, operation) {
17688
+ const messages = input?.messages;
17689
+ const tracksUserTurn = event.purpose === "agent" && operation?.metadata["flue.operation"] === "prompt" && Array.isArray(messages);
17690
+ if (!tracksUserTurn) {
17691
+ return {
17692
+ messages,
17693
+ metadata: {
17694
+ ...input?.systemPrompt ? { "flue.system_prompt": input.systemPrompt } : {},
17695
+ ...input?.tools ? { tools: input.tools } : {}
17696
+ }
17697
+ };
17698
+ }
17699
+ const previous = operation.turnInputState;
17700
+ const previousMessageCount = previous?.messageCount ?? 0;
17701
+ const boundaryFingerprint = messages.length > 0 ? fingerprintJsonValue(messages[messages.length - 1]) : void 0;
17702
+ const continuesPreviousInput = previous !== void 0 && messages.length >= previousMessageCount && (previousMessageCount === 0 || previous.boundaryFingerprint !== void 0 && previous.boundaryFingerprint === fingerprintJsonValue(messages[previousMessageCount - 1]));
17703
+ const inputMode = previous === void 0 ? "full" : continuesPreviousInput ? "delta" : "reset";
17704
+ const systemPromptFingerprint = fingerprintJsonValue(input?.systemPrompt);
17705
+ const toolsFingerprint = fingerprintJsonValue(input?.tools);
17706
+ operation.turnInputState = {
17707
+ ...boundaryFingerprint !== void 0 ? { boundaryFingerprint } : {},
17708
+ messageCount: messages.length,
17709
+ ...systemPromptFingerprint !== void 0 ? { systemPromptFingerprint } : {},
17710
+ ...toolsFingerprint !== void 0 ? { toolsFingerprint } : {}
17711
+ };
17712
+ return {
17713
+ messages: continuesPreviousInput ? messages.slice(previousMessageCount) : messages,
17714
+ metadata: {
17715
+ "flue.input_mode": inputMode,
17716
+ ...continuesPreviousInput ? { "flue.input_message_offset": previousMessageCount } : {},
17717
+ ...input?.systemPrompt && (!continuesPreviousInput || systemPromptFingerprint !== previous?.systemPromptFingerprint) ? { "flue.system_prompt": input.systemPrompt } : {},
17718
+ ...input?.tools && (!continuesPreviousInput || toolsFingerprint !== previous?.toolsFingerprint) ? { tools: input.tools } : {}
17719
+ }
17720
+ };
17721
+ }
17722
+ function fingerprintJsonValue(value) {
17723
+ try {
17724
+ const serialized = JSON.stringify(value);
17725
+ if (serialized === void 0) {
17726
+ return void 0;
17727
+ }
17728
+ let hash = 2166136261;
17729
+ for (let i = 0; i < serialized.length; i++) {
17730
+ hash = Math.imul(hash ^ serialized.charCodeAt(i), 16777619);
17731
+ }
17732
+ return `${serialized.length}:${hash >>> 0}`;
17733
+ } catch {
17734
+ return void 0;
17735
+ }
17736
+ }
17737
+ function latestUserMessageInput(messages) {
17738
+ if (!messages) {
17739
+ return void 0;
17740
+ }
17741
+ for (let i = messages.length - 1; i >= 0; i--) {
17742
+ const message = messages[i];
17743
+ if (isObjectLike(message) && Reflect.get(message, "role") === "user") {
17744
+ return [message];
17745
+ }
17746
+ }
17747
+ return void 0;
17748
+ }
17749
+ function flueOperationInput(event) {
17750
+ return typeof event.agentInput?.text === "string" ? [{ content: event.agentInput.text, role: "user" }] : void 0;
17751
+ }
17503
17752
  function flueTurnRequestModel(event) {
17504
17753
  return event.request?.requestedModel ?? event.request?.model ?? event.model;
17505
17754
  }
@@ -17657,6 +17906,21 @@ function startFlueSpan(parent, args) {
17657
17906
  withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE)
17658
17907
  );
17659
17908
  }
17909
+ function startFlueRootSpan(args) {
17910
+ const state = _internalGetGlobalState();
17911
+ const spanId = state.idGenerator.getSpanId();
17912
+ const rootSpanId = state.idGenerator.shareRootSpanId() ? spanId : state.idGenerator.getTraceId();
17913
+ return withCurrent(
17914
+ NOOP_SPAN,
17915
+ () => startSpan({
17916
+ ...withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE),
17917
+ parentSpanIds: { parentSpanIds: [], rootSpanId },
17918
+ spanId,
17919
+ state
17920
+ }),
17921
+ state
17922
+ );
17923
+ }
17660
17924
  function runWithCurrentSpanStore(span, next) {
17661
17925
  const state = _internalGetGlobalState();
17662
17926
  const contextManager = state?.contextManager;
@@ -19152,12 +19416,30 @@ function logInstrumentationError2(context, error) {
19152
19416
 
19153
19417
  // src/wrappers/anthropic-tokens-util.ts
19154
19418
  function finalizeAnthropicTokens(metrics) {
19155
- const prompt_tokens = (metrics.prompt_tokens || 0) + (metrics.prompt_cached_tokens || 0) + (metrics.prompt_cache_creation_tokens || 0);
19156
- return {
19419
+ const hasSplitCacheCreationTokens = metrics.prompt_cache_creation_5m_tokens !== void 0 || metrics.prompt_cache_creation_1h_tokens !== void 0;
19420
+ const splitCacheCreationTokens = (metrics.prompt_cache_creation_5m_tokens || 0) + (metrics.prompt_cache_creation_1h_tokens || 0);
19421
+ const aggregateCacheCreationTokens = metrics.prompt_cache_creation_tokens || 0;
19422
+ const effectiveCacheCreationTokens = Math.max(
19423
+ aggregateCacheCreationTokens,
19424
+ splitCacheCreationTokens
19425
+ );
19426
+ const prompt_tokens = (metrics.prompt_tokens || 0) + (metrics.prompt_cached_tokens || 0) + effectiveCacheCreationTokens;
19427
+ const finalized = {
19157
19428
  ...metrics,
19158
19429
  prompt_tokens,
19159
19430
  tokens: prompt_tokens + (metrics.completion_tokens || 0)
19160
19431
  };
19432
+ if (hasSplitCacheCreationTokens && splitCacheCreationTokens >= aggregateCacheCreationTokens) {
19433
+ delete finalized.prompt_cache_creation_tokens;
19434
+ }
19435
+ return finalized;
19436
+ }
19437
+ function toNumericMetrics(metrics) {
19438
+ return Object.fromEntries(
19439
+ Object.entries(metrics).filter(
19440
+ (entry) => entry[1] !== void 0
19441
+ )
19442
+ );
19161
19443
  }
19162
19444
  function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens = 0) {
19163
19445
  const cacheTokens = {};
@@ -19716,6 +19998,18 @@ function parseMetricsFromUsage2(usage) {
19716
19998
  saveIfExistsTo("output_tokens", "completion_tokens");
19717
19999
  saveIfExistsTo("cache_read_input_tokens", "prompt_cached_tokens");
19718
20000
  saveIfExistsTo("cache_creation_input_tokens", "prompt_cache_creation_tokens");
20001
+ if (isObject(usage.cache_creation)) {
20002
+ const cacheCreation = usage.cache_creation;
20003
+ for (const [source, target] of [
20004
+ ["ephemeral_5m_input_tokens", "prompt_cache_creation_5m_tokens"],
20005
+ ["ephemeral_1h_input_tokens", "prompt_cache_creation_1h_tokens"]
20006
+ ]) {
20007
+ const value = cacheCreation[source];
20008
+ if (typeof value === "number") {
20009
+ metrics[target] = value;
20010
+ }
20011
+ }
20012
+ }
19719
20013
  if (isObject(usage.server_tool_use)) {
19720
20014
  for (const [name, value] of Object.entries(usage.server_tool_use)) {
19721
20015
  if (typeof value === "number") {
@@ -20687,37 +20981,97 @@ function seedTaskToolUseIdMapping(taskIdToToolUseId, message) {
20687
20981
  taskIdToToolUseId.set(message.task_id, message.tool_use_id);
20688
20982
  }
20689
20983
  }
20690
- function extractUsageFromMessage(message) {
20691
- const metrics = {};
20692
- let usage;
20693
- if (message.type === "assistant") {
20694
- usage = message.message?.usage;
20695
- } else if (message.type === "result") {
20696
- usage = message.usage;
20697
- }
20984
+ function tokenCount(value) {
20985
+ return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value) && value >= 0 ? value : void 0;
20986
+ }
20987
+ function copyUsage(usage) {
20698
20988
  if (!usage || typeof usage !== "object") {
20699
- return metrics;
20989
+ return void 0;
20990
+ }
20991
+ const copy = {};
20992
+ for (const key of [
20993
+ "input_tokens",
20994
+ "output_tokens",
20995
+ "cache_read_input_tokens",
20996
+ "cache_creation_input_tokens"
20997
+ ]) {
20998
+ const value = tokenCount(Reflect.get(usage, key));
20999
+ if (value !== void 0) {
21000
+ copy[key] = value;
21001
+ }
21002
+ }
21003
+ const cacheCreation = Reflect.get(usage, "cache_creation");
21004
+ if (cacheCreation && typeof cacheCreation === "object") {
21005
+ const cacheCreationCopy = {};
21006
+ for (const key of [
21007
+ "ephemeral_5m_input_tokens",
21008
+ "ephemeral_1h_input_tokens"
21009
+ ]) {
21010
+ const value = tokenCount(Reflect.get(cacheCreation, key));
21011
+ if (value !== void 0) {
21012
+ cacheCreationCopy[key] = value;
21013
+ }
21014
+ }
21015
+ if (Object.keys(cacheCreationCopy).length > 0) {
21016
+ copy.cache_creation = cacheCreationCopy;
21017
+ }
21018
+ }
21019
+ return Object.keys(copy).length > 0 ? copy : void 0;
21020
+ }
21021
+ function mergeUsage(base, override) {
21022
+ if (!base || !override) {
21023
+ return override ?? base;
21024
+ }
21025
+ const cacheCreation = base.cache_creation || override.cache_creation ? { ...base.cache_creation, ...override.cache_creation } : void 0;
21026
+ return {
21027
+ ...base,
21028
+ ...override,
21029
+ ...cacheCreation && { cache_creation: cacheCreation }
21030
+ };
21031
+ }
21032
+ function extractUsage(usage, includeOutput) {
21033
+ const metrics = {};
21034
+ if (!usage) {
21035
+ return {};
20700
21036
  }
20701
21037
  const inputTokens = getNumberProperty(usage, "input_tokens");
20702
21038
  if (inputTokens !== void 0) {
20703
21039
  metrics.prompt_tokens = inputTokens;
20704
21040
  }
20705
- const outputTokens = getNumberProperty(usage, "output_tokens");
20706
- if (outputTokens !== void 0) {
20707
- metrics.completion_tokens = outputTokens;
21041
+ if (includeOutput) {
21042
+ const outputTokens = getNumberProperty(usage, "output_tokens");
21043
+ if (outputTokens !== void 0) {
21044
+ metrics.completion_tokens = outputTokens;
21045
+ }
20708
21046
  }
20709
21047
  const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
20710
21048
  const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
20711
- if (cacheReadTokens > 0 || cacheCreationTokens > 0) {
20712
- Object.assign(
20713
- metrics,
20714
- extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
20715
- );
21049
+ Object.assign(
21050
+ metrics,
21051
+ extractAnthropicCacheTokens(cacheReadTokens, cacheCreationTokens)
21052
+ );
21053
+ const cacheCreation5mTokens = getNumberProperty(
21054
+ usage.cache_creation,
21055
+ "ephemeral_5m_input_tokens"
21056
+ );
21057
+ const cacheCreation1hTokens = getNumberProperty(
21058
+ usage.cache_creation,
21059
+ "ephemeral_1h_input_tokens"
21060
+ );
21061
+ if (cacheCreation5mTokens !== void 0) {
21062
+ metrics.prompt_cache_creation_5m_tokens = cacheCreation5mTokens;
20716
21063
  }
20717
- if (Object.keys(metrics).length > 0) {
20718
- Object.assign(metrics, finalizeAnthropicTokens(metrics));
21064
+ if (cacheCreation1hTokens !== void 0) {
21065
+ metrics.prompt_cache_creation_1h_tokens = cacheCreation1hTokens;
20719
21066
  }
20720
- return metrics;
21067
+ if (Object.keys(metrics).length === 0) {
21068
+ return {};
21069
+ }
21070
+ const finalized = finalizeAnthropicTokens(metrics);
21071
+ if (metrics.completion_tokens === void 0) {
21072
+ delete finalized.tokens;
21073
+ }
21074
+ return toNumericMetrics(finalized);
20721
21075
  }
20722
21076
  function buildLLMInput(promptMessages, conversationHistory) {
20723
21077
  const inputParts = [...promptMessages, ...conversationHistory];
@@ -20751,16 +21105,16 @@ function buildRootPromptMessages(prompt, capturedPromptMessages) {
20751
21105
  function formatCapturedMessages(messages) {
20752
21106
  return messages.length > 0 ? messages : [];
20753
21107
  }
20754
- async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, existingSpan) {
21108
+ async function createLLMSpanForMessages(messages, promptMessages, conversationHistory, options, startTime, parentSpan, usage, hasFinalOutputUsage, existingSpan) {
20755
21109
  if (messages.length === 0) {
20756
21110
  return void 0;
20757
21111
  }
20758
21112
  const lastMessage = messages[messages.length - 1];
20759
- if (lastMessage.type !== "assistant" || !lastMessage.message?.usage) {
21113
+ if (lastMessage.type !== "assistant") {
20760
21114
  return void 0;
20761
21115
  }
20762
- const model = lastMessage.message.model || options.model;
20763
- const usage = extractUsageFromMessage(lastMessage);
21116
+ const model = lastMessage.message?.model || options.model;
21117
+ const metrics = options.includePartialMessages ? extractUsage(usage, hasFinalOutputUsage) : {};
20764
21118
  const input = buildLLMInput(promptMessages, conversationHistory);
20765
21119
  const outputs = messages.map(
20766
21120
  (m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
@@ -20782,8 +21136,8 @@ async function createLLMSpanForMessages(messages, promptMessages, conversationHi
20782
21136
  );
20783
21137
  span.log({
20784
21138
  input,
20785
- metadata: model ? { model } : void 0,
20786
- metrics: usage,
21139
+ metadata: { ...model && { model }, provider: "anthropic" },
21140
+ ...Object.keys(metrics).length > 0 ? { metrics } : {},
20787
21141
  output: outputs
20788
21142
  });
20789
21143
  const spanExport = await span.export();
@@ -20873,11 +21227,17 @@ function prepareLocalToolHandlersInMcpServers(mcpServers) {
20873
21227
  }
20874
21228
  return { hasLocalToolHandlers, localToolHookNames };
20875
21229
  }
20876
- function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
21230
+ function createToolTracingHooks(resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
20877
21231
  const preToolUse = async (input, toolUseID) => {
20878
21232
  if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
20879
21233
  return {};
20880
21234
  }
21235
+ if (!toolUseToParent.has(toolUseID) && input.agent_id) {
21236
+ const parentToolUseId = taskIdToToolUseId.get(input.agent_id);
21237
+ if (parentToolUseId) {
21238
+ toolUseToParent.set(toolUseID, parentToolUseId);
21239
+ }
21240
+ }
20881
21241
  if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
20882
21242
  return {};
20883
21243
  }
@@ -21073,9 +21433,6 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
21073
21433
  }
21074
21434
  const metadata = {
21075
21435
  ...subAgentDetailsToMetadata(details),
21076
- ...input.agent_transcript_path && {
21077
- "claude_agent_sdk.agent_transcript_path": input.agent_transcript_path
21078
- },
21079
21436
  "claude_agent_sdk.stop_hook_active": input.stop_hook_active
21080
21437
  };
21081
21438
  try {
@@ -21097,7 +21454,7 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
21097
21454
  subagentStop
21098
21455
  };
21099
21456
  }
21100
- function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
21457
+ function injectTracingHooks(options, resolveParentSpan, taskIdToToolUseId, toolUseToParent, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
21101
21458
  const {
21102
21459
  preToolUse,
21103
21460
  postToolUse,
@@ -21106,6 +21463,8 @@ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localTo
21106
21463
  subagentStop
21107
21464
  } = createToolTracingHooks(
21108
21465
  resolveParentSpan,
21466
+ taskIdToToolUseId,
21467
+ toolUseToParent,
21109
21468
  activeToolSpans,
21110
21469
  options.mcpServers,
21111
21470
  localToolHookNames,
@@ -21187,6 +21546,13 @@ async function finalizeCurrentMessageGroup(state) {
21187
21546
  }
21188
21547
  }
21189
21548
  const existingLlmSpan = state.activeLlmSpansByParentToolUse.get(parentKey);
21549
+ const lastMessage = state.currentMessages[state.currentMessages.length - 1];
21550
+ const messageId = lastMessage?.message?.id;
21551
+ const usage = state.options.includePartialMessages ? mergeUsage(
21552
+ copyUsage(lastMessage?.message?.usage),
21553
+ messageId ? state.usageByMessageId.get(messageId) : void 0
21554
+ ) : void 0;
21555
+ const hasFinalOutputUsage = messageId !== void 0 && state.finalOutputUsageMessageIds.has(messageId);
21190
21556
  const llmSpanResult = await createLLMSpanForMessages(
21191
21557
  state.currentMessages,
21192
21558
  promptMessages,
@@ -21194,6 +21560,8 @@ async function finalizeCurrentMessageGroup(state) {
21194
21560
  state.options,
21195
21561
  state.currentMessageStartTime,
21196
21562
  parentSpan,
21563
+ usage,
21564
+ hasFinalOutputUsage,
21197
21565
  existingLlmSpan
21198
21566
  );
21199
21567
  if (llmSpanResult) {
@@ -21211,9 +21579,17 @@ async function finalizeCurrentMessageGroup(state) {
21211
21579
  }
21212
21580
  }
21213
21581
  state.activeLlmSpansByParentToolUse.delete(parentKey);
21214
- const lastMessage = state.currentMessages[state.currentMessages.length - 1];
21215
- if (lastMessage?.message?.usage) {
21216
- state.accumulatedOutputTokens += getNumberProperty(lastMessage.message.usage, "output_tokens") || 0;
21582
+ if (messageId) {
21583
+ state.usageByMessageId.delete(messageId);
21584
+ state.finalOutputUsageMessageIds.delete(messageId);
21585
+ for (const [
21586
+ parent,
21587
+ activeMessageId
21588
+ ] of state.activePartialMessageIdByParentKey) {
21589
+ if (activeMessageId === messageId) {
21590
+ state.activePartialMessageIdByParentKey.delete(parent);
21591
+ }
21592
+ }
21217
21593
  }
21218
21594
  state.currentMessages.length = 0;
21219
21595
  }
@@ -21304,6 +21680,10 @@ async function ensureActiveLlmSpanForParentToolUse(rootSpan, activeLlmSpansByPar
21304
21680
  );
21305
21681
  llmParentSpan = await subAgentSpan.export();
21306
21682
  }
21683
+ const racedLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
21684
+ if (racedLlmSpan) {
21685
+ return racedLlmSpan;
21686
+ }
21307
21687
  const llmSpan = startSpan(
21308
21688
  withSpanInstrumentationName(
21309
21689
  {
@@ -21423,7 +21803,49 @@ async function maybeHandleTaskLifecycleMessage(state, message) {
21423
21803
  }
21424
21804
  return true;
21425
21805
  }
21806
+ function handlePartialUsageMessage(state, message) {
21807
+ if (message.type !== "stream_event") {
21808
+ return false;
21809
+ }
21810
+ const event = message.event;
21811
+ if (!event || typeof event !== "object") {
21812
+ return true;
21813
+ }
21814
+ const parentKey = llmParentKey(message.parent_tool_use_id ?? null);
21815
+ if (event.type === "message_start") {
21816
+ const messageId2 = event.message?.id;
21817
+ const usage = copyUsage(event.message?.usage);
21818
+ if (messageId2) {
21819
+ state.activePartialMessageIdByParentKey.set(parentKey, messageId2);
21820
+ if (usage) {
21821
+ state.usageByMessageId.set(messageId2, usage);
21822
+ }
21823
+ }
21824
+ return true;
21825
+ }
21826
+ const messageId = state.activePartialMessageIdByParentKey.get(parentKey);
21827
+ if (!messageId) {
21828
+ return true;
21829
+ }
21830
+ if (event.type === "message_delta") {
21831
+ const update = copyUsage(event.usage);
21832
+ if (update) {
21833
+ const usage = state.usageByMessageId.get(messageId) ?? {};
21834
+ Object.assign(usage, update);
21835
+ state.usageByMessageId.set(messageId, usage);
21836
+ if (update.output_tokens !== void 0) {
21837
+ state.finalOutputUsageMessageIds.add(messageId);
21838
+ }
21839
+ }
21840
+ } else if (event.type === "message_stop") {
21841
+ state.activePartialMessageIdByParentKey.delete(parentKey);
21842
+ }
21843
+ return true;
21844
+ }
21426
21845
  async function handleStreamMessage(state, message) {
21846
+ if (handlePartialUsageMessage(state, message)) {
21847
+ return;
21848
+ }
21427
21849
  maybeTrackToolUseContext(state, message);
21428
21850
  if (await maybeHandleTaskLifecycleMessage(state, message)) {
21429
21851
  return;
@@ -21470,36 +21892,9 @@ async function handleStreamMessage(state, message) {
21470
21892
  );
21471
21893
  state.currentMessages.push(message);
21472
21894
  }
21473
- if (message.type !== "result" || !message.usage) {
21895
+ if (message.type !== "result") {
21474
21896
  return;
21475
21897
  }
21476
- const finalUsageMetrics = extractUsageFromMessage(message);
21477
- if (state.currentMessages.length > 0 && finalUsageMetrics.completion_tokens !== void 0) {
21478
- const lastMessage = state.currentMessages[state.currentMessages.length - 1];
21479
- if (lastMessage?.message?.usage) {
21480
- const adjustedTokens = finalUsageMetrics.completion_tokens - state.accumulatedOutputTokens;
21481
- if (adjustedTokens >= 0) {
21482
- lastMessage.message.usage.output_tokens = adjustedTokens;
21483
- }
21484
- const resultUsage = message.usage;
21485
- if (resultUsage && typeof resultUsage === "object") {
21486
- const cacheReadTokens = getNumberProperty(
21487
- resultUsage,
21488
- "cache_read_input_tokens"
21489
- );
21490
- if (cacheReadTokens !== void 0) {
21491
- lastMessage.message.usage.cache_read_input_tokens = cacheReadTokens;
21492
- }
21493
- const cacheCreationTokens = getNumberProperty(
21494
- resultUsage,
21495
- "cache_creation_input_tokens"
21496
- );
21497
- if (cacheCreationTokens !== void 0) {
21498
- lastMessage.message.usage.cache_creation_input_tokens = cacheCreationTokens;
21499
- }
21500
- }
21501
- }
21502
- }
21503
21898
  const metadata = {};
21504
21899
  if (message.num_turns !== void 0) {
21505
21900
  metadata.num_turns = message.num_turns;
@@ -21507,8 +21902,12 @@ async function handleStreamMessage(state, message) {
21507
21902
  if (message.session_id !== void 0) {
21508
21903
  metadata.session_id = message.session_id;
21509
21904
  }
21510
- if (Object.keys(metadata).length > 0) {
21511
- state.span.log({ metadata });
21905
+ const metrics = state.options.includePartialMessages ? {} : extractUsage(copyUsage(message.usage), true);
21906
+ if (Object.keys(metadata).length > 0 || Object.keys(metrics).length > 0) {
21907
+ state.span.log({
21908
+ ...Object.keys(metadata).length > 0 ? { metadata } : {},
21909
+ ...Object.keys(metrics).length > 0 ? { metrics } : {}
21910
+ });
21512
21911
  }
21513
21912
  }
21514
21913
  async function finalizeQuerySpan(state) {
@@ -21532,6 +21931,9 @@ async function finalizeQuerySpan(state) {
21532
21931
  llmSpan.end();
21533
21932
  }
21534
21933
  state.activeLlmSpansByParentToolUse.clear();
21934
+ state.activePartialMessageIdByParentKey.clear();
21935
+ state.finalOutputUsageMessageIds.clear();
21936
+ state.usageByMessageId.clear();
21535
21937
  for (const toolSpan of state.activeToolSpans.values()) {
21536
21938
  toolSpan.end();
21537
21939
  }
@@ -21656,6 +22058,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
21656
22058
  const optionsWithHooks = injectTracingHooks(
21657
22059
  options,
21658
22060
  resolveToolUseParentSpan,
22061
+ taskIdToToolUseId,
22062
+ toolUseToParent,
21659
22063
  activeToolSpans,
21660
22064
  localToolHookNames,
21661
22065
  skipLocalToolHooks,
@@ -21666,8 +22070,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
21666
22070
  params.options = optionsWithHooks;
21667
22071
  event.arguments[0] = params;
21668
22072
  spans.set(event, {
21669
- accumulatedOutputTokens: 0,
21670
22073
  activeLlmSpansByParentToolUse,
22074
+ activePartialMessageIdByParentKey: /* @__PURE__ */ new Map(),
21671
22075
  activeToolSpans,
21672
22076
  conversationHistoryByParentKey,
21673
22077
  capturedPromptMessages,
@@ -21675,6 +22079,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
21675
22079
  currentMessageStartTime: startTime,
21676
22080
  currentMessages: [],
21677
22081
  endedSubAgentSpans,
22082
+ finalOutputUsageMessageIds: /* @__PURE__ */ new Set(),
21678
22083
  finalResults: [],
21679
22084
  options: optionsWithHooks,
21680
22085
  originalPrompt,
@@ -21690,6 +22095,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
21690
22095
  latestLlmParentBySubAgentToolUse,
21691
22096
  latestRootLlmParentRef,
21692
22097
  toolUseToParent,
22098
+ usageByMessageId: /* @__PURE__ */ new Map(),
21693
22099
  localToolContext
21694
22100
  });
21695
22101
  },
@@ -24080,9 +24486,9 @@ function extractEmbedPromptTokenCount(response) {
24080
24486
  let sawAny = false;
24081
24487
  for (const embedding of embeddings) {
24082
24488
  const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
24083
- const tokenCount = embeddingStats?.tokenCount;
24084
- if (typeof tokenCount === "number" && Number.isFinite(tokenCount)) {
24085
- total += tokenCount;
24489
+ const tokenCount2 = embeddingStats?.tokenCount;
24490
+ if (typeof tokenCount2 === "number" && Number.isFinite(tokenCount2)) {
24491
+ total += tokenCount2;
24086
24492
  sawAny = true;
24087
24493
  }
24088
24494
  }
@@ -30632,7 +31038,7 @@ function getStringProperty2(obj, key) {
30632
31038
  return typeof value === "string" ? value : void 0;
30633
31039
  }
30634
31040
  function extractMetricsFromUsage(usage) {
30635
- const metrics = {
31041
+ const rawMetrics = {
30636
31042
  prompt_tokens: usage.inputTokens,
30637
31043
  completion_tokens: usage.outputTokens,
30638
31044
  ...extractAnthropicCacheTokens(
@@ -30641,10 +31047,10 @@ function extractMetricsFromUsage(usage) {
30641
31047
  )
30642
31048
  };
30643
31049
  if (usage.reasoningTokens !== void 0) {
30644
- metrics.completion_reasoning_tokens = usage.reasoningTokens;
30645
- metrics.reasoning_tokens = usage.reasoningTokens;
31050
+ rawMetrics.completion_reasoning_tokens = usage.reasoningTokens;
31051
+ rawMetrics.reasoning_tokens = usage.reasoningTokens;
30646
31052
  }
30647
- Object.assign(metrics, finalizeAnthropicTokens(metrics));
31053
+ const metrics = finalizeAnthropicTokens(rawMetrics);
30648
31054
  const metadata = {
30649
31055
  model: usage.model
30650
31056
  };
@@ -32599,8 +33005,7 @@ function startAgentStream(event, activeChildParents) {
32599
33005
  ...extractAgentMetadata2(agent),
32600
33006
  ...extractModelMetadata3(model),
32601
33007
  "strands.operation": "Agent.stream",
32602
- provider: extractProvider(model),
32603
- ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
33008
+ provider: extractProvider(model)
32604
33009
  };
32605
33010
  const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
32606
33011
  const attachmentCache = createStrandsAttachmentCache();
@@ -32650,8 +33055,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
32650
33055
  const metadata = {
32651
33056
  "strands.operation": operation,
32652
33057
  provider: "strands",
32653
- ...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {},
32654
- ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
33058
+ ...orchestrator?.id ? { "strands.orchestrator.id": orchestrator.id } : {}
32655
33059
  };
32656
33060
  const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
32657
33061
  const input = processStrandsInputAttachments(event.arguments[0]);
@@ -33437,6 +33841,296 @@ function logInstrumentationError5(context, error) {
33437
33841
  debugLogger.debug(`${context}:`, error);
33438
33842
  }
33439
33843
 
33844
+ // src/instrumentation/plugins/voyageai-plugin.ts
33845
+ var RERANK_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
33846
+ "model",
33847
+ "returnDocuments",
33848
+ "topK",
33849
+ "truncation"
33850
+ ]);
33851
+ var VoyageAIPlugin = class extends BasePlugin {
33852
+ onEnable() {
33853
+ this.unsubscribers.push(
33854
+ interceptVoyageAICall(
33855
+ voyageAIChannels.embed,
33856
+ "voyageai.embed",
33857
+ extractTextEmbeddingInput,
33858
+ summarizeEmbeddingOutput,
33859
+ extractEmbeddingUsageMetrics
33860
+ ),
33861
+ interceptVoyageAICall(
33862
+ voyageAIChannels.multimodalEmbed,
33863
+ "voyageai.multimodalEmbed",
33864
+ extractMultimodalEmbeddingInput,
33865
+ summarizeEmbeddingOutput,
33866
+ extractEmbeddingUsageMetrics
33867
+ ),
33868
+ interceptVoyageAICall(
33869
+ voyageAIChannels.rerank,
33870
+ "voyageai.rerank",
33871
+ extractRerankInput,
33872
+ summarizeRerankOutput
33873
+ ),
33874
+ interceptVoyageAICall(
33875
+ voyageAIChannels.contextualizedEmbed,
33876
+ "voyageai.contextualizedEmbed",
33877
+ extractContextualizedEmbeddingInput,
33878
+ summarizeContextualizedEmbeddingOutput,
33879
+ extractEmbeddingUsageMetrics
33880
+ )
33881
+ );
33882
+ }
33883
+ onDisable() {
33884
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
33885
+ }
33886
+ };
33887
+ function interceptVoyageAICall(channel, name, extractInput2, extractOutput2, extractMetrics2 = extractUsageMetrics3) {
33888
+ return channel.intercept((target, thisArg, args) => {
33889
+ const invokeTarget = () => Reflect.apply(target, thisArg, args);
33890
+ if (isAutoInstrumentationSuppressed()) {
33891
+ return invokeTarget();
33892
+ }
33893
+ let span;
33894
+ try {
33895
+ const { input, metadata } = extractInput2(args);
33896
+ span = startSpan(
33897
+ withSpanInstrumentationName(
33898
+ {
33899
+ event: { input, metadata },
33900
+ name,
33901
+ spanAttributes: { type: "llm" /* LLM */ }
33902
+ },
33903
+ INSTRUMENTATION_NAMES.VOYAGEAI
33904
+ )
33905
+ );
33906
+ } catch (error) {
33907
+ debugLogger.error(`Error starting span for ${name}:`, error);
33908
+ return invokeTarget();
33909
+ }
33910
+ let result;
33911
+ try {
33912
+ result = withCurrent(
33913
+ span,
33914
+ () => runWithAutoInstrumentationSuppressed(invokeTarget)
33915
+ );
33916
+ } catch (error) {
33917
+ finishVoyageAISpan(span, name, () => span.log({ error }));
33918
+ throw error;
33919
+ }
33920
+ void Promise.resolve(result).then(
33921
+ (value) => finishVoyageAISpan(span, name, () => {
33922
+ const metadata = extractResponseMetadata3(value);
33923
+ span.log({
33924
+ output: extractOutput2(value),
33925
+ ...metadata ? { metadata } : {},
33926
+ metrics: extractMetrics2(value)
33927
+ });
33928
+ }),
33929
+ (error) => finishVoyageAISpan(span, name, () => span.log({ error }))
33930
+ );
33931
+ return result;
33932
+ });
33933
+ }
33934
+ function finishVoyageAISpan(span, name, log2) {
33935
+ try {
33936
+ log2();
33937
+ } catch (error) {
33938
+ debugLogger.error(`Error logging span for ${name}:`, error);
33939
+ }
33940
+ try {
33941
+ span.end();
33942
+ } catch (error) {
33943
+ debugLogger.error(`Error ending span for ${name}:`, error);
33944
+ }
33945
+ }
33946
+ function getRequestArg2(args) {
33947
+ if (Array.isArray(args)) {
33948
+ return isObject(args[0]) ? args[0] : void 0;
33949
+ }
33950
+ if (!isObject(args)) {
33951
+ return void 0;
33952
+ }
33953
+ const firstArg = Reflect.get(args, "0");
33954
+ return isObject(firstArg) ? firstArg : void 0;
33955
+ }
33956
+ function pickMetadata(request, allowlist) {
33957
+ const metadata = {};
33958
+ if (request) {
33959
+ for (const key of allowlist) {
33960
+ if (!Object.hasOwn(request, key)) {
33961
+ continue;
33962
+ }
33963
+ const value = request[key];
33964
+ if (value !== void 0) {
33965
+ metadata[key] = value;
33966
+ }
33967
+ }
33968
+ }
33969
+ return {
33970
+ ...metadata,
33971
+ provider: "voyage"
33972
+ };
33973
+ }
33974
+ function buildEmbeddingInput(inputs, request) {
33975
+ const outputDimensions = request?.outputDimension;
33976
+ return {
33977
+ inputs,
33978
+ ...typeof outputDimensions === "number" && Number.isFinite(outputDimensions) ? { output_dimensions: outputDimensions } : {}
33979
+ };
33980
+ }
33981
+ function embeddingMetadata(request) {
33982
+ return {
33983
+ ...typeof request?.model === "string" ? { model: request.model } : {},
33984
+ provider: "voyage"
33985
+ };
33986
+ }
33987
+ function extractTextEmbeddingInput(args) {
33988
+ const request = getRequestArg2(args);
33989
+ const rawInput = request?.input;
33990
+ const values = Array.isArray(rawInput) ? rawInput : [rawInput];
33991
+ return {
33992
+ input: buildEmbeddingInput(
33993
+ values.flatMap(
33994
+ (value) => typeof value === "string" ? [{ content: value }] : []
33995
+ ),
33996
+ request
33997
+ ),
33998
+ metadata: embeddingMetadata(request)
33999
+ };
34000
+ }
34001
+ function extractContextualizedEmbeddingInput(args) {
34002
+ const request = getRequestArg2(args);
34003
+ const rawInputs = request?.inputs;
34004
+ const values = Array.isArray(rawInputs) ? rawInputs.flatMap((value) => Array.isArray(value) ? value : [value]) : [];
34005
+ return {
34006
+ input: buildEmbeddingInput(
34007
+ values.flatMap(
34008
+ (value) => typeof value === "string" ? [{ content: value }] : []
34009
+ ),
34010
+ request
34011
+ ),
34012
+ metadata: embeddingMetadata(request)
34013
+ };
34014
+ }
34015
+ function extractMultimodalEmbeddingInput(args) {
34016
+ const request = getRequestArg2(args);
34017
+ const rawInputs = request?.inputs;
34018
+ const inputs = Array.isArray(rawInputs) ? rawInputs.map((rawInput) => {
34019
+ const rawContent = isObject(rawInput) ? rawInput.content : void 0;
34020
+ return {
34021
+ content: Array.isArray(rawContent) ? rawContent.flatMap(normalizeMultimodalContentPart) : []
34022
+ };
34023
+ }) : [];
34024
+ const input = buildEmbeddingInput(inputs, request);
34025
+ const processedInput = processInputAttachments(input);
34026
+ return {
34027
+ input: hasInlineEmbeddingMedia(processedInput) ? input : processedInput,
34028
+ metadata: embeddingMetadata(request)
34029
+ };
34030
+ }
34031
+ function normalizeMultimodalContentPart(part) {
34032
+ if (!isObject(part) || typeof part.type !== "string") {
34033
+ return [];
34034
+ }
34035
+ if (part.type === "text") {
34036
+ return typeof part.text === "string" ? [{ type: "text", text: part.text }] : [];
34037
+ }
34038
+ const camelCaseField = {
34039
+ image_base64: "imageBase64",
34040
+ image_url: "imageUrl",
34041
+ video_base64: "videoBase64",
34042
+ video_url: "videoUrl"
34043
+ };
34044
+ const field = camelCaseField[part.type];
34045
+ if (!field) {
34046
+ return [];
34047
+ }
34048
+ const data = typeof part[field] === "string" ? part[field] : part[part.type];
34049
+ if (typeof data !== "string") {
34050
+ return [];
34051
+ }
34052
+ return part.type.startsWith("image_") ? [{ type: "image_url", image_url: { url: data } }] : [{ type: "file", file: { file_data: data } }];
34053
+ }
34054
+ function hasInlineEmbeddingMedia(input) {
34055
+ return input.inputs.some(
34056
+ ({ content }) => Array.isArray(content) ? content.some((part) => {
34057
+ const value = part.type === "image_url" ? part.image_url.url : part.type === "file" ? part.file.file_data : void 0;
34058
+ return typeof value === "string" && value.startsWith("data:");
34059
+ }) : false
34060
+ );
34061
+ }
34062
+ function extractRerankInput(args) {
34063
+ const request = getRequestArg2(args);
34064
+ const documents = request?.documents;
34065
+ return {
34066
+ input: {
34067
+ documents,
34068
+ query: request?.query
34069
+ },
34070
+ metadata: {
34071
+ ...pickMetadata(request, RERANK_METADATA_ALLOWLIST),
34072
+ ...Array.isArray(documents) ? { document_count: documents.length } : {}
34073
+ }
34074
+ };
34075
+ }
34076
+ function extractResponseMetadata3(result) {
34077
+ if (!isObject(result)) {
34078
+ return void 0;
34079
+ }
34080
+ const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
34081
+ const model = typeof result.model === "string" ? result.model : typeof rawResponse?.model === "string" ? rawResponse.model : void 0;
34082
+ return model ? { model } : void 0;
34083
+ }
34084
+ function summarizeEmbeddingOutput(result) {
34085
+ return {
34086
+ count: isObject(result) && Array.isArray(result.data) ? result.data.length : 0
34087
+ };
34088
+ }
34089
+ function summarizeRerankOutput(result) {
34090
+ if (!isObject(result) || !Array.isArray(result.data)) {
34091
+ return void 0;
34092
+ }
34093
+ return result.data.slice(0, 100).map((item) => ({
34094
+ index: isObject(item) ? item.index : void 0,
34095
+ relevance_score: isObject(item) ? (typeof item.relevanceScore === "number" ? item.relevanceScore : item.relevance_score) ?? null : null
34096
+ }));
34097
+ }
34098
+ function summarizeContextualizedEmbeddingOutput(result) {
34099
+ if (!isObject(result)) {
34100
+ return { count: 0 };
34101
+ }
34102
+ if (Array.isArray(result.results)) {
34103
+ return {
34104
+ count: result.results.reduce(
34105
+ (count, item) => count + (isObject(item) && Array.isArray(item.embeddings) ? item.embeddings.length : 0),
34106
+ 0
34107
+ )
34108
+ };
34109
+ }
34110
+ if (!Array.isArray(result.data)) {
34111
+ return { count: 0 };
34112
+ }
34113
+ return {
34114
+ count: result.data.reduce(
34115
+ (count, item) => count + (isObject(item) && Array.isArray(item.data) ? item.data.length : 0),
34116
+ 0
34117
+ )
34118
+ };
34119
+ }
34120
+ function extractEmbeddingUsageMetrics(result) {
34121
+ const metrics = extractUsageMetrics3(result);
34122
+ return typeof metrics.tokens === "number" ? { prompt_tokens: metrics.tokens, tokens: metrics.tokens } : {};
34123
+ }
34124
+ function extractUsageMetrics3(result) {
34125
+ if (!isObject(result)) {
34126
+ return {};
34127
+ }
34128
+ const rawResponse = isObject(result.rawResponse) ? result.rawResponse : void 0;
34129
+ const usage = isObject(result.usage) ? result.usage : isObject(rawResponse?.usage) ? rawResponse.usage : void 0;
34130
+ const tokens = typeof result.totalTokens === "number" ? result.totalTokens : usage?.totalTokens ?? usage?.total_tokens;
34131
+ return typeof tokens === "number" && Number.isFinite(tokens) && tokens >= 0 ? { tokens } : {};
34132
+ }
34133
+
33440
34134
  // src/instrumentation/plugins/cloudflare-ai-chat-instrumentation.ts
33441
34135
  var wrappedTurnRunners = /* @__PURE__ */ new WeakSet();
33442
34136
  var wrappedResponseHooks = /* @__PURE__ */ new WeakSet();
@@ -33987,6 +34681,7 @@ var BraintrustPlugin = class extends BasePlugin {
33987
34681
  langSmithPlugin = null;
33988
34682
  piCodingAgentPlugin = null;
33989
34683
  strandsAgentSDKPlugin = null;
34684
+ voyageAIPlugin = null;
33990
34685
  cloudflareAIChatPlugin = null;
33991
34686
  cloudflareAgentsPlugin = null;
33992
34687
  constructor(config = {}) {
@@ -34061,6 +34756,10 @@ var BraintrustPlugin = class extends BasePlugin {
34061
34756
  this.coherePlugin = new CoherePlugin();
34062
34757
  this.coherePlugin.enable();
34063
34758
  }
34759
+ if (integrations.voyageai !== false) {
34760
+ this.voyageAIPlugin = new VoyageAIPlugin();
34761
+ this.voyageAIPlugin.enable();
34762
+ }
34064
34763
  if (integrations.groq !== false) {
34065
34764
  this.groqPlugin = new GroqPlugin();
34066
34765
  this.groqPlugin.enable();
@@ -34177,6 +34876,10 @@ var BraintrustPlugin = class extends BasePlugin {
34177
34876
  this.coherePlugin.disable();
34178
34877
  this.coherePlugin = null;
34179
34878
  }
34879
+ if (this.voyageAIPlugin) {
34880
+ this.voyageAIPlugin.disable();
34881
+ this.voyageAIPlugin = null;
34882
+ }
34180
34883
  if (this.groqPlugin) {
34181
34884
  this.groqPlugin.disable();
34182
34885
  this.groqPlugin = null;
@@ -34543,7 +35246,7 @@ function wrapMastraAgent(agent, _options) {
34543
35246
 
34544
35247
  // src/node/config.ts
34545
35248
  import { AsyncLocalStorage } from "node:async_hooks";
34546
- import * as path from "node:path";
35249
+ import * as path2 from "node:path";
34547
35250
  import * as fs from "node:fs/promises";
34548
35251
  import * as os from "node:os";
34549
35252
  import * as fsSync from "node:fs";
@@ -34552,34 +35255,93 @@ import { promisify } from "node:util";
34552
35255
  import * as zlib from "node:zlib";
34553
35256
  import * as dotenv from "dotenv";
34554
35257
 
34555
- // src/gitutil.ts
34556
- import { simpleGit } from "simple-git";
34557
- var COMMON_BASE_BRANCHES = ["main", "master", "develop"];
34558
- async function currentRepo() {
34559
- try {
34560
- const git = simpleGit();
34561
- if (await git.checkIsRepo()) {
34562
- return git;
34563
- } else {
34564
- return null;
35258
+ // src/git-command.ts
35259
+ import { execFile } from "node:child_process";
35260
+ import { constants } from "node:fs";
35261
+ import { access } from "node:fs/promises";
35262
+ import * as path from "node:path";
35263
+ var GIT_EXECUTABLE_NAMES = process.platform === "win32" ? ["git.exe", "git"] : ["git"];
35264
+ var GIT_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
35265
+ var gitExecutablePromise;
35266
+ function executableSearchPath() {
35267
+ return Object.entries(process.env).find(
35268
+ ([name]) => name.toUpperCase() === "PATH"
35269
+ )?.[1];
35270
+ }
35271
+ async function findGitExecutable(searchPath = executableSearchPath()) {
35272
+ if (!searchPath) {
35273
+ return void 0;
35274
+ }
35275
+ for (const rawSearchDir of searchPath.split(path.delimiter)) {
35276
+ const searchDir = rawSearchDir.trim().replace(/^"(.*)"$/, "$1");
35277
+ if (!path.isAbsolute(searchDir)) {
35278
+ continue;
35279
+ }
35280
+ for (const executableName of GIT_EXECUTABLE_NAMES) {
35281
+ const candidate = path.join(searchDir, executableName);
35282
+ try {
35283
+ await access(
35284
+ candidate,
35285
+ process.platform === "win32" ? constants.F_OK : constants.X_OK
35286
+ );
35287
+ return candidate;
35288
+ } catch {
35289
+ }
34565
35290
  }
34566
- } catch {
34567
- return null;
34568
35291
  }
35292
+ return void 0;
35293
+ }
35294
+ async function resolveGitExecutable() {
35295
+ gitExecutablePromise ??= findGitExecutable();
35296
+ return await gitExecutablePromise;
34569
35297
  }
35298
+ async function runGitCommand(args, options = {}) {
35299
+ const executable = await resolveGitExecutable();
35300
+ if (!executable) {
35301
+ throw new Error("Could not find a git executable on PATH");
35302
+ }
35303
+ return await new Promise((resolve, reject) => {
35304
+ execFile(
35305
+ executable,
35306
+ args,
35307
+ {
35308
+ cwd: options.cwd,
35309
+ encoding: "utf8",
35310
+ maxBuffer: GIT_MAX_BUFFER_BYTES
35311
+ },
35312
+ (error, stdout) => {
35313
+ if (error) {
35314
+ reject(error);
35315
+ } else {
35316
+ resolve(stdout);
35317
+ }
35318
+ }
35319
+ );
35320
+ });
35321
+ }
35322
+
35323
+ // src/gitutil.ts
35324
+ var COMMON_BASE_BRANCHES = ["main", "master", "develop"];
34570
35325
  var _baseBranch = null;
34571
35326
  async function getBaseBranch(remote = void 0) {
34572
35327
  if (_baseBranch === null) {
34573
- const git = await currentRepo();
34574
- if (git === null) {
35328
+ const repoPath = await currentRepoPath();
35329
+ if (!repoPath) {
34575
35330
  throw new Error("Not in a git repo");
34576
35331
  }
34577
- const remoteName = remote ?? (await git.getRemotes())[0]?.name;
35332
+ const runGit = async (args) => await runGitCommand(args, { cwd: repoPath });
35333
+ const remoteName = remote ?? (await runGit(["remote"])).trim().split(/\r?\n/)[0];
34578
35334
  if (!remoteName) {
34579
35335
  throw new Error("No remote found");
34580
35336
  }
34581
35337
  let branch = null;
34582
- const repoBranches = new Set((await git.branchLocal()).all);
35338
+ const repoBranches = new Set(
35339
+ (await runGit([
35340
+ "for-each-ref",
35341
+ "--format=%(refname:short)",
35342
+ "refs/heads/"
35343
+ ])).trim().split(/\r?\n/)
35344
+ );
34583
35345
  const matchingBaseBranches = COMMON_BASE_BRANCHES.filter(
34584
35346
  (b) => repoBranches.has(b)
34585
35347
  );
@@ -34587,7 +35349,7 @@ async function getBaseBranch(remote = void 0) {
34587
35349
  branch = matchingBaseBranches[0];
34588
35350
  } else {
34589
35351
  try {
34590
- const remoteInfo = await git.remote(["show", remoteName]);
35352
+ const remoteInfo = await runGit(["remote", "show", remoteName]);
34591
35353
  if (!remoteInfo) {
34592
35354
  throw new Error(`Could not find remote ${remoteName}`);
34593
35355
  }
@@ -34605,27 +35367,28 @@ async function getBaseBranch(remote = void 0) {
34605
35367
  return _baseBranch;
34606
35368
  }
34607
35369
  async function getBaseBranchAncestor(remote = void 0) {
34608
- const git = await currentRepo();
34609
- if (git === null) {
35370
+ const repoPath = await currentRepoPath();
35371
+ if (!repoPath) {
34610
35372
  throw new Error("Not in a git repo");
34611
35373
  }
34612
35374
  const { remote: remoteName, branch: baseBranch } = await getBaseBranch(remote);
34613
- const isDirty = (await git.diffSummary()).files.length > 0;
35375
+ const isDirty = (await runGitCommand(["diff", "--name-only"], {
35376
+ cwd: repoPath
35377
+ })).trim().length > 0;
34614
35378
  const head = isDirty ? "HEAD" : "HEAD^";
34615
35379
  try {
34616
- const ancestor = await git.raw([
34617
- "merge-base",
34618
- head,
34619
- `${remoteName}/${baseBranch}`
34620
- ]);
35380
+ const ancestor = await runGitCommand(
35381
+ ["merge-base", head, `${remoteName}/${baseBranch}`],
35382
+ { cwd: repoPath }
35383
+ );
34621
35384
  return ancestor.trim();
34622
35385
  } catch {
34623
35386
  return void 0;
34624
35387
  }
34625
35388
  }
34626
35389
  async function getPastNAncestors(n = 1e3, remote = void 0) {
34627
- const git = await currentRepo();
34628
- if (git === null) {
35390
+ const repoPath = await currentRepoPath();
35391
+ if (!repoPath) {
34629
35392
  return [];
34630
35393
  }
34631
35394
  let ancestor = void 0;
@@ -34640,8 +35403,10 @@ async function getPastNAncestors(n = 1e3, remote = void 0) {
34640
35403
  if (!ancestor) {
34641
35404
  return [];
34642
35405
  }
34643
- const commits = await git.log({ from: ancestor, to: "HEAD", maxCount: n });
34644
- return commits.all.slice(0, n).map((c) => c.hash);
35406
+ const commits = (await runGitCommand(["rev-list", `--max-count=${n}`, `${ancestor}..HEAD`], {
35407
+ cwd: repoPath
35408
+ })).trim();
35409
+ return commits ? commits.split(/\r?\n/).slice(0, n) : [];
34645
35410
  }
34646
35411
  async function attempt(fn) {
34647
35412
  try {
@@ -34672,9 +35437,14 @@ async function getRepoInfo(settings) {
34672
35437
  });
34673
35438
  return sanitized;
34674
35439
  }
35440
+ async function currentRepoPath() {
35441
+ return await attempt(
35442
+ async () => (await runGitCommand(["rev-parse", "--show-toplevel"])).trim()
35443
+ );
35444
+ }
34675
35445
  async function repoInfo() {
34676
- const git = await currentRepo();
34677
- if (git === null) {
35446
+ const repoPath = await currentRepoPath();
35447
+ if (!repoPath) {
34678
35448
  return void 0;
34679
35449
  }
34680
35450
  let commit = void 0;
@@ -34685,29 +35455,32 @@ async function repoInfo() {
34685
35455
  let tag = void 0;
34686
35456
  let branch = void 0;
34687
35457
  let git_diff = void 0;
34688
- const dirty = (await git.diffSummary()).files.length > 0;
34689
- commit = await attempt(async () => await git.revparse(["HEAD"]));
35458
+ const runGit = async (args) => await runGitCommand(args, { cwd: repoPath });
35459
+ const dirty = (await runGit(["diff", "--name-only"])).trim().length > 0;
35460
+ commit = await attempt(
35461
+ async () => (await runGit(["rev-parse", "HEAD"])).trim()
35462
+ );
34690
35463
  commit_message = await attempt(
34691
- async () => (await git.raw(["log", "-1", "--pretty=%B"])).trim()
35464
+ async () => (await runGit(["log", "-1", "--pretty=%B"])).trim()
34692
35465
  );
34693
35466
  commit_time = await attempt(
34694
- async () => (await git.raw(["log", "-1", "--pretty=%cI"])).trim()
35467
+ async () => (await runGit(["log", "-1", "--pretty=%cI"])).trim()
34695
35468
  );
34696
35469
  author_name = await attempt(
34697
- async () => (await git.raw(["log", "-1", "--pretty=%aN"])).trim()
35470
+ async () => (await runGit(["log", "-1", "--pretty=%aN"])).trim()
34698
35471
  );
34699
35472
  author_email = await attempt(
34700
- async () => (await git.raw(["log", "-1", "--pretty=%aE"])).trim()
35473
+ async () => (await runGit(["log", "-1", "--pretty=%aE"])).trim()
34701
35474
  );
34702
35475
  tag = await attempt(
34703
- async () => (await git.raw(["describe", "--tags", "--exact-match", "--always"])).trim()
35476
+ async () => (await runGit(["describe", "--tags", "--exact-match", "--always"])).trim()
34704
35477
  );
34705
35478
  branch = await attempt(
34706
- async () => (await git.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim()
35479
+ async () => (await runGit(["rev-parse", "--abbrev-ref", "HEAD"])).trim()
34707
35480
  );
34708
35481
  if (dirty) {
34709
35482
  git_diff = await attempt(
34710
- async () => truncateToByteLimit(await git.raw(["--no-ext-diff", "diff", "HEAD"]))
35483
+ async () => truncateToByteLimit(await runGit(["diff", "--no-ext-diff", "HEAD"]))
34711
35484
  );
34712
35485
  }
34713
35486
  return {
@@ -34788,9 +35561,9 @@ function configureNode() {
34788
35561
  return value;
34789
35562
  }
34790
35563
  const envPaths = [];
34791
- for (let dir = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir = path.dirname(dir), depth++) {
34792
- envPaths.push(path.join(dir, ".env.braintrust"));
34793
- if (path.dirname(dir) === dir) {
35564
+ for (let dir = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir = path2.dirname(dir), depth++) {
35565
+ envPaths.push(path2.join(dir, ".env.braintrust"));
35566
+ if (path2.dirname(dir) === dir) {
34794
35567
  break;
34795
35568
  }
34796
35569
  }
@@ -34832,10 +35605,10 @@ function configureNode() {
34832
35605
  isomorph_default.processOn = (event, handler) => {
34833
35606
  process.on(event, handler);
34834
35607
  };
34835
- isomorph_default.basename = path.basename;
35608
+ isomorph_default.basename = path2.basename;
34836
35609
  isomorph_default.writeln = (text) => process.stdout.write(text + "\n");
34837
- isomorph_default.pathJoin = path.join;
34838
- isomorph_default.pathDirname = path.dirname;
35610
+ isomorph_default.pathJoin = path2.join;
35611
+ isomorph_default.pathDirname = path2.dirname;
34839
35612
  isomorph_default.mkdir = fs.mkdir;
34840
35613
  isomorph_default.writeFile = fs.writeFile;
34841
35614
  isomorph_default.readFile = fs.readFile;
@@ -34870,8 +35643,8 @@ function configureNode() {
34870
35643
  registry.enable();
34871
35644
  }
34872
35645
  function getNearestBraintrustEnvValue(name) {
34873
- for (let dir = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir = path.dirname(dir), depth++) {
34874
- const envPath = path.join(dir, ".env.braintrust");
35646
+ for (let dir = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir = path2.dirname(dir), depth++) {
35647
+ const envPath = path2.join(dir, ".env.braintrust");
34875
35648
  try {
34876
35649
  const parsed = dotenv.parse(fsSync.readFileSync(envPath, "utf8"));
34877
35650
  const value = parsed[name];
@@ -34881,7 +35654,7 @@ function getNearestBraintrustEnvValue(name) {
34881
35654
  return void 0;
34882
35655
  }
34883
35656
  }
34884
- if (path.dirname(dir) === dir) {
35657
+ if (path2.dirname(dir) === dir) {
34885
35658
  break;
34886
35659
  }
34887
35660
  }
@@ -34939,9 +35712,10 @@ export {
34939
35712
  TRACESTATE_HEADER,
34940
35713
  BAGGAGE_HEADER,
34941
35714
  BRAINTRUST_PARENT_KEY,
35715
+ uint8ArrayToBase64,
35716
+ base64ToUint8Array,
34942
35717
  spanObjectTypeV3ToTypedString,
34943
35718
  isObject,
34944
- mergeDicts,
34945
35719
  slugify,
34946
35720
  SpanComponentsV4,
34947
35721
  makeScorerPropagatedEvent,
@@ -34992,6 +35766,7 @@ export {
34992
35766
  ReadonlyAttachment,
34993
35767
  JSONAttachment,
34994
35768
  updateSpan,
35769
+ _internalResumeSpan,
34995
35770
  spanComponentsToObjectId,
34996
35771
  ERR_PERMALINK,
34997
35772
  permalink,
@@ -35053,6 +35828,7 @@ export {
35053
35828
  X_CACHED_HEADER,
35054
35829
  parseCachedHeader,
35055
35830
  finalizeAnthropicTokens,
35831
+ toNumericMetrics,
35056
35832
  extractAnthropicCacheTokens,
35057
35833
  collectAnthropicSession,
35058
35834
  zodToJsonSchema,