braintrust 3.23.1 → 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 -586
  4. package/dev/dist/index.mjs +320 -4
  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 -65
  29. package/dist/browser.mjs +703 -65
  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-B6ZQIAK3.js → chunk-SU6EHKJV.js} +1085 -799
  33. package/dist/{chunk-RBXD2KYN.mjs → chunk-XE5FS7QY.mjs} +291 -5
  34. package/dist/cli.js +328 -8
  35. package/dist/edge-light.js +703 -65
  36. package/dist/edge-light.mjs +703 -65
  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 -65
  44. package/dist/instrumentation/index.mjs +601 -65
  45. package/dist/vitest-evals-reporter.js +17 -16
  46. package/dist/vitest-evals-reporter.mjs +3 -2
  47. package/dist/workerd.js +703 -65
  48. package/dist/workerd.mjs +703 -65
  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
  }
@@ -29348,6 +29618,16 @@ function cleanObject(obj) {
29348
29618
  })
29349
29619
  );
29350
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
+ }
29351
29631
  function walkGenerations(response) {
29352
29632
  const result = [];
29353
29633
  const generations = response.generations || [];
@@ -29394,7 +29674,7 @@ function getMetricsFromResponse(response) {
29394
29674
  continue;
29395
29675
  }
29396
29676
  const inputTokenDetails = usageMetadata.input_token_details;
29397
- return cleanObject({
29677
+ return normalizeTokenMetrics({
29398
29678
  total_tokens: usageMetadata.total_tokens,
29399
29679
  prompt_tokens: usageMetadata.input_tokens,
29400
29680
  completion_tokens: usageMetadata.output_tokens,
@@ -29404,7 +29684,7 @@ function getMetricsFromResponse(response) {
29404
29684
  }
29405
29685
  const llmOutput = response.llmOutput || {};
29406
29686
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
29407
- return cleanObject({
29687
+ return normalizeTokenMetrics({
29408
29688
  total_tokens: tokenUsage.totalTokens,
29409
29689
  prompt_tokens: tokenUsage.promptTokens,
29410
29690
  completion_tokens: tokenUsage.completionTokens
@@ -33008,6 +33288,26 @@ function wrapAISDK(aiSDK, options = {}) {
33008
33288
  }
33009
33289
  });
33010
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
+ }
33011
33311
  var wrapAgentClass = (AgentClass, options = {}) => {
33012
33312
  const typedAgentClass = AgentClass;
33013
33313
  return new Proxy(typedAgentClass, {
@@ -33017,9 +33317,46 @@ var wrapAgentClass = (AgentClass, options = {}) => {
33017
33317
  args,
33018
33318
  newTarget
33019
33319
  );
33320
+ const harnessAgent = isHarnessAgentInstance(instance) ? instance : null;
33020
33321
  return new Proxy(instance, {
33021
33322
  get(instanceTarget, prop, instanceReceiver) {
33022
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
+ }
33023
33360
  if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
33024
33361
  return wrapAgentGenerate(original, instanceTarget, options);
33025
33362
  }
@@ -33035,6 +33372,26 @@ var wrapAgentClass = (AgentClass, options = {}) => {
33035
33372
  }
33036
33373
  });
33037
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
+ );
33038
33395
  var wrapAgentGenerate = (generate, instance, options = {}) => {
33039
33396
  const defaultName = `${instance.constructor.name}.generate`;
33040
33397
  return async (params) => makeGenerateTextWrapper(
@@ -33261,6 +33618,7 @@ var BraintrustLanguageModelWrapper = class {
33261
33618
  this.supportsUrl = (url) => this.model.supportsUrl(url);
33262
33619
  }
33263
33620
  }
33621
+ model;
33264
33622
  supportsUrl;
33265
33623
  get specificationVersion() {
33266
33624
  return this.model.specificationVersion;
@@ -33843,6 +34201,7 @@ function BraintrustMiddleware(config = {}) {
33843
34201
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
33844
34202
  var MAX_EVE_CACHE_ENTRIES = 1e4;
33845
34203
  var MAX_STORED_LLM_INPUTS = 100;
34204
+ var MAX_STORED_REASONING_BLOCKS = 100;
33846
34205
  var MAX_STORED_SPAN_REFERENCES = 1e4;
33847
34206
  var MAX_STORED_STEP_STARTS = 1e4;
33848
34207
  function braintrustEveHook(options) {
@@ -33881,6 +34240,7 @@ var ResumedEveSpan = class {
33881
34240
  this.reference = reference;
33882
34241
  this.endTime = reference.endTime;
33883
34242
  }
34243
+ reference;
33884
34244
  endTime;
33885
34245
  get rootSpanId() {
33886
34246
  return this.reference.rootSpanId;
@@ -33913,6 +34273,7 @@ var EveBridge = class {
33913
34273
  constructor(state) {
33914
34274
  this.state = state;
33915
34275
  }
34276
+ state;
33916
34277
  eventQueuesBySession = /* @__PURE__ */ new Map();
33917
34278
  completedToolKeys = new LRUCache({
33918
34279
  max: MAX_EVE_CACHE_ENTRIES
@@ -34091,6 +34452,9 @@ var EveBridge = class {
34091
34452
  case "step.started":
34092
34453
  await this.handleStepStarted(event, ctx, hookMetadata);
34093
34454
  return true;
34455
+ case "reasoning.completed":
34456
+ this.handleReasoningCompleted(event, ctx);
34457
+ return true;
34094
34458
  case "message.completed":
34095
34459
  this.handleMessageCompleted(event, ctx);
34096
34460
  return true;
@@ -34182,6 +34546,7 @@ var EveBridge = class {
34182
34546
  key,
34183
34547
  metadata,
34184
34548
  metrics: {},
34549
+ sessionId,
34185
34550
  span,
34186
34551
  stepsByIndex: /* @__PURE__ */ new Map(),
34187
34552
  turnId: event.data.turnId
@@ -34212,6 +34577,12 @@ var EveBridge = class {
34212
34577
  const endTime = eventTime2(event);
34213
34578
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
34214
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
+ );
34215
34586
  }
34216
34587
  const stepOrdinal = this.stepOrdinal(event);
34217
34588
  const metadata = { ...turn.metadata };
@@ -34221,6 +34592,13 @@ var EveBridge = class {
34221
34592
  event.data.turnId,
34222
34593
  event.data.stepIndex
34223
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);
34224
34602
  const { rowId: eventId, spanId } = await generateEveIds(
34225
34603
  "step",
34226
34604
  sessionId,
@@ -34238,32 +34616,52 @@ var EveBridge = class {
34238
34616
  spanId,
34239
34617
  startTime: eventTime2(event)
34240
34618
  });
34241
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
34619
+ span.log({
34620
+ ...input !== void 0 ? { input } : {},
34621
+ metadata
34622
+ });
34242
34623
  turn.stepsByIndex.set(event.data.stepIndex, {
34243
34624
  ...input !== void 0 ? { input } : {},
34244
34625
  metadata,
34245
34626
  metrics: {},
34627
+ ...output !== void 0 ? { output } : {},
34628
+ reasoning,
34246
34629
  span
34247
34630
  });
34248
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
+ }
34249
34644
  handleMessageCompleted(event, ctx) {
34250
34645
  const step = this.stepForEvent(event, ctx);
34251
34646
  if (!step) {
34252
34647
  return;
34253
34648
  }
34254
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
34649
+ const existingMessage = eveOutputMessage(step.output);
34255
34650
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
34256
- step.output = [
34257
- {
34258
- finish_reason: normalizedFinishReason(event.data.finishReason),
34259
- index: 0,
34260
- message: {
34261
- content: event.data.message,
34262
- role: "assistant",
34263
- ...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
+ }
34264
34661
  }
34265
- }
34266
- ];
34662
+ ],
34663
+ step.reasoning
34664
+ );
34267
34665
  const turn = this.turnForEvent(event, ctx);
34268
34666
  if (turn && event.data.finishReason !== "tool-calls") {
34269
34667
  turn.output = event.data.message;
@@ -34272,16 +34670,19 @@ var EveBridge = class {
34272
34670
  handleResultCompleted(event, ctx) {
34273
34671
  const step = this.stepForEvent(event, ctx);
34274
34672
  if (step) {
34275
- step.output = [
34276
- {
34277
- finish_reason: "stop",
34278
- index: 0,
34279
- message: {
34280
- content: event.data.result,
34281
- 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
+ }
34282
34682
  }
34283
- }
34284
- ];
34683
+ ],
34684
+ step.reasoning
34685
+ );
34285
34686
  }
34286
34687
  const turn = this.turnForEvent(event, ctx);
34287
34688
  if (turn) {
@@ -34331,18 +34732,20 @@ var EveBridge = class {
34331
34732
  type: "function"
34332
34733
  });
34333
34734
  }
34334
- step.output = [
34335
- {
34336
- finish_reason: "tool_calls",
34337
- index: 0,
34338
- message: {
34339
- content: null,
34340
- role: "assistant",
34341
- 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
+ }
34342
34745
  }
34343
- }
34344
- ];
34345
- step.span.log({ metadata: step.metadata, output: step.output });
34746
+ ],
34747
+ step.reasoning
34748
+ );
34346
34749
  }
34347
34750
  async handleActionResult(event, ctx, hookMetadata) {
34348
34751
  if (isToolResult(event.data.result)) {
@@ -34520,6 +34923,7 @@ var EveBridge = class {
34520
34923
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
34521
34924
  };
34522
34925
  step.metrics = { ...step.metrics, ...metrics };
34926
+ const sessionId = sessionIdFromContext(ctx);
34523
34927
  if (Array.isArray(step.output) && isObject(step.output[0])) {
34524
34928
  const finishReason = step.output[0].finish_reason;
34525
34929
  if (typeof finishReason !== "string") {
@@ -34544,6 +34948,14 @@ var EveBridge = class {
34544
34948
  turn.stepsByIndex.delete(event.data.stepIndex);
34545
34949
  }
34546
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
+ }
34547
34959
  }
34548
34960
  handleStepFailed(event, ctx) {
34549
34961
  const step = this.stepForEvent(event, ctx);
@@ -34561,6 +34973,15 @@ var EveBridge = class {
34561
34973
  const turn = this.turnForEvent(event, ctx);
34562
34974
  turn?.stepsByIndex.delete(event.data.stepIndex);
34563
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
+ }
34564
34985
  }
34565
34986
  handleTurnCompleted(event, ctx) {
34566
34987
  const turn = this.turnForEvent(event, ctx);
@@ -34658,6 +35079,7 @@ var EveBridge = class {
34658
35079
  key,
34659
35080
  metadata,
34660
35081
  metrics: {},
35082
+ sessionId,
34661
35083
  span,
34662
35084
  stepsByIndex: /* @__PURE__ */ new Map(),
34663
35085
  turnId: event.data.turnId
@@ -34920,6 +35342,9 @@ var EveBridge = class {
34920
35342
  const normalized = normalizeEveTraceState(current);
34921
35343
  return {
34922
35344
  ...normalized,
35345
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35346
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
35347
+ ),
34923
35348
  stepStarts: normalized.stepStarts.filter(
34924
35349
  (entry) => entry.turnId !== turn.turnId
34925
35350
  )
@@ -34959,6 +35384,7 @@ function emptyEveTraceState() {
34959
35384
  return {
34960
35385
  llmInputs: [],
34961
35386
  metadata: {},
35387
+ reasoningBlocks: [],
34962
35388
  spanReferences: [],
34963
35389
  stepStarts: []
34964
35390
  };
@@ -35009,6 +35435,21 @@ function normalizeEveTraceState(state) {
35009
35435
  const input = entry["input"];
35010
35436
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
35011
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) : [];
35012
35453
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
35013
35454
  if (!isObject(entry)) {
35014
35455
  return [];
@@ -35019,7 +35460,13 @@ function normalizeEveTraceState(state) {
35019
35460
  const turnId = entry["turnId"];
35020
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 }] : [];
35021
35462
  }).slice(-MAX_STORED_STEP_STARTS) : [];
35022
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
35463
+ return {
35464
+ llmInputs,
35465
+ metadata: { ...metadata },
35466
+ reasoningBlocks,
35467
+ spanReferences,
35468
+ stepStarts
35469
+ };
35023
35470
  }
35024
35471
  function readEveTraceState(state) {
35025
35472
  try {
@@ -35028,23 +35475,85 @@ function readEveTraceState(state) {
35028
35475
  return emptyEveTraceState();
35029
35476
  }
35030
35477
  }
35031
- function captureEveModelInput(state, input) {
35032
- if (!isObject(input)) {
35033
- return;
35034
- }
35035
- const session = input["session"];
35036
- const turn = input["turn"];
35037
- const step = input["step"];
35038
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
35039
- return;
35040
- }
35041
- const sessionId = session["id"];
35042
- const turnId = turn["id"];
35043
- const stepIndex = step["index"];
35044
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
35045
- 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;
35046
35536
  }
35047
- 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);
35048
35557
  if (!captured) {
35049
35558
  return;
35050
35559
  }
@@ -35085,18 +35594,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
35085
35594
  }
35086
35595
  }
35087
35596
  function capturedModelInput(modelInput) {
35088
- if (!isObject(modelInput)) {
35089
- return void 0;
35090
- }
35091
- const messages = modelInput["messages"];
35092
- if (!Array.isArray(messages)) {
35093
- return void 0;
35094
- }
35095
- const instructions = modelInput["instructions"];
35096
- const value = [
35097
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
35098
- ...messages
35099
- ];
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));
35100
35605
  try {
35101
35606
  const cloned = JSON.parse(JSON.stringify(value));
35102
35607
  if (!Array.isArray(cloned)) {
@@ -35107,8 +35612,123 @@ function capturedModelInput(modelInput) {
35107
35612
  return void 0;
35108
35613
  }
35109
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
+ }
35110
35728
  function isCapturedModelInput(input) {
35111
- 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
+ );
35112
35732
  }
35113
35733
  function llmInputKey(sessionId, turnId, stepIndex) {
35114
35734
  return `${sessionId}\0${turnId}\0${stepIndex}`;
@@ -38503,6 +39123,8 @@ var BaseNode = class {
38503
39123
  this.graph = graph;
38504
39124
  this.id = id;
38505
39125
  }
39126
+ graph;
39127
+ id;
38506
39128
  __type = "node";
38507
39129
  dependencies = [];
38508
39130
  addDependency(dependency) {
@@ -38536,6 +39158,7 @@ var PromptNode = class extends BaseNode {
38536
39158
  super(graph, id);
38537
39159
  this.prompt = prompt;
38538
39160
  }
39161
+ prompt;
38539
39162
  async build(context) {
38540
39163
  return {
38541
39164
  type: "function",
@@ -38548,6 +39171,7 @@ var GateNode = class extends BaseNode {
38548
39171
  super(graph, id);
38549
39172
  this.condition = condition;
38550
39173
  }
39174
+ condition;
38551
39175
  async build(context) {
38552
39176
  return {
38553
39177
  type: "gate",
@@ -38572,6 +39196,7 @@ var PromptTemplateNode = class extends BaseNode {
38572
39196
  super(graph, id);
38573
39197
  this.prompt = prompt;
38574
39198
  }
39199
+ prompt;
38575
39200
  async build(context) {
38576
39201
  return {
38577
39202
  type: "prompt_template",
@@ -38584,6 +39209,7 @@ var LiteralNode = class extends BaseNode {
38584
39209
  super(graph, id);
38585
39210
  this.value = value;
38586
39211
  }
39212
+ value;
38587
39213
  async build(context) {
38588
39214
  return {
38589
39215
  type: "literal",
@@ -39677,6 +40303,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
39677
40303
  this._state = _state;
39678
40304
  this.spanTypeFilter = spanTypeFilter;
39679
40305
  }
40306
+ _objectId;
40307
+ rootSpanId;
40308
+ _state;
40309
+ spanTypeFilter;
39680
40310
  static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
39681
40311
  const children = [
39682
40312
  // Base filter: root_span_id = 'value'
@@ -40127,6 +40757,8 @@ var EvalResultWithSummary = class {
40127
40757
  this.summary = summary;
40128
40758
  this.results = results;
40129
40759
  }
40760
+ summary;
40761
+ results;
40130
40762
  /**
40131
40763
  * @deprecated Use `summary` instead.
40132
40764
  */
@@ -41545,6 +42177,7 @@ var ToolBuilder = class {
41545
42177
  constructor(project) {
41546
42178
  this.project = project;
41547
42179
  }
42180
+ project;
41548
42181
  taskCounter = 0;
41549
42182
  // This type definition is just a catch all so that the implementation can be
41550
42183
  // less specific than the two more specific declarations above.
@@ -41575,6 +42208,7 @@ var ScorerBuilder = class {
41575
42208
  constructor(project) {
41576
42209
  this.project = project;
41577
42210
  }
42211
+ project;
41578
42212
  taskCounter = 0;
41579
42213
  create(opts) {
41580
42214
  this.taskCounter++;
@@ -41634,6 +42268,7 @@ var ClassifierBuilder = class {
41634
42268
  constructor(project) {
41635
42269
  this.project = project;
41636
42270
  }
42271
+ project;
41637
42272
  taskCounter = 0;
41638
42273
  create(opts) {
41639
42274
  this.taskCounter++;
@@ -41669,6 +42304,7 @@ var CodeFunction = class {
41669
42304
  throw new Error("parameters are required if return type is defined");
41670
42305
  }
41671
42306
  }
42307
+ project;
41672
42308
  handler;
41673
42309
  name;
41674
42310
  slug;
@@ -41756,6 +42392,7 @@ var PromptBuilder = class {
41756
42392
  constructor(project) {
41757
42393
  this.project = project;
41758
42394
  }
42395
+ project;
41759
42396
  create(opts) {
41760
42397
  const toolFunctions = [];
41761
42398
  const rawTools = [];
@@ -41832,6 +42469,7 @@ var ParametersBuilder = class {
41832
42469
  constructor(project) {
41833
42470
  this.project = project;
41834
42471
  }
42472
+ project;
41835
42473
  create(opts) {
41836
42474
  const slug = opts.slug ?? slugify(opts.name, { lower: true, strict: true });
41837
42475
  const codeParameters = new CodeParameters(this.project, {