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.js CHANGED
@@ -222,6 +222,7 @@ var DefaultChannel = class {
222
222
  constructor(name) {
223
223
  this.name = name;
224
224
  }
225
+ name;
225
226
  hasSubscribers = false;
226
227
  subscribe(_subscription) {
227
228
  }
@@ -1278,6 +1279,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1278
1279
  constructor(data) {
1279
1280
  this.data = data;
1280
1281
  }
1282
+ data;
1281
1283
  toStr() {
1282
1284
  const jsonObj = {
1283
1285
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1785,6 +1787,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1785
1787
  constructor(data) {
1786
1788
  this.data = data;
1787
1789
  }
1790
+ data;
1788
1791
  toStr() {
1789
1792
  const jsonObj = {
1790
1793
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -5018,6 +5021,97 @@ var SpanCache = class {
5018
5021
  }
5019
5022
  };
5020
5023
 
5024
+ // src/span-origin.ts
5025
+ var SDK_VERSION = true ? "3.24.0" : "0.0.0";
5026
+ function detectSpanOriginEnvironment(explicit) {
5027
+ if (explicit) return explicit;
5028
+ const envType = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_TYPE");
5029
+ const envName = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_NAME");
5030
+ if (envType || envName) {
5031
+ return {
5032
+ ...envType ? { type: envType } : {},
5033
+ ...envName ? { name: envName } : {}
5034
+ };
5035
+ }
5036
+ const ci = firstPresent([
5037
+ ["GITHUB_ACTIONS", "github_actions"],
5038
+ ["GITLAB_CI", "gitlab_ci"],
5039
+ ["CIRCLECI", "circleci"],
5040
+ ["BUILDKITE", "buildkite"],
5041
+ ["JENKINS_URL", "jenkins"],
5042
+ ["JENKINS_HOME", "jenkins"],
5043
+ ["TF_BUILD", "azure_pipelines"],
5044
+ ["TEAMCITY_VERSION", "teamcity"],
5045
+ ["TRAVIS", "travis"],
5046
+ ["BITBUCKET_BUILD_NUMBER", "bitbucket"]
5047
+ ]);
5048
+ if (ci) return { type: "ci", name: ci };
5049
+ if (isomorph_default.getEnv("CI")) return { type: "ci", name: "ci" };
5050
+ const earlyServer = firstPresent([
5051
+ ["VERCEL", "vercel"],
5052
+ ["NETLIFY", "netlify"]
5053
+ ]);
5054
+ if (earlyServer) return { type: "server", name: earlyServer };
5055
+ if (isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI") || isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI_V4")) {
5056
+ return { type: "server", name: "ecs" };
5057
+ }
5058
+ const awsExecutionEnv = isomorph_default.getEnv("AWS_EXECUTION_ENV");
5059
+ if (awsExecutionEnv?.startsWith("AWS_ECS_")) {
5060
+ return { type: "server", name: "ecs" };
5061
+ }
5062
+ if (awsExecutionEnv?.startsWith("AWS_Lambda_")) {
5063
+ return { type: "server", name: "aws_lambda" };
5064
+ }
5065
+ if (isomorph_default.getEnv("AWS_LAMBDA_FUNCTION_NAME")) {
5066
+ return { type: "server", name: "aws_lambda" };
5067
+ }
5068
+ const server = firstPresent([
5069
+ ["K_SERVICE", "cloud_run"],
5070
+ ["FUNCTION_TARGET", "gcp_functions"],
5071
+ ["KUBERNETES_SERVICE_HOST", "kubernetes"],
5072
+ ["DYNO", "heroku"],
5073
+ ["FLY_APP_NAME", "fly"],
5074
+ ["RAILWAY_ENVIRONMENT", "railway"],
5075
+ ["RENDER_SERVICE_NAME", "render"]
5076
+ ]);
5077
+ if (server) return { type: "server", name: server };
5078
+ return deploymentModeEnvironment("NODE_ENV", isomorph_default.getEnv("NODE_ENV"));
5079
+ }
5080
+ function makeSpanOrigin(instrumentationName, environment) {
5081
+ return {
5082
+ name: "braintrust.sdk.javascript",
5083
+ version: SDK_VERSION,
5084
+ instrumentation: { name: instrumentationName },
5085
+ ...environment ? { environment } : {}
5086
+ };
5087
+ }
5088
+ function mergeSpanOriginContext(context, instrumentationName, environment) {
5089
+ const next = { ...context ?? {} };
5090
+ const current = isObject2(next.span_origin) ? { ...next.span_origin } : {};
5091
+ next.span_origin = {
5092
+ ...makeSpanOrigin(instrumentationName, environment),
5093
+ ...current
5094
+ };
5095
+ return next;
5096
+ }
5097
+ function firstPresent(entries) {
5098
+ return entries.find(([key]) => Boolean(isomorph_default.getEnv(key)))?.[1];
5099
+ }
5100
+ function deploymentModeEnvironment(_key, value) {
5101
+ if (!value) return void 0;
5102
+ const normalized = value.toLowerCase();
5103
+ if (normalized === "production" || normalized === "staging") {
5104
+ return { type: "server", name: normalized };
5105
+ }
5106
+ if (normalized === "development" || normalized === "local") {
5107
+ return { type: "local", name: normalized };
5108
+ }
5109
+ return { name: value };
5110
+ }
5111
+ function isObject2(value) {
5112
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5113
+ }
5114
+
5021
5115
  // src/logger.ts
5022
5116
  var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
5023
5117
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
@@ -5066,6 +5160,7 @@ var LoginInvalidOrgError = class extends Error {
5066
5160
  super(message);
5067
5161
  this.message = message;
5068
5162
  }
5163
+ message;
5069
5164
  };
5070
5165
  var REDACTION_FIELDS = [
5071
5166
  "input",
@@ -5081,6 +5176,8 @@ var MaskingError = class {
5081
5176
  this.fieldName = fieldName;
5082
5177
  this.errorType = errorType;
5083
5178
  }
5179
+ fieldName;
5180
+ errorType;
5084
5181
  get errorMsg() {
5085
5182
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
5086
5183
  }
@@ -5290,7 +5387,9 @@ var BraintrustState = class _BraintrustState {
5290
5387
  diskCache: parametersDiskCache
5291
5388
  });
5292
5389
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5390
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5293
5391
  }
5392
+ loginParams;
5294
5393
  id;
5295
5394
  currentExperiment;
5296
5395
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5325,6 +5424,7 @@ var BraintrustState = class _BraintrustState {
5325
5424
  _idGenerator = null;
5326
5425
  _contextManager = null;
5327
5426
  _otelFlushCallback = null;
5427
+ spanOriginEnvironment;
5328
5428
  resetLoginInfo() {
5329
5429
  this.appUrl = null;
5330
5430
  this.appPublicUrl = null;
@@ -7943,6 +8043,7 @@ function initLogger(options = {}) {
7943
8043
  orgName,
7944
8044
  forceLogin,
7945
8045
  debugLogLevel,
8046
+ environment,
7946
8047
  fetch: fetch2,
7947
8048
  state: stateArg
7948
8049
  } = options || {};
@@ -7959,6 +8060,7 @@ function initLogger(options = {}) {
7959
8060
  };
7960
8061
  const state = stateArg ?? _globalState;
7961
8062
  state.setDebugLogLevel(debugLogLevel);
8063
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7962
8064
  state.enforceQueueSizeLimit(true);
7963
8065
  const lazyMetadata = new LazyValue(
7964
8066
  async () => {
@@ -9150,6 +9252,11 @@ var ObjectFetcher = class {
9150
9252
  this._internal_btql = _internal_btql;
9151
9253
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
9152
9254
  }
9255
+ objectType;
9256
+ pinnedVersion;
9257
+ mutateRecord;
9258
+ _internal_btql;
9259
+ _internalBrainstoreRealtime;
9153
9260
  _fetchedData = void 0;
9154
9261
  get id() {
9155
9262
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -9588,6 +9695,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9588
9695
  this.state = state;
9589
9696
  this.lazyMetadata = lazyMetadata;
9590
9697
  }
9698
+ state;
9699
+ lazyMetadata;
9591
9700
  get id() {
9592
9701
  return (async () => {
9593
9702
  return (await this.lazyMetadata.get()).experiment.id;
@@ -9710,7 +9819,11 @@ var SpanImpl = class _SpanImpl {
9710
9819
  metrics: {
9711
9820
  start: args.startTime ?? getCurrentUnixTimestamp()
9712
9821
  },
9713
- context: { ...callerLocation },
9822
+ context: mergeSpanOriginContext(
9823
+ { ...callerLocation },
9824
+ "braintrust-js-logger",
9825
+ this._state.spanOriginEnvironment
9826
+ ),
9714
9827
  span_attributes: {
9715
9828
  name,
9716
9829
  type,
@@ -10084,6 +10197,7 @@ var Dataset2 = class extends ObjectFetcher {
10084
10197
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
10085
10198
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
10086
10199
  }
10200
+ state;
10087
10201
  lazyMetadata;
10088
10202
  __braintrust_dataset_marker = true;
10089
10203
  newRecords = 0;
@@ -10598,6 +10712,9 @@ var Prompt2 = class _Prompt {
10598
10712
  this.noTrace = noTrace;
10599
10713
  void this.__braintrust_prompt_marker;
10600
10714
  }
10715
+ metadata;
10716
+ defaults;
10717
+ noTrace;
10601
10718
  parsedPromptData;
10602
10719
  hasParsedPromptData = false;
10603
10720
  __braintrust_prompt_marker = true;
@@ -10835,6 +10952,7 @@ var RemoteEvalParameters = class {
10835
10952
  this.metadata = metadata;
10836
10953
  void this.__braintrust_parameters_marker;
10837
10954
  }
10955
+ metadata;
10838
10956
  __braintrust_parameters_marker = true;
10839
10957
  get id() {
10840
10958
  return this.metadata.id;
@@ -15300,6 +15418,24 @@ var aiSDKChannels = defineChannels("ai", {
15300
15418
  kind: "sync-stream"
15301
15419
  })
15302
15420
  });
15421
+ var harnessAgentChannels = defineChannels("@ai-sdk/harness", {
15422
+ generate: channel({
15423
+ channelName: "HarnessAgent.generate",
15424
+ kind: "async"
15425
+ }),
15426
+ stream: channel({
15427
+ channelName: "HarnessAgent.stream",
15428
+ kind: "async"
15429
+ }),
15430
+ continueGenerate: channel({
15431
+ channelName: "HarnessAgent.continueGenerate",
15432
+ kind: "async"
15433
+ }),
15434
+ continueStream: channel({
15435
+ channelName: "HarnessAgent.continueStream",
15436
+ kind: "async"
15437
+ })
15438
+ });
15303
15439
 
15304
15440
  // src/instrumentation/plugins/ai-sdk-plugin.ts
15305
15441
  var DEFAULT_DENY_OUTPUT_PATHS = [
@@ -15568,6 +15704,84 @@ var AISDKPlugin = class extends BasePlugin {
15568
15704
  })
15569
15705
  })
15570
15706
  );
15707
+ this.unsubscribers.push(
15708
+ traceStreamingChannel(harnessAgentChannels.generate, {
15709
+ name: "HarnessAgent.generate",
15710
+ type: "task" /* TASK */,
15711
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15712
+ extractOutput: (result, endEvent) => processAISDKOutput(
15713
+ result,
15714
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15715
+ ),
15716
+ extractMetrics: (result) => extractTokenMetrics(result),
15717
+ aggregateChunks: aggregateAISDKChunks
15718
+ })
15719
+ );
15720
+ this.unsubscribers.push(
15721
+ traceStreamingChannel(harnessAgentChannels.stream, {
15722
+ name: "HarnessAgent.stream",
15723
+ type: "task" /* TASK */,
15724
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15725
+ extractOutput: (result, endEvent) => processAISDKOutput(
15726
+ result,
15727
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15728
+ ),
15729
+ extractMetrics: (result, startTime) => ({
15730
+ ...extractTokenMetrics(result),
15731
+ ...startTime === void 0 ? {} : {
15732
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15733
+ }
15734
+ }),
15735
+ aggregateChunks: aggregateAISDKChunks,
15736
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15737
+ defaultDenyOutputPaths: denyOutputPaths,
15738
+ endEvent,
15739
+ result,
15740
+ resolvePromiseUsage: true,
15741
+ span,
15742
+ startTime
15743
+ })
15744
+ })
15745
+ );
15746
+ this.unsubscribers.push(
15747
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
15748
+ name: "HarnessAgent.continueGenerate",
15749
+ type: "task" /* TASK */,
15750
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15751
+ extractOutput: (result, endEvent) => processAISDKOutput(
15752
+ result,
15753
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15754
+ ),
15755
+ extractMetrics: (result) => extractTokenMetrics(result),
15756
+ aggregateChunks: aggregateAISDKChunks
15757
+ })
15758
+ );
15759
+ this.unsubscribers.push(
15760
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
15761
+ name: "HarnessAgent.continueStream",
15762
+ type: "task" /* TASK */,
15763
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
15764
+ extractOutput: (result, endEvent) => processAISDKOutput(
15765
+ result,
15766
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
15767
+ ),
15768
+ extractMetrics: (result, startTime) => ({
15769
+ ...extractTokenMetrics(result),
15770
+ ...startTime === void 0 ? {} : {
15771
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
15772
+ }
15773
+ }),
15774
+ aggregateChunks: aggregateAISDKChunks,
15775
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
15776
+ defaultDenyOutputPaths: denyOutputPaths,
15777
+ endEvent,
15778
+ result,
15779
+ resolvePromiseUsage: true,
15780
+ span,
15781
+ startTime
15782
+ })
15783
+ })
15784
+ );
15571
15785
  this.unsubscribers.push(
15572
15786
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
15573
15787
  name: "ToolLoopAgent.generate",
@@ -16098,6 +16312,45 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
16098
16312
  metadata
16099
16313
  };
