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
@@ -179,8 +179,54 @@ var DefaultAsyncLocalStorage = class {
179
179
  return void 0;
180
180
  }
181
181
  };
182
- var DefaultTracingChannel = class {
182
+ var DefaultChannel = class {
183
+ constructor(name) {
184
+ this.name = name;
185
+ }
183
186
  hasSubscribers = false;
187
+ subscribe(_subscription) {
188
+ }
189
+ unsubscribe(_subscription) {
190
+ return false;
191
+ }
192
+ bindStore(_store, _transform) {
193
+ }
194
+ unbindStore(_store) {
195
+ return false;
196
+ }
197
+ publish(_message) {
198
+ }
199
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
200
+ runStores(_message, fn, thisArg, ...args) {
201
+ return fn.apply(thisArg, args);
202
+ }
203
+ };
204
+ var DefaultTracingChannel = class {
205
+ start;
206
+ end;
207
+ asyncStart;
208
+ asyncEnd;
209
+ error;
210
+ constructor(nameOrChannels) {
211
+ if (typeof nameOrChannels === "string") {
212
+ this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
213
+ this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
214
+ this.asyncStart = new DefaultChannel(
215
+ `tracing:${nameOrChannels}:asyncStart`
216
+ );
217
+ this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
218
+ this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
219
+ return;
220
+ }
221
+ this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
222
+ this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
223
+ this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
224
+ this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
225
+ this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
226
+ }
227
+ get hasSubscribers() {
228
+ return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
229
+ }
184
230
  subscribe(_handlers) {
185
231
  }
186
232
  unsubscribe(_handlers) {
@@ -208,7 +254,7 @@ var iso = {
208
254
  getCallerLocation: () => void 0,
209
255
  newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
210
256
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
211
- newTracingChannel: (_nameOrChannels) => new DefaultTracingChannel(),
257
+ newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
212
258
  processOn: (_0, _1) => {
213
259
  },
214
260
  basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
@@ -2275,6 +2321,8 @@ var Experiment = import_v36.z.object({
2275
2321
  deleted_at: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2276
2322
  dataset_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2277
2323
  dataset_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2324
+ parameters_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2325
+ parameters_version: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2278
2326
  public: import_v36.z.boolean(),
2279
2327
  user_id: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
2280
2328
  metadata: import_v36.z.union([import_v36.z.object({}).partial().passthrough(), import_v36.z.null()]).optional(),
@@ -2297,7 +2345,11 @@ var SpanType = import_v36.z.union([
2297
2345
  import_v36.z.null()
2298
2346
  ]);
2299
2347
  var SpanAttributes = import_v36.z.union([
2300
- import_v36.z.object({ name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]), type: SpanType }).partial().passthrough(),
2348
+ import_v36.z.object({
2349
+ name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]),
2350
+ type: SpanType,
2351
+ purpose: import_v36.z.union([import_v36.z.literal("scorer"), import_v36.z.null()])
2352
+ }).partial().passthrough(),
2301
2353
  import_v36.z.null()
2302
2354
  ]);
2303
2355
  var ExperimentEvent = import_v36.z.object({
@@ -2737,6 +2789,7 @@ var FunctionId = import_v36.z.union([
2737
2789
  version: import_v36.z.string()
2738
2790
  }),
2739
2791
  code: import_v36.z.string(),
2792
+ function_type: FunctionTypeEnum.and(import_v36.z.unknown()).optional(),
2740
2793
  name: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
2741
2794
  }),
2742
2795
  import_v36.z.object({
@@ -2966,7 +3019,12 @@ var TopicAutomationConfig = import_v36.z.object({
2966
3019
  topic_map_functions: import_v36.z.array(TopicMapFunctionAutomation),
2967
3020
  scope: import_v36.z.union([SpanScope, TraceScope, GroupScope, import_v36.z.null()]).optional(),
2968
3021
  data_scope: TopicAutomationDataScope.optional(),
2969
- btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional()
3022
+ btql_filter: import_v36.z.union([import_v36.z.string(), import_v36.z.null()]).optional(),
3023
+ backfill_time_range: import_v36.z.union([
3024
+ import_v36.z.string(),
3025
+ import_v36.z.object({ from: import_v36.z.string(), to: import_v36.z.string() }),
3026
+ import_v36.z.null()
3027
+ ]).optional()
2970
3028
  });
2971
3029
  var ProjectAutomation = import_v36.z.object({
2972
3030
  id: import_v36.z.string().uuid(),
@@ -4403,6 +4461,12 @@ var parametersRowSchema = import_v38.z.object({
4403
4461
  }),
4404
4462
  metadata: import_v38.z.union([import_v38.z.object({}).partial().passthrough(), import_v38.z.null()]).optional()
4405
4463
  });
4464
+ var InlineAttachmentReferenceSchema = import_v38.z.object({
4465
+ type: import_v38.z.literal("inline_attachment"),
4466
+ src: import_v38.z.string().min(1),
4467
+ content_type: import_v38.z.string().optional(),
4468
+ filename: import_v38.z.string().optional()
4469
+ });
4406
4470
  var LoginInvalidOrgError = class extends Error {
4407
4471
  constructor(message) {
4408
4472
  super(message);
@@ -6604,6 +6668,7 @@ function init(projectOrOptions, optionalOptions) {
6604
6668
  experiment,
6605
6669
  description,
6606
6670
  dataset,
6671
+ parameters,
6607
6672
  baseExperiment,
6608
6673
  isPublic,
6609
6674
  open,
@@ -6721,6 +6786,17 @@ function init(projectOrOptions, optionalOptions) {
6721
6786
  args["dataset_version"] = await dataset.version();
6722
6787
  }
6723
6788
  }
6789
+ if (parameters !== void 0) {
6790
+ if (RemoteEvalParameters.isParameters(parameters)) {
6791
+ args["parameters_id"] = parameters.id;
6792
+ args["parameters_version"] = parameters.version;
6793
+ } else {
6794
+ args["parameters_id"] = parameters.id;
6795
+ if (parameters.version !== void 0) {
6796
+ args["parameters_version"] = parameters.version;
6797
+ }
6798
+ }
6799
+ }
6724
6800
  if (isPublic !== void 0) {
6725
6801
  args["public"] = isPublic;
6726
6802
  }
@@ -8919,40 +8995,85 @@ var Dataset2 = class extends ObjectFetcher {
8919
8995
  return typeof data === "object" && data !== null && "__braintrust_dataset_marker" in data;
8920
8996
  }
8921
8997
  };
8998
+ function isAttachmentObject(value) {
8999
+ return BraintrustAttachmentReference.safeParse(value).success || InlineAttachmentReferenceSchema.safeParse(value).success || ExternalAttachmentReference.safeParse(value).success;
9000
+ }
9001
+ function isURL(url) {
9002
+ try {
9003
+ const parsedUrl = new URL(url.trim());
9004
+ return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
9005
+ } catch {
9006
+ return false;
9007
+ }
9008
+ }
9009
+ function expandAttachmentArrayPreTemplate(content, variables) {
9010
+ if (typeof content !== "string") return null;
9011
+ const match = content.match(/^\{\{\s*([\w.]+)\s*\}\}$/);
9012
+ if (!match) return null;
9013
+ const varPath = match[1];
9014
+ const value = varPath.includes(".") ? getObjValueByPath(variables, varPath.split(".")) : variables[varPath];
9015
+ if (!Array.isArray(value)) return null;
9016
+ const allValid = value.every(
9017
+ (v) => isAttachmentObject(v) || typeof v === "string" && isURL(v)
9018
+ );
9019
+ if (!allValid) return null;
9020
+ return value.map((item) => ({
9021
+ type: "image_url",
9022
+ image_url: { url: item }
9023
+ }));
9024
+ }
8922
9025
  function renderMessage(render, message) {
9026
+ return renderMessageImpl(render, message, {});
9027
+ }
9028
+ function renderMessageImpl(render, message, variables) {
8923
9029
  return {
8924
9030
  ...message,
8925
9031
  ..."content" in message ? {
8926
- content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.map((c) => {
9032
+ content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.flatMap((c) => {
8927
9033
  switch (c.type) {
8928
9034
  case "text":
8929
- return { ...c, text: render(c.text) };
9035
+ return [{ ...c, text: render(c.text) }];
8930
9036
  case "image_url":
8931
9037
  if (isObject(c.image_url.url)) {
8932
9038
  throw new Error(
8933
9039
  "Attachments must be replaced with URLs before calling `build()`"
8934
9040
  );
8935
9041
  }
8936
- return {
8937
- ...c,
8938
- image_url: {
8939
- ...c.image_url,
8940
- url: render(c.image_url.url)
9042
+ if (variables) {
9043
+ const expanded = expandAttachmentArrayPreTemplate(
9044
+ c.image_url.url,
9045
+ variables
9046
+ );
9047
+ if (expanded) {
9048
+ return expanded;
8941
9049
  }
8942
- };
9050
+ }
9051
+ return [
9052
+ {
9053
+ ...c,
9054
+ image_url: {
9055
+ ...c.image_url,
9056
+ url: render(c.image_url.url)
9057
+ }
9058
+ }
9059
+ ];
8943
9060
  case "file":
8944
- return {
8945
- ...c,
8946
- file: {
8947
- file_data: render(c.file.file_data || ""),
8948
- ...c.file.file_id && {
8949
- file_id: render(c.file.file_id)
8950
- },
8951
- ...c.file.filename && {
8952
- filename: render(c.file.filename)
9061
+ return [
9062
+ {
9063
+ ...c,
9064
+ file: {
9065
+ ...c.file.file_data && {
9066
+ file_data: render(c.file.file_data)
9067
+ },
9068
+ ...c.file.file_id && {
9069
+ file_id: render(c.file.file_id)
9070
+ },
9071
+ ...c.file.filename && {
9072
+ filename: render(c.file.filename)
9073
+ }
8953
9074
  }
8954
9075
  }
8955
- };
9076
+ ];
8956
9077
  default:
8957
9078
  const _exhaustiveCheck = c;
8958
9079
  return _exhaustiveCheck;
@@ -9109,17 +9230,19 @@ var Prompt2 = class _Prompt {
9109
9230
  }
9110
9231
  runBuild(buildArgs, options) {
9111
9232
  const { flavor } = options;
9112
- const params = {
9113
- ...this.defaults,
9114
- ...Object.fromEntries(
9115
- Object.entries(this.options.params || {}).filter(
9116
- ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
9117
- )
9118
- ),
9119
- ...!isEmpty2(this.options.model) ? {
9120
- model: this.options.model
9121
- } : {}
9122
- };
9233
+ const params = Object.fromEntries(
9234
+ Object.entries({
9235
+ ...this.defaults,
9236
+ ...Object.fromEntries(
9237
+ Object.entries(this.options.params || {}).filter(
9238
+ ([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
9239
+ )
9240
+ ),
9241
+ ...!isEmpty2(this.options.model) ? {
9242
+ model: this.options.model
9243
+ } : {}
9244
+ }).filter(([key, value]) => key !== "response_format" || value !== null)
9245
+ );
9123
9246
  if (!("model" in params) || isEmpty2(params.model)) {
9124
9247
  throw new Error(
9125
9248
  "No model specified. Either specify it in the prompt or as a default"
@@ -9219,7 +9342,7 @@ var Prompt2 = class _Prompt {
9219
9342
  templateFormat
9220
9343
  });
9221
9344
  const baseMessages = (prompt.messages || []).map(
9222
- (m) => renderMessage(render, m)
9345
+ (m) => renderMessageImpl(render, m, variables)
9223
9346
  );
9224
9347
  const hasSystemPrompt = baseMessages.some((m) => m.role === "system");
9225
9348
  const messages = [
@@ -9417,6 +9540,40 @@ var _exportsForTestingOnly = {
9417
9540
  // Expose isomorph for build type detection
9418
9541
  };
9419
9542
 
9543
+ // src/runtime-async-local-storage.ts
9544
+ function isAsyncLocalStorageConstructor(candidate) {
9545
+ return typeof candidate === "function";
9546
+ }
9547
+ function resolveRuntimeAsyncLocalStorage() {
9548
+ try {
9549
+ const globalAsyncLocalStorage = Reflect.get(
9550
+ globalThis,
9551
+ "AsyncLocalStorage"
9552
+ );
9553
+ if (isAsyncLocalStorageConstructor(globalAsyncLocalStorage)) {
9554
+ return globalAsyncLocalStorage;
9555
+ }
9556
+ if (typeof process === "undefined") {
9557
+ return void 0;
9558
+ }
9559
+ const getBuiltinModule = Reflect.get(process, "getBuiltinModule");
9560
+ if (typeof getBuiltinModule !== "function") {
9561
+ return void 0;
9562
+ }
9563
+ const asyncHooksModule = getBuiltinModule("node:async_hooks");
9564
+ if (typeof asyncHooksModule !== "object" || asyncHooksModule === null) {
9565
+ return void 0;
9566
+ }
9567
+ if (!("AsyncLocalStorage" in asyncHooksModule)) {
9568
+ return void 0;
9569
+ }
9570
+ const { AsyncLocalStorage: runtimeAsyncLocalStorage } = asyncHooksModule;
9571
+ return isAsyncLocalStorageConstructor(runtimeAsyncLocalStorage) ? runtimeAsyncLocalStorage : void 0;
9572
+ } catch {
9573
+ return void 0;
9574
+ }
9575
+ }
9576
+
9420
9577
  // src/edge-light/config.ts
9421
9578
  var edgeLightConfigured = false;
9422
9579
  function configureEdgeLight() {
@@ -9424,11 +9581,9 @@ function configureEdgeLight() {
9424
9581
  return;
9425
9582
  }
9426
9583
  isomorph_default.buildType = "edge-light";
9427
- try {
9428
- if (typeof AsyncLocalStorage !== "undefined") {
9429
- isomorph_default.newAsyncLocalStorage = () => new AsyncLocalStorage();
9430
- }
9431
- } catch {
9584
+ const runtimeAsyncLocalStorage = resolveRuntimeAsyncLocalStorage();
9585
+ if (runtimeAsyncLocalStorage) {
9586
+ isomorph_default.newAsyncLocalStorage = () => new runtimeAsyncLocalStorage();
9432
9587
  }
9433
9588
  isomorph_default.getEnv = (name) => {
9434
9589
  if (typeof process === "undefined" || typeof process.env === "undefined") {
@@ -10189,15 +10344,23 @@ function createEndpointProxy(target, wrapperFn) {
10189
10344
  });
10190
10345
  }
10191
10346
  function wrapApiCreateWithChannel(create, channel2) {
10192
- return async (allParams, options) => {
10347
+ return (allParams, options) => {
10193
10348
  const { span_info, params } = splitSpanInfo(allParams);
10194
- const traceContext = createChannelContext(channel2, params, span_info);
10195
- const { data } = await tracePromiseWithResponse(
10196
- channel2,
10197
- traceContext,
10198
- create(params, options)
10199
- );
10200
- return data;
10349
+ let executionPromise = null;
10350
+ const ensureExecuted = () => {
10351
+ if (!executionPromise) {
10352
+ executionPromise = (async () => {
10353
+ const traceContext = createChannelContext(channel2, params, span_info);
10354
+ return tracePromiseWithResponse(
10355
+ channel2,
10356
+ traceContext,
10357
+ create(params, options)
10358
+ );
10359
+ })();
10360
+ }
10361
+ return executionPromise;
10362
+ };
10363
+ return createLazyAPIPromise(ensureExecuted);
10201
10364
  };
10202
10365
  }
10203
10366
  var wrapEmbeddings = (create) => wrapApiCreateWithChannel(create, openAIChannels.embeddingsCreate);
@@ -10377,6 +10540,93 @@ function zodToJsonSchema(schema) {
10377
10540
  return (0, import_zod_to_json_schema.zodToJsonSchema)(schema);
10378
10541
  }
10379
10542
 
10543
+ // src/wrappers/ai-sdk/normalize-logged-output.ts
10544
+ var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
10545
+ function normalizeAISDKLoggedOutput(value) {
10546
+ const normalized = normalizeAISDKLoggedValue(value);
10547
+ return normalized === REMOVE_NORMALIZED_VALUE ? {} : normalized;
10548
+ }
10549
+ function normalizeAISDKLoggedValue(value, context = {}) {
10550
+ if (Array.isArray(value)) {
10551
+ return value.map((entry) => normalizeAISDKLoggedValue(entry, context)).filter((entry) => entry !== REMOVE_NORMALIZED_VALUE);
10552
+ }
10553
+ if (!value || typeof value !== "object") {
10554
+ return value;
10555
+ }
10556
+ const nextInProviderMetadata = context.inProviderMetadata || context.parentKey === "providerMetadata" || context.parentKey === "experimental_providerMetadata";
10557
+ const normalizedEntries = [];
10558
+ for (const [key, entry] of Object.entries(value)) {
10559
+ if (key === "cachedPromptTokens" && entry === 0) {
10560
+ continue;
10561
+ }
10562
+ if (context.parentKey === "request" && key === "body" && entry === "<omitted>") {
10563
+ continue;
10564
+ }
10565
+ const normalizedEntry = normalizeAISDKLoggedValue(entry, {
10566
+ inProviderMetadata: nextInProviderMetadata,
10567
+ parentKey: key
10568
+ });
10569
+ if (normalizedEntry === REMOVE_NORMALIZED_VALUE) {
10570
+ continue;
10571
+ }
10572
+ normalizedEntries.push([key, normalizedEntry]);
10573
+ }
10574
+ if (normalizedEntries.length === 0) {
10575
+ if (context.parentKey === "request" || nextInProviderMetadata) {
10576
+ return REMOVE_NORMALIZED_VALUE;
10577
+ }
10578
+ return {};
10579
+ }
10580
+ return Object.fromEntries(normalizedEntries);
10581
+ }
10582
+
10583
+ // src/wrappers/ai-sdk/tool-serialization.ts
10584
+ function isZodSchema(value) {
10585
+ return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
10586
+ }
10587
+ function serializeZodSchema(schema) {
10588
+ try {
10589
+ return zodToJsonSchema(schema);
10590
+ } catch {
10591
+ return {
10592
+ type: "object",
10593
+ description: "Zod schema (conversion failed)"
10594
+ };
10595
+ }
10596
+ }
10597
+ function serializeTool(tool) {
10598
+ if (!tool || typeof tool !== "object") {
10599
+ return tool;
10600
+ }
10601
+ const serialized = { ...tool };
10602
+ if (isZodSchema(serialized.inputSchema)) {
10603
+ serialized.inputSchema = serializeZodSchema(serialized.inputSchema);
10604
+ }
10605
+ if (isZodSchema(serialized.parameters)) {
10606
+ serialized.parameters = serializeZodSchema(serialized.parameters);
10607
+ }
10608
+ if ("execute" in serialized) {
10609
+ delete serialized.execute;
10610
+ }
10611
+ if ("render" in serialized) {
10612
+ delete serialized.render;
10613
+ }
10614
+ return serialized;
10615
+ }
10616
+ function serializeAISDKToolsForLogging(tools) {
10617
+ if (!tools || typeof tools !== "object") {
10618
+ return tools;
10619
+ }
10620
+ if (Array.isArray(tools)) {
10621
+ return tools.map(serializeTool);
10622
+ }
10623
+ const serialized = {};
10624
+ for (const [key, tool] of Object.entries(tools)) {
10625
+ serialized[key] = serializeTool(tool);
10626
+ }
10627
+ return serialized;
10628
+ }
10629
+
10380
10630
  // src/wrappers/ai-sdk/ai-sdk.ts
10381
10631
  var DENY_OUTPUT_PATHS = [
10382
10632
  // v3
@@ -10471,9 +10721,11 @@ var wrapAgentGenerate = (generate, instance, options = {}) => {
10471
10721
  return async (params) => makeGenerateTextWrapper(
10472
10722
  `${instance.constructor.name}.generate`,
10473
10723
  options,
10474
- generate.bind(instance)
10724
+ generate.bind(instance),
10475
10725
  // as of v5 this is just streamText under the hood
10476
10726
  // Follows what the AI SDK does under the hood when calling generateText
10727
+ void 0,
10728
+ "function" /* FUNCTION */
10477
10729
  )({ ...instance.settings, ...params });
10478
10730
  };
10479
10731
  var wrapAgentStream = (stream, instance, options = {}) => {
@@ -10482,11 +10734,12 @@ var wrapAgentStream = (stream, instance, options = {}) => {
10482
10734
  options,
10483
10735
  stream.bind(instance),
10484
10736
  // as of v5 this is just streamText under the hood
10485
- void 0
10737
+ void 0,
10486
10738
  // aiSDK not needed since model is already on instance
10739
+ "function" /* FUNCTION */
10487
10740
  )({ ...instance.settings, ...params });
10488
10741
  };
10489
- var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
10742
+ var makeGenerateTextWrapper = (name, options, generateText, aiSDK, spanType = "llm" /* LLM */) => {
10490
10743
  const wrapper = async function(allParams) {
10491
10744
  const { span_info, ...params } = allParams;
10492
10745
  const {
@@ -10495,6 +10748,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
10495
10748
  spanAttributes: spanInfoAttrs
10496
10749
  } = span_info ?? {};
10497
10750
  const { model, provider } = serializeModelWithProvider(params.model);
10751
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
10498
10752
  const processedInput = await processInputAttachments2(params);
10499
10753
  return traced(
10500
10754
  async (span) => {
@@ -10525,7 +10779,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
10525
10779
  {
10526
10780
  name: spanName || name,
10527
10781
  spanAttributes: {
10528
- type: "llm" /* LLM */,
10782
+ type: spanType,
10529
10783
  ...spanInfoAttrs
10530
10784
  },
10531
10785
  event: {
@@ -10534,6 +10788,7 @@ var makeGenerateTextWrapper = (name, options, generateText, aiSDK) => {
10534
10788
  ...spanInfoMetadata,
10535
10789
  model,
10536
10790
  ...provider ? { provider } : {},
10791
+ ...serializedTools ? { tools: serializedTools } : {},
10537
10792
  braintrust: {
10538
10793
  integration_name: "ai-sdk",
10539
10794
  sdk_language: "typescript"
@@ -10568,6 +10823,7 @@ var wrapModel = (model, ai) => {
10568
10823
  const originalDoStream = resolvedModel.doStream?.bind(resolvedModel);
10569
10824
  const { model: modelId, provider } = serializeModelWithProvider(resolvedModel);
10570
10825
  const wrappedDoGenerate = async (options) => {
10826
+ const serializedTools = serializeAISDKToolsForLogging(options.tools);
10571
10827
  const processedInput = await processInputAttachments2(options);
10572
10828
  return traced(
10573
10829
  async (span) => {
@@ -10600,6 +10856,7 @@ var wrapModel = (model, ai) => {
10600
10856
  metadata: {
10601
10857
  model: modelId,
10602
10858
  ...provider ? { provider } : {},
10859
+ ...serializedTools ? { tools: serializedTools } : {},
10603
10860
  braintrust: {
10604
10861
  integration_name: "ai-sdk",
10605
10862
  sdk_language: "typescript"
@@ -10612,6 +10869,7 @@ var wrapModel = (model, ai) => {
10612
10869
  const wrappedDoStream = async (options) => {
10613
10870
  const startTime = Date.now();
10614
10871
  let receivedFirst = false;
10872
+ const serializedTools = serializeAISDKToolsForLogging(options.tools);
10615
10873
  const processedInput = await processInputAttachments2(options);
10616
10874
  const span = startSpan({
10617
10875
  name: "doStream",
@@ -10623,6 +10881,7 @@ var wrapModel = (model, ai) => {
10623
10881
  metadata: {
10624
10882
  model: modelId,
10625
10883
  ...provider ? { provider } : {},
10884
+ ...serializedTools ? { tools: serializedTools } : {},
10626
10885
  braintrust: {
10627
10886
  integration_name: "ai-sdk",
10628
10887
  sdk_language: "typescript"
@@ -10636,7 +10895,7 @@ var wrapModel = (model, ai) => {
10636
10895
  let reasoning = "";
10637
10896
  const toolCalls = [];
10638
10897
  let object = void 0;
10639
- const extractTextDelta = (chunk) => {
10898
+ const extractTextDelta2 = (chunk) => {
10640
10899
  if (typeof chunk.textDelta === "string") return chunk.textDelta;
10641
10900
  if (typeof chunk.delta === "string") return chunk.delta;
10642
10901
  if (typeof chunk.text === "string") return chunk.text;
@@ -10655,7 +10914,7 @@ var wrapModel = (model, ai) => {
10655
10914
  }
10656
10915
  switch (chunk.type) {
10657
10916
  case "text-delta":
10658
- text += extractTextDelta(chunk);
10917
+ text += extractTextDelta2(chunk);
10659
10918
  break;
10660
10919
  case "reasoning-delta":
10661
10920
  if (chunk.delta) {
@@ -10755,6 +11014,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
10755
11014
  spanAttributes: spanInfoAttrs
10756
11015
  } = span_info ?? {};
10757
11016
  const { model, provider } = serializeModelWithProvider(params.model);
11017
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
10758
11018
  const processedInput = await processInputAttachments2(params);
10759
11019
  return traced(
10760
11020
  async (span) => {
@@ -10795,6 +11055,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
10795
11055
  ...spanInfoMetadata,
10796
11056
  model,
10797
11057
  ...provider ? { provider } : {},
11058
+ ...serializedTools ? { tools: serializedTools } : {},
10798
11059
  braintrust: {
10799
11060
  integration_name: "ai-sdk",
10800
11061
  sdk_language: "typescript"
@@ -10805,7 +11066,7 @@ var wrapGenerateObject = (generateObject, options = {}, aiSDK) => {
10805
11066
  );
10806
11067
  };
10807
11068
  };
10808
- var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
11069
+ var makeStreamTextWrapper = (name, options, streamText, aiSDK, spanType = "llm" /* LLM */) => {
10809
11070
  const wrapper = function(allParams) {
10810
11071
  const { span_info, ...params } = allParams;
10811
11072
  const {
@@ -10814,11 +11075,12 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
10814
11075
  spanAttributes: spanInfoAttrs
10815
11076
  } = span_info ?? {};
10816
11077
  const { model, provider } = serializeModelWithProvider(params.model);
11078
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
10817
11079
  const { input: processedInput, outputPromise } = processInputAttachmentsSync(params);
10818
11080
  const span = startSpan({
10819
11081
  name: spanName || name,
10820
11082
  spanAttributes: {
10821
- type: "llm" /* LLM */,
11083
+ type: spanType,
10822
11084
  ...spanInfoAttrs
10823
11085
  },
10824
11086
  event: {
@@ -10827,6 +11089,7 @@ var makeStreamTextWrapper = (name, options, streamText, aiSDK) => {
10827
11089
  ...spanInfoMetadata,
10828
11090
  model,
10829
11091
  ...provider ? { provider } : {},
11092
+ ...serializedTools ? { tools: serializedTools } : {},
10830
11093
  braintrust: {
10831
11094
  integration_name: "ai-sdk",
10832
11095
  sdk_language: "typescript"
@@ -10942,6 +11205,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
10942
11205
  spanAttributes: spanInfoAttrs
10943
11206
  } = span_info ?? {};
10944
11207
  const { model, provider } = serializeModelWithProvider(params.model);
11208
+ const serializedTools = serializeAISDKToolsForLogging(params.tools);
10945
11209
  const { input: processedInput, outputPromise } = processInputAttachmentsSync(params);
10946
11210
  const span = startSpan({
10947
11211
  name: spanName || "streamObject",
@@ -10955,6 +11219,7 @@ var wrapStreamObject = (streamObject, options = {}, aiSDK) => {
10955
11219
  ...spanInfoMetadata,
10956
11220
  model,
10957
11221
  ...provider ? { provider } : {},
11222
+ ...serializedTools ? { tools: serializedTools } : {},
10958
11223
  braintrust: {
10959
11224
  integration_name: "ai-sdk",
10960
11225
  sdk_language: "typescript"
@@ -11221,10 +11486,10 @@ function extractGatewayRoutingInfo(result) {
11221
11486
  }
11222
11487
  return null;
11223
11488
  }
11224
- var isZodSchema = (value) => {
11489
+ var isZodSchema2 = (value) => {
11225
11490
  return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
11226
11491
  };
11227
- var serializeZodSchema = (schema) => {
11492
+ var serializeZodSchema2 = (schema) => {
11228
11493
  try {
11229
11494
  return zodToJsonSchema(schema);
11230
11495
  } catch {
@@ -11234,34 +11499,6 @@ var serializeZodSchema = (schema) => {
11234
11499
  };
11235
11500
  }
11236
11501
  };
11237
- var processTools = (tools) => {
11238
- if (!tools || typeof tools !== "object") return tools;
11239
- if (Array.isArray(tools)) {
11240
- return tools.map(processTool);
11241
- }
11242
- const processed = {};
11243
- for (const [key, tool] of Object.entries(tools)) {
11244
- processed[key] = processTool(tool);
11245
- }
11246
- return processed;
11247
- };
11248
- var processTool = (tool) => {
11249
- if (!tool || typeof tool !== "object") return tool;
11250
- const processed = { ...tool };
11251
- if (isZodSchema(processed.inputSchema)) {
11252
- processed.inputSchema = serializeZodSchema(processed.inputSchema);
11253
- }
11254
- if (isZodSchema(processed.parameters)) {
11255
- processed.parameters = serializeZodSchema(processed.parameters);
11256
- }
11257
- if ("execute" in processed) {
11258
- processed.execute = "[Function]";
11259
- }
11260
- if ("render" in processed) {
11261
- processed.render = "[Function]";
11262
- }
11263
- return processed;
11264
- };
11265
11502
  var isOutputObject = (value) => {
11266
11503
  if (value == null || typeof value !== "object") {
11267
11504
  return false;
@@ -11300,10 +11537,10 @@ var serializeOutputObject = (output, model) => {
11300
11537
  if (typeof responseFormat.then === "function") {
11301
11538
  result.response_format = Promise.resolve(responseFormat).then(
11302
11539
  (resolved) => {
11303
- if (resolved.schema && isZodSchema(resolved.schema)) {
11540
+ if (resolved.schema && isZodSchema2(resolved.schema)) {
11304
11541
  return {
11305
11542
  ...resolved,
11306
- schema: serializeZodSchema(resolved.schema)
11543
+ schema: serializeZodSchema2(resolved.schema)
11307
11544
  };
11308
11545
  }
11309
11546
  return resolved;
@@ -11311,10 +11548,10 @@ var serializeOutputObject = (output, model) => {
11311
11548
  );
11312
11549
  } else {
11313
11550
  const syncResponseFormat = responseFormat;
11314
- if (syncResponseFormat.schema && isZodSchema(syncResponseFormat.schema)) {
11551
+ if (syncResponseFormat.schema && isZodSchema2(syncResponseFormat.schema)) {
11315
11552
  responseFormat = {
11316
11553
  ...syncResponseFormat,
11317
- schema: serializeZodSchema(syncResponseFormat.schema)
11554
+ schema: serializeZodSchema2(syncResponseFormat.schema)
11318
11555
  };
11319
11556
  }
11320
11557
  result.response_format = responseFormat;
@@ -11340,14 +11577,14 @@ var processInputAttachmentsSync = (input) => {
11340
11577
  processed.prompt = processPromptContent(input.prompt);
11341
11578
  }
11342
11579
  }
11343
- if (input.tools) {
11344
- processed.tools = processTools(input.tools);
11580
+ if (input.schema && isZodSchema2(input.schema)) {
11581
+ processed.schema = serializeZodSchema2(input.schema);
11345
11582
  }
11346
- if (input.schema && isZodSchema(input.schema)) {
11347
- processed.schema = serializeZodSchema(input.schema);
11583
+ if (input.callOptionsSchema && isZodSchema2(input.callOptionsSchema)) {
11584
+ processed.callOptionsSchema = serializeZodSchema2(input.callOptionsSchema);
11348
11585
  }
11349
- if (input.callOptionsSchema && isZodSchema(input.callOptionsSchema)) {
11350
- processed.callOptionsSchema = serializeZodSchema(input.callOptionsSchema);
11586
+ if (input.tools) {
11587
+ processed.tools = serializeAISDKToolsForLogging(input.tools);
11351
11588
  }
11352
11589
  let outputPromise;
11353
11590
  if (input.output && isOutputObject(input.output)) {
@@ -11381,14 +11618,14 @@ var processInputAttachments2 = async (input) => {
11381
11618
  processed.prompt = processPromptContent(input.prompt);
11382
11619
  }
11383
11620
  }
11384
- if (input.tools) {
11385
- processed.tools = processTools(input.tools);
11621
+ if (input.schema && isZodSchema2(input.schema)) {
11622
+ processed.schema = serializeZodSchema2(input.schema);
11386
11623
  }
11387
- if (input.schema && isZodSchema(input.schema)) {
11388
- processed.schema = serializeZodSchema(input.schema);
11624
+ if (input.callOptionsSchema && isZodSchema2(input.callOptionsSchema)) {
11625
+ processed.callOptionsSchema = serializeZodSchema2(input.callOptionsSchema);
11389
11626
  }
11390
- if (input.callOptionsSchema && isZodSchema(input.callOptionsSchema)) {
11391
- processed.callOptionsSchema = serializeZodSchema(input.callOptionsSchema);
11627
+ if (input.tools) {
11628
+ processed.tools = serializeAISDKToolsForLogging(input.tools);
11392
11629
  }
11393
11630
  if (input.output && isOutputObject(input.output)) {
11394
11631
  const serialized = serializeOutputObject(input.output, input.model);
@@ -11589,7 +11826,9 @@ var processOutput = async (output, denyOutputPaths) => {
11589
11826
  const getterValues = extractGetterValues(output);
11590
11827
  const processed = await processOutputAttachments(output);
11591
11828
  const merged = { ...processed, ...getterValues };
11592
- return omit(merged, denyOutputPaths ?? DENY_OUTPUT_PATHS);
11829
+ return normalizeAISDKLoggedOutput(
11830
+ omit(merged, denyOutputPaths ?? DENY_OUTPUT_PATHS)
11831
+ );
11593
11832
  };
11594
11833
  var processOutputAttachments = async (output) => {
11595
11834
  try {
@@ -13667,11 +13906,13 @@ function serializeInput(params) {
13667
13906
  if (params.config) {
13668
13907
  const config = tryToDict(params.config);
13669
13908
  if (config) {
13670
- const tools = serializeTools(params);
13671
- if (tools) {
13672
- config.tools = tools;
13673
- }
13674
- input.config = config;
13909
+ const filteredConfig = {};
13910
+ Object.keys(config).forEach((key) => {
13911
+ if (key !== "tools") {
13912
+ filteredConfig[key] = config[key];
13913
+ }
13914
+ });
13915
+ input.config = filteredConfig;
13675
13916
  }
13676
13917
  }
13677
13918
  return input;
@@ -13752,6 +13993,10 @@ function extractMetadata(params) {
13752
13993
  });
13753
13994
  }
13754
13995
  }
13996
+ const tools = serializeTools(params);
13997
+ if (tools) {
13998
+ metadata.tools = tools;
13999
+ }
13755
14000
  return metadata;
13756
14001
  }
13757
14002
  function extractGenerateContentMetrics(response, start) {
@@ -14789,7 +15034,7 @@ function unescapePath(path) {
14789
15034
  }
14790
15035
  var graph_framework_default = { createGraph };
14791
15036
 
14792
- // ../node_modules/async/dist/async.mjs
15037
+ // ../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
14793
15038
  function initialParams(fn) {
14794
15039
  return function(...args) {
14795
15040
  var callback = args.pop();
@@ -14914,6 +15159,7 @@ function isArrayLike(value) {
14914
15159
  return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
14915
15160
  }
14916
15161
  var breakLoop = {};
15162
+ var breakLoop$1 = breakLoop;
14917
15163
  function once(fn) {
14918
15164
  function wrapper(...args) {
14919
15165
  if (fn === null) return;
@@ -15005,7 +15251,7 @@ function asyncEachOfLimit(generator, limit, iteratee, callback) {
15005
15251
  canceled = true;
15006
15252
  return;
15007
15253
  }
15008
- if (result === breakLoop || done && running <= 0) {
15254
+ if (result === breakLoop$1 || done && running <= 0) {
15009
15255
  done = true;
15010
15256
  return callback(null);
15011
15257
  }
@@ -15048,7 +15294,7 @@ var eachOfLimit$2 = (limit) => {
15048
15294
  } else if (err === false) {
15049
15295
  done = true;
15050
15296
  canceled = true;
15051
- } else if (value === breakLoop || done && running <= 0) {
15297
+ } else if (value === breakLoop$1 || done && running <= 0) {
15052
15298
  done = true;
15053
15299
  return callback(null);
15054
15300
  } else if (!looping) {
@@ -15091,7 +15337,7 @@ function eachOfArrayLike(coll, iteratee, callback) {
15091
15337
  if (canceled === true) return;
15092
15338
  if (err) {
15093
15339
  callback(err);
15094
- } else if (++completed === length || value === breakLoop) {
15340
+ } else if (++completed === length || value === breakLoop$1) {
15095
15341
  callback(null);
15096
15342
  }
15097
15343
  }
@@ -15487,7 +15733,7 @@ function _createTester(check, getResult) {
15487
15733
  if (check(result) && !testResult) {
15488
15734
  testPassed = true;
15489
15735
  testResult = getResult(true, value);
15490
- return callback(null, breakLoop);
15736
+ return callback(null, breakLoop$1);
15491
15737
  }
15492
15738
  callback();
15493
15739
  });
@@ -16111,7 +16357,8 @@ var promptDefinitionSchema = promptContentsSchema.and(
16111
16357
  import_v310.z.object({
16112
16358
  model: import_v310.z.string(),
16113
16359
  params: ModelParams.optional(),
16114
- templateFormat: import_v310.z.enum(["mustache", "nunjucks", "none"]).optional()
16360
+ templateFormat: import_v310.z.enum(["mustache", "nunjucks", "none"]).optional(),
16361
+ environments: import_v310.z.array(import_v310.z.string()).optional()
16115
16362
  })
16116
16363
  );
16117
16364
  var promptDefinitionWithToolsSchema = promptDefinitionSchema.and(
@@ -16270,6 +16517,22 @@ function initExperiment2(state, options = {}) {
16270
16517
  setCurrent: false
16271
16518
  });
16272
16519
  }
16520
+ async function getExperimentParametersRef(parameters) {
16521
+ if (!parameters) {
16522
+ return void 0;
16523
+ }
16524
+ const resolvedParameters = parameters instanceof Promise ? await parameters : parameters;
16525
+ if (!RemoteEvalParameters.isParameters(resolvedParameters)) {
16526
+ return void 0;
16527
+ }
16528
+ if (resolvedParameters.id === void 0) {
16529
+ return void 0;
16530
+ }
16531
+ return {
16532
+ id: resolvedParameters.id,
16533
+ version: resolvedParameters.version
16534
+ };
16535
+ }
16273
16536
  function callEvaluatorData(data) {
16274
16537
  const dataResult = typeof data === "function" ? data() : data;
16275
16538
  let baseExperiment = void 0;
@@ -16336,6 +16599,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
16336
16599
  const { data, baseExperiment: defaultBaseExperiment } = callEvaluatorData(
16337
16600
  evaluator.data
16338
16601
  );
16602
+ const parameters = await getExperimentParametersRef(evaluator.parameters);
16339
16603
  const experiment = options.parent || options.noSendLogs ? null : initExperiment2(evaluator.state, {
16340
16604
  ...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
16341
16605
  experiment: evaluator.experimentName,
@@ -16348,7 +16612,8 @@ async function Eval(name, evaluator, reporterOrOpts) {
16348
16612
  baseExperimentId: evaluator.baseExperimentId,
16349
16613
  gitMetadataSettings: evaluator.gitMetadataSettings,
16350
16614
  repoInfo: evaluator.repoInfo,
16351
- dataset: Dataset2.isDataset(data) ? data : void 0
16615
+ dataset: Dataset2.isDataset(data) ? data : void 0,
16616
+ parameters
16352
16617
  });
16353
16618
  if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
16354
16619
  await experiment._waitForId();
@@ -16403,7 +16668,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
16403
16668
  if (experiment) {
16404
16669
  await experiment.flush().catch(console.error);
16405
16670
  } else if (options.parent) {
16406
- await flush().catch(console.error);
16671
+ await flush({ state: evaluator.state }).catch(console.error);
16407
16672
  }
16408
16673
  }
16409
16674
  } finally {
@@ -16791,6 +17056,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
16791
17056
  },
16792
17057
  Math.max(evaluator.maxConcurrency ?? Number.MAX_SAFE_INTEGER, 1)
16793
17058
  );
17059
+ const queueErrors = [];
16794
17060
  const enqueuePromise = (async () => {
16795
17061
  for await (const datum of dataIterable) {
16796
17062
  if (cancelled) {
@@ -16806,7 +17072,11 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
16806
17072
  }
16807
17073
  scheduledTrials++;
16808
17074
  progressReporter.setTotal?.(evaluator.evalName, scheduledTrials);
16809
- q.push({ datum, trialIndex });
17075
+ q.pushAsync({ datum, trialIndex }).catch((e) => {
17076
+ if (queueErrors.length < 5) {
17077
+ queueErrors.push(e);
17078
+ }
17079
+ });
16810
17080
  }
16811
17081
  }
16812
17082
  })();
@@ -16854,6 +17124,12 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
16854
17124
  })();
16855
17125
  try {
16856
17126
  await Promise.race([waitForQueue, cancel()]);
17127
+ if (queueErrors.length > 0) {
17128
+ throw new AggregateError(
17129
+ queueErrors,
17130
+ `Encountered ${queueErrors.length} unhandled task errors`
17131
+ );
17132
+ }
16857
17133
  } catch (e) {
16858
17134
  q.kill();
16859
17135
  if (e instanceof InternalAbortError) {
@@ -17257,6 +17533,7 @@ var CodePrompt = class {
17257
17533
  toolFunctions;
17258
17534
  tags;
17259
17535
  metadata;
17536
+ environmentSlugs;
17260
17537
  constructor(project, prompt, toolFunctions, opts, functionType) {
17261
17538
  this.project = project;
17262
17539
  this.name = opts.name;
@@ -17269,6 +17546,7 @@ var CodePrompt = class {
17269
17546
  this.functionType = functionType;
17270
17547
  this.tags = opts.tags;
17271
17548
  this.metadata = opts.metadata;
17549
+ this.environmentSlugs = opts.environments;
17272
17550
  }
17273
17551
  async toFunctionDefinition(projectNameToId) {
17274
17552
  const prompt_data = {
@@ -17303,7 +17581,8 @@ var CodePrompt = class {
17303
17581
  prompt_data,
17304
17582
  if_exists: this.ifExists,
17305
17583
  tags: this.tags,
17306
- metadata: this.metadata
17584
+ metadata: this.metadata,
17585
+ environments: this.environmentSlugs && this.environmentSlugs.length > 0 ? this.environmentSlugs.map((slug) => ({ slug })) : void 0
17307
17586
  };
17308
17587
  }
17309
17588
  };
@@ -18085,7 +18364,11 @@ function startSpanForEvent(config, event, channelName) {
18085
18364
  });
18086
18365
  const startTime = getCurrentUnixTimestamp();
18087
18366
  try {
18088
- const { input, metadata } = config.extractInput(event.arguments);
18367
+ const { input, metadata } = config.extractInput(
18368
+ event.arguments,
18369
+ event,
18370
+ span
18371
+ );
18089
18372
  span.log({
18090
18373
  input,
18091
18374
  metadata: mergeInputMetadata(metadata, spanInfoMetadata)
@@ -18249,6 +18532,16 @@ function traceStreamingChannel(channel2, config) {
18249
18532
  });
18250
18533
  return;
18251
18534
  }
18535
+ if (config.patchResult?.({
18536
+ channelName,
18537
+ endEvent: asyncEndEvent,
18538
+ result: asyncEndEvent.result,
18539
+ span,
18540
+ startTime
18541
+ })) {
18542
+ states.delete(event);
18543
+ return;
18544
+ }
18252
18545
  try {
18253
18546
  const output = config.extractOutput(
18254
18547
  asyncEndEvent.result,
@@ -18305,8 +18598,17 @@ function traceSyncStreamChannel(channel2, config) {
18305
18598
  return;
18306
18599
  }
18307
18600
  const { span, startTime } = spanData;
18308
- const resultEvent = event;
18309
- const stream = resultEvent.result;
18601
+ const endEvent = event;
18602
+ if (config.patchResult?.({
18603
+ channelName,
18604
+ endEvent,
18605
+ result: endEvent.result,
18606
+ span,
18607
+ startTime
18608
+ })) {
18609
+ return;
18610
+ }
18611
+ const stream = endEvent.result;
18310
18612
  if (!isSyncStreamLike(stream)) {
18311
18613
  span.end();
18312
18614
  states.delete(event);
@@ -18971,6 +19273,10 @@ var aiSDKChannels = defineChannels("ai", {
18971
19273
  channelName: "streamText",
18972
19274
  kind: "async"
18973
19275
  }),
19276
+ streamTextSync: channel({
19277
+ channelName: "streamText.sync",
19278
+ kind: "sync-stream"
19279
+ }),
18974
19280
  generateObject: channel({
18975
19281
  channelName: "generateObject",
18976
19282
  kind: "async"
@@ -18979,6 +19285,10 @@ var aiSDKChannels = defineChannels("ai", {
18979
19285
  channelName: "streamObject",
18980
19286
  kind: "async"
18981
19287
  }),
19288
+ streamObjectSync: channel({
19289
+ channelName: "streamObject.sync",
19290
+ kind: "sync-stream"
19291
+ }),
18982
19292
  agentGenerate: channel({
18983
19293
  channelName: "Agent.generate",
18984
19294
  kind: "async"
@@ -18986,6 +19296,14 @@ var aiSDKChannels = defineChannels("ai", {
18986
19296
  agentStream: channel({
18987
19297
  channelName: "Agent.stream",
18988
19298
  kind: "async"
19299
+ }),
19300
+ toolLoopAgentGenerate: channel({
19301
+ channelName: "ToolLoopAgent.generate",
19302
+ kind: "async"
19303
+ }),
19304
+ toolLoopAgentStream: channel({
19305
+ channelName: "ToolLoopAgent.stream",
19306
+ kind: "async"
18989
19307
  })
18990
19308
  });
18991
19309
 
@@ -19004,6 +19322,8 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
19004
19322
  "steps[].response.body",
19005
19323
  "steps[].response.headers"
19006
19324
  ];
19325
+ var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
19326
+ var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
19007
19327
  var AISDKPlugin = class extends BasePlugin {
19008
19328
  config;
19009
19329
  constructor(config = {}) {
@@ -19022,22 +19342,12 @@ var AISDKPlugin = class extends BasePlugin {
19022
19342
  traceStreamingChannel(aiSDKChannels.generateText, {
19023
19343
  name: "generateText",
19024
19344
  type: "llm" /* LLM */,
19025
- extractInput: ([params]) => {
19026
- return {
19027
- input: processAISDKInput(params),
19028
- metadata: extractMetadataFromParams(params)
19029
- };
19030
- },
19031
- extractOutput: (result) => {
19345
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19346
+ extractOutput: (result, endEvent) => {
19347
+ finalizeAISDKChildTracing(endEvent);
19032
19348
  return processAISDKOutput(result, denyOutputPaths);
19033
19349
  },
19034
- extractMetrics: (result, startTime) => {
19035
- const metrics = extractTokenMetrics2(result);
19036
- if (startTime) {
19037
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
19038
- }
19039
- return metrics;
19040
- },
19350
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
19041
19351
  aggregateChunks: aggregateAISDKChunks
19042
19352
  })
19043
19353
  );
@@ -19045,45 +19355,43 @@ var AISDKPlugin = class extends BasePlugin {
19045
19355
  traceStreamingChannel(aiSDKChannels.streamText, {
19046
19356
  name: "streamText",
19047
19357
  type: "llm" /* LLM */,
19048
- extractInput: ([params]) => {
19049
- return {
19050
- input: processAISDKInput(params),
19051
- metadata: extractMetadataFromParams(params)
19052
- };
19053
- },
19054
- extractOutput: (result) => {
19055
- return processAISDKOutput(result, denyOutputPaths);
19056
- },
19057
- extractMetrics: (result, startTime) => {
19058
- const metrics = extractTokenMetrics2(result);
19059
- if (startTime) {
19060
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
19061
- }
19062
- return metrics;
19063
- },
19064
- aggregateChunks: aggregateAISDKChunks
19358
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19359
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
19360
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
19361
+ aggregateChunks: aggregateAISDKChunks,
19362
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19363
+ denyOutputPaths,
19364
+ endEvent,
19365
+ result,
19366
+ span,
19367
+ startTime
19368
+ })
19369
+ })
19370
+ );
19371
+ this.unsubscribers.push(
19372
+ traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
19373
+ name: "streamText",
19374
+ type: "llm" /* LLM */,
19375
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19376
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19377
+ denyOutputPaths,
19378
+ endEvent,
19379
+ result,
19380
+ span,
19381
+ startTime
19382
+ })
19065
19383
  })
19066
19384
  );
19067
19385
  this.unsubscribers.push(
19068
19386
  traceStreamingChannel(aiSDKChannels.generateObject, {
19069
19387
  name: "generateObject",
19070
19388
  type: "llm" /* LLM */,
19071
- extractInput: ([params]) => {
19072
- return {
19073
- input: processAISDKInput(params),
19074
- metadata: extractMetadataFromParams(params)
19075
- };
19076
- },
19077
- extractOutput: (result) => {
19389
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19390
+ extractOutput: (result, endEvent) => {
19391
+ finalizeAISDKChildTracing(endEvent);
19078
19392
  return processAISDKOutput(result, denyOutputPaths);
19079
19393
  },
19080
- extractMetrics: (result, startTime) => {
19081
- const metrics = extractTokenMetrics2(result);
19082
- if (startTime) {
19083
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
19084
- }
19085
- return metrics;
19086
- },
19394
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
19087
19395
  aggregateChunks: aggregateAISDKChunks
19088
19396
  })
19089
19397
  );
@@ -19091,45 +19399,43 @@ var AISDKPlugin = class extends BasePlugin {
19091
19399
  traceStreamingChannel(aiSDKChannels.streamObject, {
19092
19400
  name: "streamObject",
19093
19401
  type: "llm" /* LLM */,
19094
- extractInput: ([params]) => {
19095
- return {
19096
- input: processAISDKInput(params),
19097
- metadata: extractMetadataFromParams(params)
19098
- };
19099
- },
19100
- extractOutput: (result) => {
19101
- return processAISDKOutput(result, denyOutputPaths);
19102
- },
19103
- extractMetrics: (result, startTime) => {
19104
- const metrics = extractTokenMetrics2(result);
19105
- if (startTime) {
19106
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
19107
- }
19108
- return metrics;
19109
- },
19110
- aggregateChunks: aggregateAISDKChunks
19402
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19403
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
19404
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
19405
+ aggregateChunks: aggregateAISDKChunks,
19406
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19407
+ denyOutputPaths,
19408
+ endEvent,
19409
+ result,
19410
+ span,
19411
+ startTime
19412
+ })
19413
+ })
19414
+ );
19415
+ this.unsubscribers.push(
19416
+ traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
19417
+ name: "streamObject",
19418
+ type: "llm" /* LLM */,
19419
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19420
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19421
+ denyOutputPaths,
19422
+ endEvent,
19423
+ result,
19424
+ span,
19425
+ startTime
19426
+ })
19111
19427
  })
19112
19428
  );
19113
19429
  this.unsubscribers.push(
19114
19430
  traceStreamingChannel(aiSDKChannels.agentGenerate, {
19115
19431
  name: "Agent.generate",
19116
19432
  type: "llm" /* LLM */,
19117
- extractInput: ([params]) => {
19118
- return {
19119
- input: processAISDKInput(params),
19120
- metadata: extractMetadataFromParams(params)
19121
- };
19122
- },
19123
- extractOutput: (result) => {
19433
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19434
+ extractOutput: (result, endEvent) => {
19435
+ finalizeAISDKChildTracing(endEvent);
19124
19436
  return processAISDKOutput(result, denyOutputPaths);
19125
19437
  },
19126
- extractMetrics: (result, startTime) => {
19127
- const metrics = extractTokenMetrics2(result);
19128
- if (startTime) {
19129
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
19130
- }
19131
- return metrics;
19132
- },
19438
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
19133
19439
  aggregateChunks: aggregateAISDKChunks
19134
19440
  })
19135
19441
  );
@@ -19137,52 +19443,470 @@ var AISDKPlugin = class extends BasePlugin {
19137
19443
  traceStreamingChannel(aiSDKChannels.agentStream, {
19138
19444
  name: "Agent.stream",
19139
19445
  type: "llm" /* LLM */,
19140
- extractInput: ([params]) => {
19141
- return {
19142
- input: processAISDKInput(params),
19143
- metadata: extractMetadataFromParams(params)
19144
- };
19145
- },
19146
- extractOutput: (result) => {
19446
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19447
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
19448
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
19449
+ aggregateChunks: aggregateAISDKChunks,
19450
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19451
+ denyOutputPaths,
19452
+ endEvent,
19453
+ result,
19454
+ span,
19455
+ startTime
19456
+ })
19457
+ })
19458
+ );
19459
+ this.unsubscribers.push(
19460
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
19461
+ name: "ToolLoopAgent.generate",
19462
+ type: "llm" /* LLM */,
19463
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19464
+ extractOutput: (result, endEvent) => {
19465
+ finalizeAISDKChildTracing(endEvent);
19147
19466
  return processAISDKOutput(result, denyOutputPaths);
19148
19467
  },
19149
- extractMetrics: (result, startTime) => {
19150
- const metrics = extractTokenMetrics2(result);
19151
- if (startTime) {
19152
- metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
19153
- }
19154
- return metrics;
19155
- },
19468
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
19156
19469
  aggregateChunks: aggregateAISDKChunks
19157
19470
  })
19158
19471
  );
19472
+ this.unsubscribers.push(
19473
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
19474
+ name: "ToolLoopAgent.stream",
19475
+ type: "llm" /* LLM */,
19476
+ extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
19477
+ extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
19478
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
19479
+ aggregateChunks: aggregateAISDKChunks,
19480
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
19481
+ denyOutputPaths,
19482
+ endEvent,
19483
+ result,
19484
+ span,
19485
+ startTime
19486
+ })
19487
+ })
19488
+ );
19159
19489
  }
19160
19490
  };
19161
19491
  function processAISDKInput(params) {
19162
19492
  if (!params) return params;
19163
- return processInputAttachments(params);
19493
+ const input = processInputAttachments(params);
19494
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
19495
+ return input;
19496
+ }
19497
+ const { tools: _tools, ...rest } = input;
19498
+ return rest;
19164
19499
  }
19165
- function extractMetadataFromParams(params) {
19500
+ function prepareAISDKInput(params, event, span, denyOutputPaths) {
19501
+ const input = processAISDKInput(params);
19502
+ const metadata = extractMetadataFromParams(params, event.self);
19503
+ const childTracing = prepareAISDKChildTracing(
19504
+ params,
19505
+ event.self,
19506
+ span,
19507
+ denyOutputPaths
19508
+ );
19509
+ event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
19510
+ if (childTracing.cleanup) {
19511
+ event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
19512
+ }
19513
+ return {
19514
+ input,
19515
+ metadata
19516
+ };
19517
+ }
19518
+ function extractTopLevelAISDKMetrics(result, event, startTime) {
19519
+ const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics2(result);
19520
+ if (startTime) {
19521
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
19522
+ }
19523
+ return metrics;
19524
+ }
19525
+ function hasModelChildTracing(event) {
19526
+ return event?.__braintrust_ai_sdk_model_wrapped === true;
19527
+ }
19528
+ function extractMetadataFromParams(params, self) {
19166
19529
  const metadata = {
19167
19530
  braintrust: {
19168
19531
  integration_name: "ai-sdk",
19169
19532
  sdk_language: "typescript"
19170
19533
  }
19171
19534
  };
19172
- const { model, provider } = serializeModelWithProvider2(params.model);
19535
+ 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;
19536
+ const { model, provider } = serializeModelWithProvider2(
19537
+ params.model ?? agentModel
19538
+ );
19173
19539
  if (model) {
19174
19540
  metadata.model = model;
19175
19541
  }
19176
19542
  if (provider) {
19177
19543
  metadata.provider = provider;
19178
19544
  }
19545
+ const tools = serializeAISDKToolsForLogging(params.tools);
19546
+ if (tools) {
19547
+ metadata.tools = tools;
19548
+ }
19179
19549
  return metadata;
19180
19550
  }
19551
+ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
19552
+ const cleanup = [];
19553
+ const patchedModels = /* @__PURE__ */ new WeakSet();
19554
+ const patchedTools = /* @__PURE__ */ new WeakSet();
19555
+ let modelWrapped = false;
19556
+ const patchModel = (model) => {
19557
+ const resolvedModel = resolveAISDKModel(model);
19558
+ if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
19559
+ return;
19560
+ }
19561
+ patchedModels.add(resolvedModel);
19562
+ resolvedModel[AUTO_PATCHED_MODEL] = true;
19563
+ modelWrapped = true;
19564
+ const originalDoGenerate = resolvedModel.doGenerate;
19565
+ const originalDoStream = resolvedModel.doStream;
19566
+ const baseMetadata = buildAISDKChildMetadata(resolvedModel);
19567
+ resolvedModel.doGenerate = async function doGeneratePatched(options) {
19568
+ return parentSpan.traced(
19569
+ async (span) => {
19570
+ const result = await Reflect.apply(
19571
+ originalDoGenerate,
19572
+ resolvedModel,
19573
+ [options]
19574
+ );
19575
+ span.log({
19576
+ output: processAISDKOutput(result, denyOutputPaths),
19577
+ metrics: extractTokenMetrics2(result),
19578
+ ...buildResolvedMetadataPayload(result)
19579
+ });
19580
+ return result;
19581
+ },
19582
+ {
19583
+ name: "doGenerate",
19584
+ spanAttributes: {
19585
+ type: "llm" /* LLM */
19586
+ },
19587
+ event: {
19588
+ input: processAISDKInput(options),
19589
+ metadata: baseMetadata
19590
+ }
19591
+ }
19592
+ );
19593
+ };
19594
+ if (originalDoStream) {
19595
+ resolvedModel.doStream = async function doStreamPatched(options) {
19596
+ const span = parentSpan.startSpan({
19597
+ name: "doStream",
19598
+ spanAttributes: {
19599
+ type: "llm" /* LLM */
19600
+ },
19601
+ event: {
19602
+ input: processAISDKInput(options),
19603
+ metadata: baseMetadata
19604
+ }
19605
+ });
19606
+ const result = await withCurrent(
19607
+ span,
19608
+ () => Reflect.apply(originalDoStream, resolvedModel, [options])
19609
+ );
19610
+ const output = {};
19611
+ let text = "";
19612
+ let reasoning = "";
19613
+ const toolCalls = [];
19614
+ let object = void 0;
19615
+ const transformStream = new TransformStream({
19616
+ transform(chunk, controller) {
19617
+ switch (chunk.type) {
19618
+ case "text-delta":
19619
+ text += extractTextDelta(chunk);
19620
+ break;
19621
+ case "reasoning-delta":
19622
+ if (chunk.delta) {
19623
+ reasoning += chunk.delta;
19624
+ } else if (chunk.text) {
19625
+ reasoning += chunk.text;
19626
+ }
19627
+ break;
19628
+ case "tool-call":
19629
+ toolCalls.push(chunk);
19630
+ break;
19631
+ case "object":
19632
+ object = chunk.object;
19633
+ break;
19634
+ case "raw":
19635
+ if (chunk.rawValue) {
19636
+ const rawVal = chunk.rawValue;
19637
+ if (rawVal.delta?.content) {
19638
+ text += rawVal.delta.content;
19639
+ } else if (rawVal.choices?.[0]?.delta?.content) {
19640
+ text += rawVal.choices[0].delta.content;
19641
+ } else if (typeof rawVal.text === "string") {
19642
+ text += rawVal.text;
19643
+ } else if (typeof rawVal.content === "string") {
19644
+ text += rawVal.content;
19645
+ }
19646
+ }
19647
+ break;
19648
+ case "finish":
19649
+ output.text = text;
19650
+ output.reasoning = reasoning;
19651
+ output.toolCalls = toolCalls;
19652
+ output.finishReason = chunk.finishReason;
19653
+ output.usage = chunk.usage;
19654
+ if (object !== void 0) {
19655
+ output.object = object;
19656
+ }
19657
+ span.log({
19658
+ output: processAISDKOutput(
19659
+ output,
19660
+ denyOutputPaths
19661
+ ),
19662
+ metrics: extractTokenMetrics2(output),
19663
+ ...buildResolvedMetadataPayload(output)
19664
+ });
19665
+ span.end();
19666
+ break;
19667
+ }
19668
+ controller.enqueue(chunk);
19669
+ }
19670
+ });
19671
+ return {
19672
+ ...result,
19673
+ stream: result.stream.pipeThrough(transformStream)
19674
+ };
19675
+ };
19676
+ }
19677
+ cleanup.push(() => {
19678
+ resolvedModel.doGenerate = originalDoGenerate;
19679
+ if (originalDoStream) {
19680
+ resolvedModel.doStream = originalDoStream;
19681
+ }
19682
+ delete resolvedModel[AUTO_PATCHED_MODEL];
19683
+ });
19684
+ };
19685
+ const patchTool = (tool, name) => {
19686
+ if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
19687
+ return;
19688
+ }
19689
+ patchedTools.add(tool);
19690
+ tool[AUTO_PATCHED_TOOL] = true;
19691
+ const originalExecute = tool.execute;
19692
+ tool.execute = function executePatched(...args) {
19693
+ const result = Reflect.apply(originalExecute, this, args);
19694
+ if (isAsyncGenerator3(result)) {
19695
+ return (async function* () {
19696
+ const span = parentSpan.startSpan({
19697
+ name,
19698
+ spanAttributes: {
19699
+ type: "tool" /* TOOL */
19700
+ }
19701
+ });
19702
+ span.log({ input: args.length === 1 ? args[0] : args });
19703
+ try {
19704
+ let lastValue;
19705
+ for await (const value of result) {
19706
+ lastValue = value;
19707
+ yield value;
19708
+ }
19709
+ span.log({ output: lastValue });
19710
+ } catch (error) {
19711
+ span.log({
19712
+ error: error instanceof Error ? error.message : String(error)
19713
+ });
19714
+ throw error;
19715
+ } finally {
19716
+ span.end();
19717
+ }
19718
+ })();
19719
+ }
19720
+ return parentSpan.traced(
19721
+ async (span) => {
19722
+ span.log({ input: args.length === 1 ? args[0] : args });
19723
+ const awaitedResult = await result;
19724
+ span.log({ output: awaitedResult });
19725
+ return awaitedResult;
19726
+ },
19727
+ {
19728
+ name,
19729
+ spanAttributes: {
19730
+ type: "tool" /* TOOL */
19731
+ }
19732
+ }
19733
+ );
19734
+ };
19735
+ cleanup.push(() => {
19736
+ tool.execute = originalExecute;
19737
+ delete tool[AUTO_PATCHED_TOOL];
19738
+ });
19739
+ };
19740
+ const patchTools = (tools) => {
19741
+ if (!tools) {
19742
+ return;
19743
+ }
19744
+ const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
19745
+ if (Array.isArray(tools)) {
19746
+ tools.forEach(
19747
+ (tool, index) => patchTool(tool, inferName(tool, `tool[${index}]`))
19748
+ );
19749
+ return;
19750
+ }
19751
+ for (const [key, tool] of Object.entries(tools)) {
19752
+ patchTool(tool, key);
19753
+ }
19754
+ };
19755
+ if (params && typeof params === "object") {
19756
+ patchModel(params.model);
19757
+ patchTools(params.tools);
19758
+ }
19759
+ if (self && typeof self === "object") {
19760
+ const selfRecord = self;
19761
+ if (selfRecord.model !== void 0) {
19762
+ patchModel(selfRecord.model);
19763
+ }
19764
+ if (selfRecord.settings && typeof selfRecord.settings === "object") {
19765
+ if (selfRecord.settings.model !== void 0) {
19766
+ patchModel(selfRecord.settings.model);
19767
+ }
19768
+ if (selfRecord.settings.tools !== void 0) {
19769
+ patchTools(selfRecord.settings.tools);
19770
+ }
19771
+ }
19772
+ }
19773
+ return {
19774
+ cleanup: cleanup.length > 0 ? () => {
19775
+ while (cleanup.length > 0) {
19776
+ cleanup.pop()?.();
19777
+ }
19778
+ } : void 0,
19779
+ modelWrapped
19780
+ };
19781
+ }
19782
+ function finalizeAISDKChildTracing(event) {
19783
+ const cleanup = event?.__braintrust_ai_sdk_cleanup;
19784
+ if (event && typeof cleanup === "function") {
19785
+ cleanup();
19786
+ delete event.__braintrust_ai_sdk_cleanup;
19787
+ }
19788
+ }
19789
+ function patchAISDKStreamingResult(args) {
19790
+ const { denyOutputPaths, endEvent, result, span, startTime } = args;
19791
+ if (!result || typeof result !== "object") {
19792
+ return false;
19793
+ }
19794
+ const resultRecord = result;
19795
+ if (!isReadableStreamLike(resultRecord.baseStream)) {
19796
+ return false;
19797
+ }
19798
+ let firstChunkTime;
19799
+ const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
19800
+ new TransformStream({
19801
+ transform(chunk, controller) {
19802
+ if (firstChunkTime === void 0) {
19803
+ firstChunkTime = getCurrentUnixTimestamp();
19804
+ }
19805
+ controller.enqueue(chunk);
19806
+ },
19807
+ async flush() {
19808
+ const metrics = extractTopLevelAISDKMetrics(result, endEvent);
19809
+ if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
19810
+ metrics.time_to_first_token = firstChunkTime - startTime;
19811
+ }
19812
+ const output = await processAISDKStreamingOutput(
19813
+ result,
19814
+ denyOutputPaths
19815
+ );
19816
+ const metadata = buildResolvedMetadataPayload(result).metadata;
19817
+ span.log({
19818
+ output,
19819
+ ...metadata ? { metadata } : {},
19820
+ metrics
19821
+ });
19822
+ finalizeAISDKChildTracing(endEvent);
19823
+ span.end();
19824
+ }
19825
+ })
19826
+ );
19827
+ Object.defineProperty(resultRecord, "baseStream", {
19828
+ configurable: true,
19829
+ enumerable: true,
19830
+ value: wrappedBaseStream,
19831
+ writable: true
19832
+ });
19833
+ return true;
19834
+ }
19835
+ function isReadableStreamLike(value) {
19836
+ return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
19837
+ }
19838
+ async function processAISDKStreamingOutput(result, denyOutputPaths) {
19839
+ const output = processAISDKOutput(result, denyOutputPaths);
19840
+ if (!output || typeof output !== "object") {
19841
+ return output;
19842
+ }
19843
+ const outputRecord = output;
19844
+ try {
19845
+ if ("text" in result && typeof result.text === "string") {
19846
+ outputRecord.text = result.text;
19847
+ }
19848
+ } catch {
19849
+ }
19850
+ try {
19851
+ if ("object" in result) {
19852
+ const resolvedObject = await Promise.resolve(result.object);
19853
+ if (resolvedObject !== void 0) {
19854
+ outputRecord.object = resolvedObject;
19855
+ }
19856
+ }
19857
+ } catch {
19858
+ }
19859
+ return outputRecord;
19860
+ }
19861
+ function buildAISDKChildMetadata(model) {
19862
+ const { model: modelId, provider } = serializeModelWithProvider2(model);
19863
+ return {
19864
+ ...modelId ? { model: modelId } : {},
19865
+ ...provider ? { provider } : {},
19866
+ braintrust: {
19867
+ integration_name: "ai-sdk",
19868
+ sdk_language: "typescript"
19869
+ }
19870
+ };
19871
+ }
19872
+ function buildResolvedMetadataPayload(result) {
19873
+ const gatewayInfo = extractGatewayRoutingInfo2(result);
19874
+ const metadata = {};
19875
+ if (gatewayInfo?.provider) {
19876
+ metadata.provider = gatewayInfo.provider;
19877
+ }
19878
+ if (gatewayInfo?.model) {
19879
+ metadata.model = gatewayInfo.model;
19880
+ }
19881
+ if (result.finishReason !== void 0) {
19882
+ metadata.finish_reason = result.finishReason;
19883
+ }
19884
+ return Object.keys(metadata).length > 0 ? { metadata } : {};
19885
+ }
19886
+ function resolveAISDKModel(model) {
19887
+ if (typeof model !== "string") {
19888
+ return model;
19889
+ }
19890
+ const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? null;
19891
+ if (provider && typeof provider.languageModel === "function") {
19892
+ return provider.languageModel(model);
19893
+ }
19894
+ return model;
19895
+ }
19896
+ function extractTextDelta(chunk) {
19897
+ if (typeof chunk.textDelta === "string") return chunk.textDelta;
19898
+ if (typeof chunk.delta === "string") return chunk.delta;
19899
+ if (typeof chunk.text === "string") return chunk.text;
19900
+ if (typeof chunk.content === "string") return chunk.content;
19901
+ return "";
19902
+ }
19903
+ function isAsyncGenerator3(value) {
19904
+ return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
19905
+ }
19181
19906
  function processAISDKOutput(output, denyOutputPaths) {
19182
19907
  if (!output) return output;
19183
- const getterValues = extractGetterValues2(output);
19184
- const merged = { ...output, ...getterValues };
19185
- return omit2(merged, denyOutputPaths);
19908
+ const merged = extractSerializableOutputFields(output);
19909
+ return normalizeAISDKLoggedOutput(omit2(merged, denyOutputPaths));
19186
19910
  }
19187
19911
  function extractTokenMetrics2(result) {
19188
19912
  const metrics = {};
@@ -19232,12 +19956,14 @@ function extractTokenMetrics2(result) {
19232
19956
  }
19233
19957
  return metrics;
19234
19958
  }
19235
- function aggregateAISDKChunks(chunks) {
19959
+ function aggregateAISDKChunks(chunks, _result, endEvent) {
19236
19960
  const lastChunk = chunks[chunks.length - 1];
19237
19961
  const output = {};
19238
19962
  let metrics = {};
19963
+ let metadata;
19239
19964
  if (lastChunk) {
19240
- metrics = extractTokenMetrics2(lastChunk);
19965
+ metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics2(lastChunk);
19966
+ metadata = buildResolvedMetadataPayload(lastChunk).metadata;
19241
19967
  if (lastChunk.text !== void 0) {
19242
19968
  output.text = lastChunk.text;
19243
19969
  }
@@ -19251,7 +19977,8 @@ function aggregateAISDKChunks(chunks) {
19251
19977
  output.toolCalls = lastChunk.toolCalls;
19252
19978
  }
19253
19979
  }
19254
- return { output, metrics };
19980
+ finalizeAISDKChildTracing(endEvent);
19981
+ return { output, metrics, metadata };
19255
19982
  }
19256
19983
  function extractGetterValues2(obj) {
19257
19984
  const getterValues = {};
@@ -19271,7 +19998,7 @@ function extractGetterValues2(obj) {
19271
19998
  ];
19272
19999
  for (const name of getterNames) {
19273
20000
  try {
19274
- if (obj && name in obj && typeof obj[name] !== "function") {
20001
+ if (obj && name in obj && isSerializableOutputValue(obj[name])) {
19275
20002
  getterValues[name] = obj[name];
19276
20003
  }
19277
20004
  } catch {
@@ -19279,6 +20006,47 @@ function extractGetterValues2(obj) {
19279
20006
  }
19280
20007
  return getterValues;
19281
20008
  }
20009
+ function extractSerializableOutputFields(output) {
20010
+ const serialized = {};
20011
+ const directFieldNames = [
20012
+ "steps",
20013
+ "request",
20014
+ "responseMessages",
20015
+ "warnings",
20016
+ "rawResponse",
20017
+ "response",
20018
+ "providerMetadata",
20019
+ "experimental_providerMetadata"
20020
+ ];
20021
+ for (const name of directFieldNames) {
20022
+ try {
20023
+ const value = output?.[name];
20024
+ if (isSerializableOutputValue(value)) {
20025
+ serialized[name] = value;
20026
+ }
20027
+ } catch {
20028
+ }
20029
+ }
20030
+ return {
20031
+ ...serialized,
20032
+ ...extractGetterValues2(output)
20033
+ };
20034
+ }
20035
+ function isSerializableOutputValue(value) {
20036
+ if (typeof value === "function") {
20037
+ return false;
20038
+ }
20039
+ if (value && typeof value === "object" && typeof value.then === "function") {
20040
+ return false;
20041
+ }
20042
+ if (value && typeof value === "object" && typeof value.getReader === "function") {
20043
+ return false;
20044
+ }
20045
+ if (value && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function") {
20046
+ return false;
20047
+ }
20048
+ return true;
20049
+ }
19282
20050
  function serializeModelWithProvider2(model) {
19283
20051
  const modelId = typeof model === "string" ? model : model?.modelId;
19284
20052
  const explicitProvider = typeof model === "object" ? model?.provider : void 0;
@@ -19304,6 +20072,25 @@ function parseGatewayModelString2(modelString) {
19304
20072
  }
19305
20073
  return { model: modelString };
19306
20074
  }
20075
+ function extractGatewayRoutingInfo2(result) {
20076
+ if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
20077
+ const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
20078
+ if (routing2) {
20079
+ return {
20080
+ provider: routing2.resolvedProvider || routing2.finalProvider,
20081
+ model: routing2.resolvedProviderApiModelId
20082
+ };
20083
+ }
20084
+ }
20085
+ const routing = result?.providerMetadata?.gateway?.routing;
20086
+ if (routing) {
20087
+ return {
20088
+ provider: routing.resolvedProvider || routing.finalProvider,
20089
+ model: routing.resolvedProviderApiModelId
20090
+ };
20091
+ }
20092
+ return null;
20093
+ }
19307
20094
  function extractCostFromResult2(result) {
19308
20095
  if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
19309
20096
  let totalCost = 0;