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
@@ -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
  }
@@ -16006,8 +16270,6 @@ function filterSerializableOptions(options) {
16006
16270
  "additionalDirectories",
16007
16271
  "permissionMode",
16008
16272
  "debug",
16009
- "apiKey",
16010
- "apiKeySource",
16011
16273
  "agentName",
16012
16274
  "instructions"
16013
16275
  ];
@@ -27035,6 +27297,16 @@ function cleanObject(obj) {
27035
27297
  })
27036
27298
  );
27037
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
+ }
27038
27310
  function walkGenerations(response) {
27039
27311
  const result = [];
27040
27312
  const generations = response.generations || [];
@@ -27081,7 +27353,7 @@ function getMetricsFromResponse(response) {
27081
27353
  continue;
27082
27354
  }
27083
27355
  const inputTokenDetails = usageMetadata.input_token_details;
27084
- return cleanObject({
27356
+ return normalizeTokenMetrics({
27085
27357
  total_tokens: usageMetadata.total_tokens,
27086
27358
  prompt_tokens: usageMetadata.input_tokens,
27087
27359
  completion_tokens: usageMetadata.output_tokens,
@@ -27091,7 +27363,7 @@ function getMetricsFromResponse(response) {
27091
27363
  }
27092
27364
  const llmOutput = response.llmOutput || {};
27093
27365
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
27094
- return cleanObject({
27366
+ return normalizeTokenMetrics({
27095
27367
  total_tokens: tokenUsage.totalTokens,
27096
27368
  prompt_tokens: tokenUsage.promptTokens,
27097
27369
  completion_tokens: tokenUsage.completionTokens
@@ -29711,6 +29983,7 @@ var BraintrustPlugin = class extends BasePlugin {
29711
29983
  var EVE_TRACE_STATE_KEY = "braintrust.eve.tracing";
29712
29984
  var MAX_EVE_CACHE_ENTRIES = 1e4;
29713
29985
  var MAX_STORED_LLM_INPUTS = 100;
29986
+ var MAX_STORED_REASONING_BLOCKS = 100;
29714
29987
  var MAX_STORED_SPAN_REFERENCES = 1e4;
29715
29988
  var MAX_STORED_STEP_STARTS = 1e4;
29716
29989
  function braintrustEveHook(options) {
@@ -29749,6 +30022,7 @@ var ResumedEveSpan = class {
29749
30022
  this.reference = reference;
29750
30023
  this.endTime = reference.endTime;
29751
30024
  }
30025
+ reference;
29752
30026
  endTime;
29753
30027
  get rootSpanId() {
29754
30028
  return this.reference.rootSpanId;
@@ -29781,6 +30055,7 @@ var EveBridge = class {
29781
30055
  constructor(state) {
29782
30056
  this.state = state;
29783
30057
  }
30058
+ state;
29784
30059
  eventQueuesBySession = /* @__PURE__ */ new Map();
29785
30060
  completedToolKeys = new LRUCache({
29786
30061
  max: MAX_EVE_CACHE_ENTRIES
@@ -29959,6 +30234,9 @@ var EveBridge = class {
29959
30234
  case "step.started":
29960
30235
  await this.handleStepStarted(event, ctx, hookMetadata);
29961
30236
  return true;
30237
+ case "reasoning.completed":
30238
+ this.handleReasoningCompleted(event, ctx);
30239
+ return true;
29962
30240
  case "message.completed":
29963
30241
  this.handleMessageCompleted(event, ctx);
29964
30242
  return true;
@@ -30050,6 +30328,7 @@ var EveBridge = class {
30050
30328
  key,
30051
30329
  metadata,
30052
30330
  metrics: {},
30331
+ sessionId,
30053
30332
  span,
30054
30333
  stepsByIndex: /* @__PURE__ */ new Map(),
30055
30334
  turnId: event.data.turnId
@@ -30080,6 +30359,12 @@ var EveBridge = class {
30080
30359
  const endTime = eventTime2(event);
30081
30360
  existing.span.end(endTime === void 0 ? void 0 : { endTime });
30082
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
+ );
30083
30368
  }
30084
30369
  const stepOrdinal = this.stepOrdinal(event);
30085
30370
  const metadata = { ...turn.metadata };
@@ -30089,6 +30374,13 @@ var EveBridge = class {
30089
30374
  event.data.turnId,
30090
30375
  event.data.stepIndex
30091
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);
30092
30384
  const { rowId: eventId, spanId } = await generateEveIds(
30093
30385
  "step",
30094
30386
  sessionId,
@@ -30106,32 +30398,52 @@ var EveBridge = class {
30106
30398
  spanId,
30107
30399
  startTime: eventTime2(event)
30108
30400
  });
30109
- span.log({ ...input !== void 0 ? { input } : {}, metadata });
30401
+ span.log({
30402
+ ...input !== void 0 ? { input } : {},
30403
+ metadata
30404
+ });
30110
30405
  turn.stepsByIndex.set(event.data.stepIndex, {
30111
30406
  ...input !== void 0 ? { input } : {},
30112
30407
  metadata,
30113
30408
  metrics: {},
30409
+ ...output !== void 0 ? { output } : {},
30410
+ reasoning,
30114
30411
  span
30115
30412
  });
30116
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
+ }
30117
30426
  handleMessageCompleted(event, ctx) {
30118
30427
  const step = this.stepForEvent(event, ctx);
30119
30428
  if (!step) {
30120
30429
  return;
30121
30430
  }
30122
- const existingMessage = Array.isArray(step.output) && isObject(step.output[0]) ? step.output[0].message : void 0;
30431
+ const existingMessage = eveOutputMessage(step.output);
30123
30432
  const existingToolCalls = isObject(existingMessage) ? existingMessage.tool_calls : void 0;
30124
- step.output = [
30125
- {
30126
- finish_reason: normalizedFinishReason(event.data.finishReason),
30127
- index: 0,
30128
- message: {
30129
- content: event.data.message,
30130
- role: "assistant",
30131
- ...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
+ }
30132
30443
  }
30133
- }
30134
- ];
30444
+ ],
30445
+ step.reasoning
30446
+ );
30135
30447
  const turn = this.turnForEvent(event, ctx);
30136
30448
  if (turn && event.data.finishReason !== "tool-calls") {
30137
30449
  turn.output = event.data.message;
@@ -30140,16 +30452,19 @@ var EveBridge = class {
30140
30452
  handleResultCompleted(event, ctx) {
30141
30453
  const step = this.stepForEvent(event, ctx);
30142
30454
  if (step) {
30143
- step.output = [
30144
- {
30145
- finish_reason: "stop",
30146
- index: 0,
30147
- message: {
30148
- content: event.data.result,
30149
- 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
+ }
30150
30464
  }
30151
- }
30152
- ];
30465
+ ],
30466
+ step.reasoning
30467
+ );
30153
30468
  }
30154
30469
  const turn = this.turnForEvent(event, ctx);
30155
30470
  if (turn) {
@@ -30199,18 +30514,20 @@ var EveBridge = class {
30199
30514
  type: "function"
30200
30515
  });
30201
30516
  }
30202
- step.output = [
30203
- {
30204
- finish_reason: "tool_calls",
30205
- index: 0,
30206
- message: {
30207
- content: null,
30208
- role: "assistant",
30209
- 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
+ }
30210
30527
  }
30211
- }
30212
- ];
30213
- step.span.log({ metadata: step.metadata, output: step.output });
30528
+ ],
30529
+ step.reasoning
30530
+ );
30214
30531
  }
30215
30532
  async handleActionResult(event, ctx, hookMetadata) {
30216
30533
  if (isToolResult(event.data.result)) {
@@ -30388,6 +30705,7 @@ var EveBridge = class {
30388
30705
  ...costUsd !== void 0 ? { estimated_cost: costUsd } : {}
30389
30706
  };
30390
30707
  step.metrics = { ...step.metrics, ...metrics };
30708
+ const sessionId = sessionIdFromContext(ctx);
30391
30709
  if (Array.isArray(step.output) && isObject(step.output[0])) {
30392
30710
  const finishReason = step.output[0].finish_reason;
30393
30711
  if (typeof finishReason !== "string") {
@@ -30412,6 +30730,14 @@ var EveBridge = class {
30412
30730
  turn.stepsByIndex.delete(event.data.stepIndex);
30413
30731
  }
30414
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
+ }
30415
30741
  }
30416
30742
  handleStepFailed(event, ctx) {
30417
30743
  const step = this.stepForEvent(event, ctx);
@@ -30429,6 +30755,15 @@ var EveBridge = class {
30429
30755
  const turn = this.turnForEvent(event, ctx);
30430
30756
  turn?.stepsByIndex.delete(event.data.stepIndex);
30431
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
+ }
30432
30767
  }
30433
30768
  handleTurnCompleted(event, ctx) {
30434
30769
  const turn = this.turnForEvent(event, ctx);
@@ -30526,6 +30861,7 @@ var EveBridge = class {
30526
30861
  key,
30527
30862
  metadata,
30528
30863
  metrics: {},
30864
+ sessionId,
30529
30865
  span,
30530
30866
  stepsByIndex: /* @__PURE__ */ new Map(),
30531
30867
  turnId: event.data.turnId
@@ -30788,6 +31124,9 @@ var EveBridge = class {
30788
31124
  const normalized = normalizeEveTraceState(current);
30789
31125
  return {
30790
31126
  ...normalized,
31127
+ reasoningBlocks: normalized.reasoningBlocks.filter(
31128
+ (entry) => !entry.key.startsWith(`${turn.sessionId}\0${turn.turnId}\0`)
31129
+ ),
30791
31130
  stepStarts: normalized.stepStarts.filter(
30792
31131
  (entry) => entry.turnId !== turn.turnId
30793
31132
  )
@@ -30827,6 +31166,7 @@ function emptyEveTraceState() {
30827
31166
  return {
30828
31167
  llmInputs: [],
30829
31168
  metadata: {},
31169
+ reasoningBlocks: [],
30830
31170
  spanReferences: [],
30831
31171
  stepStarts: []
30832
31172
  };
@@ -30877,6 +31217,21 @@ function normalizeEveTraceState(state) {
30877
31217
  const input = entry["input"];
30878
31218
  return typeof key === "string" && isCapturedModelInput(input) ? [{ input, key }] : [];
30879
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) : [];
30880
31235
  const stepStarts = Array.isArray(state["stepStarts"]) ? state["stepStarts"].flatMap((entry) => {
30881
31236
  if (!isObject(entry)) {
30882
31237
  return [];
@@ -30887,7 +31242,13 @@ function normalizeEveTraceState(state) {
30887
31242
  const turnId = entry["turnId"];
30888
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 }] : [];
30889
31244
  }).slice(-MAX_STORED_STEP_STARTS) : [];
30890
- return { llmInputs, metadata: { ...metadata }, spanReferences, stepStarts };
31245
+ return {
31246
+ llmInputs,
31247
+ metadata: { ...metadata },
31248
+ reasoningBlocks,
31249
+ spanReferences,
31250
+ stepStarts
31251
+ };
30891
31252
  }
30892
31253
  function readEveTraceState(state) {
30893
31254
  try {
@@ -30896,23 +31257,85 @@ function readEveTraceState(state) {
30896
31257
  return emptyEveTraceState();
30897
31258
  }
30898
31259
  }
30899
- function captureEveModelInput(state, input) {
30900
- if (!isObject(input)) {
30901
- return;
30902
- }
30903
- const session = input["session"];
30904
- const turn = input["turn"];
30905
- const step = input["step"];
30906
- if (!isObject(session) || !isObject(turn) || !isObject(step)) {
30907
- return;
30908
- }
30909
- const sessionId = session["id"];
30910
- const turnId = turn["id"];
30911
- const stepIndex = step["index"];
30912
- if (typeof sessionId !== "string" || typeof turnId !== "string" || typeof stepIndex !== "number" || !Number.isInteger(stepIndex)) {
30913
- 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;
30914
31318
  }
30915
- 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);
30916
31339
  if (!captured) {
30917
31340
  return;
30918
31341
  }
@@ -30953,18 +31376,14 @@ function consumeCapturedEveModelInput(state, sessionId, turnId, stepIndex) {
30953
31376
  }
30954
31377
  }
30955
31378
  function capturedModelInput(modelInput) {
30956
- if (!isObject(modelInput)) {
30957
- return void 0;
30958
- }
30959
- const messages = modelInput["messages"];
30960
- if (!Array.isArray(messages)) {
30961
- return void 0;
30962
- }
30963
- const instructions = modelInput["instructions"];
30964
- const value = [
30965
- ...instructions !== void 0 ? [{ content: instructions, role: "system" }] : [],
30966
- ...messages
30967
- ];
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));
30968
31387
  try {
30969
31388
  const cloned = JSON.parse(JSON.stringify(value));
30970
31389
  if (!Array.isArray(cloned)) {
@@ -30975,8 +31394,123 @@ function capturedModelInput(modelInput) {
30975
31394
  return void 0;
30976
31395
  }
30977
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
+ }
30978
31510
  function isCapturedModelInput(input) {
30979
- 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
+ );
30980
31514
  }
30981
31515
  function llmInputKey(sessionId, turnId, stepIndex) {
30982
31516
  return `${sessionId}\0${turnId}\0${stepIndex}`;