braintrust 3.27.0 → 3.29.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 (54) hide show
  1. package/README.md +1 -1
  2. package/dev/dist/index.d.mts +879 -197
  3. package/dev/dist/index.d.ts +879 -197
  4. package/dev/dist/index.js +2960 -1865
  5. package/dev/dist/index.mjs +2217 -1122
  6. package/dist/apply-auto-instrumentation.js +345 -260
  7. package/dist/apply-auto-instrumentation.mjs +137 -52
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +124 -7
  9. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  10. package/dist/auto-instrumentations/bundler/next.cjs +124 -7
  11. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  12. package/dist/auto-instrumentations/bundler/rollup.cjs +124 -7
  13. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.cjs +124 -7
  15. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  16. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +124 -7
  17. package/dist/auto-instrumentations/bundler/webpack.cjs +124 -7
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  19. package/dist/auto-instrumentations/{chunk-ZNHTSSGI.mjs → chunk-AOIYCVEL.mjs} +34 -3
  20. package/dist/auto-instrumentations/{chunk-XEYKUBLY.mjs → chunk-DKTGDNA7.mjs} +91 -5
  21. package/dist/auto-instrumentations/{chunk-BW33ULMW.mjs → chunk-OMCZ3MV2.mjs} +1 -1
  22. package/dist/auto-instrumentations/hook.mjs +1186 -161
  23. package/dist/auto-instrumentations/index.cjs +34 -3
  24. package/dist/auto-instrumentations/index.mjs +1 -1
  25. package/dist/browser.d.mts +1388 -75
  26. package/dist/browser.d.ts +1388 -75
  27. package/dist/browser.js +3954 -1124
  28. package/dist/browser.mjs +3954 -1124
  29. package/dist/{chunk-MF7NU6BT.js → chunk-6Z5S7VOU.js} +175 -25
  30. package/dist/{chunk-CZM5JIQL.mjs → chunk-7FA6VP2S.mjs} +172 -22
  31. package/dist/{chunk-YKD22IMR.mjs → chunk-M6XPNJC4.mjs} +2102 -1113
  32. package/dist/{chunk-QRHGVBKU.js → chunk-XLLGRXGR.js} +3273 -2284
  33. package/dist/cli.js +6353 -1483
  34. package/dist/edge-light.d.mts +1 -1
  35. package/dist/edge-light.d.ts +1 -1
  36. package/dist/edge-light.js +3954 -1124
  37. package/dist/edge-light.mjs +3954 -1124
  38. package/dist/index.d.mts +1972 -659
  39. package/dist/index.d.ts +1972 -659
  40. package/dist/index.js +2453 -676
  41. package/dist/index.mjs +1973 -196
  42. package/dist/instrumentation/index.d.mts +738 -15
  43. package/dist/instrumentation/index.d.ts +738 -15
  44. package/dist/instrumentation/index.js +2791 -874
  45. package/dist/instrumentation/index.mjs +2791 -874
  46. package/dist/vitest-evals-reporter.js +16 -16
  47. package/dist/vitest-evals-reporter.mjs +2 -2
  48. package/dist/workerd.d.mts +1 -1
  49. package/dist/workerd.d.ts +1 -1
  50. package/dist/workerd.js +3954 -1124
  51. package/dist/workerd.mjs +3954 -1124
  52. package/package.json +2 -3
  53. package/util/dist/index.d.mts +1596 -109
  54. package/util/dist/index.d.ts +1596 -109
@@ -84,7 +84,10 @@ var envIntegrationAliases = {
84
84
  "langchain-js": "langchain",
85
85
  "@langchain": "langchain",
86
86
  langgraph: "langgraph",
87
- langsmith: "langsmith"
87
+ langsmith: "langsmith",
88
+ voyage: "voyageai",
89
+ "voyage-ai": "voyageai",
90
+ voyageai: "voyageai"
88
91
  };