16100
16314
  }
16315
+ function prepareAISDKHarnessAgentInput(params, self) {
16316
+ if (isObject(self)) {
16317
+ try {
16318
+ if (isObject(self.settings)) {
16319
+ const settings = self.settings;
16320
+ if (settings.telemetry === void 0) {
16321
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
16322
+ }
16323
+ }
16324
+ } catch {
16325
+ }
16326
+ }
16327
+ const selectedInput = {};
16328
+ if (params.prompt !== void 0) {
16329
+ selectedInput.prompt = params.prompt;
16330
+ }
16331
+ if (params.messages !== void 0) {
16332
+ selectedInput.messages = params.messages;
16333
+ }
16334
+ if (params.toolApprovalContinuations !== void 0) {
16335
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
16336
+ }
16337
+ const metadata = extractMetadataFromCallParams({}, self);
16338
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
16339
+ metadata.sessionId = params.session.sessionId;
16340
+ }
16341
+ if (isObject(self)) {
16342
+ if (typeof self.harnessId === "string") {
16343
+ metadata.harnessId = self.harnessId;
16344
+ }
16345
+ if (typeof self.permissionMode === "string") {
16346
+ metadata.permissionMode = self.permissionMode;
16347
+ }
16348
+ }
16349
+ return {
16350
+ input: processAISDKCallInput(selectedInput).input,
16351
+ metadata
16352
+ };
16353
+ }
16101
16354
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
16102
16355
  registerWorkflowAgentWrapperSpan(span);
