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
@@ -15,6 +15,7 @@ var DefaultChannel = class {
15
15
  constructor(name) {
16
16
  this.name = name;
17
17
  }
18
+ name;
18
19
  hasSubscribers = false;
19
20
  subscribe(_subscription) {
20
21
  }
@@ -1291,6 +1292,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1291
1292
  constructor(data) {
1292
1293
  this.data = data;
1293
1294
  }
1295
+ data;
1294
1296
  toStr() {
1295
1297
  const jsonObj = {
1296
1298
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1711,6 +1713,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1711
1713
  constructor(data) {
1712
1714
  this.data = data;
1713
1715
  }
1716
+ data;
1714
1717
  toStr() {
1715
1718
  const jsonObj = {
1716
1719
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -4872,6 +4875,97 @@ var SpanCache = class {
4872
4875
  }
4873
4876
  };
4874
4877
 
4878
+ // src/span-origin.ts
4879
+ var SDK_VERSION = true ? "3.24.0" : "0.0.0";
4880
+ function detectSpanOriginEnvironment(explicit) {
4881
+ if (explicit) return explicit;
4882
+ const envType = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_TYPE");
4883
+ const envName = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_NAME");
4884
+ if (envType || envName) {
4885
+ return {
4886
+ ...envType ? { type: envType } : {},
4887
+ ...envName ? { name: envName } : {}
4888
+ };
4889
+ }
4890
+ const ci = firstPresent([
4891
+ ["GITHUB_ACTIONS", "github_actions"],
4892
+ ["GITLAB_CI", "gitlab_ci"],
4893
+ ["CIRCLECI", "circleci"],
4894
+ ["BUILDKITE", "buildkite"],
4895
+ ["JENKINS_URL", "jenkins"],
4896
+ ["JENKINS_HOME", "jenkins"],
4897
+ ["TF_BUILD", "azure_pipelines"],
4898
+ ["TEAMCITY_VERSION", "teamcity"],
4899
+ ["TRAVIS", "travis"],
4900
+ ["BITBUCKET_BUILD_NUMBER", "bitbucket"]
4901
+ ]);
4902
+ if (ci) return { type: "ci", name: ci };
4903
+ if (isomorph_default.getEnv("CI")) return { type: "ci", name: "ci" };
4904
+ const earlyServer = firstPresent([
4905
+ ["VERCEL", "vercel"],
4906
+ ["NETLIFY", "netlify"]
4907
+ ]);
4908
+ if (earlyServer) return { type: "server", name: earlyServer };
4909
+ if (isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI") || isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI_V4")) {
4910
+ return { type: "server", name: "ecs" };
4911
+ }
4912
+ const awsExecutionEnv = isomorph_default.getEnv("AWS_EXECUTION_ENV");
4913
+ if (awsExecutionEnv?.startsWith("AWS_ECS_")) {
4914
+ return { type: "server", name: "ecs" };
4915
+ }
4916
+ if (awsExecutionEnv?.startsWith("AWS_Lambda_")) {
4917
+ return { type: "server", name: "aws_lambda" };
4918
+ }
4919
+ if (isomorph_default.getEnv("AWS_LAMBDA_FUNCTION_NAME")) {
4920
+ return { type: "server", name: "aws_lambda" };
4921
+ }
4922
+ const server = firstPresent([
4923
+ ["K_SERVICE", "cloud_run"],
4924
+ ["FUNCTION_TARGET", "gcp_functions"],
4925
+ ["KUBERNETES_SERVICE_HOST", "kubernetes"],
4926
+ ["DYNO", "heroku"],
4927
+ ["FLY_APP_NAME", "fly"],
4928
+ ["RAILWAY_ENVIRONMENT", "railway"],
4929
+ ["RENDER_SERVICE_NAME", "render"]
4930
+ ]);
4931
+ if (server) return { type: "server", name: server };
4932
+ return deploymentModeEnvironment("NODE_ENV", isomorph_default.getEnv("NODE_ENV"));
4933
+ }
4934
+ function makeSpanOrigin(instrumentationName, environment) {
4935
+ return {
4936
+ name: "braintrust.sdk.javascript",
4937
+ version: SDK_VERSION,
4938
+ instrumentation: { name: instrumentationName },
4939
+ ...environment ? { environment } : {}
4940
+ };
4941
+ }
4942
+ function mergeSpanOriginContext(context, instrumentationName, environment) {
4943
+ const next = { ...context ?? {} };
4944
+ const current = isObject2(next.span_origin) ? { ...next.span_origin } : {};
4945
+ next.span_origin = {
4946
+ ...makeSpanOrigin(instrumentationName, environment),
4947
+ ...current
4948
+ };
4949
+ return next;
4950
+ }
4951
+ function firstPresent(entries) {
4952
+ return entries.find(([key]) => Boolean(isomorph_default.getEnv(key)))?.[1];
4953
+ }
4954
+ function deploymentModeEnvironment(_key, value) {
4955
+ if (!value) return void 0;
4956
+ const normalized = value.toLowerCase();
4957
+ if (normalized === "production" || normalized === "staging") {
4958
+ return { type: "server", name: normalized };
4959
+ }
4960
+ if (normalized === "development" || normalized === "local") {
4961
+ return { type: "local", name: normalized };
4962
+ }
4963
+ return { name: value };
4964
+ }
4965
+ function isObject2(value) {
4966
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4967
+ }
4968
+
4875
4969
  // src/logger.ts
4876
4970
  var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
4877
4971
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
@@ -4920,6 +5014,7 @@ var LoginInvalidOrgError = class extends Error {
4920
5014
  super(message);
4921
5015
  this.message = message;
4922
5016
  }
5017
+ message;
4923
5018
  };
4924
5019
  var REDACTION_FIELDS = [
4925
5020
  "input",
@@ -4935,6 +5030,8 @@ var MaskingError = class {
4935
5030
  this.fieldName = fieldName;
4936
5031
  this.errorType = errorType;
4937
5032
  }
5033
+ fieldName;
5034
+ errorType;
4938
5035
  get errorMsg() {
4939
5036
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
4940
5037
  }
@@ -5144,7 +5241,9 @@ var BraintrustState = class _BraintrustState {
5144
5241
  diskCache: parametersDiskCache
5145
5242
  });
5146
5243
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5244
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5147
5245
  }
5246
+ loginParams;
5148
5247
  id;
5149
5248
  currentExperiment;
5150
5249
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5179,6 +5278,7 @@ var BraintrustState = class _BraintrustState {
5179
5278
  _idGenerator = null;
5180
5279
  _contextManager = null;
5181
5280
  _otelFlushCallback = null;
5281
+ spanOriginEnvironment;
5182
5282
  resetLoginInfo() {
5183
5283
  this.appUrl = null;
5184
5284
  this.appPublicUrl = null;
@@ -7096,6 +7196,7 @@ function initLogger(options = {}) {
7096
7196
  orgName,
7097
7197
  forceLogin,
7098
7198
  debugLogLevel,
7199
+ environment,
7099
7200
  fetch: fetch2,
7100
7201
  state: stateArg
7101
7202
  } = options || {};
@@ -7112,6 +7213,7 @@ function initLogger(options = {}) {
7112
7213
  };
7113
7214
  const state = stateArg ?? _globalState;
7114
7215
  state.setDebugLogLevel(debugLogLevel);
7216
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7115
7217
  state.enforceQueueSizeLimit(true);
7116
7218
  const lazyMetadata = new LazyValue(
7117
7219
  async () => {
@@ -7751,6 +7853,11 @@ var ObjectFetcher = class {
7751
7853
  this._internal_btql = _internal_btql;
7752
7854
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
7753
7855
  }
7856
+ objectType;
7857
+ pinnedVersion;
7858
+ mutateRecord;
7859
+ _internal_btql;
7860
+ _internalBrainstoreRealtime;
7754
7861
  _fetchedData = void 0;
7755
7862
  get id() {
7756
7863
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -8270,7 +8377,11 @@ var SpanImpl = class _SpanImpl {
8270
8377
  metrics: {
8271
8378
  start: args.startTime ?? getCurrentUnixTimestamp()
8272
8379
  },
8273
- context: { ...callerLocation },
8380
+ context: mergeSpanOriginContext(
8381
+ { ...callerLocation },
8382
+ "braintrust-js-logger",
8383
+ this._state.spanOriginEnvironment
8384
+ ),
8274
8385
  span_attributes: {
8275
8386
  name,
8276
8387
  type,
@@ -8644,6 +8755,7 @@ var Dataset2 = class extends ObjectFetcher {
8644
8755
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
8645
8756
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
8646
8757
  }
8758
+ state;
8647
8759
  lazyMetadata;
8648
8760
  __braintrust_dataset_marker = true;
8649
8761
  newRecords = 0;
@@ -13105,6 +13217,24 @@ var aiSDKChannels = defineChannels("ai", {
13105
13217
  kind: "sync-stream"
13106
13218
  })
13107
13219
  });
13220
+ var harnessAgentChannels = defineChannels("@ai-sdk/harness", {
13221
+ generate: channel({
13222
+ channelName: "HarnessAgent.generate",
13223
+ kind: "async"
13224
+ }),
13225
+ stream: channel({
13226
+ channelName: "HarnessAgent.stream",
13227
+ kind: "async"
13228
+ }),
13229
+ continueGenerate: channel({
13230
+ channelName: "HarnessAgent.continueGenerate",
13231
+ kind: "async"
13232
+ }),
13233
+ continueStream: channel({
13234
+ channelName: "HarnessAgent.continueStream",
13235
+ kind: "async"
13236
+ })
13237
+ });
13108
13238
 
13109
13239
  // src/instrumentation/plugins/ai-sdk-plugin.ts
13110
13240
  var DEFAULT_DENY_OUTPUT_PATHS = [
@@ -13373,6 +13503,84 @@ var AISDKPlugin = class extends BasePlugin {
13373
13503
  })
13374
13504
  })
13375
13505
  );
13506
+ this.unsubscribers.push(
13507
+ traceStreamingChannel(harnessAgentChannels.generate, {
13508
+ name: "HarnessAgent.generate",
13509
+ type: "task" /* TASK */,
13510
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13511
+ extractOutput: (result, endEvent) => processAISDKOutput(
13512
+ result,
13513
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13514
+ ),
13515
+ extractMetrics: (result) => extractTokenMetrics(result),
13516
+ aggregateChunks: aggregateAISDKChunks
13517
+ })
13518
+ );
13519
+ this.unsubscribers.push(
13520
+ traceStreamingChannel(harnessAgentChannels.stream, {
13521
+ name: "HarnessAgent.stream",
13522
+ type: "task" /* TASK */,
13523
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13524
+ extractOutput: (result, endEvent) => processAISDKOutput(
13525
+ result,
13526
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13527
+ ),
13528
+ extractMetrics: (result, startTime) => ({
13529
+ ...extractTokenMetrics(result),
13530
+ ...startTime === void 0 ? {} : {
13531
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
13532
+ }
13533
+ }),
13534
+ aggregateChunks: aggregateAISDKChunks,
13535
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13536
+ defaultDenyOutputPaths: denyOutputPaths,
13537
+ endEvent,
13538
+ result,
13539
+ resolvePromiseUsage: true,
13540
+ span,
13541
+ startTime
13542
+ })
13543
+ })
13544
+ );
13545
+ this.unsubscribers.push(
13546
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
13547
+ name: "HarnessAgent.continueGenerate",
13548
+ type: "task" /* TASK */,
13549
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13550
+ extractOutput: (result, endEvent) => processAISDKOutput(
13551
+ result,
13552
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13553
+ ),
13554
+ extractMetrics: (result) => extractTokenMetrics(result),
13555
+ aggregateChunks: aggregateAISDKChunks
13556
+ })
13557
+ );
13558
+ this.unsubscribers.push(
13559
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
13560
+ name: "HarnessAgent.continueStream",
13561
+ type: "task" /* TASK */,
13562
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13563
+ extractOutput: (result, endEvent) => processAISDKOutput(
13564
+ result,
13565
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13566
+ ),
13567
+ extractMetrics: (result, startTime) => ({
13568
+ ...extractTokenMetrics(result),
13569
+ ...startTime === void 0 ? {} : {
13570
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
13571
+ }
13572
+ }),
13573
+ aggregateChunks: aggregateAISDKChunks,
13574
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13575
+ defaultDenyOutputPaths: denyOutputPaths,
13576
+ endEvent,
13577
+ result,
13578
+ resolvePromiseUsage: true,
13579
+ span,
13580
+ startTime
13581
+ })
13582
+ })
13583
+ );
13376
13584
  this.unsubscribers.push(
13377
13585
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
13378
13586
  name: "ToolLoopAgent.generate",
@@ -13903,6 +14111,45 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
13903
14111
  metadata
13904
14112
  };
