braintrust 3.23.0 → 3.24.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 (51) hide show
  1. package/dev/dist/index.d.mts +6 -0
  2. package/dev/dist/index.d.ts +6 -0
  3. package/dev/dist/index.js +902 -588
  4. package/dev/dist/index.mjs +320 -6
  5. package/dist/apply-auto-instrumentation.js +211 -189
  6. package/dist/apply-auto-instrumentation.mjs +23 -1
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +40 -0
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +40 -0
  10. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +40 -0
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +40 -0
  14. package/dist/auto-instrumentations/bundler/vite.d.mts +1 -1
  15. package/dist/auto-instrumentations/bundler/vite.d.ts +1 -1
  16. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  17. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +40 -0
  18. package/dist/auto-instrumentations/bundler/webpack.cjs +40 -0
  19. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  20. package/dist/auto-instrumentations/{chunk-KIMLYPRW.mjs → chunk-BURMPO7L.mjs} +1 -1
  21. package/dist/auto-instrumentations/{chunk-YXLNSAMJ.mjs → chunk-F43DNLPD.mjs} +40 -0
  22. package/dist/auto-instrumentations/{chunk-EXY7QCJD.mjs → chunk-GSZHTAQW.mjs} +1 -1
  23. package/dist/auto-instrumentations/hook.mjs +150 -1
  24. package/dist/auto-instrumentations/index.cjs +40 -0
  25. package/dist/auto-instrumentations/index.mjs +1 -1
  26. package/dist/browser.d.mts +131 -9
  27. package/dist/browser.d.ts +131 -9
  28. package/dist/browser.js +703 -67
  29. package/dist/browser.mjs +703 -67
  30. package/dist/{chunk-CDIKAHDZ.js → chunk-7AUY2XWX.js} +21 -1
  31. package/dist/{chunk-36IPYKMG.mjs → chunk-7F6GCRHH.mjs} +20 -0
  32. package/dist/{chunk-FZWPFCVE.js → chunk-SU6EHKJV.js} +1085 -801
  33. package/dist/{chunk-IXL4PMY4.mjs → chunk-XE5FS7QY.mjs} +291 -7
  34. package/dist/cli.js +328 -10
  35. package/dist/edge-light.js +703 -67
  36. package/dist/edge-light.mjs +703 -67
  37. package/dist/index.d.mts +131 -9
  38. package/dist/index.d.ts +131 -9
  39. package/dist/index.js +891 -532
  40. package/dist/index.mjs +423 -64
  41. package/dist/instrumentation/index.d.mts +130 -9
  42. package/dist/instrumentation/index.d.ts +130 -9
  43. package/dist/instrumentation/index.js +601 -67
  44. package/dist/instrumentation/index.mjs +601 -67
  45. package/dist/vitest-evals-reporter.js +17 -16
  46. package/dist/vitest-evals-reporter.mjs +3 -2
  47. package/dist/workerd.js +703 -67
  48. package/dist/workerd.mjs +703 -67
  49. package/package.json +3 -3
  50. package/util/dist/index.js +4 -0
  51. package/util/dist/index.mjs +4 -0