16103
16356
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -16945,6 +17198,7 @@ function patchAISDKStreamingResult(args) {
16945
17198
  endEvent,
16946
17199
  onComplete,
16947
17200
  result,
17201
+ resolvePromiseUsage,
16948
17202
  span,
16949
17203
  startTime
16950
17204
  } = args;
@@ -16971,6 +17225,22 @@ function patchAISDKStreamingResult(args) {
16971
17225
  outputLogged = true;
16972
17226
  try {
16973
17227
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
17228
+ if (resolvePromiseUsage) {
17229
+ try {
17230
+ const resultRecord2 = result;
17231
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
17232
+ if (isPromiseLike(pendingUsage)) {
17233
+ const usage = await Promise.resolve(pendingUsage);
17234
+ if (isObject(usage)) {
17235
+ Object.assign(
17236
+ metrics,
17237
+ extractTokenMetrics({ usage })
17238
+ );
17239
+ }
17240
+ }
17241
+ } catch {
17242
+ }
17243
+ }
16974
17244
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
16975
17245
  metrics.time_to_first_token = firstChunkTime - startTime;
16976
17246
  }
@@ -29228,6 +29498,16 @@ function cleanObject(obj) {
29228
29498
  })
29229
29499
  );
29230
29500
  }
29501
+ function normalizeTokenMetrics(obj) {
29502
+ const metrics = cleanObject(obj);
29503
+ if (metrics.total_tokens !== void 0) {
29504
+ metrics.tokens = metrics.total_tokens;
29505
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
29506
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
29507
+ }
29508
+ delete metrics.total_tokens;
29509
+ return metrics;
29510
+ }
29231
29511
  function walkGenerations(response) {
29232
29512
  const result = [];
29233
29513
  const generations = response.generations || [];
@@ -29274,7 +29554,7 @@ function getMetricsFromResponse(response) {
29274
29554
  continue;
29275
29555
  }
29276
29556
  const inputTokenDetails = usageMetadata.input_token_details;
29277
- return cleanObject({
29557
+ return normalizeTokenMetrics({
29278
29558
  total_tokens: usageMetadata.total_tokens,
29279
29559
  prompt_tokens: usageMetadata.input_tokens,
29280
29560
  completion_tokens: usageMetadata.output_tokens,
@@ -29284,7 +29564,7 @@ function getMetricsFromResponse(response) {
29284
29564
  }
29285
29565
  const llmOutput = response.llmOutput || {};
29286
29566
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
29287
- return cleanObject({
29567
+ return normalizeTokenMetrics({
29288
29568
  total_tokens: tokenUsage.totalTokens,
29289
29569
  prompt_tokens: tokenUsage.promptTokens,
29290
29570
  completion_tokens: tokenUsage.completionTokens
@@ -32973,6 +33253,26 @@ function wrapAISDK(aiSDK, options = {}) {
32973
33253
  }
32974
33254
  });
32975
33255
  }
33256
+ function isHarnessAgentInstance(instance) {
33257
+ try {
33258
+ const visited = /* @__PURE__ */ new Set();
33259
+ let prototype = Object.getPrototypeOf(instance);
33260
+ while (prototype !== null && !visited.has(prototype)) {
33261
+ visited.add(prototype);
33262
+ const constructor = Object.getOwnPropertyDescriptor(
33263
+ prototype,
33264
+ "constructor"
33265
+ )?.value;
33266
+ const constructorName = typeof constructor === "function" ? Object.getOwnPropertyDescriptor(constructor, "name")?.value : void 0;
33267
+ if (constructorName === "HarnessAgent") {
33268
+ return true;
33269
+ }
33270
+ prototype = Object.getPrototypeOf(prototype);
33271
+ }
33272
+ } catch {
33273
+ }
33274
+ return false;
33275
+ }
32976
33276
  var wrapAgentClass = (AgentClass, options = {}) => {
32977
33277
  const typedAgentClass = AgentClass;
32978
33278
  return new Proxy(typedAgentClass, {
@@ -32982,9 +33282,46 @@ var wrapAgentClass = (AgentClass, options = {}) => {
32982
33282
  args,
32983
33283
  newTarget
32984
33284
  );
33285
+ const harnessAgent = isHarnessAgentInstance(instance) ? instance : null;
32985
33286
  return new Proxy(instance, {
32986
33287
  get(instanceTarget, prop, instanceReceiver) {
32987
33288
  const original = Reflect.get(instanceTarget, prop, instanceTarget);
33289
+ if (harnessAgent && typeof original === "function") {
33290
+ switch (prop) {
33291
+ case "generate":
33292
+ return wrapHarnessAgentGenerate(
33293
+ original,
33294
+ harnessAgent,
33295
+ harnessAgentChannels.generate,
33296
+ "HarnessAgent.generate",
33297
+ options
33298
+ );
33299
+ case "stream":
33300
+ return wrapHarnessAgentStream(
33301
+ original,
33302
+ harnessAgent,
33303
+ harnessAgentChannels.stream,
33304
+ "HarnessAgent.stream",
33305
+ options
33306
+ );
33307
+ case "continueGenerate":
33308
+ return wrapHarnessAgentGenerate(
33309
+ original,
33310
+ harnessAgent,
33311
+ harnessAgentChannels.continueGenerate,
33312
+ "HarnessAgent.continueGenerate",
33313
+ options
33314
+ );
33315
+ case "continueStream":
33316
+ return wrapHarnessAgentStream(
33317
+ original,
33318
+ harnessAgent,
33319
+ harnessAgentChannels.continueStream,
33320
+ "HarnessAgent.continueStream",
33321
+ options
33322
+ );
33323
+ }
33324
+ }
32988
33325
  if (prop === "generate" && typeof original === "function" && instanceTarget.constructor.name !== "WorkflowAgent") {
32989
33326
  return wrapAgentGenerate(original, instanceTarget, options);
32990
33327
  }
@@ -33000,6 +33337,26 @@ var wrapAgentClass = (AgentClass, options = {}) => {
33000
33337
  }
33001
33338
  });
33002
33339
  };
33340
+ var wrapHarnessAgentGenerate = (generate, instance, channel2, name, options) => makeGenerateTextWrapper(
33341
+ channel2,
33342
+ name,
33343
+ generate.bind(instance),
33344
+ {
33345
+ self: instance,
33346
+ spanType: "task" /* TASK */
33347
+ },
33348
+ options
33349
+ );
33350
+ var wrapHarnessAgentStream = (stream, instance, channel2, name, options) => makeStreamWrapper(
33351
+ channel2,
33352
+ name,
33353
+ stream.bind(instance),
33354
+ {
33355
+ self: instance,
33356
+ spanType: "task" /* TASK */
33357
+ },
33358
+ options
33359
+ );
33003
33360
  var wrapAgentGenerate = (generate, instance, options = {}) => {
33004
33361
  const defaultName = `${instance.constructor.name}.generate`;
33005
33362
  return async (params) => makeGenerateTextWrapper(
@@ -33226,6 +33583,7 @@ var BraintrustLanguageModelWrapper = class {
33226
33583
  this.supportsUrl = (url) => this.model.supportsUrl(url);
33227
33584
  }
33228
33585
  }
33586
+ model;
33229
33587
  supportsUrl;
33230
33588
  get specificationVersion() {
33231
33589
  return this.model.specificationVersion;
@@ -33808,6 +34166,7 @@ function BraintrustMiddleware(config = {}) {
33808
34166
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
33809
34167
  var MAX_EVE_CACHE_ENTRIES = 1e4;
33810
34168
  var MAX_STORED_LLM_INPUTS = 100;
34169
+ var MAX_STORED_REASONING_BLOCKS = 100;
33811
34170
  var MAX_STORED_SPAN_REFERENCES = 1e4;
33812
34171
  var MAX_STORED_STEP_STARTS = 1e4;
33813
34172
  function braintrustEveHook(options) {
@@ -33846,6 +34205,7 @@ var ResumedEveSpan = class {
33846
34205
  this.reference = reference;
33847
34206
  this.endTime = reference.endTime;
33848
34207
  }
34208
+ reference;
33849
34209
  endTime;
33850
34210
  get rootSpanId() {
33851
34211
  return this.reference.rootSpanId;
@@ -33878,6 +34238,7 @@ var EveBridge = class {
33878
34238
  constructor(state) {
33879
34239
  this.state = state;
33880
34240
  }
34241
+ state;
33881
34242
  eventQueuesBySession = /* @__PURE__ */ new Map();
33882
34243
  completedToolKeys = new LRUCache({
33883
34244
  max: MAX_EVE_CACHE_ENTRIES
@@ -34056,6 +34417,9 @@ var EveBridge = class {
34056
34417
  case "step.started":
34057
34418
  await this.handleStepStarted(event, ctx, hookMetadata);
34058
34419
  return true;
34420
+ case "reasoning.completed":
34421
+ this.handleReasoningCompleted(event, ctx);
34422
+ return true;
34059
34423
  case "message.completed":
34060
34424
  this.handleMessageCompleted(event, ctx);
34061
34425
  return true;
@@ -34147,6 +34511,7 @@ var EveBridge = class {
34147
34511
  key,
34148
34512
  metadata,
34149
34513
  metrics: {},
34514
+ sessionId,
34150
34515
  span,
34151
34516
  stepsByIndex: /* @__PURE__ */ new Map(),
34152
34517
  turnId: event.data.turnId
@@ -34177,6 +34542,12 @@ var EveBridge = class {
34177
34542
  const endTime = eventTime2(event);
34178
34543
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
34179
34544
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34545
+ clearStoredEveReasoning(
34546
+ this.state,
34547
+ sessionId,
34548
+ event.data.turnId,
34549
+ event.data.stepIndex
34550
+ );
34180
34551
  }
34181
34552
  const stepOrdinal = this.stepOrdinal(event);
34182
34553
  const metadata = { ...turn.metadata };
@@ -34186,6 +34557,13 @@ var EveBridge = class {
34186
34557
  event.data.turnId,
34187
34558
  event.data.stepIndex
34188
34559
  );
34560
+ const reasoning = readStoredEveReasoning(
34561
+ this.state,
34562
+ sessionId,
34563
+ event.data.turnId,
34564
+ event.data.stepIndex
34565
+ );
34566
+ const output = mergeEveReasoning(void 0, reasoning);
34189
34567
  const { rowId: eventId, spanId } = await generateEveIds(
34190
34568
  "step",
34191
34569
  sessionId,
@@ -34203,32 +34581,52 @@ var EveBridge = class {
34203
34581
  spanId,
34204
34582
  startTime: eventTime2(event)
34205
34583
  });
34206
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
34584
+ span.log({
34585
+ ...input !== void 0 ? { input } : {},
34586
+ metadata
34587
+ });
34207
34588
  turn.stepsByIndex.set(event.data.stepIndex, {
34208
34589
  ...input !== void 0 ? { input } : {},
34209
34590
  metadata,
34210
34591
  metrics: {},
34592
+ ...output !== void 0 ? { output } : {},
34593
+ reasoning,
34211
34594
  span
34212
34595
  });
34213
34596
  }
34597
+ handleReasoningCompleted(event, ctx) {
34598
+ const sessionId = sessionIdFromContext(ctx);
34599
+ if (!sessionId) {
34600
+ return;
34601
+ }
34602
+ const reasoning = storeEveReasoning(this.state, sessionId, event);
34603
+ const step = this.stepForEvent(event, ctx);
34604
+ if (step) {
34605
+ step.reasoning = reasoning;
34606
+ step.output = mergeEveReasoning(step.output, reasoning);
34607
+ }
34608
+ }
34214
34609
  handleMessageCompleted(event, ctx) {
34215
34610
  const step = this.stepForEvent(event, ctx);
34216
34611
  if (!step) {
34217
34612
  return;
34218
34613
  }
34219
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
34614
+ const existingMessage = eveOutputMessage(step.output);
34220
34615
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
34221
- step.output = [
34222
- {
34223
- finish_reason: normalizedFinishReason(event.data.finishReason),
34224
- index: 0,
34225
- message: {
34226
- content: event.data.message,
34227
- role: "assistant",
34228
- ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34616
+ step.output = mergeEveReasoning(
34617
+ [
34618
+ {
34619
+ finish_reason: normalizedFinishReason(event.data.finishReason),
34620
+ index: 0,
34621
+ message: {
34622
+ content: event.data.message,
34623
+ role: "assistant",
34624
+ ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
34625
+ }
34229
34626
  }
34230
- }
34231
- ];
34627
+ ],
34628
+ step.reasoning
34629
+ );
34232
34630
  const turn = this.turnForEvent(event, ctx);
34233
34631
  if (turn && event.data.finishReason !== "tool-calls") {
34234
34632
  turn.output = event.data.message;
@@ -34237,16 +34635,19 @@ var EveBridge = class {
34237
34635
  handleResultCompleted(event, ctx) {
34238
34636
  const step = this.stepForEvent(event, ctx);
34239
34637
  if (step) {
34240
- step.output = [
34241
- {
34242
- finish_reason: "stop",
34243
- index: 0,
34244
- message: {
34245
- content: event.data.result,
34246
- role: "assistant"
34638
+ step.output = mergeEveReasoning(
34639
+ [
34640
+ {
34641
+ finish_reason: "stop",
34642
+ index: 0,
34643
+ message: {
34644
+ content: event.data.result,
34645
+ role: "assistant"
34646
+ }
34247
34647
  }
34248
- }
34249
- ];
34648
+ ],
34649
+ step.reasoning
34650
+ );
34250
34651
  }
34251
34652
  const turn = this.turnForEvent(event, ctx);
34252
34653
  if (turn) {
@@ -34296,18 +34697,20 @@ var EveBridge = class {
34296
34697
  type: "function"
34297
34698
  });
34298
34699
  }
34299
- step.output = [
34300
- {
34301
- finish_reason: "tool_calls",
34302
- index: 0,
34303
- message: {
34304
- content: null,
34305
- role: "assistant",
34306
- tool_calls: [...toolCallsById.values()]
34700
+ step.output = mergeEveReasoning(
34701
+ [
34702
+ {
34703
+ finish_reason: "tool_calls",
34704
+ index: 0,
34705
+ message: {
34706
+ content: null,
34707
+ role: "assistant",
34708
+ tool_calls: [...toolCallsById.values()]
34709
+ }
34307
34710
  }
34308
- }
34309
- ];
34310
- step.span.log({ metadata: step.metadata, output: step.output });
34711
+ ],
34712
+ step.reasoning
34713
+ );
34311
34714
  }
34312
34715
  async handleActionResult(event, ctx, hookMetadata) {
34313
34716
  if (isToolResult(event.data.result)) {
@@ -34485,6 +34888,7 @@ var EveBridge = class {
34485
34888
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
34486
34889
  };
34487
34890
  step.metrics = { ...step.metrics, ...metrics };
34891
+ const sessionId = sessionIdFromContext(ctx);
34488
34892
  if (Array.isArray(step.output) && isObject(step.output[0])) {
34489
34893
  const finishReason = step.output[0].finish_reason;
34490
34894
  if (typeof finishReason !== "string") {
@@ -34509,6 +34913,14 @@ var EveBridge = class {
34509
34913
  turn.stepsByIndex.delete(event.data.stepIndex);
34510
34914
  }
34511
34915
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34916
+ if (sessionId) {
34917
+ clearStoredEveReasoning(
34918
+ this.state,
34919
+ sessionId,
34920
+ event.data.turnId,
34921
+ event.data.stepIndex
34922
+ );
34923
+ }
34512
34924
  }
34513
34925
  handleStepFailed(event, ctx) {
34514
34926
  const step = this.stepForEvent(event, ctx);
@@ -34526,6 +34938,15 @@ var EveBridge = class {
34526
34938
  const turn = this.turnForEvent(event, ctx);
34527
34939
  turn?.stepsByIndex.delete(event.data.stepIndex);
34528
34940
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
34941
+ const sessionId = sessionIdFromContext(ctx);
34942
+ if (sessionId) {
34943
+ clearStoredEveReasoning(
34944
+ this.state,
34945
+ sessionId,
34946
+ event.data.turnId,
34947
+ event.data.stepIndex
34948
+ );
34949
+ }
34529
34950
  }
34530
34951
  handleTurnCompleted(event, ctx) {
34531
34952
  const turn = this.turnForEvent(event, ctx);
@@ -34623,6 +35044,7 @@ var EveBridge = class {
34623
35044
  key,
34624
35045
  metadata,
34625
35046
  metrics: {},
35047
+ sessionId,
34626
35048
  span,
34627
35049
  stepsByIndex: /* @__PURE__ */ new Map(),
34628
35050
  turnId: event.data.turnId
@@ -34885,6 +35307,9 @@ var EveBridge = class {
34885
35307
  const normalized = normalizeEveTraceState(current);
34886
35308
  return {
34887
35309
  ...normalized,
35310
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35311
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
35312
+ ),
34888
35313
  stepStarts: normalized.stepStarts.filter(
34889
35314
  (entry) => entry.turnId !== turn.turnId
34890
35315
  )
@@ -34924,6 +35349,7 @@ function emptyEveTraceState() {
34924
35349
  return {
34925
35350
  llmInputs: [],
34926
35351
  metadata: {},
35352
+ reasoningBlocks: [],
34927
35353
  spanReferences: [],
34928
35354
  stepStarts: []
34929
35355
  };
@@ -34974,6 +35400,21 @@ function normalizeEveTraceState(state) {
34974
35400
  const input = entry["input"];
34975
35401
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
34976
35402
  }).slice(-MAX_STORED_LLM_INPUTS) : [];
35403
+ const reasoningBlocks = Array.isArray(state["reasoningBlocks"]) ? state["reasoningBlocks"].flatMap((entry) => {
35404
+ if (!isObject(entry)) {
35405
+ return [];
35406
+ }
35407
+ const content = entry["content"];
35408
+ const eventAt = entry["eventAt"];
35409
+ const key = entry["key"];
35410
+ return typeof content === "string" && (eventAt === void 0 || typeof eventAt === "string") && typeof key === "string" ? [
35411
+ {
35412
+ content,
35413
+ ...typeof eventAt === "string" ? { eventAt } : {},
35414
+ key
35415
+ }
35416
+ ] : [];
35417
+ }).slice(-MAX_STORED_REASONING_BLOCKS) : [];
34977
35418
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
34978
35419
  if (!isObject(entry)) {
34979
35420
  return [];
@@ -34984,7 +35425,13 @@ function normalizeEveTraceState(state) {
34984
35425
  const turnId = entry["turnId"];
34985
35426
  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 }] : [];
34986
35427
  }).slice(-MAX_STORED_STEP_STARTS) : [];
34987
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
35428
+ return {
35429
+ llmInputs,
35430
+ metadata: { ...metadata },
35431
+ reasoningBlocks,
35432
+ spanReferences,
35433
+ stepStarts
35434
+ };
34988
35435
  }
34989
35436
  function readEveTraceState(state) {
34990
35437
  try {
@@ -34993,23 +35440,85 @@ function readEveTraceState(state) {
34993
35440
  return emptyEveTraceState();
34994
35441
  }
34995
35442
  }
34996
- function captureEveModelInput(state, input) {
34997
- if (!isObject(input)) {
34998
- return;
34999
- }
35000
- const session = input["session"];
35001
- const turn = input["turn"];
35002
- const step = input["step"];
35003
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
35004
- return;
35005
- }
35006
- const sessionId = session["id"];
35007
- const turnId = turn["id"];
35008
- const stepIndex = step["index"];
35009
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
35010
- return;
35443
+ function storeEveReasoning(state, sessionId, event) {
35444
+ const eventAt = event.meta?.at;
35445
+ const key = llmInputKey(sessionId, event.data.turnId, event.data.stepIndex);
35446
+ let stored = [];
35447
+ state.update((current) => {
35448
+ const normalized = normalizeEveTraceState(current);
35449
+ const alreadyStored = normalized.reasoningBlocks.some(
35450
+ (entry) => entry.content === event.data.reasoning && entry.eventAt === eventAt && entry.key === key
35451
+ );
35452
+ const reasoningBlocks = alreadyStored ? normalized.reasoningBlocks : [
35453
+ ...normalized.reasoningBlocks,
35454
+ {
35455
+ content: event.data.reasoning,
35456
+ ...eventAt ? { eventAt } : {},
35457
+ key
35458
+ }
35459
+ ].slice(-MAX_STORED_REASONING_BLOCKS);
35460
+ stored = reasoningBlocks.flatMap(
35461
+ (entry) => entry.key === key ? [
35462
+ {
35463
+ content: entry.content,
35464
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35465
+ }
35466
+ ] : []
35467
+ );
35468
+ return alreadyStored ? normalized : { ...normalized, reasoningBlocks };
35469
+ });
35470
+ return stored;
35471
+ }
35472
+ function readStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35473
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35474
+ return readEveTraceState(state).reasoningBlocks.flatMap(
35475
+ (entry) => entry.key === key ? [
35476
+ {
35477
+ content: entry.content,
35478
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
35479
+ }
35480
+ ] : []
35481
+ );
35482
+ }
35483
+ function clearStoredEveReasoning(state, sessionId, turnId, stepIndex) {
35484
+ const key = llmInputKey(sessionId, turnId, stepIndex);
35485
+ state.update((current) => {
35486
+ const normalized = normalizeEveTraceState(current);
35487
+ return {
35488
+ ...normalized,
35489
+ reasoningBlocks: normalized.reasoningBlocks.filter(
35490
+ (entry) => entry.key !== key
35491
+ )
35492
+ };
35493
+ });
35494
+ }
35495
+ function eveOutputMessage(output) {
35496
+ return Array.isArray(output) && isObject(output[0]) ? output[0]["message"] : void 0;
35497
+ }
35498
+ function mergeEveReasoning(output, reasoning) {
35499
+ if (reasoning.length === 0) {
35500
+ return output;
35011
35501
  }
35012
- const captured = capturedModelInput(input["modelInput"]);
35502
+ const choice = Array.isArray(output) && isObject(output[0]) ? output[0] : {};
35503
+ const message = isObject(choice["message"]) ? choice["message"] : {};
35504
+ return [
35505
+ {
35506
+ ...choice,
35507
+ index: typeof choice["index"] === "number" ? choice["index"] : 0,
35508
+ message: {
35509
+ ...message,
35510
+ content: "content" in message ? message["content"] : null,
35511
+ reasoning: reasoning.map((block) => ({ content: block.content })),
35512
+ role: typeof message["role"] === "string" ? message["role"] : "assistant"
35513
+ }
35514
+ }
35515
+ ];
35516
+ }
35517
+ function captureEveModelInput(state, input) {
35518
+ const sessionId = input.session.id;
35519
+ const turnId = input.turn.id;
35520
+ const stepIndex = input.step.index;
35521
+ const captured = capturedModelInput(input.modelInput);
35013
35522
  if (!captured) {
35014
35523
  return;
35015
35524
  }
@@ -35050,18 +35559,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
35050
35559
  }
35051
35560
  }
35052
35561
  function capturedModelInput(modelInput) {
35053
- if (!isObject(modelInput)) {
35054
- return void 0;
35055
- }
35056
- const messages = modelInput["messages"];
35057
- if (!Array.isArray(messages)) {
35058
- return void 0;
35059
- }
35060
- const instructions = modelInput["instructions"];
35061
- const value = [
35062
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
35063
- ...messages
35064
- ];
35562
+ const { instructions, messages } = modelInput;
35563
+ const value = [];
35564
+ if (typeof instructions === "string") {
35565
+ value.push({ content: instructions, role: "system" });
35566
+ } else if (instructions) {
35567
+ value.push(...instructions.map(capturedEveModelMessage));
35568
+ }
35569
+ value.push(...messages.map(capturedEveModelMessage));
35065
35570
  try {
35066
35571
  const cloned = JSON.parse(JSON.stringify(value));
35067
35572
  if (!Array.isArray(cloned)) {
@@ -35072,8 +35577,123 @@ function capturedModelInput(modelInput) {
35072
35577
  return void 0;
35073
35578
  }
35074
35579
  }
35580
+ function capturedEveModelMessage(message) {
35581
+ const { content, role } = message;
35582
+ if (typeof content === "string") {
35583
+ return { content, role };
35584
+ }
35585
+ return { content: content.map(capturedEveModelContentPart), role };
35586
+ }
35587
+ function capturedEveModelContentPart(part) {
35588
+ switch (part.type) {
35589
+ case "text":
35590
+ case "reasoning":
35591
+ return { text: part.text, type: part.type };
35592
+ case "image":
35593
+ return {
35594
+ image: part.image,
35595
+ ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35596
+ type: "image"
35597
+ };
35598
+ case "file":
35599
+ case "reasoning-file":
35600
+ return {
35601
+ data: part.data,
35602
+ ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
35603
+ mediaType: part.mediaType,
35604
+ type: part.type
35605
+ };
35606
+ case "custom":
35607
+ return {
35608
+ ..."kind" in part ? { kind: part.kind } : {},
35609
+ type: "custom"
35610
+ };
35611
+ case "tool-call":
35612
+ return {
35613
+ input: part.input,
35614
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35615
+ toolCallId: part.toolCallId,
35616
+ toolName: part.toolName,
35617
+ type: "tool-call"
35618
+ };
35619
+ case "tool-result": {
35620
+ const output = part.output;
35621
+ let capturedOutput;
35622
+ switch (output.type) {
35623
+ case "text":
35624
+ case "error-text":
35625
+ capturedOutput = { type: output.type, value: output.value };
35626
+ break;
35627
+ case "json":
35628
+ case "error-json":
35629
+ capturedOutput = { type: output.type, value: output.value };
35630
+ break;
35631
+ case "execution-denied":
35632
+ capturedOutput = {
35633
+ ...output.reason !== void 0 ? { reason: output.reason } : {},
35634
+ type: "execution-denied"
35635
+ };
35636
+ break;
35637
+ case "content":
35638
+ capturedOutput = {
35639
+ type: "content",
35640
+ value: output.value.map(capturedEveModelContentPart)
35641
+ };
35642
+ break;
35643
+ }
35644
+ return {
35645
+ output: capturedOutput,
35646
+ toolCallId: part.toolCallId,
35647
+ toolName: part.toolName,
35648
+ type: "tool-result"
35649
+ };
35650
+ }
35651
+ case "tool-approval-request":
35652
+ return {
35653
+ approvalId: part.approvalId,
35654
+ ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
35655
+ ...part.signature !== void 0 ? { signature: part.signature } : {},
35656
+ toolCallId: part.toolCallId,
35657
+ type: "tool-approval-request"
35658
+ };
35659
+ case "tool-approval-response":
35660
+ return {
35661
+ approvalId: part.approvalId,
35662
+ approved: part.approved,
35663
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
35664
+ ...part.reason !== void 0 ? { reason: part.reason } : {},
35665
+ type: "tool-approval-response"
35666
+ };
35667
+ case "file-data":
35668
+ case "image-data":
35669
+ return {
35670
+ data: part.data,
35671
+ ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
35672
+ mediaType: part.mediaType,
35673
+ type: part.type
35674
+ };
35675
+ case "file-url":
35676
+ case "image-url":
35677
+ return {
35678
+ ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
35679
+ type: part.type,
35680
+ url: part.url
35681
+ };
35682
+ case "file-id":
35683
+ case "image-file-id":
35684
+ return { fileId: part.fileId, type: part.type };
35685
+ case "file-reference":
35686
+ case "image-file-reference":
35687
+ return {
35688
+ providerReference: part.providerReference,
35689
+ type: part.type
35690
+ };
35691
+ }
35692
+ }
35075
35693
  function isCapturedModelInput(input) {
35076
- return Array.isArray(input);
35694
+ return Array.isArray(input) && input.every(
35695
+ (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))
35696
+ );
35077
35697
  }
35078
35698
  function llmInputKey(sessionId, turnId, stepIndex) {
35079
35699
  return `${sessionId}\0${turnId}\0${stepIndex}`;
@@ -38468,6 +39088,8 @@ var BaseNode = class {
38468
39088
  this.graph = graph;
38469
39089
  this.id = id;
38470
39090
  }
39091
+ graph;
39092
+ id;
38471
39093
  __type = "node";
38472
39094
  dependencies = [];
38473
39095
  addDependency(dependency) {
@@ -38501,6 +39123,7 @@ var PromptNode = class extends BaseNode {
38501
39123
  super(graph, id);
38502
39124
  this.prompt = prompt;
38503
39125
  }
39126
+ prompt;
38504
39127
  async build(context) {
38505
39128
  return {
38506
39129
  type: "function",
@@ -38513,6 +39136,7 @@ var GateNode = class extends BaseNode {
38513
39136
  super(graph, id);
38514
39137
  this.condition = condition;
38515
39138
  }
39139
+ condition;
38516
39140
  async build(context) {
38517
39141
  return {
38518
39142
  type: "gate",
@@ -38537,6 +39161,7 @@ var PromptTemplateNode = class extends BaseNode {
38537
39161
  super(graph, id);
38538
39162
  this.prompt = prompt;
38539
39163
  }
39164
+ prompt;
38540
39165
  async build(context) {
38541
39166
  return {
38542
39167
  type: "prompt_template",
@@ -38549,6 +39174,7 @@ var LiteralNode = class extends BaseNode {
38549
39174
  super(graph, id);
38550
39175
  this.value = value;
38551
39176
  }
39177
+ value;
38552
39178
  async build(context) {
38553
39179
  return {
38554
39180
  type: "literal",
@@ -39642,6 +40268,10 @@ var SpanFetcher = class _SpanFetcher extends ObjectFetcher {
39642
40268
  this._state = _state;
39643
40269
  this.spanTypeFilter = spanTypeFilter;
39644
40270
  }
40271
+ _objectId;
40272
+ rootSpanId;
40273
+ _state;
40274
+ spanTypeFilter;
39645
40275
  static buildFilter(rootSpanId, spanTypeFilter, includeScorers = false) {
39646
40276
  const children = [
39647
40277
  // Base filter: root_span_id = 'value'
@@ -40092,6 +40722,8 @@ var EvalResultWithSummary = class {
40092
40722
  this.summary = summary;
40093
40723
  this.results = results;
40094
40724
  }
40725
+ summary;
40726
+ results;
40095
40727
  /**
40096
40728
  * @deprecated Use `summary` instead.
40097
40729
  */
@@ -41510,6 +42142,7 @@ var ToolBuilder = class {
41510
42142
  constructor(project) {
41511
42143
  this.project = project;
41512
42144
  }
42145
+ project;
41513
42146
  taskCounter = 0;
41514
42147
  // This type definition is just a catch all so that the implementation can be
41515
42148
  // less specific than the two more specific declarations above.
@@ -41540,6 +42173,7 @@ var ScorerBuilder = class {
41540
42173
  constructor(project) {
41541
42174
  this.project = project;
41542
42175
  }
42176
+ project;
41543
42177
  taskCounter = 0;
41544
42178
  create(opts) {
41545
42179
  this.taskCounter++;
@@ -41599,6 +42233,7 @@ var ClassifierBuilder = class {
41599
42233
  constructor(project) {
41600
42234
  this.project = project;
41601
42235
  }
42236
+ project;
41602
42237
  taskCounter = 0;
41603
42238
  create(opts) {
41604
42239
  this.taskCounter++;
@@ -41634,6 +42269,7 @@ var CodeFunction = class {
41634
42269
  throw new Error("parameters are required if return type is defined");
41635
42270
  }
41636
42271
  }
42272
+ project;
41637
42273
  handler;
41638
42274
  name;
41639
42275
  slug;
@@ -41721,6 +42357,7 @@ var PromptBuilder = class {
41721
42357
  constructor(project) {
41722
42358
  this.project = project;
41723
42359
  }
42360
+ project;
41724
42361
  create(opts) {
41725
42362
  const toolFunctions = [];
41726
42363
  const rawTools = [];
@@ -41797,6 +42434,7 @@ var ParametersBuilder = class {
41797
42434
  constructor(project) {
41798
42435
  this.project = project;
41799
42436
  }
42437
+ project;
41800
42438
  create(opts) {
41801
42439
  const slug = opts.slug ?? slugify(opts.name, { lower: true, strict: true });
41802
42440
  const codeParameters = new CodeParameters(this.project, {