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
@@ -219,6 +219,7 @@ var DefaultChannel = class {
219
219
  constructor(name) {
220
220
  this.name = name;
221
221
  }
222
+ name;
222
223
  hasSubscribers = false;
223
224
  subscribe(_subscription) {
224
225
  }
@@ -1275,6 +1276,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1275
1276
  constructor(data) {
1276
1277
  this.data = data;
1277
1278
  }
1279
+ data;
1278
1280
  toStr() {
1279
1281
  const jsonObj = {
1280
1282
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1782,6 +1784,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1782
1784
  constructor(data) {
1783
1785
  this.data = data;
1784
1786
  }
1787
+ data;
1785
1788
  toStr() {
1786
1789
  const jsonObj = {
1787
1790
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -5015,6 +5018,97 @@ var SpanCache = class {
5015
5018
  }
5016
5019
  };
5017
5020
 
5021
+ // src/span-origin.ts
5022
+ var SDK_VERSION = true ? "3.24.0" : "0.0.0";
5023
+ function detectSpanOriginEnvironment(explicit) {
5024
+ if (explicit) return explicit;
5025
+ const envType = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_TYPE");
5026
+ const envName = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_NAME");
5027
+ if (envType || envName) {
5028
+ return {
5029
+ ...envType ? { type: envType } : {},
5030
+ ...envName ? { name: envName } : {}
5031
+ };
5032
+ }
5033
+ const ci = firstPresent([
5034
+ ["GITHUB_ACTIONS", "github_actions"],
5035
+ ["GITLAB_CI", "gitlab_ci"],
5036
+ ["CIRCLECI", "circleci"],
5037
+ ["BUILDKITE", "buildkite"],
5038
+ ["JENKINS_URL", "jenkins"],
5039
+ ["JENKINS_HOME", "jenkins"],
5040
+ ["TF_BUILD", "azure_pipelines"],
5041
+ ["TEAMCITY_VERSION", "teamcity"],
5042
+ ["TRAVIS", "travis"],
5043
+ ["BITBUCKET_BUILD_NUMBER", "bitbucket"]
5044
+ ]);
5045
+ if (ci) return { type: "ci", name: ci };
5046
+ if (isomorph_default.getEnv("CI")) return { type: "ci", name: "ci" };
5047
+ const earlyServer = firstPresent([
5048
+ ["VERCEL", "vercel"],
5049
+ ["NETLIFY", "netlify"]
5050
+ ]);
5051
+ if (earlyServer) return { type: "server", name: earlyServer };
5052
+ if (isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI") || isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI_V4")) {
5053
+ return { type: "server", name: "ecs" };
5054
+ }
5055
+ const awsExecutionEnv = isomorph_default.getEnv("AWS_EXECUTION_ENV");
5056
+ if (awsExecutionEnv?.startsWith("AWS_ECS_")) {
5057
+ return { type: "server", name: "ecs" };
5058
+ }
5059
+ if (awsExecutionEnv?.startsWith("AWS_Lambda_")) {
5060
+ return { type: "server", name: "aws_lambda" };
5061
+ }
5062
+ if (isomorph_default.getEnv("AWS_LAMBDA_FUNCTION_NAME")) {
5063
+ return { type: "server", name: "aws_lambda" };
5064
+ }
5065
+ const server = firstPresent([
5066
+ ["K_SERVICE", "cloud_run"],
5067
+ ["FUNCTION_TARGET", "gcp_functions"],
5068
+ ["KUBERNETES_SERVICE_HOST", "kubernetes"],
5069
+ ["DYNO", "heroku"],
5070
+ ["FLY_APP_NAME", "fly"],
5071
+ ["RAILWAY_ENVIRONMENT", "railway"],
5072
+ ["RENDER_SERVICE_NAME", "render"]
5073
+ ]);
5074
+ if (server) return { type: "server", name: server };
5075
+ return deploymentModeEnvironment("NODE_ENV", isomorph_default.getEnv("NODE_ENV"));
5076
+ }
5077
+ function makeSpanOrigin(instrumentationName, environment) {
5078
+ return {
5079
+ name: "braintrust.sdk.javascript",
5080
+ version: SDK_VERSION,
5081
+ instrumentation: { name: instrumentationName },
5082
+ ...environment ? { environment } : {}
5083
+ };
5084
+ }
5085
+ function mergeSpanOriginContext(context, instrumentationName, environment) {
5086
+ const next = { ...context ?? {} };
5087
+ const current = isObject2(next.span_origin) ? { ...next.span_origin } : {};
5088
+ next.span_origin = {
5089
+ ...makeSpanOrigin(instrumentationName, environment),
5090
+ ...current
5091
+ };
5092
+ return next;
5093
+ }
5094
+ function firstPresent(entries) {
5095
+ return entries.find(([key]) => Boolean(isomorph_default.getEnv(key)))?.[1];
5096
+ }
5097
+ function deploymentModeEnvironment(_key, value) {
5098
+ if (!value) return void 0;
5099
+ const normalized = value.toLowerCase();
5100
+ if (normalized === "production" || normalized === "staging") {
5101
+ return { type: "server", name: normalized };
5102
+ }
5103
+ if (normalized === "development" || normalized === "local") {
5104
+ return { type: "local", name: normalized };
5105
+ }
5106
+ return { name: value };
5107
+ }
5108
+ function isObject2(value) {
5109
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5110
+ }
5111
+
5018
5112
  // src/logger.ts
5019
5113
  var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
5020
5114
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
@@ -5063,6 +5157,7 @@ var LoginInvalidOrgError = class extends Error {
5063
5157
  super(message);
5064
5158
  this.message = message;
5065
5159
  }
5160
+ message;
5066
5161
  };
5067
5162
  var REDACTION_FIELDS = [
5068
5163
  "input",
@@ -5078,6 +5173,8 @@ var MaskingError = class {
5078
5173
  this.fieldName = fieldName;
5079
5174
  this.errorType = errorType;
5080
5175
  }
5176
+ fieldName;
5177
+ errorType;
5081
5178
  get errorMsg() {
5082
5179
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
5083
5180
  }
@@ -5287,7 +5384,9 @@ var BraintrustState = class _BraintrustState {
5287
5384
  diskCache: parametersDiskCache
5288
5385
  });
5289
5386
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5387
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5290
5388
  }
5389
+ loginParams;
5291
5390
  id;
5292
5391
  currentExperiment;
5293
5392
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5322,6 +5421,7 @@ var BraintrustState = class _BraintrustState {
5322
5421
  _idGenerator = null;
5323
5422
  _contextManager = null;
5324
5423
  _otelFlushCallback = null;
5424
+ spanOriginEnvironment;
5325
5425
  resetLoginInfo() {
5326
5426
  this.appUrl = null;
5327
5427
  this.appPublicUrl = null;
@@ -7940,6 +8040,7 @@ function initLogger(options = {}) {
7940
8040
  orgName,
7941
8041
  forceLogin,
7942
8042
  debugLogLevel,
8043
+ environment,
7943
8044
  fetch: fetch2,
7944
8045
  state: stateArg
7945
8046
  } = options || {};
@@ -7956,6 +8057,7 @@ function initLogger(options = {}) {
7956
8057
  };
7957
8058
  const state = stateArg ?? _globalState;
7958
8059
  state.setDebugLogLevel(debugLogLevel);
8060
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7959
8061
  state.enforceQueueSizeLimit(true);
7960
8062
  const lazyMetadata = new LazyValue(
7961
8063
  async () => {
@@ -9147,6 +9249,11 @@ var ObjectFetcher = class {
9147
9249
  this._internal_btql = _internal_btql;
9148
9250
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
9149
9251
  }
9252
+ objectType;
9253
+ pinnedVersion;
9254
+ mutateRecord;
9255
+ _internal_btql;
9256
+ _internalBrainstoreRealtime;
9150
9257
  _fetchedData = void 0;
9151
9258
  get id() {
9152
9259
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -9585,6 +9692,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9585
9692
  this.state = state;
9586
9693
  this.lazyMetadata = lazyMetadata;
9587
9694
  }
9695
+ state;
9696
+ lazyMetadata;
9588
9697
  get id() {
9589
9698
  return (async () => {
9590
9699
  return (await this.lazyMetadata.get()).experiment.id;
@@ -9707,7 +9816,11 @@ var SpanImpl = class _SpanImpl {
9707
9816
  metrics: {
9708
9817
  start: args.startTime ?? getCurrentUnixTimestamp()
9709
9818
  },
9710
- context: { ...callerLocation },
9819
+ context: mergeSpanOriginContext(
9820
+ { ...callerLocation },
9821
+ "braintrust-js-logger",
9822
+ this._state.spanOriginEnvironment
9823
+ ),
9711
9824
  span_attributes: {
9712
9825
  name,
9713
9826
  type,
@@ -10081,6 +10194,7 @@ var Dataset2 = class extends ObjectFetcher {
10081
10194
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
10082
10195
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
10083
10196
  }
10197
+ state;
10084
10198
  lazyMetadata;
10085
10199
  __braintrust_dataset_marker = true;
10086
10200
  newRecords = 0;
@@ -10595,6 +10709,9 @@ var Prompt2 = class _Prompt {
10595
10709
  this.noTrace = noTrace;
10596
10710
  void this.__braintrust_prompt_marker;
10597
10711
  }
10712
+ metadata;
10713
+ defaults;
10714
+ noTrace;
10598
10715
  parsedPromptData;
10599
10716
  hasParsedPromptData = false;
10600
10717
  __braintrust_prompt_marker = true;
@@ -10832,6 +10949,7 @@ var RemoteEvalParameters = class {
10832
10949
  this.metadata = metadata;
10833
10950
  void this.__braintrust_parameters_marker;
10834
10951
  }
10952
+ metadata;
10835
10953
  __braintrust_parameters_marker = true;
10836
10954
  get id() {
10837
10955
  return this.metadata.id;
@@ -15420,6 +15538,24 @@ var aiSDKChannels = defineChannels("ai", {
15420
15538
  kind: "sync-stream"
15421
15539
  })
15422
15540
  });
15541
+ var harnessAgentChannels = defineChannels("@ai-sdk/harness", {
15542
+ generate: channel({
15543
+ channelName: "HarnessAgent.generate",
15544
+ kind: "async"
15545
+ }),
15546
+ stream: channel({
15547
+ channelName: "HarnessAgent.stream",
15548
+ kind: "async"
15549
+ }),
15550
+ continueGenerate: channel({
15551
+ channelName: "HarnessAgent.continueGenerate",
15552
+ kind: "async"
15553
+ }),
15554
+ continueStream: channel({
15555
+ channelName: "HarnessAgent.continueStream",
15556
+ kind: "async"
15557
+ })
15558
+ });
15423
15559
 
15424
15560
  // src/instrumentation/plugins/ai-sdk-plugin.ts
15425
15561
  var DEFAULT_DENY_OUTPUT_PATHS = [
@@ -15688,6 +15824,84 @@ var AISDKPlugin = class extends BasePlugin {
15688
15824
  })
15689
15825
  })
15690
15826
  );
15827
+ this.unsubscribers.push(
15828
+ traceStreamingChannel(harnessAgentChannels.generate, {
15829
+ name: "HarnessAgent.generate",
15830
+ type: "task" /* TASK */,
15831
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15832
+ extractOutput: (result, endEvent) => processAISDKOutput(
15833
+ result,
15834
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15835
+ ),
15836
+ extractMetrics: (result) => extractTokenMetrics(result),
15837
+ aggregateChunks: aggregateAISDKChunks
15838
+ })
15839
+ );
15840
+ this.unsubscribers.push(
15841
+ traceStreamingChannel(harnessAgentChannels.stream, {
15842
+ name: "HarnessAgent.stream",
15843
+ type: "task" /* TASK */,
15844
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15845
+ extractOutput: (result, endEvent) => processAISDKOutput(
15846
+ result,
15847
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15848
+ ),
15849
+ extractMetrics: (result, startTime) => ({
15850
+ ...extractTokenMetrics(result),
15851
+ ...startTime === void 0 ? {} : {
15852
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15853
+ }
15854
+ }),
15855
+ aggregateChunks: aggregateAISDKChunks,
15856
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15857
+ defaultDenyOutputPaths: denyOutputPaths,
15858
+ endEvent,
15859
+ result,
15860
+ resolvePromiseUsage: true,
15861
+ span,
15862
+ startTime
15863
+ })
15864
+ })
15865
+ );
15866
+ this.unsubscribers.push(
15867
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
15868
+ name: "HarnessAgent.continueGenerate",
15869
+ type: "task" /* TASK */,
15870
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15871
+ extractOutput: (result, endEvent) => processAISDKOutput(
15872
+ result,
15873
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15874
+ ),
15875
+ extractMetrics: (result) => extractTokenMetrics(result),
15876
+ aggregateChunks: aggregateAISDKChunks
15877
+ })
15878
+ );
15879
+ this.unsubscribers.push(
15880
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
15881
+ name: "HarnessAgent.continueStream",
15882
+ type: "task" /* TASK */,
15883
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15884
+ extractOutput: (result, endEvent) => processAISDKOutput(
15885
+ result,
15886
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15887
+ ),
15888
+ extractMetrics: (result, startTime) => ({
15889
+ ...extractTokenMetrics(result),
15890
+ ...startTime === void 0 ? {} : {
15891
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15892
+ }
15893
+ }),
15894
+ aggregateChunks: aggregateAISDKChunks,
15895
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15896
+ defaultDenyOutputPaths: denyOutputPaths,
15897
+ endEvent,
15898
+ result,
15899
+ resolvePromiseUsage: true,
15900
+ span,
15901
+ startTime
15902
+ })
15903
+ })
15904
+ );
15691
15905
  this.unsubscribers.push(
15692
15906
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
15693
15907
  name: "ToolLoopAgent.generate",
@@ -16218,6 +16432,45 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
16218
16432
  metadata
16219
16433
  };
