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
@@ -61,6 +61,7 @@ var DefaultChannel = class {
61
61
  constructor(name) {
62
62
  this.name = name;
63
63
  }
64
+ name;
64
65
  hasSubscribers = false;
65
66
  subscribe(_subscription) {
66
67
  }
@@ -1337,6 +1338,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
1337
1338
  constructor(data) {
1338
1339
  this.data = data;
1339
1340
  }
1341
+ data;
1340
1342
  toStr() {
1341
1343
  const jsonObj = {
1342
1344
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1757,6 +1759,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1757
1759
  constructor(data) {
1758
1760
  this.data = data;
1759
1761
  }
1762
+ data;
1760
1763
  toStr() {
1761
1764
  const jsonObj = {
1762
1765
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -4916,6 +4919,97 @@ var SpanCache = class {
4916
4919
  }
4917
4920
  };
4918
4921
 
4922
+ // src/span-origin.ts
4923
+ var SDK_VERSION = true ? "3.24.0" : "0.0.0";
4924
+ function detectSpanOriginEnvironment(explicit) {
4925
+ if (explicit) return explicit;
4926
+ const envType = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_TYPE");
4927
+ const envName = isomorph_default.getEnv("BRAINTRUST_ENVIRONMENT_NAME");
4928
+ if (envType || envName) {
4929
+ return {
4930
+ ...envType ? { type: envType } : {},
4931
+ ...envName ? { name: envName } : {}
4932
+ };
4933
+ }
4934
+ const ci = firstPresent([
4935
+ ["GITHUB_ACTIONS", "github_actions"],
4936
+ ["GITLAB_CI", "gitlab_ci"],
4937
+ ["CIRCLECI", "circleci"],
4938
+ ["BUILDKITE", "buildkite"],
4939
+ ["JENKINS_URL", "jenkins"],
4940
+ ["JENKINS_HOME", "jenkins"],
4941
+ ["TF_BUILD", "azure_pipelines"],
4942
+ ["TEAMCITY_VERSION", "teamcity"],
4943
+ ["TRAVIS", "travis"],
4944
+ ["BITBUCKET_BUILD_NUMBER", "bitbucket"]
4945
+ ]);
4946
+ if (ci) return { type: "ci", name: ci };
4947
+ if (isomorph_default.getEnv("CI")) return { type: "ci", name: "ci" };
4948
+ const earlyServer = firstPresent([
4949
+ ["VERCEL", "vercel"],
4950
+ ["NETLIFY", "netlify"]
4951
+ ]);
4952
+ if (earlyServer) return { type: "server", name: earlyServer };
4953
+ if (isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI") || isomorph_default.getEnv("ECS_CONTAINER_METADATA_URI_V4")) {
4954
+ return { type: "server", name: "ecs" };
4955
+ }
4956
+ const awsExecutionEnv = isomorph_default.getEnv("AWS_EXECUTION_ENV");
4957
+ if (awsExecutionEnv?.startsWith("AWS_ECS_")) {
4958
+ return { type: "server", name: "ecs" };
4959
+ }
4960
+ if (awsExecutionEnv?.startsWith("AWS_Lambda_")) {
4961
+ return { type: "server", name: "aws_lambda" };
4962
+ }
4963
+ if (isomorph_default.getEnv("AWS_LAMBDA_FUNCTION_NAME")) {
4964
+ return { type: "server", name: "aws_lambda" };
4965
+ }
4966
+ const server = firstPresent([
4967
+ ["K_SERVICE", "cloud_run"],
4968
+ ["FUNCTION_TARGET", "gcp_functions"],
4969
+ ["KUBERNETES_SERVICE_HOST", "kubernetes"],
4970
+ ["DYNO", "heroku"],
4971
+ ["FLY_APP_NAME", "fly"],
4972
+ ["RAILWAY_ENVIRONMENT", "railway"],
4973
+ ["RENDER_SERVICE_NAME", "render"]
4974
+ ]);
4975
+ if (server) return { type: "server", name: server };
4976
+ return deploymentModeEnvironment("NODE_ENV", isomorph_default.getEnv("NODE_ENV"));
4977
+ }
4978
+ function makeSpanOrigin(instrumentationName, environment) {
4979
+ return {
4980
+ name: "braintrust.sdk.javascript",
4981
+ version: SDK_VERSION,
4982
+ instrumentation: { name: instrumentationName },
4983
+ ...environment ? { environment } : {}
4984
+ };
4985
+ }
4986
+ function mergeSpanOriginContext(context, instrumentationName, environment) {
4987
+ const next = { ...context ?? {} };
4988
+ const current = isObject2(next.span_origin) ? { ...next.span_origin } : {};
4989
+ next.span_origin = {
4990
+ ...makeSpanOrigin(instrumentationName, environment),
4991
+ ...current
4992
+ };
4993
+ return next;
4994
+ }
4995
+ function firstPresent(entries) {
4996
+ return entries.find(([key]) => Boolean(isomorph_default.getEnv(key)))?.[1];
4997
+ }
4998
+ function deploymentModeEnvironment(_key, value) {
4999
+ if (!value) return void 0;
5000
+ const normalized = value.toLowerCase();
5001
+ if (normalized === "production" || normalized === "staging") {
5002
+ return { type: "server", name: normalized };
5003
+ }
5004
+ if (normalized === "development" || normalized === "local") {
5005
+ return { type: "local", name: normalized };
5006
+ }
5007
+ return { name: value };
5008
+ }
5009
+ function isObject2(value) {
5010
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5011
+ }
5012
+
4919
5013
  // src/logger.ts
4920
5014
  var BRAINTRUST_ATTACHMENT = BraintrustAttachmentReference.shape.type.value;
4921
5015
  var EXTERNAL_ATTACHMENT = ExternalAttachmentReference.shape.type.value;
@@ -4964,6 +5058,7 @@ var LoginInvalidOrgError = class extends Error {
4964
5058
  super(message);
4965
5059
  this.message = message;
4966
5060
  }
5061
+ message;
4967
5062
  };
4968
5063
  var REDACTION_FIELDS = [
4969
5064
  "input",
@@ -4979,6 +5074,8 @@ var MaskingError = class {
4979
5074
  this.fieldName = fieldName;
4980
5075
  this.errorType = errorType;
4981
5076
  }
5077
+ fieldName;
5078
+ errorType;
4982
5079
  get errorMsg() {
4983
5080
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
4984
5081
  }
@@ -5188,7 +5285,9 @@ var BraintrustState = class _BraintrustState {
5188
5285
  diskCache: parametersDiskCache
5189
5286
  });
5190
5287
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5288
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5191
5289
  }
5290
+ loginParams;
5192
5291
  id;
5193
5292
  currentExperiment;
5194
5293
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5223,6 +5322,7 @@ var BraintrustState = class _BraintrustState {
5223
5322
  _idGenerator = null;
5224
5323
  _contextManager = null;
5225
5324
  _otelFlushCallback = null;
5325
+ spanOriginEnvironment;
5226
5326
  resetLoginInfo() {
5227
5327
  this.appUrl = null;
5228
5328
  this.appPublicUrl = null;
@@ -7140,6 +7240,7 @@ function initLogger(options = {}) {
7140
7240
  orgName,
7141
7241
  forceLogin,
7142
7242
  debugLogLevel,
7243
+ environment,
7143
7244
  fetch: fetch2,
7144
7245
  state: stateArg
7145
7246
  } = options || {};
@@ -7156,6 +7257,7 @@ function initLogger(options = {}) {
7156
7257
  };
7157
7258
  const state = stateArg ?? _globalState;
7158
7259
  state.setDebugLogLevel(debugLogLevel);
7260
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7159
7261
  state.enforceQueueSizeLimit(true);
7160
7262
  const lazyMetadata = new LazyValue(
7161
7263
  async () => {
@@ -7795,6 +7897,11 @@ var ObjectFetcher = class {
7795
7897
  this._internal_btql = _internal_btql;
7796
7898
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
7797
7899
  }
7900
+ objectType;
7901
+ pinnedVersion;
7902
+ mutateRecord;
7903
+ _internal_btql;
7904
+ _internalBrainstoreRealtime;
7798
7905
  _fetchedData = void 0;
7799
7906
  get id() {
7800
7907
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -8314,7 +8421,11 @@ var SpanImpl = class _SpanImpl {
8314
8421
  metrics: {
8315
8422
  start: args.startTime ?? getCurrentUnixTimestamp()
8316
8423
  },
8317
- context: { ...callerLocation },
8424
+ context: mergeSpanOriginContext(
8425
+ { ...callerLocation },
8426
+ "braintrust-js-logger",
8427
+ this._state.spanOriginEnvironment
8428
+ ),
8318
8429
  span_attributes: {
8319
8430
  name,
8320
8431
  type,
@@ -8688,6 +8799,7 @@ var Dataset2 = class extends ObjectFetcher {
8688
8799
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
8689
8800
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
8690
8801
  }
8802
+ state;
8691
8803
  lazyMetadata;
8692
8804
  __braintrust_dataset_marker = true;
8693
8805
  newRecords = 0;
@@ -13149,6 +13261,24 @@ var aiSDKChannels = defineChannels("ai", {
13149
13261
  kind: "sync-stream"
13150
13262
  })
13151
13263
  });
13264
+ var harnessAgentChannels = defineChannels("@ai-sdk/harness", {
13265
+ generate: channel({
13266
+ channelName: "HarnessAgent.generate",
13267
+ kind: "async"
13268
+ }),
13269
+ stream: channel({
13270
+ channelName: "HarnessAgent.stream",
13271
+ kind: "async"
13272
+ }),
13273
+ continueGenerate: channel({
13274
+ channelName: "HarnessAgent.continueGenerate",
13275
+ kind: "async"
13276
+ }),
13277
+ continueStream: channel({
13278
+ channelName: "HarnessAgent.continueStream",
13279
+ kind: "async"
13280
+ })
13281
+ });
13152
13282
 
13153
13283
  // src/instrumentation/plugins/ai-sdk-plugin.ts
13154
13284
  var DEFAULT_DENY_OUTPUT_PATHS = [
@@ -13417,6 +13547,84 @@ var AISDKPlugin = class extends BasePlugin {
13417
13547
  })
13418
13548
  })
13419
13549
  );
13550
+ this.unsubscribers.push(
13551
+ traceStreamingChannel(harnessAgentChannels.generate, {
13552
+ name: "HarnessAgent.generate",
13553
+ type: "task" /* TASK */,
13554
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13555
+ extractOutput: (result, endEvent) => processAISDKOutput(
13556
+ result,
13557
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13558
+ ),
13559
+ extractMetrics: (result) => extractTokenMetrics(result),
13560
+ aggregateChunks: aggregateAISDKChunks
13561
+ })
13562
+ );
13563
+ this.unsubscribers.push(
13564
+ traceStreamingChannel(harnessAgentChannels.stream, {
13565
+ name: "HarnessAgent.stream",
13566
+ type: "task" /* TASK */,
13567
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13568
+ extractOutput: (result, endEvent) => processAISDKOutput(
13569
+ result,
13570
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13571
+ ),
13572
+ extractMetrics: (result, startTime) => ({
13573
+ ...extractTokenMetrics(result),
13574
+ ...startTime === void 0 ? {} : {
13575
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
13576
+ }
13577
+ }),
13578
+ aggregateChunks: aggregateAISDKChunks,
13579
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13580
+ defaultDenyOutputPaths: denyOutputPaths,
13581
+ endEvent,
13582
+ result,
13583
+ resolvePromiseUsage: true,
13584
+ span,
13585
+ startTime
13586
+ })
13587
+ })
13588
+ );
13589
+ this.unsubscribers.push(
13590
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
13591
+ name: "HarnessAgent.continueGenerate",
13592
+ type: "task" /* TASK */,
13593
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13594
+ extractOutput: (result, endEvent) => processAISDKOutput(
13595
+ result,
13596
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13597
+ ),
13598
+ extractMetrics: (result) => extractTokenMetrics(result),
13599
+ aggregateChunks: aggregateAISDKChunks
13600
+ })
13601
+ );
13602
+ this.unsubscribers.push(
13603
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
13604
+ name: "HarnessAgent.continueStream",
13605
+ type: "task" /* TASK */,
13606
+ extractInput: ([params], event) => prepareAISDKHarnessAgentInput(params, event.self),
13607
+ extractOutput: (result, endEvent) => processAISDKOutput(
13608
+ result,
13609
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13610
+ ),
13611
+ extractMetrics: (result, startTime) => ({
13612
+ ...extractTokenMetrics(result),
13613
+ ...startTime === void 0 ? {} : {
13614
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
13615
+ }
13616
+ }),
13617
+ aggregateChunks: aggregateAISDKChunks,
13618
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13619
+ defaultDenyOutputPaths: denyOutputPaths,
13620
+ endEvent,
13621
+ result,
13622
+ resolvePromiseUsage: true,
13623
+ span,
13624
+ startTime
13625
+ })
13626
+ })
13627
+ );
13420
13628
  this.unsubscribers.push(
13421
13629
  traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
13422
13630
  name: "ToolLoopAgent.generate",
@@ -13947,6 +14155,45 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
13947
14155
  metadata
13948
14156
  };