13905
14113
  }
14114
+ function prepareAISDKHarnessAgentInput(params, self) {
14115
+ if (isObject(self)) {
14116
+ try {
14117
+ if (isObject(self.settings)) {
14118
+ const settings = self.settings;
14119
+ if (settings.telemetry === void 0) {
14120
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
14121
+ }
14122
+ }
14123
+ } catch {
14124
+ }
14125
+ }
14126
+ const selectedInput = {};
14127
+ if (params.prompt !== void 0) {
14128
+ selectedInput.prompt = params.prompt;
14129
+ }
14130
+ if (params.messages !== void 0) {
14131
+ selectedInput.messages = params.messages;
14132
+ }
14133
+ if (params.toolApprovalContinuations !== void 0) {
14134
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
14135
+ }
14136
+ const metadata = extractMetadataFromCallParams({}, self);
14137
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
14138
+ metadata.sessionId = params.session.sessionId;
14139
+ }
14140
+ if (isObject(self)) {
14141
+ if (typeof self.harnessId === "string") {
14142
+ metadata.harnessId = self.harnessId;
14143
+ }
14144
+ if (typeof self.permissionMode === "string") {
14145
+ metadata.permissionMode = self.permissionMode;
14146
+ }
14147
+ }
14148
+ return {
14149
+ input: processAISDKCallInput(selectedInput).input,
14150
+ metadata
14151
+ };
14152
+ }
13906
14153
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
13907
14154
  registerWorkflowAgentWrapperSpan(span);