package/dist/browser.js CHANGED
@@ -222,6 +222,7 @@ var DefaultChannel = class {
222
222
  constructor(name) {
223
223
  this.name = name;
224
224
  }
225
+ name;
225
226
  hasSubscribers = false;
226
227
  subscribe(_subscription) {
227
228
  }
@@ -1278,6 +1279,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1278
1279
  constructor(data) {
1279
1280
  this.data = data;
1280
1281
  }
1282
+ data;
1281
1283
  toStr() {
1282
1284
  const jsonObj = {
1283
1285
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1785,6 +1787,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1785
1787
  constructor(data) {
1786
1788
  this.data = data;
1787
1789
  }
1790
+ data;
1788
1791
  toStr() {
1789
1792
  const jsonObj = {
1790
1793
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -5018,6 +5021,97 @@ var SpanCache = class {
5018
5021
  }
5019
5022
  };
5020
5023
 
5024
+ // src/span-origin.ts
5025
+ var SDK_VERSION = true ? "3.24.0" : "0.0.0";
5026
+ function detectSpanOriginEnvironment(explicit) {
5027
+ if (explicit) return explicit;
5028
+ const envType = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_TYPE");
5029
+ const envName = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_NAME");
5030
+ if (envType || envName) {
5031
+ return {
5032
+ ...envType ? { type: envType } : {},
5033
+ ...envName ? { name: envName } : {}
5034
+ };
5035
+ }
5036
+ const ci = firstPresent([
5037
+ ["GITHUB_ACTIONS", "github_actions"],
5038
+ ["GITLAB_CI", "gitlab_ci"],
5039
+ ["CIRCLECI", "circleci"],
5040
+ ["BUILDKITE", "buildkite"],
5041
+ ["JENKINS_URL", "jenkins"],
5042
+ ["JENKINS_HOME", "jenkins"],
5043
+ ["TF_BUILD", "azure_pipelines"],
5044
+ ["TEAMCITY_VERSION", "teamcity"],
5045
+ ["TRAVIS", "travis"],
5046
+ ["BITBUCKET_BUILD_NUMBER", "bitbucket"]
5047
+ ]);
5048
+ if (ci) return { type: "ci", name: ci };
5049
+ if (isomorph_default.getEnv("CI")) return { type: "ci", name: "ci" };
5050
+ const earlyServer = firstPresent([
5051
+ ["VERCEL", "vercel"],
5052
+ ["NETLIFY", "netlify"]
5053
+ ]);
5054
+ if (earlyServer) return { type: "server", name: earlyServer };
5055
+ if (isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI") || isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI_V4")) {
5056
+ return { type: "server", name: "ecs" };
5057
+ }
5058
+ const awsExecutionEnv = isomorph_default.getEnv("AWS_EXECUTION_ENV");
5059
+ if (awsExecutionEnv?.startsWith("AWS_ECS_")) {
5060
+ return { type: "server", name: "ecs" };
5061
+ }
5062
+ if (awsExecutionEnv?.startsWith("AWS_Lambda_")) {
5063
+ return { type: "server", name: "aws_lambda" };
5064
+ }
5065
+ if (isomorph_default.getEnv("AWS_LAMBDA_FUNCTION_NAME")) {
5066
+ return { type: "server", name: "aws_lambda" };
5067
+ }
5068
+ const server = firstPresent([
5069
+ ["K_SERVICE", "cloud_run"],
5070
+ ["FUNCTION_TARGET", "gcp_functions"],
5071
+ ["KUBERNETES_SERVICE_HOST", "kubernetes"],
5072
+ ["DYNO", "heroku"],
5073
+ ["FLY_APP_NAME", "fly"],
5074
+ ["RAILWAY_ENVIRONMENT", "railway"],
5075
+ ["RENDER_SERVICE_NAME", "render"]
5076
+ ]);
5077
+ if (server) return { type: "server", name: server };
5078
+ return deploymentModeEnvironment("NODE_ENV", isomorph_default.getEnv("NODE_ENV"));
5079
+ }
5080
+ function makeSpanOrigin(instrumentationName, environment) {
5081
+ return {
5082
+ name: "braintrust.sdk.javascript",
5083
+ version: SDK_VERSION,
5084
+ instrumentation: { name: instrumentationName },
5085
+ ...environment ? { environment } : {}
5086
+ };
5087
+ }
5088
+ function mergeSpanOriginContext(context, instrumentationName, environment) {
5089
+ const next = { ...context ?? {} };
5090
+ const current = isObject2(next.span_origin) ? { ...next.span_origin } : {};
5091
+ next.span_origin = {
5092
+ ...makeSpanOrigin(instrumentationName, environment),
5093
+ ...current
5094
+ };
5095
+ return next;
5096
+ }
5097
+ function firstPresent(entries) {
5098
+ return entries.find(([key]) => Boolean(isomorph_default.getEnv(key)))?.[1];
5099
+ }
5100
+ function deploymentModeEnvironment(_key, value) {
5101
+ if (!value) return void 0;
5102
+ const normalized = value.toLowerCase();
5103
+ if (normalized === "production" || normalized === "staging") {
5104
+ return { type: "server", name: normalized };
5105
+ }
5106
+ if (normalized === "development" || normalized === "local") {
5107
+ return { type: "local", name: normalized };
5108
+ }
5109
+ return { name: value };
5110
+ }
5111
+ function isObject2(value) {
5112
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5113
+ }
5114
+
5021
5115
  // src/logger.ts
5022
5116
  var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
5023
5117
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
@@ -5066,6 +5160,7 @@ var LoginInvalidOrgError = class extends Error {
5066
5160
  super(message);
5067
5161
  this.message = message;
5068
5162
  }
5163
+ message;
5069
5164
  };
5070
5165
  var REDACTION_FIELDS = [
5071
5166
  "input",
@@ -5081,6 +5176,8 @@ var MaskingError = class {
5081
5176
  this.fieldName = fieldName;
5082
5177
  this.errorType = errorType;
5083
5178
  }
5179
+ fieldName;
5180
+ errorType;
5084
5181
  get errorMsg() {
5085
5182
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
5086
5183
  }
@@ -5290,7 +5387,9 @@ var BraintrustState = class _BraintrustState {
5290
5387
  diskCache: parametersDiskCache
5291
5388
  });
5292
5389
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5390
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5293
5391
  }
5392
+ loginParams;
5294
5393
  id;
5295
5394
  currentExperiment;
5296
5395
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5325,6 +5424,7 @@ var BraintrustState = class _BraintrustState {
5325
5424
  _idGenerator = null;
5326
5425
  _contextManager = null;
5327
5426
  _otelFlushCallback = null;
5427
+ spanOriginEnvironment;
5328
5428
  resetLoginInfo() {
5329
5429
  this.appUrl = null;
5330
5430
  this.appPublicUrl = null;
@@ -7943,6 +8043,7 @@ function initLogger(options = {}) {
7943
8043
  orgName,
7944
8044
  forceLogin,
7945
8045
  debugLogLevel,
8046
+ environment,
7946
8047
  fetch: fetch2,
7947
8048
  state: stateArg
7948
8049
  } = options || {};
@@ -7959,6 +8060,7 @@ function initLogger(options = {}) {
7959
8060
  };
7960
8061
  const state = stateArg ?? _globalState;
7961
8062
  state.setDebugLogLevel(debugLogLevel);
8063
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7962
8064
  state.enforceQueueSizeLimit(true);
7963
8065
  const lazyMetadata = new LazyValue(
7964
8066
  async () => {
@@ -9150,6 +9252,11 @@ var ObjectFetcher = class {
9150
9252
  this._internal_btql = _internal_btql;
9151
9253
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
9152
9254
  }
9255
+ objectType;
9256
+ pinnedVersion;
9257
+ mutateRecord;
9258
+ _internal_btql;
9259
+ _internalBrainstoreRealtime;
9153
9260
  _fetchedData = void 0;
9154
9261
  get id() {
9155
9262
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -9588,6 +9695,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9588
9695
  this.state = state;
9589
9696
  this.lazyMetadata = lazyMetadata;
9590
9697
  }
9698
+ state;
9699
+ lazyMetadata;
9591
9700
  get id() {
9592
9701
  return (async () => {
9593
9702
  return (await this.lazyMetadata.get()).experiment.id;
@@ -9710,7 +9819,11 @@ var SpanImpl = class _SpanImpl {
9710
9819
  metrics: {
9711
9820
  start: args.startTime ?? getCurrentUnixTimestamp()
9712
9821
  },
9713
- context: { ...callerLocation },
9822
+ context: mergeSpanOriginContext(
9823
+ { ...callerLocation },
9824
+ "braintrust-js-logger",
9825
+ this._state.spanOriginEnvironment
9826
+ ),
9714
9827
  span_attributes: {
9715
9828
  name,
9716
9829
  type,
@@ -10084,6 +10197,7 @@ var Dataset2 = class extends ObjectFetcher {
10084
10197
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
10085
10198
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
10086
10199
  }
10200
+ state;
10087
10201
  lazyMetadata;
10088
10202
  __braintrust_dataset_marker = true;
10089
10203
  newRecords = 0;
@@ -10598,6 +10712,9 @@ var Prompt2 = class _Prompt {
10598
10712
  this.noTrace = noTrace;
10599
10713
  void this.__braintrust_prompt_marker;
10600
10714
  }
10715
+ metadata;
10716
+ defaults;
10717
+ noTrace;
10601
10718
  parsedPromptData;
10602
10719
  hasParsedPromptData = false;
10603
10720
  __braintrust_prompt_marker = true;
@@ -10835,6 +10952,7 @@ var RemoteEvalParameters = class {
10835
10952
  this.metadata = metadata;
10836
10953
  void this.__braintrust_parameters_marker;
10837
10954
  }
10955
+ metadata;
10838
10956
  __braintrust_parameters_marker = true;
10839
10957
  get id() {
10840
10958
  return this.metadata.id;
@@ -15300,6 +15418,24 @@ var aiSDKChannels = defineChannels("ai", {
15300
15418
  kind: "sync-stream"
15301
15419
  })
15302
15420
  });
15421
+ var harnessAgentChannels = defineChannels("@ai-sdk/harness", {
15422
+ generate: channel({
15423
+ channelName: "HarnessAgent.generate",
15424
+ kind: "async"
15425
+ }),
15426
+ stream: channel({
15427
+ channelName: "HarnessAgent.stream",
15428
+ kind: "async"
15429
+ }),
15430
+ continueGenerate: channel({
15431
+ channelName: "HarnessAgent.continueGenerate",
15432
+ kind: "async"
15433
+ }),
15434
+ continueStream: channel({
15435
+ channelName: "HarnessAgent.continueStream",
15436
+ kind: "async"
15437
+ })
15438
+ });
15303
15439
 
15304
15440
  // src/instrumentation/plugins/ai-sdk-plugin.ts
15305
15441
  var DEFAULT_DENY_OUTPUT_PATHS = [
@@ -15568,6 +15704,84 @@ var AISDKPlugin = class extends BasePlugin {
15568
15704
  })
15569
15705
  })
15570
15706
  );
15707
+ this.unsubscribers.push(
15708
+ traceStreamingChannel(harnessAgentChannels.generate, {
15709
+ name: "HarnessAgent.generate",
15710
+ type: "task" /* TASK */,
15711
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15712
+ extractOutput: (result, endEvent) => processAISDKOutput(
15713
+ result,
15714
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15715
+ ),
15716
+ extractMetrics: (result) => extractTokenMetrics(result),
15717
+ aggregateChunks: aggregateAISDKChunks
15718
+ })
15719
+ );
15720
+ this.unsubscribers.push(
15721
+ traceStreamingChannel(harnessAgentChannels.stream, {
15722
+ name: "HarnessAgent.stream",
15723
+ type: "task" /* TASK */,
15724
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15725
+ extractOutput: (result, endEvent) => processAISDKOutput(
15726
+ result,
15727
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15728
+ ),
15729
+ extractMetrics: (result, startTime) => ({
15730
+ ...extractTokenMetrics(result),
15731
+ ...startTime === void 0 ? {} : {
15732
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15733
+ }
15734
+ }),
15735
+ aggregateChunks: aggregateAISDKChunks,
15736
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15737
+ defaultDenyOutputPaths: denyOutputPaths,
15738
+ endEvent,
15739
+ result,
15740
+ resolvePromiseUsage: true,
15741
+ span,
15742
+ startTime
15743
+ })
15744
+ })
15745
+ );
15746
+ this.unsubscribers.push(
15747
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
15748
+ name: "HarnessAgent.continueGenerate",
15749
+ type: "task" /* TASK */,
15750
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15751
+ extractOutput: (result, endEvent) => processAISDKOutput(
15752
+ result,
15753
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15754
+ ),
15755
+ extractMetrics: (result) => extractTokenMetrics(result),
15756
+ aggregateChunks: aggregateAISDKChunks
15757
+ })
15758
+ );
15759
+ this.unsubscribers.push(
15760
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
15761
+ name: "HarnessAgent.continueStream",
15762
+ type: "task" /* TASK */,
15763
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15764
+ extractOutput: (result, endEvent) => processAISDKOutput(
15765
+ result,
15766
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15767
+ ),
15768
+ extractMetrics: (result, startTime) => ({
15769
+ ...extractTokenMetrics(result),
15770
+ ...startTime === void 0 ? {} : {
15771
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15772
+ }
15773
+ }),
15774
+ aggregateChunks: aggregateAISDKChunks,
15775
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15776
+ defaultDenyOutputPaths: denyOutputPaths,
15777
+ endEvent,
15778
+ result,
15779
+ resolvePromiseUsage: true,
15780
+ span,
15781
+ startTime
15782
+ })
15783
+ })
15784
+ );
15571
15785
  this.unsubscribers.push(
15572
15786
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
15573
15787
  name: "ToolLoopAgent.generate",
@@ -16098,6 +16312,45 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
16098
16312
  metadata
16099
16313
  };
