braintrust 3.23.0 → 3.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dev/dist/index.d.mts +6 -0
  2. package/dev/dist/index.d.ts +6 -0
  3. package/dev/dist/index.js +902 -588
  4. package/dev/dist/index.mjs +320 -6
  5. package/dist/apply-auto-instrumentation.js +211 -189
  6. package/dist/apply-auto-instrumentation.mjs +23 -1
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +40 -0
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +40 -0
  10. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +40 -0
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +40 -0
  14. package/dist/auto-instrumentations/bundler/vite.d.mts +1 -1
  15. package/dist/auto-instrumentations/bundler/vite.d.ts +1 -1
  16. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  17. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +40 -0
  18. package/dist/auto-instrumentations/bundler/webpack.cjs +40 -0
  19. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  20. package/dist/auto-instrumentations/{chunk-KIMLYPRW.mjs → chunk-BURMPO7L.mjs} +1 -1
  21. package/dist/auto-instrumentations/{chunk-YXLNSAMJ.mjs → chunk-F43DNLPD.mjs} +40 -0
  22. package/dist/auto-instrumentations/{chunk-EXY7QCJD.mjs → chunk-GSZHTAQW.mjs} +1 -1
  23. package/dist/auto-instrumentations/hook.mjs +150 -1
  24. package/dist/auto-instrumentations/index.cjs +40 -0
  25. package/dist/auto-instrumentations/index.mjs +1 -1
  26. package/dist/browser.d.mts +131 -9
  27. package/dist/browser.d.ts +131 -9
  28. package/dist/browser.js +703 -67
  29. package/dist/browser.mjs +703 -67
  30. package/dist/{chunk-CDIKAHDZ.js → chunk-7AUY2XWX.js} +21 -1
  31. package/dist/{chunk-36IPYKMG.mjs → chunk-7F6GCRHH.mjs} +20 -0
  32. package/dist/{chunk-FZWPFCVE.js → chunk-SU6EHKJV.js} +1085 -801
  33. package/dist/{chunk-IXL4PMY4.mjs → chunk-XE5FS7QY.mjs} +291 -7
  34. package/dist/cli.js +328 -10
  35. package/dist/edge-light.js +703 -67
  36. package/dist/edge-light.mjs +703 -67
  37. package/dist/index.d.mts +131 -9
  38. package/dist/index.d.ts +131 -9
  39. package/dist/index.js +891 -532
  40. package/dist/index.mjs +423 -64
  41. package/dist/instrumentation/index.d.mts +130 -9
  42. package/dist/instrumentation/index.d.ts +130 -9
  43. package/dist/instrumentation/index.js +601 -67
  44. package/dist/instrumentation/index.mjs +601 -67
  45. package/dist/vitest-evals-reporter.js +17 -16
  46. package/dist/vitest-evals-reporter.mjs +3 -2
  47. package/dist/workerd.js +703 -67
  48. package/dist/workerd.mjs +703 -67
  49. package/package.json +3 -3
  50. package/util/dist/index.js +4 -0
  51. package/util/dist/index.mjs +4 -0
@@ -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
  }
@@ -16050,8 +16314,6 @@ function filterSerializableOptions(options) {
16050
16314
  "additionalDirectories",
16051
16315
  "permissionMode",
16052
16316
  "debug",
16053
- "apiKey",
16054
- "apiKeySource",
16055
16317
  "agentName",
16056
16318
  "instructions"
16057
16319
  ];
@@ -27079,6 +27341,16 @@ function cleanObject(obj) {
27079
27341
  })
27080
27342
  );
