braintrust 3.23.0 → 3.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dev/dist/index.d.mts +6 -0
  2. package/dev/dist/index.d.ts +6 -0
  3. package/dev/dist/index.js +902 -588
  4. package/dev/dist/index.mjs +320 -6
  5. package/dist/apply-auto-instrumentation.js +211 -189
  6. package/dist/apply-auto-instrumentation.mjs +23 -1
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +40 -0
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +40 -0
  10. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +40 -0
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +40 -0
  14. package/dist/auto-instrumentations/bundler/vite.d.mts +1 -1
  15. package/dist/auto-instrumentations/bundler/vite.d.ts +1 -1
  16. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  17. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +40 -0
  18. package/dist/auto-instrumentations/bundler/webpack.cjs +40 -0
  19. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  20. package/dist/auto-instrumentations/{chunk-KIMLYPRW.mjs → chunk-BURMPO7L.mjs} +1 -1
  21. package/dist/auto-instrumentations/{chunk-YXLNSAMJ.mjs → chunk-F43DNLPD.mjs} +40 -0
  22. package/dist/auto-instrumentations/{chunk-EXY7QCJD.mjs → chunk-GSZHTAQW.mjs} +1 -1
  23. package/dist/auto-instrumentations/hook.mjs +150 -1
  24. package/dist/auto-instrumentations/index.cjs +40 -0
  25. package/dist/auto-instrumentations/index.mjs +1 -1
  26. package/dist/browser.d.mts +131 -9
  27. package/dist/browser.d.ts +131 -9
  28. package/dist/browser.js +703 -67
  29. package/dist/browser.mjs +703 -67
  30. package/dist/{chunk-CDIKAHDZ.js → chunk-7AUY2XWX.js} +21 -1
  31. package/dist/{chunk-36IPYKMG.mjs → chunk-7F6GCRHH.mjs} +20 -0
  32. package/dist/{chunk-FZWPFCVE.js → chunk-SU6EHKJV.js} +1085 -801
  33. package/dist/{chunk-IXL4PMY4.mjs → chunk-XE5FS7QY.mjs} +291 -7
  34. package/dist/cli.js +328 -10
  35. package/dist/edge-light.js +703 -67
  36. package/dist/edge-light.mjs +703 -67
  37. package/dist/index.d.mts +131 -9
  38. package/dist/index.d.ts +131 -9
  39. package/dist/index.js +891 -532
  40. package/dist/index.mjs +423 -64
  41. package/dist/instrumentation/index.d.mts +130 -9
  42. package/dist/instrumentation/index.d.ts +130 -9
  43. package/dist/instrumentation/index.js +601 -67
  44. package/dist/instrumentation/index.mjs +601 -67
  45. package/dist/vitest-evals-reporter.js +17 -16
  46. package/dist/vitest-evals-reporter.mjs +3 -2
  47. package/dist/workerd.js +703 -67
  48. package/dist/workerd.mjs +703 -67
  49. package/package.json +3 -3
  50. package/util/dist/index.js +4 -0
  51. package/util/dist/index.mjs +4 -0