13949
14157
  }
14158
+ function prepareAISDKHarnessAgentInput(params, self) {
14159
+ if (isObject(self)) {
14160
+ try {
14161
+ if (isObject(self.settings)) {
14162
+ const settings = self.settings;
14163
+ if (settings.telemetry === void 0) {
14164
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
14165
+ }
14166
+ }
14167
+ } catch {
14168
+ }
14169
+ }
14170
+ const selectedInput = {};
14171
+ if (params.prompt !== void 0) {
14172
+ selectedInput.prompt = params.prompt;
14173
+ }
14174
+ if (params.messages !== void 0) {
14175
+ selectedInput.messages = params.messages;
14176
+ }
14177
+ if (params.toolApprovalContinuations !== void 0) {
14178
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
14179
+ }
14180
+ const metadata = extractMetadataFromCallParams({}, self);
14181
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
14182
+ metadata.sessionId = params.session.sessionId;
14183
+ }
14184
+ if (isObject(self)) {
14185
+ if (typeof self.harnessId === "string") {
14186
+ metadata.harnessId = self.harnessId;
14187
+ }
14188
+ if (typeof self.permissionMode === "string") {
14189
+ metadata.permissionMode = self.permissionMode;
14190
+ }
14191
+ }
14192
+ return {
14193
+ input: processAISDKCallInput(selectedInput).input,
14194
+ metadata
14195
+ };
14196
+ }
13950
14197
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
13951
14198
  registerWorkflowAgentWrapperSpan(span);
