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/workerd.mjs CHANGED
@@ -21,6 +21,7 @@ var DefaultChannel = class {
21
21
  constructor(name) {
22
22
  this.name = name;
23
23
  }
24
+ name;
24
25
  hasSubscribers = false;
25
26
  subscribe(_subscription) {
26
27
  }
@@ -1077,6 +1078,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1077
1078
  constructor(data) {
1078
1079
  this.data = data;
1079
1080
  }
1081
+ data;
1080
1082
  toStr() {
1081
1083
  const jsonObj = {
1082
1084
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1584,6 +1586,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1584
1586
  constructor(data) {
1585
1587
  this.data = data;
1586
1588
  }
1589
+ data;
1587
1590
  toStr() {
1588
1591
  const jsonObj = {
1589
1592
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -4819,6 +4822,97 @@ var SpanCache = class {
4819
4822
  }
4820
4823
  };
4821
4824
 
4825
+ // src/span-origin.ts
4826
+ var SDK_VERSION = true ? "3.24.0" : "0.0.0";
4827
+ function detectSpanOriginEnvironment(explicit) {
4828
+ if (explicit) return explicit;
4829
+ const envType = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_TYPE");
4830
+ const envName = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_NAME");
4831
+ if (envType || envName) {
4832
+ return {
4833
+ ...envType ? { type: envType } : {},
4834
+ ...envName ? { name: envName } : {}
4835
+ };
4836
+ }
4837
+ const ci = firstPresent([
4838
+ ["GITHUB_ACTIONS", "github_actions"],
4839
+ ["GITLAB_CI", "gitlab_ci"],
4840
+ ["CIRCLECI", "circleci"],
4841
+ ["BUILDKITE", "buildkite"],
4842
+ ["JENKINS_URL", "jenkins"],
4843
+ ["JENKINS_HOME", "jenkins"],
4844
+ ["TF_BUILD", "azure_pipelines"],
4845
+ ["TEAMCITY_VERSION", "teamcity"],
4846
+ ["TRAVIS", "travis"],
4847
+ ["BITBUCKET_BUILD_NUMBER", "bitbucket"]
4848
+ ]);
4849
+ if (ci) return { type: "ci", name: ci };
4850
+ if (isomorph_default.getEnv("CI")) return { type: "ci", name: "ci" };
4851
+ const earlyServer = firstPresent([
4852
+ ["VERCEL", "vercel"],
4853
+ ["NETLIFY", "netlify"]
4854
+ ]);
4855
+ if (earlyServer) return { type: "server", name: earlyServer };
4856
+ if (isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI") || isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI_V4")) {
4857
+ return { type: "server", name: "ecs" };
4858
+ }
4859
+ const awsExecutionEnv = isomorph_default.getEnv("AWS_EXECUTION_ENV");
4860
+ if (awsExecutionEnv?.startsWith("AWS_ECS_")) {
4861
+ return { type: "server", name: "ecs" };
4862
+ }
4863
+ if (awsExecutionEnv?.startsWith("AWS_Lambda_")) {
4864
+ return { type: "server", name: "aws_lambda" };
4865
+ }
4866
+ if (isomorph_default.getEnv("AWS_LAMBDA_FUNCTION_NAME")) {
4867
+ return { type: "server", name: "aws_lambda" };
4868
+ }
4869
+ const server = firstPresent([
4870
+ ["K_SERVICE", "cloud_run"],
4871
+ ["FUNCTION_TARGET", "gcp_functions"],
4872
+ ["KUBERNETES_SERVICE_HOST", "kubernetes"],
4873
+ ["DYNO", "heroku"],
4874
+ ["FLY_APP_NAME", "fly"],
4875
+ ["RAILWAY_ENVIRONMENT", "railway"],
4876
+ ["RENDER_SERVICE_NAME", "render"]
4877
+ ]);
4878
+ if (server) return { type: "server", name: server };
4879
+ return deploymentModeEnvironment("NODE_ENV", isomorph_default.getEnv("NODE_ENV"));
4880
+ }
4881
+ function makeSpanOrigin(instrumentationName, environment) {
4882
+ return {
4883
+ name: "braintrust.sdk.javascript",
4884
+ version: SDK_VERSION,
4885
+ instrumentation: { name: instrumentationName },
4886
+ ...environment ? { environment } : {}
4887
+ };
4888
+ }
4889
+ function mergeSpanOriginContext(context, instrumentationName, environment) {
4890
+ const next = { ...context ?? {} };
4891
+ const current = isObject2(next.span_origin) ? { ...next.span_origin } : {};
4892
+ next.span_origin = {
4893
+ ...makeSpanOrigin(instrumentationName, environment),
4894
+ ...current
4895
+ };
4896
+ return next;
4897
+ }
4898
+ function firstPresent(entries) {
4899
+ return entries.find(([key]) => Boolean(isomorph_default.getEnv(key)))?.[1];
4900
+ }
4901
+ function deploymentModeEnvironment(_key, value) {
4902
+ if (!value) return void 0;
4903
+ const normalized = value.toLowerCase();
4904
+ if (normalized === "production" || normalized === "staging") {
4905
+ return { type: "server", name: normalized };
4906
+ }
4907
+ if (normalized === "development" || normalized === "local") {
4908
+ return { type: "local", name: normalized };
4909
+ }
4910
+ return { name: value };
4911
+ }
4912
+ function isObject2(value) {
4913
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4914
+ }
4915
+
4822
4916
  // src/logger.ts
4823
4917
  var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
4824
4918
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
@@ -4867,6 +4961,7 @@ var LoginInvalidOrgError = class extends Error {
4867
4961
  super(message);
4868
4962
  this.message = message;
4869
4963
  }
4964
+ message;
4870
4965
  };
4871
4966
  var REDACTION_FIELDS = [
4872
4967
  "input",
@@ -4882,6 +4977,8 @@ var MaskingError = class {
4882
4977
  this.fieldName = fieldName;
4883
4978
  this.errorType = errorType;
4884
4979
  }
4980
+ fieldName;
4981
+ errorType;
4885
4982
  get errorMsg() {
4886
4983
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
4887
4984
  }
@@ -5091,7 +5188,9 @@ var BraintrustState = class _BraintrustState {
5091
5188
  diskCache: parametersDiskCache
5092
5189
  });
5093
5190
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5191
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5094
5192
  }
5193
+ loginParams;
5095
5194
  id;
5096
5195
  currentExperiment;
5097
5196
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5126,6 +5225,7 @@ var BraintrustState = class _BraintrustState {
5126
5225
  _idGenerator = null;
5127
5226
  _contextManager = null;
5128
5227
  _otelFlushCallback = null;
5228
+ spanOriginEnvironment;
5129
5229
  resetLoginInfo() {
5130
5230
  this.appUrl = null;
5131
5231
  this.appPublicUrl = null;
@@ -7744,6 +7844,7 @@ function initLogger(options = {}) {
7744
7844
  orgName,
7745
7845
  forceLogin,
7746
7846
  debugLogLevel,
7847
+ environment,
7747
7848
  fetch: fetch2,
7748
7849
  state: stateArg
7749
7850
  } = options || {};
@@ -7760,6 +7861,7 @@ function initLogger(options = {}) {
7760
7861
  };
7761
7862
  const state = stateArg ?? _globalState;
7762
7863
  state.setDebugLogLevel(debugLogLevel);
7864
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7763
7865
  state.enforceQueueSizeLimit(true);
7764
7866
  const lazyMetadata = new LazyValue(
7765
7867
  async () => {
@@ -8951,6 +9053,11 @@ var ObjectFetcher = class {
8951
9053
  this._internal_btql = _internal_btql;
8952
9054
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
8953
9055
  }
9056
+ objectType;
9057
+ pinnedVersion;
9058
+ mutateRecord;
9059
+ _internal_btql;
9060
+ _internalBrainstoreRealtime;
8954
9061
  _fetchedData = void 0;
8955
9062
  get id() {
8956
9063
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -9389,6 +9496,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9389
9496
  this.state = state;
9390
9497
  this.lazyMetadata = lazyMetadata;
9391
9498
  }
9499
+ state;
9500
+ lazyMetadata;
9392
9501
  get id() {
9393
9502
  return (async () => {
9394
9503
  return (await this.lazyMetadata.get()).experiment.id;
@@ -9511,7 +9620,11 @@ var SpanImpl = class _SpanImpl {
9511
9620
  metrics: {
9512
9621
  start: args.startTime ?? getCurrentUnixTimestamp()
9513
9622
  },
9514
- context: { ...callerLocation },
9623
+ context: mergeSpanOriginContext(
9624
+ { ...callerLocation },
9625
+ "braintrust-js-logger",
9626
+ this._state.spanOriginEnvironment
9627
+ ),
9515
9628
  span_attributes: {
9516
9629
  name,
9517
9630
  type,
@@ -9885,6 +9998,7 @@ var Dataset2 = class extends ObjectFetcher {
9885
9998
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
9886
9999
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
9887
10000
  }
10001
+ state;
9888
10002
  lazyMetadata;
9889
10003
  __braintrust_dataset_marker = true;
9890
10004
  newRecords = 0;
@@ -10399,6 +10513,9 @@ var Prompt2 = class _Prompt {
10399
10513
  this.noTrace = noTrace;
10400
10514
  void this.__braintrust_prompt_marker;
10401
10515
  }
10516
+ metadata;
10517
+ defaults;
10518
+ noTrace;
10402
10519
  parsedPromptData;
10403
10520
  hasParsedPromptData = false;
10404
10521
  __braintrust_prompt_marker = true;
@@ -10636,6 +10753,7 @@ var RemoteEvalParameters = class {
10636
10753
  this.metadata = metadata;
10637
10754
  void this.__braintrust_parameters_marker;
10638
10755
  }
10756
+ metadata;
10639
10757
  __braintrust_parameters_marker = true;
10640
10758
  get id() {
10641
10759
  return this.metadata.id;
@@ -15224,6 +15342,24 @@ var aiSDKChannels = defineChannels("ai", {
15224
15342
  kind: "sync-stream"
15225
15343
  })
15226
15344
  });
15345
+ var harnessAgentChannels = defineChannels("@ai-sdk/harness", {
15346
+ generate: channel({
15347
+ channelName: "HarnessAgent.generate",
15348
+ kind: "async"
15349
+ }),
15350
+ stream: channel({
15351
+ channelName: "HarnessAgent.stream",
15352
+ kind: "async"
15353
+ }),
15354
+ continueGenerate: channel({
15355
+ channelName: "HarnessAgent.continueGenerate",
15356
+ kind: "async"
15357
+ }),
15358
+ continueStream: channel({
15359
+ channelName: "HarnessAgent.continueStream",
15360
+ kind: "async"
15361
+ })
15362
+ });
15227
15363
 
15228
15364
  // src/instrumentation/plugins/ai-sdk-plugin.ts
15229
15365
  var DEFAULT_DENY_OUTPUT_PATHS = [
@@ -15492,6 +15628,84 @@ var AISDKPlugin = class extends BasePlugin {
15492
15628
  })
15493
15629
  })
15494
15630
  );
15631
+ this.unsubscribers.push(
15632
+ traceStreamingChannel(harnessAgentChannels.generate, {
15633
+ name: "HarnessAgent.generate",
15634
+ type: "task" /* TASK */,
15635
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15636
+ extractOutput: (result, endEvent) => processAISDKOutput(
15637
+ result,
15638
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15639
+ ),
15640
+ extractMetrics: (result) => extractTokenMetrics(result),
15641
+ aggregateChunks: aggregateAISDKChunks
15642
+ })
15643
+ );
15644
+ this.unsubscribers.push(
15645
+ traceStreamingChannel(harnessAgentChannels.stream, {
15646
+ name: "HarnessAgent.stream",
15647
+ type: "task" /* TASK */,
15648
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15649
+ extractOutput: (result, endEvent) => processAISDKOutput(
15650
+ result,
15651
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15652
+ ),
15653
+ extractMetrics: (result, startTime) => ({
15654
+ ...extractTokenMetrics(result),
15655
+ ...startTime === void 0 ? {} : {
15656
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15657
+ }
15658
+ }),
15659
+ aggregateChunks: aggregateAISDKChunks,
15660
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15661
+ defaultDenyOutputPaths: denyOutputPaths,
15662
+ endEvent,
15663
+ result,
15664
+ resolvePromiseUsage: true,
15665
+ span,
15666
+ startTime
15667
+ })
15668
+ })
15669
+ );
15670
+ this.unsubscribers.push(
15671
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
15672
+ name: "HarnessAgent.continueGenerate",
15673
+ type: "task" /* TASK */,
15674
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15675
+ extractOutput: (result, endEvent) => processAISDKOutput(
15676
+ result,
15677
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15678
+ ),
15679
+ extractMetrics: (result) => extractTokenMetrics(result),
15680
+ aggregateChunks: aggregateAISDKChunks
15681
+ })
15682
+ );
15683
+ this.unsubscribers.push(
15684
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
15685
+ name: "HarnessAgent.continueStream",
15686
+ type: "task" /* TASK */,
15687
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15688
+ extractOutput: (result, endEvent) => processAISDKOutput(
15689
+ result,
15690
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15691
+ ),
15692
+ extractMetrics: (result, startTime) => ({
15693
+ ...extractTokenMetrics(result),
15694
+ ...startTime === void 0 ? {} : {
15695
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15696
+ }
15697
+ }),
15698
+ aggregateChunks: aggregateAISDKChunks,
15699
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15700
+ defaultDenyOutputPaths: denyOutputPaths,
15701
+ endEvent,
15702
+ result,
15703
+ resolvePromiseUsage: true,
15704
+ span,
15705
+ startTime
15706
+ })
15707
+ })
15708
+ );
15495
15709
  this.unsubscribers.push(
15496
15710
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
15497
15711
  name: "ToolLoopAgent.generate",
@@ -16022,6 +16236,45 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
16022
16236
  metadata
16023
16237
  };