package/dist/browser.mjs CHANGED
@@ -24,6 +24,7 @@ var DefaultChannel = class {
24
24
  constructor(name) {
25
25
  this.name = name;
26
26
  }
27
+ name;
27
28
  hasSubscribers = false;
28
29
  subscribe(_subscription) {
29
30
  }
@@ -1080,6 +1081,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1080
1081
  constructor(data) {
1081
1082
  this.data = data;
1082
1083
  }
1084
+ data;
1083
1085
  toStr() {
1084
1086
  const jsonObj = {
1085
1087
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1587,6 +1589,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1587
1589
  constructor(data) {
1588
1590
  this.data = data;
1589
1591
  }
1592
+ data;
1590
1593
  toStr() {
1591
1594
  const jsonObj = {
1592
1595
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -4822,6 +4825,97 @@ var SpanCache = class {
4822
4825
  }
4823
4826
  };
4824
4827
 
4828
+ // src/span-origin.ts
4829
+ var SDK_VERSION = true ? "3.24.0" : "0.0.0";
4830
+ function detectSpanOriginEnvironment(explicit) {
4831
+ if (explicit) return explicit;
4832
+ const envType = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_TYPE");
4833
+ const envName = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_NAME");
4834
+ if (envType || envName) {
4835
+ return {
4836
+ ...envType ? { type: envType } : {},
4837
+ ...envName ? { name: envName } : {}
4838
+ };
4839
+ }
4840
+ const ci = firstPresent([
4841
+ ["GITHUB_ACTIONS", "github_actions"],
4842
+ ["GITLAB_CI", "gitlab_ci"],
4843
+ ["CIRCLECI", "circleci"],
4844
+ ["BUILDKITE", "buildkite"],
4845
+ ["JENKINS_URL", "jenkins"],
4846
+ ["JENKINS_HOME", "jenkins"],
4847
+ ["TF_BUILD", "azure_pipelines"],
4848
+ ["TEAMCITY_VERSION", "teamcity"],
4849
+ ["TRAVIS", "travis"],
4850
+ ["BITBUCKET_BUILD_NUMBER", "bitbucket"]
4851
+ ]);
4852
+ if (ci) return { type: "ci", name: ci };
4853
+ if (isomorph_default.getEnv("CI")) return { type: "ci", name: "ci" };
4854
+ const earlyServer = firstPresent([
4855
+ ["VERCEL", "vercel"],
4856
+ ["NETLIFY", "netlify"]
4857
+ ]);
4858
+ if (earlyServer) return { type: "server", name: earlyServer };
4859
+ if (isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI") || isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI_V4")) {
4860
+ return { type: "server", name: "ecs" };
4861
+ }
4862
+ const awsExecutionEnv = isomorph_default.getEnv("AWS_EXECUTION_ENV");
4863
+ if (awsExecutionEnv?.startsWith("AWS_ECS_")) {
4864
+ return { type: "server", name: "ecs" };
4865
+ }
4866
+ if (awsExecutionEnv?.startsWith("AWS_Lambda_")) {
4867
+ return { type: "server", name: "aws_lambda" };
4868
+ }
4869
+ if (isomorph_default.getEnv("AWS_LAMBDA_FUNCTION_NAME")) {
4870
+ return { type: "server", name: "aws_lambda" };
4871
+ }
4872
+ const server = firstPresent([
4873
+ ["K_SERVICE", "cloud_run"],
4874
+ ["FUNCTION_TARGET", "gcp_functions"],
4875
+ ["KUBERNETES_SERVICE_HOST", "kubernetes"],
4876
+ ["DYNO", "heroku"],
4877
+ ["FLY_APP_NAME", "fly"],
4878
+ ["RAILWAY_ENVIRONMENT", "railway"],
4879
+ ["RENDER_SERVICE_NAME", "render"]
4880
+ ]);
4881
+ if (server) return { type: "server", name: server };
4882
+ return deploymentModeEnvironment("NODE_ENV", isomorph_default.getEnv("NODE_ENV"));
4883
+ }
4884
+ function makeSpanOrigin(instrumentationName, environment) {
4885
+ return {
4886
+ name: "braintrust.sdk.javascript",
4887
+ version: SDK_VERSION,
4888
+ instrumentation: { name: instrumentationName },
4889
+ ...environment ? { environment } : {}
4890
+ };
4891
+ }
4892
+ function mergeSpanOriginContext(context, instrumentationName, environment) {
4893
+ const next = { ...context ?? {} };
4894
+ const current = isObject2(next.span_origin) ? { ...next.span_origin } : {};
4895
+ next.span_origin = {
4896
+ ...makeSpanOrigin(instrumentationName, environment),
4897
+ ...current
4898
+ };
4899
+ return next;
4900
+ }
4901
+ function firstPresent(entries) {
4902
+ return entries.find(([key]) => Boolean(isomorph_default.getEnv(key)))?.[1];
4903
+ }
4904
+ function deploymentModeEnvironment(_key, value) {
4905
+ if (!value) return void 0;
4906
+ const normalized = value.toLowerCase();
4907
+ if (normalized === "production" || normalized === "staging") {
4908
+ return { type: "server", name: normalized };
4909
+ }
4910
+ if (normalized === "development" || normalized === "local") {
4911
+ return { type: "local", name: normalized };
4912
+ }
4913
+ return { name: value };
4914
+ }
4915
+ function isObject2(value) {
4916
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4917
+ }
4918
+
4825
4919
  // src/logger.ts
4826
4920
  var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
4827
4921
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
@@ -4870,6 +4964,7 @@ var LoginInvalidOrgError = class extends Error {
4870
4964
  super(message);
4871
4965
  this.message = message;
4872
4966
  }
4967
+ message;
4873
4968
  };
4874
4969
  var REDACTION_FIELDS = [
4875
4970
  "input",
@@ -4885,6 +4980,8 @@ var MaskingError = class {
4885
4980
  this.fieldName = fieldName;
4886
4981
  this.errorType = errorType;
4887
4982
  }
4983
+ fieldName;
4984
+ errorType;
4888
4985
  get errorMsg() {
4889
4986
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
4890
4987
  }
@@ -5094,7 +5191,9 @@ var BraintrustState = class _BraintrustState {
5094
5191
  diskCache: parametersDiskCache
5095
5192
  });
5096
5193
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5194
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5097
5195
  }
5196
+ loginParams;
5098
5197
  id;
5099
5198
  currentExperiment;
5100
5199
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5129,6 +5228,7 @@ var BraintrustState = class _BraintrustState {
5129
5228
  _idGenerator = null;
5130
5229
  _contextManager = null;
5131
5230
  _otelFlushCallback = null;
5231
+ spanOriginEnvironment;
5132
5232
  resetLoginInfo() {
5133
5233
  this.appUrl = null;
5134
5234
  this.appPublicUrl = null;
@@ -7747,6 +7847,7 @@ function initLogger(options = {}) {
7747
7847
  orgName,
7748
7848
  forceLogin,
7749
7849
  debugLogLevel,
7850
+ environment,
7750
7851
  fetch: fetch2,
7751
7852
  state: stateArg
7752
7853
  } = options || {};
@@ -7763,6 +7864,7 @@ function initLogger(options = {}) {
7763
7864
  };
7764
7865
  const state = stateArg ?? _globalState;
7765
7866
  state.setDebugLogLevel(debugLogLevel);
7867
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7766
7868
  state.enforceQueueSizeLimit(true);
7767
7869
  const lazyMetadata = new LazyValue(
7768
7870
  async () => {
@@ -8954,6 +9056,11 @@ var ObjectFetcher = class {
8954
9056
  this._internal_btql = _internal_btql;
8955
9057
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
8956
9058
  }
9059
+ objectType;
9060
+ pinnedVersion;
9061
+ mutateRecord;
9062
+ _internal_btql;
9063
+ _internalBrainstoreRealtime;
8957
9064
  _fetchedData = void 0;
8958
9065
  get id() {
8959
9066
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -9392,6 +9499,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9392
9499
  this.state = state;
9393
9500
  this.lazyMetadata = lazyMetadata;
9394
9501
  }
9502
+ state;
9503
+ lazyMetadata;
9395
9504
  get id() {
9396
9505
  return (async () => {
9397
9506
  return (await this.lazyMetadata.get()).experiment.id;
@@ -9514,7 +9623,11 @@ var SpanImpl = class _SpanImpl {
9514
9623
  metrics: {
9515
9624
  start: args.startTime ?? getCurrentUnixTimestamp()
9516
9625
  },
9517
- context: { ...callerLocation },
9626
+ context: mergeSpanOriginContext(
9627
+ { ...callerLocation },
9628
+ "braintrust-js-logger",
9629
+ this._state.spanOriginEnvironment
9630
+ ),
9518
9631
  span_attributes: {
9519
9632
  name,
9520
9633
  type,
@@ -9888,6 +10001,7 @@ var Dataset2 = class extends ObjectFetcher {
9888
10001
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
9889
10002
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
9890
10003
  }
10004
+ state;
9891
10005
  lazyMetadata;
9892
10006
  __braintrust_dataset_marker = true;
9893
10007
  newRecords = 0;
@@ -10402,6 +10516,9 @@ var Prompt2 = class _Prompt {
10402
10516
  this.noTrace = noTrace;
10403
10517
  void this.__braintrust_prompt_marker;
10404
10518
  }
10519
+ metadata;
10520
+ defaults;
10521
+ noTrace;
10405
10522
  parsedPromptData;
10406
10523
  hasParsedPromptData = false;
10407
10524
  __braintrust_prompt_marker = true;
@@ -10639,6 +10756,7 @@ var RemoteEvalParameters = class {
10639
10756
  this.metadata = metadata;
10640
10757
  void this.__braintrust_parameters_marker;
10641
10758
  }
10759
+ metadata;
10642
10760
  __braintrust_parameters_marker = true;
10643
10761
  get id() {
10644
10762
  return this.metadata.id;
@@ -15104,6 +15222,24 @@ var aiSDKChannels = defineChannels("ai", {
15104
15222
  kind: "sync-stream"
15105
15223
  })
15106
15224
  });
15225
+ var harnessAgentChannels = defineChannels("@ai-sdk/harness", {
15226
+ generate: channel({
15227
+ channelName: "HarnessAgent.generate",
15228
+ kind: "async"
15229
+ }),
15230
+ stream: channel({
15231
+ channelName: "HarnessAgent.stream",
15232
+ kind: "async"
15233
+ }),
15234
+ continueGenerate: channel({
15235
+ channelName: "HarnessAgent.continueGenerate",
15236
+ kind: "async"
15237
+ }),
15238
+ continueStream: channel({
15239
+ channelName: "HarnessAgent.continueStream",
15240
+ kind: "async"
15241
+ })
15242
+ });
15107
15243
 
15108
15244
  // src/instrumentation/plugins/ai-sdk-plugin.ts
15109
15245
  var DEFAULT_DENY_OUTPUT_PATHS = [
@@ -15372,6 +15508,84 @@ var AISDKPlugin = class extends BasePlugin {
15372
15508
  })
15373
15509
  })
15374
15510
  );
15511
+ this.unsubscribers.push(
15512
+ traceStreamingChannel(harnessAgentChannels.generate, {
15513
+ name: "HarnessAgent.generate",
15514
+ type: "task" /* TASK */,
15515
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15516
+ extractOutput: (result, endEvent) => processAISDKOutput(
15517
+ result,
15518
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15519
+ ),
15520
+ extractMetrics: (result) => extractTokenMetrics(result),
15521
+ aggregateChunks: aggregateAISDKChunks
15522
+ })
15523
+ );
15524
+ this.unsubscribers.push(
15525
+ traceStreamingChannel(harnessAgentChannels.stream, {
15526
+ name: "HarnessAgent.stream",
15527
+ type: "task" /* TASK */,
15528
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15529
+ extractOutput: (result, endEvent) => processAISDKOutput(
15530
+ result,
15531
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15532
+ ),
15533
+ extractMetrics: (result, startTime) => ({
15534
+ ...extractTokenMetrics(result),
15535
+ ...startTime === void 0 ? {} : {
15536
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15537
+ }
15538
+ }),
15539
+ aggregateChunks: aggregateAISDKChunks,
15540
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15541
+ defaultDenyOutputPaths: denyOutputPaths,
15542
+ endEvent,
15543
+ result,
15544
+ resolvePromiseUsage: true,
15545
+ span,
15546
+ startTime
15547
+ })
15548
+ })
15549
+ );
15550
+ this.unsubscribers.push(
15551
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
15552
+ name: "HarnessAgent.continueGenerate",
15553
+ type: "task" /* TASK */,
15554
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15555
+ extractOutput: (result, endEvent) => processAISDKOutput(
15556
+ result,
15557
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15558
+ ),
15559
+ extractMetrics: (result) => extractTokenMetrics(result),
15560
+ aggregateChunks: aggregateAISDKChunks
15561
+ })
15562
+ );
15563
+ this.unsubscribers.push(
15564
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
15565
+ name: "HarnessAgent.continueStream",
15566
+ type: "task" /* TASK */,
15567
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15568
+ extractOutput: (result, endEvent) => processAISDKOutput(
15569
+ result,
15570
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15571
+ ),
15572
+ extractMetrics: (result, startTime) => ({
15573
+ ...extractTokenMetrics(result),
15574
+ ...startTime === void 0 ? {} : {
15575
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15576
+ }
15577
+ }),
15578
+ aggregateChunks: aggregateAISDKChunks,
15579
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15580
+ defaultDenyOutputPaths: denyOutputPaths,
15581
+ endEvent,
15582
+ result,
15583
+ resolvePromiseUsage: true,
15584
+ span,
15585
+ startTime
15586
+ })
15587
+ })
15588
+ );
15375
15589
  this.unsubscribers.push(
15376
15590
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
15377
15591
  name: "ToolLoopAgent.generate",
@@ -15902,6 +16116,45 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
15902
16116
  metadata
15903
16117
  };