13952
14199
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -14794,6 +15041,7 @@ function patchAISDKStreamingResult(args) {
14794
15041
  endEvent,
14795
15042
  onComplete,
14796
15043
  result,
15044
+ resolvePromiseUsage,
14797
15045
  span,
14798
15046
  startTime
14799
15047
  } = args;
@@ -14820,6 +15068,22 @@ function patchAISDKStreamingResult(args) {
14820
15068
  outputLogged = true;
14821
15069
  try {
14822
15070
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
15071
+ if (resolvePromiseUsage) {
15072
+ try {
15073
+ const resultRecord2 = result;
15074
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
15075
+ if (isPromiseLike(pendingUsage)) {
15076
+ const usage = await Promise.resolve(pendingUsage);
15077
+ if (isObject(usage)) {
15078
+ Object.assign(
15079
+ metrics,
15080
+ extractTokenMetrics({ usage })
15081
+ );
15082
+ }
15083
+ }
15084
+ } catch {
15085
+ }
15086
+ }
14823
15087
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
14824
15088
  metrics.time_to_first_token = firstChunkTime - startTime;
14825
15089
  }
@@ -27077,6 +27341,16 @@ function cleanObject(obj) {
27077
27341
  })
27078
27342
  );
27079
27343
  }
27344
+ function normalizeTokenMetrics(obj) {
27345
+ const metrics = cleanObject(obj);
27346
+ if (metrics.total_tokens !== void 0) {
27347
+ metrics.tokens = metrics.total_tokens;
27348
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
27349
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
27350
+ }
27351
+ delete metrics.total_tokens;
27352
+ return metrics;
27353
+ }
27080
27354
  function walkGenerations(response) {
27081
27355
  const result = [];
27082
27356
  const generations = response.generations || [];
@@ -27123,7 +27397,7 @@ function getMetricsFromResponse(response) {
27123
27397
  continue;
27124
27398
  }
27125
27399
  const inputTokenDetails = usageMetadata.input_token_details;
27126
- return cleanObject({
27400
+ return normalizeTokenMetrics({
27127
27401
  total_tokens: usageMetadata.total_tokens,
27128
27402
  prompt_tokens: usageMetadata.input_tokens,
27129
27403
  completion_tokens: usageMetadata.output_tokens,
@@ -27133,7 +27407,7 @@ function getMetricsFromResponse(response) {
27133
27407
  }
27134
27408
  const llmOutput = response.llmOutput || {};
27135
27409
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
27136
- return cleanObject({
27410
+ return normalizeTokenMetrics({
27137
27411
  total_tokens: tokenUsage.totalTokens,
27138
27412
  prompt_tokens: tokenUsage.promptTokens,
27139
27413
  completion_tokens: tokenUsage.completionTokens
@@ -29753,6 +30027,7 @@ var BraintrustPlugin = class extends BasePlugin {
29753
30027
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
29754
30028
  var MAX_EVE_CACHE_ENTRIES = 1e4;
29755
30029
  var MAX_STORED_LLM_INPUTS = 100;
30030
+ var MAX_STORED_REASONING_BLOCKS = 100;
29756
30031
  var MAX_STORED_SPAN_REFERENCES = 1e4;
29757
30032
  var MAX_STORED_STEP_STARTS = 1e4;
29758
30033
  function braintrustEveHook(options) {
@@ -29791,6 +30066,7 @@ var ResumedEveSpan = class {
29791
30066
  this.reference = reference;
29792
30067
  this.endTime = reference.endTime;
29793
30068
  }
30069
+ reference;
29794
30070
  endTime;
29795
30071
  get rootSpanId() {
29796
30072
  return this.reference.rootSpanId;
@@ -29823,6 +30099,7 @@ var EveBridge = class {
29823
30099
  constructor(state) {
29824
30100
  this.state = state;
29825
30101
  }
30102
+ state;
29826
30103
  eventQueuesBySession = /* @__PURE__ */ new Map();
29827
30104
  completedToolKeys = new LRUCache({
29828
30105
  max: MAX_EVE_CACHE_ENTRIES
@@ -30001,6 +30278,9 @@ var EveBridge = class {
30001
30278
  case "step.started":
30002
30279
  await this.handleStepStarted(event, ctx, hookMetadata);
30003
30280
  return true;
30281
+ case "reasoning.completed":
30282
+ this.handleReasoningCompleted(event, ctx);
30283
+ return true;
30004
30284
  case "message.completed":
30005
30285
  this.handleMessageCompleted(event, ctx);
30006
30286
  return true;
@@ -30092,6 +30372,7 @@ var EveBridge = class {
30092
30372
  key,
30093
30373
  metadata,
30094
30374
  metrics: {},
30375
+ sessionId,
30095
30376
  span,
30096
30377
  stepsByIndex: /* @__PURE__ */ new Map(),
30097
30378
  turnId: event.data.turnId
@@ -30122,6 +30403,12 @@ var EveBridge = class {
30122
30403
  const endTime = eventTime2(event);
30123
30404
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
30124
30405
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
30406
+ clearStoredEveReasoning(
30407
+ this.state,
30408
+ sessionId,
30409
+ event.data.turnId,
30410
+ event.data.stepIndex
30411
+ );
30125
30412
  }
30126
30413
  const stepOrdinal = this.stepOrdinal(event);
30127
30414
  const metadata = { ...turn.metadata };
@@ -30131,6 +30418,13 @@ var EveBridge = class {
30131
30418
  event.data.turnId,
30132
30419
  event.data.stepIndex
30133
30420
  );
30421
+ const reasoning = readStoredEveReasoning(
30422
+ this.state,
30423
+ sessionId,
30424
+ event.data.turnId,
30425
+ event.data.stepIndex
30426
+ );
30427
+ const output = mergeEveReasoning(void 0, reasoning);
30134
30428
  const { rowId: eventId, spanId } = await generateEveIds(
30135
30429
  "step",
30136
30430
  sessionId,
@@ -30148,32 +30442,52 @@ var EveBridge = class {
30148
30442
  spanId,
30149
30443
  startTime: eventTime2(event)
30150
30444
  });
30151
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
30445
+ span.log({
30446
+ ...input !== void 0 ? { input } : {},
30447
+ metadata
30448
+ });
30152
30449
  turn.stepsByIndex.set(event.data.stepIndex, {
30153
30450
  ...input !== void 0 ? { input } : {},
30154
30451
  metadata,
30155
30452
  metrics: {},
30453
+ ...output !== void 0 ? { output } : {},
30454
+ reasoning,
30156
30455
  span
30157
30456
  });
30158
30457
  }
30458
+ handleReasoningCompleted(event, ctx) {
30459
+ const sessionId = sessionIdFromContext(ctx);
30460
+ if (!sessionId) {
30461
+ return;
30462
+ }
30463
+ const reasoning = storeEveReasoning(this.state, sessionId, event);
30464
+ const step = this.stepForEvent(event, ctx);
30465
+ if (step) {
30466
+ step.reasoning = reasoning;
30467
+ step.output = mergeEveReasoning(step.output, reasoning);
30468
+ }
30469
+ }
30159
30470
  handleMessageCompleted(event, ctx) {
30160
30471
  const step = this.stepForEvent(event, ctx);
30161
30472
  if (!step) {
30162
30473
  return;
30163
30474
  }
30164
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
30475
+ const existingMessage = eveOutputMessage(step.output);
30165
30476
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
30166
- step.output = [
30167
- {
30168
- finish_reason: normalizedFinishReason(event.data.finishReason),
30169
- index: 0,
30170
- message: {
30171
- content: event.data.message,
30172
- role: "assistant",
30173
- ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
30477
+ step.output = mergeEveReasoning(
30478
+ [
30479
+ {
30480
+ finish_reason: normalizedFinishReason(event.data.finishReason),
30481
+ index: 0,
30482
+ message: {
30483
+ content: event.data.message,
30484
+ role: "assistant",
30485
+ ...Array.isArray(existingToolCalls) ? { tool_calls: existingToolCalls } : {}
30486
+ }
30174
30487
  }
30175
- }
30176
- ];
30488
+ ],
30489
+ step.reasoning
30490
+ );
30177
30491
  const turn = this.turnForEvent(event, ctx);
30178
30492
  if (turn && event.data.finishReason !== "tool-calls") {
30179
30493
  turn.output = event.data.message;
@@ -30182,16 +30496,19 @@ var EveBridge = class {
30182
30496
  handleResultCompleted(event, ctx) {
30183
30497
  const step = this.stepForEvent(event, ctx);
30184
30498
  if (step) {
30185
- step.output = [
30186
- {
30187
- finish_reason: "stop",
30188
- index: 0,
30189
- message: {
30190
- content: event.data.result,
30191
- role: "assistant"
30499
+ step.output = mergeEveReasoning(
30500
+ [
30501
+ {
30502
+ finish_reason: "stop",
30503
+ index: 0,
30504
+ message: {
30505
+ content: event.data.result,
30506
+ role: "assistant"
30507
+ }
30192
30508
  }
30193
- }
30194
- ];
30509
+ ],
30510
+ step.reasoning
30511
+ );
30195
30512
  }
30196
30513
  const turn = this.turnForEvent(event, ctx);
30197
30514
  if (turn) {
@@ -30241,18 +30558,20 @@ var EveBridge = class {
30241
30558
  type: "function"
30242
30559
  });
30243
30560
  }
30244
- step.output = [
30245
- {
30246
- finish_reason: "tool_calls",
30247
- index: 0,
30248
- message: {
30249
- content: null,
30250
- role: "assistant",
30251
- tool_calls: [...toolCallsById.values()]
30561
+ step.output = mergeEveReasoning(
30562
+ [
30563
+ {
30564
+ finish_reason: "tool_calls",
30565
+ index: 0,
30566
+ message: {
30567
+ content: null,
30568
+ role: "assistant",
30569
+ tool_calls: [...toolCallsById.values()]
30570
+ }
30252
30571
  }
30253
- }
30254
- ];
30255
- step.span.log({ metadata: step.metadata, output: step.output });
30572
+ ],
30573
+ step.reasoning
30574
+ );
30256
30575
  }
30257
30576
  async handleActionResult(event, ctx, hookMetadata) {
30258
30577
  if (isToolResult(event.data.result)) {
@@ -30430,6 +30749,7 @@ var EveBridge = class {
30430
30749
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
30431
30750
  };
30432
30751
  step.metrics = { ...step.metrics, ...metrics };
30752
+ const sessionId = sessionIdFromContext(ctx);
30433
30753
  if (Array.isArray(step.output) && isObject(step.output[0])) {
30434
30754
  const finishReason = step.output[0].finish_reason;
30435
30755
  if (typeof finishReason !== "string") {
@@ -30454,6 +30774,14 @@ var EveBridge = class {
30454
30774
  turn.stepsByIndex.delete(event.data.stepIndex);
30455
30775
  }
30456
30776
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
30777
+ if (sessionId) {
30778
+ clearStoredEveReasoning(
30779
+ this.state,
30780
+ sessionId,
30781
+ event.data.turnId,
30782
+ event.data.stepIndex
30783
+ );
30784
+ }
30457
30785
  }
30458
30786
  handleStepFailed(event, ctx) {
30459
30787
  const step = this.stepForEvent(event, ctx);
@@ -30471,6 +30799,15 @@ var EveBridge = class {
30471
30799
  const turn = this.turnForEvent(event, ctx);
30472
30800
  turn?.stepsByIndex.delete(event.data.stepIndex);
30473
30801
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
30802
+ const sessionId = sessionIdFromContext(ctx);
30803
+ if (sessionId) {
30804
+ clearStoredEveReasoning(
30805
+ this.state,
30806
+ sessionId,
30807
+ event.data.turnId,
30808
+ event.data.stepIndex
30809
+ );
30810
+ }
30474
30811
  }
30475
30812
  handleTurnCompleted(event, ctx) {
30476
30813
  const turn = this.turnForEvent(event, ctx);
@@ -30568,6 +30905,7 @@ var EveBridge = class {
30568
30905
  key,
30569
30906
  metadata,
30570
30907
  metrics: {},
30908
+ sessionId,
30571
30909
  span,
30572
30910
  stepsByIndex: /* @__PURE__ */ new Map(),
30573
30911
  turnId: event.data.turnId
@@ -30830,6 +31168,9 @@ var EveBridge = class {
30830
31168
  const normalized = normalizeEveTraceState(current);
30831
31169
  return {
30832
31170
  ...normalized,
31171
+ reasoningBlocks: normalized.reasoningBlocks.filter(
31172
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
31173
+ ),
30833
31174
  stepStarts: normalized.stepStarts.filter(
30834
31175
  (entry) => entry.turnId !== turn.turnId
30835
31176
  )
@@ -30869,6 +31210,7 @@ function emptyEveTraceState() {
30869
31210
  return {
30870
31211
  llmInputs: [],
30871
31212
  metadata: {},
31213
+ reasoningBlocks: [],
30872
31214
  spanReferences: [],
30873
31215
  stepStarts: []
30874
31216
  };
@@ -30919,6 +31261,21 @@ function normalizeEveTraceState(state) {
30919
31261
  const input = entry["input"];
30920
31262
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
30921
31263
  }).slice(-MAX_STORED_LLM_INPUTS) : [];
31264
+ const reasoningBlocks = Array.isArray(state["reasoningBlocks"]) ? state["reasoningBlocks"].flatMap((entry) => {
31265
+ if (!isObject(entry)) {
31266
+ return [];
31267
+ }
31268
+ const content = entry["content"];
31269
+ const eventAt = entry["eventAt"];
31270
+ const key = entry["key"];
31271
+ return typeof content === "string" && (eventAt === void 0 || typeof eventAt === "string") && typeof key === "string" ? [
31272
+ {
31273
+ content,
31274
+ ...typeof eventAt === "string" ? { eventAt } : {},
31275
+ key
31276
+ }
31277
+ ] : [];
31278
+ }).slice(-MAX_STORED_REASONING_BLOCKS) : [];
30922
31279
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
30923
31280
  if (!isObject(entry)) {
30924
31281
  return [];
@@ -30929,7 +31286,13 @@ function normalizeEveTraceState(state) {
30929
31286
  const turnId = entry["turnId"];
30930
31287
  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 }] : [];
30931
31288
  }).slice(-MAX_STORED_STEP_STARTS) : [];
30932
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
31289
+ return {
31290
+ llmInputs,
31291
+ metadata: { ...metadata },
31292
+ reasoningBlocks,
31293
+ spanReferences,
31294
+ stepStarts
31295
+ };
30933
31296
  }
30934
31297
  function readEveTraceState(state) {
30935
31298
  try {
@@ -30938,23 +31301,85 @@ function readEveTraceState(state) {
30938
31301
  return emptyEveTraceState();
30939
31302
  }
30940
31303
  }
30941
- function captureEveModelInput(state, input) {
30942
- if (!isObject(input)) {
30943
- return;
30944
- }
30945
- const session = input["session"];
30946
- const turn = input["turn"];
30947
- const step = input["step"];
30948
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
30949
- return;
30950
- }
30951
- const sessionId = session["id"];
30952
- const turnId = turn["id"];
30953
- const stepIndex = step["index"];
30954
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
30955
- return;
31304
+ function storeEveReasoning(state, sessionId, event) {
31305
+ const eventAt = event.meta?.at;
31306
+ const key = llmInputKey(sessionId, event.data.turnId, event.data.stepIndex);
31307
+ let stored = [];
31308
+ state.update((current) => {
31309
+ const normalized = normalizeEveTraceState(current);
31310
+ const alreadyStored = normalized.reasoningBlocks.some(
31311
+ (entry) => entry.content === event.data.reasoning && entry.eventAt === eventAt && entry.key === key
31312
+ );
31313
+ const reasoningBlocks = alreadyStored ? normalized.reasoningBlocks : [
31314
+ ...normalized.reasoningBlocks,
31315
+ {
31316
+ content: event.data.reasoning,
31317
+ ...eventAt ? { eventAt } : {},
31318
+ key
31319
+ }
31320
+ ].slice(-MAX_STORED_REASONING_BLOCKS);
31321
+ stored = reasoningBlocks.flatMap(
31322
+ (entry) => entry.key === key ? [
31323
+ {
31324
+ content: entry.content,
31325
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
31326
+ }
31327
+ ] : []
31328
+ );
31329
+ return alreadyStored ? normalized : { ...normalized, reasoningBlocks };
31330
+ });
31331
+ return stored;
31332
+ }
31333
+ function readStoredEveReasoning(state, sessionId, turnId, stepIndex) {
31334
+ const key = llmInputKey(sessionId, turnId, stepIndex);
31335
+ return readEveTraceState(state).reasoningBlocks.flatMap(
31336
+ (entry) => entry.key === key ? [
31337
+ {
31338
+ content: entry.content,
31339
+ ...entry.eventAt ? { eventAt: entry.eventAt } : {}
31340
+ }
31341
+ ] : []
31342
+ );
31343
+ }
31344
+ function clearStoredEveReasoning(state, sessionId, turnId, stepIndex) {
31345
+ const key = llmInputKey(sessionId, turnId, stepIndex);
31346
+ state.update((current) => {
31347
+ const normalized = normalizeEveTraceState(current);
31348
+ return {
31349
+ ...normalized,
31350
+ reasoningBlocks: normalized.reasoningBlocks.filter(
31351
+ (entry) => entry.key !== key
31352
+ )
31353
+ };
31354
+ });
31355
+ }
31356
+ function eveOutputMessage(output) {
31357
+ return Array.isArray(output) && isObject(output[0]) ? output[0]["message"] : void 0;
31358
+ }
31359
+ function mergeEveReasoning(output, reasoning) {
31360
+ if (reasoning.length === 0) {
31361
+ return output;
30956
31362
  }
30957
- const captured = capturedModelInput(input["modelInput"]);
31363
+ const choice = Array.isArray(output) && isObject(output[0]) ? output[0] : {};
31364
+ const message = isObject(choice["message"]) ? choice["message"] : {};
31365
+ return [
31366
+ {
31367
+ ...choice,
31368
+ index: typeof choice["index"] === "number" ? choice["index"] : 0,
31369
+ message: {
31370
+ ...message,
31371
+ content: "content" in message ? message["content"] : null,
31372
+ reasoning: reasoning.map((block) => ({ content: block.content })),
31373
+ role: typeof message["role"] === "string" ? message["role"] : "assistant"
31374
+ }
31375
+ }
31376
+ ];
31377
+ }
31378
+ function captureEveModelInput(state, input) {
31379
+ const sessionId = input.session.id;
31380
+ const turnId = input.turn.id;
31381
+ const stepIndex = input.step.index;
31382
+ const captured = capturedModelInput(input.modelInput);
30958
31383
  if (!captured) {
30959
31384
  return;
30960
31385
  }
@@ -30995,18 +31420,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
30995
31420
  }
30996
31421
  }
30997
31422
  function capturedModelInput(modelInput) {
30998
- if (!isObject(modelInput)) {
30999
- return void 0;
31000
- }
31001
- const messages = modelInput["messages"];
31002
- if (!Array.isArray(messages)) {
31003
- return void 0;
31004
- }
31005
- const instructions = modelInput["instructions"];
31006
- const value = [
31007
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
31008
- ...messages
31009
- ];
31423
+ const { instructions, messages } = modelInput;
31424
+ const value = [];
31425
+ if (typeof instructions === "string") {
31426
+ value.push({ content: instructions, role: "system" });
31427
+ } else if (instructions) {
31428
+ value.push(...instructions.map(capturedEveModelMessage));
31429
+ }
31430
+ value.push(...messages.map(capturedEveModelMessage));
31010
31431
  try {
31011
31432
  const cloned = JSON.parse(JSON.stringify(value));
31012
31433
  if (!Array.isArray(cloned)) {
@@ -31017,8 +31438,123 @@ function capturedModelInput(modelInput) {
31017
31438
  return void 0;
31018
31439
  }
31019
31440
  }
31441
+ function capturedEveModelMessage(message) {
31442
+ const { content, role } = message;
31443
+ if (typeof content === "string") {
31444
+ return { content, role };
31445
+ }
31446
+ return { content: content.map(capturedEveModelContentPart), role };
31447
+ }
31448
+ function capturedEveModelContentPart(part) {
31449
+ switch (part.type) {
31450
+ case "text":
31451
+ case "reasoning":
31452
+ return { text: part.text, type: part.type };
31453
+ case "image":
31454
+ return {
31455
+ image: part.image,
31456
+ ...part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
31457
+ type: "image"
31458
+ };
31459
+ case "file":
31460
+ case "reasoning-file":
31461
+ return {
31462
+ data: part.data,
31463
+ ...part.type === "file" && part.filename !== void 0 ? { filename: part.filename } : {},
31464
+ mediaType: part.mediaType,
31465
+ type: part.type
31466
+ };
31467
+ case "custom":
31468
+ return {
31469
+ ..."kind" in part ? { kind: part.kind } : {},
31470
+ type: "custom"
31471
+ };
31472
+ case "tool-call":
31473
+ return {
31474
+ input: part.input,
31475
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
31476
+ toolCallId: part.toolCallId,
31477
+ toolName: part.toolName,
31478
+ type: "tool-call"
31479
+ };
31480
+ case "tool-result": {
31481
+ const output = part.output;
31482
+ let capturedOutput;
31483
+ switch (output.type) {
31484
+ case "text":
31485
+ case "error-text":
31486
+ capturedOutput = { type: output.type, value: output.value };
31487
+ break;
31488
+ case "json":
31489
+ case "error-json":
31490
+ capturedOutput = { type: output.type, value: output.value };
31491
+ break;
31492
+ case "execution-denied":
31493
+ capturedOutput = {
31494
+ ...output.reason !== void 0 ? { reason: output.reason } : {},
31495
+ type: "execution-denied"
31496
+ };
31497
+ break;
31498
+ case "content":
31499
+ capturedOutput = {
31500
+ type: "content",
31501
+ value: output.value.map(capturedEveModelContentPart)
31502
+ };
31503
+ break;
31504
+ }
31505
+ return {
31506
+ output: capturedOutput,
31507
+ toolCallId: part.toolCallId,
31508
+ toolName: part.toolName,
31509
+ type: "tool-result"
31510
+ };
31511
+ }
31512
+ case "tool-approval-request":
31513
+ return {
31514
+ approvalId: part.approvalId,
31515
+ ...part.isAutomatic !== void 0 ? { isAutomatic: part.isAutomatic } : {},
31516
+ ...part.signature !== void 0 ? { signature: part.signature } : {},
31517
+ toolCallId: part.toolCallId,
31518
+ type: "tool-approval-request"
31519
+ };
31520
+ case "tool-approval-response":
31521
+ return {
31522
+ approvalId: part.approvalId,
31523
+ approved: part.approved,
31524
+ ...part.providerExecuted !== void 0 ? { providerExecuted: part.providerExecuted } : {},
31525
+ ...part.reason !== void 0 ? { reason: part.reason } : {},
31526
+ type: "tool-approval-response"
31527
+ };
31528
+ case "file-data":
31529
+ case "image-data":
31530
+ return {
31531
+ data: part.data,
31532
+ ...part.type === "file-data" && part.filename !== void 0 ? { filename: part.filename } : {},
31533
+ mediaType: part.mediaType,
31534
+ type: part.type
31535
+ };
31536
+ case "file-url":
31537
+ case "image-url":
31538
+ return {
31539
+ ...part.type === "file-url" && part.mediaType !== void 0 ? { mediaType: part.mediaType } : {},
31540
+ type: part.type,
31541
+ url: part.url
31542
+ };
31543
+ case "file-id":
31544
+ case "image-file-id":
31545
+ return { fileId: part.fileId, type: part.type };
31546
+ case "file-reference":
31547
+ case "image-file-reference":
31548
+ return {
31549
+ providerReference: part.providerReference,
31550
+ type: part.type
31551
+ };
31552
+ }
31553
+ }
31020
31554
  function isCapturedModelInput(input) {
31021
- return Array.isArray(input);
31555
+ return Array.isArray(input) && input.every(
31556
+ (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))
31557
+ );
31022
31558
  }
31023
31559
  function llmInputKey(sessionId, turnId, stepIndex) {
31024
31560
  return `${sessionId}\0${turnId}\0${stepIndex}`;