89
92
  function readDisabledInstrumentationEnvConfig(disabledList) {
90
93
  const integrations = {};
@@ -107,8 +110,6 @@ function isInstrumentationIntegrationDisabled(integrations, ...names) {
107
110
  var DefaultAsyncLocalStorage = class {
108
111
  constructor() {
109
112
  }
110
- enterWith(_) {
111
- }
112
113
  run(_, callback) {
113
114
  return callback();
114
115
  }
@@ -1775,7 +1776,10 @@ var AclObjectType = z6.union([
1775
1776
  "org_member",
1776
1777
  "project_log",
1777
1778
  "org_project",
1778
- "org_audit_logs"
1779
+ "org_audit_logs",
1780
+ "project_group",
1781
+ "ai_secret",
1782
+ "org_ai_secret"
1779
1783
  ]),
1780
1784
  z6.null()
1781
1785
  ]);
@@ -1904,7 +1908,8 @@ var AsyncScoringState = z6.union([
1904
1908
  token: z6.string(),
1905
1909
  function_ids: z6.array(z6.unknown()),
1906
1910
  skip_logging: z6.union([z6.boolean(), z6.null()]).optional(),
1907
- triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional()
1911
+ triggered_functions: z6.union([z6.record(TriggeredFunctionState), z6.null()]).optional(),
1912
+ last_triggered_xact_id: z6.union([z6.string(), z6.number(), z6.null()]).optional()
1908
1913
  }),
1909
1914
  z6.object({ status: z6.literal("disabled") }),
1910
1915
  z6.null(),
@@ -1973,7 +1978,7 @@ var FunctionTypeEnum = z6.enum([
1973
1978
  "parameters",
1974
1979
  "sandbox"
1975
1980
  ]);
1976
- var NullableSavedFunctionId = z6.union([
1981
+ var FacetPreprocessorId = z6.union([
1977
1982
  z6.object({
1978
1983
  type: z6.literal("function"),
1979
1984
  id: z6.string(),
@@ -1984,10 +1989,23 @@ var NullableSavedFunctionId = z6.union([
1984
1989
  name: z6.string(),
1985
1990
  function_type: FunctionTypeEnum.optional().default("scorer")
1986
1991
  }),
1992
+ z6.object({ type: z6.literal("inline"), code: z6.string().min(1) }),
1987
1993
  z6.null()
1988
1994
  ]);
1995
+ var SavedFunctionId = z6.union([
1996
+ z6.object({
1997
+ type: z6.literal("function"),
1998
+ id: z6.string(),
1999
+ version: z6.string().optional()
2000
+ }),
2001
+ z6.object({
2002
+ type: z6.literal("global"),
2003
+ name: z6.string(),
2004
+ function_type: FunctionTypeEnum.optional().default("scorer")
2005
+ })
2006
+ ]);
1989
2007
  var TopicMapGenerationSettings = z6.object({
1990
- algorithm: z6.enum(["hdbscan", "kmeans"]),
2008
+ algorithm: z6.enum(["hdbscan", "kmeans", "community"]),
1991
2009
  dimension_reduction: z6.enum(["umap", "pca", "none"]),
1992
2010
  sample_size: z6.number().int().gt(0).optional(),
1993
2011
  n_clusters: z6.number().int().gt(0).optional(),
@@ -1999,6 +2017,7 @@ var TopicMapGenerationSettings = z6.object({
1999
2017
  var TopicMapData = z6.object({
2000
2018
  type: z6.literal("topic_map"),
2001
2019
  source_facet: z6.string(),
2020
+ source_facet_function: SavedFunctionId.and(z6.unknown()).optional(),
2002
2021
  embedding_model: z6.string(),
2003
2022
  bundle_key: z6.string().optional(),
2004
2023
  report_key: z6.string().optional(),
@@ -2012,7 +2031,7 @@ var TopicMapData = z6.object({
2012
2031
  });
2013
2032
  var BatchedFacetData = z6.object({
2014
2033
  type: z6.literal("batched_facet"),
2015
- preprocessor: NullableSavedFunctionId.and(z6.unknown()).optional(),
2034
+ preprocessor: FacetPreprocessorId.optional(),
2016
2035
  facets: z6.array(
2017
2036
  z6.object({
2018
2037
  name: z6.string(),
@@ -2273,18 +2292,6 @@ var ObjectReferenceNullish = z6.union([
2273
2292
  }),
2274
2293
  z6.null()
2275
2294
  ]);
2276
- var SavedFunctionId = z6.union([
2277
- z6.object({
2278
- type: z6.literal("function"),
2279
- id: z6.string(),
2280
- version: z6.string().optional()
2281
- }),
2282
- z6.object({
2283
- type: z6.literal("global"),
2284
- name: z6.string(),
2285
- function_type: FunctionTypeEnum.optional().default("scorer")
2286
- })
2287
- ]);
2288
2295
  var DatasetEvent = z6.object({
2289
2296
  id: z6.string(),
2290
2297
  _xact_id: z6.string(),
@@ -2506,7 +2513,7 @@ var ExtendedSavedFunctionId = z6.union([
2506
2513
  ]);
2507
2514
  var FacetData = z6.object({
2508
2515
  type: z6.literal("facet"),
2509
- preprocessor: NullableSavedFunctionId.and(z6.unknown()).optional(),
2516
+ preprocessor: FacetPreprocessorId.optional(),
2510
2517
  prompt: z6.string(),
2511
2518
  model: z6.string().optional(),
2512
2519
  embedding_model: z6.string().optional(),
@@ -2605,7 +2612,7 @@ var PromptParserNullish = z6.union([
2605
2612
  }),
2606
2613
  z6.null()
2607
2614
  ]);
2608
- var PreprocessorSavedFunctionId = z6.union([
2615
+ var PreprocessorId = z6.union([
2609
2616
  z6.object({
2610
2617
  type: z6.literal("function"),
2611
2618
  id: z6.string(),
@@ -2616,6 +2623,7 @@ var PreprocessorSavedFunctionId = z6.union([
2616
2623
  name: z6.string(),
2617
2624
  function_type: z6.literal("preprocessor").optional().default("preprocessor")
2618
2625
  }),
2626
+ z6.object({ type: z6.literal("inline"), code: z6.string().min(1) }),
2619
2627
  z6.null()
2620
2628
  ]);
2621
2629
  var PromptDataNullish = z6.union([
@@ -2623,7 +2631,7 @@ var PromptDataNullish = z6.union([
2623
2631
  prompt: PromptBlockDataNullish,
2624
2632
  options: PromptOptionsNullish,
2625
2633
  parser: PromptParserNullish,
2626
- preprocessor: PreprocessorSavedFunctionId,
2634
+ preprocessor: PreprocessorId,
2627
2635
  tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
2628
2636
  template_format: z6.union([
2629
2637
  z6.enum(["mustache", "nunjucks", "none"]),
@@ -2825,7 +2833,7 @@ var PromptData = z6.object({
2825
2833
  prompt: PromptBlockDataNullish,
2826
2834
  options: PromptOptionsNullish,
2827
2835
  parser: PromptParserNullish,
2828
- preprocessor: PreprocessorSavedFunctionId,
2836
+ preprocessor: PreprocessorId,
2829
2837
  tool_functions: z6.union([z6.array(SavedFunctionId), z6.null()]),
2830
2838
  template_format: z6.union([
2831
2839
  z6.enum(["mustache", "nunjucks", "none"]),
@@ -3011,6 +3019,19 @@ var MessageRole = z6.enum([
3011
3019
  "model",
3012
3020
  "developer"
3013
3021
  ]);
3022
+ var NullableSavedFunctionId = z6.union([
3023
+ z6.object({
3024
+ type: z6.literal("function"),
3025
+ id: z6.string(),
3026
+ version: z6.string().optional()
3027
+ }),
3028
+ z6.object({
3029
+ type: z6.literal("global"),
3030
+ name: z6.string(),
3031
+ function_type: FunctionTypeEnum.optional().default("scorer")
3032
+ }),
3033
+ z6.null()
3034
+ ]);
3014
3035
  var ObjectReference = z6.object({
3015
3036
  object_type: z6.enum([
3016
3037
  "project_logs",
@@ -3032,6 +3053,7 @@ var TraceScope = z6.object({
3032
3053
  });
3033
3054
  var OnlineScoreConfig = z6.union([
3034
3055
  z6.object({
3056
+ status: AutomationStatus.optional(),
3035
3057
  sampling_rate: z6.number().gte(0).lte(1),
3036
3058
  scorers: z6.array(SavedFunctionId),
3037
3059
  btql_filter: z6.union([z6.string(), z6.null()]).optional(),
@@ -3112,6 +3134,72 @@ var Project = z6.object({
3112
3134
  user_id: z6.union([z6.string(), z6.null()]).optional(),
3113
3135
  settings: ProjectSettings.optional()
3114
3136
  });
3137
+ var WindowedAutomationConfig = z6.object({
3138
+ event_type: z6.literal("windowed"),
3139
+ product_origin: z6.union([z6.literal("patterns"), z6.null()]).optional(),
3140
+ status: AutomationStatus.optional(),
3141
+ threshold: z6.object({
3142
+ calculation: z6.object({
3143
+ type: z6.literal("btql"),
3144
+ btql_query: z6.string().min(1),
3145
+ output: z6.object({
3146
+ type: z6.literal("scalar"),
3147
+ value_column: z6.string().min(1)
3148
+ })
3149
+ }),
3150
+ policy: z6.object({
3151
+ condition: z6.object({
3152
+ type: z6.literal("threshold"),
3153
+ operator: z6.enum(["lt", "lte", "gt", "gte", "eq", "neq"]),
3154
+ threshold: z6.number()
3155
+ }),
3156
+ pending_seconds: z6.number().int().gte(0).lte(2592e3),
3157
+ no_data_behavior: z6.enum(["keep_last", "resolve", "alert"]),
3158
+ renotify_interval_seconds: z6.union([z6.number(), z6.null()]).optional(),
3159
+ notify_on_recovery: z6.boolean().optional().default(true)
3160
+ })
3161
+ }).optional(),
3162
+ window: z6.object({
3163
+ window_seconds: z6.number().int().gte(1).lte(2592e3),
3164
+ schedule: z6.union([
3165
+ z6.object({
3166
+ type: z6.literal("interval"),
3167
+ evaluation_interval_seconds: z6.number().int().gte(1).lte(2592e3)
3168
+ }),
3169
+ z6.object({
3170
+ type: z6.literal("cron"),
3171
+ cron_expression: z6.string().min(1),
3172
+ timezone: z6.union([z6.string(), z6.null()]).optional()
3173
+ })
3174
+ ]),
3175
+ evaluation_delay_seconds: z6.number().int().gte(0).lte(2592e3)
3176
+ }),
3177
+ loop: z6.object({
3178
+ prompt: z6.string().min(1).max(1e4),
3179
+ include_trigger_input: z6.boolean().optional().default(false),
3180
+ agent_slug: z6.string().min(1),
3181
+ auto_approve_tools: z6.array(z6.string().min(1)).optional().default([]),
3182
+ harness: z6.enum(["native", "codex", "claude-code"]).optional(),
3183
+ model: z6.string().min(1).optional(),
3184
+ reasoning_effort: z6.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional()
3185
+ }).optional(),
3186
+ actions: z6.array(
3187
+ z6.union([
3188
+ z6.object({
3189
+ type: z6.literal("webhook"),
3190
+ url: z6.string(),
3191
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3192
+ }),
3193
+ z6.object({
3194
+ type: z6.literal("slack"),
3195
+ workspace_id: z6.string(),
3196
+ channel: z6.string(),
3197
+ message_template: z6.string().optional(),
3198
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3199
+ })
3200
+ ])
3201
+ ).max(20).optional().default([])
3202
+ });
3115
3203
  var TopicAutomationFacetModel = z6.union([
3116
3204
  z6.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]),
3117
3205
  z6.null()
@@ -3153,7 +3241,8 @@ var TopicDigestAutomationConfig = z6.object({
3153
3241
  type: z6.literal("slack"),
3154
3242
  workspace_id: z6.string(),
3155
3243
  channel: z6.string(),
3156
- message_template: z6.string().optional()
3244
+ message_template: z6.string().optional(),
3245
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3157
3246
  }),
3158
3247
  topic_map_function_ids: z6.array(z6.string()).max(10).optional()
3159
3248
  });
@@ -3167,15 +3256,21 @@ var ProjectAutomation = z6.object({
3167
3256
  config: z6.union([
3168
3257
  z6.object({
3169
3258
  event_type: z6.literal("logs"),
3259
+ status: AutomationStatus.optional(),
3170
3260
  btql_filter: z6.string(),
3171
3261
  interval_seconds: z6.number().gte(1).lte(2592e3),
3172
3262
  action: z6.union([
3173
- z6.object({ type: z6.literal("webhook"), url: z6.string() }),
3263
+ z6.object({
3264
+ type: z6.literal("webhook"),
3265
+ url: z6.string(),
3266
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3267
+ }),
3174
3268
  z6.object({
3175
3269
  type: z6.literal("slack"),
3176
3270
  workspace_id: z6.string(),
3177
3271
  channel: z6.string(),
3178
- message_template: z6.string().optional()
3272
+ message_template: z6.string().optional(),
3273
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3179
3274
  })
3180
3275
  ])
3181
3276
  }),
@@ -3226,21 +3321,38 @@ var ProjectAutomation = z6.object({
3226
3321
  }),
3227
3322
  z6.object({
3228
3323
  event_type: z6.literal("environment_update"),
3324
+ status: AutomationStatus.optional(),
3229
3325
  environment_filter: z6.array(z6.string()).optional(),
3230
3326
  action: z6.union([
3231
- z6.object({ type: z6.literal("webhook"), url: z6.string() }),
3327
+ z6.object({
3328
+ type: z6.literal("webhook"),
3329
+ url: z6.string(),
3330
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3331
+ }),
3232
3332
  z6.object({
3233
3333
  type: z6.literal("slack"),
3234
3334
  workspace_id: z6.string(),
3235
3335
  channel: z6.string(),
3236
- message_template: z6.string().optional()
3336
+ message_template: z6.string().optional(),
3337
+ formatting_prompt: z6.string().min(1).max(1e4).optional()
3237
3338
  })
3238
3339
  ])
3239
3340
  }),
3341
+ WindowedAutomationConfig,
3240
3342
  TopicAutomationConfig,
3241
3343
  TopicDigestAutomationConfig
3242
3344
  ])
3243
3345
  });
3346
+ var ProjectGroup = z6.object({
3347
+ id: z6.string().uuid(),
3348
+ org_id: z6.string().uuid(),
3349
+ user_id: z6.union([z6.string(), z6.null()]).optional(),
3350
+ created: z6.union([z6.string(), z6.null()]).optional(),
3351
+ name: z6.string(),
3352
+ description: z6.union([z6.string(), z6.null()]).optional(),
3353
+ deleted_at: z6.union([z6.string(), z6.null()]).optional(),
3354
+ member_projects: z6.array(z6.string().uuid()).max(1e4)
3355
+ });
3244
3356
  var ProjectLogsEvent = z6.object({
3245
3357
  id: z6.string(),
3246
3358
  _xact_id: z6.string(),
@@ -3458,7 +3570,8 @@ var RunEval = z6.object({
3458
3570
  dataset_environment: z6.union([z6.string(), z6.null()]).optional(),
3459
3571
  _internal_btql: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
3460
3572
  }),
3461
- z6.object({ data: z6.array(z6.unknown()) })
3573
+ z6.object({ data: z6.array(z6.unknown()) }),
3574
+ z6.object({ experiment_name: z6.string() })
3462
3575
  ]),
3463
3576
  name: z6.string().optional(),
3464
3577
  parameters: z6.object({}).partial().passthrough().optional(),
@@ -3663,7 +3776,10 @@ var View = z6.object({
3663
3776
  "for_review_datasets"
3664
3777
  ]),
3665
3778
  name: z6.string(),
3779
+ description: z6.union([z6.string(), z6.null()]).optional(),
3780
+ starred: z6.boolean().optional(),
3666
3781
  created: z6.union([z6.string(), z6.null()]).optional(),
3782
+ updated_at: z6.union([z6.string(), z6.null()]).optional(),
3667
3783
  view_data: ViewData.optional(),
3668
3784
  options: ViewOptions.optional(),
3669
3785
  user_id: z6.union([z6.string(), z6.null()]).optional(),
@@ -3751,6 +3867,34 @@ var registerTemplatePlugin = templateRegistry.register.bind(templateRegistry);
3751
3867
  var getTemplateRenderer = templateRegistry.get.bind(templateRegistry);
3752
3868
  registerTemplatePlugin(mustachePlugin);
3753
3869
 
3870
+ // src/template/renderer.ts
3871
+ function isTemplateFormat(v) {
3872
+ return v === "mustache" || v === "nunjucks" || v === "none";
3873
+ }
3874
+ function parseTemplateFormat(value, defaultFormat = "mustache") {
3875
+ return isTemplateFormat(value) ? value : defaultFormat;
3876
+ }
3877
+ function renderTemplateContent(template, variables, escape, options) {
3878
+ const strict = !!options.strict;
3879
+ const templateFormat = parseTemplateFormat(options.templateFormat);
3880
+ if (templateFormat === "none") {
3881
+ return template;
3882
+ }
3883
+ const renderer = getTemplateRenderer(templateFormat);
3884
+ if (!renderer) {
3885
+ if (templateFormat === "nunjucks") {
3886
+ throw new Error(
3887
+ "Nunjucks templating requires @braintrust/template-nunjucks. Install and import it to enable templateFormat: 'nunjucks'."
3888
+ );
3889
+ }
3890
+ throw new Error(`No template renderer registered for ${templateFormat}`);
3891
+ }
3892
+ if (strict && renderer.lint) {
3893
+ renderer.lint(template, variables);
3894
+ }
3895
+ return renderer.render(template, variables, escape, strict);
3896
+ }
3897
+
3754
3898
  // src/logger.ts
3755
3899
  import { z as z8, ZodError } from "zod/v3";
3756
3900
 
@@ -4337,44 +4481,72 @@ function createCacheLayers({
4337
4481
  }
4338
4482
 
4339
4483
  // src/prompt-cache/prompt-cache.ts
4340
- function createCacheKey(key) {
4484
+ function createCacheKey(key, namespace) {
4485
+ let cacheKey;
4341
4486
  if (key.id) {
4342
- return `id:${key.id}`;
4343
- }
4344
- const prefix = key.projectId ?? key.projectName;
4345
- if (!prefix) {
4346
- throw new Error("Either projectId or projectName must be provided");
4347
- }
4348
- if (!key.slug) {
4349
- throw new Error("Slug must be provided when not using ID");
4487
+ cacheKey = `id:${key.id}`;
4488
+ } else {
4489
+ const prefix = key.projectId ?? key.projectName;
4490
+ if (!prefix) {
4491
+ throw new Error("Either projectId or projectName must be provided");
4492
+ }
4493
+ if (!key.slug) {
4494
+ throw new Error("Slug must be provided when not using ID");
4495
+ }
4496
+ cacheKey = `${prefix}:${key.slug}:${key.version ?? "latest"}`;
4350
4497
  }
4351
- return `${prefix}:${key.slug}:${key.version ?? "latest"}`;
4498
+ return namespace === void 0 ? cacheKey : `${namespace.length}:${namespace}:${cacheKey}`;
4352
4499
  }
4353
- var PromptCache = class {
4500
+ var PromptCache = class _PromptCache {
4354
4501
  memoryCache;
4355
4502
  diskCache;
4503
+ namespace;
4504
+ expectedResolvedOrgIdentity;
4356
4505
  constructor(options) {
4357
4506
  this.memoryCache = options.memoryCache;
4358
4507
  this.diskCache = options.diskCache;
4508
+ this.namespace = options.namespace;
4509
+ this.expectedResolvedOrgIdentity = options.expectedResolvedOrgIdentity;
4510
+ }
4511
+ /**
4512
+ * Returns a cache view that shares the same storage layers but isolates all
4513
+ * entries under the provided namespace.
4514
+ */
4515
+ withNamespace(namespace, expectedResolvedOrgIdentity) {
4516
+ return new _PromptCache({
4517
+ memoryCache: this.memoryCache,
4518
+ diskCache: this.diskCache,
4519
+ namespace,
4520
+ expectedResolvedOrgIdentity
4521
+ });
4359
4522
  }
4360
4523
  /**
4361
4524
  * Retrieves a prompt from the cache.
4362
4525
  * First checks the in-memory LRU cache, then falls back to checking the disk cache if available.
4363
4526
  */
4364
4527
  async get(key) {
4365
- const cacheKey = createCacheKey(key);
4528
+ const cacheKey = createCacheKey(key, this.namespace);
4366
4529
  if (this.memoryCache) {
4367
- const memoryPrompt = this.memoryCache.get(cacheKey);
4368
- if (memoryPrompt !== void 0) {
4369
- return memoryPrompt;
4530
+ const memoryEntry = this.memoryCache.get(cacheKey);
4531
+ if (memoryEntry !== void 0 && (this.expectedResolvedOrgIdentity === void 0 || memoryEntry.resolvedOrgIdentity === this.expectedResolvedOrgIdentity)) {
4532
+ return memoryEntry.value;
4370
4533
  }
4371
4534
  }
4372
4535
  if (this.diskCache) {
4373
- const diskPrompt = await this.diskCache.get(cacheKey);
4374
- if (!diskPrompt) {
4536
+ const diskEntry = await this.diskCache.get(cacheKey);
4537
+ if (!diskEntry || this.expectedResolvedOrgIdentity !== void 0 && diskEntry.resolvedOrgIdentity !== this.expectedResolvedOrgIdentity) {
4375
4538
  return void 0;
4376
4539
  }
4377
- this.memoryCache?.set(cacheKey, diskPrompt);
4540
+ const serializedPrompt = diskEntry.value;
4541
+ const diskPrompt = new Prompt2(
4542
+ serializedPrompt.metadata,
4543
+ serializedPrompt.defaults,
4544
+ serializedPrompt.noTrace
4545
+ );
4546
+ this.memoryCache?.set(cacheKey, {
4547
+ value: diskPrompt,
4548
+ resolvedOrgIdentity: diskEntry.resolvedOrgIdentity
4549
+ });
4378
4550
  return diskPrompt;
4379
4551
  }
4380
4552
  return void 0;
@@ -4388,58 +4560,91 @@ var PromptCache = class {
4388
4560
  * @throws If there is an error writing to the disk cache.
4389
4561
  */
4390
4562
  async set(key, value) {
4391
- const cacheKey = createCacheKey(key);
4392
- this.memoryCache?.set(cacheKey, value);
4563
+ const cacheKey = createCacheKey(key, this.namespace);
4564
+ const memoryEntry = {
4565
+ value,
4566
+ resolvedOrgIdentity: this.expectedResolvedOrgIdentity
4567
+ };
4568
+ this.memoryCache?.set(cacheKey, memoryEntry);
4393
4569
  if (this.diskCache) {
4394
- await this.diskCache.set(cacheKey, value);
4570
+ await this.diskCache.set(cacheKey, {
4571
+ value: value._internalSerializeForCache(),
4572
+ resolvedOrgIdentity: this.expectedResolvedOrgIdentity
4573
+ });
4395
4574
  }
4396
4575
  }
4397
4576
  };
4398
4577
 
4399
4578
  // src/prompt-cache/parameters-cache.ts
4400
- function createCacheKey2(key) {
4579
+ function createCacheKey2(key, namespace) {
4580
+ let cacheKey;
4401
4581
  if (key.id) {
4402
- return `parameters:id:${key.id}`;
4403
- }
4404
- const prefix = key.projectId ?? key.projectName;
4405
- if (!prefix) {
4406
- throw new Error("Either projectId or projectName must be provided");
4407
- }
4408
- if (!key.slug) {
4409
- throw new Error("Slug must be provided when not using ID");
4582
+ cacheKey = `parameters:id:${key.id}`;
4583
+ } else {
4584
+ const prefix = key.projectId ?? key.projectName;
4585
+ if (!prefix) {
4586
+ throw new Error("Either projectId or projectName must be provided");
4587
+ }
4588
+ if (!key.slug) {
4589
+ throw new Error("Slug must be provided when not using ID");
4590
+ }
4591
+ cacheKey = `parameters:${prefix}:${key.slug}:${key.version ?? "latest"}`;
4410
4592
  }
4411
- return `parameters:${prefix}:${key.slug}:${key.version ?? "latest"}`;
4593
+ return namespace === void 0 ? cacheKey : `${namespace.length}:${namespace}:${cacheKey}`;
4412
4594
  }
4413
- var ParametersCache = class {
4595
+ var ParametersCache = class _ParametersCache {
4414
4596
  memoryCache;
4415
4597
  diskCache;
4598
+ namespace;
4599
+ expectedResolvedOrgIdentity;
4416
4600
  constructor(options) {
4417
4601
  this.memoryCache = options.memoryCache;
4418
4602
  this.diskCache = options.diskCache;
4603
+ this.namespace = options.namespace;
4604
+ this.expectedResolvedOrgIdentity = options.expectedResolvedOrgIdentity;
4605
+ }
4606
+ withNamespace(namespace, expectedResolvedOrgIdentity) {
4607
+ return new _ParametersCache({
4608
+ memoryCache: this.memoryCache,
4609
+ diskCache: this.diskCache,
4610
+ namespace,
4611
+ expectedResolvedOrgIdentity
4612
+ });
4419
4613
  }
4420
4614
  async get(key) {
4421
- const cacheKey = createCacheKey2(key);
4615
+ const cacheKey = createCacheKey2(key, this.namespace);
4422
4616
  if (this.memoryCache) {
4423
- const memoryParams = this.memoryCache.get(cacheKey);
4424
- if (memoryParams !== void 0) {
4425
- return memoryParams;
4617
+ const memoryEntry = this.memoryCache.get(cacheKey);
4618
+ if (memoryEntry !== void 0 && (this.expectedResolvedOrgIdentity === void 0 || memoryEntry.resolvedOrgIdentity === this.expectedResolvedOrgIdentity)) {
4619
+ return memoryEntry.value;
4426
4620
  }
4427
4621
  }
4428
4622
  if (this.diskCache) {
4429
- const diskParams = await this.diskCache.get(cacheKey);
4430
- if (!diskParams) {
4623
+ const diskEntry = await this.diskCache.get(cacheKey);
4624
+ if (!diskEntry || this.expectedResolvedOrgIdentity !== void 0 && diskEntry.resolvedOrgIdentity !== this.expectedResolvedOrgIdentity) {
4431
4625
  return void 0;
4432
4626
  }
4433
- this.memoryCache?.set(cacheKey, diskParams);
4434
- return diskParams;
4627
+ const diskParameters = new RemoteEvalParameters(diskEntry.value.metadata);
4628
+ this.memoryCache?.set(cacheKey, {
4629
+ value: diskParameters,
4630
+ resolvedOrgIdentity: diskEntry.resolvedOrgIdentity
4631
+ });
4632
+ return diskParameters;
4435
4633
  }
4436
4634
  return void 0;
4437
4635
  }
4438
4636
  async set(key, value) {
4439
- const cacheKey = createCacheKey2(key);
4440
- this.memoryCache?.set(cacheKey, value);
4637
+ const cacheKey = createCacheKey2(key, this.namespace);
4638
+ const memoryEntry = {
4639
+ value,
4640
+ resolvedOrgIdentity: this.expectedResolvedOrgIdentity
4641
+ };
4642
+ this.memoryCache?.set(cacheKey, memoryEntry);
4441
4643
  if (this.diskCache) {
4442
- await this.diskCache.set(cacheKey, value);
4644
+ await this.diskCache.set(cacheKey, {
4645
+ value: value._internalSerializeForCache(),
4646
+ resolvedOrgIdentity: this.expectedResolvedOrgIdentity
4647
+ });
4443
4648
  }
4444
4649
  }
4445
4650
  };
@@ -4743,6 +4948,7 @@ var INSTRUMENTATION_NAMES = {
4743
4948
  CLOUDFLARE_THINK: "cloudflare-think",
4744
4949
  COHERE: "cohere",
4745
4950
  CURSOR_SDK: "cursor-sdk",
4951
+ DEEPSEEK_HARNESS: "deepseek-harness",
4746
4952
  EVE: "eve",
4747
4953
  FLUE: "flue",
4748
4954
  GENKIT: "genkit",
@@ -4762,12 +4968,13 @@ var INSTRUMENTATION_NAMES = {
4762
4968
  OPENROUTER: "openrouter",
4763
4969
  OPENROUTER_AGENT: "openrouter-agent",
4764
4970
  PI_CODING_AGENT: "pi-coding-agent",
4765
- STRANDS_AGENT_SDK: "strands-agent-sdk"
4971
+ STRANDS_AGENT_SDK: "strands-agent-sdk",
4972
+ VOYAGEAI: "voyageai"
4766
4973
  };
4767
4974
  var INTERNAL_SPAN_INSTRUMENTATION_NAME = /* @__PURE__ */ Symbol.for(
4768
4975
  "braintrust.spanInstrumentationName"
4769
4976
  );
4770
- var SDK_VERSION = true ? "3.27.0" : "0.0.0";
4977
+ var SDK_VERSION = true ? "3.29.0" : "0.0.0";
4771
4978
  function withSpanInstrumentationName(args, instrumentationName) {
4772
4979
  return {
4773
4980
  ...args,
@@ -4886,6 +5093,16 @@ var datasetSnapshotRegisterResponseSchema = z8.object({
4886
5093
  dataset_snapshot: DatasetSnapshot,
4887
5094
  found_existing: z8.boolean().optional()
4888
5095
  });
5096
+ var datasetObjectInfoSchema = z8.object({
5097
+ object_id: z8.string(),
5098
+ object_name: z8.string(),
5099
+ parent_cols: z8.object({
5100
+ project: z8.object({
5101
+ id: z8.string(),
5102
+ name: z8.string()
5103
+ })
5104
+ })
5105
+ });
4889
5106
  var datasetRestorePreviewResultSchema = z8.object({
4890
5107
  rows_to_restore: z8.number(),
4891
5108
  rows_to_delete: z8.number()
@@ -4962,6 +5179,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
4962
5179
  var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
4963
5180
  "braintrust.initial-span-write-as-merge"
4964
5181
  );
5182
+ var RESUME_SPAN_WITHOUT_INITIAL_WRITE = /* @__PURE__ */ Symbol(
5183
+ "braintrust.resume-span-without-initial-write"
5184
+ );
4965
5185
  var INTERNAL_SPAN_CONTEXT = /* @__PURE__ */ Symbol("braintrust.internal-span-context");
4966
5186
  var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
4967
5187
  "braintrust.currentSpanStore"
@@ -5096,12 +5316,53 @@ var loginSchema = z8.strictObject({
5096
5316
  });
5097
5317
  var stateNonce = 0;
5098
5318
  var V1_PROXY_SUFFIX = "/v1/proxy";
5319
+ var LOADER_LOGIN_CACHE_MAX = 16;
5099
5320
  function normalizeProxyConnUrl(proxyUrl) {
5100
5321
  return proxyUrl.endsWith(V1_PROXY_SUFFIX) ? proxyUrl.slice(0, proxyUrl.length - V1_PROXY_SUFFIX.length) : proxyUrl;
5101
5322
  }
5102
5323
  var BraintrustState = class _BraintrustState {
5324
+ id;
5325
+ currentExperiment;
5326
+ // Note: the value of IsAsyncFlush doesn't really matter here, since we
5327
+ // (safely) dynamically cast it whenever retrieving the logger.
5328
+ currentLogger;
5329
+ currentParent;
5330
+ currentSpan;
5331
+ // Any time we re-log in, we directly update the apiConn inside the logger.
5332
+ // This is preferable to replacing the whole logger, which would create the
5333
+ // possibility of multiple loggers floating around, which may not log in a
5334
+ // deterministic order.
5335
+ _bgLogger;
5336
+ _overrideBgLogger = null;
5337
+ appUrl = null;
5338
+ appPublicUrl = null;
5339
+ loginToken = null;
5340
+ orgId = null;
5341
+ orgName = null;
5342
+ apiUrl = null;
5343
+ proxyUrl = null;
5344
+ loggedIn = false;
5345
+ gitMetadataSettings;
5346
+ debugLogLevel;
5347
+ debugLogLevelConfigured = false;
5348
+ fetch = globalThis.fetch;
5349
+ _appConn = null;
5350
+ _apiConn = null;
5351
+ _proxyConn = null;
5352
+ promptCache;
5353
+ parametersCache;
5354
+ spanCache;
5355
+ _idGenerator = null;
5356
+ _contextManager = null;
5357
+ _otelFlushCallback = null;
5358
+ spanOriginEnvironment;
5359
+ traceContextSigningSecret;
5360
+ loaderLoginCache = /* @__PURE__ */ new WeakMap();
5361
+ loginParams;
5362
+ activeLoginOrgNameSelector;
5103
5363
  constructor(loginParams) {
5104
- this.loginParams = loginParams;
5364
+ this.loginParams = { ...loginParams };
5365
+ this.activeLoginOrgNameSelector = loginParams.orgName ?? isomorph_default.getEnv("BRAINTRUST_ORG_NAME");
5105
5366
  this.id = `${(/* @__PURE__ */ new Date()).toLocaleString()}-${stateNonce++}`;
5106
5367
  this.currentExperiment = void 0;
5107
5368
  this.currentLogger = void 0;
@@ -5138,12 +5399,14 @@ var BraintrustState = class _BraintrustState {
5138
5399
  const {
5139
5400
  memoryCache: parametersMemoryCache,
5140
5401
  diskCache: parametersDiskCache
5141
- } = createCacheLayers({
5142
- memoryMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_MEMORY_MAX",
5143
- diskCacheDirEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DIR",
5144
- diskMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DISK_MAX",
5145
- getDefaultDiskCacheDir: () => `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/parameters_cache`
5146
- });
5402
+ } = createCacheLayers(
5403
+ {
5404
+ memoryMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_MEMORY_MAX",
5405
+ diskCacheDirEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DIR",
5406
+ diskMaxEnvVar: "BRAINTRUST_PARAMETERS_CACHE_DISK_MAX",
5407
+ getDefaultDiskCacheDir: () => `${isomorph_default.getEnv("HOME") ?? isomorph_default.homedir()}/.braintrust/parameters_cache`
5408
+ }
5409
+ );
5147
5410
  this.parametersCache = new ParametersCache({
5148
5411
  memoryCache: parametersMemoryCache,
5149
5412
  diskCache: parametersDiskCache
@@ -5152,43 +5415,6 @@ var BraintrustState = class _BraintrustState {
5152
5415
  this.spanOriginEnvironment = detectSpanOriginEnvironment();
5153
5416
  this._internalSetTraceContextSigningSecret(loginParams.apiKey);
5154
5417
  }
5155
- loginParams;
5156
- id;
5157
- currentExperiment;
5158
- // Note: the value of IsAsyncFlush doesn't really matter here, since we
5159
- // (safely) dynamically cast it whenever retrieving the logger.
5160
- currentLogger;
5161
- currentParent;
5162
- currentSpan;
5163
- // Any time we re-log in, we directly update the apiConn inside the logger.
5164
- // This is preferable to replacing the whole logger, which would create the
5165
- // possibility of multiple loggers floating around, which may not log in a
5166
- // deterministic order.
5167
- _bgLogger;
5168
- _overrideBgLogger = null;
5169
- appUrl = null;
5170
- appPublicUrl = null;
5171
- loginToken = null;
5172
- orgId = null;
5173
- orgName = null;
5174
- apiUrl = null;
5175
- proxyUrl = null;
5176
- loggedIn = false;
5177
- gitMetadataSettings;
5178
- debugLogLevel;
5179
- debugLogLevelConfigured = false;
5180
- fetch = globalThis.fetch;
5181
- _appConn = null;
5182
- _apiConn = null;
5183
- _proxyConn = null;
5184
- promptCache;
5185
- parametersCache;
5186
- spanCache;
5187
- _idGenerator = null;
5188
- _contextManager = null;
5189
- _otelFlushCallback = null;
5190
- spanOriginEnvironment;
5191
- traceContextSigningSecret;
5192
5418
  /** @internal */
5193
5419
  _internalSetTraceContextSigningSecret(secret) {
5194
5420
  const normalizedSecret = secret?.trim();
@@ -5213,6 +5439,101 @@ var BraintrustState = class _BraintrustState {
5213
5439
  this._appConn = null;
5214
5440
  this._apiConn = null;
5215
5441
  this._proxyConn = null;
5442
+ this.loaderLoginCache = /* @__PURE__ */ new WeakMap();
5443
+ }
5444
+ /** @internal */
5445
+ async _internalResolveLoaderLoginOptions({
5446
+ apiKey,
5447
+ appUrl,
5448
+ orgName,
5449
+ fetch: fetch2,
5450
+ forceLogin
5451
+ }) {
5452
+ const resolvedAppUrl = appUrl ?? (this.loggedIn ? this.appUrl ?? void 0 : void 0) ?? this.loginParams.appUrl ?? isomorph_default.getEnv("BRAINTRUST_APP_URL") ?? "https://www.braintrust.dev";
5453
+ const resolvedApiKey = apiKey ?? (this.loggedIn ? this.loginToken ?? void 0 : void 0) ?? this.loginParams.apiKey ?? await isomorph_default.getBraintrustApiKey();
5454
+ if (!resolvedApiKey) {
5455
+ throw new Error(
5456
+ "Please specify an api key (e.g. by setting BRAINTRUST_API_KEY)."
5457
+ );
5458
+ }
5459
+ const normalizedApiKey = HTTPConnection.sanitize_token(resolvedApiKey);
5460
+ const usesActiveCredential = this.loggedIn && normalizedApiKey === this.loginToken;
5461
+ const requestedOrgName = orgName ?? (usesActiveCredential ? this.activeLoginOrgNameSelector : void 0) ?? this.loginParams.orgName ?? isomorph_default.getEnv("BRAINTRUST_ORG_NAME");
5462
+ const resolvedOrgName = orgName ?? (usesActiveCredential ? this.orgName ?? void 0 : void 0) ?? requestedOrgName;
5463
+ const resolvedFetch = fetch2 ?? (this.loggedIn ? this.fetch : void 0) ?? this.loginParams.fetch ?? globalThis.fetch;
5464
+ const credentialCacheNamespace = JSON.stringify([
5465
+ "loader-credential",
5466
+ resolvedAppUrl,
5467
+ requestedOrgName,
5468
+ normalizedApiKey
5469
+ ]);
5470
+ return {
5471
+ apiKey: normalizedApiKey,
5472
+ appUrl: resolvedAppUrl,
5473
+ orgName: resolvedOrgName,
5474
+ fetch: resolvedFetch,
5475
+ forceLogin,
5476
+ credentialCacheNamespace,
5477
+ existingState: !forceLogin && usesActiveCredential && resolvedAppUrl === this.appUrl && resolvedOrgName === this.orgName && resolvedFetch === this.fetch ? this : void 0
5478
+ };
5479
+ }
5480
+ /** @internal */
5481
+ _internalGetLoaderCacheViews(loginOptions, requestState) {
5482
+ const expectedResolvedOrgIdentity = requestState?.orgId && requestState.appUrl ? JSON.stringify([
5483
+ "loader-org",
5484
+ requestState.appUrl,
5485
+ requestState.orgId
5486
+ ]) : void 0;
5487
+ return {
5488
+ promptCache: this.promptCache.withNamespace(
5489
+ loginOptions.credentialCacheNamespace,
5490
+ expectedResolvedOrgIdentity
5491
+ ),
5492
+ parametersCache: this.parametersCache.withNamespace(
5493
+ loginOptions.credentialCacheNamespace,
5494
+ expectedResolvedOrgIdentity
5495
+ )
5496
+ };
5497
+ }
5498
+ /** @internal */
5499
+ async _internalGetLoaderState({
5500
+ apiKey,
5501
+ appUrl,
5502
+ orgName,
5503
+ fetch: fetch2,
5504
+ forceLogin,
5505
+ existingState
5506
+ }) {
5507
+ if (existingState) {
5508
+ return existingState;
5509
+ }
5510
+ let cache = this.loaderLoginCache.get(fetch2);
5511
+ if (!cache) {
5512
+ cache = new LRUCache({ max: LOADER_LOGIN_CACHE_MAX });
5513
+ this.loaderLoginCache.set(fetch2, cache);
5514
+ }
5515
+ const cacheKey = JSON.stringify([appUrl, orgName, apiKey]);
5516
+ if (!forceLogin) {
5517
+ const cachedState = cache.get(cacheKey);
5518
+ if (cachedState) {
5519
+ return cachedState;
5520
+ }
5521
+ }
5522
+ const statePromise = loginToLoaderRequestState({
5523
+ orgName,
5524
+ apiKey,
5525
+ appUrl,
5526
+ fetch: fetch2
5527
+ });
5528
+ cache.set(cacheKey, statePromise);
5529
+ try {
5530
+ return await statePromise;
5531
+ } catch (error) {
5532
+ if (cache.get(cacheKey) === statePromise) {
5533
+ cache.delete(cacheKey);
5534
+ }
5535
+ throw error;
5536
+ }
5216
5537
  }
5217
5538
  resetIdGenState() {
5218
5539
  this._idGenerator = null;
@@ -5261,6 +5582,8 @@ var BraintrustState = class _BraintrustState {
5261
5582
  this.debugLogLevel = other.debugLogLevel;
5262
5583
  this.debugLogLevelConfigured = other.debugLogLevelConfigured;
5263
5584
  this.traceContextSigningSecret = other.traceContextSigningSecret;
5585
+ this.fetch = other.fetch;
5586
+ this.activeLoginOrgNameSelector = other.activeLoginOrgNameSelector;
5264
5587
  setGlobalDebugLogLevel(
5265
5588
  this.debugLogLevelConfigured ? this.debugLogLevel ?? false : void 0
5266
5589
  );
@@ -5468,36 +5791,76 @@ var FailedHTTPResponse = class extends Error {
5468
5791
  status;
5469
5792
  text;
5470
5793
  data;
5471
- constructor(status, text, data) {
5794
+ cause;
5795
+ constructor(status, text, data, cause) {
5472
5796
  super(`${status}: ${text} (${data})`);
5473
5797
  this.status = status;
5474
5798
  this.text = text;
5475
5799
  this.data = data;
5800
+ this.cause = cause;
5476
5801
  }
5477
5802
  };
5803
+ var HTTPTransportError = class extends Error {
5804
+ cause;
5805
+ constructor(cause) {
5806
+ super(cause instanceof Error ? cause.message : String(cause));
5807
+ this.name = "HTTPTransportError";
5808
+ this.cause = cause;
5809
+ }
5810
+ };
5811
+ var httpTransportErrorCauses = /* @__PURE__ */ new WeakSet();
5812
+ function recordHTTPTransportError(error) {
5813
+ if (typeof error === "object" && error !== null || typeof error === "function") {
5814
+ httpTransportErrorCauses.add(error);
5815
+ }
5816
+ }
5817
+ function rethrowHTTPTransportError(error, classifyTransportErrors) {
5818
+ if (classifyTransportErrors) {
5819
+ throw new HTTPTransportError(error);
5820
+ }
5821
+ recordHTTPTransportError(error);
5822
+ throw error;
5823
+ }
5824
+ async function readJSONResponse(response, classifyTransportErrors = false) {
5825
+ let data;
5826
+ try {
5827
+ data = await response.text();
5828
+ } catch (error) {
5829
+ rethrowHTTPTransportError(error, classifyTransportErrors);
5830
+ }
5831
+ return JSON.parse(data);
5832
+ }
5478
5833
  async function checkResponse(resp) {
5479
5834
  if (resp.ok) {
5480
5835
  return resp;
5481
- } else {
5836
+ }
5837
+ let data;
5838
+ try {
5839
+ data = await resp.text();
5840
+ } catch (error) {
5482
5841
  throw new FailedHTTPResponse(
5483
5842
  resp.status,
5484
5843
  resp.statusText,
5485
- await resp.text()
5844
+ "Unable to read response body",
5845
+ error
5486
5846
  );
5487
5847
  }
5848
+ throw new FailedHTTPResponse(resp.status, resp.statusText, data);
5488
5849
  }
5489
5850
  var HTTPConnection = class _HTTPConnection {
5490
- base_url;
5491
- token;
5492
- headers;
5493
- fetch;
5494
- constructor(base_url, fetch2) {
5851
+ constructor(base_url, fetch2, classifyTransportErrors = false) {
5852
+ this.classifyTransportErrors = classifyTransportErrors;
5495
5853
  this.base_url = base_url;
5496
5854
  this.token = null;
5497
5855
  this.headers = {};
5498
5856
  this._reset();
5499
5857
  this.fetch = fetch2;
5500
5858
  }
5859
+ classifyTransportErrors;
5860
+ base_url;
5861
+ token;
5862
+ headers;
5863
+ fetch;
5501
5864
  setFetch(fetch2) {
5502
5865
  this.fetch = fetch2;
5503
5866
  }
@@ -5537,9 +5900,9 @@ var HTTPConnection = class _HTTPConnection {
5537
5900
  ).toString();
5538
5901
  const this_fetch = this.fetch;
5539
5902
  const this_headers = this.headers;
5540
- return await checkResponse(
5541
- // Using toString() here makes it work with isomorphic fetch
5542
- await this_fetch(url.toString(), {
5903
+ let response;
5904
+ try {
5905
+ response = await this_fetch(url.toString(), {
5543
5906
  headers: {
5544
5907
  Accept: "application/json",
5545
5908
  ...this_headers,
@@ -5547,8 +5910,14 @@ var HTTPConnection = class _HTTPConnection {
5547
5910
  },
5548
5911
  keepalive: true,
5549
5912
  ...rest
5550
- })
5551
- );
5913
+ });
5914
+ } catch (error) {
5915
+ if (config?.signal?.aborted) {
5916
+ throw getAbortReason(config.signal);
5917
+ }
5918
+ rethrowHTTPTransportError(error, this.classifyTransportErrors);
5919
+ }
5920
+ return await checkResponse(response);
5552
5921
  }
5553
5922
  async post(path, params, config, retries = 0) {
5554
5923
  const { headers, ...rest } = config || {};
@@ -5558,8 +5927,9 @@ var HTTPConnection = class _HTTPConnection {
5558
5927
  const tries = retries + 1;
5559
5928
  for (let i = 0; i < tries; i++) {
5560
5929
  try {
5561
- return await checkResponse(
5562
- await this_fetch(_urljoin(this_base_url, path), {
5930
+ let response;
5931
+ try {
5932
+ response = await this_fetch(_urljoin(this_base_url, path), {
5563
5933
  method: "POST",
5564
5934
  headers: {
5565
5935
  Accept: "application/json",
@@ -5570,8 +5940,14 @@ var HTTPConnection = class _HTTPConnection {
5570
5940
  body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5571
5941
  keepalive: true,
5572
5942
  ...rest
5573
- })
5574
- );
5943
+ });
5944
+ } catch (error) {
5945
+ if (config?.signal?.aborted) {
5946
+ throw getAbortReason(config.signal);
5947
+ }
5948
+ rethrowHTTPTransportError(error, this.classifyTransportErrors);
5949
+ }
5950
+ return await checkResponse(response);
5575
5951
  } catch (error) {
5576
5952
  if (config?.signal?.aborted) {
5577
5953
  throw getAbortReason(config.signal);
@@ -5596,7 +5972,7 @@ var HTTPConnection = class _HTTPConnection {
5596
5972
  for (let i = 0; i < tries; i++) {
5597
5973
  try {
5598
5974
  const resp = await this.get(`${object_type}`, args);
5599
- return await resp.json();
5975
+ return await readJSONResponse(resp, this.classifyTransportErrors);
5600
5976
  } catch (e) {
5601
5977
  if (i < tries - 1) {
5602
5978
  debugLogger.debug(
@@ -5619,7 +5995,7 @@ var HTTPConnection = class _HTTPConnection {
5619
5995
  const resp = await this.post(`${object_type}`, args, {
5620
5996
  headers: { "Content-Type": "application/json" }
5621
5997
  });
5622
- return await resp.json();
5998
+ return await readJSONResponse(resp, this.classifyTransportErrors);
5623
5999
  }
5624
6000
  // Custom inspect for Node.js console.log
5625
6001
  [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
@@ -7100,6 +7476,52 @@ async function computeLoggerMetadata(state2, {
7100
7476
  };
7101
7477
  }
7102
7478
  }
7479
+ async function loginToLoaderRequestState({
7480
+ appUrl,
7481
+ apiKey,
7482
+ orgName,
7483
+ fetch: fetch2
7484
+ }) {
7485
+ let orgId;
7486
+ let apiUrl;
7487
+ if (apiKey === TEST_API_KEY) {
7488
+ orgId = "test-org-id";
7489
+ apiUrl = "https://braintrust.dev/fake-api-url";
7490
+ } else {
7491
+ let loginResponse;
7492
+ try {
7493
+ loginResponse = await fetch2(_urljoin(appUrl, `/api/apikey/login`), {
7494
+ method: "POST",
7495
+ headers: {
7496
+ "Content-Type": "application/json",
7497
+ Authorization: `Bearer ${apiKey}`
7498
+ }
7499
+ });
7500
+ } catch (error) {
7501
+ throw new HTTPTransportError(error);
7502
+ }
7503
+ const info = await readJSONResponse(
7504
+ await checkResponse(loginResponse),
7505
+ true
7506
+ );
7507
+ const org = selectLoginOrg(info.org_info, orgName);
7508
+ orgId = org.id;
7509
+ apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
7510
+ if (!apiUrl) {
7511
+ throw new Error(
7512
+ orgName ? `Unable to log into organization '${orgName}'. Are you sure this credential is scoped to the organization?` : "Unable to log into any organization with the provided credential."
7513
+ );
7514
+ }
7515
+ }
7516
+ const apiConnection = new HTTPConnection(apiUrl, fetch2, true);
7517
+ apiConnection.set_token(apiKey);
7518
+ apiConnection.make_long_lived();
7519
+ return {
7520
+ appUrl,
7521
+ orgId,
7522
+ apiConn: () => apiConnection
7523
+ };
7524
+ }
7103
7525
  async function loginToState(options = {}) {
7104
7526
  const {
7105
7527
  appUrl = isomorph_default.getEnv("BRAINTRUST_APP_URL") || "https://www.braintrust.dev",
@@ -7131,16 +7553,18 @@ async function loginToState(options = {}) {
7131
7553
  _saveOrgInfo(state2, testOrgInfo, testOrgInfo[0].name);
7132
7554
  return state2;
7133
7555
  } else {
7134
- const resp = await checkResponse(
7135
- await fetch2(_urljoin(state2.appUrl, `/api/apikey/login`), {
7556
+ const loginResponse = await fetch2(
7557
+ _urljoin(state2.appUrl, `/api/apikey/login`),
7558
+ {
7136
7559
  method: "POST",
7137
7560
  headers: {
7138
7561
  "Content-Type": "application/json",
7139
7562
  Authorization: `Bearer ${apiKey}`
7140
7563
  }
7141
- })
7564
+ }
7142
7565
  );
7143
- const info = await resp.json();
7566
+ const resp = await checkResponse(loginResponse);
7567
+ const info = await readJSONResponse(resp);
7144
7568
  _saveOrgInfo(state2, info.org_info, orgName);
7145
7569
  if (!state2.apiUrl) {
7146
7570
  if (orgName) {
@@ -7492,27 +7916,28 @@ function withCurrent(span, callback, state2 = void 0) {
7492
7916
  const currentState = state2 ?? _globalState;
7493
7917
  return currentState.contextManager.runInContext(span, () => callback(span));
7494
7918
  }
7495
- function _saveOrgInfo(state2, org_info, org_name) {
7496
- if (org_info.length === 0) {
7919
+ function _saveOrgInfo(state2, orgInfo, orgName) {
7920
+ const org = selectLoginOrg(orgInfo, orgName);
7921
+ state2.orgId = org.id;
7922
+ state2.orgName = org.name;
7923
+ state2.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
7924
+ state2.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
7925
+ state2.gitMetadataSettings = org.git_metadata || void 0;
7926
+ }
7927
+ function selectLoginOrg(orgInfo, orgName) {
7928
+ if (orgInfo.length === 0) {
7497
7929
  throw new LoginInvalidOrgError(
7498
7930
  "This user is not part of any organizations."
7499
7931
  );
7500
7932
  }
7501
- for (const org of org_info) {
7502
- if (org_name === void 0 || org.name === org_name) {
7503
- state2.orgId = org.id;
7504
- state2.orgName = org.name;
7505
- state2.apiUrl = isomorph_default.getEnv("BRAINTRUST_API_URL") ?? org.api_url;
7506
- state2.proxyUrl = isomorph_default.getEnv("BRAINTRUST_PROXY_URL") ?? org.proxy_url;
7507
- state2.gitMetadataSettings = org.git_metadata || void 0;
7508
- break;
7933
+ for (const org of orgInfo) {
7934
+ if (orgName === void 0 || org.name === orgName) {
7935
+ return org;
7509
7936
  }
7510
7937
  }
7511
- if (state2.orgId === void 0) {
7512
- throw new LoginInvalidOrgError(
7513
- `Organization ${org_name} not found. Must be one of ${org_info.map((x) => x.name).join(", ")}`
7514
- );
7515
- }
7938
+ throw new LoginInvalidOrgError(
7939
+ `Organization ${orgName} not found. Must be one of ${orgInfo.map((org) => org.name).join(", ")}`
7940
+ );
7516
7941
  }
7517
7942
  function validateTags(tags) {
7518
7943
  const seen = /* @__PURE__ */ new Set();
@@ -7677,6 +8102,19 @@ function enrichAttachments(event, state2) {
7677
8102
  }
7678
8103
  return event;
7679
8104
  }
8105
+ async function resolveAttachmentsToBase64(event, state2) {
8106
+ for (const [key, value] of Object.entries(event)) {
8107
+ if (value instanceof ReadonlyAttachment) {
8108
+ event[key] = await value.asBase64Url();
8109
+ continue;
8110
+ }
8111
+ if (!(value instanceof Object)) {
8112
+ continue;
8113
+ }
8114
+ await resolveAttachmentsToBase64(value, state2);
8115
+ }
8116
+ return event;
8117
+ }
7680
8118
  function validateAndSanitizeExperimentLogFullArgs(event, hasDataset) {
7681
8119
  if ("input" in event && !isEmpty2(event.input) && "inputs" in event && !isEmpty2(event.inputs) || !("input" in event) && !("inputs" in event)) {
7682
8120
  throw new Error(
@@ -7734,7 +8172,7 @@ var ObjectFetcher = class {
7734
8172
  const objectId = await this.id;
7735
8173
  const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
7736
8174
  const internalLimit = getInternalBtqlLimit(this._internal_btql);
7737
- const limit = batchSize !== void 0 ? batchSize : internalLimit ?? batchLimit;
8175
+ let remainingLimit = internalLimit;
7738
8176
  const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
7739
8177
  Object.entries(this._internal_btql ?? {}).filter(
7740
8178
  ([key]) => key !== "cursor" && key !== "limit" && key !== "select" && key !== "from"
@@ -7743,6 +8181,10 @@ var ObjectFetcher = class {
7743
8181
  let cursor = void 0;
7744
8182
  let iterations = 0;
7745
8183
  while (true) {
8184
+ if (remainingLimit !== void 0 && remainingLimit <= 0) {
8185
+ return;
8186
+ }
8187
+ const limit = remainingLimit === void 0 ? batchLimit : Math.min(batchLimit, remainingLimit);
7746
8188
  const resp = await state2.apiConn().post(
7747
8189
  `btql`,
7748
8190
  {
@@ -7782,7 +8224,14 @@ var ObjectFetcher = class {
7782
8224
  const respJson = await resp.json();
7783
8225
  const mutate = this.mutateRecord;
7784
8226
  for (const record of respJson.data ?? []) {
7785
- yield mutate ? mutate(record) : record;
8227
+ if (remainingLimit !== void 0 && remainingLimit <= 0) {
8228
+ return;
8229
+ }
8230
+ const mutatedRecord = mutate ? mutate(record) : record;
8231
+ if (remainingLimit !== void 0) {
8232
+ remainingLimit--;
8233
+ }
8234
+ yield mutatedRecord;
7786
8235
  }
7787
8236
  if (!respJson.cursor) {
7788
8237
  break;
@@ -8259,7 +8708,9 @@ var SpanImpl = class _SpanImpl {
8259
8708
  this._rootSpanId = resolvedIds.rootSpanId;
8260
8709
  this._spanParents = resolvedIds.spanParents;
8261
8710
  this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
8262
- this.logInternal({ event, internalData });
8711
+ if (!args[RESUME_SPAN_WITHOUT_INITIAL_WRITE]) {
8712
+ this.logInternal({ event, internalData });
8713
+ }
8263
8714
  this.isMerge = true;
8264
8715
  }
8265
8716
  getParentInfo() {
@@ -8953,6 +9404,473 @@ var Dataset2 = class extends ObjectFetcher {
8953
9404
  return typeof data === "object" && data !== null && "__braintrust_dataset_marker" in data;
8954
9405
  }
8955
9406
  };
9407
+ function isAttachmentObject(value) {
9408
+ return BraintrustAttachmentReference.safeParse(value).success || InlineAttachmentReferenceSchema.safeParse(value).success || ExternalAttachmentReference.safeParse(value).success;
9409
+ }
9410
+ function isURL(url) {
9411
+ try {
9412
+ const parsedUrl = new URL(url.trim());
9413
+ return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
9414
+ } catch {
9415
+ return false;
9416
+ }
9417
+ }
9418
+ function expandAttachmentArrayPreTemplate(content, variables) {
9419
+ if (typeof content !== "string") return null;
9420
+ const match = content.match(/^\{\{\s*([\w.]+)\s*\}\}$/);
9421
+ if (!match) return null;
9422
+ const varPath = match[1];
9423
+ const value = varPath.includes(".") ? getObjValueByPath(variables, varPath.split(".")) : variables[varPath];
9424
+ if (!Array.isArray(value)) return null;
9425
+ const allValid = value.every(
9426
+ (v) => isAttachmentObject(v) || typeof v === "string" && isURL(v)
9427
+ );
9428
+ if (!allValid) return null;
9429
+ return value.map((item) => ({
9430
+ type: "image_url",
9431
+ image_url: { url: item }
9432
+ }));
9433
+ }
9434
+ function renderMessageImpl(render, message, variables) {
9435
+ return {
9436
+ ...message,
9437
+ ..."content" in message ? {
9438
+ content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.flatMap((c) => {
9439
+ switch (c.type) {
9440
+ case "text":
9441
+ return [{ ...c, text: render(c.text) }];
9442
+ case "image_url":
9443
+ if (isObject(c.image_url.url)) {
9444
+ throw new Error(
9445
+ "Attachments must be replaced with URLs before calling `build()`"
9446
+ );
9447
+ }
9448
+ if (variables) {
9449
+ const expanded = expandAttachmentArrayPreTemplate(
9450
+ c.image_url.url,
9451
+ variables
9452
+ );
9453
+ if (expanded) {
9454
+ return expanded;
9455
+ }
9456
+ }
9457
+ return [
9458
+ {
9459
+ ...c,
9460
+ image_url: {
9461
+ ...c.image_url,
9462
+ url: render(c.image_url.url)
9463
+ }
9464
+ }
9465
+ ];
9466
+ case "file":
9467
+ return [
9468
+ {
9469
+ ...c,
9470
+ file: {
9471
+ ...c.file.file_data && {
9472
+ file_data: render(c.file.file_data)
9473
+ },
9474
+ ...c.file.file_id && {
9475
+ file_id: render(c.file.file_id)
9476
+ },
9477
+ ...c.file.filename && {
9478
+ filename: render(c.file.filename)
9479
+ }
9480
+ }
9481
+ }
9482
+ ];
9483
+ default:
9484
+ const _exhaustiveCheck = c;
9485
+ return _exhaustiveCheck;
9486
+ }
9487
+ })
9488
+ } : {},
9489
+ ..."tool_calls" in message ? {
9490
+ tool_calls: isEmpty2(message.tool_calls) ? void 0 : message.tool_calls.map((t) => {
9491
+ return {
9492
+ type: t.type,
9493
+ id: render(t.id),
9494
+ function: {
9495
+ name: render(t.function.name),
9496
+ arguments: render(t.function.arguments)
9497
+ }
9498
+ };
9499
+ })
9500
+ } : {},
9501
+ ..."tool_call_id" in message ? {
9502
+ tool_call_id: render(message.tool_call_id)
9503
+ } : {}
9504
+ };
9505
+ }
9506
+ function deserializePlainStringAsJSON(s) {
9507
+ if (s.trim() === "") {
9508
+ return { value: null, error: void 0 };
9509
+ }
9510
+ try {
9511
+ return { value: JSON.parse(s), error: void 0 };
9512
+ } catch (e) {
9513
+ return { value: s, error: e };
9514
+ }
9515
+ }
9516
+ function renderTemplatedObject(obj, args, options) {
9517
+ if (typeof obj === "string") {
9518
+ return renderTemplateContent(
9519
+ obj,
9520
+ args,
9521
+ (value) => typeof value === "string" ? value : JSON.stringify(value),
9522
+ {
9523
+ strict: options.strict,
9524
+ templateFormat: options.templateFormat
9525
+ }
9526
+ );
9527
+ } else if (isArray(obj)) {
9528
+ return obj.map((item) => renderTemplatedObject(item, args, options));
9529
+ } else if (isObject(obj)) {
9530
+ return Object.fromEntries(
9531
+ Object.entries(obj).map(([key, value]) => [
9532
+ key,
9533
+ renderTemplatedObject(value, args, options)
9534
+ ])
9535
+ );
9536
+ }
9537
+ return obj;
9538
+ }
9539
+ function renderPromptParams(params, args, options = {}) {
9540
+ const templateFormat = parseTemplateFormat(options.templateFormat);
9541
+ const strict = !!options.strict;
9542
+ const schemaParsed = z8.object({
9543
+ response_format: z8.object({
9544
+ type: z8.literal("json_schema"),
9545
+ json_schema: ResponseFormatJsonSchema.omit({ schema: true }).extend({
9546
+ schema: z8.unknown()
9547
+ })
9548
+ })
9549
+ }).safeParse(params);
9550
+ if (schemaParsed.success) {
9551
+ const rawSchema = schemaParsed.data.response_format.json_schema.schema;
9552
+ const templatedSchema = renderTemplatedObject(rawSchema, args, {
9553
+ strict,
9554
+ templateFormat
9555
+ });
9556
+ const parsedSchema = typeof templatedSchema === "string" ? deserializePlainStringAsJSON(templatedSchema).value : templatedSchema;
9557
+ return {
9558
+ ...params,
9559
+ response_format: {
9560
+ ...schemaParsed.data.response_format,
9561
+ json_schema: {
9562
+ ...schemaParsed.data.response_format.json_schema,
9563
+ schema: parsedSchema
9564
+ }
9565
+ }
9566
+ };
9567
+ }
9568
+ return params;
9569
+ }
9570
+ var Prompt2 = class _Prompt {
9571
+ constructor(metadata, defaults, noTrace) {
9572
+ this.metadata = metadata;
9573
+ this.defaults = defaults;
9574
+ this.noTrace = noTrace;
9575
+ void this.__braintrust_prompt_marker;
9576
+ }
9577
+ metadata;
9578
+ defaults;
9579
+ noTrace;
9580
+ parsedPromptData;
9581
+ hasParsedPromptData = false;
9582
+ __braintrust_prompt_marker = true;
9583
+ get id() {
9584
+ return this.metadata.id;
9585
+ }
9586
+ get projectId() {
9587
+ return this.metadata.project_id;
9588
+ }
9589
+ get name() {
9590
+ return "name" in this.metadata ? this.metadata.name : `Playground function ${this.metadata.id}`;
9591
+ }
9592
+ get slug() {
9593
+ return "slug" in this.metadata ? this.metadata.slug : this.metadata.id;
9594
+ }
9595
+ get prompt() {
9596
+ return this.getParsedPromptData()?.prompt;
9597
+ }
9598
+ get version() {
9599
+ return this.metadata[TRANSACTION_ID_FIELD];
9600
+ }
9601
+ get options() {
9602
+ return this.getParsedPromptData()?.options || {};
9603
+ }
9604
+ get templateFormat() {
9605
+ return this.getParsedPromptData()?.template_format;
9606
+ }
9607
+ get promptData() {
9608
+ return this.getParsedPromptData();
9609
+ }
9610
+ /**
9611
+ * Build the prompt with the given formatting options. The args you pass in will
9612
+ * be forwarded to the mustache template that defines the prompt and rendered with
9613
+ * the `mustache-js` library.
9614
+ *
9615
+ * @param buildArgs Args to forward along to the prompt template.
9616
+ */
9617
+ build(buildArgs, options = {}) {
9618
+ return this.runBuild(buildArgs, {
9619
+ flavor: options.flavor ?? "chat",
9620
+ messages: options.messages,
9621
+ strict: options.strict,
9622
+ templateFormat: options.templateFormat
9623
+ });
9624
+ }
9625
+ /**
9626
+ * This is a special build method that first resolves attachment references, and then
9627
+ * calls the regular build method. You should use this if you are building prompts from
9628
+ * dataset rows that contain attachments.
9629
+ *
9630
+ * @param buildArgs Args to forward along to the prompt template.
9631
+ */
9632
+ async buildWithAttachments(buildArgs, options = {}) {
9633
+ const hydrated = buildArgs instanceof Object ? await resolveAttachmentsToBase64(buildArgs, options.state) : buildArgs;
9634
+ return this.runBuild(hydrated, {
9635
+ flavor: options.flavor ?? "chat",
9636
+ messages: options.messages,
9637
+ strict: options.strict,
9638
+ templateFormat: options.templateFormat
9639
+ });
9640
+ }
9641
+ runBuild(buildArgs, options) {
9642
+ const { flavor } = options;
9643
+ const params = Object.fromEntries(
9644
+ Object.entries({
9645
+ ...this.defaults,
9646
+ ...Object.fromEntries(
9647
+ Object.entries(this.options.params || {}).filter(
9648
+ ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
9649
+ )
9650
+ ),
9651
+ ...!isEmpty2(this.options.model) ? {
9652
+ model: this.options.model
9653
+ } : {}
9654
+ }).filter(([key, value]) => key !== "response_format" || value !== null)
9655
+ );
9656
+ if (!("model" in params) || isEmpty2(params.model)) {
9657
+ throw new Error(
9658
+ "No model specified. Either specify it in the prompt or as a default"
9659
+ );
9660
+ }
9661
+ const spanInfo = this.noTrace ? {} : {
9662
+ span_info: {
9663
+ metadata: {
9664
+ prompt: this.id ? {
9665
+ variables: buildArgs,
9666
+ id: this.id,
9667
+ project_id: this.projectId,
9668
+ version: this.version,
9669
+ ..."prompt_session_id" in this.metadata ? { prompt_session_id: this.metadata.prompt_session_id } : {}
9670
+ } : void 0
9671
+ }
9672
+ }
9673
+ };
9674
+ const prompt = this.prompt;
9675
+ if (!prompt) {
9676
+ throw new Error("Empty prompt");
9677
+ }
9678
+ const dictArgParsed = z8.record(z8.unknown()).safeParse(buildArgs);
9679
+ const variables = {
9680
+ input: buildArgs,
9681
+ ...dictArgParsed.success ? dictArgParsed.data : {}
9682
+ };
9683
+ const promptDataTemplateFormat = this.templateFormat;
9684
+ const resolvedTemplateFormat = parseTemplateFormat(
9685
+ options.templateFormat ?? promptDataTemplateFormat
9686
+ );
9687
+ const renderedPrompt = _Prompt.renderPrompt({
9688
+ prompt,
9689
+ buildArgs,
9690
+ options: { ...options, templateFormat: resolvedTemplateFormat }
9691
+ });
9692
+ if (flavor === "chat") {
9693
+ if (renderedPrompt.type !== "chat") {
9694
+ throw new Error(
9695
+ "Prompt is a completion prompt. Use buildCompletion() instead"
9696
+ );
9697
+ }
9698
+ return {
9699
+ ...renderPromptParams(params, variables, {
9700
+ strict: options.strict,
9701
+ templateFormat: resolvedTemplateFormat
9702
+ }),
9703
+ ...spanInfo,
9704
+ messages: renderedPrompt.messages,
9705
+ ...renderedPrompt.tools ? {
9706
+ tools: ChatCompletionTool.array().parse(JSON.parse(renderedPrompt.tools))
9707
+ } : void 0
9708
+ };
9709
+ } else if (flavor === "completion") {
9710
+ if (renderedPrompt.type !== "completion") {
9711
+ throw new Error(`Prompt is a chat prompt. Use flavor: 'chat' instead`);
9712
+ }
9713
+ return {
9714
+ ...renderPromptParams(params, variables, {
9715
+ strict: options.strict,
9716
+ templateFormat: resolvedTemplateFormat
9717
+ }),
9718
+ ...spanInfo,
9719
+ prompt: renderedPrompt.content
9720
+ };
9721
+ } else {
9722
+ throw new Error("never!");
9723
+ }
9724
+ }
9725
+ static renderPrompt({
9726
+ prompt,
9727
+ buildArgs,
9728
+ options
9729
+ }) {
9730
+ const escape = (v) => {
9731
+ if (v === void 0) {
9732
+ throw new Error("Missing!");
9733
+ } else if (typeof v === "string") {
9734
+ return v;
9735
+ } else if (v instanceof ReadonlyAttachment) {
9736
+ throw new Error(
9737
+ "Use buildWithAttachments() to build prompts with attachments"
9738
+ );
9739
+ } else {
9740
+ return JSON.stringify(v);
9741
+ }
9742
+ };
9743
+ const dictArgParsed = z8.record(z8.unknown()).safeParse(buildArgs);
9744
+ const variables = {
9745
+ input: buildArgs,
9746
+ ...dictArgParsed.success ? dictArgParsed.data : {}
9747
+ };
9748
+ const templateFormat = parseTemplateFormat(options.templateFormat);
9749
+ if (prompt.type === "chat") {
9750
+ const render = (template) => renderTemplateContent(template, variables, escape, {
9751
+ strict: options.strict,
9752
+ templateFormat
9753
+ });
9754
+ const baseMessages = (prompt.messages || []).map(
9755
+ (m) => renderMessageImpl(render, m, variables)
9756
+ );
9757
+ const hasSystemPrompt = baseMessages.some((m) => m.role === "system");
9758
+ const messages = [
9759
+ ...baseMessages,
9760
+ ...(options.messages ?? []).filter(
9761
+ (m) => !(hasSystemPrompt && m.role === "system")
9762
+ )
9763
+ ];
9764
+ return {
9765
+ type: "chat",
9766
+ messages,
9767
+ ...prompt.tools?.trim() ? {
9768
+ tools: render(prompt.tools)
9769
+ } : void 0
9770
+ };
9771
+ } else if (prompt.type === "completion") {
9772
+ if (options.messages) {
9773
+ throw new Error(
9774
+ "extra messages are not supported for completion prompts"
9775
+ );
9776
+ }
9777
+ const content = renderTemplateContent(prompt.content, variables, escape, {
9778
+ strict: options.strict,
9779
+ templateFormat
9780
+ });
9781
+ return {
9782
+ type: "completion",
9783
+ content
9784
+ };
9785
+ } else {
9786
+ const _ = prompt;
9787
+ throw new Error(`Invalid prompt type: ${_}`);
9788
+ }
9789
+ }
9790
+ getParsedPromptData() {
9791
+ if (!this.hasParsedPromptData) {
9792
+ this.parsedPromptData = PromptData.parse(this.metadata.prompt_data);
9793
+ this.hasParsedPromptData = true;
9794
+ }
9795
+ return this.parsedPromptData;
9796
+ }
9797
+ static isPrompt(data) {
9798
+ return typeof data === "object" && data !== null && "__braintrust_prompt_marker" in data;
9799
+ }
9800
+ /** @internal */
9801
+ _internalSerializeForCache() {
9802
+ return {
9803
+ metadata: this.metadata,
9804
+ defaults: this.defaults,
9805
+ noTrace: this.noTrace
9806
+ };
9807
+ }
9808
+ static fromPromptData(name, promptData) {
9809
+ return new _Prompt(
9810
+ {
9811
+ name,
9812
+ slug: name,
9813
+ prompt_data: promptData
9814
+ },
9815
+ {},
9816
+ false
9817
+ );
9818
+ }
9819
+ };
9820
+ var RemoteEvalParameters = class {
9821
+ constructor(metadata) {
9822
+ this.metadata = metadata;
9823
+ void this.__braintrust_parameters_marker;
9824
+ }
9825
+ metadata;
9826
+ __braintrust_parameters_marker = true;
9827
+ get id() {
9828
+ return this.metadata.id;
9829
+ }
9830
+ get projectId() {
9831
+ return this.metadata.project_id;
9832
+ }
9833
+ get name() {
9834
+ return this.metadata.name;
9835
+ }
9836
+ get slug() {
9837
+ return this.metadata.slug;
9838
+ }
9839
+ get version() {
9840
+ return this.metadata[TRANSACTION_ID_FIELD];
9841
+ }
9842
+ get schema() {
9843
+ return this.metadata.function_data.__schema;
9844
+ }
9845
+ get data() {
9846
+ return this.metadata.function_data.data ?? {};
9847
+ }
9848
+ /** @internal */
9849
+ _internalSerializeForCache() {
9850
+ return { metadata: this.metadata };
9851
+ }
9852
+ validate(data) {
9853
+ if (typeof data !== "object" || data === null) {
9854
+ return false;
9855
+ }
9856
+ const schemaProps = this.schema.properties;
9857
+ if (typeof schemaProps !== "object" || schemaProps === null) {
9858
+ return true;
9859
+ }
9860
+ for (const key of Object.keys(schemaProps)) {
9861
+ if (!(key in data)) {
9862
+ const required = Array.isArray(this.schema.required) ? this.schema.required : [];
9863
+ if (required.includes(key)) {
9864
+ return false;
9865
+ }
9866
+ }
9867
+ }
9868
+ return true;
9869
+ }
9870
+ static isParameters(x) {
9871
+ return typeof x === "object" && x !== null && "__braintrust_parameters_marker" in x && x.__braintrust_parameters_marker === true;
9872
+ }
9873
+ };
8956
9874
  var TEST_API_KEY = "___TEST_API_KEY__THIS_IS_NOT_REAL___";
8957
9875
 
8958
9876
  // src/wrappers/mastra.ts
@@ -9249,6 +10167,10 @@ var aiSDKChannels = defineChannels(
9249
10167
  channelName: "generateText",
9250
10168
  kind: "async"
9251
10169
  }),
10170
+ generateImage: channel({
10171
+ channelName: "generateImage",
10172
+ kind: "async"
10173
+ }),
9252
10174
  streamText: channel({
9253
10175
  channelName: "streamText",
9254
10176
  kind: "async"
@@ -9388,6 +10310,33 @@ var aiSDKConfigs = [
9388
10310
  kind: "Async"
9389
10311
  }
9390
10312
  },
10313
+ // generateImage - stable in v6+, experimental alias in v5
10314
+ ...[
10315
+ {
10316
+ functionName: "generateImage",
10317
+ versionRange: ">=6.0.0 <8.0.0",
10318
+ isExportAlias: false
10319
+ },
10320
+ {
10321
+ functionName: "experimental_generateImage",
10322
+ versionRange: ">=5.0.0 <6.0.0",
10323
+ isExportAlias: true
10324
+ }
10325
+ ].flatMap(
10326
+ ({ functionName, versionRange: versionRange2, isExportAlias }) => ["dist/index.mjs", "dist/index.js"].map((filePath) => ({
10327
+ channelName: aiSDKChannels.generateImage.channelName,
10328
+ module: {
10329
+ name: "ai",
10330
+ versionRange: versionRange2,
10331
+ filePath
10332
+ },
10333
+ functionQuery: {
10334
+ functionName,
10335
+ kind: "Async",
10336
+ ...isExportAlias ? { isExportAlias } : {}
10337
+ }
10338
+ }))
10339
+ ),
9391
10340
  // streamText - async function (v3 only, before the sync refactor in v4)
9392
10341
  {
9393
10342
  channelName: aiSDKChannels.streamText.channelName,
@@ -12629,6 +13578,77 @@ var strandsAgentSDKConfigs = [
12629
13578
  }
12630
13579
  ];
12631
13580
 
13581
+ // src/instrumentation/plugins/voyageai-channels.ts
13582
+ var voyageAIChannels = defineChannels(
13583
+ "voyageai",
13584
+ {
13585
+ embed: channel({
13586
+ channelName: "embed",
13587
+ kind: "async"
13588
+ }),
13589
+ multimodalEmbed: channel({
13590
+ channelName: "multimodalEmbed",
13591
+ kind: "async"
13592
+ }),
13593
+ rerank: channel({
13594
+ channelName: "rerank",
13595
+ kind: "async"
13596
+ }),
13597
+ contextualizedEmbed: channel({
13598
+ channelName: "contextualizedEmbed",
13599
+ kind: "async"
13600
+ })
13601
+ },
13602
+ { instrumentationName: INSTRUMENTATION_NAMES.VOYAGEAI }
13603
+ );
13604
+
13605
+ // src/auto-instrumentations/configs/voyageai.ts
13606
+ var GENERATED_CLIENT_MODULES = [
13607
+ "dist/cjs/Client.js",
13608
+ "dist/esm/Client.mjs"
13609
+ ];
13610
+ var generatedClientOperations = [
13611
+ {
13612
+ channelName: voyageAIChannels.embed.channelName,
13613
+ methodName: "embed",
13614
+ versionRange: ">=0.2.0 <1.0.0"
13615
+ },
13616
+ {
13617
+ channelName: voyageAIChannels.multimodalEmbed.channelName,
13618
+ methodName: "multimodalEmbed",
13619
+ versionRange: ">=0.2.0 <1.0.0"
13620
+ },
13621
+ {
13622
+ channelName: voyageAIChannels.rerank.channelName,
13623
+ methodName: "rerank",
13624
+ versionRange: ">=0.2.0 <1.0.0"
13625
+ },
13626
+ {
13627
+ channelName: voyageAIChannels.contextualizedEmbed.channelName,
13628
+ methodName: "contextualizedEmbed",
13629
+ versionRange: ">=0.2.0 <1.0.0"
13630
+ }
13631
+ ];
13632
+ var voyageAIConfigs = [
13633
+ ...GENERATED_CLIENT_MODULES.flatMap(
13634
+ (filePath) => generatedClientOperations.map(
13635
+ ({ channelName, methodName, versionRange: versionRange2 }) => ({
13636
+ channelName,
13637
+ module: {
13638
+ name: "voyageai",
13639
+ versionRange: versionRange2,
13640
+ filePath
13641
+ },
13642
+ functionQuery: {
13643
+ className: "VoyageAIClient",
13644
+ methodName,
13645
+ kind: "Async"
13646
+ }
13647
+ })
13648
+ )
13649
+ )
13650
+ ];
13651
+
12632
13652
  // src/auto-instrumentations/configs/all.ts
12633
13653
  var defaultInstrumentationConfigGroups = [
12634
13654
  { integrations: ["openai"], configs: openaiConfigs },
@@ -12708,6 +13728,10 @@ var defaultInstrumentationConfigGroups = [
12708
13728
  {
12709
13729
  integrations: ["flue"],
12710
13730
  configs: flueConfigs
13731
+ },
13732
+ {
13733
+ integrations: ["voyageai"],
13734
+ configs: voyageAIConfigs
12711
13735
  }
12712
13736
  // Note: `@mastra/core` is not listed here because its instrumentation
12713
13737
  // doesn't go through the AST `code-transformer` matcher — Mastra's
@@ -12732,8 +13756,9 @@ function getDefaultInstrumentationConfigs({
12732
13756
  ...additionalInstrumentations ?? []
12733
13757
  ];
12734
13758
  }
12735
- function getDefaultAutoInstrumentationConfigs() {
13759
+ function getDefaultAutoInstrumentationConfigs(additionalInstrumentations) {
12736
13760
  return getDefaultInstrumentationConfigs({
13761
+ additionalInstrumentations,
12737
13762
  disabledIntegrationConfig: readDisabledInstrumentationEnvConfig(
12738
13763
  process.env.BRAINTRUST_DISABLE_INSTRUMENTATION
12739
13764
  ).integrations