16024
16238
  }
16239
+ function prepareAISDKHarnessAgentInput(params, self) {
16240
+ if (isObject(self)) {
16241
+ try {
16242
+ if (isObject(self.settings)) {
16243
+ const settings = self.settings;
16244
+ if (settings.telemetry === void 0) {
16245
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
16246
+ }
16247
+ }
16248
+ } catch {
16249
+ }
16250
+ }
16251
+ const selectedInput = {};
16252
+ if (params.prompt !== void 0) {
16253
+ selectedInput.prompt = params.prompt;
16254
+ }
16255
+ if (params.messages !== void 0) {
16256
+ selectedInput.messages = params.messages;
16257
+ }
16258
+ if (params.toolApprovalContinuations !== void 0) {
16259
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
16260
+ }
16261
+ const metadata = extractMetadataFromCallParams({}, self);
16262
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
16263
+ metadata.sessionId = params.session.sessionId;
16264
+ }
16265
+ if (isObject(self)) {
16266
+ if (typeof self.harnessId === "string") {
16267
+ metadata.harnessId = self.harnessId;
16268
+ }
16269
+ if (typeof self.permissionMode === "string") {
16270
+ metadata.permissionMode = self.permissionMode;
16271
+ }
16272
+ }
16273
+ return {
16274
+ input: processAISDKCallInput(selectedInput).input,
16275
+ metadata
16276
+ };
16277
+ }
16025
16278
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
16026
16279
  registerWorkflowAgentWrapperSpan(span);