16220
16434
  }
16435
+ function prepareAISDKHarnessAgentInput(params, self) {
16436
+ if (isObject(self)) {
16437
+ try {
16438
+ if (isObject(self.settings)) {
16439
+ const settings = self.settings;
16440
+ if (settings.telemetry === void 0) {
16441
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
16442
+ }
16443
+ }
16444
+ } catch {
16445
+ }
16446
+ }
16447
+ const selectedInput = {};
16448
+ if (params.prompt !== void 0) {
16449
+ selectedInput.prompt = params.prompt;
16450
+ }
16451
+ if (params.messages !== void 0) {
16452
+ selectedInput.messages = params.messages;
16453
+ }
16454
+ if (params.toolApprovalContinuations !== void 0) {
16455
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
16456
+ }
16457
+ const metadata = extractMetadataFromCallParams({}, self);
16458
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
16459
+ metadata.sessionId = params.session.sessionId;
16460
+ }
16461
+ if (isObject(self)) {
16462
+ if (typeof self.harnessId === "string") {
16463
+ metadata.harnessId = self.harnessId;
16464
+ }
16465
+ if (typeof self.permissionMode === "string") {
16466
+ metadata.permissionMode = self.permissionMode;
16467
+ }
16468
+ }
16469
+ return {
16470
+ input: processAISDKCallInput(selectedInput).input,
16471
+ metadata
16472
+ };
16473
+ }
16221
16474
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
16222
16475
  registerWorkflowAgentWrapperSpan(span);
