braintrust 3.4.0 → 3.5.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 (50) hide show
  1. package/dev/dist/index.d.mts +45 -5
  2. package/dev/dist/index.d.ts +45 -5
  3. package/dev/dist/index.js +992 -245
  4. package/dev/dist/index.mjs +914 -167
  5. package/dist/auto-instrumentations/bundler/esbuild.cjs +208 -10
  6. package/dist/auto-instrumentations/bundler/esbuild.d.mts +2 -2
  7. package/dist/auto-instrumentations/bundler/esbuild.d.ts +2 -2
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/rollup.cjs +208 -10
  10. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  11. package/dist/auto-instrumentations/bundler/vite.cjs +208 -10
  12. package/dist/auto-instrumentations/bundler/vite.d.mts +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.d.ts +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  15. package/dist/auto-instrumentations/bundler/webpack.cjs +208 -10
  16. package/dist/auto-instrumentations/bundler/webpack.d.mts +2 -2
  17. package/dist/auto-instrumentations/bundler/webpack.d.ts +2 -2
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
  19. package/dist/auto-instrumentations/{chunk-LVWWLUMN.mjs → chunk-DQTPSXJB.mjs} +208 -10
  20. package/dist/auto-instrumentations/chunk-EVUKFMHG.mjs +41 -0
  21. package/dist/auto-instrumentations/{chunk-D5ZPIUEL.mjs → chunk-F3TJZ3Z2.mjs} +1 -1
  22. package/dist/auto-instrumentations/chunk-VLEJ5AEK.mjs +41 -0
  23. package/dist/auto-instrumentations/hook.mjs +238 -18
  24. package/dist/auto-instrumentations/index.cjs +208 -10
  25. package/dist/auto-instrumentations/index.mjs +1 -1
  26. package/dist/auto-instrumentations/loader/cjs-patch.cjs +32 -10
  27. package/dist/auto-instrumentations/loader/cjs-patch.mjs +10 -5
  28. package/dist/auto-instrumentations/loader/esm-hook.mjs +4 -4
  29. package/dist/auto-instrumentations/loader/get-package-version.cjs +28 -8
  30. package/dist/auto-instrumentations/loader/get-package-version.d.mts +2 -1
  31. package/dist/auto-instrumentations/loader/get-package-version.d.ts +2 -1
  32. package/dist/auto-instrumentations/loader/get-package-version.mjs +3 -1
  33. package/dist/browser.d.mts +342 -269
  34. package/dist/browser.d.ts +342 -269
  35. package/dist/browser.js +996 -241
  36. package/dist/browser.mjs +996 -241
  37. package/dist/cli.js +1029 -289
  38. package/dist/edge-light.js +1007 -220
  39. package/dist/edge-light.mjs +1007 -220
  40. package/dist/index.d.mts +342 -269
  41. package/dist/index.d.ts +342 -269
  42. package/dist/index.js +1182 -427
  43. package/dist/index.mjs +996 -241
  44. package/dist/instrumentation/index.js +781 -107
  45. package/dist/instrumentation/index.mjs +781 -107
  46. package/dist/workerd.js +1007 -220
  47. package/dist/workerd.mjs +1007 -220
  48. package/package.json +22 -6
  49. package/dist/auto-instrumentations/chunk-XDBPUTVE.mjs +0 -22
  50. package/dist/auto-instrumentations/chunk-ZEC7BCL4.mjs +0 -22
package/dist/index.mjs CHANGED
@@ -28,8 +28,54 @@ var DefaultAsyncLocalStorage = class {
28
28
  return void 0;
29
29
  }
30
30
  };