16100
16314
  }
16315
+ function prepareAISDKHarnessAgentInput(params, self) {
16316
+ if (isObject(self)) {
16317
+ try {
16318
+ if (isObject(self.settings)) {
16319
+ const settings = self.settings;
16320
+ if (settings.telemetry === void 0) {
16321
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
16322
+ }
16323
+ }
16324
+ } catch {
16325
+ }
16326
+ }
16327
+ const selectedInput = {};
16328
+ if (params.prompt !== void 0) {
16329
+ selectedInput.prompt = params.prompt;
16330
+ }
16331
+ if (params.messages !== void 0) {
16332
+ selectedInput.messages = params.messages;
16333
+ }
16334
+ if (params.toolApprovalContinuations !== void 0) {
16335
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
16336
+ }
16337
+ const metadata = extractMetadataFromCallParams({}, self);
16338
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
16339
+ metadata.sessionId = params.session.sessionId;
16340
+ }
16341
+ if (isObject(self)) {
16342
+ if (typeof self.harnessId === "string") {
16343
+ metadata.harnessId = self.harnessId;
16344
+ }
16345
+ if (typeof self.permissionMode === "string") {
16346
+ metadata.permissionMode = self.permissionMode;
16347
+ }
16348
+ }
16349
+ return {
16350
+ input: processAISDKCallInput(selectedInput).input,
16351
+ metadata
16352
+ };
16353
+ }
16101
16354
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
16102
16355
  registerWorkflowAgentWrapperSpan(span);
16103
16356
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -16945,6 +17198,7 @@ function patchAISDKStreamingResult(args) {
16945
17198
  endEvent,
16946
17199
  onComplete,
16947
17200
  result,
17201
+ resolvePromiseUsage,
16948
17202
  span,
16949
17203
  startTime
16950
17204
  } = args;