16027
16280
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -16869,6 +17122,7 @@ function patchAISDKStreamingResult(args) {
16869
17122
  endEvent,
16870
17123
  onComplete,
16871
17124
  result,
17125
+ resolvePromiseUsage,
16872
17126
  span,
16873
17127
  startTime
16874
17128
  } = args;
@@ -16895,6 +17149,22 @@ function patchAISDKStreamingResult(args) {
16895
17149
  outputLogged = true;
16896
17150
  try {
16897
17151
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
17152
+ if (resolvePromiseUsage) {
17153
+ try {
17154
+ const resultRecord2 = result;
17155
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
17156
+ if (isPromiseLike(pendingUsage)) {
17157
+ const usage = await Promise.resolve(pendingUsage);
17158
+ if (isObject(usage)) {
17159
+ Object.assign(
17160
+ metrics,
17161
+ extractTokenMetrics({ usage })
17162
+ );
17163
+ }
17164
+ }
17165
+ } catch {
17166
+ }
17167
+ }
16898
17168
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
16899
17169
  metrics.time_to_first_token = firstChunkTime - startTime;
16900
17170
  }
@@ -18125,8 +18395,6 @@ function filterSerializableOptions(options) {
18125
18395
  "additionalDirectories",
18126
18396
  "permissionMode",
18127
18397
  "debug",
18128
- "apiKey",
18129
- "apiKeySource",
18130
18398
  "agentName",
18131
18399
  "instructions"
18132
18400
  ];
@@ -29154,6 +29422,16 @@ function cleanObject(obj) {
29154
29422
  })
29155
29423
  );
29156
29424
  }
