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
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
  }
@@ -29032,6 +29302,16 @@ function cleanObject(obj) {
29032
29302
  })
29033
29303
  );
29034
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
+ }
29035
29315
  function walkGenerations(response) {
29036
29316
  const result = [];
29037
29317
  const generations = response.generations || [];
@@ -29078,7 +29358,7 @@ function getMetricsFromResponse(response) {
29078
29358
  continue;
29079
29359
  }
29080
29360
  const inputTokenDetails = usageMetadata.input_token_details;
29081
- return cleanObject({
29361
+ return normalizeTokenMetrics({
29082
29362
  total_tokens: usageMetadata.total_tokens,
29083
29363
  prompt_tokens: usageMetadata.input_tokens,
29084
29364
  completion_tokens: usageMetadata.output_tokens,
@@ -29088,7 +29368,7 @@ function getMetricsFromResponse(response) {
29088
29368
  }
29089
29369
  const llmOutput = response.llmOutput || {};
29090
29370
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
29091
- return cleanObject({
29371
+ return normalizeTokenMetrics({
29092
29372
  total_tokens: tokenUsage.totalTokens,
29093
29373
  prompt_tokens: tokenUsage.promptTokens,
29094
29374
  completion_tokens: tokenUsage.completionTokens
@@ -32777,6 +33057,26 @@ function wrapAISDK(aiSDK, options = {}) {
32777
33057
  }
32778
33058
  });
32779
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
+ }
32780
33080
  var wrapAgentClass = (AgentClass, options = {}) => {
32781
33081
  const typedAgentClass = AgentClass;
32782
33082
  return new Proxy(typedAgentClass, {
@@ -32786,9 +33086,46 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32786
33086
  args,
32787
33087
  newTarget
32788
33088
  );
33089
+ const harnessAgent = isHarnessAgentInstance(instance) ? instance : null;
32789
33090
  return new Proxy(instance, {
32790
33091
  get(instanceTarget, prop, instanceReceiver) {
32791
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
+ }
32792
33129
  if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
32793
33130
  return wrapAgentGenerate(original, instanceTarget, options);
32794
33131
  }
@@ -32804,6 +33141,26 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32804
33141
  }
32805
33142
  });
32806
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
+ );
32807
33164
  var wrapAgentGenerate = (generate, instance, options = {}) => {
32808
33165
  const defaultName = `${instance.constructor.name}.generate`;
32809
33166
  return async (params) => makeGenerateTextWrapper(
@@ -33030,6 +33387,7 @@ var BraintrustLanguageModelWrapper = class {
33030
33387
  this.supportsUrl = (url) => this.model.supportsUrl(url);
33031
33388
  }
33032
33389
  }
33390
+ model;
33033
33391
  supportsUrl;
33034
33392
  get specificationVersion() {
33035
33393
  return this.model.specificationVersion;
@@ -33612,6 +33970,7 @@ function BraintrustMiddleware(config = {}) {
33612
33970
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
33613
33971
  var MAX_EVE_CACHE_ENTRIES = 1e4;
33614
33972
  var MAX_STORED_LLM_INPUTS = 100;
33973
+ var MAX_STORED_REASONING_BLOCKS = 100;
33615
33974
  var MAX_STORED_SPAN_REFERENCES = 1e4;
33616
33975
  var MAX_STORED_STEP_STARTS = 1e4;
33617
33976
  function braintrustEveHook(options) {
@@ -33650,6 +34009,7 @@ var ResumedEveSpan = class {
33650
34009
  this.reference = reference;
33651
34010
  this.endTime = reference.endTime;
33652
34011
  }
34012
+ reference;
33653
34013
  endTime;
33654
34014
  get rootSpanId() {
33655
34015
  return this.reference.rootSpanId;
@@ -33682,6 +34042,7 @@ var EveBridge = class {
33682
34042
  constructor(state) {
33683
34043
  this.state = state;
33684
34044
  }
34045
+ state;
33685
34046
  eventQueuesBySession = /* @__PURE__ */ new Map();
33686
34047
  completedToolKeys = new LRUCache({
33687
34048
  max: MAX_EVE_CACHE_ENTRIES
@@ -33860,6 +34221,9 @@ var EveBridge = class {
33860
34221
  case "step.started":
33861
34222
  await this.handleStepStarted(event, ctx, hookMetadata);
33862
34223
  return true;
34224
+ case "reasoning.completed":
34225
+ this.handleReasoningCompleted(event, ctx);
34226
+ return true;
33863
34227
  case "message.completed":
33864
34228
  this.handleMessageCompleted(event, ctx);
33865
34229
  return true;
@@ -33951,6 +34315,7 @@ var EveBridge = class {
33951
34315
  key,
33952
34316
  metadata,
33953
34317
  metrics: {},
34318
+ sessionId,
33954
34319
  span,
33955
34320
  stepsByIndex: /* @__PURE__ */ new Map(),
33956
34321
  turnId: event.data.turnId
@@ -33981,6 +34346,12 @@ var EveBridge = class {
33981
34346
  const endTime = eventTime2(event);
33982
34347
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
33983
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
+ );
33984
34355
  }
33985
34356
  const stepOrdinal = this.stepOrdinal(event);
33986
34357
  const metadata = { ...turn.metadata };
@@ -33990,6 +34361,13 @@ var EveBridge = class {
33990
34361
  event.data.turnId,
33991
34362
  event.data.stepIndex
33992
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);
33993
34371
  const { rowId: eventId, spanId } = await generateEveIds(
33994
34372
  "step",
33995
34373
  sessionId,
@@ -34007,32 +34385,52 @@ var EveBridge = class {
34007
34385
  spanId,
34008
34386
  startTime: eventTime2(event)
34009
34387
  });
34010
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
34388
+ span.log({
34389
+ ...input !== void 0 ? { input } : {},
34390
+ metadata
34391
+ });
34011
34392
  turn.stepsByIndex.set(event.data.stepIndex, {
34012
34393
  ...input !== void 0 ? { input } : {},
34013
34394
  metadata,
34014
34395
  metrics: {},
34396
+ ...output !== void 0 ? { output } : {},
34397
+ reasoning,
34015
34398
  span
34016
34399
  });
34017
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
+ }
34018
34413
  handleMessageCompleted(event, ctx) {
34019
34414
  const step = this.stepForEvent(event, ctx);
34020
34415
  if (!step) {
34021
34416
  return;
34022
34417
  }
34023
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
34418
+ const existingMessage = eveOutputMessage(step.output);
34024
34419
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
34025
- step.output = [
34026
- {
34027
- finish_reason: normalizedFinishReason(event.data.finishReason),
34028
- index: 0,
34029
- message: {
34030
- content: event.data.message,
34031
- role: "assistant",
34032
- ...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
+ }
34033
34430
  }
34034
- }
34035
- ];
34431
+ ],
34432
+ step.reasoning
34433
+ );
34036
34434
  const turn = this.turnForEvent(event, ctx);
34037
34435
  if (turn && event.data.finishReason !== "tool-calls") {
34038
34436
  turn.output = event.data.message;
@@ -34041,16 +34439,19 @@ var EveBridge = class {
34041
34439
  handleResultCompleted(event, ctx) {
34042
34440
  const step = this.stepForEvent(event, ctx);
34043
34441
  if (step) {
34044
- step.output = [
34045
- {
34046
- finish_reason: "stop",
34047
- index: 0,
34048
- message: {
34049
- content: event.data.result,
34050
- 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
+ }
34051
34451
  }
34052
- }
34053
- ];
34452
+ ],
34453
+ step.reasoning
34454
+ );
34054
34455
  }
34055
34456
  const turn = this.turnForEvent(event, ctx);
34056
34457
  if (turn) {
@@ -34100,18 +34501,20 @@ var EveBridge = class {
34100
34501
  type: "function"
34101
34502
  });
34102
34503
  }
34103
- step.output = [
34104
- {
34105
- finish_reason: "tool_calls",
34106
- index: 0,
34107
- message: {
34108
- content: null,
34109
- role: "assistant",
34110
- 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
+ }
34111
34514
  }
34112
- }
34113
- ];
34114
- step.span.log({ metadata: step.metadata, output: step.output });
34515
+ ],
34516
+ step.reasoning
34517
+ );
34115
34518
  }
34116
34519
  async handleActionResult(event, ctx, hookMetadata) {
34117
34520
  if (isToolResult(event.data.result)) {
@@ -34289,6 +34692,7 @@ var EveBridge = class {
34289
34692
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
34290
34693
  };
34291
34694
  step.metrics = { ...step.metrics, ...metrics };
34695
+ const sessionId = sessionIdFromContext(ctx);
34292
34696
  if (Array.isArray(step.output) && isObject(step.output[0])) {
34293
34697
  const finishReason = step.output[0].finish_reason;
34294
34698
  if (typeof finishReason !== "string") {
@@ -34313,6 +34717,14 @@ var EveBridge = class {
34313
34717
  turn.stepsByIndex.delete(event.data.stepIndex);
34314
34718
  }
34315
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
+ }
34316
34728
  }
34317
34729
  handleStepFailed(event, ctx) {
34318
34730
  const step = this.stepForEvent(event, ctx);
@@ -34330,6 +34742,15 @@ var EveBridge = class {
34330
34742
  const turn = this.turnForEvent(event, ctx);
34331
34743
  turn?.stepsByIndex.delete(event.data.stepIndex);
34332
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
+ }
34333
34754
  }
34334
34755
  handleTurnCompleted(event, ctx) {
34335
34756
  const turn = this.turnForEvent(event, ctx);
@@ -34427,6 +34848,7 @@ var EveBridge = class {
34427
34848
  key,
34428
34849
  metadata,
34429
34850
  metrics: {},
34851
+ sessionId,
34430
34852
  span,
34431
34853
  stepsByIndex: /* @__PURE__ */ new Map(),
34432
34854
  turnId: event.data.turnId
@@ -34689,6 +35111,9 @@ var EveBridge = class {
34689
35111
  const normalized = normalizeEveTraceState(current);
34690
35112
  return {
34691
35113
  ...normalized,
35114
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35115
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
35116
+ ),
34692
35117
  stepStarts: normalized.stepStarts.filter(
34693
35118
  (entry) => entry.turnId !== turn.turnId
34694
35119
  )
@@ -34728,6 +35153,7 @@ function emptyEveTraceState() {
34728
35153
  return {
34729
35154
  llmInputs: [],
34730
35155
  metadata: {},
35156
+ reasoningBlocks: [],
34731
35157
  spanReferences: [],
34732
35158
  stepStarts: []
34733
35159
  };
@@ -34778,6 +35204,21 @@ function normalizeEveTraceState(state) {
34778
35204
  const input = entry["input"];
34779
35205
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
34780
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) : [];
34781
35222
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
34782
35223
  if (!isObject(entry)) {
34783
35224
  return [];
@@ -34788,7 +35229,13 @@ function normalizeEveTraceState(state) {
34788
35229
  const turnId = entry["turnId"];
34789
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 }] : [];
34790
35231
  }).slice(-MAX_STORED_STEP_STARTS) : [];
34791
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
35232
+ return {
35233
+ llmInputs,
35234
+ metadata: { ...metadata },
35235
+ reasoningBlocks,
35236
+ spanReferences,
35237
+ stepStarts
35238
+ };
34792
35239
  }
34793
35240
  function readEveTraceState(state) {
34794
35241
  try {
@@ -34797,23 +35244,85 @@ function readEveTraceState(state) {
34797
35244
  return emptyEveTraceState();
34798
35245
  }
34799
35246
  }
34800
- function captureEveModelInput(state, input) {
34801
- if (!isObject(input)) {
34802
- return;
34803
- }
34804
- const session = input["session"];
34805
- const turn = input["turn"];
34806
- const step = input["step"];
34807
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
34808
- return;
34809
- }
34810
- const sessionId = session["id"];
34811
- const turnId = turn["id"];
34812
- const stepIndex = step["index"];
34813
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
34814
- 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;
34815
35305
  }
34816
- 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);
34817
35326
  if (!captured) {
34818
35327
  return;
34819
35328
  }
@@ -34854,18 +35363,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
34854
35363
  }
34855
35364
  }
34856
35365
  function capturedModelInput(modelInput) {
34857
- if (!isObject(modelInput)) {
34858
- return void 0;
34859
- }
34860
- const messages = modelInput["messages"];
34861
- if (!Array.isArray(messages)) {
34862
- return void 0;
34863
- }
34864
- const instructions = modelInput["instructions"];
34865
- const value = [
34866
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
34867
- ...messages
34868
- ];
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));
34869
35374
  try {
34870
35375
  const cloned = JSON.parse(JSON.stringify(value));
34871
35376
  if (!Array.isArray(cloned)) {
@@ -34876,8 +35381,123 @@ function capturedModelInput(modelInput) {
34876
35381
  return void 0;
34877
35382
  }
34878
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
+ }
34879
35497
  function isCapturedModelInput(input) {
34880
- 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
+ );
34881
35501
  }
34882
35502
  function llmInputKey(sessionId, turnId, stepIndex) {
34883
35503
  return `${sessionId}\0${turnId}\0${stepIndex}`;
@@ -38272,6 +38892,8 @@ var BaseNode = class {
38272
38892
  this.graph = graph;
38273
38893
  this.id = id;
38274
38894
  }
38895
+ graph;
38896
+ id;
38275
38897
  __type = "node";
38276
38898
  dependencies = [];
38277
38899
  addDependency(dependency) {
@@ -38305,6 +38927,7 @@ var PromptNode = class extends BaseNode {
38305
38927
  super(graph, id);
38306
38928
  this.prompt = prompt;
38307
38929
  }
38930
+ prompt;
38308
38931
  async build(context) {
38309
38932
  return {
38310
38933
  type: "function",
@@ -38317,6 +38940,7 @@ var GateNode = class extends BaseNode {
38317
38940
  super(graph, id);
38318
38941
  this.condition = condition;
38319
38942
  }
38943
+ condition;
38320
38944
  async build(context) {
38321
38945
  return {
38322
38946
  type: "gate",
@@ -38341,6 +38965,7 @@ var PromptTemplateNode = class extends BaseNode {
38341
38965
  super(graph, id);
38342
38966
  this.prompt = prompt;
38343
38967
  }
38968
+ prompt;
38344
38969
  async build(context) {
38345
38970
  return {
38346
38971
  type: "prompt_template",
@@ -38353,6 +38978,7 @@ var LiteralNode = class extends BaseNode {
38353
38978
  super(graph, id);
38354
38979
  this.value = value;
38355
38980
  }
38981
+ value;
38356
38982
  async build(context) {
38357
38983
  return {
38358
38984
  type: "literal",
@@ -39446,6 +40072,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
39446
40072
  this._state = _state;
39447
40073
  this.spanTypeFilter = spanTypeFilter;
39448
40074
  }
40075
+ _objectId;
40076
+ rootSpanId;
40077
+ _state;
40078
+ spanTypeFilter;
39449
40079
  static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
39450
40080
  const children = [
39451
40081
  // Base filter: root_span_id = 'value'
@@ -39896,6 +40526,8 @@ var EvalResultWithSummary = class {
39896
40526
  this.summary = summary;
39897
40527
  this.results = results;
39898
40528
  }
40529
+ summary;
40530
+ results;
39899
40531
  /**
39900
40532
  * @deprecated Use `summary` instead.
39901
40533
  */
@@ -41314,6 +41946,7 @@ var ToolBuilder = class {
41314
41946
  constructor(project) {
41315
41947
  this.project = project;
41316
41948
  }
41949
+ project;
41317
41950
  taskCounter = 0;
41318
41951
  // This type definition is just a catch all so that the implementation can be
41319
41952
  // less specific than the two more specific declarations above.
@@ -41344,6 +41977,7 @@ var ScorerBuilder = class {
41344
41977
  constructor(project) {
41345
41978
  this.project = project;
41346
41979
  }
41980
+ project;
41347
41981
  taskCounter = 0;
41348
41982
  create(opts) {
41349
41983
  this.taskCounter++;
@@ -41403,6 +42037,7 @@ var ClassifierBuilder = class {
41403
42037
  constructor(project) {
41404
42038
  this.project = project;
41405
42039
  }
42040
+ project;
41406
42041
  taskCounter = 0;
41407
42042
  create(opts) {
41408
42043
  this.taskCounter++;
@@ -41438,6 +42073,7 @@ var CodeFunction = class {
41438
42073
  throw new Error("parameters are required if return type is defined");
41439
42074
  }
41440
42075
  }
42076
+ project;
41441
42077
  handler;
41442
42078
  name;
41443
42079
  slug;
@@ -41525,6 +42161,7 @@ var PromptBuilder = class {
41525
42161
  constructor(project) {
41526
42162
  this.project = project;
41527
42163
  }
42164
+ project;
41528
42165
  create(opts) {
41529
42166
  const toolFunctions = [];
41530
42167
  const rawTools = [];
@@ -41601,6 +42238,7 @@ var ParametersBuilder = class {
41601
42238
  constructor(project) {
41602
42239
  this.project = project;
41603
42240
  }
42241
+ project;
41604
42242
  create(opts) {
41605
42243
  const slug = opts.slug ?? slugify(opts.name, { lower: true, strict: true });
41606
42244
  const codeParameters = new CodeParameters(this.project, {