31
- var DefaultTracingChannel = class {
31
+ var DefaultChannel = class {
32
+ constructor(name) {
33
+ this.name = name;
34
+ }
32
35
  hasSubscribers = false;
36
+ subscribe(_subscription) {
37
+ }
38
+ unsubscribe(_subscription) {
39
+ return false;
40
+ }
41
+ bindStore(_store, _transform) {
42
+ }
43
+ unbindStore(_store) {
44
+ return false;
45
+ }
46
+ publish(_message) {
47
+ }
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
+ runStores(_message, fn, thisArg, ...args) {
50
+ return fn.apply(thisArg, args);
51
+ }
52
+ };
53
+ var DefaultTracingChannel = class {
54
+ start;
55
+ end;
56
+ asyncStart;
57
+ asyncEnd;
58
+ error;
59
+ constructor(nameOrChannels) {
60
+ if (typeof nameOrChannels === "string") {
61
+ this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
62
+ this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
63
+ this.asyncStart = new DefaultChannel(
64
+ `tracing:${nameOrChannels}:asyncStart`
65
+ );
66
+ this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
67
+ this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
68
+ return;
69
+ }
70
+ this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
71
+ this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
72
+ this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
73
+ this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
74
+ this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
75
+ }
76
+ get hasSubscribers() {
77
+ return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
78
+ }
33
79
  subscribe(_handlers) {
34
80
  }
35
81
  unsubscribe(_handlers) {
@@ -57,7 +103,7 @@ var iso = {
57
103
  getCallerLocation: () => void 0,
58
104
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
59
105
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
- newTracingChannel: (_nameOrChannels) => new DefaultTracingChannel(),
106
+ newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
61
107
  processOn: (_0, _1) => {
62
108
  },
63
109
  basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
@@ -2338,6 +2384,8 @@ var Experiment = z6.object({
2338
2384
  deleted_at: z6.union([z6.string(), z6.null()]).optional(),
2339
2385
  dataset_id: z6.union([z6.string(), z6.null()]).optional(),
2340
2386
  dataset_version: z6.union([z6.string(), z6.null()]).optional(),
2387
+ parameters_id: z6.union([z6.string(), z6.null()]).optional(),
2388
+ parameters_version: z6.union([z6.string(), z6.null()]).optional(),
2341
2389
  public: z6.boolean(),
2342
2390
  user_id: z6.union([z6.string(), z6.null()]).optional(),
2343
2391
  metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
@@ -2360,7 +2408,11 @@ var SpanType = z6.union([
2360
2408
  z6.null()
2361
2409
  ]);
2362
2410
  var SpanAttributes = z6.union([
2363
- z6.object({ name: z6.union([z6.string(), z6.null()]), type: SpanType }).partial().passthrough(),
2411
+ z6.object({
2412
+ name: z6.union([z6.string(), z6.null()]),
2413
+ type: SpanType,
2414
+ purpose: z6.union([z6.literal("scorer"), z6.null()])
2415
+ }).partial().passthrough(),
2364
2416
  z6.null()
2365
2417
  ]);
2366
2418
  var ExperimentEvent = z6.object({
@@ -2800,6 +2852,7 @@ var FunctionId = z6.union([
2800
2852
  version: z6.string()
2801
2853
  }),
2802
2854
  code: z6.string(),
2855
+ function_type: FunctionTypeEnum.and(z6.unknown()).optional(),
2803
2856
  name: z6.union([z6.string(), z6.null()]).optional()
2804
2857
  }),
2805
2858
  z6.object({
@@ -3029,7 +3082,12 @@ var TopicAutomationConfig = z6.object({
3029
3082
  topic_map_functions: z6.array(TopicMapFunctionAutomation),
3030
3083
  scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
3031
3084
  data_scope: TopicAutomationDataScope.optional(),
3032
- btql_filter: z6.union([z6.string(), z6.null()]).optional()
3085
+ btql_filter: z6.union([z6.string(), z6.null()]).optional(),
3086
+ backfill_time_range: z6.union([
3087
+ z6.string(),
3088
+ z6.object({ from: z6.string(), to: z6.string() }),
3089
+ z6.null()
3090
+ ]).optional()
3033
3091
  });
3034
3092
  var ProjectAutomation = z6.object({
3035
3093
  id: z6.string().uuid(),
@@ -4468,6 +4526,12 @@ var parametersRowSchema = z8.object({
4468
4526
  }),
4469
4527
  metadata: z8.union([z8.object({}).partial().passthrough(), z8.null()]).optional()
4470
4528
  });
4529
+ var InlineAttachmentReferenceSchema = z8.object({
4530
+ type: z8.literal("inline_attachment"),
4531
+ src: z8.string().min(1),
4532
+ content_type: z8.string().optional(),
4533
+ filename: z8.string().optional()
4534
+ });
4471
4535
  var LoginInvalidOrgError = class extends Error {
4472
4536
  constructor(message) {
4473
4537
  super(message);
@@ -6669,6 +6733,7 @@ function init(projectOrOptions, optionalOptions) {
6669
6733
  experiment,
6670
6734
  description,
6671
6735
  dataset,
6736
+ parameters,
6672
6737
  baseExperiment,
6673
6738
  isPublic,
6674
6739
  open: open2,
@@ -6786,6 +6851,17 @@ function init(projectOrOptions, optionalOptions) {
6786
6851
  args["dataset_version"] = await dataset.version();
6787
6852
  }
6788
6853
  }
6854
+ if (parameters !== void 0) {
6855
+ if (RemoteEvalParameters.isParameters(parameters)) {
6856
+ args["parameters_id"] = parameters.id;
6857
+ args["parameters_version"] = parameters.version;
6858
+ } else {
6859
+ args["parameters_id"] = parameters.id;
6860
+ if (parameters.version !== void 0) {
6861
+ args["parameters_version"] = parameters.version;
6862
+ }
6863
+ }
6864
+ }
6789
6865
  if (isPublic !== void 0) {
6790
6866
  args["public"] = isPublic;
6791
6867
  }
@@ -8984,40 +9060,85 @@ var Dataset2 = class extends ObjectFetcher {
8984
9060
  return typeof data === "object" && data !== null && "__braintrust_dataset_marker" in data;
8985
9061
  }
8986
9062
  };
9063
+ function isAttachmentObject(value) {
9064
+ return BraintrustAttachmentReference.safeParse(value).success || InlineAttachmentReferenceSchema.safeParse(value).success || ExternalAttachmentReference.safeParse(value).success;
9065
+ }
9066
+ function isURL(url) {
9067
+ try {
9068
+ const parsedUrl = new URL(url.trim());
9069
+ return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
9070
+ } catch {
9071
+ return false;
9072
+ }
9073
+ }
9074
+ function expandAttachmentArrayPreTemplate(content, variables) {
9075
+ if (typeof content !== "string") return null;
9076
+ const match = content.match(/^\{\{\s*([\w.]+)\s*\}\}$/);
9077
+ if (!match) return null;
9078
+ const varPath = match[1];
9079
+ const value = varPath.includes(".") ? getObjValueByPath(variables, varPath.split(".")) : variables[varPath];
9080
+ if (!Array.isArray(value)) return null;
9081
+ const allValid = value.every(
9082
+ (v) => isAttachmentObject(v) || typeof v === "string" && isURL(v)
9083
+ );
9084
+ if (!allValid) return null;
9085
+ return value.map((item) => ({
9086
+ type: "image_url",
9087
+ image_url: { url: item }
9088
+ }));
9089
+ }
8987
9090
  function renderMessage(render, message) {
9091
+ return renderMessageImpl(render, message, {});
9092
+ }
9093
+ function renderMessageImpl(render, message, variables) {
8988
9094
  return {
8989
9095
  ...message,
8990
9096
  ..."content" in message ? {
8991
- content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.map((c) => {
9097
+ content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.flatMap((c) => {
8992
9098
  switch (c.type) {
8993
9099
  case "text":
8994
- return { ...c, text: render(c.text) };
9100
+ return [{ ...c, text: render(c.text) }];
8995
9101
  case "image_url":
8996
9102
  if (isObject(c.image_url.url)) {
8997
9103
  throw new Error(
8998
9104
  "Attachments must be replaced with URLs before calling `build()`"
8999
9105
  );
9000
9106
  }
9001
- return {
9002
- ...c,
9003
- image_url: {
9004
- ...c.image_url,
9005
- url: render(c.image_url.url)
9107
+ if (variables) {
9108
+ const expanded = expandAttachmentArrayPreTemplate(
9109
+ c.image_url.url,
9110
+ variables
9111
+ );
9112
+ if (expanded) {
9113
+ return expanded;
9006
9114
  }
9007
- };
9115
+ }
9116
+ return [
9117
+ {
9118
+ ...c,
9119
+ image_url: {
9120
+ ...c.image_url,
9121
+ url: render(c.image_url.url)
9122
+ }
9123
+ }
9124
+ ];
9008
9125
  case "file":
9009
- return {
9010
- ...c,
9011
- file: {
9012
- file_data: render(c.file.file_data || ""),
9013
- ...c.file.file_id && {
9014
- file_id: render(c.file.file_id)
9015
- },
9016
- ...c.file.filename && {
9017
- filename: render(c.file.filename)
9126
+ return [
9127
+ {
9128
+ ...c,
9129
+ file: {
9130
+ ...c.file.file_data && {
9131
+ file_data: render(c.file.file_data)
9132
+ },
9133
+ ...c.file.file_id && {
9134
+ file_id: render(c.file.file_id)
9135
+ },
9136
+ ...c.file.filename && {
9137
+ filename: render(c.file.filename)
9138
+ }
9018
9139
  }
9019
9140
  }
9020
- };
9141
+ ];
9021
9142
  default:
9022
9143
  const _exhaustiveCheck = c;
9023
9144
  return _exhaustiveCheck;
@@ -9174,17 +9295,19 @@ var Prompt2 = class _Prompt {
9174
9295
  }
9175
9296
  runBuild(buildArgs, options) {
9176
9297
  const { flavor } = options;
9177
- const params = {
9178
- ...this.defaults,
9179
- ...Object.fromEntries(
9180
- Object.entries(this.options.params || {}).filter(
9181
- ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
9182
- )
9183
- ),
9184
- ...!isEmpty2(this.options.model) ? {
9185
- model: this.options.model
9186
- } : {}
9187
- };
9298
+ const params = Object.fromEntries(
9299
+ Object.entries({
9300
+ ...this.defaults,
9301
+ ...Object.fromEntries(
9302
+ Object.entries(this.options.params || {}).filter(
9303
+ ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
9304
+ )
9305
+ ),
9306
+ ...!isEmpty2(this.options.model) ? {
9307
+ model: this.options.model
9308
+ } : {}
9309
+ }).filter(([key, value]) => key !== "response_format" || value !== null)
9310
+ );
9188
9311
  if (!("model" in params) || isEmpty2(params.model)) {
9189
9312
  throw new Error(
9190
9313
  "No model specified. Either specify it in the prompt or as a default"
@@ -9284,7 +9407,7 @@ var Prompt2 = class _Prompt {
9284
9407
  templateFormat
9285
9408
  });
9286
9409
  const baseMessages = (prompt.messages || []).map(
9287
- (m) => renderMessage(render, m)
9410
+ (m) => renderMessageImpl(render, m, variables)
9288
9411
  );
9289
9412
  const hasSystemPrompt = baseMessages.some((m) => m.role === "system");
9290
9413
  const messages = [
@@ -10003,7 +10126,11 @@ function startSpanForEvent(config, event, channelName) {
10003
10126
  });
10004
10127
  const startTime = getCurrentUnixTimestamp();
10005
10128
  try {
10006
- const { input, metadata } = config.extractInput(event.arguments);
10129
+ const { input, metadata } = config.extractInput(
10130
+ event.arguments,
10131
+ event,
10132
+ span
10133
+ );
10007
10134
  span.log({
10008
10135
  input,
10009
10136
  metadata: mergeInputMetadata(metadata, spanInfoMetadata)
@@ -10167,6 +10294,16 @@ function traceStreamingChannel(channel2, config) {
10167
10294
  });
10168
10295
  return;
10169
10296
  }
10297
+ if (config.patchResult?.({
10298
+ channelName,
10299
+ endEvent: asyncEndEvent,
10300
+ result: asyncEndEvent.result,
10301
+ span,
10302
+ startTime
10303
+ })) {
10304
+ states.delete(event);
10305
+ return;
10306
+ }
10170
10307
  try {
10171
10308
  const output = config.extractOutput(
10172
10309
  asyncEndEvent.result,
@@ -10223,8 +10360,17 @@ function traceSyncStreamChannel(channel2, config) {
10223
10360
  return;
10224
10361
  }
10225
10362
  const { span, startTime } = spanData;
10226
- const resultEvent = event;
10227
- const stream = resultEvent.result;
10363
+ const endEvent = event;
10364
+ if (config.patchResult?.({
10365
+ channelName,
10366
+ endEvent,
10367
+ result: endEvent.result,
10368
+ span,
10369
+ startTime
10370
+ })) {
10371
+ return;
10372
+ }
10373
+ const stream = endEvent.result;
10228
10374
  if (!isSyncStreamLike(stream)) {
10229
10375
  span.end();
10230
10376
  states.delete(event);
@@ -11195,6 +11341,108 @@ function filterFrom2(obj, fieldsToRemove) {
11195
11341
  return result;
11196
11342
  }
11197
11343
 
11344
+ // src/wrappers/ai-sdk/normalize-logged-output.ts
11345
+ var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
11346
+ function normalizeAISDKLoggedOutput(value) {
11347
+ const normalized = normalizeAISDKLoggedValue(value);
11348
+ return normalized === REMOVE_NORMALIZED_VALUE ? {} : normalized;
11349
+ }
11350
+ function normalizeAISDKLoggedValue(value, context = {}) {
11351
+ if (Array.isArray(value)) {
11352
+ return value.map((entry) => normalizeAISDKLoggedValue(entry, context)).filter((entry) => entry !== REMOVE_NORMALIZED_VALUE);
11353
+ }
11354
+ if (!value || typeof value !== "object") {
11355
+ return value;
11356
+ }
11357
+ const nextInProviderMetadata = context.inProviderMetadata || context.parentKey === "providerMetadata" || context.parentKey === "experimental_providerMetadata";
11358
+ const normalizedEntries = [];
11359
+ for (const [key, entry] of Object.entries(value)) {
11360
+ if (key === "cachedPromptTokens" && entry === 0) {
11361
+ continue;
11362
+ }
11363
+ if (context.parentKey === "request" && key === "body" && entry === "<omitted>") {
11364
+ continue;
11365
+ }
11366
+ const normalizedEntry = normalizeAISDKLoggedValue(entry, {
11367
+ inProviderMetadata: nextInProviderMetadata,
11368
+ parentKey: key
11369
+ });
11370
+ if (normalizedEntry === REMOVE_NORMALIZED_VALUE) {
11371
+ continue;
11372
+ }
11373
+ normalizedEntries.push([key, normalizedEntry]);
11374
+ }
11375
+ if (normalizedEntries.length === 0) {
11376
+ if (context.parentKey === "request" || nextInProviderMetadata) {
11377
+ return REMOVE_NORMALIZED_VALUE;
11378
+ }
11379
+ return {};
11380
+ }
11381
+ return Object.fromEntries(normalizedEntries);
11382
+ }
11383
+
11384
+ // src/zod/utils.ts
11385
+ import { zodToJsonSchema as zodToJsonSchemaV3 } from "zod-to-json-schema";
11386
+ import * as z42 from "zod/v4";
11387
+ function isZodV4(zodObject) {
11388
+ return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
11389
+ }
11390
+ function zodToJsonSchema(schema) {
11391
+ if (isZodV4(schema)) {
11392
+ return z42.toJSONSchema(schema, {
11393
+ target: "draft-7"
11394
+ });
11395
+ }
11396
+ return zodToJsonSchemaV3(schema);
11397
+ }
11398
+
11399
+ // src/wrappers/ai-sdk/tool-serialization.ts
11400
+ function isZodSchema(value) {
11401
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
11402
+ }
11403
+ function serializeZodSchema(schema) {
11404
+ try {
11405
+ return zodToJsonSchema(schema);
11406
+ } catch {
11407
+ return {
11408
+ type: "object",
11409
+ description: "Zod schema (conversion failed)"
11410
+ };
11411
+ }
11412
+ }
11413
+ function serializeTool(tool) {
11414
+ if (!tool || typeof tool !== "object") {
11415
+ return tool;
11416
+ }
11417
+ const serialized = { ...tool };
11418
+ if (isZodSchema(serialized.inputSchema)) {
11419
+ serialized.inputSchema = serializeZodSchema(serialized.inputSchema);
11420
+ }
11421
+ if (isZodSchema(serialized.parameters)) {
11422
+ serialized.parameters = serializeZodSchema(serialized.parameters);
11423
+ }
11424
+ if ("execute" in serialized) {
11425
+ delete serialized.execute;
11426
+ }
11427
+ if ("render" in serialized) {
11428
+ delete serialized.render;
11429
+ }
11430
+ return serialized;
11431
+ }
11432
+ function serializeAISDKToolsForLogging(tools) {
11433
+ if (!tools || typeof tools !== "object") {
11434
+ return tools;
11435
+ }
11436
+ if (Array.isArray(tools)) {
11437
+ return tools.map(serializeTool);
11438
+ }
11439
+ const serialized = {};
11440
+ for (const [key, tool] of Object.entries(tools)) {
11441
+ serialized[key] = serializeTool(tool);
11442
+ }
11443
+ return serialized;
11444
+ }
11445
+
11198
11446
  // src/instrumentation/plugins/ai-sdk-channels.ts
11199
11447
  var aiSDKChannels = defineChannels("ai", {
11200
11448
  generateText: channel({
@@ -11205,6 +11453,10 @@ var aiSDKChannels = defineChannels("ai", {
11205
11453
  channelName: "streamText",
11206
11454
  kind: "async"
11207
11455
  }),
11456
+ streamTextSync: channel({
11457
+ channelName: "streamText.sync",
11458
+ kind: "sync-stream"
11459
+ }),
11208
11460
  generateObject: channel({
11209
11461
  channelName: "generateObject",
11210
11462
  kind: "async"
@@ -11213,6 +11465,10 @@ var aiSDKChannels = defineChannels("ai", {
11213
11465
  channelName: "streamObject",
11214
11466
  kind: "async"
11215
11467
  }),
11468
+ streamObjectSync: channel({
11469
+ channelName: "streamObject.sync",
11470
+ kind: "sync-stream"
11471
+ }),
11216
11472
  agentGenerate: channel({
11217
11473
  channelName: "Agent.generate",
11218
11474
  kind: "async"
@@ -11220,6 +11476,14 @@ var aiSDKChannels = defineChannels("ai", {
11220
11476
  agentStream: channel({
11221
11477
  channelName: "Agent.stream",
11222
11478
  kind: "async"
11479
+ }),
11480
+ toolLoopAgentGenerate: channel({
11481
+ channelName: "ToolLoopAgent.generate",
11482
+ kind: "async"
11483
+ }),
11484
+ toolLoopAgentStream: channel({
11485
+ channelName: "ToolLoopAgent.stream",
11486
+ kind: "async"
11223
11487
  })
11224
11488
  });
11225
11489
 
@@ -11238,6 +11502,8 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
11238
11502
  "steps[].response.body",
11239
11503
  "steps[].response.headers"
11240
11504
  ];
11505
+ var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
11506
+ var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
11241
11507
  var AISDKPlugin = class extends BasePlugin {
11242
11508
  config;
11243
11509
  constructor(config = {}) {
@@ -11256,22 +11522,12 @@ var AISDKPlugin = class extends BasePlugin {
11256
11522
  traceStreamingChannel(aiSDKChannels.generateText, {
11257
11523
  name: "generateText",
11258
11524
  type: "llm" /* LLM */,
11259
- extractInput: ([params]) => {
11260
- return {
11261
- input: processAISDKInput(params),
11262
- metadata: extractMetadataFromParams(params)
11263
- };
11264
- },
11265
- extractOutput: (result) => {
11525
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11526
+ extractOutput: (result, endEvent) => {
11527
+ finalizeAISDKChildTracing(endEvent);
11266
11528
  return processAISDKOutput(result, denyOutputPaths);
11267
11529
  },
11268
- extractMetrics: (result, startTime) => {
11269
- const metrics = extractTokenMetrics(result);
11270
- if (startTime) {
11271
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11272
- }
11273
- return metrics;
11274
- },
11530
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
11275
11531
  aggregateChunks: aggregateAISDKChunks
11276
11532
  })
11277
11533
  );
@@ -11279,45 +11535,43 @@ var AISDKPlugin = class extends BasePlugin {
11279
11535
  traceStreamingChannel(aiSDKChannels.streamText, {
11280
11536
  name: "streamText",
11281
11537
  type: "llm" /* LLM */,
11282
- extractInput: ([params]) => {
11283
- return {
11284
- input: processAISDKInput(params),
11285
- metadata: extractMetadataFromParams(params)
11286
- };
11287
- },
11288
- extractOutput: (result) => {
11289
- return processAISDKOutput(result, denyOutputPaths);
11290
- },
11291
- extractMetrics: (result, startTime) => {
11292
- const metrics = extractTokenMetrics(result);
11293
- if (startTime) {
11294
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11295
- }
11296
- return metrics;
11297
- },
11298
- aggregateChunks: aggregateAISDKChunks
11538
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11539
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
11540
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
11541
+ aggregateChunks: aggregateAISDKChunks,
11542
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
11543
+ denyOutputPaths,
11544
+ endEvent,
11545
+ result,
11546
+ span,
11547
+ startTime
11548
+ })
11549
+ })
11550
+ );
11551
+ this.unsubscribers.push(
11552
+ traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
11553
+ name: "streamText",
11554
+ type: "llm" /* LLM */,
11555
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11556
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
11557
+ denyOutputPaths,
11558
+ endEvent,
11559
+ result,
11560
+ span,
11561
+ startTime
11562
+ })
11299
11563
  })
11300
11564
  );
11301
11565
  this.unsubscribers.push(
11302
11566
  traceStreamingChannel(aiSDKChannels.generateObject, {
11303
11567
  name: "generateObject",
11304
11568
  type: "llm" /* LLM */,
11305
- extractInput: ([params]) => {
11306
- return {
11307
- input: processAISDKInput(params),
11308
- metadata: extractMetadataFromParams(params)
11309
- };
11310
- },
11311
- extractOutput: (result) => {
11569
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11570
+ extractOutput: (result, endEvent) => {
11571
+ finalizeAISDKChildTracing(endEvent);
11312
11572
  return processAISDKOutput(result, denyOutputPaths);
11313
11573
  },
11314
- extractMetrics: (result, startTime) => {
11315
- const metrics = extractTokenMetrics(result);
11316
- if (startTime) {
11317
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11318
- }
11319
- return metrics;
11320
- },
11574
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
11321
11575
  aggregateChunks: aggregateAISDKChunks
11322
11576
  })
11323
11577
  );
@@ -11325,45 +11579,43 @@ var AISDKPlugin = class extends BasePlugin {
11325
11579
  traceStreamingChannel(aiSDKChannels.streamObject, {
11326
11580
  name: "streamObject",
11327
11581
  type: "llm" /* LLM */,
11328
- extractInput: ([params]) => {
11329
- return {
11330
- input: processAISDKInput(params),
11331
- metadata: extractMetadataFromParams(params)
11332
- };
11333
- },
11334
- extractOutput: (result) => {
11335
- return processAISDKOutput(result, denyOutputPaths);
11336
- },
11337
- extractMetrics: (result, startTime) => {
11338
- const metrics = extractTokenMetrics(result);
11339
- if (startTime) {
11340
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11341
- }
11342
- return metrics;
11343
- },
11344
- aggregateChunks: aggregateAISDKChunks
11582
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11583
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
11584
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
11585
+ aggregateChunks: aggregateAISDKChunks,
11586
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
11587
+ denyOutputPaths,
11588
+ endEvent,
11589
+ result,
11590
+ span,
11591
+ startTime
11592
+ })
11593
+ })
11594
+ );
11595
+ this.unsubscribers.push(
11596
+ traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
11597
+ name: "streamObject",
11598
+ type: "llm" /* LLM */,
11599
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11600
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
11601
+ denyOutputPaths,
11602
+ endEvent,
11603
+ result,
11604
+ span,
11605
+ startTime
11606
+ })
11345
11607
  })
11346
11608
  );
11347
11609
  this.unsubscribers.push(
11348
11610
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
11349
11611
  name: "Agent.generate",
11350
11612
  type: "llm" /* LLM */,
11351
- extractInput: ([params]) => {
11352
- return {
11353
- input: processAISDKInput(params),
11354
- metadata: extractMetadataFromParams(params)
11355
- };
11356
- },
11357
- extractOutput: (result) => {
11613
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11614
+ extractOutput: (result, endEvent) => {
11615
+ finalizeAISDKChildTracing(endEvent);
11358
11616
  return processAISDKOutput(result, denyOutputPaths);
11359
11617
  },
11360
- extractMetrics: (result, startTime) => {
11361
- const metrics = extractTokenMetrics(result);
11362
- if (startTime) {
11363
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11364
- }
11365
- return metrics;
11366
- },
11618
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
11367
11619
  aggregateChunks: aggregateAISDKChunks
11368
11620
  })
11369
11621
  );
@@ -11371,52 +11623,470 @@ var AISDKPlugin = class extends BasePlugin {
11371
11623
  traceStreamingChannel(aiSDKChannels.agentStream, {
11372
11624
  name: "Agent.stream",
11373
11625
  type: "llm" /* LLM */,
11374
- extractInput: ([params]) => {
11375
- return {
11376
- input: processAISDKInput(params),
11377
- metadata: extractMetadataFromParams(params)
11378
- };
11379
- },
11380
- extractOutput: (result) => {
11626
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11627
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
11628
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
11629
+ aggregateChunks: aggregateAISDKChunks,
11630
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
11631
+ denyOutputPaths,
11632
+ endEvent,
11633
+ result,
11634
+ span,
11635
+ startTime
11636
+ })
11637
+ })
11638
+ );
11639
+ this.unsubscribers.push(
11640
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
11641
+ name: "ToolLoopAgent.generate",
11642
+ type: "llm" /* LLM */,
11643
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11644
+ extractOutput: (result, endEvent) => {
11645
+ finalizeAISDKChildTracing(endEvent);
11381
11646
  return processAISDKOutput(result, denyOutputPaths);
11382
11647
  },
11383
- extractMetrics: (result, startTime) => {
11384
- const metrics = extractTokenMetrics(result);
11385
- if (startTime) {
11386
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11387
- }
11388
- return metrics;
11389
- },
11648
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
11390
11649
  aggregateChunks: aggregateAISDKChunks
11391
11650
  })
11392
11651
  );
11652
+ this.unsubscribers.push(
11653
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
11654
+ name: "ToolLoopAgent.stream",
11655
+ type: "llm" /* LLM */,
11656
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
11657
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
11658
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
11659
+ aggregateChunks: aggregateAISDKChunks,
11660
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
11661
+ denyOutputPaths,
11662
+ endEvent,
11663
+ result,
11664
+ span,
11665
+ startTime
11666
+ })
11667
+ })
11668
+ );
11393
11669
  }
11394
11670
  };
11395
11671
  function processAISDKInput(params) {
11396
11672
  if (!params) return params;
11397
- return processInputAttachments(params);
11673
+ const input = processInputAttachments(params);
11674
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
11675
+ return input;
11676
+ }
11677
+ const { tools: _tools, ...rest } = input;
11678
+ return rest;
11398
11679
  }
11399
- function extractMetadataFromParams(params) {
11680
+ function prepareAISDKInput(params, event, span, denyOutputPaths) {
11681
+ const input = processAISDKInput(params);
11682
+ const metadata = extractMetadataFromParams(params, event.self);
11683
+ const childTracing = prepareAISDKChildTracing(
11684
+ params,
11685
+ event.self,
11686
+ span,
11687
+ denyOutputPaths
11688
+ );
11689
+ event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
11690
+ if (childTracing.cleanup) {
11691
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
11692
+ }
11693
+ return {
11694
+ input,
11695
+ metadata
11696
+ };
11697
+ }
11698
+ function extractTopLevelAISDKMetrics(result, event, startTime) {
11699
+ const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
11700
+ if (startTime) {
11701
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11702
+ }
11703
+ return metrics;
11704
+ }
11705
+ function hasModelChildTracing(event) {
11706
+ return event?.__braintrust_ai_sdk_model_wrapped === true;
11707
+ }
11708
+ function extractMetadataFromParams(params, self) {
11400
11709
  const metadata = {
11401
11710
  braintrust: {
11402
11711
  integration_name: "ai-sdk",
11403
11712
  sdk_language: "typescript"
11404
11713
  }
11405
11714
  };
11406
- const { model, provider } = serializeModelWithProvider(params.model);
11715
+ const agentModel = self && typeof self === "object" && "model" in self && self.model ? self.model : self && typeof self === "object" && "settings" in self && self.settings?.model ? self.settings?.model : void 0;
11716
+ const { model, provider } = serializeModelWithProvider(
11717
+ params.model ?? agentModel
11718
+ );
11407
11719
  if (model) {
11408
11720
  metadata.model = model;
11409
11721
  }
11410
11722
  if (provider) {
11411
11723
  metadata.provider = provider;
11412
11724
  }
11725
+ const tools = serializeAISDKToolsForLogging(params.tools);
11726
+ if (tools) {
11727
+ metadata.tools = tools;
11728
+ }
11413
11729
  return metadata;
11414
11730
  }
11731
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
11732
+ const cleanup = [];
11733
+ const patchedModels = /* @__PURE__ */ new WeakSet();
11734
+ const patchedTools = /* @__PURE__ */ new WeakSet();
11735
+ let modelWrapped = false;
11736
+ const patchModel = (model) => {
11737
+ const resolvedModel = resolveAISDKModel(model);
11738
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
11739
+ return;
11740
+ }
11741
+ patchedModels.add(resolvedModel);
11742
+ resolvedModel[AUTO_PATCHED_MODEL] = true;
11743
+ modelWrapped = true;
11744
+ const originalDoGenerate = resolvedModel.doGenerate;
11745
+ const originalDoStream = resolvedModel.doStream;
11746
+ const baseMetadata = buildAISDKChildMetadata(resolvedModel);
11747
+ resolvedModel.doGenerate = async function doGeneratePatched(options) {
11748
+ return parentSpan.traced(
11749
+ async (span) => {
11750
+ const result = await Reflect.apply(
11751
+ originalDoGenerate,
11752
+ resolvedModel,
11753
+ [options]
11754
+ );
11755
+ span.log({
11756
+ output: processAISDKOutput(result, denyOutputPaths),
11757
+ metrics: extractTokenMetrics(result),
11758
+ ...buildResolvedMetadataPayload(result)
11759
+ });
11760
+ return result;
11761
+ },
11762
+ {
11763
+ name: "doGenerate",
11764
+ spanAttributes: {
11765
+ type: "llm" /* LLM */
11766
+ },
11767
+ event: {
11768
+ input: processAISDKInput(options),
11769
+ metadata: baseMetadata
11770
+ }
11771
+ }
11772
+ );
11773
+ };
11774
+ if (originalDoStream) {
11775
+ resolvedModel.doStream = async function doStreamPatched(options) {
11776
+ const span = parentSpan.startSpan({
11777
+ name: "doStream",
11778
+ spanAttributes: {
11779
+ type: "llm" /* LLM */
11780
+ },
11781
+ event: {
11782
+ input: processAISDKInput(options),
11783
+ metadata: baseMetadata
11784
+ }
11785
+ });
11786
+ const result = await withCurrent(
11787
+ span,
11788
+ () => Reflect.apply(originalDoStream, resolvedModel, [options])
11789
+ );
11790
+ const output = {};
11791
+ let text = "";
11792
+ let reasoning = "";
11793
+ const toolCalls = [];
11794
+ let object = void 0;
11795
+ const transformStream = new TransformStream({
11796
+ transform(chunk, controller) {
11797
+ switch (chunk.type) {
11798
+ case "text-delta":
11799
+ text += extractTextDelta(chunk);
11800
+ break;
11801
+ case "reasoning-delta":
11802
+ if (chunk.delta) {
11803
+ reasoning += chunk.delta;
11804
+ } else if (chunk.text) {
11805
+ reasoning += chunk.text;
11806
+ }
11807
+ break;
11808
+ case "tool-call":
11809
+ toolCalls.push(chunk);
11810
+ break;
11811
+ case "object":
11812
+ object = chunk.object;
11813
+ break;
11814
+ case "raw":
11815
+ if (chunk.rawValue) {
11816
+ const rawVal = chunk.rawValue;
11817
+ if (rawVal.delta?.content) {
11818
+ text += rawVal.delta.content;
11819
+ } else if (rawVal.choices?.[0]?.delta?.content) {
11820
+ text += rawVal.choices[0].delta.content;
11821
+ } else if (typeof rawVal.text === "string") {
11822
+ text += rawVal.text;
11823
+ } else if (typeof rawVal.content === "string") {
11824
+ text += rawVal.content;
11825
+ }
11826
+ }
11827
+ break;
11828
+ case "finish":
11829
+ output.text = text;
11830
+ output.reasoning = reasoning;
11831
+ output.toolCalls = toolCalls;
11832
+ output.finishReason = chunk.finishReason;
11833
+ output.usage = chunk.usage;
11834
+ if (object !== void 0) {
11835
+ output.object = object;
11836
+ }
11837
+ span.log({
11838
+ output: processAISDKOutput(
11839
+ output,
11840
+ denyOutputPaths
11841
+ ),
11842
+ metrics: extractTokenMetrics(output),
11843
+ ...buildResolvedMetadataPayload(output)
11844
+ });
11845
+ span.end();
11846
+ break;
11847
+ }
11848
+ controller.enqueue(chunk);
11849
+ }
11850
+ });
11851
+ return {
11852
+ ...result,
11853
+ stream: result.stream.pipeThrough(transformStream)
11854
+ };
11855
+ };
11856
+ }
11857
+ cleanup.push(() => {
11858
+ resolvedModel.doGenerate = originalDoGenerate;
11859
+ if (originalDoStream) {
11860
+ resolvedModel.doStream = originalDoStream;
11861
+ }
11862
+ delete resolvedModel[AUTO_PATCHED_MODEL];
11863
+ });
11864
+ };
11865
+ const patchTool = (tool, name) => {
11866
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
11867
+ return;
11868
+ }
11869
+ patchedTools.add(tool);
11870
+ tool[AUTO_PATCHED_TOOL] = true;
11871
+ const originalExecute = tool.execute;
11872
+ tool.execute = function executePatched(...args) {
11873
+ const result = Reflect.apply(originalExecute, this, args);
11874
+ if (isAsyncGenerator(result)) {
11875
+ return (async function* () {
11876
+ const span = parentSpan.startSpan({
11877
+ name,
11878
+ spanAttributes: {
11879
+ type: "tool" /* TOOL */
11880
+ }
11881
+ });
11882
+ span.log({ input: args.length === 1 ? args[0] : args });
11883
+ try {
11884
+ let lastValue;
11885
+ for await (const value of result) {
11886
+ lastValue = value;
11887
+ yield value;
11888
+ }
11889
+ span.log({ output: lastValue });
11890
+ } catch (error) {
11891
+ span.log({
11892
+ error: error instanceof Error ? error.message : String(error)
11893
+ });
11894
+ throw error;
11895
+ } finally {
11896
+ span.end();
11897
+ }
11898
+ })();
11899
+ }
11900
+ return parentSpan.traced(
11901
+ async (span) => {
11902
+ span.log({ input: args.length === 1 ? args[0] : args });
11903
+ const awaitedResult = await result;
11904
+ span.log({ output: awaitedResult });
11905
+ return awaitedResult;
11906
+ },
11907
+ {
11908
+ name,
11909
+ spanAttributes: {
11910
+ type: "tool" /* TOOL */
11911
+ }
11912
+ }
11913
+ );
11914
+ };
11915
+ cleanup.push(() => {
11916
+ tool.execute = originalExecute;
11917
+ delete tool[AUTO_PATCHED_TOOL];
11918
+ });
11919
+ };
11920
+ const patchTools = (tools) => {
11921
+ if (!tools) {
11922
+ return;
11923
+ }
11924
+ const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
11925
+ if (Array.isArray(tools)) {
11926
+ tools.forEach(
11927
+ (tool, index) => patchTool(tool, inferName(tool, `tool[${index}]`))
11928
+ );
11929
+ return;
11930
+ }
11931
+ for (const [key, tool] of Object.entries(tools)) {
11932
+ patchTool(tool, key);
11933
+ }
11934
+ };
11935
+ if (params && typeof params === "object") {
11936
+ patchModel(params.model);
11937
+ patchTools(params.tools);
11938
+ }
11939
+ if (self && typeof self === "object") {
11940
+ const selfRecord = self;
11941
+ if (selfRecord.model !== void 0) {
11942
+ patchModel(selfRecord.model);
11943
+ }
11944
+ if (selfRecord.settings && typeof selfRecord.settings === "object") {
11945
+ if (selfRecord.settings.model !== void 0) {
11946
+ patchModel(selfRecord.settings.model);
11947
+ }
11948
+ if (selfRecord.settings.tools !== void 0) {
11949
+ patchTools(selfRecord.settings.tools);
11950
+ }
11951
+ }
11952
+ }
11953
+ return {
11954
+ cleanup: cleanup.length > 0 ? () => {
11955
+ while (cleanup.length > 0) {
11956
+ cleanup.pop()?.();
11957
+ }
11958
+ } : void 0,
11959
+ modelWrapped
11960
+ };
11961
+ }
11962
+ function finalizeAISDKChildTracing(event) {
11963
+ const cleanup = event?.__braintrust_ai_sdk_cleanup;
11964
+ if (event && typeof cleanup === "function") {
11965
+ cleanup();
11966
+ delete event.__braintrust_ai_sdk_cleanup;
11967
+ }
11968
+ }
11969
+ function patchAISDKStreamingResult(args) {
11970
+ const { denyOutputPaths, endEvent, result, span, startTime } = args;
11971
+ if (!result || typeof result !== "object") {
11972
+ return false;
11973
+ }
11974
+ const resultRecord = result;
11975
+ if (!isReadableStreamLike(resultRecord.baseStream)) {
11976
+ return false;
11977
+ }
11978
+ let firstChunkTime;
11979
+ const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
11980
+ new TransformStream({
11981
+ transform(chunk, controller) {
11982
+ if (firstChunkTime === void 0) {
11983
+ firstChunkTime = getCurrentUnixTimestamp();
11984
+ }
11985
+ controller.enqueue(chunk);
11986
+ },
11987
+ async flush() {
11988
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
11989
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
11990
+ metrics.time_to_first_token = firstChunkTime - startTime;
11991
+ }
11992
+ const output = await processAISDKStreamingOutput(
11993
+ result,
11994
+ denyOutputPaths
11995
+ );
11996
+ const metadata = buildResolvedMetadataPayload(result).metadata;
11997
+ span.log({
11998
+ output,
11999
+ ...metadata ? { metadata } : {},
12000
+ metrics
12001
+ });
12002
+ finalizeAISDKChildTracing(endEvent);
12003
+ span.end();
12004
+ }
12005
+ })
12006
+ );
12007
+ Object.defineProperty(resultRecord, "baseStream", {
12008
+ configurable: true,
12009
+ enumerable: true,
12010
+ value: wrappedBaseStream,
12011
+ writable: true
12012
+ });
12013
+ return true;
12014
+ }
12015
+ function isReadableStreamLike(value) {
12016
+ return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
12017
+ }
12018
+ async function processAISDKStreamingOutput(result, denyOutputPaths) {
12019
+ const output = processAISDKOutput(result, denyOutputPaths);
12020
+ if (!output || typeof output !== "object") {
12021
+ return output;
12022
+ }
12023
+ const outputRecord = output;
12024
+ try {
12025
+ if ("text" in result && typeof result.text === "string") {
12026
+ outputRecord.text = result.text;
12027
+ }
12028
+ } catch {
12029
+ }
12030
+ try {
12031
+ if ("object" in result) {
12032
+ const resolvedObject = await Promise.resolve(result.object);
12033
+ if (resolvedObject !== void 0) {
12034
+ outputRecord.object = resolvedObject;
12035
+ }
12036
+ }
12037
+ } catch {
12038
+ }
12039
+ return outputRecord;
12040
+ }
12041
+ function buildAISDKChildMetadata(model) {
12042
+ const { model: modelId, provider } = serializeModelWithProvider(model);
12043
+ return {
12044
+ ...modelId ? { model: modelId } : {},
12045
+ ...provider ? { provider } : {},
12046
+ braintrust: {
12047
+ integration_name: "ai-sdk",
12048
+ sdk_language: "typescript"
12049
+ }
12050
+ };
12051
+ }
12052
+ function buildResolvedMetadataPayload(result) {
12053
+ const gatewayInfo = extractGatewayRoutingInfo(result);
12054
+ const metadata = {};
12055
+ if (gatewayInfo?.provider) {
12056
+ metadata.provider = gatewayInfo.provider;
12057
+ }
12058
+ if (gatewayInfo?.model) {
12059
+ metadata.model = gatewayInfo.model;
12060
+ }
12061
+ if (result.finishReason !== void 0) {
12062
+ metadata.finish_reason = result.finishReason;
12063
+ }
12064
+ return Object.keys(metadata).length > 0 ? { metadata } : {};
12065
+ }
12066
+ function resolveAISDKModel(model) {
12067
+ if (typeof model !== "string") {
12068
+ return model;
12069
+ }
12070
+ const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? null;
12071
+ if (provider && typeof provider.languageModel === "function") {
12072
+ return provider.languageModel(model);
12073
+ }
12074
+ return model;
12075
+ }
12076
+ function extractTextDelta(chunk) {
12077
+ if (typeof chunk.textDelta === "string") return chunk.textDelta;
12078
+ if (typeof chunk.delta === "string") return chunk.delta;
12079
+ if (typeof chunk.text === "string") return chunk.text;
12080
+ if (typeof chunk.content === "string") return chunk.content;
12081
+ return "";
12082
+ }
12083
+ function isAsyncGenerator(value) {
12084
+ return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
12085
+ }
11415
12086
  function processAISDKOutput(output, denyOutputPaths) {
11416
12087
  if (!output) return output;
11417
- const getterValues = extractGetterValues(output);
11418
- const merged = { ...output, ...getterValues };
11419
- return omit(merged, denyOutputPaths);
12088
+ const merged = extractSerializableOutputFields(output);
12089
+ return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
11420
12090
  }
11421
12091
  function extractTokenMetrics(result) {
11422
12092
  const metrics = {};
@@ -11466,12 +12136,14 @@ function extractTokenMetrics(result) {
11466
12136
  }
11467
12137
  return metrics;
11468
12138
  }
11469
- function aggregateAISDKChunks(chunks) {
12139
+ function aggregateAISDKChunks(chunks, _result, endEvent) {
11470
12140
  const lastChunk = chunks[chunks.length - 1];
11471
12141
  const output = {};
11472
12142
  let metrics = {};
12143
+ let metadata;
11473
12144
  if (lastChunk) {
11474
- metrics = extractTokenMetrics(lastChunk);
12145
+ metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics(lastChunk);
12146
+ metadata = buildResolvedMetadataPayload(lastChunk).metadata;
11475
12147
  if (lastChunk.text !== void 0) {
11476
12148
  output.text = lastChunk.text;
11477
12149
  }
@@ -11485,7 +12157,8 @@ function aggregateAISDKChunks(chunks) {
11485
12157
  output.toolCalls = lastChunk.toolCalls;
11486
12158
  }
11487
12159
  }
11488
- return { output, metrics };
12160
+ finalizeAISDKChildTracing(endEvent);
12161
+ return { output, metrics, metadata };
11489
12162
  }
11490
12163
  function extractGetterValues(obj) {
11491
12164
  const getterValues = {};
@@ -11505,7 +12178,7 @@ function extractGetterValues(obj) {
11505
12178
  ];
11506
12179
  for (const name of getterNames) {
11507
12180
  try {
11508
- if (obj && name in obj && typeof obj[name] !== "function") {
12181
+ if (obj && name in obj && isSerializableOutputValue(obj[name])) {
11509
12182
  getterValues[name] = obj[name];
11510
12183
  }
11511
12184
  } catch {
@@ -11513,6 +12186,47 @@ function extractGetterValues(obj) {
11513
12186
  }
11514
12187
  return getterValues;
11515
12188
  }
12189
+ function extractSerializableOutputFields(output) {
12190
+ const serialized = {};
12191
+ const directFieldNames = [
12192
+ "steps",
12193
+ "request",
12194
+ "responseMessages",
12195
+ "warnings",
12196
+ "rawResponse",
12197
+ "response",
12198
+ "providerMetadata",
12199
+ "experimental_providerMetadata"
12200
+ ];
12201
+ for (const name of directFieldNames) {
12202
+ try {
12203
+ const value = output?.[name];
12204
+ if (isSerializableOutputValue(value)) {
12205
+ serialized[name] = value;
12206
+ }
12207
+ } catch {
12208
+ }
12209
+ }
12210
+ return {
12211
+ ...serialized,
12212
+ ...extractGetterValues(output)
12213
+ };
12214
+ }
12215
+ function isSerializableOutputValue(value) {
12216
+ if (typeof value === "function") {
12217
+ return false;
12218
+ }
12219
+ if (value && typeof value === "object" && typeof value.then === "function") {
12220
+ return false;
12221
+ }
12222
+ if (value && typeof value === "object" && typeof value.getReader === "function") {
12223
+ return false;
12224
+ }
12225
+ if (value && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function") {
12226
+ return false;
12227
+ }
12228
+ return true;
12229
+ }
11516
12230
  function serializeModelWithProvider(model) {
11517
12231
  const modelId = typeof model === "string" ? model : model?.modelId;
11518
12232
  const explicitProvider = typeof model === "object" ? model?.provider : void 0;
@@ -11538,6 +12252,25 @@ function parseGatewayModelString(modelString) {
11538
12252
  }
11539
12253
  return { model: modelString };
11540
12254
  }
12255
+ function extractGatewayRoutingInfo(result) {
12256
+ if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
12257
+ const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
12258
+ if (routing2) {
12259
+ return {
12260
+ provider: routing2.resolvedProvider || routing2.finalProvider,
12261
+ model: routing2.resolvedProviderApiModelId
12262
+ };
12263
+ }
12264
+ }
12265
+ const routing = result?.providerMetadata?.gateway?.routing;
12266
+ if (routing) {
12267
+ return {
12268
+ provider: routing.resolvedProvider || routing.finalProvider,
12269
+ model: routing.resolvedProviderApiModelId
12270
+ };
12271
+ }
12272
+ return null;
12273
+ }
11541
12274
  function extractCostFromResult(result) {
11542
12275
  if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
11543
12276
  let totalCost = 0;
@@ -13059,35 +13792,28 @@ function createEndpointProxy(target, wrapperFn) {
13059
13792
  });
13060
13793
  }
13061
13794
  function wrapApiCreateWithChannel(create, channel2) {
13062
- return async (allParams, options) => {
13795
+ return (allParams, options) => {
13063
13796
  const { span_info, params } = splitSpanInfo(allParams);
13064
- const traceContext = createChannelContext(channel2, params, span_info);
13065
- const { data } = await tracePromiseWithResponse(
13066
- channel2,
13067
- traceContext,
13068
- create(params, options)
13069
- );
13070
- return data;
13797
+ let executionPromise = null;
13798
+ const ensureExecuted = () => {
13799
+ if (!executionPromise) {
13800
+ executionPromise = (async () => {
13801
+ const traceContext = createChannelContext(channel2, params, span_info);
13802
+ return tracePromiseWithResponse(
13803
+ channel2,
13804
+ traceContext,
13805
+ create(params, options)
13806
+ );
13807
+ })();
13808
+ }
13809
+ return executionPromise;
13810
+ };
13811
+ return createLazyAPIPromise(ensureExecuted);
13071
13812
  };
13072
13813
  }
13073
13814
  var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
13074
13815
  var wrapModerations = (create) => wrapApiCreateWithChannel(create, openAIChannels.moderationsCreate);
13075
13816
 
13076
- // src/zod/utils.ts
13077
- import { zodToJsonSchema as zodToJsonSchemaV3 } from "zod-to-json-schema";
13078
- import * as z42 from "zod/v4";
13079
- function isZodV4(zodObject) {
13080
- return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
13081
- }
13082
- function zodToJsonSchema(schema) {
13083
- if (isZodV4(schema)) {
13084
- return z42.toJSONSchema(schema, {
13085
- target: "draft-7"
13086
- });
13087
- }
13088
- return zodToJsonSchemaV3(schema);
13089
- }
13090
-
13091
13817
  // src/wrappers/ai-sdk/ai-sdk.ts
13092
13818
  var DENY_OUTPUT_PATHS = [
13093
13819
  // v3
@@ -13182,9 +13908,11 @@ var wrapAgentGenerate = (generate, instance, options = {}) => {
13182
13908
  return async (params) => makeGenerateTextWrapper(
13183
13909
  `${instance.constructor.name}.generate`,
13184
13910
  options,
13185
- generate.bind(instance)
13911
+ generate.bind(instance),
13186
13912
  // as of v5 this is just streamText under the hood
13187
13913
  // Follows what the AI SDK does under the hood when calling generateText
13914
+ void 0,
13915
+ "function" /* FUNCTION */
13188
13916
  )({ ...instance.settings, ...params });
13189
13917
  };
13190
13918
  var wrapAgentStream = (stream, instance, options = {}) => {
@@ -13193,11 +13921,12 @@ var wrapAgentStream = (stream, instance, options = {}) => {
13193
13921
  options,
13194
13922
  stream.bind(instance),
13195
13923
  // as of v5 this is just streamText under the hood
13196
- void 0
13924
+ void 0,
13197
13925
  // aiSDK not needed since model is already on instance
13926
+ "function" /* FUNCTION */
13198
13927
  )({ ...instance.settings, ...params });
13199
13928
  };
13200
- var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
13929
+ var makeGenerateTextWrapper = (name, options, generateText, aiSDK, spanType = "llm" /* LLM */) => {
13201
13930
  const wrapper = async function(allParams) {
13202
13931
  const { span_info, ...params } = allParams;
13203
13932
  const {
@@ -13206,6 +13935,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
13206
13935
  spanAttributes: spanInfoAttrs
13207
13936
  } = span_info ?? {};
13208
13937
  const { model, provider } = serializeModelWithProvider2(params.model);
13938
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
13209
13939
  const processedInput = await processInputAttachments2(params);
13210
13940
  return traced(
13211
13941
  async (span) => {
@@ -13218,7 +13948,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
13218
13948
  model: wrappedModel,
13219
13949
  tools: wrapTools(params.tools)
13220
13950
  });
13221
- const gatewayInfo = extractGatewayRoutingInfo(result);
13951
+ const gatewayInfo = extractGatewayRoutingInfo2(result);
13222
13952
  const resolvedMetadata = {};
13223
13953
  if (gatewayInfo?.provider) {
13224
13954
  resolvedMetadata.provider = gatewayInfo.provider;
@@ -13236,7 +13966,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
13236
13966
  {
13237
13967
  name: spanName || name,
13238
13968
  spanAttributes: {
13239
- type: "llm" /* LLM */,
13969
+ type: spanType,
13240
13970
  ...spanInfoAttrs
13241
13971
  },
13242
13972
  event: {
@@ -13245,6 +13975,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
13245
13975
  ...spanInfoMetadata,
13246
13976
  model,
13247
13977
  ...provider ? { provider } : {},
13978
+ ...serializedTools ? { tools: serializedTools } : {},
13248
13979
  braintrust: {
13249
13980
  integration_name: "ai-sdk",
13250
13981
  sdk_language: "typescript"
@@ -13279,11 +14010,12 @@ var wrapModel = (model, ai) => {
13279
14010
  const originalDoStream = resolvedModel.doStream?.bind(resolvedModel);
13280
14011
  const { model: modelId, provider } = serializeModelWithProvider2(resolvedModel);
13281
14012
  const wrappedDoGenerate = async (options) => {
14013
+ const serializedTools = serializeAISDKToolsForLogging(options.tools);
13282
14014
  const processedInput = await processInputAttachments2(options);
13283
14015
  return traced(
13284
14016
  async (span) => {
13285
14017
  const result = await originalDoGenerate(options);
13286
- const gatewayInfo = extractGatewayRoutingInfo(result);
14018
+ const gatewayInfo = extractGatewayRoutingInfo2(result);
13287
14019
  const resolvedMetadata = {};
13288
14020
  if (gatewayInfo?.provider) {
13289
14021
  resolvedMetadata.provider = gatewayInfo.provider;
@@ -13311,6 +14043,7 @@ var wrapModel = (model, ai) => {
13311
14043
  metadata: {
13312
14044
  model: modelId,
13313
14045
  ...provider ? { provider } : {},
14046
+ ...serializedTools ? { tools: serializedTools } : {},
13314
14047
  braintrust: {
13315
14048
  integration_name: "ai-sdk",
13316
14049
  sdk_language: "typescript"
@@ -13323,6 +14056,7 @@ var wrapModel = (model, ai) => {
13323
14056
  const wrappedDoStream = async (options) => {
13324
14057
  const startTime = Date.now();
13325
14058
  let receivedFirst = false;
14059
+ const serializedTools = serializeAISDKToolsForLogging(options.tools);
13326
14060
  const processedInput = await processInputAttachments2(options);
13327
14061
  const span = startSpan({
13328
14062
  name: "doStream",
@@ -13334,6 +14068,7 @@ var wrapModel = (model, ai) => {
13334
14068
  metadata: {
13335
14069
  model: modelId,
13336
14070
  ...provider ? { provider } : {},
14071
+ ...serializedTools ? { tools: serializedTools } : {},
13337
14072
  braintrust: {
13338
14073
  integration_name: "ai-sdk",
13339
14074
  sdk_language: "typescript"
@@ -13347,7 +14082,7 @@ var wrapModel = (model, ai) => {
13347
14082
  let reasoning = "";
13348
14083
  const toolCalls = [];
13349
14084
  let object = void 0;
13350
- const extractTextDelta = (chunk) => {
14085
+ const extractTextDelta2 = (chunk) => {
13351
14086
  if (typeof chunk.textDelta === "string") return chunk.textDelta;
13352
14087
  if (typeof chunk.delta === "string") return chunk.delta;
13353
14088
  if (typeof chunk.text === "string") return chunk.text;
@@ -13366,7 +14101,7 @@ var wrapModel = (model, ai) => {
13366
14101
  }
13367
14102
  switch (chunk.type) {
13368
14103
  case "text-delta":
13369
- text += extractTextDelta(chunk);
14104
+ text += extractTextDelta2(chunk);
13370
14105
  break;
13371
14106
  case "reasoning-delta":
13372
14107
  if (chunk.delta) {
@@ -13404,7 +14139,7 @@ var wrapModel = (model, ai) => {
13404
14139
  if (object !== void 0) {
13405
14140
  output.object = object;
13406
14141
  }
13407
- const gatewayInfo = extractGatewayRoutingInfo(output);
14142
+ const gatewayInfo = extractGatewayRoutingInfo2(output);
13408
14143
  const resolvedMetadata = {};
13409
14144
  if (gatewayInfo?.provider) {
13410
14145
  resolvedMetadata.provider = gatewayInfo.provider;
@@ -13466,6 +14201,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
13466
14201
  spanAttributes: spanInfoAttrs
13467
14202
  } = span_info ?? {};
13468
14203
  const { model, provider } = serializeModelWithProvider2(params.model);
14204
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
13469
14205
  const processedInput = await processInputAttachments2(params);
13470
14206
  return traced(
13471
14207
  async (span) => {
@@ -13479,7 +14215,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
13479
14215
  tools: wrapTools(params.tools)
13480
14216
  });
13481
14217
  const output = await processOutput(result, options.denyOutputPaths);
13482
- const gatewayInfo = extractGatewayRoutingInfo(result);
14218
+ const gatewayInfo = extractGatewayRoutingInfo2(result);
13483
14219
  const resolvedMetadata = {};
13484
14220
  if (gatewayInfo?.provider) {
13485
14221
  resolvedMetadata.provider = gatewayInfo.provider;
@@ -13506,6 +14242,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
13506
14242
  ...spanInfoMetadata,
13507
14243
  model,
13508
14244
  ...provider ? { provider } : {},
14245
+ ...serializedTools ? { tools: serializedTools } : {},
13509
14246
  braintrust: {
13510
14247
  integration_name: "ai-sdk",
13511
14248
  sdk_language: "typescript"
@@ -13516,7 +14253,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
13516
14253
  );
13517
14254
  };
13518
14255
  };
13519
- var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
14256
+ var makeStreamTextWrapper = (name, options, streamText, aiSDK, spanType = "llm" /* LLM */) => {
13520
14257
  const wrapper = function(allParams) {
13521
14258
  const { span_info, ...params } = allParams;
13522
14259
  const {
@@ -13525,11 +14262,12 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
13525
14262
  spanAttributes: spanInfoAttrs
13526
14263
  } = span_info ?? {};
13527
14264
  const { model, provider } = serializeModelWithProvider2(params.model);
14265
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
13528
14266
  const { input: processedInput, outputPromise } = processInputAttachmentsSync(params);
13529
14267
  const span = startSpan({
13530
14268
  name: spanName || name,
13531
14269
  spanAttributes: {
13532
- type: "llm" /* LLM */,
14270
+ type: spanType,
13533
14271
  ...spanInfoAttrs
13534
14272
  },
13535
14273
  event: {
@@ -13538,6 +14276,7 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
13538
14276
  ...spanInfoMetadata,
13539
14277
  model,
13540
14278
  ...provider ? { provider } : {},
14279
+ ...serializedTools ? { tools: serializedTools } : {},
13541
14280
  braintrust: {
13542
14281
  integration_name: "ai-sdk",
13543
14282
  sdk_language: "typescript"
@@ -13577,7 +14316,7 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
13577
14316
  },
13578
14317
  onFinish: async (event) => {
13579
14318
  params.onFinish?.(event);
13580
- const gatewayInfo = extractGatewayRoutingInfo(event);
14319
+ const gatewayInfo = extractGatewayRoutingInfo2(event);
13581
14320
  const resolvedMetadata = {};
13582
14321
  if (gatewayInfo?.provider) {
13583
14322
  resolvedMetadata.provider = gatewayInfo.provider;
@@ -13653,6 +14392,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
13653
14392
  spanAttributes: spanInfoAttrs
13654
14393
  } = span_info ?? {};
13655
14394
  const { model, provider } = serializeModelWithProvider2(params.model);
14395
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
13656
14396
  const { input: processedInput, outputPromise } = processInputAttachmentsSync(params);
13657
14397
  const span = startSpan({
13658
14398
  name: spanName || "streamObject",
@@ -13666,6 +14406,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
13666
14406
  ...spanInfoMetadata,
13667
14407
  model,
13668
14408
  ...provider ? { provider } : {},
14409
+ ...serializedTools ? { tools: serializedTools } : {},
13669
14410
  braintrust: {
13670
14411
  integration_name: "ai-sdk",
13671
14412
  sdk_language: "typescript"
@@ -13705,7 +14446,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
13705
14446
  },
13706
14447
  onFinish: async (event) => {
13707
14448
  params.onFinish?.(event);
13708
- const gatewayInfo = extractGatewayRoutingInfo(event);
14449
+ const gatewayInfo = extractGatewayRoutingInfo2(event);
13709
14450
  const resolvedMetadata = {};
13710
14451
  if (gatewayInfo?.provider) {
13711
14452
  resolvedMetadata.provider = gatewayInfo.provider;
@@ -13782,7 +14523,7 @@ var wrapTools = (tools) => {
13782
14523
  }
13783
14524
  return wrappedTools;
13784
14525
  };
13785
- var isAsyncGenerator = (value) => {
14526
+ var isAsyncGenerator2 = (value) => {
13786
14527
  return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
13787
14528
  };
13788
14529
  var wrapToolExecute = (tool, name) => {
@@ -13793,7 +14534,7 @@ var wrapToolExecute = (tool, name) => {
13793
14534
  if (prop === "execute") {
13794
14535
  const wrappedExecute = (...args) => {
13795
14536
  const result = originalExecute.apply(target, args);
13796
- if (isAsyncGenerator(result)) {
14537
+ if (isAsyncGenerator2(result)) {
13797
14538
  return (async function* () {
13798
14539
  const span = startSpan({
13799
14540
  name,
@@ -13913,7 +14654,7 @@ function serializeModelWithProvider2(model) {
13913
14654
  provider: explicitProvider || parsed.provider
13914
14655
  };
13915
14656
  }
13916
- function extractGatewayRoutingInfo(result) {
14657
+ function extractGatewayRoutingInfo2(result) {
13917
14658
  if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
13918
14659
  const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
13919
14660
  if (routing2) {
@@ -13932,10 +14673,10 @@ function extractGatewayRoutingInfo(result) {
13932
14673
  }
13933
14674
  return null;
13934
14675
  }
13935
- var isZodSchema = (value) => {
14676
+ var isZodSchema2 = (value) => {
13936
14677
  return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
13937
14678
  };
13938
- var serializeZodSchema = (schema) => {
14679
+ var serializeZodSchema2 = (schema) => {
13939
14680
  try {
13940
14681
  return zodToJsonSchema(schema);
13941
14682
  } catch {
@@ -13945,34 +14686,6 @@ var serializeZodSchema = (schema) => {
13945
14686
  };
13946
14687
  }
13947
14688
  };
13948
- var processTools = (tools) => {
13949
- if (!tools || typeof tools !== "object") return tools;
13950
- if (Array.isArray(tools)) {
13951
- return tools.map(processTool);
13952
- }
13953
- const processed = {};
13954
- for (const [key, tool] of Object.entries(tools)) {
13955
- processed[key] = processTool(tool);
13956
- }
13957
- return processed;
13958
- };
13959
- var processTool = (tool) => {
13960
- if (!tool || typeof tool !== "object") return tool;
13961
- const processed = { ...tool };
13962
- if (isZodSchema(processed.inputSchema)) {
13963
- processed.inputSchema = serializeZodSchema(processed.inputSchema);
13964
- }
13965
- if (isZodSchema(processed.parameters)) {
13966
- processed.parameters = serializeZodSchema(processed.parameters);
13967
- }
13968
- if ("execute" in processed) {
13969
- processed.execute = "[Function]";
13970
- }
13971
- if ("render" in processed) {
13972
- processed.render = "[Function]";
13973
- }
13974
- return processed;
13975
- };
13976
14689
  var isOutputObject = (value) => {
13977
14690
  if (value == null || typeof value !== "object") {
13978
14691
  return false;
@@ -14011,10 +14724,10 @@ var serializeOutputObject = (output, model) => {
14011
14724
  if (typeof responseFormat.then === "function") {
14012
14725
  result.response_format = Promise.resolve(responseFormat).then(
14013
14726
  (resolved) => {
14014
- if (resolved.schema && isZodSchema(resolved.schema)) {
14727
+ if (resolved.schema && isZodSchema2(resolved.schema)) {
14015
14728
  return {
14016
14729
  ...resolved,
14017
- schema: serializeZodSchema(resolved.schema)
14730
+ schema: serializeZodSchema2(resolved.schema)
14018
14731
  };
14019
14732
  }
14020
14733
  return resolved;
@@ -14022,10 +14735,10 @@ var serializeOutputObject = (output, model) => {
14022
14735
  );
14023
14736
  } else {
14024
14737
  const syncResponseFormat = responseFormat;
14025
- if (syncResponseFormat.schema && isZodSchema(syncResponseFormat.schema)) {
14738
+ if (syncResponseFormat.schema && isZodSchema2(syncResponseFormat.schema)) {
14026
14739
  responseFormat = {
14027
14740
  ...syncResponseFormat,
14028
- schema: serializeZodSchema(syncResponseFormat.schema)
14741
+ schema: serializeZodSchema2(syncResponseFormat.schema)
14029
14742
  };
14030
14743
  }
14031
14744
  result.response_format = responseFormat;
@@ -14051,14 +14764,14 @@ var processInputAttachmentsSync = (input) => {
14051
14764
  processed.prompt = processPromptContent(input.prompt);
14052
14765
  }
14053
14766
  }
14054
- if (input.tools) {
14055
- processed.tools = processTools(input.tools);
14767
+ if (input.schema && isZodSchema2(input.schema)) {
14768
+ processed.schema = serializeZodSchema2(input.schema);
14056
14769
  }
14057
- if (input.schema && isZodSchema(input.schema)) {
14058
- processed.schema = serializeZodSchema(input.schema);
14770
+ if (input.callOptionsSchema && isZodSchema2(input.callOptionsSchema)) {
14771
+ processed.callOptionsSchema = serializeZodSchema2(input.callOptionsSchema);
14059
14772
  }
14060
- if (input.callOptionsSchema && isZodSchema(input.callOptionsSchema)) {
14061
- processed.callOptionsSchema = serializeZodSchema(input.callOptionsSchema);
14773
+ if (input.tools) {
14774
+ processed.tools = serializeAISDKToolsForLogging(input.tools);
14062
14775
  }
14063
14776
  let outputPromise;
14064
14777
  if (input.output && isOutputObject(input.output)) {
@@ -14092,14 +14805,14 @@ var processInputAttachments2 = async (input) => {
14092
14805
  processed.prompt = processPromptContent(input.prompt);
14093
14806
  }
14094
14807
  }
14095
- if (input.tools) {
14096
- processed.tools = processTools(input.tools);
14808
+ if (input.schema && isZodSchema2(input.schema)) {
14809
+ processed.schema = serializeZodSchema2(input.schema);
14097
14810
  }
14098
- if (input.schema && isZodSchema(input.schema)) {
14099
- processed.schema = serializeZodSchema(input.schema);
14811
+ if (input.callOptionsSchema && isZodSchema2(input.callOptionsSchema)) {
14812
+ processed.callOptionsSchema = serializeZodSchema2(input.callOptionsSchema);
14100
14813
  }
14101
- if (input.callOptionsSchema && isZodSchema(input.callOptionsSchema)) {
14102
- processed.callOptionsSchema = serializeZodSchema(input.callOptionsSchema);
14814
+ if (input.tools) {
14815
+ processed.tools = serializeAISDKToolsForLogging(input.tools);
14103
14816
  }
14104
14817
  if (input.output && isOutputObject(input.output)) {
14105
14818
  const serialized = serializeOutputObject(input.output, input.model);
@@ -14300,7 +15013,9 @@ var processOutput = async (output, denyOutputPaths) => {
14300
15013
  const getterValues = extractGetterValues2(output);
14301
15014
  const processed = await processOutputAttachments(output);
14302
15015
  const merged = { ...processed, ...getterValues };
14303
- return omit2(merged, denyOutputPaths ?? DENY_OUTPUT_PATHS);
15016
+ return normalizeAISDKLoggedOutput(
15017
+ omit2(merged, denyOutputPaths ?? DENY_OUTPUT_PATHS)
15018
+ );
14304
15019
  };
14305
15020
  var processOutputAttachments = async (output) => {
14306
15021
  try {
@@ -16358,11 +17073,13 @@ function serializeInput2(params) {
16358
17073
  if (params.config) {
16359
17074
  const config = tryToDict2(params.config);
16360
17075
  if (config) {
16361
- const tools = serializeTools2(params);
16362
- if (tools) {
16363
- config.tools = tools;
16364
- }
16365
- input.config = config;
17076
+ const filteredConfig = {};
17077
+ Object.keys(config).forEach((key) => {
17078
+ if (key !== "tools") {
17079
+ filteredConfig[key] = config[key];
17080
+ }
17081
+ });
17082
+ input.config = filteredConfig;
16366
17083
  }
16367
17084
  }
16368
17085
  return input;
@@ -16443,6 +17160,10 @@ function extractMetadata2(params) {
16443
17160
  });
16444
17161
  }
16445
17162
  }
17163
+ const tools = serializeTools2(params);
17164
+ if (tools) {
17165
+ metadata.tools = tools;
17166
+ }
16446
17167
  return metadata;
16447
17168
  }
16448
17169
  function extractGenerateContentMetrics2(response, start) {
@@ -17480,7 +18201,7 @@ function unescapePath(path2) {
17480
18201
  }
17481
18202
  var graph_framework_default = { createGraph };
17482
18203
 
17483
- // ../node_modules/async/dist/async.mjs
18204
+ // ../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
17484
18205
  function initialParams(fn) {
17485
18206
  return function(...args) {
17486
18207
  var callback = args.pop();
@@ -17548,7 +18269,7 @@ function invokeCallback(callback, error, value) {
17548
18269
  function isAsync(fn) {
17549
18270
  return fn[Symbol.toStringTag] === "AsyncFunction";
17550
18271
  }
17551
- function isAsyncGenerator2(fn) {
18272
+ function isAsyncGenerator3(fn) {
17552
18273
  return fn[Symbol.toStringTag] === "AsyncGenerator";
17553
18274
  }
17554
18275
  function isAsyncIterable3(obj) {
@@ -17605,6 +18326,7 @@ function isArrayLike(value) {
17605
18326
  return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
17606
18327
  }
17607
18328
  var breakLoop = {};
18329
+ var breakLoop$1 = breakLoop;
17608
18330
  function once(fn) {
17609
18331
  function wrapper(...args) {
17610
18332
  if (fn === null) return;
@@ -17696,7 +18418,7 @@ function asyncEachOfLimit(generator, limit, iteratee, callback) {
17696
18418
  canceled = true;
17697
18419
  return;
17698
18420
  }
17699
- if (result === breakLoop || done && running <= 0) {
18421
+ if (result === breakLoop$1 || done && running <= 0) {
17700
18422
  done = true;
17701
18423
  return callback(null);
17702
18424
  }
@@ -17719,7 +18441,7 @@ var eachOfLimit$2 = (limit) => {
17719
18441
  if (!obj) {
17720
18442
  return callback(null);
17721
18443
  }
17722
- if (isAsyncGenerator2(obj)) {
18444
+ if (isAsyncGenerator3(obj)) {
17723
18445
  return asyncEachOfLimit(obj, limit, iteratee, callback);
17724
18446
  }
17725
18447
  if (isAsyncIterable3(obj)) {
@@ -17739,7 +18461,7 @@ var eachOfLimit$2 = (limit) => {
17739
18461
  } else if (err === false) {
17740
18462
  done = true;
17741
18463
  canceled = true;
17742
- } else if (value === breakLoop || done && running <= 0) {
18464
+ } else if (value === breakLoop$1 || done && running <= 0) {
17743
18465
  done = true;
17744
18466
  return callback(null);
17745
18467
  } else if (!looping) {
@@ -17782,7 +18504,7 @@ function eachOfArrayLike(coll, iteratee, callback) {
17782
18504
  if (canceled === true) return;
17783
18505
  if (err) {
17784
18506
  callback(err);
17785
- } else if (++completed === length || value === breakLoop) {
18507
+ } else if (++completed === length || value === breakLoop$1) {
17786
18508
  callback(null);
17787
18509
  }
17788
18510
  }
@@ -18178,7 +18900,7 @@ function _createTester(check, getResult) {
18178
18900
  if (check(result) && !testResult) {
18179
18901
  testPassed = true;
18180
18902
  testResult = getResult(true, value);
18181
- return callback(null, breakLoop);
18903
+ return callback(null, breakLoop$1);
18182
18904
  }
18183
18905
  callback();
18184
18906
  });
@@ -18802,7 +19524,8 @@ var promptDefinitionSchema = promptContentsSchema.and(
18802
19524
  z10.object({
18803
19525
  model: z10.string(),
18804
19526
  params: ModelParams.optional(),
18805
- templateFormat: z10.enum(["mustache", "nunjucks", "none"]).optional()
19527
+ templateFormat: z10.enum(["mustache", "nunjucks", "none"]).optional(),
19528
+ environments: z10.array(z10.string()).optional()
18806
19529
  })
18807
19530
  );
18808
19531
  var promptDefinitionWithToolsSchema = promptDefinitionSchema.and(
@@ -18961,6 +19684,22 @@ function initExperiment2(state, options = {}) {
18961
19684
  setCurrent: false
18962
19685
  });
18963
19686
  }
19687
+ async function getExperimentParametersRef(parameters) {
19688
+ if (!parameters) {
19689
+ return void 0;
19690
+ }
19691
+ const resolvedParameters = parameters instanceof Promise ? await parameters : parameters;
19692
+ if (!RemoteEvalParameters.isParameters(resolvedParameters)) {
19693
+ return void 0;
19694
+ }
19695
+ if (resolvedParameters.id === void 0) {
19696
+ return void 0;
19697
+ }
19698
+ return {
19699
+ id: resolvedParameters.id,
19700
+ version: resolvedParameters.version
19701
+ };
19702
+ }
18964
19703
  function callEvaluatorData(data) {
18965
19704
  const dataResult = typeof data === "function" ? data() : data;
18966
19705
  let baseExperiment = void 0;
@@ -19027,6 +19766,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
19027
19766
  const { data, baseExperiment: defaultBaseExperiment } = callEvaluatorData(
19028
19767
  evaluator.data
19029
19768
  );
19769
+ const parameters = await getExperimentParametersRef(evaluator.parameters);
19030
19770
  const experiment = options.parent || options.noSendLogs ? null : initExperiment2(evaluator.state, {
19031
19771
  ...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
19032
19772
  experiment: evaluator.experimentName,
@@ -19039,7 +19779,8 @@ async function Eval(name, evaluator, reporterOrOpts) {
19039
19779
  baseExperimentId: evaluator.baseExperimentId,
19040
19780
  gitMetadataSettings: evaluator.gitMetadataSettings,
19041
19781
  repoInfo: evaluator.repoInfo,
19042
- dataset: Dataset2.isDataset(data) ? data : void 0
19782
+ dataset: Dataset2.isDataset(data) ? data : void 0,
19783
+ parameters
19043
19784
  });
19044
19785
  if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
19045
19786
  await experiment._waitForId();
@@ -19094,7 +19835,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
19094
19835
  if (experiment) {
19095
19836
  await experiment.flush().catch(console.error);
19096
19837
  } else if (options.parent) {
19097
- await flush().catch(console.error);
19838
+ await flush({ state: evaluator.state }).catch(console.error);
19098
19839
  }
19099
19840
  }
19100
19841
  } finally {
@@ -19482,6 +20223,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
19482
20223
  },
19483
20224
  Math.max(evaluator.maxConcurrency ?? Number.MAX_SAFE_INTEGER, 1)
19484
20225
  );
20226
+ const queueErrors = [];
19485
20227
  const enqueuePromise = (async () => {
19486
20228
  for await (const datum of dataIterable) {
19487
20229
  if (cancelled) {
@@ -19497,7 +20239,11 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
19497
20239
  }
19498
20240
  scheduledTrials++;
19499
20241
  progressReporter.setTotal?.(evaluator.evalName, scheduledTrials);
19500
- q.push({ datum, trialIndex });
20242
+ q.pushAsync({ datum, trialIndex }).catch((e) => {
20243
+ if (queueErrors.length < 5) {
20244
+ queueErrors.push(e);
20245
+ }
20246
+ });
19501
20247
  }
19502
20248
  }
19503
20249
  })();
@@ -19545,6 +20291,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
19545
20291
  })();
19546
20292
  try {
19547
20293
  await Promise.race([waitForQueue, cancel()]);
20294
+ if (queueErrors.length > 0) {
20295
+ throw new AggregateError(
20296
+ queueErrors,
20297
+ `Encountered ${queueErrors.length} unhandled task errors`
20298
+ );
20299
+ }
19548
20300
  } catch (e) {
19549
20301
  q.kill();
19550
20302
  if (e instanceof InternalAbortError) {
@@ -19948,6 +20700,7 @@ var CodePrompt = class {
19948
20700
  toolFunctions;
19949
20701
  tags;
19950
20702
  metadata;
20703
+ environmentSlugs;
19951
20704
  constructor(project, prompt, toolFunctions, opts, functionType) {
19952
20705
  this.project = project;
19953
20706
  this.name = opts.name;
@@ -19960,6 +20713,7 @@ var CodePrompt = class {
19960
20713
  this.functionType = functionType;
19961
20714
  this.tags = opts.tags;
19962
20715
  this.metadata = opts.metadata;
20716
+ this.environmentSlugs = opts.environments;
19963
20717
  }
19964
20718
  async toFunctionDefinition(projectNameToId) {
19965
20719
  const prompt_data = {
@@ -19994,7 +20748,8 @@ var CodePrompt = class {
19994
20748
  prompt_data,
19995
20749
  if_exists: this.ifExists,
19996
20750
  tags: this.tags,
19997
- metadata: this.metadata
20751
+ metadata: this.metadata,
20752
+ environments: this.environmentSlugs && this.environmentSlugs.length > 0 ? this.environmentSlugs.map((slug) => ({ slug })) : void 0
19998
20753
  };
19999
20754
  }
20000
20755
  };