29425
+ function normalizeTokenMetrics(obj) {
29426
+ const metrics = cleanObject(obj);
29427
+ if (metrics.total_tokens !== void 0) {
29428
+ metrics.tokens = metrics.total_tokens;
29429
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
29430
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
29431
+ }
29432
+ delete metrics.total_tokens;
29433
+ return metrics;
29434
+ }
29157
29435
  function walkGenerations(response) {
29158
29436
  const result = [];
29159
29437
  const generations = response.generations || [];
@@ -29200,7 +29478,7 @@ function getMetricsFromResponse(response) {
29200
29478
  continue;
29201
29479
  }
29202
29480
  const inputTokenDetails = usageMetadata.input_token_details;
29203
- return cleanObject({
29481
+ return normalizeTokenMetrics({
29204
29482
  total_tokens: usageMetadata.total_tokens,
29205
29483
  prompt_tokens: usageMetadata.input_tokens,
29206
29484
  completion_tokens: usageMetadata.output_tokens,
@@ -29210,7 +29488,7 @@ function getMetricsFromResponse(response) {
29210
29488
  }
29211
29489
  const llmOutput = response.llmOutput || {};
29212
29490
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
29213
- return cleanObject({
29491
+ return normalizeTokenMetrics({
29214
29492
  total_tokens: tokenUsage.totalTokens,
29215
29493
  prompt_tokens: tokenUsage.promptTokens,
29216
29494
  completion_tokens: tokenUsage.completionTokens
@@ -32814,6 +33092,26 @@ function wrapAISDK(aiSDK, options = {}) {
32814
33092
  }
32815
33093
  });
32816
33094
  }
33095
+ function isHarnessAgentInstance(instance) {
33096
+ try {
33097
+ const visited = /* @__PURE__ */ new Set();
33098
+ let prototype = Object.getPrototypeOf(instance);
33099
+ while (prototype !== null && !visited.has(prototype)) {
33100
+ visited.add(prototype);
33101
+ const constructor = Object.getOwnPropertyDescriptor(
33102
+ prototype,
33103
+ "constructor"
33104
+ )?.value;
33105
+ const constructorName = typeof constructor === "function" ? Object.getOwnPropertyDescriptor(constructor, "name")?.value : void 0;
33106
+ if (constructorName === "HarnessAgent") {
33107
+ return true;
33108
+ }
33109
+ prototype = Object.getPrototypeOf(prototype);
33110
+ }
33111
+ } catch {
33112
+ }
33113
+ return false;
33114
+ }
32817
33115
  var wrapAgentClass = (AgentClass, options = {}) => {
32818
33116
  const typedAgentClass = AgentClass;
32819
33117
  return new Proxy(typedAgentClass, {
@@ -32823,9 +33121,46 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32823
33121
  args,
32824
33122
  newTarget
32825
33123
  );
33124
+ const harnessAgent = isHarnessAgentInstance(instance) ? instance : null;
32826
33125
  return new Proxy(instance, {
32827
33126
  get(instanceTarget, prop, instanceReceiver) {
32828
33127
  const original = Reflect.get(instanceTarget, prop, instanceTarget);
33128
+ if (harnessAgent && typeof original === "function") {
33129
+ switch (prop) {
33130
+ case "generate":
33131
+ return wrapHarnessAgentGenerate(
33132
+ original,
33133
+ harnessAgent,
33134
+ harnessAgentChannels.generate,
33135
+ "HarnessAgent.generate",
33136
+ options
33137
+ );
33138
+ case "stream":
33139
+ return wrapHarnessAgentStream(
33140
+ original,
33141
+ harnessAgent,
33142
+ harnessAgentChannels.stream,
33143
+ "HarnessAgent.stream",
33144
+ options
33145
+ );
33146
+ case "continueGenerate":
33147
+ return wrapHarnessAgentGenerate(
33148
+ original,
33149
+ harnessAgent,
33150
+ harnessAgentChannels.continueGenerate,
33151
+ "HarnessAgent.continueGenerate",
33152
+ options
33153
+ );
33154
+ case "continueStream":
33155
+ return wrapHarnessAgentStream(
33156
+ original,
33157
+ harnessAgent,
33158
+ harnessAgentChannels.continueStream,
33159
+ "HarnessAgent.continueStream",
33160
+ options
33161
+ );
33162
+ }
33163
+ }
32829
33164
  if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
32830
33165
  return wrapAgentGenerate(original, instanceTarget, options);
32831
33166
  }
@@ -32841,6 +33176,26 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32841
33176
  }
32842
33177
  });
32843
33178
  };
33179
+ var wrapHarnessAgentGenerate = (generate, instance, channel2, name, options) => makeGenerateTextWrapper(
33180
+ channel2,
33181
+ name,
33182
+ generate.bind(instance),
33183
+ {
33184
+ self: instance,
33185
+ spanType: "task" /* TASK */
33186
+ },
33187
+ options
33188
+ );
33189
+ var wrapHarnessAgentStream = (stream, instance, channel2, name, options) => makeStreamWrapper(
33190
+ channel2,
33191
+ name,
33192
+ stream.bind(instance),
33193
+ {
33194
+ self: instance,
33195
+ spanType: "task" /* TASK */
33196
+ },
33197
+ options
33198
+ );
32844
33199
  var wrapAgentGenerate = (generate, instance, options = {}) => {
32845
33200
  const defaultName = `${instance.constructor.name}.generate`;
32846
33201
  return async (params) => makeGenerateTextWrapper(
@@ -33067,6 +33422,7 @@ var BraintrustLanguageModelWrapper = class {
33067
33422
  this.supportsUrl = (url) => this.model.supportsUrl(url);
33068
33423
  }
33069
33424
  }
33425
+ model;
33070
33426
  supportsUrl;
33071
33427
  get specificationVersion() {
33072
33428
  return this.model.specificationVersion;
@@ -33649,6 +34005,7 @@ function BraintrustMiddleware(config = {}) {
33649
34005
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
33650
34006
  var MAX_EVE_CACHE_ENTRIES = 1e4;
33651
34007
  var MAX_STORED_LLM_INPUTS = 100;
34008
+ var MAX_STORED_REASONING_BLOCKS = 100;
33652
34009
  var MAX_STORED_SPAN_REFERENCES = 1e4;
33653
34010
  var MAX_STORED_STEP_STARTS = 1e4;
33654
34011
  function braintrustEveHook(options) {
@@ -33687,6 +34044,7 @@ var ResumedEveSpan = class {
33687
34044
  this.reference = reference;
33688
34045
  this.endTime = reference.endTime;
33689
34046
  }
34047
+ reference;
33690
34048
  endTime;
33691
34049
  get rootSpanId() {
33692
34050
  return this.reference.rootSpanId;
@@ -33719,6 +34077,7 @@ var EveBridge = class {
33719
34077
  constructor(state) {
33720
34078
  this.state = state;
33721
34079
  }
34080
+ state;
33722
34081
  eventQueuesBySession = /* @__PURE__ */ new Map();
33723
34082
  completedToolKeys = new LRUCache({
33724
34083
  max: MAX_EVE_CACHE_ENTRIES
@@ -33897,6 +34256,9 @@ var EveBridge = class {
33897
34256
  case "step.started":
33898
34257
  await this.handleStepStarted(event, ctx, hookMetadata);
33899
34258
  return true;
34259
+ case "reasoning.completed":
34260
+ this.handleReasoningCompleted(event, ctx);
34261
+ return true;
33900
34262
  case "message.completed":
33901
34263
  this.handleMessageCompleted(event, ctx);
33902
34264
  return true;
@@ -33988,6 +34350,7 @@ var EveBridge = class {
33988
34350
  key,
33989
34351
  metadata,
33990
34352
  metrics: {},
34353
+ sessionId,
33991
34354
  span,
33992
34355
  stepsByIndex: /* @__PURE__ */ new Map(),
33993
34356
  turnId: event.data.turnId
@@ -34018,6 +34381,12 @@ var EveBridge = class {
34018
34381
  const endTime = eventTime2(event);
34019
34382
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
34020
34383
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34384
+ clearStoredEveReasoning(
34385
+ this.state,
34386
+ sessionId,
34387
+ event.data.turnId,
34388
+ event.data.stepIndex
34389
+ );
34021
34390
  }
34022
34391
  const stepOrdinal = this.stepOrdinal(event);
34023
34392
  const metadata = { ...turn.metadata };
@@ -34027,6 +34396,13 @@ var EveBridge = class {
34027
34396
  event.data.turnId,
34028
34397
  event.data.stepIndex
34029
34398
  );
34399
+ const reasoning = readStoredEveReasoning(
34400
+ this.state,
34401
+ sessionId,
34402
+ event.data.turnId,
34403
+ event.data.stepIndex
34404
+ );
34405
+ const output = mergeEveReasoning(void 0, reasoning);
34030
34406
  const { rowId: eventId, spanId } = await generateEveIds(
34031
34407
  "step",
34032
34408
  sessionId,
@@ -34044,32 +34420,52 @@ var EveBridge = class {
34044
34420
  spanId,
34045
34421
  startTime: eventTime2(event)
34046
34422
  });
34047
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
34423
+ span.log({
34424
+ ...input !== void 0 ? { input } : {},
34425
+ metadata
34426
+ });
34048
34427
  turn.stepsByIndex.set(event.data.stepIndex, {
34049
34428
  ...input !== void 0 ? { input } : {},
34050
34429
  metadata,
34051
34430
  metrics: {},
34431
+ ...output !== void 0 ? { output } : {},
34432
+ reasoning,
34052
34433
  span
34053
34434
  });
34054
34435
  }
34436
+ handleReasoningCompleted(event, ctx) {
34437
+ const sessionId = sessionIdFromContext(ctx);
34438
+ if (!sessionId) {
34439
+ return;
34440
+ }
34441
+ const reasoning = storeEveReasoning(this.state, sessionId, event);
34442
+ const step = this.stepForEvent(event, ctx);
34443
+ if (step) {
34444
+ step.reasoning = reasoning;
34445
+ step.output = mergeEveReasoning(step.output, reasoning);
34446
+ }
34447
+ }
34055
34448
  handleMessageCompleted(event, ctx) {
34056
34449
  const step = this.stepForEvent(event, ctx);
34057
34450
  if (!step) {
34058
34451
  return;
34059
34452
  }
34060
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
34453
+ const existingMessage = eveOutputMessage(step.output);
34061
34454
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
34062
- step.output = [
34063
- {
34064
- finish_reason: normalizedFinishReason(event.data.finishReason),
34065
- index: 0,
34066
- message: {
34067
- content: event.data.message,
34068
- role: "assistant",
34069
- ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34455
+ step.output = mergeEveReasoning(
34456
+ [
34457
+ {
34458
+ finish_reason: normalizedFinishReason(event.data.finishReason),
34459
+ index: 0,
34460
+ message: {
34461
+ content: event.data.message,
34462
+ role: "assistant",
34463
+ ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34464
+ }
34070
34465
  }
34071
- }
34072
- ];
34466
+ ],
34467
+ step.reasoning
34468
+ );
34073
34469
  const turn = this.turnForEvent(event, ctx);
34074
34470
  if (turn && event.data.finishReason !== "tool-calls") {
34075
34471
  turn.output = event.data.message;
@@ -34078,16 +34474,19 @@ var EveBridge = class {
34078
34474
  handleResultCompleted(event, ctx) {
34079
34475
  const step = this.stepForEvent(event, ctx);
34080
34476
  if (step) {
34081
- step.output = [
34082
- {
34083
- finish_reason: "stop",
34084
- index: 0,
34085
- message: {
34086
- content: event.data.result,
34087
- role: "assistant"
34477
+ step.output = mergeEveReasoning(
34478
+ [
34479
+ {
34480
+ finish_reason: "stop",
34481
+ index: 0,
34482
+ message: {
34483
+ content: event.data.result,
34484
+ role: "assistant"
34485
+ }
34088
34486
  }
34089
- }
34090
- ];
34487
+ ],
34488
+ step.reasoning
34489
+ );
34091
34490
  }
34092
34491
  const turn = this.turnForEvent(event, ctx);
34093
34492
  if (turn) {
@@ -34137,18 +34536,20 @@ var EveBridge = class {
34137
34536
  type: "function"
34138
34537
  });
34139
34538
  }
34140
- step.output = [
34141
- {
34142
- finish_reason: "tool_calls",
34143
- index: 0,
34144
- message: {
34145
- content: null,
34146
- role: "assistant",
34147
- tool_calls: [...toolCallsById.values()]
34539
+ step.output = mergeEveReasoning(
34540
+ [
34541
+ {
34542
+ finish_reason: "tool_calls",
34543
+ index: 0,
34544
+ message: {
34545
+ content: null,
34546
+ role: "assistant",
34547
+ tool_calls: [...toolCallsById.values()]
34548
+ }
34148
34549
  }
34149
- }
34150
- ];
34151
- step.span.log({ metadata: step.metadata, output: step.output });
34550
+ ],
34551
+ step.reasoning
34552
+ );
34152
34553
  }
34153
34554
  async handleActionResult(event, ctx, hookMetadata) {
34154
34555
  if (isToolResult(event.data.result)) {
@@ -34326,6 +34727,7 @@ var EveBridge = class {
34326
34727
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
34327
34728
  };
34328
34729
  step.metrics = { ...step.metrics, ...metrics };
34730
+ const sessionId = sessionIdFromContext(ctx);
34329
34731
  if (Array.isArray(step.output) && isObject(step.output[0])) {
34330
34732
  const finishReason = step.output[0].finish_reason;
34331
34733
  if (typeof finishReason !== "string") {
@@ -34350,6 +34752,14 @@ var EveBridge = class {
34350
34752
  turn.stepsByIndex.delete(event.data.stepIndex);
34351
34753
  }
34352
34754
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34755
+ if (sessionId) {
34756
+ clearStoredEveReasoning(
34757
+ this.state,
34758
+ sessionId,
34759
+ event.data.turnId,
34760
+ event.data.stepIndex
34761
+ );
34762
+ }
34353
34763
  }
34354
34764
  handleStepFailed(event, ctx) {
34355
34765
  const step = this.stepForEvent(event, ctx);
@@ -34367,6 +34777,15 @@ var EveBridge = class {
34367
34777
  const turn = this.turnForEvent(event, ctx);
34368
34778
  turn?.stepsByIndex.delete(event.data.stepIndex);
34369
34779
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34780
+ const sessionId = sessionIdFromContext(ctx);
34781
+ if (sessionId) {
34782
+ clearStoredEveReasoning(
34783
+ this.state,
34784
+ sessionId,
34785
+ event.data.turnId,
34786
+ event.data.stepIndex
34787
+ );
34788
+ }
34370
34789
  }
34371
34790
  handleTurnCompleted(event, ctx) {
34372
34791
  const turn = this.turnForEvent(event, ctx);
@@ -34464,6 +34883,7 @@ var EveBridge = class {
34464
34883
  key,
34465
34884
  metadata,
34466
34885
  metrics: {},
34886
+ sessionId,
34467
34887
  span,
34468
34888
  stepsByIndex: /* @__PURE__ */ new Map(),
34469
34889
  turnId: event.data.turnId
@@ -34726,6 +35146,9 @@ var EveBridge = class {
34726
35146
  const normalized = normalizeEveTraceState(current);
34727
35147
  return {
34728
35148
  ...normalized,
35149
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35150
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
35151
+ ),
34729
35152
  stepStarts: normalized.stepStarts.filter(
34730
35153
  (entry) => entry.turnId !== turn.turnId
34731
35154
  )
@@ -34765,6 +35188,7 @@ function emptyEveTraceState() {
34765
35188
  return {
34766
35189
  llmInputs: [],
34767
35190
  metadata: {},
35191
+ reasoningBlocks: [],
34768
35192
  spanReferences: [],
34769
35193
  stepStarts: []
34770
35194
  };
@@ -34815,6 +35239,21 @@ function normalizeEveTraceState(state) {
34815
35239
  const input = entry["input"];
34816
35240
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
34817
35241
  }).slice(-MAX_STORED_LLM_INPUTS) : [];
35242
+ const reasoningBlocks = Array.isArray(state["reasoningBlocks"]) ? state["reasoningBlocks"].flatMap((entry) => {
35243
+ if (!isObject(entry)) {
35244
+ return [];
35245
+ }
35246
+ const content = entry["content"];
35247
+ const eventAt = entry["eventAt"];
35248
+ const key = entry["key"];
35249
+ return typeof content === "string" && (eventAt === void 0 || typeof eventAt === "string") && typeof key === "string" ? [
35250
+ {
35251
+ content,
35252
+ ...typeof eventAt === "string" ? { eventAt } : {},
35253
+ key
35254
+ }
35255
+ ] : [];
35256
+ }).slice(-MAX_STORED_REASONING_BLOCKS) : [];
34818
35257
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
34819
35258
  if (!isObject(entry)) {
34820
35259
  return [];
@@ -34825,7 +35264,13 @@ function normalizeEveTraceState(state) {
34825
35264
  const turnId = entry["turnId"];
34826
35265
  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 }] : [];
34827
35266
  }).slice(-MAX_STORED_STEP_STARTS) : [];
34828
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
35267
+ return {
35268
+ llmInputs,
35269
+ metadata: { ...metadata },
35270
+ reasoningBlocks,
35271
+ spanReferences,
35272
+ stepStarts
35273
+ };
34829
35274
  }
34830
35275
  function readEveTraceState(state) {
34831
35276
  try {
@@ -34834,23 +35279,85 @@ function readEveTraceState(state) {
34834
35279
  return emptyEveTraceState();
34835
35280
  }
34836
35281
  }
34837
- function captureEveModelInput(state, input) {
34838
- if (!isObject(input)) {
34839
- return;
34840
- }
34841
- const session = input["session"];
34842
- const turn = input["turn"];
34843
- const step = input["step"];
34844
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
34845
- return;
34846
- }
34847
- const sessionId = session["id"];
34848
- const turnId = turn["id"];
34849
- const stepIndex = step["index"];
34850
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
34851
- return;
35282
+ function storeEveReasoning(state, sessionId, event) {
35283
+ const eventAt = event.meta?.at;
35284
+ const key = llmInputKey(sessionId, event.data.turnId, event.data.stepIndex);
35285
+ let stored = [];
35286
+ state.update((current) => {
35287
+ const normalized = normalizeEveTraceState(current);
35288
+ const alreadyStored = normalized.reasoningBlocks.some(
35289
+ (entry) => entry.content === event.data.reasoning && entry.eventAt === eventAt && entry.key === key
35290
+ );
35291
+ const reasoningBlocks = alreadyStored ? normalized.reasoningBlocks : [
35292
+ ...normalized.reasoningBlocks,
35293
+ {
35294
+ content: event.data.reasoning,
35295
+ ...eventAt ? { eventAt } : {},
35296
+ key
35297
+ }
35298
+ ].slice(-MAX_STORED_REASONING_BLOCKS);
35299
+ stored = reasoningBlocks.flatMap(
35300
+ (entry) => entry.key === key ? [
35301
+ {
35302
+ content: entry.content,
35303
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35304
+ }
35305
+ ] : []
35306
+ );
35307
+ return alreadyStored ? normalized : { ...normalized, reasoningBlocks };
35308
+ });
35309
+ return stored;
35310
+ }
35311
+ function readStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35312
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35313
+ return readEveTraceState(state).reasoningBlocks.flatMap(
35314
+ (entry) => entry.key === key ? [
35315
+ {
35316
+ content: entry.content,
35317
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35318
+ }
35319
+ ] : []
35320
+ );
35321
+ }
35322
+ function clearStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35323
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35324
+ state.update((current) => {
35325
+ const normalized = normalizeEveTraceState(current);
35326
+ return {
35327
+ ...normalized,
35328
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35329
+ (entry) => entry.key !== key
35330
+ )
35331
+ };
35332
+ });
35333
+ }
35334
+ function eveOutputMessage(output) {
35335
+ return Array.isArray(output) && isObject(output[0]) ? output[0]["message"] : void 0;
35336
+ }
35337
+ function mergeEveReasoning(output, reasoning) {
35338
+ if (reasoning.length === 0) {
35339
+ return output;
34852
35340
  }
34853
- const captured = capturedModelInput(input["modelInput"]);
35341
+ const choice = Array.isArray(output) && isObject(output[0]) ? output[0] : {};
35342
+ const message = isObject(choice["message"]) ? choice["message"] : {};
35343
+ return [
35344
+ {
35345
+ ...choice,
35346
+ index: typeof choice["index"] === "number" ? choice["index"] : 0,
35347
+ message: {
35348
+ ...message,
35349
+ content: "content" in message ? message["content"] : null,
35350
+ reasoning: reasoning.map((block) => ({ content: block.content })),
35351
+ role: typeof message["role"] === "string" ? message["role"] : "assistant"
35352
+ }
35353
+ }
35354
+ ];
35355
+ }
35356
+ function captureEveModelInput(state, input) {
35357
+ const sessionId = input.session.id;
35358
+ const turnId = input.turn.id;
35359
+ const stepIndex = input.step.index;
35360
+ const captured = capturedModelInput(input.modelInput);
34854
35361
  if (!captured) {
34855
35362
  return;
34856
35363
  }
@@ -34891,18 +35398,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
34891
35398
  }
34892
35399
  }
34893
35400
  function capturedModelInput(modelInput) {
34894
- if (!isObject(modelInput)) {
34895
- return void 0;
34896
- }
34897
- const messages = modelInput["messages"];
34898
- if (!Array.isArray(messages)) {
34899
- return void 0;
34900
- }
34901
- const instructions = modelInput["instructions"];
34902
- const value = [
34903
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
34904
- ...messages
34905
- ];
35401
+ const { instructions, messages } = modelInput;
35402
+ const value = [];
35403
+ if (typeof instructions === "string") {
35404
+ value.push({ content: instructions, role: "system" });
35405
+ } else if (instructions) {
35406
+ value.push(...instructions.map(capturedEveModelMessage));
35407
+ }
35408
+ value.push(...messages.map(capturedEveModelMessage));
34906
35409
  try {
34907
35410
  const cloned = JSON.parse(JSON.stringify(value));
34908
35411
  if (!Array.isArray(cloned)) {
@@ -34913,8 +35416,123 @@ function capturedModelInput(modelInput) {
34913
35416
  return void 0;
34914
35417
  }
34915
35418
  }
35419
+ function capturedEveModelMessage(message) {
35420
+ const { content, role } = message;
35421
+ if (typeof content === "string") {
35422
+ return { content, role };
35423
+ }
35424
+ return { content: content.map(capturedEveModelContentPart), role };
35425
+ }
35426
+ function capturedEveModelContentPart(part) {
35427
+ switch (part.type) {
35428
+ case "text":
35429
+ case "reasoning":
35430
+ return { text: part.text, type: part.type };
35431
+ case "image":
35432
+ return {
35433
+ image: part.image,
35434
+ ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35435
+ type: "image"
35436
+ };
35437
+ case "file":
35438
+ case "reasoning-file":
35439
+ return {
35440
+ data: part.data,
35441
+ ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
35442
+ mediaType: part.mediaType,
35443
+ type: part.type
35444
+ };
35445
+ case "custom":
35446
+ return {
35447
+ ..."kind" in part ? { kind: part.kind } : {},
35448
+ type: "custom"
35449
+ };
35450
+ case "tool-call":
35451
+ return {
35452
+ input: part.input,
35453
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35454
+ toolCallId: part.toolCallId,
35455
+ toolName: part.toolName,
35456
+ type: "tool-call"
35457
+ };
35458
+ case "tool-result": {
35459
+ const output = part.output;
35460
+ let capturedOutput;
35461
+ switch (output.type) {
35462
+ case "text":
35463
+ case "error-text":
35464
+ capturedOutput = { type: output.type, value: output.value };
35465
+ break;
35466
+ case "json":
35467
+ case "error-json":
35468
+ capturedOutput = { type: output.type, value: output.value };
35469
+ break;
35470
+ case "execution-denied":
35471
+ capturedOutput = {
35472
+ ...output.reason !== void 0 ? { reason: output.reason } : {},
35473
+ type: "execution-denied"
35474
+ };
35475
+ break;
35476
+ case "content":
35477
+ capturedOutput = {
35478
+ type: "content",
35479
+ value: output.value.map(capturedEveModelContentPart)
35480
+ };
35481
+ break;
35482
+ }
35483
+ return {
35484
+ output: capturedOutput,
35485
+ toolCallId: part.toolCallId,
35486
+ toolName: part.toolName,
35487
+ type: "tool-result"
35488
+ };
35489
+ }
35490
+ case "tool-approval-request":
35491
+ return {
35492
+ approvalId: part.approvalId,
35493
+ ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
35494
+ ...part.signature !== void 0 ? { signature: part.signature } : {},
35495
+ toolCallId: part.toolCallId,
35496
+ type: "tool-approval-request"
35497
+ };
35498
+ case "tool-approval-response":
35499
+ return {
35500
+ approvalId: part.approvalId,
35501
+ approved: part.approved,
35502
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35503
+ ...part.reason !== void 0 ? { reason: part.reason } : {},
35504
+ type: "tool-approval-response"
35505
+ };
35506
+ case "file-data":
35507
+ case "image-data":
35508
+ return {
35509
+ data: part.data,
35510
+ ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
35511
+ mediaType: part.mediaType,
35512
+ type: part.type
35513
+ };
35514
+ case "file-url":
35515
+ case "image-url":
35516
+ return {
35517
+ ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35518
+ type: part.type,
35519
+ url: part.url
35520
+ };
35521
+ case "file-id":
35522
+ case "image-file-id":
35523
+ return { fileId: part.fileId, type: part.type };
35524
+ case "file-reference":
35525
+ case "image-file-reference":
35526
+ return {
35527
+ providerReference: part.providerReference,
35528
+ type: part.type
35529
+ };
35530
+ }
35531
+ }
34916
35532
  function isCapturedModelInput(input) {
34917
- return Array.isArray(input);
35533
+ return Array.isArray(input) && input.every(
35534
+ (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))
35535
+ );
34918
35536
  }
34919
35537
  function llmInputKey(sessionId, turnId, stepIndex) {
34920
35538
  return `${sessionId}\0${turnId}\0${stepIndex}`;
@@ -38309,6 +38927,8 @@ var BaseNode = class {
38309
38927
  this.graph = graph;
38310
38928
  this.id = id;
38311
38929
  }
38930
+ graph;
38931
+ id;
38312
38932
  __type = "node";
38313
38933
  dependencies = [];
38314
38934
  addDependency(dependency) {
@@ -38342,6 +38962,7 @@ var PromptNode = class extends BaseNode {
38342
38962
  super(graph, id);
38343
38963
  this.prompt = prompt;
38344
38964
  }
38965
+ prompt;
38345
38966
  async build(context) {
38346
38967
  return {
38347
38968
  type: "function",
@@ -38354,6 +38975,7 @@ var GateNode = class extends BaseNode {
38354
38975
  super(graph, id);
38355
38976
  this.condition = condition;
38356
38977
  }
38978
+ condition;
38357
38979
  async build(context) {
38358
38980
  return {
38359
38981
  type: "gate",
@@ -38378,6 +39000,7 @@ var PromptTemplateNode = class extends BaseNode {
38378
39000
  super(graph, id);
38379
39001
  this.prompt = prompt;
38380
39002
  }
39003
+ prompt;
38381
39004
  async build(context) {
38382
39005
  return {
38383
39006
  type: "prompt_template",
@@ -38390,6 +39013,7 @@ var LiteralNode = class extends BaseNode {
38390
39013
  super(graph, id);
38391
39014
  this.value = value;
38392
39015
  }
39016
+ value;
38393
39017
  async build(context) {
38394
39018
  return {
38395
39019
  type: "literal",
@@ -39483,6 +40107,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
39483
40107
  this._state = _state;
39484
40108
  this.spanTypeFilter = spanTypeFilter;
39485
40109
  }
40110
+ _objectId;
40111
+ rootSpanId;
40112
+ _state;
40113
+ spanTypeFilter;
39486
40114
  static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
39487
40115
  const children = [
39488
40116
  // Base filter: root_span_id = 'value'
@@ -39933,6 +40561,8 @@ var EvalResultWithSummary = class {
39933
40561
  this.summary = summary;
39934
40562
  this.results = results;
39935
40563
  }
40564
+ summary;
40565
+ results;
39936
40566
  /**
39937
40567
  * @deprecated Use `summary` instead.
39938
40568
  */
@@ -41351,6 +41981,7 @@ var ToolBuilder = class {
41351
41981
  constructor(project) {
41352
41982
  this.project = project;
41353
41983
  }
41984
+ project;
41354
41985
  taskCounter = 0;
41355
41986
  // This type definition is just a catch all so that the implementation can be
41356
41987
  // less specific than the two more specific declarations above.
@@ -41381,6 +42012,7 @@ var ScorerBuilder = class {
41381
42012
  constructor(project) {
41382
42013
  this.project = project;
41383
42014
  }
42015
+ project;
41384
42016
  taskCounter = 0;
41385
42017
  create(opts) {
41386
42018
  this.taskCounter++;
@@ -41440,6 +42072,7 @@ var ClassifierBuilder = class {
41440
42072
  constructor(project) {
41441
42073
  this.project = project;
41442
42074
  }
42075
+ project;
41443
42076
  taskCounter = 0;
41444
42077
  create(opts) {
41445
42078
  this.taskCounter++;
@@ -41475,6 +42108,7 @@ var CodeFunction = class {
41475
42108
  throw new Error("parameters are required if return type is defined");
41476
42109
  }
41477
42110
  }
42111
+ project;
41478
42112
  handler;
41479
42113
  name;
41480
42114
  slug;
@@ -41562,6 +42196,7 @@ var PromptBuilder = class {
41562
42196
  constructor(project) {
41563
42197
  this.project = project;
41564
42198
  }
42199
+ project;
41565
42200
  create(opts) {
41566
42201
  const toolFunctions = [];
41567
42202
  const rawTools = [];
@@ -41638,6 +42273,7 @@ var ParametersBuilder = class {
41638
42273
  constructor(project) {
41639
42274
  this.project = project;
41640
42275
  }
42276
+ project;
41641
42277
  create(opts) {
41642
42278
  const slug = opts.slug ?? slugify(opts.name, { lower: true, strict: true });
41643
42279
  const codeParameters = new CodeParameters(this.project, {