15904
16118
  }
16119
+ function prepareAISDKHarnessAgentInput(params, self) {
16120
+ if (isObject(self)) {
16121
+ try {
16122
+ if (isObject(self.settings)) {
16123
+ const settings = self.settings;
16124
+ if (settings.telemetry === void 0) {
16125
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
16126
+ }
16127
+ }
16128
+ } catch {
16129
+ }
16130
+ }
16131
+ const selectedInput = {};
16132
+ if (params.prompt !== void 0) {
16133
+ selectedInput.prompt = params.prompt;
16134
+ }
16135
+ if (params.messages !== void 0) {
16136
+ selectedInput.messages = params.messages;
16137
+ }
16138
+ if (params.toolApprovalContinuations !== void 0) {
16139
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
16140
+ }
16141
+ const metadata = extractMetadataFromCallParams({}, self);
16142
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
16143
+ metadata.sessionId = params.session.sessionId;
16144
+ }
16145
+ if (isObject(self)) {
16146
+ if (typeof self.harnessId === "string") {
16147
+ metadata.harnessId = self.harnessId;
16148
+ }
16149
+ if (typeof self.permissionMode === "string") {
16150
+ metadata.permissionMode = self.permissionMode;
16151
+ }
16152
+ }
16153
+ return {
16154
+ input: processAISDKCallInput(selectedInput).input,
16155
+ metadata
16156
+ };
16157
+ }
15905
16158
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
15906
16159
  registerWorkflowAgentWrapperSpan(span);
15907
16160
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -16749,6 +17002,7 @@ function patchAISDKStreamingResult(args) {
16749
17002
  endEvent,
16750
17003
  onComplete,
16751
17004
  result,
17005
+ resolvePromiseUsage,
16752
17006
  span,
16753
17007
  startTime
16754
17008
  } = args;