13908
14155
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -14750,6 +14997,7 @@ function patchAISDKStreamingResult(args) {
14750
14997
  endEvent,
14751
14998
  onComplete,
14752
14999
  result,
15000
+ resolvePromiseUsage,
14753
15001
  span,
14754
15002
  startTime
14755
15003
  } = args;
@@ -14776,6 +15024,22 @@ function patchAISDKStreamingResult(args) {
14776
15024
  outputLogged = true;
14777
15025
  try {
14778
15026
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
15027
+ if (resolvePromiseUsage) {
15028
+ try {
15029
+ const resultRecord2 = result;
15030
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
15031
+ if (isPromiseLike(pendingUsage)) {
15032
+ const usage = await Promise.resolve(pendingUsage);
15033
+ if (isObject(usage)) {
15034
+ Object.assign(
15035
+ metrics,
15036
+ extractTokenMetrics({ usage })
15037
+ );
15038
+ }
15039
+ }
15040
+ } catch {
15041
+ }
15042
+ }
14779
15043
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
14780
15044
  metrics.time_to_first_token = firstChunkTime - startTime;
14781
15045
  }
@@ -27033,6 +27297,16 @@ function cleanObject(obj) {
27033
27297
  })
27034
27298
  );
27035
27299
  }
27300
+ function normalizeTokenMetrics(obj) {
27301
+ const metrics = cleanObject(obj);
27302
+ if (metrics.total_tokens !== void 0) {
27303
+ metrics.tokens = metrics.total_tokens;
27304
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
27305
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
27306
+ }
27307
+ delete metrics.total_tokens;
27308
+ return metrics;
27309
+ }
27036
27310
  function walkGenerations(response) {
27037
27311
  const result = [];
27038
27312
  const generations = response.generations || [];
@@ -27079,7 +27353,7 @@ function getMetricsFromResponse(response) {
27079
27353
  continue;
27080
27354
  }
27081
27355
  const inputTokenDetails = usageMetadata.input_token_details;
27082
- return cleanObject({
27356
+ return normalizeTokenMetrics({
27083
27357
  total_tokens: usageMetadata.total_tokens,
27084
27358
  prompt_tokens: usageMetadata.input_tokens,
27085
27359
  completion_tokens: usageMetadata.output_tokens,
@@ -27089,7 +27363,7 @@ function getMetricsFromResponse(response) {
27089
27363
  }
27090
27364
  const llmOutput = response.llmOutput || {};
27091
27365
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
27092
- return cleanObject({
27366
+ return normalizeTokenMetrics({
27093
27367
  total_tokens: tokenUsage.totalTokens,
27094
27368
  prompt_tokens: tokenUsage.promptTokens,
27095
27369
  completion_tokens: tokenUsage.completionTokens
@@ -29709,6 +29983,7 @@ var BraintrustPlugin = class extends BasePlugin {
29709
29983
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
29710
29984
  var MAX_EVE_CACHE_ENTRIES = 1e4;
29711
29985
  var MAX_STORED_LLM_INPUTS = 100;
29986
+ var MAX_STORED_REASONING_BLOCKS = 100;
29712
29987
  var MAX_STORED_SPAN_REFERENCES = 1e4;
29713
29988
  var MAX_STORED_STEP_STARTS = 1e4;
29714
29989
  function braintrustEveHook(options) {
@@ -29747,6 +30022,7 @@ var ResumedEveSpan = class {
29747
30022
  this.reference = reference;
29748
30023
  this.endTime = reference.endTime;
29749
30024
  }
30025
+ reference;
29750
30026
  endTime;
29751
30027
  get rootSpanId() {
29752
30028
  return this.reference.rootSpanId;
@@ -29779,6 +30055,7 @@ var EveBridge = class {
29779
30055
  constructor(state) {
29780
30056
  this.state = state;
29781
30057
  }
30058
+ state;
29782
30059
  eventQueuesBySession = /* @__PURE__ */ new Map();
29783
30060
  completedToolKeys = new LRUCache({
29784
30061
  max: MAX_EVE_CACHE_ENTRIES
@@ -29957,6 +30234,9 @@ var EveBridge = class {
29957
30234
  case "step.started":
29958
30235
  await this.handleStepStarted(event, ctx, hookMetadata);
29959
30236
  return true;
30237
+ case "reasoning.completed":
30238
+ this.handleReasoningCompleted(event, ctx);
30239
+ return true;
29960
30240
  case "message.completed":
29961
30241
  this.handleMessageCompleted(event, ctx);
29962
30242
  return true;
@@ -30048,6 +30328,7 @@ var EveBridge = class {
30048
30328
  key,
30049
30329
  metadata,
30050
30330
  metrics: {},
30331
+ sessionId,
30051
30332
  span,
30052
30333
  stepsByIndex: /* @__PURE__ */ new Map(),
30053
30334
  turnId: event.data.turnId
@@ -30078,6 +30359,12 @@ var EveBridge = class {
30078
30359
  const endTime = eventTime2(event);
30079
30360
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
30080
30361
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
30362
+ clearStoredEveReasoning(
30363
+ this.state,
30364
+ sessionId,
30365
+ event.data.turnId,
30366
+ event.data.stepIndex
30367
+ );
30081
30368
  }
30082
30369
  const stepOrdinal = this.stepOrdinal(event);
30083
30370
  const metadata = { ...turn.metadata };
@@ -30087,6 +30374,13 @@ var EveBridge = class {
30087
30374
  event.data.turnId,
30088
30375
  event.data.stepIndex
30089
30376
  );
30377
+ const reasoning = readStoredEveReasoning(
30378
+ this.state,
30379
+ sessionId,
30380
+ event.data.turnId,
30381
+ event.data.stepIndex
30382
+ );
30383
+ const output = mergeEveReasoning(void 0, reasoning);
30090
30384
  const { rowId: eventId, spanId } = await generateEveIds(
30091
30385
  "step",
30092
30386
  sessionId,
@@ -30104,32 +30398,52 @@ var EveBridge = class {
30104
30398
  spanId,
30105
30399
  startTime: eventTime2(event)
30106
30400
  });
30107
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
30401
+ span.log({
30402
+ ...input !== void 0 ? { input } : {},
30403
+ metadata
30404
+ });
30108
30405
  turn.stepsByIndex.set(event.data.stepIndex, {
30109
30406
  ...input !== void 0 ? { input } : {},
30110
30407
  metadata,
30111
30408
  metrics: {},
30409
+ ...output !== void 0 ? { output } : {},
30410
+ reasoning,
30112
30411
  span
30113
30412
  });
30114
30413
  }
30414
+ handleReasoningCompleted(event, ctx) {
30415
+ const sessionId = sessionIdFromContext(ctx);
30416
+ if (!sessionId) {
30417
+ return;
30418
+ }
30419
+ const reasoning = storeEveReasoning(this.state, sessionId, event);
30420
+ const step = this.stepForEvent(event, ctx);
30421
+ if (step) {
30422
+ step.reasoning = reasoning;
30423
+ step.output = mergeEveReasoning(step.output, reasoning);
30424
+ }
30425
+ }
30115
30426
  handleMessageCompleted(event, ctx) {
30116
30427
  const step = this.stepForEvent(event, ctx);
30117
30428
  if (!step) {
30118
30429
  return;
30119
30430
  }
30120
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
30431
+ const existingMessage = eveOutputMessage(step.output);
30121
30432
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
30122
- step.output = [
30123
- {
30124
- finish_reason: normalizedFinishReason(event.data.finishReason),
30125
- index: 0,
30126
- message: {
30127
- content: event.data.message,
30128
- role: "assistant",
30129
- ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
30433
+ step.output = mergeEveReasoning(
30434
+ [
30435
+ {
30436
+ finish_reason: normalizedFinishReason(event.data.finishReason),
30437
+ index: 0,
30438
+ message: {
30439
+ content: event.data.message,
30440
+ role: "assistant",
30441
+ ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
30442
+ }
30130
30443
  }
30131
- }
30132
- ];
30444
+ ],
30445
+ step.reasoning
30446
+ );
30133
30447
  const turn = this.turnForEvent(event, ctx);
30134
30448
  if (turn && event.data.finishReason !== "tool-calls") {
30135
30449
  turn.output = event.data.message;
@@ -30138,16 +30452,19 @@ var EveBridge = class {
30138
30452
  handleResultCompleted(event, ctx) {
30139
30453
  const step = this.stepForEvent(event, ctx);
30140
30454
  if (step) {
30141
- step.output = [
30142
- {
30143
- finish_reason: "stop",
30144
- index: 0,
30145
- message: {
30146
- content: event.data.result,
30147
- role: "assistant"
30455
+ step.output = mergeEveReasoning(
30456
+ [
30457
+ {
30458
+ finish_reason: "stop",
30459
+ index: 0,
30460
+ message: {
30461
+ content: event.data.result,
30462
+ role: "assistant"
30463
+ }
30148
30464
  }
30149
- }
30150
- ];
30465
+ ],
30466
+ step.reasoning
30467
+ );
30151
30468
  }
30152
30469
  const turn = this.turnForEvent(event, ctx);
30153
30470
  if (turn) {
@@ -30197,18 +30514,20 @@ var EveBridge = class {
30197
30514
  type: "function"
30198
30515
  });
30199
30516
  }
30200
- step.output = [
30201
- {
30202
- finish_reason: "tool_calls",
30203
- index: 0,
30204
- message: {
30205
- content: null,
30206
- role: "assistant",
30207
- tool_calls: [...toolCallsById.values()]
30517
+ step.output = mergeEveReasoning(
30518
+ [
30519
+ {
30520
+ finish_reason: "tool_calls",
30521
+ index: 0,
30522
+ message: {
30523
+ content: null,
30524
+ role: "assistant",
30525
+ tool_calls: [...toolCallsById.values()]
30526
+ }
30208
30527
  }
30209
- }
30210
- ];
30211
- step.span.log({ metadata: step.metadata, output: step.output });
30528
+ ],
30529
+ step.reasoning
30530
+ );
30212
30531
  }
30213
30532
  async handleActionResult(event, ctx, hookMetadata) {
30214
30533
  if (isToolResult(event.data.result)) {
@@ -30386,6 +30705,7 @@ var EveBridge = class {
30386
30705
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
30387
30706
  };
30388
30707
  step.metrics = { ...step.metrics, ...metrics };
30708
+ const sessionId = sessionIdFromContext(ctx);
30389
30709
  if (Array.isArray(step.output) && isObject(step.output[0])) {
30390
30710
  const finishReason = step.output[0].finish_reason;
30391
30711
  if (typeof finishReason !== "string") {
@@ -30410,6 +30730,14 @@ var EveBridge = class {
30410
30730
  turn.stepsByIndex.delete(event.data.stepIndex);
30411
30731
  }
30412
30732
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
30733
+ if (sessionId) {
30734
+ clearStoredEveReasoning(
30735
+ this.state,
30736
+ sessionId,
30737
+ event.data.turnId,
30738
+ event.data.stepIndex
30739
+ );
30740
+ }
30413
30741
  }
30414
30742
  handleStepFailed(event, ctx) {
30415
30743
  const step = this.stepForEvent(event, ctx);
@@ -30427,6 +30755,15 @@ var EveBridge = class {
30427
30755
  const turn = this.turnForEvent(event, ctx);
30428
30756
  turn?.stepsByIndex.delete(event.data.stepIndex);
30429
30757
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
30758
+ const sessionId = sessionIdFromContext(ctx);
30759
+ if (sessionId) {
30760
+ clearStoredEveReasoning(
30761
+ this.state,
30762
+ sessionId,
30763
+ event.data.turnId,
30764
+ event.data.stepIndex
30765
+ );
30766
+ }
30430
30767
  }
30431
30768
  handleTurnCompleted(event, ctx) {
30432
30769
  const turn = this.turnForEvent(event, ctx);
@@ -30524,6 +30861,7 @@ var EveBridge = class {
30524
30861
  key,
30525
30862
  metadata,
30526
30863
  metrics: {},
30864
+ sessionId,
30527
30865
  span,
30528
30866
  stepsByIndex: /* @__PURE__ */ new Map(),
30529
30867
  turnId: event.data.turnId
@@ -30786,6 +31124,9 @@ var EveBridge = class {
30786
31124
  const normalized = normalizeEveTraceState(current);
30787
31125
  return {
30788
31126
  ...normalized,
31127
+ reasoningBlocks: normalized.reasoningBlocks.filter(
31128
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
31129
+ ),
30789
31130
  stepStarts: normalized.stepStarts.filter(
30790
31131
  (entry) => entry.turnId !== turn.turnId
30791
31132
  )
@@ -30825,6 +31166,7 @@ function emptyEveTraceState() {
30825
31166
  return {
30826
31167
  llmInputs: [],
30827
31168
  metadata: {},
31169
+ reasoningBlocks: [],
30828
31170
  spanReferences: [],
30829
31171
  stepStarts: []
30830
31172
  };
@@ -30875,6 +31217,21 @@ function normalizeEveTraceState(state) {
30875
31217
  const input = entry["input"];
30876
31218
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
30877
31219
  }).slice(-MAX_STORED_LLM_INPUTS) : [];
31220
+ const reasoningBlocks = Array.isArray(state["reasoningBlocks"]) ? state["reasoningBlocks"].flatMap((entry) => {
31221
+ if (!isObject(entry)) {
31222
+ return [];
31223
+ }
31224
+ const content = entry["content"];
31225
+ const eventAt = entry["eventAt"];
31226
+ const key = entry["key"];
31227
+ return typeof content === "string" && (eventAt === void 0 || typeof eventAt === "string") && typeof key === "string" ? [
31228
+ {
31229
+ content,
31230
+ ...typeof eventAt === "string" ? { eventAt } : {},
31231
+ key
31232
+ }
31233
+ ] : [];
31234
+ }).slice(-MAX_STORED_REASONING_BLOCKS) : [];
30878
31235
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
30879
31236
  if (!isObject(entry)) {
30880
31237
  return [];
@@ -30885,7 +31242,13 @@ function normalizeEveTraceState(state) {
30885
31242
  const turnId = entry["turnId"];
30886
31243
  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 }] : [];
30887
31244
  }).slice(-MAX_STORED_STEP_STARTS) : [];
30888
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
31245
+ return {
31246
+ llmInputs,
31247
+ metadata: { ...metadata },
31248
+ reasoningBlocks,
31249
+ spanReferences,
31250
+ stepStarts
31251
+ };
30889
31252
  }
30890
31253
  function readEveTraceState(state) {
30891
31254
  try {
@@ -30894,23 +31257,85 @@ function readEveTraceState(state) {
30894
31257
  return emptyEveTraceState();
30895
31258
  }
30896
31259
  }
30897
- function captureEveModelInput(state, input) {
30898
- if (!isObject(input)) {
30899
- return;
30900
- }
30901
- const session = input["session"];
30902
- const turn = input["turn"];
30903
- const step = input["step"];
30904
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
30905
- return;
30906
- }
30907
- const sessionId = session["id"];
30908
- const turnId = turn["id"];
30909
- const stepIndex = step["index"];
30910
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
30911
- return;
31260
+ function storeEveReasoning(state, sessionId, event) {
31261
+ const eventAt = event.meta?.at;
31262
+ const key = llmInputKey(sessionId, event.data.turnId, event.data.stepIndex);
31263
+ let stored = [];
31264
+ state.update((current) => {
31265
+ const normalized = normalizeEveTraceState(current);
31266
+ const alreadyStored = normalized.reasoningBlocks.some(
31267
+ (entry) => entry.content === event.data.reasoning && entry.eventAt === eventAt && entry.key === key
31268
+ );
31269
+ const reasoningBlocks = alreadyStored ? normalized.reasoningBlocks : [
31270
+ ...normalized.reasoningBlocks,
31271
+ {
31272
+ content: event.data.reasoning,
31273
+ ...eventAt ? { eventAt } : {},
31274
+ key
31275
+ }
31276
+ ].slice(-MAX_STORED_REASONING_BLOCKS);
31277
+ stored = reasoningBlocks.flatMap(
31278
+ (entry) => entry.key === key ? [
31279
+ {
31280
+ content: entry.content,
31281
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
31282
+ }
31283
+ ] : []
31284
+ );
31285
+ return alreadyStored ? normalized : { ...normalized, reasoningBlocks };
31286
+ });
31287
+ return stored;
31288
+ }
31289
+ function readStoredEveReasoning(state, sessionId, turnId, stepIndex) {
31290
+ const key = llmInputKey(sessionId, turnId, stepIndex);
31291
+ return readEveTraceState(state).reasoningBlocks.flatMap(
31292
+ (entry) => entry.key === key ? [
31293
+ {
31294
+ content: entry.content,
31295
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
31296
+ }
31297
+ ] : []
31298
+ );
31299
+ }
31300
+ function clearStoredEveReasoning(state, sessionId, turnId, stepIndex) {
31301
+ const key = llmInputKey(sessionId, turnId, stepIndex);
31302
+ state.update((current) => {
31303
+ const normalized = normalizeEveTraceState(current);
31304
+ return {
31305
+ ...normalized,
31306
+ reasoningBlocks: normalized.reasoningBlocks.filter(
31307
+ (entry) => entry.key !== key
31308
+ )
31309
+ };
31310
+ });
31311
+ }
31312
+ function eveOutputMessage(output) {
31313
+ return Array.isArray(output) && isObject(output[0]) ? output[0]["message"] : void 0;
31314
+ }
31315
+ function mergeEveReasoning(output, reasoning) {
31316
+ if (reasoning.length === 0) {
31317
+ return output;
30912
31318
  }
30913
- const captured = capturedModelInput(input["modelInput"]);
31319
+ const choice = Array.isArray(output) && isObject(output[0]) ? output[0] : {};
31320
+ const message = isObject(choice["message"]) ? choice["message"] : {};
31321
+ return [
31322
+ {
31323
+ ...choice,
31324
+ index: typeof choice["index"] === "number" ? choice["index"] : 0,
31325
+ message: {
31326
+ ...message,
31327
+ content: "content" in message ? message["content"] : null,
31328
+ reasoning: reasoning.map((block) => ({ content: block.content })),
31329
+ role: typeof message["role"] === "string" ? message["role"] : "assistant"
31330
+ }
31331
+ }
31332
+ ];
31333
+ }
31334
+ function captureEveModelInput(state, input) {
31335
+ const sessionId = input.session.id;
31336
+ const turnId = input.turn.id;
31337
+ const stepIndex = input.step.index;
31338
+ const captured = capturedModelInput(input.modelInput);
30914
31339
  if (!captured) {
30915
31340
  return;
30916
31341
  }
@@ -30951,18 +31376,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
30951
31376
  }
30952
31377
  }
30953
31378
  function capturedModelInput(modelInput) {
30954
- if (!isObject(modelInput)) {
30955
- return void 0;
30956
- }
30957
- const messages = modelInput["messages"];
30958
- if (!Array.isArray(messages)) {
30959
- return void 0;
30960
- }
30961
- const instructions = modelInput["instructions"];
30962
- const value = [
30963
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
30964
- ...messages
30965
- ];
31379
+ const { instructions, messages } = modelInput;
31380
+ const value = [];
31381
+ if (typeof instructions === "string") {
31382
+ value.push({ content: instructions, role: "system" });
31383
+ } else if (instructions) {
31384
+ value.push(...instructions.map(capturedEveModelMessage));
31385
+ }
31386
+ value.push(...messages.map(capturedEveModelMessage));
30966
31387
  try {
30967
31388
  const cloned = JSON.parse(JSON.stringify(value));
30968
31389
  if (!Array.isArray(cloned)) {
@@ -30973,8 +31394,123 @@ function capturedModelInput(modelInput) {
30973
31394
  return void 0;
30974
31395
  }
30975
31396
  }
31397
+ function capturedEveModelMessage(message) {
31398
+ const { content, role } = message;
31399
+ if (typeof content === "string") {
31400
+ return { content, role };
31401
+ }
31402
+ return { content: content.map(capturedEveModelContentPart), role };
31403
+ }
31404
+ function capturedEveModelContentPart(part) {
31405
+ switch (part.type) {
31406
+ case "text":
31407
+ case "reasoning":
31408
+ return { text: part.text, type: part.type };
31409
+ case "image":
31410
+ return {
31411
+ image: part.image,
31412
+ ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
31413
+ type: "image"
31414
+ };
31415
+ case "file":
31416
+ case "reasoning-file":
31417
+ return {
31418
+ data: part.data,
31419
+ ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
31420
+ mediaType: part.mediaType,
31421
+ type: part.type
31422
+ };
31423
+ case "custom":
31424
+ return {
31425
+ ..."kind" in part ? { kind: part.kind } : {},
31426
+ type: "custom"
31427
+ };
31428
+ case "tool-call":
31429
+ return {
31430
+ input: part.input,
31431
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
31432
+ toolCallId: part.toolCallId,
31433
+ toolName: part.toolName,
31434
+ type: "tool-call"
31435
+ };
31436
+ case "tool-result": {
31437
+ const output = part.output;
31438
+ let capturedOutput;
31439
+ switch (output.type) {
31440
+ case "text":
31441
+ case "error-text":
31442
+ capturedOutput = { type: output.type, value: output.value };
31443
+ break;
31444
+ case "json":
31445
+ case "error-json":
31446
+ capturedOutput = { type: output.type, value: output.value };
31447
+ break;
31448
+ case "execution-denied":
31449
+ capturedOutput = {
31450
+ ...output.reason !== void 0 ? { reason: output.reason } : {},
31451
+ type: "execution-denied"
31452
+ };
31453
+ break;
31454
+ case "content":
31455
+ capturedOutput = {
31456
+ type: "content",
31457
+ value: output.value.map(capturedEveModelContentPart)
31458
+ };
31459
+ break;
31460
+ }
31461
+ return {
31462
+ output: capturedOutput,
31463
+ toolCallId: part.toolCallId,
31464
+ toolName: part.toolName,
31465
+ type: "tool-result"
31466
+ };
31467
+ }
31468
+ case "tool-approval-request":
31469
+ return {
31470
+ approvalId: part.approvalId,
31471
+ ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
31472
+ ...part.signature !== void 0 ? { signature: part.signature } : {},
31473
+ toolCallId: part.toolCallId,
31474
+ type: "tool-approval-request"
31475
+ };
31476
+ case "tool-approval-response":
31477
+ return {
31478
+ approvalId: part.approvalId,
31479
+ approved: part.approved,
31480
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
31481
+ ...part.reason !== void 0 ? { reason: part.reason } : {},
31482
+ type: "tool-approval-response"
31483
+ };
31484
+ case "file-data":
31485
+ case "image-data":
31486
+ return {
31487
+ data: part.data,
31488
+ ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
31489
+ mediaType: part.mediaType,
31490
+ type: part.type
31491
+ };
31492
+ case "file-url":
31493
+ case "image-url":
31494
+ return {
31495
+ ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
31496
+ type: part.type,
31497
+ url: part.url
31498
+ };
31499
+ case "file-id":
31500
+ case "image-file-id":
31501
+ return { fileId: part.fileId, type: part.type };
31502
+ case "file-reference":
31503
+ case "image-file-reference":
31504
+ return {
31505
+ providerReference: part.providerReference,
31506
+ type: part.type
31507
+ };
31508
+ }
31509
+ }
30976
31510
  function isCapturedModelInput(input) {
30977
- return Array.isArray(input);
31511
+ return Array.isArray(input) && input.every(
31512
+ (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))
31513
+ );
30978
31514
  }
30979
31515
  function llmInputKey(sessionId, turnId, stepIndex) {
30980
31516
  return `${sessionId}\0${turnId}\0${stepIndex}`;