@@ -16971,6 +17225,22 @@ function patchAISDKStreamingResult(args) {
16971
17225
  outputLogged = true;
16972
17226
  try {
16973
17227
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
17228
+ if (resolvePromiseUsage) {
17229
+ try {
17230
+ const resultRecord2 = result;
17231
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
17232
+ if (isPromiseLike(pendingUsage)) {
17233
+ const usage = await Promise.resolve(pendingUsage);
17234
+ if (isObject(usage)) {
17235
+ Object.assign(
17236
+ metrics,
17237
+ extractTokenMetrics({ usage })
17238
+ );
17239
+ }
17240
+ }
17241
+ } catch {
17242
+ }
17243
+ }
16974
17244
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
16975
17245
  metrics.time_to_first_token = firstChunkTime - startTime;
16976
17246
  }
@@ -18201,8 +18471,6 @@ function filterSerializableOptions(options) {
18201
18471
  "additionalDirectories",
18202
18472
  "permissionMode",
18203
18473
  "debug",
18204
- "apiKey",
18205
- "apiKeySource",
18206
18474
  "agentName",
18207
18475
  "instructions"
18208
18476
  ];
@@ -29230,6 +29498,16 @@ function cleanObject(obj) {
29230
29498
  })
29231
29499
  );
29232
29500
  }