@@ -16775,6 +17029,22 @@ function patchAISDKStreamingResult(args) {
16775
17029
  outputLogged = true;
16776
17030
  try {
16777
17031
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
17032
+ if (resolvePromiseUsage) {
17033
+ try {
17034
+ const resultRecord2 = result;
17035
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
17036
+ if (isPromiseLike(pendingUsage)) {
17037
+ const usage = await Promise.resolve(pendingUsage);
17038
+ if (isObject(usage)) {
17039
+ Object.assign(
17040
+ metrics,
17041
+ extractTokenMetrics({ usage })
17042
+ );
17043
+ }
17044
+ }
17045
+ } catch {
17046
+ }
17047
+ }
16778
17048
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
16779
17049
  metrics.time_to_first_token = firstChunkTime - startTime;
16780
17050
  }
@@ -18005,8 +18275,6 @@ function filterSerializableOptions(options) {
18005
18275
  "additionalDirectories",
18006
18276
  "permissionMode",
18007
18277
  "debug",
18008
- "apiKey",
18009
- "apiKeySource",
18010
18278
  "agentName",
18011
18279
  "instructions"
18012
18280
  ];
@@ -29034,6 +29302,16 @@ function cleanObject(obj) {
29034
29302
  })
29035
29303
  );
29036
29304
  }