16223
16476
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -17065,6 +17318,7 @@ function patchAISDKStreamingResult(args) {
17065
17318
  endEvent,
17066
17319
  onComplete,
17067
17320
  result,
17321
+ resolvePromiseUsage,
17068
17322
  span,
17069
17323
  startTime
17070
17324
  } = args;
@@ -17091,6 +17345,22 @@ function patchAISDKStreamingResult(args) {
17091
17345
  outputLogged = true;
17092
17346
  try {
17093
17347
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
17348
+ if (resolvePromiseUsage) {
17349
+ try {
17350
+ const resultRecord2 = result;
17351
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
17352
+ if (isPromiseLike(pendingUsage)) {
17353
+ const usage = await Promise.resolve(pendingUsage);
17354
+ if (isObject(usage)) {
17355
+ Object.assign(
17356
+ metrics,
17357
+ extractTokenMetrics({ usage })
17358
+ );
17359
+ }
17360
+ }
17361
+ } catch {
17362
+ }
17363
+ }
17094
17364
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
17095
17365
  metrics.time_to_first_token = firstChunkTime - startTime;
17096
17366
  }
@@ -18321,8 +18591,6 @@ function filterSerializableOptions(options) {
18321
18591
  "additionalDirectories",
18322
18592
  "permissionMode",
18323
18593
  "debug",
18324
- "apiKey",
18325
- "apiKeySource",
18326
18594
  "agentName",
18327
18595
  "instructions"
18328
18596
  ];
@@ -29350,6 +29618,16 @@ function cleanObject(obj) {
29350
29618
  })
29351
29619
  );
29352
29620
  }