29501
+ function normalizeTokenMetrics(obj) {
29502
+ const metrics = cleanObject(obj);
29503
+ if (metrics.total_tokens !== void 0) {
29504
+ metrics.tokens = metrics.total_tokens;
29505
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
29506
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
29507
+ }
29508
+ delete metrics.total_tokens;
29509
+ return metrics;
29510
+ }
29233
29511
  function walkGenerations(response) {
29234
29512
  const result = [];
29235
29513
  const generations = response.generations || [];
@@ -29276,7 +29554,7 @@ function getMetricsFromResponse(response) {
29276
29554
  continue;
29277
29555
  }
29278
29556
  const inputTokenDetails = usageMetadata.input_token_details;
29279
- return cleanObject({
29557
+ return normalizeTokenMetrics({
29280
29558
  total_tokens: usageMetadata.total_tokens,
29281
29559
  prompt_tokens: usageMetadata.input_tokens,
29282
29560
  completion_tokens: usageMetadata.output_tokens,
@@ -29286,7 +29564,7 @@ function getMetricsFromResponse(response) {
29286
29564
  }
29287
29565
  const llmOutput = response.llmOutput || {};
29288
29566
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
29289
- return cleanObject({
29567
+ return normalizeTokenMetrics({
29290
29568
  total_tokens: tokenUsage.totalTokens,
29291
29569
  prompt_tokens: tokenUsage.promptTokens,
29292
29570
  completion_tokens: tokenUsage.completionTokens
@@ -32975,6 +33253,26 @@ function wrapAISDK(aiSDK, options = {}) {
32975
33253
  }
32976
33254
  });
32977
33255
  }
33256
+ function isHarnessAgentInstance(instance) {
33257
+ try {
33258
+ const visited = /* @__PURE__ */ new Set();
33259
+ let prototype = Object.getPrototypeOf(instance);
33260
+ while (prototype !== null && !visited.has(prototype)) {
33261
+ visited.add(prototype);
33262
+ const constructor = Object.getOwnPropertyDescriptor(
33263
+ prototype,
33264
+ "constructor"
33265
+ )?.value;
33266
+ const constructorName = typeof constructor === "function" ? Object.getOwnPropertyDescriptor(constructor, "name")?.value : void 0;
33267
+ if (constructorName === "HarnessAgent") {
33268
+ return true;
33269
+ }
33270
+ prototype = Object.getPrototypeOf(prototype);
33271
+ }
33272
+ } catch {
33273
+ }
33274
+ return false;
33275
+ }
32978
33276
  var wrapAgentClass = (AgentClass, options = {}) => {
32979
33277
  const typedAgentClass = AgentClass;
32980
33278
  return new Proxy(typedAgentClass, {
@@ -32984,9 +33282,46 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32984
33282
  args,
32985
33283
  newTarget
32986
33284
  );
33285
+ const harnessAgent = isHarnessAgentInstance(instance) ? instance : null;
32987
33286
  return new Proxy(instance, {
32988
33287
  get(instanceTarget, prop, instanceReceiver) {
32989
33288
  const original = Reflect.get(instanceTarget, prop, instanceTarget);
33289
+ if (harnessAgent && typeof original === "function") {
33290
+ switch (prop) {
33291
+ case "generate":
33292
+ return wrapHarnessAgentGenerate(
33293
+ original,
33294
+ harnessAgent,
33295
+ harnessAgentChannels.generate,
33296
+ "HarnessAgent.generate",
33297
+ options
33298
+ );
33299
+ case "stream":
33300
+ return wrapHarnessAgentStream(
33301
+ original,
33302
+ harnessAgent,
33303
+ harnessAgentChannels.stream,
33304
+ "HarnessAgent.stream",
33305
+ options
33306
+ );
33307
+ case "continueGenerate":
33308
+ return wrapHarnessAgentGenerate(
33309
+ original,
33310
+ harnessAgent,
33311
+ harnessAgentChannels.continueGenerate,
33312
+ "HarnessAgent.continueGenerate",
33313
+ options
33314
+ );
33315
+ case "continueStream":
33316
+ return wrapHarnessAgentStream(
33317
+ original,
33318
+ harnessAgent,
33319
+ harnessAgentChannels.continueStream,
33320
+ "HarnessAgent.continueStream",
33321
+ options
33322
+ );
33323
+ }
33324
+ }
32990
33325
  if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
32991
33326
  return wrapAgentGenerate(original, instanceTarget, options);
32992
33327
  }
@@ -33002,6 +33337,26 @@ var wrapAgentClass = (AgentClass, options = {}) => {
33002
33337
  }
33003
33338
  });
33004
33339
  };
33340
+ var wrapHarnessAgentGenerate = (generate, instance, channel2, name, options) => makeGenerateTextWrapper(
33341
+ channel2,
33342
+ name,
33343
+ generate.bind(instance),
33344
+ {
33345
+ self: instance,
33346
+ spanType: "task" /* TASK */
33347
+ },
33348
+ options
33349
+ );
33350
+ var wrapHarnessAgentStream = (stream, instance, channel2, name, options) => makeStreamWrapper(
33351
+ channel2,
33352
+ name,
33353
+ stream.bind(instance),
33354
+ {
33355
+ self: instance,
33356
+ spanType: "task" /* TASK */
33357
+ },
33358
+ options
33359
+ );
33005
33360
  var wrapAgentGenerate = (generate, instance, options = {}) => {
33006
33361
  const defaultName = `${instance.constructor.name}.generate`;
33007
33362
  return async (params) => makeGenerateTextWrapper(
@@ -33228,6 +33583,7 @@ var BraintrustLanguageModelWrapper = class {
33228
33583
  this.supportsUrl = (url) => this.model.supportsUrl(url);
33229
33584
  }
33230
33585
  }
33586
+ model;
33231
33587
  supportsUrl;
33232
33588
  get specificationVersion() {
33233
33589
  return this.model.specificationVersion;
@@ -33810,6 +34166,7 @@ function BraintrustMiddleware(config = {}) {
33810
34166
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
33811
34167
  var MAX_EVE_CACHE_ENTRIES = 1e4;
33812
34168
  var MAX_STORED_LLM_INPUTS = 100;
34169
+ var MAX_STORED_REASONING_BLOCKS = 100;
33813
34170
  var MAX_STORED_SPAN_REFERENCES = 1e4;
33814
34171
  var MAX_STORED_STEP_STARTS = 1e4;
33815
34172
  function braintrustEveHook(options) {
@@ -33848,6 +34205,7 @@ var ResumedEveSpan = class {
33848
34205
  this.reference = reference;
33849
34206
  this.endTime = reference.endTime;
33850
34207
  }
34208
+ reference;
33851
34209
  endTime;
33852
34210
  get rootSpanId() {
33853
34211
  return this.reference.rootSpanId;
@@ -33880,6 +34238,7 @@ var EveBridge = class {
33880
34238
  constructor(state) {
33881
34239
  this.state = state;
33882
34240
  }
34241
+ state;
33883
34242
  eventQueuesBySession = /* @__PURE__ */ new Map();
33884
34243
  completedToolKeys = new LRUCache({
33885
34244
  max: MAX_EVE_CACHE_ENTRIES
@@ -34058,6 +34417,9 @@ var EveBridge = class {
34058
34417
  case "step.started":
34059
34418
  await this.handleStepStarted(event, ctx, hookMetadata);
34060
34419
  return true;
34420
+ case "reasoning.completed":
34421
+ this.handleReasoningCompleted(event, ctx);
34422
+ return true;
34061
34423
  case "message.completed":
34062
34424
  this.handleMessageCompleted(event, ctx);
34063
34425
  return true;
@@ -34149,6 +34511,7 @@ var EveBridge = class {
34149
34511
  key,
34150
34512
  metadata,
34151
34513
  metrics: {},
34514
+ sessionId,
34152
34515
  span,
34153
34516
  stepsByIndex: /* @__PURE__ */ new Map(),
34154
34517
  turnId: event.data.turnId
@@ -34179,6 +34542,12 @@ var EveBridge = class {
34179
34542
  const endTime = eventTime2(event);
34180
34543
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
34181
34544
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34545
+ clearStoredEveReasoning(
34546
+ this.state,
34547
+ sessionId,
34548
+ event.data.turnId,
34549
+ event.data.stepIndex
34550
+ );
34182
34551
  }
34183
34552
  const stepOrdinal = this.stepOrdinal(event);
34184
34553
  const metadata = { ...turn.metadata };
@@ -34188,6 +34557,13 @@ var EveBridge = class {
34188
34557
  event.data.turnId,
34189
34558
  event.data.stepIndex
34190
34559
  );
34560
+ const reasoning = readStoredEveReasoning(
34561
+ this.state,
34562
+ sessionId,
34563
+ event.data.turnId,
34564
+ event.data.stepIndex
34565
+ );
34566
+ const output = mergeEveReasoning(void 0, reasoning);
34191
34567
  const { rowId: eventId, spanId } = await generateEveIds(
34192
34568
  "step",
34193
34569
  sessionId,
@@ -34205,32 +34581,52 @@ var EveBridge = class {
34205
34581
  spanId,
34206
34582
  startTime: eventTime2(event)
34207
34583
  });
34208
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
34584
+ span.log({
34585
+ ...input !== void 0 ? { input } : {},
34586
+ metadata
34587
+ });
34209
34588
  turn.stepsByIndex.set(event.data.stepIndex, {
34210
34589
  ...input !== void 0 ? { input } : {},
34211
34590
  metadata,
34212
34591
  metrics: {},
34592
+ ...output !== void 0 ? { output } : {},
34593
+ reasoning,
34213
34594
  span
34214
34595
  });
34215
34596
  }
34597
+ handleReasoningCompleted(event, ctx) {
34598
+ const sessionId = sessionIdFromContext(ctx);
34599
+ if (!sessionId) {
34600
+ return;
34601
+ }
34602
+ const reasoning = storeEveReasoning(this.state, sessionId, event);
34603
+ const step = this.stepForEvent(event, ctx);
34604
+ if (step) {
34605
+ step.reasoning = reasoning;
34606
+ step.output = mergeEveReasoning(step.output, reasoning);
34607
+ }
34608
+ }
34216
34609
  handleMessageCompleted(event, ctx) {
34217
34610
  const step = this.stepForEvent(event, ctx);
34218
34611
  if (!step) {
34219
34612
  return;
34220
34613
  }
34221
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
34614
+ const existingMessage = eveOutputMessage(step.output);
34222
34615
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
34223
- step.output = [
34224
- {
34225
- finish_reason: normalizedFinishReason(event.data.finishReason),
34226
- index: 0,
34227
- message: {
34228
- content: event.data.message,
34229
- role: "assistant",
34230
- ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34616
+ step.output = mergeEveReasoning(
34617
+ [
34618
+ {
34619
+ finish_reason: normalizedFinishReason(event.data.finishReason),
34620
+ index: 0,
34621
+ message: {
34622
+ content: event.data.message,
34623
+ role: "assistant",
34624
+ ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34625
+ }
34231
34626
  }
34232
- }
34233
- ];
34627
+ ],
34628
+ step.reasoning
34629
+ );
34234
34630
  const turn = this.turnForEvent(event, ctx);
34235
34631
  if (turn && event.data.finishReason !== "tool-calls") {
34236
34632
  turn.output = event.data.message;
@@ -34239,16 +34635,19 @@ var EveBridge = class {
34239
34635
  handleResultCompleted(event, ctx) {
34240
34636
  const step = this.stepForEvent(event, ctx);
34241
34637
  if (step) {
34242
- step.output = [
34243
- {
34244
- finish_reason: "stop",
34245
- index: 0,
34246
- message: {
34247
- content: event.data.result,
34248
- role: "assistant"
34638
+ step.output = mergeEveReasoning(
34639
+ [
34640
+ {
34641
+ finish_reason: "stop",
34642
+ index: 0,
34643
+ message: {
34644
+ content: event.data.result,
34645
+ role: "assistant"
34646
+ }
34249
34647
  }
34250
- }
34251
- ];
34648
+ ],
34649
+ step.reasoning
34650
+ );
34252
34651
  }
34253
34652
  const turn = this.turnForEvent(event, ctx);
34254
34653
  if (turn) {
@@ -34298,18 +34697,20 @@ var EveBridge = class {
34298
34697
  type: "function"
34299
34698
  });
34300
34699
  }
34301
- step.output = [
34302
- {
34303
- finish_reason: "tool_calls",
34304
- index: 0,
34305
- message: {
34306
- content: null,
34307
- role: "assistant",
34308
- tool_calls: [...toolCallsById.values()]
34700
+ step.output = mergeEveReasoning(
34701
+ [
34702
+ {
34703
+ finish_reason: "tool_calls",
34704
+ index: 0,
34705
+ message: {
34706
+ content: null,
34707
+ role: "assistant",
34708
+ tool_calls: [...toolCallsById.values()]
34709
+ }
34309
34710
  }
34310
- }
34311
- ];
34312
- step.span.log({ metadata: step.metadata, output: step.output });
34711
+ ],
34712
+ step.reasoning
34713
+ );
34313
34714
  }
34314
34715
  async handleActionResult(event, ctx, hookMetadata) {
34315
34716
  if (isToolResult(event.data.result)) {
@@ -34487,6 +34888,7 @@ var EveBridge = class {
34487
34888
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
34488
34889
  };
34489
34890
  step.metrics = { ...step.metrics, ...metrics };
34891
+ const sessionId = sessionIdFromContext(ctx);
34490
34892
  if (Array.isArray(step.output) && isObject(step.output[0])) {
34491
34893
  const finishReason = step.output[0].finish_reason;
34492
34894
  if (typeof finishReason !== "string") {
@@ -34511,6 +34913,14 @@ var EveBridge = class {
34511
34913
  turn.stepsByIndex.delete(event.data.stepIndex);
34512
34914
  }
34513
34915
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34916
+ if (sessionId) {
34917
+ clearStoredEveReasoning(
34918
+ this.state,
34919
+ sessionId,
34920
+ event.data.turnId,
34921
+ event.data.stepIndex
34922
+ );
34923
+ }
34514
34924
  }
34515
34925
  handleStepFailed(event, ctx) {
34516
34926
  const step = this.stepForEvent(event, ctx);
@@ -34528,6 +34938,15 @@ var EveBridge = class {
34528
34938
  const turn = this.turnForEvent(event, ctx);
34529
34939
  turn?.stepsByIndex.delete(event.data.stepIndex);
34530
34940
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34941
+ const sessionId = sessionIdFromContext(ctx);
34942
+ if (sessionId) {
34943
+ clearStoredEveReasoning(
34944
+ this.state,
34945
+ sessionId,
34946
+ event.data.turnId,
34947
+ event.data.stepIndex
34948
+ );
34949
+ }
34531
34950
  }
34532
34951
  handleTurnCompleted(event, ctx) {
34533
34952
  const turn = this.turnForEvent(event, ctx);
@@ -34625,6 +35044,7 @@ var EveBridge = class {
34625
35044
  key,
34626
35045
  metadata,
34627
35046
  metrics: {},
35047
+ sessionId,
34628
35048
  span,
34629
35049
  stepsByIndex: /* @__PURE__ */ new Map(),
34630
35050
  turnId: event.data.turnId
@@ -34887,6 +35307,9 @@ var EveBridge = class {
34887
35307
  const normalized = normalizeEveTraceState(current);
34888
35308
  return {
34889
35309
  ...normalized,
35310
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35311
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
35312
+ ),
34890
35313
  stepStarts: normalized.stepStarts.filter(
34891
35314
  (entry) => entry.turnId !== turn.turnId
34892
35315
  )
@@ -34926,6 +35349,7 @@ function emptyEveTraceState() {
34926
35349
  return {
34927
35350
  llmInputs: [],
34928
35351
  metadata: {},
35352
+ reasoningBlocks: [],
34929
35353
  spanReferences: [],
34930
35354
  stepStarts: []
34931
35355
  };
@@ -34976,6 +35400,21 @@ function normalizeEveTraceState(state) {
34976
35400
  const input = entry["input"];
34977
35401
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
34978
35402
  }).slice(-MAX_STORED_LLM_INPUTS) : [];
35403
+ const reasoningBlocks = Array.isArray(state["reasoningBlocks"]) ? state["reasoningBlocks"].flatMap((entry) => {
35404
+ if (!isObject(entry)) {
35405
+ return [];
35406
+ }
35407
+ const content = entry["content"];
35408
+ const eventAt = entry["eventAt"];
35409
+ const key = entry["key"];
35410
+ return typeof content === "string" && (eventAt === void 0 || typeof eventAt === "string") && typeof key === "string" ? [
35411
+ {
35412
+ content,
35413
+ ...typeof eventAt === "string" ? { eventAt } : {},
35414
+ key
35415
+ }
35416
+ ] : [];
35417
+ }).slice(-MAX_STORED_REASONING_BLOCKS) : [];
34979
35418
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
34980
35419
  if (!isObject(entry)) {
34981
35420
  return [];
@@ -34986,7 +35425,13 @@ function normalizeEveTraceState(state) {
34986
35425
  const turnId = entry["turnId"];
34987
35426
  return typeof ordinal === "number" && Number.isInteger(ordinal) && ordinal >= 0 && typeof open === "boolean" && typeof stepIndex === "number" && Number.isInteger(stepIndex) && typeof turnId === "string" ? [{ open, ordinal, stepIndex, turnId }] : [];
34988
35427
  }).slice(-MAX_STORED_STEP_STARTS) : [];
34989
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
35428
+ return {
35429
+ llmInputs,
35430
+ metadata: { ...metadata },
35431
+ reasoningBlocks,
35432
+ spanReferences,
35433
+ stepStarts
35434
+ };
34990
35435
  }
34991
35436
  function readEveTraceState(state) {
34992
35437
  try {
@@ -34995,23 +35440,85 @@ function readEveTraceState(state) {
34995
35440
  return emptyEveTraceState();
34996
35441
  }
34997
35442
  }
34998
- function captureEveModelInput(state, input) {
34999
- if (!isObject(input)) {
35000
- return;
35001
- }
35002
- const session = input["session"];
35003
- const turn = input["turn"];
35004
- const step = input["step"];
35005
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
35006
- return;
35007
- }
35008
- const sessionId = session["id"];
35009
- const turnId = turn["id"];
35010
- const stepIndex = step["index"];
35011
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
35012
- return;
35443
+ function storeEveReasoning(state, sessionId, event) {
35444
+ const eventAt = event.meta?.at;
35445
+ const key = llmInputKey(sessionId, event.data.turnId, event.data.stepIndex);
35446
+ let stored = [];
35447
+ state.update((current) => {
35448
+ const normalized = normalizeEveTraceState(current);
35449
+ const alreadyStored = normalized.reasoningBlocks.some(
35450
+ (entry) => entry.content === event.data.reasoning && entry.eventAt === eventAt && entry.key === key
35451
+ );
35452
+ const reasoningBlocks = alreadyStored ? normalized.reasoningBlocks : [
35453
+ ...normalized.reasoningBlocks,
35454
+ {
35455
+ content: event.data.reasoning,
35456
+ ...eventAt ? { eventAt } : {},
35457
+ key
35458
+ }
35459
+ ].slice(-MAX_STORED_REASONING_BLOCKS);
35460
+ stored = reasoningBlocks.flatMap(
35461
+ (entry) => entry.key === key ? [
35462
+ {
35463
+ content: entry.content,
35464
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35465
+ }
35466
+ ] : []
35467
+ );
35468
+ return alreadyStored ? normalized : { ...normalized, reasoningBlocks };
35469
+ });
35470
+ return stored;
35471
+ }
35472
+ function readStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35473
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35474
+ return readEveTraceState(state).reasoningBlocks.flatMap(
35475
+ (entry) => entry.key === key ? [
35476
+ {
35477
+ content: entry.content,
35478
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35479
+ }
35480
+ ] : []
35481
+ );
35482
+ }
35483
+ function clearStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35484
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35485
+ state.update((current) => {
35486
+ const normalized = normalizeEveTraceState(current);
35487
+ return {
35488
+ ...normalized,
35489
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35490
+ (entry) => entry.key !== key
35491
+ )
35492
+ };
35493
+ });
35494
+ }
35495
+ function eveOutputMessage(output) {
35496
+ return Array.isArray(output) && isObject(output[0]) ? output[0]["message"] : void 0;
35497
+ }
35498
+ function mergeEveReasoning(output, reasoning) {
35499
+ if (reasoning.length === 0) {
35500
+ return output;
35013
35501
  }
35014
- const captured = capturedModelInput(input["modelInput"]);
35502
+ const choice = Array.isArray(output) && isObject(output[0]) ? output[0] : {};
35503
+ const message = isObject(choice["message"]) ? choice["message"] : {};
35504
+ return [
35505
+ {
35506
+ ...choice,
35507
+ index: typeof choice["index"] === "number" ? choice["index"] : 0,
35508
+ message: {
35509
+ ...message,
35510
+ content: "content" in message ? message["content"] : null,
35511
+ reasoning: reasoning.map((block) => ({ content: block.content })),
35512
+ role: typeof message["role"] === "string" ? message["role"] : "assistant"
35513
+ }
35514
+ }
35515
+ ];
35516
+ }
35517
+ function captureEveModelInput(state, input) {
35518
+ const sessionId = input.session.id;
35519
+ const turnId = input.turn.id;
35520
+ const stepIndex = input.step.index;
35521
+ const captured = capturedModelInput(input.modelInput);
35015
35522
  if (!captured) {
35016
35523
  return;
35017
35524
  }
@@ -35052,18 +35559,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
35052
35559
  }
35053
35560
  }
35054
35561
  function capturedModelInput(modelInput) {
35055
- if (!isObject(modelInput)) {
35056
- return void 0;
35057
- }
35058
- const messages = modelInput["messages"];
35059
- if (!Array.isArray(messages)) {
35060
- return void 0;
35061
- }
35062
- const instructions = modelInput["instructions"];
35063
- const value = [
35064
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
35065
- ...messages
35066
- ];
35562
+ const { instructions, messages } = modelInput;
35563
+ const value = [];
35564
+ if (typeof instructions === "string") {
35565
+ value.push({ content: instructions, role: "system" });
35566
+ } else if (instructions) {
35567
+ value.push(...instructions.map(capturedEveModelMessage));
35568
+ }
35569
+ value.push(...messages.map(capturedEveModelMessage));
35067
35570
  try {
35068
35571
  const cloned = JSON.parse(JSON.stringify(value));
35069
35572
  if (!Array.isArray(cloned)) {
@@ -35074,8 +35577,123 @@ function capturedModelInput(modelInput) {
35074
35577
  return void 0;
35075
35578
  }
35076
35579
  }
35580
+ function capturedEveModelMessage(message) {
35581
+ const { content, role } = message;
35582
+ if (typeof content === "string") {
35583
+ return { content, role };
35584
+ }
35585
+ return { content: content.map(capturedEveModelContentPart), role };
35586
+ }
35587
+ function capturedEveModelContentPart(part) {
35588
+ switch (part.type) {
35589
+ case "text":
35590
+ case "reasoning":
35591
+ return { text: part.text, type: part.type };
35592
+ case "image":
35593
+ return {
35594
+ image: part.image,
35595
+ ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35596
+ type: "image"
35597
+ };
35598
+ case "file":
35599
+ case "reasoning-file":
35600
+ return {
35601
+ data: part.data,
35602
+ ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
35603
+ mediaType: part.mediaType,
35604
+ type: part.type
35605
+ };
35606
+ case "custom":
35607
+ return {
35608
+ ..."kind" in part ? { kind: part.kind } : {},
35609
+ type: "custom"
35610
+ };
35611
+ case "tool-call":
35612
+ return {
35613
+ input: part.input,
35614
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35615
+ toolCallId: part.toolCallId,
35616
+ toolName: part.toolName,
35617
+ type: "tool-call"
35618
+ };
35619
+ case "tool-result": {
35620
+ const output = part.output;
35621
+ let capturedOutput;
35622
+ switch (output.type) {
35623
+ case "text":
35624
+ case "error-text":
35625
+ capturedOutput = { type: output.type, value: output.value };
35626
+ break;
35627
+ case "json":
35628
+ case "error-json":
35629
+ capturedOutput = { type: output.type, value: output.value };
35630
+ break;
35631
+ case "execution-denied":
35632
+ capturedOutput = {
35633
+ ...output.reason !== void 0 ? { reason: output.reason } : {},
35634
+ type: "execution-denied"
35635
+ };
35636
+ break;
35637
+ case "content":
35638
+ capturedOutput = {
35639
+ type: "content",
35640
+ value: output.value.map(capturedEveModelContentPart)
35641
+ };
35642
+ break;
35643
+ }
35644
+ return {
35645
+ output: capturedOutput,
35646
+ toolCallId: part.toolCallId,
35647
+ toolName: part.toolName,
35648
+ type: "tool-result"
35649
+ };
35650
+ }
35651
+ case "tool-approval-request":
35652
+ return {
35653
+ approvalId: part.approvalId,
35654
+ ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
35655
+ ...part.signature !== void 0 ? { signature: part.signature } : {},
35656
+ toolCallId: part.toolCallId,
35657
+ type: "tool-approval-request"
35658
+ };
35659
+ case "tool-approval-response":
35660
+ return {
35661
+ approvalId: part.approvalId,
35662
+ approved: part.approved,
35663
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35664
+ ...part.reason !== void 0 ? { reason: part.reason } : {},
35665
+ type: "tool-approval-response"
35666
+ };
35667
+ case "file-data":
35668
+ case "image-data":
35669
+ return {
35670
+ data: part.data,
35671
+ ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
35672
+ mediaType: part.mediaType,
35673
+ type: part.type
35674
+ };
35675
+ case "file-url":
35676
+ case "image-url":
35677
+ return {
35678
+ ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35679
+ type: part.type,
35680
+ url: part.url
35681
+ };
35682
+ case "file-id":
35683
+ case "image-file-id":
35684
+ return { fileId: part.fileId, type: part.type };
35685
+ case "file-reference":
35686
+ case "image-file-reference":
35687
+ return {
35688
+ providerReference: part.providerReference,
35689
+ type: part.type
35690
+ };
35691
+ }
35692
+ }
35077
35693
  function isCapturedModelInput(input) {
35078
- return Array.isArray(input);
35694
+ return Array.isArray(input) && input.every(
35695
+ (message) => isObject(message) && (message["role"] === "system" || message["role"] === "user" || message["role"] === "assistant" || message["role"] === "tool") && (typeof message["content"] === "string" || Array.isArray(message["content"]) && message["content"].every(isObject))
35696
+ );
35079
35697
  }
35080
35698
  function llmInputKey(sessionId, turnId, stepIndex) {
35081
35699
  return `${sessionId}\0${turnId}\0${stepIndex}`;
@@ -38470,6 +39088,8 @@ var BaseNode = class {
38470
39088
  this.graph = graph;
38471
39089
  this.id = id;
38472
39090
  }
39091
+ graph;
39092
+ id;
38473
39093
  __type = "node";
38474
39094
  dependencies = [];
38475
39095
  addDependency(dependency) {
@@ -38503,6 +39123,7 @@ var PromptNode = class extends BaseNode {
38503
39123
  super(graph, id);
38504
39124
  this.prompt = prompt;
38505
39125
  }
39126
+ prompt;
38506
39127
  async build(context) {
38507
39128
  return {
38508
39129
  type: "function",
@@ -38515,6 +39136,7 @@ var GateNode = class extends BaseNode {
38515
39136
  super(graph, id);
38516
39137
  this.condition = condition;
38517
39138
  }
39139
+ condition;
38518
39140
  async build(context) {
38519
39141
  return {
38520
39142
  type: "gate",
@@ -38539,6 +39161,7 @@ var PromptTemplateNode = class extends BaseNode {
38539
39161
  super(graph, id);
38540
39162
  this.prompt = prompt;
38541
39163
  }
39164
+ prompt;
38542
39165
  async build(context) {
38543
39166
  return {
38544
39167
  type: "prompt_template",
@@ -38551,6 +39174,7 @@ var LiteralNode = class extends BaseNode {
38551
39174
  super(graph, id);
38552
39175
  this.value = value;
38553
39176
  }
39177
+ value;
38554
39178
  async build(context) {
38555
39179
  return {
38556
39180
  type: "literal",
@@ -39644,6 +40268,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
39644
40268
  this._state = _state;
39645
40269
  this.spanTypeFilter = spanTypeFilter;
39646
40270
  }
40271
+ _objectId;
40272
+ rootSpanId;
40273
+ _state;
40274
+ spanTypeFilter;
39647
40275
  static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
39648
40276
  const children = [
39649
40277
  // Base filter: root_span_id = 'value'
@@ -40094,6 +40722,8 @@ var EvalResultWithSummary = class {
40094
40722
  this.summary = summary;
40095
40723
  this.results = results;
40096
40724
  }
40725
+ summary;
40726
+ results;
40097
40727
  /**
40098
40728
  * @deprecated Use `summary` instead.
40099
40729
  */
@@ -41512,6 +42142,7 @@ var ToolBuilder = class {
41512
42142
  constructor(project) {
41513
42143
  this.project = project;
41514
42144
  }
42145
+ project;
41515
42146
  taskCounter = 0;
41516
42147
  // This type definition is just a catch all so that the implementation can be
41517
42148
  // less specific than the two more specific declarations above.
@@ -41542,6 +42173,7 @@ var ScorerBuilder = class {
41542
42173
  constructor(project) {
41543
42174
  this.project = project;
41544
42175
  }
42176
+ project;
41545
42177
  taskCounter = 0;
41546
42178
  create(opts) {
41547
42179
  this.taskCounter++;
@@ -41601,6 +42233,7 @@ var ClassifierBuilder = class {
41601
42233
  constructor(project) {
41602
42234
  this.project = project;
41603
42235
  }
42236
+ project;
41604
42237
  taskCounter = 0;
41605
42238
  create(opts) {
41606
42239
  this.taskCounter++;
@@ -41636,6 +42269,7 @@ var CodeFunction = class {
41636
42269
  throw new Error("parameters are required if return type is defined");
41637
42270
  }
41638
42271
  }
42272
+ project;
41639
42273
  handler;
41640
42274
  name;
41641
42275
  slug;
@@ -41723,6 +42357,7 @@ var PromptBuilder = class {
41723
42357
  constructor(project) {
41724
42358
  this.project = project;
41725
42359
  }
42360
+ project;
41726
42361
  create(opts) {
41727
42362
  const toolFunctions = [];
41728
42363
  const rawTools = [];
@@ -41799,6 +42434,7 @@ var ParametersBuilder = class {
41799
42434
  constructor(project) {
41800
42435
  this.project = project;
41801
42436
  }
42437
+ project;
41802
42438
  create(opts) {
41803
42439
  const slug = opts.slug ?? slugify(opts.name, { lower: true, strict: true });
41804
42440
  const codeParameters = new CodeParameters(this.project, {