29305
+ function normalizeTokenMetrics(obj) {
29306
+ const metrics = cleanObject(obj);
29307
+ if (metrics.total_tokens !== void 0) {
29308
+ metrics.tokens = metrics.total_tokens;
29309
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
29310
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
29311
+ }
29312
+ delete metrics.total_tokens;
29313
+ return metrics;
29314
+ }
29037
29315
  function walkGenerations(response) {
29038
29316
  const result = [];
29039
29317
  const generations = response.generations || [];
@@ -29080,7 +29358,7 @@ function getMetricsFromResponse(response) {
29080
29358
  continue;
29081
29359
  }
29082
29360
  const inputTokenDetails = usageMetadata.input_token_details;
29083
- return cleanObject({
29361
+ return normalizeTokenMetrics({
29084
29362
  total_tokens: usageMetadata.total_tokens,
29085
29363
  prompt_tokens: usageMetadata.input_tokens,
29086
29364
  completion_tokens: usageMetadata.output_tokens,
@@ -29090,7 +29368,7 @@ function getMetricsFromResponse(response) {
29090
29368
  }
29091
29369
  const llmOutput = response.llmOutput || {};
29092
29370
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
29093
- return cleanObject({
29371
+ return normalizeTokenMetrics({
29094
29372
  total_tokens: tokenUsage.totalTokens,
29095
29373
  prompt_tokens: tokenUsage.promptTokens,
29096
29374
  completion_tokens: tokenUsage.completionTokens
@@ -32779,6 +33057,26 @@ function wrapAISDK(aiSDK, options = {}) {
32779
33057
  }
32780
33058
  });
32781
33059
  }
33060
+ function isHarnessAgentInstance(instance) {
33061
+ try {
33062
+ const visited = /* @__PURE__ */ new Set();
33063
+ let prototype = Object.getPrototypeOf(instance);
33064
+ while (prototype !== null && !visited.has(prototype)) {
33065
+ visited.add(prototype);
33066
+ const constructor = Object.getOwnPropertyDescriptor(
33067
+ prototype,
33068
+ "constructor"
33069
+ )?.value;
33070
+ const constructorName = typeof constructor === "function" ? Object.getOwnPropertyDescriptor(constructor, "name")?.value : void 0;
33071
+ if (constructorName === "HarnessAgent") {
33072
+ return true;
33073
+ }
33074
+ prototype = Object.getPrototypeOf(prototype);
33075
+ }
33076
+ } catch {
33077
+ }
33078
+ return false;
33079
+ }
32782
33080
  var wrapAgentClass = (AgentClass, options = {}) => {
32783
33081
  const typedAgentClass = AgentClass;
32784
33082
  return new Proxy(typedAgentClass, {
@@ -32788,9 +33086,46 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32788
33086
  args,
32789
33087
  newTarget
32790
33088
  );
33089
+ const harnessAgent = isHarnessAgentInstance(instance) ? instance : null;
32791
33090
  return new Proxy(instance, {
32792
33091
  get(instanceTarget, prop, instanceReceiver) {
32793
33092
  const original = Reflect.get(instanceTarget, prop, instanceTarget);
33093
+ if (harnessAgent && typeof original === "function") {
33094
+ switch (prop) {
33095
+ case "generate":
33096
+ return wrapHarnessAgentGenerate(
33097
+ original,
33098
+ harnessAgent,
33099
+ harnessAgentChannels.generate,
33100
+ "HarnessAgent.generate",
33101
+ options
33102
+ );
33103
+ case "stream":
33104
+ return wrapHarnessAgentStream(
33105
+ original,
33106
+ harnessAgent,
33107
+ harnessAgentChannels.stream,
33108
+ "HarnessAgent.stream",
33109
+ options
33110
+ );
33111
+ case "continueGenerate":
33112
+ return wrapHarnessAgentGenerate(
33113
+ original,
33114
+ harnessAgent,
33115
+ harnessAgentChannels.continueGenerate,
33116
+ "HarnessAgent.continueGenerate",
33117
+ options
33118
+ );
33119
+ case "continueStream":
33120
+ return wrapHarnessAgentStream(
33121
+ original,
33122
+ harnessAgent,
33123
+ harnessAgentChannels.continueStream,
33124
+ "HarnessAgent.continueStream",
33125
+ options
33126
+ );
33127
+ }
33128
+ }
32794
33129
  if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
32795
33130
  return wrapAgentGenerate(original, instanceTarget, options);
32796
33131
  }
@@ -32806,6 +33141,26 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32806
33141
  }
32807
33142
  });
32808
33143
  };
33144
+ var wrapHarnessAgentGenerate = (generate, instance, channel2, name, options) => makeGenerateTextWrapper(
33145
+ channel2,
33146
+ name,
33147
+ generate.bind(instance),
33148
+ {
33149
+ self: instance,
33150
+ spanType: "task" /* TASK */
33151
+ },
33152
+ options
33153
+ );
33154
+ var wrapHarnessAgentStream = (stream, instance, channel2, name, options) => makeStreamWrapper(
33155
+ channel2,
33156
+ name,
33157
+ stream.bind(instance),
33158
+ {
33159
+ self: instance,
33160
+ spanType: "task" /* TASK */
33161
+ },
33162
+ options
33163
+ );
32809
33164
  var wrapAgentGenerate = (generate, instance, options = {}) => {
32810
33165
  const defaultName = `${instance.constructor.name}.generate`;
32811
33166
  return async (params) => makeGenerateTextWrapper(
@@ -33032,6 +33387,7 @@ var BraintrustLanguageModelWrapper = class {
33032
33387
  this.supportsUrl = (url) => this.model.supportsUrl(url);
33033
33388
  }
33034
33389
  }
33390
+ model;
33035
33391
  supportsUrl;
33036
33392
  get specificationVersion() {
33037
33393
  return this.model.specificationVersion;
@@ -33614,6 +33970,7 @@ function BraintrustMiddleware(config = {}) {
33614
33970
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
33615
33971
  var MAX_EVE_CACHE_ENTRIES = 1e4;
33616
33972
  var MAX_STORED_LLM_INPUTS = 100;
33973
+ var MAX_STORED_REASONING_BLOCKS = 100;
33617
33974
  var MAX_STORED_SPAN_REFERENCES = 1e4;
33618
33975
  var MAX_STORED_STEP_STARTS = 1e4;
33619
33976
  function braintrustEveHook(options) {
@@ -33652,6 +34009,7 @@ var ResumedEveSpan = class {
33652
34009
  this.reference = reference;
33653
34010
  this.endTime = reference.endTime;
33654
34011
  }
34012
+ reference;
33655
34013
  endTime;
33656
34014
  get rootSpanId() {
33657
34015
  return this.reference.rootSpanId;
@@ -33684,6 +34042,7 @@ var EveBridge = class {
33684
34042
  constructor(state) {
33685
34043
  this.state = state;
33686
34044
  }
34045
+ state;
33687
34046
  eventQueuesBySession = /* @__PURE__ */ new Map();
33688
34047
  completedToolKeys = new LRUCache({
33689
34048
  max: MAX_EVE_CACHE_ENTRIES
@@ -33862,6 +34221,9 @@ var EveBridge = class {
33862
34221
  case "step.started":
33863
34222
  await this.handleStepStarted(event, ctx, hookMetadata);
33864
34223
  return true;
34224
+ case "reasoning.completed":
34225
+ this.handleReasoningCompleted(event, ctx);
34226
+ return true;
33865
34227
  case "message.completed":
33866
34228
  this.handleMessageCompleted(event, ctx);
33867
34229
  return true;
@@ -33953,6 +34315,7 @@ var EveBridge = class {
33953
34315
  key,
33954
34316
  metadata,
33955
34317
  metrics: {},
34318
+ sessionId,
33956
34319
  span,
33957
34320
  stepsByIndex: /* @__PURE__ */ new Map(),
33958
34321
  turnId: event.data.turnId
@@ -33983,6 +34346,12 @@ var EveBridge = class {
33983
34346
  const endTime = eventTime2(event);
33984
34347
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
33985
34348
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34349
+ clearStoredEveReasoning(
34350
+ this.state,
34351
+ sessionId,
34352
+ event.data.turnId,
34353
+ event.data.stepIndex
34354
+ );
33986
34355
  }
33987
34356
  const stepOrdinal = this.stepOrdinal(event);
33988
34357
  const metadata = { ...turn.metadata };
@@ -33992,6 +34361,13 @@ var EveBridge = class {
33992
34361
  event.data.turnId,
33993
34362
  event.data.stepIndex
33994
34363
  );
34364
+ const reasoning = readStoredEveReasoning(
34365
+ this.state,
34366
+ sessionId,
34367
+ event.data.turnId,
34368
+ event.data.stepIndex
34369
+ );
34370
+ const output = mergeEveReasoning(void 0, reasoning);
33995
34371
  const { rowId: eventId, spanId } = await generateEveIds(
33996
34372
  "step",
33997
34373
  sessionId,
@@ -34009,32 +34385,52 @@ var EveBridge = class {
34009
34385
  spanId,
34010
34386
  startTime: eventTime2(event)
34011
34387
  });
34012
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
34388
+ span.log({
34389
+ ...input !== void 0 ? { input } : {},
34390
+ metadata
34391
+ });
34013
34392
  turn.stepsByIndex.set(event.data.stepIndex, {
34014
34393
  ...input !== void 0 ? { input } : {},
34015
34394
  metadata,
34016
34395
  metrics: {},
34396
+ ...output !== void 0 ? { output } : {},
34397
+ reasoning,
34017
34398
  span
34018
34399
  });
34019
34400
  }
34401
+ handleReasoningCompleted(event, ctx) {
34402
+ const sessionId = sessionIdFromContext(ctx);
34403
+ if (!sessionId) {
34404
+ return;
34405
+ }
34406
+ const reasoning = storeEveReasoning(this.state, sessionId, event);
34407
+ const step = this.stepForEvent(event, ctx);
34408
+ if (step) {
34409
+ step.reasoning = reasoning;
34410
+ step.output = mergeEveReasoning(step.output, reasoning);
34411
+ }
34412
+ }
34020
34413
  handleMessageCompleted(event, ctx) {
34021
34414
  const step = this.stepForEvent(event, ctx);
34022
34415
  if (!step) {
34023
34416
  return;
34024
34417
  }
34025
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
34418
+ const existingMessage = eveOutputMessage(step.output);
34026
34419
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
34027
- step.output = [
34028
- {
34029
- finish_reason: normalizedFinishReason(event.data.finishReason),
34030
- index: 0,
34031
- message: {
34032
- content: event.data.message,
34033
- role: "assistant",
34034
- ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34420
+ step.output = mergeEveReasoning(
34421
+ [
34422
+ {
34423
+ finish_reason: normalizedFinishReason(event.data.finishReason),
34424
+ index: 0,
34425
+ message: {
34426
+ content: event.data.message,
34427
+ role: "assistant",
34428
+ ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34429
+ }
34035
34430
  }
34036
- }
34037
- ];
34431
+ ],
34432
+ step.reasoning
34433
+ );
34038
34434
  const turn = this.turnForEvent(event, ctx);
34039
34435
  if (turn && event.data.finishReason !== "tool-calls") {
34040
34436
  turn.output = event.data.message;
@@ -34043,16 +34439,19 @@ var EveBridge = class {
34043
34439
  handleResultCompleted(event, ctx) {
34044
34440
  const step = this.stepForEvent(event, ctx);
34045
34441
  if (step) {
34046
- step.output = [
34047
- {
34048
- finish_reason: "stop",
34049
- index: 0,
34050
- message: {
34051
- content: event.data.result,
34052
- role: "assistant"
34442
+ step.output = mergeEveReasoning(
34443
+ [
34444
+ {
34445
+ finish_reason: "stop",
34446
+ index: 0,
34447
+ message: {
34448
+ content: event.data.result,
34449
+ role: "assistant"
34450
+ }
34053
34451
  }
34054
- }
34055
- ];
34452
+ ],
34453
+ step.reasoning
34454
+ );
34056
34455
  }
34057
34456
  const turn = this.turnForEvent(event, ctx);
34058
34457
  if (turn) {
@@ -34102,18 +34501,20 @@ var EveBridge = class {
34102
34501
  type: "function"
34103
34502
  });
34104
34503
  }
34105
- step.output = [
34106
- {
34107
- finish_reason: "tool_calls",
34108
- index: 0,
34109
- message: {
34110
- content: null,
34111
- role: "assistant",
34112
- tool_calls: [...toolCallsById.values()]
34504
+ step.output = mergeEveReasoning(
34505
+ [
34506
+ {
34507
+ finish_reason: "tool_calls",
34508
+ index: 0,
34509
+ message: {
34510
+ content: null,
34511
+ role: "assistant",
34512
+ tool_calls: [...toolCallsById.values()]
34513
+ }
34113
34514
  }
34114
- }
34115
- ];
34116
- step.span.log({ metadata: step.metadata, output: step.output });
34515
+ ],
34516
+ step.reasoning
34517
+ );
34117
34518
  }
34118
34519
  async handleActionResult(event, ctx, hookMetadata) {
34119
34520
  if (isToolResult(event.data.result)) {
@@ -34291,6 +34692,7 @@ var EveBridge = class {
34291
34692
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
34292
34693
  };
34293
34694
  step.metrics = { ...step.metrics, ...metrics };
34695
+ const sessionId = sessionIdFromContext(ctx);
34294
34696
  if (Array.isArray(step.output) && isObject(step.output[0])) {
34295
34697
  const finishReason = step.output[0].finish_reason;
34296
34698
  if (typeof finishReason !== "string") {
@@ -34315,6 +34717,14 @@ var EveBridge = class {
34315
34717
  turn.stepsByIndex.delete(event.data.stepIndex);
34316
34718
  }
34317
34719
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34720
+ if (sessionId) {
34721
+ clearStoredEveReasoning(
34722
+ this.state,
34723
+ sessionId,
34724
+ event.data.turnId,
34725
+ event.data.stepIndex
34726
+ );
34727
+ }
34318
34728
  }
34319
34729
  handleStepFailed(event, ctx) {
34320
34730
  const step = this.stepForEvent(event, ctx);
@@ -34332,6 +34742,15 @@ var EveBridge = class {
34332
34742
  const turn = this.turnForEvent(event, ctx);
34333
34743
  turn?.stepsByIndex.delete(event.data.stepIndex);
34334
34744
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34745
+ const sessionId = sessionIdFromContext(ctx);
34746
+ if (sessionId) {
34747
+ clearStoredEveReasoning(
34748
+ this.state,
34749
+ sessionId,
34750
+ event.data.turnId,
34751
+ event.data.stepIndex
34752
+ );
34753
+ }
34335
34754
  }
34336
34755
  handleTurnCompleted(event, ctx) {
34337
34756
  const turn = this.turnForEvent(event, ctx);
@@ -34429,6 +34848,7 @@ var EveBridge = class {
34429
34848
  key,
34430
34849
  metadata,
34431
34850
  metrics: {},
34851
+ sessionId,
34432
34852
  span,
34433
34853
  stepsByIndex: /* @__PURE__ */ new Map(),
34434
34854
  turnId: event.data.turnId
@@ -34691,6 +35111,9 @@ var EveBridge = class {
34691
35111
  const normalized = normalizeEveTraceState(current);
34692
35112
  return {
34693
35113
  ...normalized,
35114
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35115
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
35116
+ ),
34694
35117
  stepStarts: normalized.stepStarts.filter(
34695
35118
  (entry) => entry.turnId !== turn.turnId
34696
35119
  )
@@ -34730,6 +35153,7 @@ function emptyEveTraceState() {
34730
35153
  return {
34731
35154
  llmInputs: [],
34732
35155
  metadata: {},
35156
+ reasoningBlocks: [],
34733
35157
  spanReferences: [],
34734
35158
  stepStarts: []
34735
35159
  };
@@ -34780,6 +35204,21 @@ function normalizeEveTraceState(state) {
34780
35204
  const input = entry["input"];
34781
35205
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
34782
35206
  }).slice(-MAX_STORED_LLM_INPUTS) : [];
35207
+ const reasoningBlocks = Array.isArray(state["reasoningBlocks"]) ? state["reasoningBlocks"].flatMap((entry) => {
35208
+ if (!isObject(entry)) {
35209
+ return [];
35210
+ }
35211
+ const content = entry["content"];
35212
+ const eventAt = entry["eventAt"];
35213
+ const key = entry["key"];
35214
+ return typeof content === "string" && (eventAt === void 0 || typeof eventAt === "string") && typeof key === "string" ? [
35215
+ {
35216
+ content,
35217
+ ...typeof eventAt === "string" ? { eventAt } : {},
35218
+ key
35219
+ }
35220
+ ] : [];
35221
+ }).slice(-MAX_STORED_REASONING_BLOCKS) : [];
34783
35222
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
34784
35223
  if (!isObject(entry)) {
34785
35224
  return [];
@@ -34790,7 +35229,13 @@ function normalizeEveTraceState(state) {
34790
35229
  const turnId = entry["turnId"];
34791
35230
  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 }] : [];
34792
35231
  }).slice(-MAX_STORED_STEP_STARTS) : [];
34793
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
35232
+ return {
35233
+ llmInputs,
35234
+ metadata: { ...metadata },
35235
+ reasoningBlocks,
35236
+ spanReferences,
35237
+ stepStarts
35238
+ };
34794
35239
  }
34795
35240
  function readEveTraceState(state) {
34796
35241
  try {
@@ -34799,23 +35244,85 @@ function readEveTraceState(state) {
34799
35244
  return emptyEveTraceState();
34800
35245
  }
34801
35246
  }
34802
- function captureEveModelInput(state, input) {
34803
- if (!isObject(input)) {
34804
- return;
34805
- }
34806
- const session = input["session"];
34807
- const turn = input["turn"];
34808
- const step = input["step"];
34809
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
34810
- return;
34811
- }
34812
- const sessionId = session["id"];
34813
- const turnId = turn["id"];
34814
- const stepIndex = step["index"];
34815
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
34816
- return;
35247
+ function storeEveReasoning(state, sessionId, event) {
35248
+ const eventAt = event.meta?.at;
35249
+ const key = llmInputKey(sessionId, event.data.turnId, event.data.stepIndex);
35250
+ let stored = [];
35251
+ state.update((current) => {
35252
+ const normalized = normalizeEveTraceState(current);
35253
+ const alreadyStored = normalized.reasoningBlocks.some(
35254
+ (entry) => entry.content === event.data.reasoning && entry.eventAt === eventAt && entry.key === key
35255
+ );
35256
+ const reasoningBlocks = alreadyStored ? normalized.reasoningBlocks : [
35257
+ ...normalized.reasoningBlocks,
35258
+ {
35259
+ content: event.data.reasoning,
35260
+ ...eventAt ? { eventAt } : {},
35261
+ key
35262
+ }
35263
+ ].slice(-MAX_STORED_REASONING_BLOCKS);
35264
+ stored = reasoningBlocks.flatMap(
35265
+ (entry) => entry.key === key ? [
35266
+ {
35267
+ content: entry.content,
35268
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35269
+ }
35270
+ ] : []
35271
+ );
35272
+ return alreadyStored ? normalized : { ...normalized, reasoningBlocks };
35273
+ });
35274
+ return stored;
35275
+ }
35276
+ function readStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35277
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35278
+ return readEveTraceState(state).reasoningBlocks.flatMap(
35279
+ (entry) => entry.key === key ? [
35280
+ {
35281
+ content: entry.content,
35282
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35283
+ }
35284
+ ] : []
35285
+ );
35286
+ }
35287
+ function clearStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35288
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35289
+ state.update((current) => {
35290
+ const normalized = normalizeEveTraceState(current);
35291
+ return {
35292
+ ...normalized,
35293
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35294
+ (entry) => entry.key !== key
35295
+ )
35296
+ };
35297
+ });
35298
+ }
35299
+ function eveOutputMessage(output) {
35300
+ return Array.isArray(output) && isObject(output[0]) ? output[0]["message"] : void 0;
35301
+ }
35302
+ function mergeEveReasoning(output, reasoning) {
35303
+ if (reasoning.length === 0) {
35304
+ return output;
34817
35305
  }
34818
- const captured = capturedModelInput(input["modelInput"]);
35306
+ const choice = Array.isArray(output) && isObject(output[0]) ? output[0] : {};
35307
+ const message = isObject(choice["message"]) ? choice["message"] : {};
35308
+ return [
35309
+ {
35310
+ ...choice,
35311
+ index: typeof choice["index"] === "number" ? choice["index"] : 0,
35312
+ message: {
35313
+ ...message,
35314
+ content: "content" in message ? message["content"] : null,
35315
+ reasoning: reasoning.map((block) => ({ content: block.content })),
35316
+ role: typeof message["role"] === "string" ? message["role"] : "assistant"
35317
+ }
35318
+ }
35319
+ ];
35320
+ }
35321
+ function captureEveModelInput(state, input) {
35322
+ const sessionId = input.session.id;
35323
+ const turnId = input.turn.id;
35324
+ const stepIndex = input.step.index;
35325
+ const captured = capturedModelInput(input.modelInput);
34819
35326
  if (!captured) {
34820
35327
  return;
34821
35328
  }
@@ -34856,18 +35363,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
34856
35363
  }
34857
35364
  }
34858
35365
  function capturedModelInput(modelInput) {
34859
- if (!isObject(modelInput)) {
34860
- return void 0;
34861
- }
34862
- const messages = modelInput["messages"];
34863
- if (!Array.isArray(messages)) {
34864
- return void 0;
34865
- }
34866
- const instructions = modelInput["instructions"];
34867
- const value = [
34868
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
34869
- ...messages
34870
- ];
35366
+ const { instructions, messages } = modelInput;
35367
+ const value = [];
35368
+ if (typeof instructions === "string") {
35369
+ value.push({ content: instructions, role: "system" });
35370
+ } else if (instructions) {
35371
+ value.push(...instructions.map(capturedEveModelMessage));
35372
+ }
35373
+ value.push(...messages.map(capturedEveModelMessage));
34871
35374
  try {
34872
35375
  const cloned = JSON.parse(JSON.stringify(value));
34873
35376
  if (!Array.isArray(cloned)) {
@@ -34878,8 +35381,123 @@ function capturedModelInput(modelInput) {
34878
35381
  return void 0;
34879
35382
  }
34880
35383
  }
35384
+ function capturedEveModelMessage(message) {
35385
+ const { content, role } = message;
35386
+ if (typeof content === "string") {
35387
+ return { content, role };
35388
+ }
35389
+ return { content: content.map(capturedEveModelContentPart), role };
35390
+ }
35391
+ function capturedEveModelContentPart(part) {
35392
+ switch (part.type) {
35393
+ case "text":
35394
+ case "reasoning":
35395
+ return { text: part.text, type: part.type };
35396
+ case "image":
35397
+ return {
35398
+ image: part.image,
35399
+ ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35400
+ type: "image"
35401
+ };
35402
+ case "file":
35403
+ case "reasoning-file":
35404
+ return {
35405
+ data: part.data,
35406
+ ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
35407
+ mediaType: part.mediaType,
35408
+ type: part.type
35409
+ };
35410
+ case "custom":
35411
+ return {
35412
+ ..."kind" in part ? { kind: part.kind } : {},
35413
+ type: "custom"
35414
+ };
35415
+ case "tool-call":
35416
+ return {
35417
+ input: part.input,
35418
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35419
+ toolCallId: part.toolCallId,
35420
+ toolName: part.toolName,
35421
+ type: "tool-call"
35422
+ };
35423
+ case "tool-result": {
35424
+ const output = part.output;
35425
+ let capturedOutput;
35426
+ switch (output.type) {
35427
+ case "text":
35428
+ case "error-text":
35429
+ capturedOutput = { type: output.type, value: output.value };
35430
+ break;
35431
+ case "json":
35432
+ case "error-json":
35433
+ capturedOutput = { type: output.type, value: output.value };
35434
+ break;
35435
+ case "execution-denied":
35436
+ capturedOutput = {
35437
+ ...output.reason !== void 0 ? { reason: output.reason } : {},
35438
+ type: "execution-denied"
35439
+ };
35440
+ break;
35441
+ case "content":
35442
+ capturedOutput = {
35443
+ type: "content",
35444
+ value: output.value.map(capturedEveModelContentPart)
35445
+ };
35446
+ break;
35447
+ }
35448
+ return {
35449
+ output: capturedOutput,
35450
+ toolCallId: part.toolCallId,
35451
+ toolName: part.toolName,
35452
+ type: "tool-result"
35453
+ };
35454
+ }
35455
+ case "tool-approval-request":
35456
+ return {
35457
+ approvalId: part.approvalId,
35458
+ ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
35459
+ ...part.signature !== void 0 ? { signature: part.signature } : {},
35460
+ toolCallId: part.toolCallId,
35461
+ type: "tool-approval-request"
35462
+ };
35463
+ case "tool-approval-response":
35464
+ return {
35465
+ approvalId: part.approvalId,
35466
+ approved: part.approved,
35467
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35468
+ ...part.reason !== void 0 ? { reason: part.reason } : {},
35469
+ type: "tool-approval-response"
35470
+ };
35471
+ case "file-data":
35472
+ case "image-data":
35473
+ return {
35474
+ data: part.data,
35475
+ ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
35476
+ mediaType: part.mediaType,
35477
+ type: part.type
35478
+ };
35479
+ case "file-url":
35480
+ case "image-url":
35481
+ return {
35482
+ ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35483
+ type: part.type,
35484
+ url: part.url
35485
+ };
35486
+ case "file-id":
35487
+ case "image-file-id":
35488
+ return { fileId: part.fileId, type: part.type };
35489
+ case "file-reference":
35490
+ case "image-file-reference":
35491
+ return {
35492
+ providerReference: part.providerReference,
35493
+ type: part.type
35494
+ };
35495
+ }
35496
+ }
34881
35497
  function isCapturedModelInput(input) {
34882
- return Array.isArray(input);
35498
+ return Array.isArray(input) && input.every(
35499
+ (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))
35500
+ );
34883
35501
  }
34884
35502
  function llmInputKey(sessionId, turnId, stepIndex) {
34885
35503
  return `${sessionId}\0${turnId}\0${stepIndex}`;
@@ -38274,6 +38892,8 @@ var BaseNode = class {
38274
38892
  this.graph = graph;
38275
38893
  this.id = id;
38276
38894
  }
38895
+ graph;
38896
+ id;
38277
38897
  __type = "node";
38278
38898
  dependencies = [];
38279
38899
  addDependency(dependency) {
@@ -38307,6 +38927,7 @@ var PromptNode = class extends BaseNode {
38307
38927
  super(graph, id);
38308
38928
  this.prompt = prompt;
38309
38929
  }
38930
+ prompt;
38310
38931
  async build(context) {
38311
38932
  return {
38312
38933
  type: "function",
@@ -38319,6 +38940,7 @@ var GateNode = class extends BaseNode {
38319
38940
  super(graph, id);
38320
38941
  this.condition = condition;
38321
38942
  }
38943
+ condition;
38322
38944
  async build(context) {
38323
38945
  return {
38324
38946
  type: "gate",
@@ -38343,6 +38965,7 @@ var PromptTemplateNode = class extends BaseNode {
38343
38965
  super(graph, id);
38344
38966
  this.prompt = prompt;
38345
38967
  }
38968
+ prompt;
38346
38969
  async build(context) {
38347
38970
  return {
38348
38971
  type: "prompt_template",
@@ -38355,6 +38978,7 @@ var LiteralNode = class extends BaseNode {
38355
38978
  super(graph, id);
38356
38979
  this.value = value;
38357
38980
  }
38981
+ value;
38358
38982
  async build(context) {
38359
38983
  return {
38360
38984
  type: "literal",
@@ -39448,6 +40072,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
39448
40072
  this._state = _state;
39449
40073
  this.spanTypeFilter = spanTypeFilter;
39450
40074
  }
40075
+ _objectId;
40076
+ rootSpanId;
40077
+ _state;
40078
+ spanTypeFilter;
39451
40079
  static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
39452
40080
  const children = [
39453
40081
  // Base filter: root_span_id = 'value'
@@ -39898,6 +40526,8 @@ var EvalResultWithSummary = class {
39898
40526
  this.summary = summary;
39899
40527
  this.results = results;
39900
40528
  }
40529
+ summary;
40530
+ results;
39901
40531
  /**
39902
40532
  * @deprecated Use `summary` instead.
39903
40533
  */
@@ -41316,6 +41946,7 @@ var ToolBuilder = class {
41316
41946
  constructor(project) {
41317
41947
  this.project = project;
41318
41948
  }
41949
+ project;
41319
41950
  taskCounter = 0;
41320
41951
  // This type definition is just a catch all so that the implementation can be
41321
41952
  // less specific than the two more specific declarations above.
@@ -41346,6 +41977,7 @@ var ScorerBuilder = class {
41346
41977
  constructor(project) {
41347
41978
  this.project = project;
41348
41979
  }
41980
+ project;
41349
41981
  taskCounter = 0;
41350
41982
  create(opts) {
41351
41983
  this.taskCounter++;
@@ -41405,6 +42037,7 @@ var ClassifierBuilder = class {
41405
42037
  constructor(project) {
41406
42038
  this.project = project;
41407
42039
  }
42040
+ project;
41408
42041
  taskCounter = 0;
41409
42042
  create(opts) {
41410
42043
  this.taskCounter++;
@@ -41440,6 +42073,7 @@ var CodeFunction = class {
41440
42073
  throw new Error("parameters are required if return type is defined");
41441
42074
  }
41442
42075
  }
42076
+ project;
41443
42077
  handler;
41444
42078
  name;
41445
42079
  slug;
@@ -41527,6 +42161,7 @@ var PromptBuilder = class {
41527
42161
  constructor(project) {
41528
42162
  this.project = project;
41529
42163
  }
42164
+ project;
41530
42165
  create(opts) {
41531
42166
  const toolFunctions = [];
41532
42167
  const rawTools = [];
@@ -41603,6 +42238,7 @@ var ParametersBuilder = class {
41603
42238
  constructor(project) {
41604
42239
  this.project = project;
41605
42240
  }
42241
+ project;
41606
42242
  create(opts) {
41607
42243
  const slug = opts.slug ?? slugify(opts.name, { lower: true, strict: true });
41608
42244
  const codeParameters = new CodeParameters(this.project, {