27081
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
+ }
27082
27354
  function walkGenerations(response) {
27083
27355
  const result = [];
27084
27356
  const generations = response.generations || [];
@@ -27125,7 +27397,7 @@ function getMetricsFromResponse(response) {
27125
27397
  continue;
27126
27398
  }
27127
27399
  const inputTokenDetails = usageMetadata.input_token_details;
27128
- return cleanObject({
27400
+ return normalizeTokenMetrics({
27129
27401
  total_tokens: usageMetadata.total_tokens,
27130
27402
  prompt_tokens: usageMetadata.input_tokens,
27131
27403
  completion_tokens: usageMetadata.output_tokens,
@@ -27135,7 +27407,7 @@ function getMetricsFromResponse(response) {
27135
27407
  }
27136
27408
  const llmOutput = response.llmOutput || {};
27137
27409
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
27138
- return cleanObject({
27410
+ return normalizeTokenMetrics({
27139
27411
  total_tokens: tokenUsage.totalTokens,
27140
27412
  prompt_tokens: tokenUsage.promptTokens,
27141
27413
  completion_tokens: tokenUsage.completionTokens
@@ -29755,6 +30027,7 @@ var BraintrustPlugin = class extends BasePlugin {
29755
30027
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
29756
30028
  var MAX_EVE_CACHE_ENTRIES = 1e4;
29757
30029
  var MAX_STORED_LLM_INPUTS = 100;
30030
+ var MAX_STORED_REASONING_BLOCKS = 100;
29758
30031
  var MAX_STORED_SPAN_REFERENCES = 1e4;
29759
30032
  var MAX_STORED_STEP_STARTS = 1e4;
29760
30033
  function braintrustEveHook(options) {
@@ -29793,6 +30066,7 @@ var ResumedEveSpan = class {
29793
30066
  this.reference = reference;
29794
30067
  this.endTime = reference.endTime;
29795
30068
  }
30069
+ reference;
29796
30070
  endTime;
29797
30071
  get rootSpanId() {
29798
30072
  return this.reference.rootSpanId;
@@ -29825,6 +30099,7 @@ var EveBridge = class {
29825
30099
  constructor(state) {
29826
30100
  this.state = state;
29827
30101
  }
30102
+ state;
29828
30103
  eventQueuesBySession = /* @__PURE__ */ new Map();
29829
30104
  completedToolKeys = new LRUCache({
29830
30105
  max: MAX_EVE_CACHE_ENTRIES
@@ -30003,6 +30278,9 @@ var EveBridge = class {
30003
30278
  case "step.started":
30004
30279
  await this.handleStepStarted(event, ctx, hookMetadata);
30005
30280
  return true;
30281
+ case "reasoning.completed":
30282
+ this.handleReasoningCompleted(event, ctx);
30283
+ return true;
30006
30284
  case "message.completed":
30007
30285
  this.handleMessageCompleted(event, ctx);
30008
30286
  return true;
@@ -30094,6 +30372,7 @@ var EveBridge = class {
30094
30372
  key,
30095
30373
  metadata,
30096
30374
  metrics: {},
30375
+ sessionId,
30097
30376
  span,
30098
30377
  stepsByIndex: /* @__PURE__ */ new Map(),
30099
30378
  turnId: event.data.turnId
@@ -30124,6 +30403,12 @@ var EveBridge = class {
30124
30403
  const endTime = eventTime2(event);
30125
30404
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
30126
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
+ );
30127
30412
  }
30128
30413
  const stepOrdinal = this.stepOrdinal(event);
30129
30414
  const metadata = { ...turn.metadata };
@@ -30133,6 +30418,13 @@ var EveBridge = class {
30133
30418
  event.data.turnId,
30134
30419
  event.data.stepIndex
30135
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);
30136
30428
  const { rowId: eventId, spanId } = await generateEveIds(
30137
30429
  "step",
30138
30430
  sessionId,
@@ -30150,32 +30442,52 @@ var EveBridge = class {
30150
30442
  spanId,
30151
30443
  startTime: eventTime2(event)
30152
30444
  });
30153
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
30445
+ span.log({
30446
+ ...input !== void 0 ? { input } : {},
30447
+ metadata
30448
+ });
30154
30449
  turn.stepsByIndex.set(event.data.stepIndex, {
30155
30450
  ...input !== void 0 ? { input } : {},
30156
30451
  metadata,
30157
30452
  metrics: {},
30453
+ ...output !== void 0 ? { output } : {},
30454
+ reasoning,
30158
30455
  span
30159
30456
  });
30160
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
+ }
30161
30470
  handleMessageCompleted(event, ctx) {
30162
30471
  const step = this.stepForEvent(event, ctx);
30163
30472
  if (!step) {
30164
30473
  return;
30165
30474
  }
30166
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
30475
+ const existingMessage = eveOutputMessage(step.output);
30167
30476
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
30168
- step.output = [
30169
- {
30170
- finish_reason: normalizedFinishReason(event.data.finishReason),
30171
- index: 0,
30172
- message: {
30173
- content: event.data.message,
30174
- role: "assistant",
30175
- ...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
+ }
30176
30487
  }
30177
- }
30178
- ];
30488
+ ],
30489
+ step.reasoning
30490
+ );
30179
30491
  const turn = this.turnForEvent(event, ctx);
30180
30492
  if (turn && event.data.finishReason !== "tool-calls") {
30181
30493
  turn.output = event.data.message;
@@ -30184,16 +30496,19 @@ var EveBridge = class {
30184
30496
  handleResultCompleted(event, ctx) {
30185
30497
  const step = this.stepForEvent(event, ctx);
30186
30498
  if (step) {
30187
- step.output = [
30188
- {
30189
- finish_reason: "stop",
30190
- index: 0,
30191
- message: {
30192
- content: event.data.result,
30193
- 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
+ }
30194
30508
  }
30195
- }
30196
- ];
30509
+ ],
30510
+ step.reasoning
30511
+ );
30197
30512
  }
30198
30513
  const turn = this.turnForEvent(event, ctx);
30199
30514
  if (turn) {
@@ -30243,18 +30558,20 @@ var EveBridge = class {
30243
30558
  type: "function"
30244
30559
  });
30245
30560
  }
30246
- step.output = [
30247
- {
30248
- finish_reason: "tool_calls",
30249
- index: 0,
30250
- message: {
30251
- content: null,
30252
- role: "assistant",
30253
- 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
+ }
30254
30571
  }
30255
- }
30256
- ];
30257
- step.span.log({ metadata: step.metadata, output: step.output });
30572
+ ],
30573
+ step.reasoning
30574
+ );
30258
30575
  }
30259
30576
  async handleActionResult(event, ctx, hookMetadata) {
30260
30577
  if (isToolResult(event.data.result)) {
@@ -30432,6 +30749,7 @@ var EveBridge = class {
30432
30749
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
30433
30750
  };
30434
30751
  step.metrics = { ...step.metrics, ...metrics };
30752
+ const sessionId = sessionIdFromContext(ctx);
30435
30753
  if (Array.isArray(step.output) && isObject(step.output[0])) {
30436
30754
  const finishReason = step.output[0].finish_reason;
30437
30755
  if (typeof finishReason !== "string") {
@@ -30456,6 +30774,14 @@ var EveBridge = class {
30456
30774
  turn.stepsByIndex.delete(event.data.stepIndex);
30457
30775
  }
30458
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
+ }
30459
30785
  }
30460
30786
  handleStepFailed(event, ctx) {
30461
30787
  const step = this.stepForEvent(event, ctx);
@@ -30473,6 +30799,15 @@ var EveBridge = class {
30473
30799
  const turn = this.turnForEvent(event, ctx);
30474
30800
  turn?.stepsByIndex.delete(event.data.stepIndex);
30475
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
+ }
30476
30811
  }
30477
30812
  handleTurnCompleted(event, ctx) {
30478
30813
  const turn = this.turnForEvent(event, ctx);
@@ -30570,6 +30905,7 @@ var EveBridge = class {
30570
30905
  key,
30571
30906
  metadata,
30572
30907
  metrics: {},
30908
+ sessionId,
30573
30909
  span,
30574
30910
  stepsByIndex: /* @__PURE__ */ new Map(),
30575
30911
  turnId: event.data.turnId
@@ -30832,6 +31168,9 @@ var EveBridge = class {
30832
31168
  const normalized = normalizeEveTraceState(current);
30833
31169
  return {
30834
31170
  ...normalized,
31171
+ reasoningBlocks: normalized.reasoningBlocks.filter(
31172
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
31173
+ ),
30835
31174
  stepStarts: normalized.stepStarts.filter(
30836
31175
  (entry) => entry.turnId !== turn.turnId
30837
31176
  )
@@ -30871,6 +31210,7 @@ function emptyEveTraceState() {
30871
31210
  return {
30872
31211
  llmInputs: [],
30873
31212
  metadata: {},
31213
+ reasoningBlocks: [],
30874
31214
  spanReferences: [],
30875
31215
  stepStarts: []
30876
31216
  };
@@ -30921,6 +31261,21 @@ function normalizeEveTraceState(state) {
30921
31261
  const input = entry["input"];
30922
31262
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
30923
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) : [];
30924
31279
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
30925
31280
  if (!isObject(entry)) {
30926
31281
  return [];
@@ -30931,7 +31286,13 @@ function normalizeEveTraceState(state) {
30931
31286
  const turnId = entry["turnId"];
30932
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 }] : [];
30933
31288
  }).slice(-MAX_STORED_STEP_STARTS) : [];
30934
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
31289
+ return {
31290
+ llmInputs,
31291
+ metadata: { ...metadata },
31292
+ reasoningBlocks,
31293
+ spanReferences,
31294
+ stepStarts
31295
+ };
30935
31296
  }
30936
31297
  function readEveTraceState(state) {
30937
31298
  try {
@@ -30940,23 +31301,85 @@ function readEveTraceState(state) {
30940
31301
  return emptyEveTraceState();
30941
31302
  }
30942
31303
  }
30943
- function captureEveModelInput(state, input) {
30944
- if (!isObject(input)) {
30945
- return;
30946
- }
30947
- const session = input["session"];
30948
- const turn = input["turn"];
30949
- const step = input["step"];
30950
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
30951
- return;
30952
- }
30953
- const sessionId = session["id"];
30954
- const turnId = turn["id"];
30955
- const stepIndex = step["index"];
30956
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
30957
- 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;
30958
31362
  }
30959
- 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);
30960
31383
  if (!captured) {
30961
31384
  return;
30962
31385
  }
@@ -30997,18 +31420,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
30997
31420
  }
30998
31421
  }
30999
31422
  function capturedModelInput(modelInput) {
31000
- if (!isObject(modelInput)) {
31001
- return void 0;
31002
- }
31003
- const messages = modelInput["messages"];
31004
- if (!Array.isArray(messages)) {
31005
- return void 0;
31006
- }
31007
- const instructions = modelInput["instructions"];
31008
- const value = [
31009
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
31010
- ...messages
31011
- ];
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));
31012
31431
  try {
31013
31432
  const cloned = JSON.parse(JSON.stringify(value));
31014
31433
  if (!Array.isArray(cloned)) {
@@ -31019,8 +31438,123 @@ function capturedModelInput(modelInput) {
31019
31438
  return void 0;
31020
31439
  }
31021
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
+ }
31022
31554
  function isCapturedModelInput(input) {
31023
- 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
+ );
31024
31558
  }
31025
31559
  function llmInputKey(sessionId, turnId, stepIndex) {
31026
31560
  return `${sessionId}\0${turnId}\0${stepIndex}`;