29621
+ function normalizeTokenMetrics(obj) {
29622
+ const metrics = cleanObject(obj);
29623
+ if (metrics.total_tokens !== void 0) {
29624
+ metrics.tokens = metrics.total_tokens;
29625
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
29626
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
29627
+ }
29628
+ delete metrics.total_tokens;
29629
+ return metrics;
29630
+ }
29353
29631
  function walkGenerations(response) {
29354
29632
  const result = [];
29355
29633
  const generations = response.generations || [];
@@ -29396,7 +29674,7 @@ function getMetricsFromResponse(response) {
29396
29674
  continue;
29397
29675
  }
29398
29676
  const inputTokenDetails = usageMetadata.input_token_details;
29399
- return cleanObject({
29677
+ return normalizeTokenMetrics({
29400
29678
  total_tokens: usageMetadata.total_tokens,
29401
29679
  prompt_tokens: usageMetadata.input_tokens,
29402
29680
  completion_tokens: usageMetadata.output_tokens,
@@ -29406,7 +29684,7 @@ function getMetricsFromResponse(response) {
29406
29684
  }
29407
29685
  const llmOutput = response.llmOutput || {};
29408
29686
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
29409
- return cleanObject({
29687
+ return normalizeTokenMetrics({
29410
29688
  total_tokens: tokenUsage.totalTokens,
29411
29689
  prompt_tokens: tokenUsage.promptTokens,
29412
29690
  completion_tokens: tokenUsage.completionTokens
@@ -33010,6 +33288,26 @@ function wrapAISDK(aiSDK, options = {}) {
33010
33288
  }
33011
33289
  });
33012
33290
  }
33291
+ function isHarnessAgentInstance(instance) {
33292
+ try {
33293
+ const visited = /* @__PURE__ */ new Set();
33294
+ let prototype = Object.getPrototypeOf(instance);
33295
+ while (prototype !== null && !visited.has(prototype)) {
33296
+ visited.add(prototype);
33297
+ const constructor = Object.getOwnPropertyDescriptor(
33298
+ prototype,
33299
+ "constructor"
33300
+ )?.value;
33301
+ const constructorName = typeof constructor === "function" ? Object.getOwnPropertyDescriptor(constructor, "name")?.value : void 0;
33302
+ if (constructorName === "HarnessAgent") {
33303
+ return true;
33304
+ }
33305
+ prototype = Object.getPrototypeOf(prototype);
33306
+ }
33307
+ } catch {
33308
+ }
33309
+ return false;
33310
+ }
33013
33311
  var wrapAgentClass = (AgentClass, options = {}) => {
33014
33312
  const typedAgentClass = AgentClass;
33015
33313
  return new Proxy(typedAgentClass, {
@@ -33019,9 +33317,46 @@ var wrapAgentClass = (AgentClass, options = {}) => {
33019
33317
  args,
33020
33318
  newTarget
33021
33319
  );
33320
+ const harnessAgent = isHarnessAgentInstance(instance) ? instance : null;
33022
33321
  return new Proxy(instance, {
33023
33322
  get(instanceTarget, prop, instanceReceiver) {
33024
33323
  const original = Reflect.get(instanceTarget, prop, instanceTarget);
33324
+ if (harnessAgent && typeof original === "function") {
33325
+ switch (prop) {
33326
+ case "generate":
33327
+ return wrapHarnessAgentGenerate(
33328
+ original,
33329
+ harnessAgent,
33330
+ harnessAgentChannels.generate,
33331
+ "HarnessAgent.generate",
33332
+ options
33333
+ );
33334
+ case "stream":
33335
+ return wrapHarnessAgentStream(
33336
+ original,
33337
+ harnessAgent,
33338
+ harnessAgentChannels.stream,
33339
+ "HarnessAgent.stream",
33340
+ options
33341
+ );
33342
+ case "continueGenerate":
33343
+ return wrapHarnessAgentGenerate(
33344
+ original,
33345
+ harnessAgent,
33346
+ harnessAgentChannels.continueGenerate,
33347
+ "HarnessAgent.continueGenerate",
33348
+ options
33349
+ );
33350
+ case "continueStream":
33351
+ return wrapHarnessAgentStream(
33352
+ original,
33353
+ harnessAgent,
33354
+ harnessAgentChannels.continueStream,
33355
+ "HarnessAgent.continueStream",
33356
+ options
33357
+ );
33358
+ }
33359
+ }
33025
33360
  if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
33026
33361
  return wrapAgentGenerate(original, instanceTarget, options);
33027
33362
  }
@@ -33037,6 +33372,26 @@ var wrapAgentClass = (AgentClass, options = {}) => {
33037
33372
  }
33038
33373
  });
33039
33374
  };
33375
+ var wrapHarnessAgentGenerate = (generate, instance, channel2, name, options) => makeGenerateTextWrapper(
33376
+ channel2,
33377
+ name,
33378
+ generate.bind(instance),
33379
+ {
33380
+ self: instance,
33381
+ spanType: "task" /* TASK */
33382
+ },
33383
+ options
33384
+ );
33385
+ var wrapHarnessAgentStream = (stream, instance, channel2, name, options) => makeStreamWrapper(
33386
+ channel2,
33387
+ name,
33388
+ stream.bind(instance),
33389
+ {
33390
+ self: instance,
33391
+ spanType: "task" /* TASK */
33392
+ },
33393
+ options
33394
+ );
33040
33395
  var wrapAgentGenerate = (generate, instance, options = {}) => {
33041
33396
  const defaultName = `${instance.constructor.name}.generate`;
33042
33397
  return async (params) => makeGenerateTextWrapper(
@@ -33263,6 +33618,7 @@ var BraintrustLanguageModelWrapper = class {
33263
33618
  this.supportsUrl = (url) => this.model.supportsUrl(url);
33264
33619
  }
33265
33620
  }
33621
+ model;
33266
33622
  supportsUrl;
33267
33623
  get specificationVersion() {
33268
33624
  return this.model.specificationVersion;
@@ -33845,6 +34201,7 @@ function BraintrustMiddleware(config = {}) {
33845
34201
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
33846
34202
  var MAX_EVE_CACHE_ENTRIES = 1e4;
33847
34203
  var MAX_STORED_LLM_INPUTS = 100;
34204
+ var MAX_STORED_REASONING_BLOCKS = 100;
33848
34205
  var MAX_STORED_SPAN_REFERENCES = 1e4;
33849
34206
  var MAX_STORED_STEP_STARTS = 1e4;
33850
34207
  function braintrustEveHook(options) {
@@ -33883,6 +34240,7 @@ var ResumedEveSpan = class {
33883
34240
  this.reference = reference;
33884
34241
  this.endTime = reference.endTime;
33885
34242
  }
34243
+ reference;
33886
34244
  endTime;
33887
34245
  get rootSpanId() {
33888
34246
  return this.reference.rootSpanId;
@@ -33915,6 +34273,7 @@ var EveBridge = class {
33915
34273
  constructor(state) {
33916
34274
  this.state = state;
33917
34275
  }
34276
+ state;
33918
34277
  eventQueuesBySession = /* @__PURE__ */ new Map();
33919
34278
  completedToolKeys = new LRUCache({
33920
34279
  max: MAX_EVE_CACHE_ENTRIES
@@ -34093,6 +34452,9 @@ var EveBridge = class {
34093
34452
  case "step.started":
34094
34453
  await this.handleStepStarted(event, ctx, hookMetadata);
34095
34454
  return true;
34455
+ case "reasoning.completed":
34456
+ this.handleReasoningCompleted(event, ctx);
34457
+ return true;
34096
34458
  case "message.completed":
34097
34459
  this.handleMessageCompleted(event, ctx);
34098
34460
  return true;
@@ -34184,6 +34546,7 @@ var EveBridge = class {
34184
34546
  key,
34185
34547
  metadata,
34186
34548
  metrics: {},
34549
+ sessionId,
34187
34550
  span,
34188
34551
  stepsByIndex: /* @__PURE__ */ new Map(),
34189
34552
  turnId: event.data.turnId
@@ -34214,6 +34577,12 @@ var EveBridge = class {
34214
34577
  const endTime = eventTime2(event);
34215
34578
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
34216
34579
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34580
+ clearStoredEveReasoning(
34581
+ this.state,
34582
+ sessionId,
34583
+ event.data.turnId,
34584
+ event.data.stepIndex
34585
+ );
34217
34586
  }
34218
34587
  const stepOrdinal = this.stepOrdinal(event);
34219
34588
  const metadata = { ...turn.metadata };
@@ -34223,6 +34592,13 @@ var EveBridge = class {
34223
34592
  event.data.turnId,
34224
34593
  event.data.stepIndex
34225
34594
  );
34595
+ const reasoning = readStoredEveReasoning(
34596
+ this.state,
34597
+ sessionId,
34598
+ event.data.turnId,
34599
+ event.data.stepIndex
34600
+ );
34601
+ const output = mergeEveReasoning(void 0, reasoning);
34226
34602
  const { rowId: eventId, spanId } = await generateEveIds(
34227
34603
  "step",
34228
34604
  sessionId,
@@ -34240,32 +34616,52 @@ var EveBridge = class {
34240
34616
  spanId,
34241
34617
  startTime: eventTime2(event)
34242
34618
  });
34243
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
34619
+ span.log({
34620
+ ...input !== void 0 ? { input } : {},
34621
+ metadata
34622
+ });
34244
34623
  turn.stepsByIndex.set(event.data.stepIndex, {
34245
34624
  ...input !== void 0 ? { input } : {},
34246
34625
  metadata,
34247
34626
  metrics: {},
34627
+ ...output !== void 0 ? { output } : {},
34628
+ reasoning,
34248
34629
  span
34249
34630
  });
34250
34631
  }
34632
+ handleReasoningCompleted(event, ctx) {
34633
+ const sessionId = sessionIdFromContext(ctx);
34634
+ if (!sessionId) {
34635
+ return;
34636
+ }
34637
+ const reasoning = storeEveReasoning(this.state, sessionId, event);
34638
+ const step = this.stepForEvent(event, ctx);
34639
+ if (step) {
34640
+ step.reasoning = reasoning;
34641
+ step.output = mergeEveReasoning(step.output, reasoning);
34642
+ }
34643
+ }
34251
34644
  handleMessageCompleted(event, ctx) {
34252
34645
  const step = this.stepForEvent(event, ctx);
34253
34646
  if (!step) {
34254
34647
  return;
34255
34648
  }
34256
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
34649
+ const existingMessage = eveOutputMessage(step.output);
34257
34650
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
34258
- step.output = [
34259
- {
34260
- finish_reason: normalizedFinishReason(event.data.finishReason),
34261
- index: 0,
34262
- message: {
34263
- content: event.data.message,
34264
- role: "assistant",
34265
- ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34651
+ step.output = mergeEveReasoning(
34652
+ [
34653
+ {
34654
+ finish_reason: normalizedFinishReason(event.data.finishReason),
34655
+ index: 0,
34656
+ message: {
34657
+ content: event.data.message,
34658
+ role: "assistant",
34659
+ ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34660
+ }
34266
34661
  }
34267
- }
34268
- ];
34662
+ ],
34663
+ step.reasoning
34664
+ );
34269
34665
  const turn = this.turnForEvent(event, ctx);
34270
34666
  if (turn && event.data.finishReason !== "tool-calls") {
34271
34667
  turn.output = event.data.message;
@@ -34274,16 +34670,19 @@ var EveBridge = class {
34274
34670
  handleResultCompleted(event, ctx) {
34275
34671
  const step = this.stepForEvent(event, ctx);
34276
34672
  if (step) {
34277
- step.output = [
34278
- {
34279
- finish_reason: "stop",
34280
- index: 0,
34281
- message: {
34282
- content: event.data.result,
34283
- role: "assistant"
34673
+ step.output = mergeEveReasoning(
34674
+ [
34675
+ {
34676
+ finish_reason: "stop",
34677
+ index: 0,
34678
+ message: {
34679
+ content: event.data.result,
34680
+ role: "assistant"
34681
+ }
34284
34682
  }
34285
- }
34286
- ];
34683
+ ],
34684
+ step.reasoning
34685
+ );
34287
34686
  }
34288
34687
  const turn = this.turnForEvent(event, ctx);
34289
34688
  if (turn) {
@@ -34333,18 +34732,20 @@ var EveBridge = class {
34333
34732
  type: "function"
34334
34733
  });
34335
34734
  }
34336
- step.output = [
34337
- {
34338
- finish_reason: "tool_calls",
34339
- index: 0,
34340
- message: {
34341
- content: null,
34342
- role: "assistant",
34343
- tool_calls: [...toolCallsById.values()]
34735
+ step.output = mergeEveReasoning(
34736
+ [
34737
+ {
34738
+ finish_reason: "tool_calls",
34739
+ index: 0,
34740
+ message: {
34741
+ content: null,
34742
+ role: "assistant",
34743
+ tool_calls: [...toolCallsById.values()]
34744
+ }
34344
34745
  }
34345
- }
34346
- ];
34347
- step.span.log({ metadata: step.metadata, output: step.output });
34746
+ ],
34747
+ step.reasoning
34748
+ );
34348
34749
  }
34349
34750
  async handleActionResult(event, ctx, hookMetadata) {
34350
34751
  if (isToolResult(event.data.result)) {
@@ -34522,6 +34923,7 @@ var EveBridge = class {
34522
34923
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
34523
34924
  };
34524
34925
  step.metrics = { ...step.metrics, ...metrics };
34926
+ const sessionId = sessionIdFromContext(ctx);
34525
34927
  if (Array.isArray(step.output) && isObject(step.output[0])) {
34526
34928
  const finishReason = step.output[0].finish_reason;
34527
34929
  if (typeof finishReason !== "string") {
@@ -34546,6 +34948,14 @@ var EveBridge = class {
34546
34948
  turn.stepsByIndex.delete(event.data.stepIndex);
34547
34949
  }
34548
34950
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34951
+ if (sessionId) {
34952
+ clearStoredEveReasoning(
34953
+ this.state,
34954
+ sessionId,
34955
+ event.data.turnId,
34956
+ event.data.stepIndex
34957
+ );
34958
+ }
34549
34959
  }
34550
34960
  handleStepFailed(event, ctx) {
34551
34961
  const step = this.stepForEvent(event, ctx);
@@ -34563,6 +34973,15 @@ var EveBridge = class {
34563
34973
  const turn = this.turnForEvent(event, ctx);
34564
34974
  turn?.stepsByIndex.delete(event.data.stepIndex);
34565
34975
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34976
+ const sessionId = sessionIdFromContext(ctx);
34977
+ if (sessionId) {
34978
+ clearStoredEveReasoning(
34979
+ this.state,
34980
+ sessionId,
34981
+ event.data.turnId,
34982
+ event.data.stepIndex
34983
+ );
34984
+ }
34566
34985
  }
34567
34986
  handleTurnCompleted(event, ctx) {
34568
34987
  const turn = this.turnForEvent(event, ctx);
@@ -34660,6 +35079,7 @@ var EveBridge = class {
34660
35079
  key,
34661
35080
  metadata,
34662
35081
  metrics: {},
35082
+ sessionId,
34663
35083
  span,
34664
35084
  stepsByIndex: /* @__PURE__ */ new Map(),
34665
35085
  turnId: event.data.turnId
@@ -34922,6 +35342,9 @@ var EveBridge = class {
34922
35342
  const normalized = normalizeEveTraceState(current);
34923
35343
  return {
34924
35344
  ...normalized,
35345
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35346
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
35347
+ ),
34925
35348
  stepStarts: normalized.stepStarts.filter(
34926
35349
  (entry) => entry.turnId !== turn.turnId
34927
35350
  )
@@ -34961,6 +35384,7 @@ function emptyEveTraceState() {
34961
35384
  return {
34962
35385
  llmInputs: [],
34963
35386
  metadata: {},
35387
+ reasoningBlocks: [],
34964
35388
  spanReferences: [],
34965
35389
  stepStarts: []
34966
35390
  };
@@ -35011,6 +35435,21 @@ function normalizeEveTraceState(state) {
35011
35435
  const input = entry["input"];
35012
35436
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
35013
35437
  }).slice(-MAX_STORED_LLM_INPUTS) : [];
35438
+ const reasoningBlocks = Array.isArray(state["reasoningBlocks"]) ? state["reasoningBlocks"].flatMap((entry) => {
35439
+ if (!isObject(entry)) {
35440
+ return [];
35441
+ }
35442
+ const content = entry["content"];
35443
+ const eventAt = entry["eventAt"];
35444
+ const key = entry["key"];
35445
+ return typeof content === "string" && (eventAt === void 0 || typeof eventAt === "string") && typeof key === "string" ? [
35446
+ {
35447
+ content,
35448
+ ...typeof eventAt === "string" ? { eventAt } : {},
35449
+ key
35450
+ }
35451
+ ] : [];
35452
+ }).slice(-MAX_STORED_REASONING_BLOCKS) : [];
35014
35453
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
35015
35454
  if (!isObject(entry)) {
35016
35455
  return [];
@@ -35021,7 +35460,13 @@ function normalizeEveTraceState(state) {
35021
35460
  const turnId = entry["turnId"];
35022
35461
  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 }] : [];
35023
35462
  }).slice(-MAX_STORED_STEP_STARTS) : [];
35024
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
35463
+ return {
35464
+ llmInputs,
35465
+ metadata: { ...metadata },
35466
+ reasoningBlocks,
35467
+ spanReferences,
35468
+ stepStarts
35469
+ };
35025
35470
  }
35026
35471
  function readEveTraceState(state) {
35027
35472
  try {
@@ -35030,23 +35475,85 @@ function readEveTraceState(state) {
35030
35475
  return emptyEveTraceState();
35031
35476
  }
35032
35477
  }
35033
- function captureEveModelInput(state, input) {
35034
- if (!isObject(input)) {
35035
- return;
35036
- }
35037
- const session = input["session"];
35038
- const turn = input["turn"];
35039
- const step = input["step"];
35040
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
35041
- return;
35042
- }
35043
- const sessionId = session["id"];
35044
- const turnId = turn["id"];
35045
- const stepIndex = step["index"];
35046
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
35047
- return;
35478
+ function storeEveReasoning(state, sessionId, event) {
35479
+ const eventAt = event.meta?.at;
35480
+ const key = llmInputKey(sessionId, event.data.turnId, event.data.stepIndex);
35481
+ let stored = [];
35482
+ state.update((current) => {
35483
+ const normalized = normalizeEveTraceState(current);
35484
+ const alreadyStored = normalized.reasoningBlocks.some(
35485
+ (entry) => entry.content === event.data.reasoning && entry.eventAt === eventAt && entry.key === key
35486
+ );
35487
+ const reasoningBlocks = alreadyStored ? normalized.reasoningBlocks : [
35488
+ ...normalized.reasoningBlocks,
35489
+ {
35490
+ content: event.data.reasoning,
35491
+ ...eventAt ? { eventAt } : {},
35492
+ key
35493
+ }
35494
+ ].slice(-MAX_STORED_REASONING_BLOCKS);
35495
+ stored = reasoningBlocks.flatMap(
35496
+ (entry) => entry.key === key ? [
35497
+ {
35498
+ content: entry.content,
35499
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35500
+ }
35501
+ ] : []
35502
+ );
35503
+ return alreadyStored ? normalized : { ...normalized, reasoningBlocks };
35504
+ });
35505
+ return stored;
35506
+ }
35507
+ function readStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35508
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35509
+ return readEveTraceState(state).reasoningBlocks.flatMap(
35510
+ (entry) => entry.key === key ? [
35511
+ {
35512
+ content: entry.content,
35513
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35514
+ }
35515
+ ] : []
35516
+ );
35517
+ }
35518
+ function clearStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35519
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35520
+ state.update((current) => {
35521
+ const normalized = normalizeEveTraceState(current);
35522
+ return {
35523
+ ...normalized,
35524
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35525
+ (entry) => entry.key !== key
35526
+ )
35527
+ };
35528
+ });
35529
+ }
35530
+ function eveOutputMessage(output) {
35531
+ return Array.isArray(output) && isObject(output[0]) ? output[0]["message"] : void 0;
35532
+ }
35533
+ function mergeEveReasoning(output, reasoning) {
35534
+ if (reasoning.length === 0) {
35535
+ return output;
35048
35536
  }
35049
- const captured = capturedModelInput(input["modelInput"]);
35537
+ const choice = Array.isArray(output) && isObject(output[0]) ? output[0] : {};
35538
+ const message = isObject(choice["message"]) ? choice["message"] : {};
35539
+ return [
35540
+ {
35541
+ ...choice,
35542
+ index: typeof choice["index"] === "number" ? choice["index"] : 0,
35543
+ message: {
35544
+ ...message,
35545
+ content: "content" in message ? message["content"] : null,
35546
+ reasoning: reasoning.map((block) => ({ content: block.content })),
35547
+ role: typeof message["role"] === "string" ? message["role"] : "assistant"
35548
+ }
35549
+ }
35550
+ ];
35551
+ }
35552
+ function captureEveModelInput(state, input) {
35553
+ const sessionId = input.session.id;
35554
+ const turnId = input.turn.id;
35555
+ const stepIndex = input.step.index;
35556
+ const captured = capturedModelInput(input.modelInput);
35050
35557
  if (!captured) {
35051
35558
  return;
35052
35559
  }
@@ -35087,18 +35594,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
35087
35594
  }
35088
35595
  }
35089
35596
  function capturedModelInput(modelInput) {
35090
- if (!isObject(modelInput)) {
35091
- return void 0;
35092
- }
35093
- const messages = modelInput["messages"];
35094
- if (!Array.isArray(messages)) {
35095
- return void 0;
35096
- }
35097
- const instructions = modelInput["instructions"];
35098
- const value = [
35099
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
35100
- ...messages
35101
- ];
35597
+ const { instructions, messages } = modelInput;
35598
+ const value = [];
35599
+ if (typeof instructions === "string") {
35600
+ value.push({ content: instructions, role: "system" });
35601
+ } else if (instructions) {
35602
+ value.push(...instructions.map(capturedEveModelMessage));
35603
+ }
35604
+ value.push(...messages.map(capturedEveModelMessage));
35102
35605
  try {
35103
35606
  const cloned = JSON.parse(JSON.stringify(value));
35104
35607
  if (!Array.isArray(cloned)) {
@@ -35109,8 +35612,123 @@ function capturedModelInput(modelInput) {
35109
35612
  return void 0;
35110
35613
  }
35111
35614
  }
35615
+ function capturedEveModelMessage(message) {
35616
+ const { content, role } = message;
35617
+ if (typeof content === "string") {
35618
+ return { content, role };
35619
+ }
35620
+ return { content: content.map(capturedEveModelContentPart), role };
35621
+ }
35622
+ function capturedEveModelContentPart(part) {
35623
+ switch (part.type) {
35624
+ case "text":
35625
+ case "reasoning":
35626
+ return { text: part.text, type: part.type };
35627
+ case "image":
35628
+ return {
35629
+ image: part.image,
35630
+ ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35631
+ type: "image"
35632
+ };
35633
+ case "file":
35634
+ case "reasoning-file":
35635
+ return {
35636
+ data: part.data,
35637
+ ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
35638
+ mediaType: part.mediaType,
35639
+ type: part.type
35640
+ };
35641
+ case "custom":
35642
+ return {
35643
+ ..."kind" in part ? { kind: part.kind } : {},
35644
+ type: "custom"
35645
+ };
35646
+ case "tool-call":
35647
+ return {
35648
+ input: part.input,
35649
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35650
+ toolCallId: part.toolCallId,
35651
+ toolName: part.toolName,
35652
+ type: "tool-call"
35653
+ };
35654
+ case "tool-result": {
35655
+ const output = part.output;
35656
+ let capturedOutput;
35657
+ switch (output.type) {
35658
+ case "text":
35659
+ case "error-text":
35660
+ capturedOutput = { type: output.type, value: output.value };
35661
+ break;
35662
+ case "json":
35663
+ case "error-json":
35664
+ capturedOutput = { type: output.type, value: output.value };
35665
+ break;
35666
+ case "execution-denied":
35667
+ capturedOutput = {
35668
+ ...output.reason !== void 0 ? { reason: output.reason } : {},
35669
+ type: "execution-denied"
35670
+ };
35671
+ break;
35672
+ case "content":
35673
+ capturedOutput = {
35674
+ type: "content",
35675
+ value: output.value.map(capturedEveModelContentPart)
35676
+ };
35677
+ break;
35678
+ }
35679
+ return {
35680
+ output: capturedOutput,
35681
+ toolCallId: part.toolCallId,
35682
+ toolName: part.toolName,
35683
+ type: "tool-result"
35684
+ };
35685
+ }
35686
+ case "tool-approval-request":
35687
+ return {
35688
+ approvalId: part.approvalId,
35689
+ ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
35690
+ ...part.signature !== void 0 ? { signature: part.signature } : {},
35691
+ toolCallId: part.toolCallId,
35692
+ type: "tool-approval-request"
35693
+ };
35694
+ case "tool-approval-response":
35695
+ return {
35696
+ approvalId: part.approvalId,
35697
+ approved: part.approved,
35698
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35699
+ ...part.reason !== void 0 ? { reason: part.reason } : {},
35700
+ type: "tool-approval-response"
35701
+ };
35702
+ case "file-data":
35703
+ case "image-data":
35704
+ return {
35705
+ data: part.data,
35706
+ ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
35707
+ mediaType: part.mediaType,
35708
+ type: part.type
35709
+ };
35710
+ case "file-url":
35711
+ case "image-url":
35712
+ return {
35713
+ ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35714
+ type: part.type,
35715
+ url: part.url
35716
+ };
35717
+ case "file-id":
35718
+ case "image-file-id":
35719
+ return { fileId: part.fileId, type: part.type };
35720
+ case "file-reference":
35721
+ case "image-file-reference":
35722
+ return {
35723
+ providerReference: part.providerReference,
35724
+ type: part.type
35725
+ };
35726
+ }
35727
+ }
35112
35728
  function isCapturedModelInput(input) {
35113
- return Array.isArray(input);
35729
+ return Array.isArray(input) && input.every(
35730
+ (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))
35731
+ );
35114
35732
  }
35115
35733
  function llmInputKey(sessionId, turnId, stepIndex) {
35116
35734
  return `${sessionId}\0${turnId}\0${stepIndex}`;
@@ -38505,6 +39123,8 @@ var BaseNode = class {
38505
39123
  this.graph = graph;
38506
39124
  this.id = id;
38507
39125
  }
39126
+ graph;
39127
+ id;
38508
39128
  __type = "node";
38509
39129
  dependencies = [];
38510
39130
  addDependency(dependency) {
@@ -38538,6 +39158,7 @@ var PromptNode = class extends BaseNode {
38538
39158
  super(graph, id);
38539
39159
  this.prompt = prompt;
38540
39160
  }
39161
+ prompt;
38541
39162
  async build(context) {
38542
39163
  return {
38543
39164
  type: "function",
@@ -38550,6 +39171,7 @@ var GateNode = class extends BaseNode {
38550
39171
  super(graph, id);
38551
39172
  this.condition = condition;
38552
39173
  }
39174
+ condition;
38553
39175
  async build(context) {
38554
39176
  return {
38555
39177
  type: "gate",
@@ -38574,6 +39196,7 @@ var PromptTemplateNode = class extends BaseNode {
38574
39196
  super(graph, id);
38575
39197
  this.prompt = prompt;
38576
39198
  }
39199
+ prompt;
38577
39200
  async build(context) {
38578
39201
  return {
38579
39202
  type: "prompt_template",
@@ -38586,6 +39209,7 @@ var LiteralNode = class extends BaseNode {
38586
39209
  super(graph, id);
38587
39210
  this.value = value;
38588
39211
  }
39212
+ value;
38589
39213
  async build(context) {
38590
39214
  return {
38591
39215
  type: "literal",
@@ -39679,6 +40303,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
39679
40303
  this._state = _state;
39680
40304
  this.spanTypeFilter = spanTypeFilter;
39681
40305
  }
40306
+ _objectId;
40307
+ rootSpanId;
40308
+ _state;
40309
+ spanTypeFilter;
39682
40310
  static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
39683
40311
  const children = [
39684
40312
  // Base filter: root_span_id = 'value'
@@ -40129,6 +40757,8 @@ var EvalResultWithSummary = class {
40129
40757
  this.summary = summary;
40130
40758
  this.results = results;
40131
40759
  }
40760
+ summary;
40761
+ results;
40132
40762
  /**
40133
40763
  * @deprecated Use `summary` instead.
40134
40764
  */
@@ -41547,6 +42177,7 @@ var ToolBuilder = class {
41547
42177
  constructor(project) {
41548
42178
  this.project = project;
41549
42179
  }
42180
+ project;
41550
42181
  taskCounter = 0;
41551
42182
  // This type definition is just a catch all so that the implementation can be
41552
42183
  // less specific than the two more specific declarations above.
@@ -41577,6 +42208,7 @@ var ScorerBuilder = class {
41577
42208
  constructor(project) {
41578
42209
  this.project = project;
41579
42210
  }
42211
+ project;
41580
42212
  taskCounter = 0;
41581
42213
  create(opts) {
41582
42214
  this.taskCounter++;
@@ -41636,6 +42268,7 @@ var ClassifierBuilder = class {
41636
42268
  constructor(project) {
41637
42269
  this.project = project;
41638
42270
  }
42271
+ project;
41639
42272
  taskCounter = 0;
41640
42273
  create(opts) {
41641
42274
  this.taskCounter++;
@@ -41671,6 +42304,7 @@ var CodeFunction = class {
41671
42304
  throw new Error("parameters are required if return type is defined");
41672
42305
  }
41673
42306
  }
42307
+ project;
41674
42308
  handler;
41675
42309
  name;
41676
42310
  slug;
@@ -41758,6 +42392,7 @@ var PromptBuilder = class {
41758
42392
  constructor(project) {
41759
42393
  this.project = project;
41760
42394
  }
42395
+ project;
41761
42396
  create(opts) {
41762
42397
  const toolFunctions = [];
41763
42398
  const rawTools = [];
@@ -41834,6 +42469,7 @@ var ParametersBuilder = class {
41834
42469
  constructor(project) {
41835
42470
  this.project = project;
41836
42471
  }
42472
+ project;
41837
42473
  create(opts) {
41838
42474
  const slug = opts.slug ?? slugify(opts.name, { lower: true, strict: true });
41839
42475
  const codeParameters = new CodeParameters(this.project, {