braintrust 3.23.1 → 3.25.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 +11 -0
  2. package/dev/dist/index.d.ts +11 -0
  3. package/dev/dist/index.js +2881 -1518
  4. package/dev/dist/index.mjs +2298 -935
  5. package/dist/apply-auto-instrumentation.js +218 -195
  6. package/dist/apply-auto-instrumentation.mjs +30 -7
  7. package/dist/auto-instrumentations/bundler/esbuild.cjs +618 -444
  8. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/next.cjs +618 -444
  10. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  11. package/dist/auto-instrumentations/bundler/rollup.cjs +618 -444
  12. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  13. package/dist/auto-instrumentations/bundler/vite.cjs +618 -444
  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 +618 -444
  18. package/dist/auto-instrumentations/bundler/webpack.cjs +618 -444
  19. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  20. package/dist/auto-instrumentations/{chunk-KIMLYPRW.mjs → chunk-7P6563SW.mjs} +1 -1
  21. package/dist/auto-instrumentations/{chunk-YXLNSAMJ.mjs → chunk-CZ24KNHT.mjs} +591 -424
  22. package/dist/auto-instrumentations/{chunk-EXY7QCJD.mjs → chunk-JPVCUKTY.mjs} +30 -21
  23. package/dist/auto-instrumentations/hook.mjs +778 -457
  24. package/dist/auto-instrumentations/index.cjs +590 -424
  25. package/dist/auto-instrumentations/index.mjs +1 -1
  26. package/dist/browser.d.mts +138 -9
  27. package/dist/browser.d.ts +138 -9
  28. package/dist/browser.js +2700 -1011
  29. package/dist/browser.mjs +2700 -1011
  30. package/dist/{chunk-RBXD2KYN.mjs → chunk-2SANLSWX.mjs} +1577 -513
  31. package/dist/{chunk-36IPYKMG.mjs → chunk-ABR2QWDP.mjs} +704 -438
  32. package/dist/{chunk-B6ZQIAK3.js → chunk-GSIDVFE6.js} +2361 -1297
  33. package/dist/{chunk-CDIKAHDZ.js → chunk-P25IOOU4.js} +706 -440
  34. package/dist/cli.js +2307 -940
  35. package/dist/edge-light.js +2700 -1011
  36. package/dist/edge-light.mjs +2700 -1011
  37. package/dist/index.d.mts +138 -9
  38. package/dist/index.d.ts +138 -9
  39. package/dist/index.js +955 -551
  40. package/dist/index.mjs +493 -89
  41. package/dist/instrumentation/index.d.mts +135 -9
  42. package/dist/instrumentation/index.d.ts +135 -9
  43. package/dist/instrumentation/index.js +2554 -1009
  44. package/dist/instrumentation/index.mjs +2554 -1009
  45. package/dist/vitest-evals-reporter.js +17 -16
  46. package/dist/vitest-evals-reporter.mjs +3 -2
  47. package/dist/workerd.js +2700 -1011
  48. package/dist/workerd.mjs +2700 -1011
  49. package/package.json +4 -4
  50. package/util/dist/index.js +4 -0
  51. package/util/dist/index.mjs +4 -0
@@ -1,24 +1,29 @@
1
1
  import {
2
+ INSTRUMENTATION_NAMES,
2
3
  aiSDKChannels,
3
4
  anthropicChannels,
4
5
  bedrockRuntimeChannels,
5
6
  claudeAgentSDKChannels,
6
7
  cohereChannels,
7
8
  cursorSDKChannels,
9
+ detectSpanOriginEnvironment,
8
10
  flueChannels,
9
11
  genkitChannels,
10
12
  genkitCoreChannels,
11
13
  getDefaultInstrumentationIntegrations,
14
+ getSpanInstrumentationName,
12
15
  gitHubCopilotChannels,
13
16
  googleADKChannels,
14
17
  googleGenAIChannels,
15
18
  groqChannels,
19
+ harnessAgentChannels,
16
20
  huggingFaceChannels,
17
21
  installMastraExporterFactory,
18
22
  isInstrumentationIntegrationDisabled,
19
23
  isomorph_default,
20
24
  langChainChannels,
21
25
  langSmithChannels,
26
+ mergeSpanOriginContext,
22
27
  mistralChannels,
23
28
  openAIAgentsCoreChannels,
24
29
  openAIChannels,
@@ -30,8 +35,9 @@ import {
30
35
  readDisabledInstrumentationEnvConfig,
31
36
  smithyClientChannels,
32
37
  smithyCoreChannels,
33
- strandsAgentSDKChannels
34
- } from "./chunk-36IPYKMG.mjs";
38
+ strandsAgentSDKChannels,
39
+ withSpanInstrumentationName
40
+ } from "./chunk-ABR2QWDP.mjs";
35
41
 
36
42
  // src/id-gen.ts
37
43
  import { v4 as uuidv4 } from "uuid";
@@ -965,6 +971,7 @@ var SpanComponentsV3 = class _SpanComponentsV3 {
965
971
  constructor(data) {
966
972
  this.data = data;
967
973
  }
974
+ data;
968
975
  toStr() {
969
976
  const jsonObj = {
970
977
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -1458,6 +1465,7 @@ var SpanComponentsV4 = class _SpanComponentsV4 {
1458
1465
  constructor(data) {
1459
1466
  this.data = data;
1460
1467
  }
1468
+ data;
1461
1469
  toStr() {
1462
1470
  const jsonObj = {
1463
1471
  compute_object_metadata_args: this.data.compute_object_metadata_args || void 0,
@@ -4798,6 +4806,7 @@ var LoginInvalidOrgError = class extends Error {
4798
4806
  super(message);
4799
4807
  this.message = message;
4800
4808
  }
4809
+ message;
4801
4810
  };
4802
4811
  var REDACTION_FIELDS = [
4803
4812
  "input",
@@ -4813,6 +4822,8 @@ var MaskingError = class {
4813
4822
  this.fieldName = fieldName;
4814
4823
  this.errorType = errorType;
4815
4824
  }
4825
+ fieldName;
4826
+ errorType;
4816
4827
  get errorMsg() {
4817
4828
  return `ERROR: Failed to mask field '${this.fieldName}' - ${this.errorType}`;
4818
4829
  }
@@ -5022,7 +5033,10 @@ var BraintrustState = class _BraintrustState {
5022
5033
  diskCache: parametersDiskCache
5023
5034
  });
5024
5035
  this.spanCache = new SpanCache({ disabled: loginParams.disableSpanCache });
5036
+ this.spanOriginEnvironment = detectSpanOriginEnvironment();
5037
+ this._internalSetTraceContextSigningSecret(loginParams.apiKey);
5025
5038
  }
5039
+ loginParams;
5026
5040
  id;
5027
5041
  currentExperiment;
5028
5042
  // Note: the value of IsAsyncFlush doesn't really matter here, since we
@@ -5057,6 +5071,19 @@ var BraintrustState = class _BraintrustState {
5057
5071
  _idGenerator = null;
5058
5072
  _contextManager = null;
5059
5073
  _otelFlushCallback = null;
5074
+ spanOriginEnvironment;
5075
+ traceContextSigningSecret;
5076
+ /** @internal */
5077
+ _internalSetTraceContextSigningSecret(secret) {
5078
+ const normalizedSecret = secret?.trim();
5079
+ if (normalizedSecret) {
5080
+ this.traceContextSigningSecret = normalizedSecret;
5081
+ }
5082
+ }
5083
+ /** @internal */
5084
+ _internalGetTraceContextSigningSecret() {
5085
+ return (this.traceContextSigningSecret ?? this.loginToken ?? isomorph_default.getEnv("BRAINTRUST_API_KEY"))?.trim();
5086
+ }
5060
5087
  resetLoginInfo() {
5061
5088
  this.appUrl = null;
5062
5089
  this.appPublicUrl = null;
@@ -5117,6 +5144,7 @@ var BraintrustState = class _BraintrustState {
5117
5144
  this.gitMetadataSettings = other.gitMetadataSettings;
5118
5145
  this.debugLogLevel = other.debugLogLevel;
5119
5146
  this.debugLogLevelConfigured = other.debugLogLevelConfigured;
5147
+ this.traceContextSigningSecret = other.traceContextSigningSecret;
5120
5148
  setGlobalDebugLogLevel(
5121
5149
  this.debugLogLevelConfigured ? this.debugLogLevel ?? false : void 0
5122
5150
  );
@@ -5204,6 +5232,7 @@ var BraintrustState = class _BraintrustState {
5204
5232
  return this.debugLogLevelConfigured;
5205
5233
  }
5206
5234
  async login(loginParams) {
5235
+ this._internalSetTraceContextSigningSecret(loginParams.apiKey);
5207
5236
  this.setDebugLogLevel(loginParams.debugLogLevel);
5208
5237
  if (this.apiUrl && !loginParams.forceLogin) {
5209
5238
  return;
@@ -7183,6 +7212,7 @@ function init(projectOrOptions, optionalOptions) {
7183
7212
  throw new Error("Cannot open and update an experiment at the same time");
7184
7213
  }
7185
7214
  const state = stateArg ?? _globalState;
7215
+ state._internalSetTraceContextSigningSecret(apiKey);
7186
7216
  state.enforceQueueSizeLimit(false);
7187
7217
  if (open2) {
7188
7218
  if (isEmpty2(experiment)) {
@@ -7675,6 +7705,7 @@ function initLogger(options = {}) {
7675
7705
  orgName,
7676
7706
  forceLogin,
7677
7707
  debugLogLevel,
7708
+ environment,
7678
7709
  fetch: fetch2,
7679
7710
  state: stateArg
7680
7711
  } = options || {};
@@ -7690,7 +7721,9 @@ function initLogger(options = {}) {
7690
7721
  project_id: projectId
7691
7722
  };
7692
7723
  const state = stateArg ?? _globalState;
7724
+ state._internalSetTraceContextSigningSecret(apiKey);
7693
7725
  state.setDebugLogLevel(debugLogLevel);
7726
+ state.spanOriginEnvironment = detectSpanOriginEnvironment(environment);
7694
7727
  state.enforceQueueSizeLimit(true);
7695
7728
  const lazyMetadata = new LazyValue(
7696
7729
  async () => {
@@ -8752,7 +8785,9 @@ function deepCopyEvent(event) {
8752
8785
  const ATTACHMENT_MARKER_KEY = "_bt_internal_saved_attachment_marker";
8753
8786
  const attachmentMarker = ++deepCopyEventMarkerCounter;
8754
8787
  const serialized = JSON.stringify(event, (_k, v) => {
8755
- if (v instanceof SpanImpl || v instanceof NoopSpan) {
8788
+ if (v instanceof Error) {
8789
+ return v.message;
8790
+ } else if (v instanceof SpanImpl || v instanceof NoopSpan) {
8756
8791
  return `<span>`;
8757
8792
  } else if (v instanceof Experiment2) {
8758
8793
  return `<experiment>`;
@@ -8882,6 +8917,11 @@ var ObjectFetcher = class {
8882
8917
  this._internal_btql = _internal_btql;
8883
8918
  this._internalBrainstoreRealtime = _internalBrainstoreRealtime;
8884
8919
  }
8920
+ objectType;
8921
+ pinnedVersion;
8922
+ mutateRecord;
8923
+ _internal_btql;
8924
+ _internalBrainstoreRealtime;
8885
8925
  _fetchedData = void 0;
8886
8926
  get id() {
8887
8927
  throw new Error("ObjectFetcher subclasses must have an 'id' attribute");
@@ -9320,6 +9360,8 @@ var ReadonlyExperiment = class extends ObjectFetcher {
9320
9360
  this.state = state;
9321
9361
  this.lazyMetadata = lazyMetadata;
9322
9362
  }
9363
+ state;
9364
+ lazyMetadata;
9323
9365
  get id() {
9324
9366
  return (async () => {
9325
9367
  return (await this.lazyMetadata.get()).experiment.id;
@@ -9413,6 +9455,7 @@ var SpanImpl = class _SpanImpl {
9413
9455
  constructor(args) {
9414
9456
  this._state = args.state;
9415
9457
  this._propagatedState = args.propagatedState;
9458
+ const instrumentationName = getSpanInstrumentationName(args) ?? INSTRUMENTATION_NAMES.BRAINTRUST_JS_LOGGER;
9416
9459
  const spanAttributes = args.spanAttributes ?? {};
9417
9460
  const rawEvent = args.event ?? {};
9418
9461
  const type = args.type ?? (args.parentSpanIds ? void 0 : args.defaultRootType);
@@ -9442,7 +9485,11 @@ var SpanImpl = class _SpanImpl {
9442
9485
  metrics: {
9443
9486
  start: args.startTime ?? getCurrentUnixTimestamp()
9444
9487
  },
9445
- context: { ...callerLocation },
9488
+ context: mergeSpanOriginContext(
9489
+ { ...callerLocation },
9490
+ instrumentationName,
9491
+ this._state.spanOriginEnvironment
9492
+ ),
9446
9493
  span_attributes: {
9447
9494
  name,
9448
9495
  type,
@@ -9816,6 +9863,7 @@ var Dataset2 = class extends ObjectFetcher {
9816
9863
  this.pinnedEnvironment = pinState?.pinnedEnvironment;
9817
9864
  this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
9818
9865
  }
9866
+ state;
9819
9867
  lazyMetadata;
9820
9868
  __braintrust_dataset_marker = true;
9821
9869
  newRecords = 0;
@@ -10330,6 +10378,9 @@ var Prompt2 = class _Prompt {
10330
10378
  this.noTrace = noTrace;
10331
10379
  void this.__braintrust_prompt_marker;
10332
10380
  }
10381
+ metadata;
10382
+ defaults;
10383
+ noTrace;
10333
10384
  parsedPromptData;
10334
10385
  hasParsedPromptData = false;
10335
10386
  __braintrust_prompt_marker = true;
@@ -10567,6 +10618,7 @@ var RemoteEvalParameters = class {
10567
10618
  this.metadata = metadata;
10568
10619
  void this.__braintrust_parameters_marker;
10569
10620
  }
10621
+ metadata;
10570
10622
  __braintrust_parameters_marker = true;
10571
10623
  get id() {
10572
10624
  return this.metadata.id;
@@ -11474,15 +11526,25 @@ function hasChoices(value) {
11474
11526
  function normalizeMetadata(metadata) {
11475
11527
  return isObject(metadata) ? metadata : void 0;
11476
11528
  }
11477
- function startSpanForEvent(config, event, channelName) {
11529
+ function startSpanForEvent(config, event, channelName, instrumentationName) {
11478
11530
  const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
11479
11531
  config,
11480
11532
  event
11481
11533
  );
11482
- const span = startSpan({
11483
- name,
11484
- spanAttributes
11485
- });
11534
+ const spanArgs = withSpanInstrumentationName(
11535
+ {
11536
+ name,
11537
+ spanAttributes
11538
+ },
11539
+ instrumentationName
11540
+ );
11541
+ let span;
11542
+ try {
11543
+ span = config.startSpan?.(spanArgs) ?? startSpan(spanArgs);
11544
+ } catch (error) {
11545
+ debugLogger.error(`Error starting span for ${channelName}:`, error);
11546
+ span = startSpan(spanArgs);
11547
+ }
11486
11548
  const startTime = getCurrentUnixTimestamp();
11487
11549
  try {
11488
11550
  const { input, metadata } = config.extractInput(
@@ -11513,7 +11575,7 @@ function shouldTraceEvent(config, event, channelName) {
11513
11575
  return true;
11514
11576
  }
11515
11577
  }
11516
- function ensureSpanStateForEvent(states, config, event, channelName) {
11578
+ function ensureSpanStateForEvent(states, config, event, channelName, instrumentationName) {
11517
11579
  const key = event;
11518
11580
  const existing = states.get(key);
11519
11581
  if (existing) {
@@ -11522,11 +11584,16 @@ function ensureSpanStateForEvent(states, config, event, channelName) {
11522
11584
  if (!shouldTraceEvent(config, event, channelName)) {
11523
11585
  return void 0;
11524
11586
  }
11525
- const created = startSpanForEvent(config, event, channelName);
11587
+ const created = startSpanForEvent(
11588
+ config,
11589
+ event,
11590
+ channelName,
11591
+ instrumentationName
11592
+ );
11526
11593
  states.set(key, created);
11527
11594
  return created;
11528
11595
  }
11529
- function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName) {
11596
+ function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelName, instrumentationName) {
11530
11597
  const state = _internalGetGlobalState();
11531
11598
  const startChannel = tracingChannel2.start;
11532
11599
  const contextManager = state?.contextManager;
@@ -11544,7 +11611,8 @@ function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelNam
11544
11611
  states,
11545
11612
  config,
11546
11613
  event,
11547
- channelName
11614
+ channelName,
11615
+ instrumentationName
11548
11616
  );
11549
11617
  return spanState ? contextManager.wrapSpanForStore(spanState.span) : currentSpanStore.getStore();
11550
11618
  }
@@ -11553,15 +11621,21 @@ function bindCurrentSpanStoreToStart(tracingChannel2, states, config, channelNam
11553
11621
  startChannel.unbindStore(currentSpanStore);
11554
11622
  };
11555
11623
  }
11556
- function logErrorAndEnd(states, event) {
11624
+ function logErrorAndEnd(states, event, channelName) {
11557
11625
  const spanData = states.get(event);
11558
11626
  if (!spanData) {
11559
11627
  return;
11560
11628
  }
11561
- spanData.span.log({
11562
- error: event.error.message
11563
- });
11564
- spanData.span.end();
11629
+ try {
11630
+ spanData.span.log({ error: event.error });
11631
+ } catch (error) {
11632
+ debugLogger.error(`Error logging failure for ${channelName}:`, error);
11633
+ }
11634
+ try {
11635
+ spanData.span.end();
11636
+ } catch (error) {
11637
+ debugLogger.error(`Error ending span for ${channelName}:`, error);
11638
+ }
11565
11639
  states.delete(event);
11566
11640
  }
11567
11641
  function runStreamingCompletionHook(args) {
@@ -11611,7 +11685,8 @@ function traceAsyncChannel(channel, config) {
11611
11685
  tracingChannel2,
11612
11686
  states,
11613
11687
  config,
11614
- channelName
11688
+ channelName,
11689
+ channel.instrumentationName
11615
11690
  );
11616
11691
  const handlers = {
11617
11692
  start: (event) => {
@@ -11622,7 +11697,8 @@ function traceAsyncChannel(channel, config) {
11622
11697
  states,
11623
11698
  config,
11624
11699
  event,
11625
- channelName
11700
+ channelName,
11701
+ channel.instrumentationName
11626
11702
  );
11627
11703
  },
11628
11704
  asyncEnd: (event) => {
@@ -11659,7 +11735,7 @@ function traceAsyncChannel(channel, config) {
11659
11735
  }
11660
11736
  },
11661
11737
  error: (event) => {
11662
- logErrorAndEnd(states, event);
11738
+ logErrorAndEnd(states, event, channelName);
11663
11739
  }
11664
11740
  };
11665
11741
  tracingChannel2.subscribe(handlers);
@@ -11676,7 +11752,8 @@ function traceStreamingChannel(channel, config) {
11676
11752
  tracingChannel2,
11677
11753
  states,
11678
11754
  config,
11679
- channelName
11755
+ channelName,
11756
+ channel.instrumentationName
11680
11757
  );
11681
11758
  const handlers = {
11682
11759
  start: (event) => {
@@ -11687,7 +11764,8 @@ function traceStreamingChannel(channel, config) {
11687
11764
  states,
11688
11765
  config,
11689
11766
  event,
11690
- channelName
11767
+ channelName,
11768
+ channel.instrumentationName
11691
11769
  );
11692
11770
  },
11693
11771
  asyncEnd: (event) => {
@@ -11706,6 +11784,7 @@ function traceStreamingChannel(channel, config) {
11706
11784
  }
11707
11785
  },
11708
11786
  onComplete: (chunks) => {
11787
+ let completion2;
11709
11788
  try {
11710
11789
  let output;
11711
11790
  let metrics;
@@ -11736,18 +11815,11 @@ function traceStreamingChannel(channel, config) {
11736
11815
  } else if (metrics.time_to_first_token === void 0 && chunks.length > 0) {
11737
11816
  metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
11738
11817
  }
11739
- runStreamingCompletionHook({
11740
- channelName,
11741
- chunks,
11742
- config,
11743
- endEvent: asyncEndEvent,
11818
+ completion2 = {
11744
11819
  ...metadata !== void 0 ? { metadata } : {},
11745
11820
  metrics,
11746
- output,
11747
- result: asyncEndEvent.result,
11748
- span,
11749
- startTime
11750
- });
11821
+ output
11822
+ };
11751
11823
  span.log({
11752
11824
  output,
11753
11825
  ...metadata !== void 0 ? { metadata } : {},
@@ -11759,11 +11831,49 @@ function traceStreamingChannel(channel, config) {
11759
11831
  error
11760
11832
  );
11761
11833
  } finally {
11762
- span.end();
11834
+ try {
11835
+ span.end();
11836
+ } catch (error) {
11837
+ debugLogger.error(
11838
+ `Error ending span for ${channelName}:`,
11839
+ error
11840
+ );
11841
+ }
11763
11842
  states.delete(event);
11764
11843
  }
11844
+ if (completion2) {
11845
+ runStreamingCompletionHook({
11846
+ channelName,
11847
+ chunks,
11848
+ config,
11849
+ endEvent: asyncEndEvent,
11850
+ ...completion2.metadata !== void 0 ? { metadata: completion2.metadata } : {},
11851
+ metrics: completion2.metrics,
11852
+ output: completion2.output,
11853
+ result: asyncEndEvent.result,
11854
+ span,
11855
+ startTime
11856
+ });
11857
+ }
11765
11858
  },
11766
11859
  onError: (error) => {
11860
+ try {
11861
+ span.log({ error });
11862
+ } catch (loggingError) {
11863
+ debugLogger.error(
11864
+ `Error logging failure for ${channelName}:`,
11865
+ loggingError
11866
+ );
11867
+ }
11868
+ try {
11869
+ span.end();
11870
+ } catch (endingError) {
11871
+ debugLogger.error(
11872
+ `Error ending span for ${channelName}:`,
11873
+ endingError
11874
+ );
11875
+ }
11876
+ states.delete(event);
11767
11877
  runStreamingErrorHook({
11768
11878
  channelName,
11769
11879
  config,
@@ -11772,11 +11882,6 @@ function traceStreamingChannel(channel, config) {
11772
11882
  span,
11773
11883
  startTime
11774
11884
  });
11775
- span.log({
11776
- error: error.message
11777
- });
11778
- span.end();
11779
- states.delete(event);
11780
11885
  }
11781
11886
  });
11782
11887
  return;
@@ -11791,6 +11896,7 @@ function traceStreamingChannel(channel, config) {
11791
11896
  states.delete(event);
11792
11897
  return;
11793
11898
  }
11899
+ let completion;
11794
11900
  try {
11795
11901
  const output = config.extractOutput(
11796
11902
  asyncEndEvent.result,
@@ -11805,17 +11911,11 @@ function traceStreamingChannel(channel, config) {
11805
11911
  asyncEndEvent.result,
11806
11912
  asyncEndEvent
11807
11913
  );
11808
- runStreamingCompletionHook({
11809
- channelName,
11810
- config,
11811
- endEvent: asyncEndEvent,
11914
+ completion = {
11812
11915
  ...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
11813
11916
  metrics,
11814
- output,
11815
- result: asyncEndEvent.result,
11816
- span,
11817
- startTime
11818
- });
11917
+ output
11918
+ };
11819
11919
  span.log({
11820
11920
  output,
11821
11921
  ...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
@@ -11824,12 +11924,30 @@ function traceStreamingChannel(channel, config) {
11824
11924
  } catch (error) {
11825
11925
  debugLogger.error(`Error extracting output for ${channelName}:`, error);
11826
11926
  } finally {
11827
- span.end();
11927
+ try {
11928
+ span.end();
11929
+ } catch (error) {
11930
+ debugLogger.error(`Error ending span for ${channelName}:`, error);
11931
+ }
11828
11932
  states.delete(event);
11829
11933
  }
11934
+ if (completion) {
11935
+ runStreamingCompletionHook({
11936
+ channelName,
11937
+ config,
11938
+ endEvent: asyncEndEvent,
11939
+ ...completion.metadata !== void 0 ? { metadata: completion.metadata } : {},
11940
+ metrics: completion.metrics,
11941
+ output: completion.output,
11942
+ result: asyncEndEvent.result,
11943
+ span,
11944
+ startTime
11945
+ });
11946
+ }
11830
11947
  },
11831
11948
  error: (event) => {
11832
11949
  const spanData = states.get(event);
11950
+ logErrorAndEnd(states, event, channelName);
11833
11951
  if (spanData) {
11834
11952
  runStreamingErrorHook({
11835
11953
  channelName,
@@ -11840,7 +11958,6 @@ function traceStreamingChannel(channel, config) {
11840
11958
  startTime: spanData.startTime
11841
11959
  });
11842
11960
  }
11843
- logErrorAndEnd(states, event);
11844
11961
  }
11845
11962
  };
11846
11963
  tracingChannel2.subscribe(handlers);
@@ -11857,7 +11974,8 @@ function traceSyncStreamChannel(channel, config) {
11857
11974
  tracingChannel2,
11858
11975
  states,
11859
11976
  config,
11860
- channelName
11977
+ channelName,
11978
+ channel.instrumentationName
11861
11979
  );
11862
11980
  const handlers = {
11863
11981
  start: (event) => {
@@ -11868,7 +11986,8 @@ function traceSyncStreamChannel(channel, config) {
11868
11986
  states,
11869
11987
  config,
11870
11988
  event,
11871
- channelName
11989
+ channelName,
11990
+ channel.instrumentationName
11872
11991
  );
11873
11992
  },
11874
11993
  end: (event) => {
@@ -11962,7 +12081,7 @@ function traceSyncStreamChannel(channel, config) {
11962
12081
  handleResolvedResult(endEvent.result);
11963
12082
  },
11964
12083
  error: (event) => {
11965
- logErrorAndEnd(states, event);
12084
+ logErrorAndEnd(states, event, channelName);
11966
12085
  }
11967
12086
  };
11968
12087
  tracingChannel2.subscribe(handlers);
@@ -12239,6 +12358,267 @@ function serializeAISDKToolsForLogging(tools) {
12239
12358
  return serialized;
12240
12359
  }
12241
12360
 
12361
+ // src/wrappers/ai-sdk/harness-agent-context.ts
12362
+ var BRAINTRUST_TURN_CONTEXT_KEY = "__braintrust_trace_context";
12363
+ var sessionTurnParents = /* @__PURE__ */ new WeakMap();
12364
+ var wrapperTurnParents = /* @__PURE__ */ new WeakMap();
12365
+ var patchedLifecycleMethods = /* @__PURE__ */ new WeakMap();
12366
+ var harnessTurnParentStore;
12367
+ function serializedTurnContext(value) {
12368
+ if (!isObject(value)) {
12369
+ return void 0;
12370
+ }
12371
+ const context = value[BRAINTRUST_TURN_CONTEXT_KEY];
12372
+ if (!isObject(context) || typeof context.parent !== "string" || typeof context.sessionId !== "string" || typeof context.signature !== "string") {
12373
+ return void 0;
12374
+ }
12375
+ const expectedSignature = signTurnContext({
12376
+ parent: context.parent,
12377
+ sessionId: context.sessionId
12378
+ });
12379
+ if (!expectedSignature || !isomorph_default.timingSafeEqual?.(context.signature, expectedSignature)) {
12380
+ return void 0;
12381
+ }
12382
+ const parent = SpanComponentsV4.fromStr(context.parent);
12383
+ if (!parent.data.row_id || !parent.data.root_span_id || !parent.data.span_id) {
12384
+ return void 0;
12385
+ }
12386
+ return {
12387
+ parent: context.parent,
12388
+ sessionId: context.sessionId
12389
+ };
12390
+ }
12391
+ function signTurnContext(context) {
12392
+ const secret = _internalGetGlobalState()._internalGetTraceContextSigningSecret();
12393
+ return secret ? isomorph_default.hmacSha256?.(
12394
+ secret,
12395
+ JSON.stringify([BRAINTRUST_TURN_CONTEXT_KEY, context])
12396
+ ) : void 0;
12397
+ }
12398
+ function continuationParentFromCreateSessionParams(params) {
12399
+ if (!isObject(params)) {
12400
+ return void 0;
12401
+ }
12402
+ const continuation = params.continueFrom ?? (isObject(params.resumeFrom) ? params.resumeFrom.continueFrom : void 0);
12403
+ const context = serializedTurnContext(continuation);
12404
+ if (!context) {
12405
+ return void 0;
12406
+ }
12407
+ if (params.sessionId !== context.sessionId) {
12408
+ return void 0;
12409
+ }
12410
+ return context.parent;
12411
+ }
12412
+ function exportSpanSynchronously(span) {
12413
+ const parentInfo = span.getParentInfo();
12414
+ if (!parentInfo) {
12415
+ return void 0;
12416
+ }
12417
+ const objectId = parentInfo.objectId.getSync().value;
12418
+ if (!objectId && !parentInfo.computeObjectMetadataArgs) {
12419
+ return void 0;
12420
+ }
12421
+ return new SpanComponentsV4({
12422
+ object_type: parentInfo.objectType,
12423
+ ...objectId ? { object_id: objectId } : {
12424
+ compute_object_metadata_args: parentInfo.computeObjectMetadataArgs ?? {}
12425
+ },
12426
+ row_id: span.id,
12427
+ root_span_id: span.rootSpanId,
12428
+ span_id: span.spanId
12429
+ }).toStr();
12430
+ }
12431
+ function exportedParent(parent) {
12432
+ return typeof parent === "string" ? parent : exportSpanSynchronously(parent);
12433
+ }
12434
+ function addSerializedContext(args) {
12435
+ if (!isObject(args.continuation) || args.sessionId === void 0) {
12436
+ return;
12437
+ }
12438
+ const parent = exportedParent(args.parent);
12439
+ if (!parent) {
12440
+ return;
12441
+ }
12442
+ const context = {
12443
+ parent,
12444
+ sessionId: args.sessionId
12445
+ };
12446
+ const signature = signTurnContext(context);
12447
+ if (!signature) {
12448
+ return;
12449
+ }
12450
+ Object.defineProperty(args.continuation, BRAINTRUST_TURN_CONTEXT_KEY, {
12451
+ configurable: true,
12452
+ enumerable: true,
12453
+ value: {
12454
+ ...context,
12455
+ signature
12456
+ },
12457
+ writable: true
12458
+ });
12459
+ }
12460
+ function lifecycleMethodDescriptor(session, method) {
12461
+ let owner = session;
12462
+ while (owner) {
12463
+ const descriptor = Object.getOwnPropertyDescriptor(owner, method);
12464
+ if (descriptor) {
12465
+ return { descriptor, owner };
12466
+ }
12467
+ owner = Object.getPrototypeOf(owner);
12468
+ }
12469
+ return void 0;
12470
+ }
12471
+ function patchLifecycleMethod(session, method) {
12472
+ let resolvedDescriptor;
12473
+ try {
12474
+ resolvedDescriptor = lifecycleMethodDescriptor(session, method);
12475
+ } catch {
12476
+ return;
12477
+ }
12478
+ if (!resolvedDescriptor || !("value" in resolvedDescriptor.descriptor) || typeof resolvedDescriptor.descriptor.value !== "function") {
12479
+ return;
12480
+ }
12481
+ const { descriptor, owner } = resolvedDescriptor;
12482
+ const patched = patchedLifecycleMethods.get(owner);
12483
+ if (patched?.has(method)) {
12484
+ return;
12485
+ }
12486
+ const original = descriptor.value;
12487
+ const replacement = function(...args) {
12488
+ const result = Reflect.apply(original, this, args);
12489
+ const addContext = (state) => {
12490
+ try {
12491
+ const parent = sessionTurnParents.get(this);
12492
+ if (!parent) {
12493
+ return;
12494
+ }
12495
+ const continuation = method === "suspendTurn" ? state : isObject(state) ? state.continueFrom : void 0;
12496
+ addSerializedContext({
12497
+ continuation,
12498
+ parent,
12499
+ sessionId: typeof this.sessionId === "string" ? this.sessionId : void 0
12500
+ });
12501
+ } catch {
12502
+ }
12503
+ };
12504
+ try {
12505
+ if (isObject(result) && typeof result.then === "function") {
12506
+ void Promise.resolve(result).then(addContext, () => {
12507
+ });
12508
+ } else {
12509
+ addContext(result);
12510
+ }
12511
+ } catch {
12512
+ }
12513
+ return result;
12514
+ };
12515
+ try {
12516
+ Object.defineProperty(owner, method, {
12517
+ ...descriptor,
12518
+ value: replacement
12519
+ });
12520
+ const ownerMethods = patched ?? /* @__PURE__ */ new Set();
12521
+ ownerMethods.add(method);
12522
+ if (!patched) {
12523
+ patchedLifecycleMethods.set(owner, ownerMethods);
12524
+ }
12525
+ } catch {
12526
+ }
12527
+ }
12528
+ function patchLifecycleMethods(session) {
12529
+ patchLifecycleMethod(session, "suspendTurn");
12530
+ patchLifecycleMethod(session, "detach");
12531
+ patchLifecycleMethod(session, "stop");
12532
+ }
12533
+ function registerHarnessTurnSpan(args) {
12534
+ if (!isObject(args.session)) {
12535
+ return;
12536
+ }
12537
+ const session = args.session;
12538
+ sessionTurnParents.set(session, args.span);
12539
+ wrapperTurnParents.set(args.span, args.span);
12540
+ patchLifecycleMethods(session);
12541
+ }
12542
+ function harnessContinuationParent(session) {
12543
+ return isObject(session) ? sessionTurnParents.get(session) : void 0;
12544
+ }
12545
+ function captureHarnessCreateSessionParent(params) {
12546
+ try {
12547
+ return continuationParentFromCreateSessionParams(params);
12548
+ } catch {
12549
+ return void 0;
12550
+ }
12551
+ }
12552
+ function registerHarnessSessionParent(session, parent) {
12553
+ if (!parent || !isObject(session)) {
12554
+ return;
12555
+ }
12556
+ const harnessSession = session;
12557
+ sessionTurnParents.set(harnessSession, parent);
12558
+ patchLifecycleMethods(harnessSession);
12559
+ }
12560
+ function currentHarnessTurnParent() {
12561
+ return harnessTurnParentStore?.getStore() ?? wrapperTurnParents.get(currentSpan());
12562
+ }
12563
+ function bindHarnessTurnParentToStart(tracingChannel2, parentFromEvent) {
12564
+ const startChannel = tracingChannel2.start;
12565
+ if (!startChannel) {
12566
+ return () => {
12567
+ };
12568
+ }
12569
+ harnessTurnParentStore ??= isomorph_default.newAsyncLocalStorage();
12570
+ const store = harnessTurnParentStore;
12571
+ startChannel.bindStore(
12572
+ store,
12573
+ (event) => parentFromEvent(event) ?? store.getStore()
12574
+ );
12575
+ return () => {
12576
+ startChannel.unbindStore(store);
12577
+ };
12578
+ }
12579
+ function startHarnessTurnChildSpan(parent, args) {
12580
+ const spanArgs = withSpanInstrumentationName(
12581
+ args,
12582
+ INSTRUMENTATION_NAMES.AI_SDK
12583
+ );
12584
+ return typeof parent === "string" ? startSpan({ ...spanArgs, parent }) : parent.startSpan(spanArgs);
12585
+ }
12586
+ function updateHarnessTurn(parent, update = {}) {
12587
+ if (!parent) {
12588
+ return;
12589
+ }
12590
+ const log2 = (event) => {
12591
+ if (typeof parent === "string") {
12592
+ updateSpan({ exported: parent, ...event });
12593
+ } else {
12594
+ parent.log(event);
12595
+ }
12596
+ };
12597
+ try {
12598
+ if (Object.prototype.hasOwnProperty.call(update, "output")) {
12599
+ log2({ output: null });
12600
+ }
12601
+ log2(update);
12602
+ } catch {
12603
+ }
12604
+ }
12605
+ function endHarnessTurn(parent) {
12606
+ const endTime = getCurrentUnixTimestamp();
12607
+ if (!parent) {
12608
+ return endTime;
12609
+ }
12610
+ try {
12611
+ const event = { metrics: { end: endTime } };
12612
+ if (typeof parent === "string") {
12613
+ updateSpan({ exported: parent, ...event });
12614
+ } else {
12615
+ parent.log(event);
12616
+ }
12617
+ } catch {
12618
+ }
12619
+ return endTime;
12620
+ }
12621
+
12242
12622
  // src/wrappers/ai-sdk/workflow-agent-context.ts
12243
12623
  var workflowAgentWrapperSpans = /* @__PURE__ */ new Map();
12244
12624
  function registerWorkflowAgentWrapperSpan(span) {
@@ -12342,6 +12722,17 @@ var AISDKPlugin = class extends BasePlugin {
12342
12722
  subscribeToAISDK() {
12343
12723
  const denyOutputPaths = this.config.denyOutputPaths || DEFAULT_DENY_OUTPUT_PATHS;
12344
12724
  this.unsubscribers.push(subscribeToAISDKV7TelemetryDispatcher());
12725
+ this.unsubscribers.push(subscribeToHarnessAgentCreateSession());
12726
+ this.unsubscribers.push(
12727
+ subscribeToHarnessContinuation(
12728
+ harnessAgentChannels.continueGenerate,
12729
+ denyOutputPaths
12730
+ ),
12731
+ subscribeToHarnessContinuation(
12732
+ harnessAgentChannels.continueStream,
12733
+ denyOutputPaths
12734
+ )
12735
+ );
12345
12736
  this.unsubscribers.push(
12346
12737
  traceStreamingChannel(aiSDKChannels.generateText, {
12347
12738
  name: "generateText",
@@ -12535,48 +12926,132 @@ var AISDKPlugin = class extends BasePlugin {
12535
12926
  })
12536
12927
  );
12537
12928
  this.unsubscribers.push(
12538
- traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
12539
- name: "ToolLoopAgent.generate",
12540
- type: "function" /* FUNCTION */,
12541
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
12542
- agentOwner: true
12543
- }),
12544
- extractOutput: (result, endEvent) => {
12545
- finalizeAISDKChildTracing(endEvent);
12546
- return processAISDKOutput(
12547
- result,
12548
- resolveDenyOutputPaths(endEvent, denyOutputPaths)
12549
- );
12550
- },
12551
- extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
12929
+ traceStreamingChannel(harnessAgentChannels.generate, {
12930
+ name: "HarnessAgent.generate",
12931
+ startSpan: _internalStartSpanWithInitialMerge,
12932
+ type: "task" /* TASK */,
12933
+ extractInput: ([params], event, span) => prepareAISDKHarnessAgentInput(params, event.self, span),
12934
+ extractOutput: (result, endEvent) => processAISDKOutput(
12935
+ result,
12936
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
12937
+ ),
12938
+ extractMetrics: (result) => extractTokenMetrics(result),
12552
12939
  aggregateChunks: aggregateAISDKChunks
12553
12940
  })
12554
12941
  );
12555
12942
  this.unsubscribers.push(
12556
- traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
12557
- name: "ToolLoopAgent.stream",
12558
- type: "function" /* FUNCTION */,
12559
- extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
12560
- agentOwner: true
12561
- }),
12943
+ traceStreamingChannel(harnessAgentChannels.stream, {
12944
+ name: "HarnessAgent.stream",
12945
+ startSpan: _internalStartSpanWithInitialMerge,
12946
+ type: "task" /* TASK */,
12947
+ extractInput: ([params], event, span) => prepareAISDKHarnessAgentInput(params, event.self, span),
12562
12948
  extractOutput: (result, endEvent) => processAISDKOutput(
12563
12949
  result,
12564
12950
  resolveDenyOutputPaths(endEvent, denyOutputPaths)
12565
12951
  ),
12566
- extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
12952
+ extractMetrics: (result, startTime) => ({
12953
+ ...extractTokenMetrics(result),
12954
+ ...startTime === void 0 ? {} : {
12955
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
12956
+ }
12957
+ }),
12567
12958
  aggregateChunks: aggregateAISDKChunks,
12568
12959
  patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
12569
12960
  defaultDenyOutputPaths: denyOutputPaths,
12570
12961
  endEvent,
12571
12962
  result,
12963
+ resolvePromiseUsage: true,
12572
12964
  span,
12573
12965
  startTime
12574
12966
  })
12575
12967
  })
12576
12968
  );
12577
12969
  this.unsubscribers.push(
12578
- traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
12579
- name: "WorkflowAgent.stream",
12970
+ traceStreamingChannel(harnessAgentChannels.continueGenerate, {
12971
+ name: "HarnessAgent.continueGenerate",
12972
+ shouldTrace: (args) => !harnessContinuationParent(harnessSessionFromArguments(args)),
12973
+ startSpan: _internalStartSpanWithInitialMerge,
12974
+ type: "task" /* TASK */,
12975
+ extractInput: ([params], event, span) => prepareAISDKHarnessAgentInput(params, event.self, span),
12976
+ extractOutput: (result, endEvent) => processAISDKOutput(
12977
+ result,
12978
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
12979
+ ),
12980
+ extractMetrics: (result) => extractTokenMetrics(result),
12981
+ aggregateChunks: aggregateAISDKChunks
12982
+ })
12983
+ );
12984
+ this.unsubscribers.push(
12985
+ traceStreamingChannel(harnessAgentChannels.continueStream, {
12986
+ name: "HarnessAgent.continueStream",
12987
+ shouldTrace: (args) => !harnessContinuationParent(harnessSessionFromArguments(args)),
12988
+ startSpan: _internalStartSpanWithInitialMerge,
12989
+ type: "task" /* TASK */,
12990
+ extractInput: ([params], event, span) => prepareAISDKHarnessAgentInput(params, event.self, span),
12991
+ extractOutput: (result, endEvent) => processAISDKOutput(
12992
+ result,
12993
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
12994
+ ),
12995
+ extractMetrics: (result, startTime) => ({
12996
+ ...extractTokenMetrics(result),
12997
+ ...startTime === void 0 ? {} : {
12998
+ time_to_first_token: getCurrentUnixTimestamp() - startTime
12999
+ }
13000
+ }),
13001
+ aggregateChunks: aggregateAISDKChunks,
13002
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13003
+ defaultDenyOutputPaths: denyOutputPaths,
13004
+ endEvent,
13005
+ result,
13006
+ resolvePromiseUsage: true,
13007
+ span,
13008
+ startTime
13009
+ })
13010
+ })
13011
+ );
13012
+ this.unsubscribers.push(
13013
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
13014
+ name: "ToolLoopAgent.generate",
13015
+ type: "function" /* FUNCTION */,
13016
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13017
+ agentOwner: true
13018
+ }),
13019
+ extractOutput: (result, endEvent) => {
13020
+ finalizeAISDKChildTracing(endEvent);
13021
+ return processAISDKOutput(
13022
+ result,
13023
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13024
+ );
13025
+ },
13026
+ extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
13027
+ aggregateChunks: aggregateAISDKChunks
13028
+ })
13029
+ );
13030
+ this.unsubscribers.push(
13031
+ traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
13032
+ name: "ToolLoopAgent.stream",
13033
+ type: "function" /* FUNCTION */,
13034
+ extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths, {
13035
+ agentOwner: true
13036
+ }),
13037
+ extractOutput: (result, endEvent) => processAISDKOutput(
13038
+ result,
13039
+ resolveDenyOutputPaths(endEvent, denyOutputPaths)
13040
+ ),
13041
+ extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
13042
+ aggregateChunks: aggregateAISDKChunks,
13043
+ patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
13044
+ defaultDenyOutputPaths: denyOutputPaths,
13045
+ endEvent,
13046
+ result,
13047
+ span,
13048
+ startTime
13049
+ })
13050
+ })
13051
+ );
13052
+ this.unsubscribers.push(
13053
+ traceStreamingChannel(aiSDKChannels.workflowAgentStream, {
13054
+ name: "WorkflowAgent.stream",
12580
13055
  type: "function" /* FUNCTION */,
12581
13056
  extractInput: ([params], event, span) => prepareAISDKWorkflowAgentStreamInput(
12582
13057
  params,
@@ -12604,6 +13079,8 @@ var AISDKPlugin = class extends BasePlugin {
12604
13079
  defaultDenyOutputPaths: denyOutputPaths,
12605
13080
  endEvent,
12606
13081
  onComplete: () => unregisterWorkflowAgentWrapperSpan(span),
13082
+ onCancel: () => unregisterWorkflowAgentWrapperSpan(span),
13083
+ onError: () => unregisterWorkflowAgentWrapperSpan(span),
12607
13084
  result,
12608
13085
  span,
12609
13086
  startTime
@@ -12612,6 +13089,153 @@ var AISDKPlugin = class extends BasePlugin {
12612
13089
  );
12613
13090
  }
12614
13091
  };
13092
+ function subscribeToHarnessAgentCreateSession() {
13093
+ const channel = harnessAgentChannels.createSession.tracingChannel();
13094
+ const parents = /* @__PURE__ */ new WeakMap();
13095
+ const handlers = {
13096
+ start: (event) => {
13097
+ const parent = captureHarnessCreateSessionParent(event.arguments?.[0]);
13098
+ if (parent) {
13099
+ parents.set(event, parent);
13100
+ }
13101
+ },
13102
+ asyncEnd: (event) => {
13103
+ registerHarnessSessionParent(event.result, parents.get(event));
13104
+ parents.delete(event);
13105
+ },
13106
+ error: (event) => {
13107
+ parents.delete(event);
13108
+ }
13109
+ };
13110
+ channel.subscribe(handlers);
13111
+ return () => channel.unsubscribe(handlers);
13112
+ }
13113
+ function harnessContinuationParentFromEvent(event) {
13114
+ try {
13115
+ return harnessContinuationParent(event.arguments?.[0]?.session);
13116
+ } catch {
13117
+ return void 0;
13118
+ }
13119
+ }
13120
+ function subscribeToHarnessContinuation(continuationChannel, defaultDenyOutputPaths) {
13121
+ const channel = continuationChannel.tracingChannel();
13122
+ const parents = /* @__PURE__ */ new WeakMap();
13123
+ const startTimes = /* @__PURE__ */ new WeakMap();
13124
+ const unbindParentStore = bindHarnessTurnParentToStart(
13125
+ channel,
13126
+ harnessContinuationParentFromEvent
13127
+ );
13128
+ const handlers = {
13129
+ start: (event) => {
13130
+ const parent = harnessContinuationParentFromEvent(event);
13131
+ if (!parent) {
13132
+ return;
13133
+ }
13134
+ parents.set(event, parent);
13135
+ startTimes.set(event, getCurrentUnixTimestamp());
13136
+ try {
13137
+ const params = event.arguments?.[0];
13138
+ if (params) {
13139
+ prepareAISDKHarnessAgentInput(params, event.self);
13140
+ }
13141
+ } catch (error) {
13142
+ debugLogger.error(
13143
+ "Error preparing Harness continuation telemetry:",
13144
+ error
13145
+ );
13146
+ }
13147
+ },
13148
+ asyncEnd: (event) => {
13149
+ const parent = parents.get(event);
13150
+ const startTime = startTimes.get(event) ?? getCurrentUnixTimestamp();
13151
+ parents.delete(event);
13152
+ startTimes.delete(event);
13153
+ if (!parent) {
13154
+ return;
13155
+ }
13156
+ const endEvent = event;
13157
+ const span = {
13158
+ end: () => endHarnessTurn(parent),
13159
+ log: (update) => updateHarnessTurn(
13160
+ parent,
13161
+ Object.prototype.hasOwnProperty.call(update, "error") && !Object.prototype.hasOwnProperty.call(update, "output") ? { ...update, output: null } : update
13162
+ )
13163
+ };
13164
+ try {
13165
+ if (isAsyncIterable(endEvent.result)) {
13166
+ patchStreamIfNeeded(endEvent.result, {
13167
+ onComplete: (chunks) => {
13168
+ try {
13169
+ const { metadata, metrics, output } = aggregateAISDKChunks(
13170
+ chunks,
13171
+ endEvent.result,
13172
+ endEvent
13173
+ );
13174
+ span.log({
13175
+ ...metadata ? { metadata } : {},
13176
+ metrics,
13177
+ output
13178
+ });
13179
+ } catch (error) {
13180
+ debugLogger.error(
13181
+ "Error aggregating Harness continuation stream:",
13182
+ error
13183
+ );
13184
+ } finally {
13185
+ span.end();
13186
+ }
13187
+ },
13188
+ onError: (error) => {
13189
+ span.log({ error: toLoggedError(error), output: null });
13190
+ span.end();
13191
+ }
13192
+ });
13193
+ return;
13194
+ }
13195
+ if (patchAISDKStreamingResult({
13196
+ defaultDenyOutputPaths,
13197
+ endEvent,
13198
+ result: endEvent.result,
13199
+ resolvePromiseUsage: true,
13200
+ span,
13201
+ startTime
13202
+ })) {
13203
+ return;
13204
+ }
13205
+ finalizeAISDKChildTracing(endEvent);
13206
+ span.log({
13207
+ metrics: extractTokenMetrics(endEvent.result),
13208
+ output: processAISDKOutput(
13209
+ endEvent.result,
13210
+ resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
13211
+ )
13212
+ });
13213
+ span.end();
13214
+ } catch (error) {
13215
+ debugLogger.error("Error tracing Harness continuation:", error);
13216
+ span.end();
13217
+ }
13218
+ },
13219
+ error: (event) => {
13220
+ const parent = parents.get(event);
13221
+ parents.delete(event);
13222
+ startTimes.delete(event);
13223
+ if (!parent) {
13224
+ return;
13225
+ }
13226
+ updateHarnessTurn(parent, {
13227
+ error: toLoggedError(event.error),
13228
+ output: null
13229
+ });
13230
+ endHarnessTurn(parent);
13231
+ }
13232
+ };
13233
+ channel.subscribe(handlers);
13234
+ return () => {
13235
+ unbindParentStore();
13236
+ channel.unsubscribe(handlers);
13237
+ };
13238
+ }
12615
13239
  function subscribeToAISDKV7TelemetryDispatcher() {
12616
13240
  const channel = aiSDKChannels.v7CreateTelemetryDispatcher.tracingChannel();
12617
13241
  const telemetry = braintrustAISDKTelemetry();
@@ -13064,6 +13688,55 @@ function prepareAISDKCallInput(params, event, span, defaultDenyOutputPaths, chil
13064
13688
  metadata
13065
13689
  };
13066
13690
  }
13691
+ function prepareAISDKHarnessAgentInput(params, self, span) {
13692
+ if (span) {
13693
+ registerHarnessTurnSpan({
13694
+ session: params.session,
13695
+ span
13696
+ });
13697
+ }
13698
+ if (isObject(self)) {
13699
+ try {
13700
+ if (isObject(self.settings)) {
13701
+ const settings = self.settings;
13702
+ if (settings.telemetry === void 0) {
13703
+ Reflect.set(self, "settings", { ...settings, telemetry: {} });
13704
+ }
13705
+ }
13706
+ } catch {
13707
+ }
13708
+ }
13709
+ const selectedInput = {};
13710
+ if (params.prompt !== void 0) {
13711
+ selectedInput.prompt = params.prompt;
13712
+ }
13713
+ if (params.messages !== void 0) {
13714
+ selectedInput.messages = params.messages;
13715
+ }
13716
+ if (params.toolApprovalContinuations !== void 0) {
13717
+ selectedInput.toolApprovalContinuations = params.toolApprovalContinuations;
13718
+ }
13719
+ const metadata = extractMetadataFromCallParams({}, self);
13720
+ if (isObject(params.session) && typeof params.session.sessionId === "string") {
13721
+ metadata.sessionId = params.session.sessionId;
13722
+ }
13723
+ if (isObject(self)) {
13724
+ if (typeof self.harnessId === "string") {
13725
+ metadata.harnessId = self.harnessId;
13726
+ }
13727
+ if (typeof self.permissionMode === "string") {
13728
+ metadata.permissionMode = self.permissionMode;
13729
+ }
13730
+ }
13731
+ return {
13732
+ input: processAISDKCallInput(selectedInput).input,
13733
+ metadata
13734
+ };
13735
+ }
13736
+ function harnessSessionFromArguments(args) {
13737
+ const params = args[0];
13738
+ return isObject(params) ? params.session : void 0;
13739
+ }
13067
13740
  function prepareAISDKWorkflowAgentStreamInput(params, event, span, defaultDenyOutputPaths) {
13068
13741
  registerWorkflowAgentWrapperSpan(span);
13069
13742
  const { input } = processAISDKWorkflowAgentCallInput(params);
@@ -13511,19 +14184,22 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
13511
14184
  activeEntry.openSpans.delete(span);
13512
14185
  }
13513
14186
  },
13514
- {
13515
- name: "doGenerate",
13516
- spanAttributes: {
13517
- type: "llm" /* LLM */
14187
+ withSpanInstrumentationName(
14188
+ {
14189
+ name: "doGenerate",
14190
+ spanAttributes: {
14191
+ type: "llm" /* LLM */
14192
+ },
14193
+ event: buildAISDKModelStartEvent(
14194
+ callOptions,
14195
+ activeEntry.baseMetadata,
14196
+ {
14197
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
14198
+ }
14199
+ )
13518
14200
  },
13519
- event: buildAISDKModelStartEvent(
13520
- callOptions,
13521
- activeEntry.baseMetadata,
13522
- {
13523
- workflowAgent: activeEntry.childTracingOptions.workflowAgent
13524
- }
13525
- )
13526
- }
14201
+ INSTRUMENTATION_NAMES.AI_SDK
14202
+ )
13527
14203
  );
13528
14204
  };
13529
14205
  if (originalDoStream) {
@@ -13533,19 +14209,24 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
13533
14209
  return Reflect.apply(originalDoStream, resolvedModel, [callOptions]);
13534
14210
  }
13535
14211
  closeOpenAISDKModelPatchSpans(activeEntry);
13536
- const span = activeEntry.parentSpan.startSpan({
13537
- name: "doStream",
13538
- spanAttributes: {
13539
- type: "llm" /* LLM */
13540
- },
13541
- event: buildAISDKModelStartEvent(
13542
- callOptions,
13543
- activeEntry.baseMetadata,
14212
+ const span = activeEntry.parentSpan.startSpan(
14213
+ withSpanInstrumentationName(
13544
14214
  {
13545
- workflowAgent: activeEntry.childTracingOptions.workflowAgent
13546
- }
14215
+ name: "doStream",
14216
+ spanAttributes: {
14217
+ type: "llm" /* LLM */
14218
+ },
14219
+ event: buildAISDKModelStartEvent(
14220
+ callOptions,
14221
+ activeEntry.baseMetadata,
14222
+ {
14223
+ workflowAgent: activeEntry.childTracingOptions.workflowAgent
14224
+ }
14225
+ )
14226
+ },
14227
+ INSTRUMENTATION_NAMES.AI_SDK
13547
14228
  )
13548
- });
14229
+ );
13549
14230
  activeEntry.openSpans.add(span);
13550
14231
  const streamStartTime = getCurrentUnixTimestamp();
13551
14232
  const result = await withCurrent(
@@ -13717,12 +14398,17 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
13717
14398
  }
13718
14399
  if (isAsyncGenerator(result)) {
13719
14400
  return (async function* () {
13720
- const span = activeEntry.parentSpan.startSpan({
13721
- name: activeEntry.name,
13722
- spanAttributes: {
13723
- type: "tool" /* TOOL */
13724
- }
13725
- });
14401
+ const span = activeEntry.parentSpan.startSpan(
14402
+ withSpanInstrumentationName(
14403
+ {
14404
+ name: activeEntry.name,
14405
+ spanAttributes: {
14406
+ type: "tool" /* TOOL */
14407
+ }
14408
+ },
14409
+ INSTRUMENTATION_NAMES.AI_SDK
14410
+ )
14411
+ );
13726
14412
  span.log({ input: serializeToolExecutionInput(args) });
13727
14413
  try {
13728
14414
  let lastValue;
@@ -13746,12 +14432,15 @@ function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiS
13746
14432
  span.log({ output: awaitedResult });
13747
14433
  return awaitedResult;
13748
14434
  },
13749
- {
13750
- name: activeEntry.name,
13751
- spanAttributes: {
13752
- type: "tool" /* TOOL */
13753
- }
13754
- }
14435
+ withSpanInstrumentationName(
14436
+ {
14437
+ name: activeEntry.name,
14438
+ spanAttributes: {
14439
+ type: "tool" /* TOOL */
14440
+ }
14441
+ },
14442
+ INSTRUMENTATION_NAMES.AI_SDK
14443
+ )
13755
14444
  );
13756
14445
  };
13757
14446
  cleanup.push(() => {
@@ -13910,7 +14599,10 @@ function patchAISDKStreamingResult(args) {
13910
14599
  defaultDenyOutputPaths,
13911
14600
  endEvent,
13912
14601
  onComplete,
14602
+ onCancel,
14603
+ onError,
13913
14604
  result,
14605
+ resolvePromiseUsage,
13914
14606
  span,
13915
14607
  startTime
13916
14608
  } = args;
@@ -13920,14 +14612,43 @@ function patchAISDKStreamingResult(args) {
13920
14612
  const resultRecord = result;
13921
14613
  attachKnownResultPromiseHandlers(resultRecord);
13922
14614
  let finalized = false;
13923
- const finalize = () => {
14615
+ const finalize = (outcome) => {
13924
14616
  if (finalized) {
13925
14617
  return;
13926
14618
  }
13927
14619
  finalized = true;
13928
- finalizeAISDKChildTracing(endEvent);
13929
- span.end();
13930
- onComplete?.();
14620
+ try {
14621
+ finalizeAISDKChildTracing(endEvent);
14622
+ } catch (error) {
14623
+ debugLogger.error("Error finalizing AI SDK child tracing:", error);
14624
+ }
14625
+ try {
14626
+ span.end();
14627
+ } catch (error) {
14628
+ debugLogger.error("Error ending AI SDK streaming span:", error);
14629
+ }
14630
+ if (outcome && "error" in outcome) {
14631
+ try {
14632
+ onError?.(outcome.error);
14633
+ } catch (error) {
14634
+ debugLogger.error("Error in AI SDK streaming error hook:", error);
14635
+ }
14636
+ } else if (outcome) {
14637
+ try {
14638
+ onComplete?.(outcome);
14639
+ } catch (error) {
14640
+ debugLogger.error("Error in AI SDK streaming completion hook:", error);
14641
+ }
14642
+ } else {
14643
+ try {
14644
+ onCancel?.();
14645
+ } catch (error) {
14646
+ debugLogger.error(
14647
+ "Error in AI SDK streaming cancellation hook:",
14648
+ error
14649
+ );
14650
+ }
14651
+ }
13931
14652
  };
13932
14653
  let outputLogged = false;
13933
14654
  const logStreamingOutput = async (firstChunkTime) => {
@@ -13937,6 +14658,22 @@ function patchAISDKStreamingResult(args) {
13937
14658
  outputLogged = true;
13938
14659
  try {
13939
14660
  const metrics = extractTopLevelAISDKMetrics(result, endEvent);
14661
+ if (resolvePromiseUsage) {
14662
+ try {
14663
+ const resultRecord2 = result;
14664
+ const pendingUsage = resultRecord2.totalUsage ?? resultRecord2.usage;
14665
+ if (isPromiseLike(pendingUsage)) {
14666
+ const usage = await Promise.resolve(pendingUsage);
14667
+ if (isObject(usage)) {
14668
+ Object.assign(
14669
+ metrics,
14670
+ extractTokenMetrics({ usage })
14671
+ );
14672
+ }
14673
+ }
14674
+ } catch {
14675
+ }
14676
+ }
13940
14677
  if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
13941
14678
  metrics.time_to_first_token = firstChunkTime - startTime;
13942
14679
  }
@@ -13945,15 +14682,29 @@ function patchAISDKStreamingResult(args) {
13945
14682
  resolveDenyOutputPaths(endEvent, defaultDenyOutputPaths)
13946
14683
  );
13947
14684
  const metadata = buildResolvedMetadataPayload(result).metadata;
13948
- span.log({
13949
- output,
13950
- ...metadata ? { metadata } : {},
13951
- metrics
13952
- });
14685
+ try {
14686
+ span.log({
14687
+ output,
14688
+ ...metadata ? { metadata } : {},
14689
+ metrics
14690
+ });
14691
+ } catch (error) {
14692
+ debugLogger.error("Error logging AI SDK streaming output:", error);
14693
+ }
14694
+ finalize({ metrics, output });
13953
14695
  } catch (error) {
13954
- span.log({ error: toLoggedError(error) });
13955
- } finally {
13956
- finalize();
14696
+ const loggedError = toLoggedError(error);
14697
+ try {
14698
+ span.log({ error: loggedError });
14699
+ } catch (loggingError) {
14700
+ debugLogger.error(
14701
+ "Error logging AI SDK streaming failure:",
14702
+ loggingError
14703
+ );
14704
+ }
14705
+ finalize({
14706
+ error: error instanceof Error ? error : new Error(String(loggedError))
14707
+ });
13957
14708
  }
13958
14709
  };
13959
14710
  const createAsyncIterableHooks = () => {
@@ -13970,11 +14721,16 @@ function patchAISDKStreamingResult(args) {
13970
14721
  onError: (error) => {
13971
14722
  if (!outputLogged) {
13972
14723
  outputLogged = true;
13973
- span.log({
13974
- error: error.message
13975
- });
14724
+ try {
14725
+ span.log({ error });
14726
+ } catch (loggingError) {
14727
+ debugLogger.error(
14728
+ "Error logging AI SDK stream failure:",
14729
+ loggingError
14730
+ );
14731
+ }
13976
14732
  }
13977
- finalize();
14733
+ finalize({ error });
13978
14734
  },
13979
14735
  onCancel: finalize
13980
14736
  };
@@ -14060,8 +14816,18 @@ function patchAISDKStreamingResult(args) {
14060
14816
  }
14061
14817
  controller.enqueue(value);
14062
14818
  } catch (error) {
14063
- span.log({ error: toLoggedError(error) });
14064
- finalize();
14819
+ const loggedError = toLoggedError(error);
14820
+ try {
14821
+ span.log({ error: loggedError });
14822
+ } catch (loggingError) {
14823
+ debugLogger.error(
14824
+ "Error logging AI SDK base stream failure:",
14825
+ loggingError
14826
+ );
14827
+ }
14828
+ finalize({
14829
+ error: error instanceof Error ? error : new Error(String(loggedError))
14830
+ });
14065
14831
  controller.error(error);
14066
14832
  }
14067
14833
  },
@@ -14860,14 +15626,17 @@ function braintrustAISDKTelemetry() {
14860
15626
  console.error(`Error in Braintrust AI SDK telemetry ${name}:`, error);
14861
15627
  }
14862
15628
  };
14863
- const startChildSpan = (operationKey, name, type, event) => {
15629
+ const startChildSpan = (operationKey, name, type, event, parentOverride) => {
14864
15630
  const parent = operations.get(operationKey)?.span;
14865
- const spanArgs = {
14866
- name,
14867
- spanAttributes: { type },
14868
- ...event ? { event } : {}
14869
- };
14870
- const span = parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
15631
+ const spanArgs = withSpanInstrumentationName(
15632
+ {
15633
+ name,
15634
+ spanAttributes: { type },
15635
+ ...event ? { event } : {}
15636
+ },
15637
+ INSTRUMENTATION_NAMES.AI_SDK
15638
+ );
15639
+ const span = parentOverride ? startHarnessTurnChildSpan(parentOverride, spanArgs) : parent ? parent.startSpan(spanArgs) : startSpan(spanArgs);
14871
15640
  const state = operations.get(operationKey);
14872
15641
  if (state && type === "llm" /* LLM */) {
14873
15642
  state.hadModelChild = true;
@@ -15147,14 +15916,30 @@ function braintrustAISDKTelemetry() {
15147
15916
  const workflowAgent = operationName === "WorkflowAgent.stream";
15148
15917
  const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() : void 0;
15149
15918
  const ownsSpan = !wrapperSpan;
15150
- const span = ownsSpan ? startSpan({
15151
- name: operationName,
15152
- spanAttributes: { type: "function" /* FUNCTION */ }
15153
- }) : wrapperSpan;
15919
+ const harnessTurnParent = currentHarnessTurnParent();
15920
+ const span = ownsSpan ? harnessTurnParent ? startHarnessTurnChildSpan(
15921
+ harnessTurnParent,
15922
+ withSpanInstrumentationName(
15923
+ {
15924
+ name: operationName,
15925
+ spanAttributes: { type: "function" /* FUNCTION */ }
15926
+ },
15927
+ INSTRUMENTATION_NAMES.AI_SDK
15928
+ )
15929
+ ) : startSpan(
15930
+ withSpanInstrumentationName(
15931
+ {
15932
+ name: operationName,
15933
+ spanAttributes: { type: "function" /* FUNCTION */ }
15934
+ },
15935
+ INSTRUMENTATION_NAMES.AI_SDK
15936
+ )
15937
+ ) : wrapperSpan;
15154
15938
  const operationKey = createOperationKey(event, operationName);
15155
15939
  registerOperation({
15156
15940
  callId: event.callId,
15157
15941
  hadModelChild: false,
15942
+ harnessTurnParent,
15158
15943
  loggedInput: false,
15159
15944
  operationName,
15160
15945
  operationKey,
@@ -15395,7 +16180,8 @@ function braintrustAISDKTelemetry() {
15395
16180
  toolCallId,
15396
16181
  ...typeof event.toolCall.toolName === "string" ? { toolName: event.toolCall.toolName } : {}
15397
16182
  }
15398
- }
16183
+ },
16184
+ state?.harnessTurnParent
15399
16185
  );
15400
16186
  toolSpans.set(toolCallId, { operationKey, span });
15401
16187
  });
@@ -15971,15 +16757,20 @@ var FlueObserveBridge = class {
15971
16757
  safeLog(existing.span, { input, metadata });
15972
16758
  return;
15973
16759
  }
15974
- const span = startSpan({
15975
- name: `workflow:${workflowName}`,
15976
- spanAttributes: { type: "task" /* TASK */ },
15977
- startTime: eventTime(event.startedAt ?? event.timestamp),
15978
- event: {
15979
- input,
15980
- metadata
15981
- }
15982
- });
16760
+ const span = startSpan(
16761
+ withSpanInstrumentationName(
16762
+ {
16763
+ name: `workflow:${workflowName}`,
16764
+ spanAttributes: { type: "task" /* TASK */ },
16765
+ startTime: eventTime(event.startedAt ?? event.timestamp),
16766
+ event: {
16767
+ input,
16768
+ metadata
16769
+ }
16770
+ },
16771
+ INSTRUMENTATION_NAMES.FLUE
16772
+ )
16773
+ );
15983
16774
  this.runsById.set(event.runId, { metadata, span });
15984
16775
  }
15985
16776
  handleRunResume(event, ctx) {
@@ -15999,12 +16790,17 @@ var FlueObserveBridge = class {
15999
16790
  safeLog(existing.span, { metadata });
16000
16791
  return;
16001
16792
  }
16002
- const span = startSpan({
16003
- name: `workflow:${workflowName}`,
16004
- spanAttributes: { type: "task" /* TASK */ },
16005
- startTime: eventTime(event.startedAt ?? event.timestamp),
16006
- event: { metadata }
16007
- });
16793
+ const span = startSpan(
16794
+ withSpanInstrumentationName(
16795
+ {
16796
+ name: `workflow:${workflowName}`,
16797
+ spanAttributes: { type: "task" /* TASK */ },
16798
+ startTime: eventTime(event.startedAt ?? event.timestamp),
16799
+ event: { metadata }
16800
+ },
16801
+ INSTRUMENTATION_NAMES.FLUE
16802
+ )
16803
+ );
16008
16804
  this.runsById.set(event.runId, { metadata, span });
16009
16805
  }
16010
16806
  handleRunEnd(event) {
@@ -16643,7 +17439,14 @@ function stateMatchesRun(state, runId) {
16643
17439
  return state.metadata["flue.run_id"] === runId;
16644
17440
  }
16645
17441
  function startFlueSpan(parent, args) {
16646
- return parent ? withCurrent(parent, () => startSpan(args)) : startSpan(args);
17442
+ return parent ? withCurrent(
17443
+ parent,
17444
+ () => startSpan(
17445
+ withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE)
17446
+ )
17447
+ ) : startSpan(
17448
+ withSpanInstrumentationName(args, INSTRUMENTATION_NAMES.FLUE)
17449
+ );
16647
17450
  }
16648
17451
  function runWithCurrentSpanStore(span, next) {
16649
17452
  const state = _internalGetGlobalState();
@@ -16733,9 +17536,13 @@ var BraintrustLangChainCallbackHandler = class {
16733
17536
  ...this.options.debug ? { runId, parentRunId } : {}
16734
17537
  }
16735
17538
  };
16736
- let span = parentSpan.startSpan(args);
17539
+ const spanArgs = withSpanInstrumentationName(
17540
+ args,
17541
+ INSTRUMENTATION_NAMES.LANGCHAIN
17542
+ );
17543
+ let span = parentSpan.startSpan(spanArgs);
16737
17544
  if (!Object.is(this.options.logger, NOOP_SPAN) && Object.is(span, NOOP_SPAN)) {
16738
- span = initLogger().startSpan(args);
17545
+ span = initLogger().startSpan(spanArgs);
16739
17546
  }
16740
17547
  this.spans.set(runId, span);
16741
17548
  }
@@ -16948,6 +17755,16 @@ function cleanObject(obj) {
16948
17755
  })
16949
17756
  );
16950
17757
  }
17758
+ function normalizeTokenMetrics(obj) {
17759
+ const metrics = cleanObject(obj);
17760
+ if (metrics.total_tokens !== void 0) {
17761
+ metrics.tokens = metrics.total_tokens;
17762
+ } else if (metrics.prompt_tokens !== void 0 && metrics.completion_tokens !== void 0) {
17763
+ metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
17764
+ }
17765
+ delete metrics.total_tokens;
17766
+ return metrics;
17767
+ }
16951
17768
  function walkGenerations(response) {
16952
17769
  const result = [];
16953
17770
  const generations = response.generations || [];
@@ -16994,7 +17811,7 @@ function getMetricsFromResponse(response) {
16994
17811
  continue;
16995
17812
  }
16996
17813
  const inputTokenDetails = usageMetadata.input_token_details;
16997
- return cleanObject({
17814
+ return normalizeTokenMetrics({
16998
17815
  total_tokens: usageMetadata.total_tokens,
16999
17816
  prompt_tokens: usageMetadata.input_tokens,
17000
17817
  completion_tokens: usageMetadata.output_tokens,
@@ -17004,7 +17821,7 @@ function getMetricsFromResponse(response) {
17004
17821
  }
17005
17822
  const llmOutput = response.llmOutput || {};
17006
17823
  const tokenUsage = isRecord(llmOutput.tokenUsage) ? llmOutput.tokenUsage : isRecord(llmOutput.estimatedTokens) ? llmOutput.estimatedTokens : {};
17007
- return cleanObject({
17824
+ return normalizeTokenMetrics({
17008
17825
  total_tokens: tokenUsage.totalTokens,
17009
17826
  prompt_tokens: tokenUsage.promptTokens,
17010
17827
  completion_tokens: tokenUsage.completionTokens
@@ -17564,10 +18381,15 @@ function startCodexRun(event, operation) {
17564
18381
  provider: "openai",
17565
18382
  ...event.moduleVersion ? { "openai_codex.version": event.moduleVersion } : {}
17566
18383
  };
17567
- const span = startSpan({
17568
- name: "OpenAI Codex",
17569
- spanAttributes: { type: "task" /* TASK */ }
17570
- });
18384
+ const span = startSpan(
18385
+ withSpanInstrumentationName(
18386
+ {
18387
+ name: "OpenAI Codex",
18388
+ spanAttributes: { type: "task" /* TASK */ }
18389
+ },
18390
+ INSTRUMENTATION_NAMES.OPENAI_CODEX
18391
+ )
18392
+ );
17571
18393
  const startTime = getCurrentUnixTimestamp();
17572
18394
  safeLog2(span, {
17573
18395
  input: sanitizedInput,
@@ -17716,7 +18538,12 @@ async function createCompletedItemSpan(state, item) {
17716
18538
  if (!spanArgs) {
17717
18539
  return;
17718
18540
  }
17719
- const span = startSpan(spanArgs.start);
18541
+ const span = startSpan(
18542
+ withSpanInstrumentationName(
18543
+ spanArgs.start,
18544
+ INSTRUMENTATION_NAMES.OPENAI_CODEX
18545
+ )
18546
+ );
17720
18547
  safeLog2(span, spanArgs.end);
17721
18548
  span.end();
17722
18549
  }
@@ -17758,15 +18585,20 @@ async function ensureActiveLlmSpan(state) {
17758
18585
  ...state.metadata["openai_codex.thread_id"] ? { "openai_codex.thread_id": state.metadata["openai_codex.thread_id"] } : {},
17759
18586
  "openai_codex.llm_sequence": sequence
17760
18587
  };
17761
- const span = startSpan({
17762
- event: {
17763
- ...sequence === 1 ? { input: state.input } : {},
17764
- metadata
17765
- },
17766
- name: "OpenAI Codex LLM",
17767
- parent: await state.span.export(),
17768
- spanAttributes: { type: "llm" /* LLM */ }
17769
- });
18588
+ const span = startSpan(
18589
+ withSpanInstrumentationName(
18590
+ {
18591
+ event: {
18592
+ ...sequence === 1 ? { input: state.input } : {},
18593
+ metadata
18594
+ },
18595
+ name: "OpenAI Codex LLM",
18596
+ parent: await state.span.export(),
18597
+ spanAttributes: { type: "llm" /* LLM */ }
18598
+ },
18599
+ INSTRUMENTATION_NAMES.OPENAI_CODEX
18600
+ )
18601
+ );
17770
18602
  state.activeLlmSpan = {
17771
18603
  anonymousMessages: [],
17772
18604
  anonymousReasoning: [],
@@ -17812,7 +18644,15 @@ async function startCodexItemSpan(state, item) {
17812
18644
  if (!spanArgs) {
17813
18645
  return;
17814
18646
  }
17815
- state.activeItemSpans.set(itemId, startSpan(spanArgs.start));
18647
+ state.activeItemSpans.set(
18648
+ itemId,
18649
+ startSpan(
18650
+ withSpanInstrumentationName(
18651
+ spanArgs.start,
18652
+ INSTRUMENTATION_NAMES.OPENAI_CODEX
18653
+ )
18654
+ )
18655
+ );
17816
18656
  }
17817
18657
  function updateCodexItem(state, item) {
17818
18658
  if (item.type === "agent_message" && typeof item.text === "string") {
@@ -18192,12 +19032,17 @@ var AnthropicPlugin = class extends BasePlugin {
18192
19032
  return;
18193
19033
  }
18194
19034
  const params = event.arguments[0] ?? {};
18195
- const span = startSpan({
18196
- name: "anthropic.beta.messages.toolRunner",
18197
- spanAttributes: {
18198
- type: "task" /* TASK */
18199
- }
18200
- });
19035
+ const span = startSpan(
19036
+ withSpanInstrumentationName(
19037
+ {
19038
+ name: "anthropic.beta.messages.toolRunner",
19039
+ spanAttributes: {
19040
+ type: "task" /* TASK */
19041
+ }
19042
+ },
19043
+ INSTRUMENTATION_NAMES.ANTHROPIC
19044
+ )
19045
+ );
18201
19046
  span.log({
18202
19047
  input: processAttachmentsInInput(
18203
19048
  coalesceInput(params.messages ?? [], params.system)
@@ -18338,19 +19183,22 @@ function wrapAnthropicToolRunnerTool(tool, index, state) {
18338
19183
  return finalizeError(error);
18339
19184
  }
18340
19185
  },
18341
- {
18342
- event: {
18343
- input: getAnthropicToolRunnerInput(args),
18344
- metadata: {
18345
- "gen_ai.tool.name": toolName,
18346
- provider: "anthropic"
19186
+ withSpanInstrumentationName(
19187
+ {
19188
+ event: {
19189
+ input: getAnthropicToolRunnerInput(args),
19190
+ metadata: {
19191
+ "gen_ai.tool.name": toolName,
19192
+ provider: "anthropic"
19193
+ }
19194
+ },
19195
+ name: `tool: ${toolName}`,
19196
+ spanAttributes: {
19197
+ type: "tool" /* TOOL */
18347
19198
  }
18348
19199
  },
18349
- name: `tool: ${toolName}`,
18350
- spanAttributes: {
18351
- type: "tool" /* TOOL */
18352
- }
18353
- }
19200
+ INSTRUMENTATION_NAMES.ANTHROPIC
19201
+ )
18354
19202
  );
18355
19203
  },
18356
19204
  writable: runDescriptor?.writable ?? true
@@ -18960,22 +19808,27 @@ function wrapLocalClaudeToolHandler(handler, getMetadata) {
18960
19808
  const spanName = metadata.serverName ? `tool: ${metadata.serverName}/${metadata.toolName}` : `tool: ${metadata.toolName}`;
18961
19809
  const runWithResolvedParent = async () => {
18962
19810
  const parent = toolUseId && localToolParentResolver ? await localToolParentResolver(toolUseId).catch(() => void 0) : void 0;
18963
- const span = startSpan({
18964
- event: {
18965
- input: handlerArgs[0],
18966
- metadata: {
18967
- "claude_agent_sdk.raw_tool_name": rawToolName,
18968
- "gen_ai.tool.name": metadata.toolName,
18969
- ...toolUseId && { "gen_ai.tool.call.id": toolUseId },
18970
- ...metadata.serverName && {
18971
- "mcp.server": metadata.serverName
18972
- }
18973
- }
18974
- },
18975
- name: spanName,
18976
- ...parent && { parent },
18977
- spanAttributes: { type: "tool" /* TOOL */ }
18978
- });
19811
+ const span = startSpan(
19812
+ withSpanInstrumentationName(
19813
+ {
19814
+ event: {
19815
+ input: handlerArgs[0],
19816
+ metadata: {
19817
+ "claude_agent_sdk.raw_tool_name": rawToolName,
19818
+ "gen_ai.tool.name": metadata.toolName,
19819
+ ...toolUseId && { "gen_ai.tool.call.id": toolUseId },
19820
+ ...metadata.serverName && {
19821
+ "mcp.server": metadata.serverName
19822
+ }
19823
+ }
19824
+ },
19825
+ name: spanName,
19826
+ ...parent && { parent },
19827
+ spanAttributes: { type: "tool" /* TOOL */ }
19828
+ },
19829
+ INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
19830
+ )
19831
+ );
18979
19832
  const runHandler = () => Reflect.apply(handler, this, handlerArgs);
18980
19833
  const finalizeSuccess = (result) => {
18981
19834
  span.log({ output: result });
@@ -19300,14 +20153,19 @@ async function createLLMSpanForMessages(messages, promptMessages, conversationHi
19300
20153
  ).filter(
19301
20154
  (c) => c !== void 0
19302
20155
  );
19303
- const span = existingSpan ?? startSpan({
19304
- name: "anthropic.messages.create",
19305
- parent: parentSpan,
19306
- spanAttributes: {
19307
- type: "llm" /* LLM */
19308
- },
19309
- startTime
19310
- });
20156
+ const span = existingSpan ?? startSpan(
20157
+ withSpanInstrumentationName(
20158
+ {
20159
+ name: "anthropic.messages.create",
20160
+ parent: parentSpan,
20161
+ spanAttributes: {
20162
+ type: "llm" /* LLM */
20163
+ },
20164
+ startTime
20165
+ },
20166
+ INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
20167
+ )
20168
+ );
19311
20169
  span.log({
19312
20170
  input,
19313
20171
  metadata: model ? { model } : void 0,
@@ -19410,25 +20268,30 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
19410
20268
  return {};
19411
20269
  }
19412
20270
  const parsed = parseToolName(input.tool_name);
19413
- const toolSpan = startSpan({
19414
- event: {
19415
- input: input.tool_input,
19416
- metadata: {
19417
- "claude_agent_sdk.cwd": input.cwd,
19418
- "claude_agent_sdk.raw_tool_name": parsed.rawToolName,
19419
- "claude_agent_sdk.session_id": input.session_id,
19420
- "gen_ai.tool.call.id": toolUseID,
19421
- "gen_ai.tool.name": parsed.toolName,
19422
- ...parsed.mcpServer && { "mcp.server": parsed.mcpServer },
19423
- ...getMcpServerMetadata(parsed.mcpServer, mcpServers)
19424
- }
19425
- },
19426
- name: parsed.displayName,
19427
- parent: await resolveParentSpan(toolUseID, {
19428
- agentId: input.agent_id
19429
- }),
19430
- spanAttributes: { type: "tool" /* TOOL */ }
19431
- });
20271
+ const toolSpan = startSpan(
20272
+ withSpanInstrumentationName(
20273
+ {
20274
+ event: {
20275
+ input: input.tool_input,
20276
+ metadata: {
20277
+ "claude_agent_sdk.cwd": input.cwd,
20278
+ "claude_agent_sdk.raw_tool_name": parsed.rawToolName,
20279
+ "claude_agent_sdk.session_id": input.session_id,
20280
+ "gen_ai.tool.call.id": toolUseID,
20281
+ "gen_ai.tool.name": parsed.toolName,
20282
+ ...parsed.mcpServer && { "mcp.server": parsed.mcpServer },
20283
+ ...getMcpServerMetadata(parsed.mcpServer, mcpServers)
20284
+ }
20285
+ },
20286
+ name: parsed.displayName,
20287
+ parent: await resolveParentSpan(toolUseID, {
20288
+ agentId: input.agent_id
20289
+ }),
20290
+ spanAttributes: { type: "tool" /* TOOL */ }
20291
+ },
20292
+ INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
20293
+ )
20294
+ );
19432
20295
  activeToolSpans.set(toolUseID, toolSpan);
19433
20296
  return {};
19434
20297
  };
@@ -19794,14 +20657,19 @@ async function ensureSubAgentSpan(subAgentDetailsByToolUseId, rootSpan, activeTo
19794
20657
  const spanName = formatSubAgentSpanName(details);
19795
20658
  const parentToolSpan = activeToolSpans.get(parentToolUseId);
19796
20659
  const parentSpan = parentToolSpan ? await parentToolSpan.export() : await rootSpan.export();
19797
- const subAgentSpan = startSpan({
19798
- event: {
19799
- metadata: subAgentDetailsToMetadata(details)
19800
- },
19801
- name: spanName,
19802
- parent: parentSpan,
19803
- spanAttributes: { type: "task" /* TASK */ }
19804
- });
20660
+ const subAgentSpan = startSpan(
20661
+ withSpanInstrumentationName(
20662
+ {
20663
+ event: {
20664
+ metadata: subAgentDetailsToMetadata(details)
20665
+ },
20666
+ name: spanName,
20667
+ parent: parentSpan,
20668
+ spanAttributes: { type: "task" /* TASK */ }
20669
+ },
20670
+ INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
20671
+ )
20672
+ );
19805
20673
  subAgentSpans.set(parentToolUseId, subAgentSpan);
19806
20674
  return subAgentSpan;
19807
20675
  }
@@ -19822,14 +20690,19 @@ async function ensureActiveLlmSpanForParentToolUse(rootSpan, activeLlmSpansByPar
19822
20690
  );
19823
20691
  llmParentSpan = await subAgentSpan.export();
19824
20692
  }
19825
- const llmSpan = startSpan({
19826
- name: "anthropic.messages.create",
19827
- parent: llmParentSpan,
19828
- spanAttributes: {
19829
- type: "llm" /* LLM */
19830
- },
19831
- startTime
19832
- });
20693
+ const llmSpan = startSpan(
20694
+ withSpanInstrumentationName(
20695
+ {
20696
+ name: "anthropic.messages.create",
20697
+ parent: llmParentSpan,
20698
+ spanAttributes: {
20699
+ type: "llm" /* LLM */
20700
+ },
20701
+ startTime
20702
+ },
20703
+ INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
20704
+ )
20705
+ );
19833
20706
  activeLlmSpansByParentToolUse.set(parentKey, llmSpan);
19834
20707
  return llmSpan;
19835
20708
  }
@@ -20098,12 +20971,17 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
20098
20971
  }
20099
20972
  })();
20100
20973
  }
20101
- const span = startSpan({
20102
- name: "Claude Agent",
20103
- spanAttributes: {
20104
- type: "task" /* TASK */
20105
- }
20106
- });
20974
+ const span = startSpan(
20975
+ withSpanInstrumentationName(
20976
+ {
20977
+ name: "Claude Agent",
20978
+ spanAttributes: {
20979
+ type: "task" /* TASK */
20980
+ }
20981
+ },
20982
+ INSTRUMENTATION_NAMES.CLAUDE_AGENT_SDK
20983
+ )
20984
+ );
20107
20985
  const startTime = getCurrentUnixTimestamp();
20108
20986
  try {
20109
20987
  span.log({
@@ -20317,10 +21195,15 @@ var CursorSDKPlugin = class extends BasePlugin {
20317
21195
  provider: "cursor",
20318
21196
  ...event.moduleVersion ? { "cursor_sdk.version": event.moduleVersion } : {}
20319
21197
  };
20320
- const span = startSpan({
20321
- name: "Cursor Agent",
20322
- spanAttributes: { type: "task" /* TASK */ }
20323
- });
21198
+ const span = startSpan(
21199
+ withSpanInstrumentationName(
21200
+ {
21201
+ name: "Cursor Agent",
21202
+ spanAttributes: { type: "task" /* TASK */ }
21203
+ },
21204
+ INSTRUMENTATION_NAMES.CURSOR_SDK
21205
+ )
21206
+ );
20324
21207
  const startTime = getCurrentUnixTimestamp();
20325
21208
  safeLog3(span, {
20326
21209
  input: sanitizeUserMessage(message),
@@ -20382,10 +21265,15 @@ var CursorSDKPlugin = class extends BasePlugin {
20382
21265
  provider: "cursor",
20383
21266
  ...event.moduleVersion ? { "cursor_sdk.version": event.moduleVersion } : {}
20384
21267
  };
20385
- const span = startSpan({
20386
- name: "Cursor Agent",
20387
- spanAttributes: { type: "task" /* TASK */ }
20388
- });
21268
+ const span = startSpan(
21269
+ withSpanInstrumentationName(
21270
+ {
21271
+ name: "Cursor Agent",
21272
+ spanAttributes: { type: "task" /* TASK */ }
21273
+ },
21274
+ INSTRUMENTATION_NAMES.CURSOR_SDK
21275
+ )
21276
+ );
20389
21277
  const startTime = getCurrentUnixTimestamp();
20390
21278
  safeLog3(span, {
20391
21279
  input: sanitizeUserMessage(message),
@@ -20832,29 +21720,39 @@ async function startToolSpan(state, args) {
20832
21720
  if (args.truncated?.result !== void 0) {
20833
21721
  metadata["cursor_sdk.tool.result_truncated"] = args.truncated.result;
20834
21722
  }
20835
- const span = startSpan({
20836
- event: {
20837
- input: args.args,
20838
- metadata
20839
- },
20840
- name: `tool: ${name}`,
20841
- parent: await state.span.export(),
20842
- spanAttributes: { type: "tool" /* TOOL */ }
20843
- });
21723
+ const span = startSpan(
21724
+ withSpanInstrumentationName(
21725
+ {
21726
+ event: {
21727
+ input: args.args,
21728
+ metadata
21729
+ },
21730
+ name: `tool: ${name}`,
21731
+ parent: await state.span.export(),
21732
+ spanAttributes: { type: "tool" /* TOOL */ }
21733
+ },
21734
+ INSTRUMENTATION_NAMES.CURSOR_SDK
21735
+ )
21736
+ );
20844
21737
  let subAgentSpan;
20845
21738
  if (isSubAgentToolName(name)) {
20846
- subAgentSpan = startSpan({
20847
- event: {
20848
- input: args.args,
20849
- metadata: {
20850
- "cursor_sdk.subagent.tool_call_id": args.callId,
20851
- "gen_ai.tool.name": name
20852
- }
20853
- },
20854
- name: formatSubAgentSpanName2(args.toolCall, args.args),
20855
- parent: await span.export(),
20856
- spanAttributes: { type: "task" /* TASK */ }
20857
- });
21739
+ subAgentSpan = startSpan(
21740
+ withSpanInstrumentationName(
21741
+ {
21742
+ event: {
21743
+ input: args.args,
21744
+ metadata: {
21745
+ "cursor_sdk.subagent.tool_call_id": args.callId,
21746
+ "gen_ai.tool.name": name
21747
+ }
21748
+ },
21749
+ name: formatSubAgentSpanName2(args.toolCall, args.args),
21750
+ parent: await span.export(),
21751
+ spanAttributes: { type: "task" /* TASK */ }
21752
+ },
21753
+ INSTRUMENTATION_NAMES.CURSOR_SDK
21754
+ )
21755
+ );
20858
21756
  }
20859
21757
  return { span, subAgentSpan };
20860
21758
  }
@@ -21226,16 +22124,19 @@ var OpenAIAgentsTraceProcessor = class _OpenAIAgentsTraceProcessor {
21226
22124
  this.evictOldestTrace();
21227
22125
  }
21228
22126
  const current = currentSpan();
21229
- const span = current && current !== NOOP_SPAN ? current.startSpan({
21230
- name: trace.name,
21231
- type: "task" /* TASK */
21232
- }) : this.logger ? this.logger.startSpan({
21233
- name: trace.name,
21234
- type: "task" /* TASK */
21235
- }) : startSpan({
21236
- name: trace.name,
21237
- type: "task" /* TASK */
21238
- });
22127
+ const spanArgs = withSpanInstrumentationName(
22128
+ {
22129
+ name: trace.name,
22130
+ type: "task" /* TASK */
22131
+ },
22132
+ INSTRUMENTATION_NAMES.OPENAI_AGENTS
22133
+ );
22134
+ const span = current && current !== NOOP_SPAN ? current.startSpan(spanArgs) : this.logger ? this.logger.startSpan(spanArgs) : startSpan(
22135
+ withSpanInstrumentationName(
22136
+ spanArgs,
22137
+ INSTRUMENTATION_NAMES.OPENAI_AGENTS
22138
+ )
22139
+ );
21239
22140
  span.log({
21240
22141
  input: "Agent workflow started",
21241
22142
  metadata: {
@@ -21286,10 +22187,15 @@ var OpenAIAgentsTraceProcessor = class _OpenAIAgentsTraceProcessor {
21286
22187
  if (!parentSpan) {
21287
22188
  return Promise.resolve();
21288
22189
  }
21289
- const childSpan = parentSpan.startSpan({
21290
- name: spanNameFromAgents(span),
21291
- type: spanTypeFromAgents(span)
21292
- });
22190
+ const childSpan = parentSpan.startSpan(
22191
+ withSpanInstrumentationName(
22192
+ {
22193
+ name: spanNameFromAgents(span),
22194
+ type: spanTypeFromAgents(span)
22195
+ },
22196
+ INSTRUMENTATION_NAMES.OPENAI_AGENTS
22197
+ )
22198
+ );
21293
22199
  traceData.childSpans.set(span.spanId, childSpan);
21294
22200
  return Promise.resolve();
21295
22201
  }
@@ -21589,13 +22495,18 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21589
22495
  const params = event.arguments[0];
21590
22496
  const input = serializeGenerateContentInput(params);
21591
22497
  const metadata = extractGenerateContentMetadata(params);
21592
- const span = startSpan({
21593
- name: "generate_content",
21594
- spanAttributes: {
21595
- type: "llm" /* LLM */
21596
- },
21597
- event: createWrapperParityEvent({ input, metadata })
21598
- });
22498
+ const span = startSpan(
22499
+ withSpanInstrumentationName(
22500
+ {
22501
+ name: "generate_content",
22502
+ spanAttributes: {
22503
+ type: "llm" /* LLM */
22504
+ },
22505
+ event: createWrapperParityEvent({ input, metadata })
22506
+ },
22507
+ INSTRUMENTATION_NAMES.GOOGLE_GENAI
22508
+ )
22509
+ );
21599
22510
  return {
21600
22511
  span,
21601
22512
  startTime: getCurrentUnixTimestamp()
@@ -21608,13 +22519,18 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21608
22519
  const params = event.arguments[0];
21609
22520
  const input = serializeGenerateContentInput(params);
21610
22521
  const metadata = extractGenerateContentMetadata(params);
21611
- const span = startSpan({
21612
- name: "generate_content",
21613
- spanAttributes: {
21614
- type: "llm" /* LLM */
21615
- },
21616
- event: createWrapperParityEvent({ input, metadata })
21617
- });
22522
+ const span = startSpan(
22523
+ withSpanInstrumentationName(
22524
+ {
22525
+ name: "generate_content",
22526
+ spanAttributes: {
22527
+ type: "llm" /* LLM */
22528
+ },
22529
+ event: createWrapperParityEvent({ input, metadata })
22530
+ },
22531
+ INSTRUMENTATION_NAMES.GOOGLE_GENAI
22532
+ )
22533
+ );
21618
22534
  return {
21619
22535
  span,
21620
22536
  startTime: getCurrentUnixTimestamp()
@@ -21690,13 +22606,18 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21690
22606
  const params = event.arguments[0];
21691
22607
  const input = serializeEmbedContentInput(params);
21692
22608
  const metadata = extractEmbedContentMetadata(params);
21693
- const span = startSpan({
21694
- name: "embed_content",
21695
- spanAttributes: {
21696
- type: "llm" /* LLM */
21697
- },
21698
- event: createWrapperParityEvent({ input, metadata })
21699
- });
22609
+ const span = startSpan(
22610
+ withSpanInstrumentationName(
22611
+ {
22612
+ name: "embed_content",
22613
+ spanAttributes: {
22614
+ type: "llm" /* LLM */
22615
+ },
22616
+ event: createWrapperParityEvent({ input, metadata })
22617
+ },
22618
+ INSTRUMENTATION_NAMES.GOOGLE_GENAI
22619
+ )
22620
+ );
21700
22621
  return {
21701
22622
  span,
21702
22623
  startTime: getCurrentUnixTimestamp()
@@ -21709,13 +22630,18 @@ var GoogleGenAIPlugin = class extends BasePlugin {
21709
22630
  const params = event.arguments[0];
21710
22631
  const input = serializeEmbedContentInput(params);
21711
22632
  const metadata = extractEmbedContentMetadata(params);
21712
- const span = startSpan({
21713
- name: "embed_content",
21714
- spanAttributes: {
21715
- type: "llm" /* LLM */
21716
- },
21717
- event: createWrapperParityEvent({ input, metadata })
21718
- });
22633
+ const span = startSpan(
22634
+ withSpanInstrumentationName(
22635
+ {
22636
+ name: "embed_content",
22637
+ spanAttributes: {
22638
+ type: "llm" /* LLM */
22639
+ },
22640
+ event: createWrapperParityEvent({ input, metadata })
22641
+ },
22642
+ INSTRUMENTATION_NAMES.GOOGLE_GENAI
22643
+ )
22644
+ );
21719
22645
  return {
21720
22646
  span,
21721
22647
  startTime: getCurrentUnixTimestamp()
@@ -21826,16 +22752,21 @@ function patchGoogleGenAIStreamingResult(args) {
21826
22752
  const requestStartTime = startTime ?? getCurrentUnixTimestamp();
21827
22753
  const ensureSpan = () => {
21828
22754
  if (!span) {
21829
- span = startSpan({
21830
- name: "generate_content_stream",
21831
- spanAttributes: {
21832
- type: "llm" /* LLM */
21833
- },
21834
- event: {
21835
- input,
21836
- metadata
21837
- }
21838
- });
22755
+ span = startSpan(
22756
+ withSpanInstrumentationName(
22757
+ {
22758
+ name: "generate_content_stream",
22759
+ spanAttributes: {
22760
+ type: "llm" /* LLM */
22761
+ },
22762
+ event: {
22763
+ input,
22764
+ metadata
22765
+ }
22766
+ },
22767
+ INSTRUMENTATION_NAMES.GOOGLE_GENAI
22768
+ )
22769
+ );
21839
22770
  }
21840
22771
  return span;
21841
22772
  };
@@ -25470,12 +26401,17 @@ var GoogleADKPlugin = class extends BasePlugin {
25470
26401
  const createState = (event) => {
25471
26402
  const params = event.arguments[0] ?? {};
25472
26403
  const contextKey = extractRunnerContextKey(params);
25473
- const span = startSpan({
25474
- name: "Google ADK Runner",
25475
- spanAttributes: {
25476
- type: "task" /* TASK */
25477
- }
25478
- });
26404
+ const span = startSpan(
26405
+ withSpanInstrumentationName(
26406
+ {
26407
+ name: "Google ADK Runner",
26408
+ spanAttributes: {
26409
+ type: "task" /* TASK */
26410
+ }
26411
+ },
26412
+ INSTRUMENTATION_NAMES.GOOGLE_ADK
26413
+ )
26414
+ );
25479
26415
  const startTime = getCurrentUnixTimestamp();
25480
26416
  try {
25481
26417
  const metadata = extractRunnerMetadata(params);
@@ -25561,18 +26497,23 @@ var GoogleADKPlugin = class extends BasePlugin {
25561
26497
  this.activeRunnerSpans
25562
26498
  );
25563
26499
  const contextKey = extractInvocationContextKey(parentContext);
25564
- const span = startSpan({
25565
- name: agentName ? `Agent: ${agentName}` : "Google ADK Agent",
25566
- spanAttributes: {
25567
- type: "task" /* TASK */
25568
- },
25569
- ...runnerParentSpan ? {
25570
- parentSpanIds: {
25571
- spanId: runnerParentSpan.spanId,
25572
- rootSpanId: runnerParentSpan.rootSpanId
25573
- }
25574
- } : {}
25575
- });
26500
+ const span = startSpan(
26501
+ withSpanInstrumentationName(
26502
+ {
26503
+ name: agentName ? `Agent: ${agentName}` : "Google ADK Agent",
26504
+ spanAttributes: {
26505
+ type: "task" /* TASK */
26506
+ },
26507
+ ...runnerParentSpan ? {
26508
+ parentSpanIds: {
26509
+ spanId: runnerParentSpan.spanId,
26510
+ rootSpanId: runnerParentSpan.rootSpanId
26511
+ }
26512
+ } : {}
26513
+ },
26514
+ INSTRUMENTATION_NAMES.GOOGLE_ADK
26515
+ )
26516
+ );
25576
26517
  const startTime = getCurrentUnixTimestamp();
25577
26518
  try {
25578
26519
  const metadata = {
@@ -25665,22 +26606,27 @@ var GoogleADKPlugin = class extends BasePlugin {
25665
26606
  this.activeAgentSpans,
25666
26607
  this.activeRunnerSpans
25667
26608
  );
25668
- const createSpan = () => startSpan({
25669
- name: toolName ? `tool: ${toolName}` : "Google ADK Tool",
25670
- spanAttributes: {
25671
- type: "tool" /* TOOL */
25672
- },
25673
- event: {
25674
- input: req.args,
25675
- metadata: {
25676
- provider: "google-adk",
25677
- ...toolName && { "google_adk.tool_name": toolName },
25678
- ...extractToolCallId(req) && {
25679
- "google_adk.tool_call_id": extractToolCallId(req)
26609
+ const createSpan = () => startSpan(
26610
+ withSpanInstrumentationName(
26611
+ {
26612
+ name: toolName ? `tool: ${toolName}` : "Google ADK Tool",
26613
+ spanAttributes: {
26614
+ type: "tool" /* TOOL */
26615
+ },
26616
+ event: {
26617
+ input: req.args,
26618
+ metadata: {
26619
+ provider: "google-adk",
26620
+ ...toolName && { "google_adk.tool_name": toolName },
26621
+ ...extractToolCallId(req) && {
26622
+ "google_adk.tool_call_id": extractToolCallId(req)
26623
+ }
26624
+ }
25680
26625
  }
25681
- }
25682
- }
25683
- });
26626
+ },
26627
+ INSTRUMENTATION_NAMES.GOOGLE_ADK
26628
+ )
26629
+ );
25684
26630
  const span = parentSpan ? withCurrent(parentSpan, () => createSpan()) : createSpan();
25685
26631
  const startTime = getCurrentUnixTimestamp();
25686
26632
  states.set(event, { span, startTime });
@@ -27654,12 +28600,17 @@ function startActionSpanState(args) {
27654
28600
  if (!shouldTraceAction(args.metadata, args.runStepName)) {
27655
28601
  return void 0;
27656
28602
  }
27657
- const span = startSpan({
27658
- name: actionSpanName(args.metadata, args.runStepName),
27659
- spanAttributes: {
27660
- type: actionSpanType(args.metadata)
27661
- }
27662
- });
28603
+ const span = startSpan(
28604
+ withSpanInstrumentationName(
28605
+ {
28606
+ name: actionSpanName(args.metadata, args.runStepName),
28607
+ spanAttributes: {
28608
+ type: actionSpanType(args.metadata)
28609
+ }
28610
+ },
28611
+ INSTRUMENTATION_NAMES.GENKIT
28612
+ )
28613
+ );
27663
28614
  const startTime = getCurrentUnixTimestamp();
27664
28615
  span.log({
27665
28616
  input: args.input,
@@ -28108,11 +29059,16 @@ async function handleTurnStart(state, agentId) {
28108
29059
  return;
28109
29060
  }
28110
29061
  const parentId = await getParentIdForAgent(state, agentId);
28111
- const span = startSpan({
28112
- name: "Copilot Turn",
28113
- parent: parentId,
28114
- spanAttributes: { type: "task" /* TASK */ }
28115
- });
29062
+ const span = startSpan(
29063
+ withSpanInstrumentationName(
29064
+ {
29065
+ name: "Copilot Turn",
29066
+ parent: parentId,
29067
+ spanAttributes: { type: "task" /* TASK */ }
29068
+ },
29069
+ INSTRUMENTATION_NAMES.GITHUB_COPILOT
29070
+ )
29071
+ );
28116
29072
  const pendingUserMessage = state.pendingUserMessages.get(key);
28117
29073
  if (pendingUserMessage) {
28118
29074
  span.log({ input: pendingUserMessage });
@@ -28143,11 +29099,16 @@ async function handleUsage(state, agentId, usage) {
28143
29099
  const parentId = turn ? await turn.id : await state.session.id;
28144
29100
  const content = state.currentMessageContent.get(key);
28145
29101
  const { metrics, metadata } = extractMetricsFromUsage(usage);
28146
- const llmSpan = startSpan({
28147
- name: "github.copilot.llm",
28148
- parent: parentId,
28149
- spanAttributes: { type: "llm" /* LLM */ }
28150
- });
29102
+ const llmSpan = startSpan(
29103
+ withSpanInstrumentationName(
29104
+ {
29105
+ name: "github.copilot.llm",
29106
+ parent: parentId,
29107
+ spanAttributes: { type: "llm" /* LLM */ }
29108
+ },
29109
+ INSTRUMENTATION_NAMES.GITHUB_COPILOT
29110
+ )
29111
+ );
28151
29112
  llmSpan.log({
28152
29113
  output: content ?? void 0,
28153
29114
  metadata,
@@ -28173,11 +29134,16 @@ async function handleToolStart(state, agentId, toolCallId, toolName, args, mcpSe
28173
29134
  }
28174
29135
  const parentId = await getToolParentId(state, agentId);
28175
29136
  const displayName = mcpServerName ? `tool: ${mcpServerName}/${toolName}` : `tool: ${toolName}`;
28176
- const span = startSpan({
28177
- name: displayName,
28178
- parent: parentId,
28179
- spanAttributes: { type: "tool" /* TOOL */ }
28180
- });
29137
+ const span = startSpan(
29138
+ withSpanInstrumentationName(
29139
+ {
29140
+ name: displayName,
29141
+ parent: parentId,
29142
+ spanAttributes: { type: "tool" /* TOOL */ }
29143
+ },
29144
+ INSTRUMENTATION_NAMES.GITHUB_COPILOT
29145
+ )
29146
+ );
28181
29147
  const metadata = {
28182
29148
  "gen_ai.tool.name": toolName,
28183
29149
  "gen_ai.tool.call.id": toolCallId
@@ -28213,11 +29179,16 @@ async function handleSubagentStarted(state, agentId, toolCallId, agentDisplayNam
28213
29179
  }
28214
29180
  const tool = state.activeTools.get(toolCallId);
28215
29181
  const parentId = tool ? await tool.id : await state.session.id;
28216
- const span = startSpan({
28217
- name: `Agent: ${agentDisplayName}`,
28218
- parent: parentId,
28219
- spanAttributes: { type: "task" /* TASK */ }
28220
- });
29182
+ const span = startSpan(
29183
+ withSpanInstrumentationName(
29184
+ {
29185
+ name: `Agent: ${agentDisplayName}`,
29186
+ parent: parentId,
29187
+ spanAttributes: { type: "task" /* TASK */ }
29188
+ },
29189
+ INSTRUMENTATION_NAMES.GITHUB_COPILOT
29190
+ )
29191
+ );
28221
29192
  span.log({
28222
29193
  metadata: {
28223
29194
  "github_copilot.agent_name": agentDisplayName,
@@ -28443,10 +29414,15 @@ function makeSessionHandlers(sessionStates, configArgIndex, includeProviderMetad
28443
29414
  if (!config || typeof config !== "object") {
28444
29415
  return;
28445
29416
  }
28446
- const sessionSpan = startSpan({
28447
- name: "Copilot Session",
28448
- spanAttributes: { type: "task" /* TASK */ }
28449
- });
29417
+ const sessionSpan = startSpan(
29418
+ withSpanInstrumentationName(
29419
+ {
29420
+ name: "Copilot Session",
29421
+ spanAttributes: { type: "task" /* TASK */ }
29422
+ },
29423
+ INSTRUMENTATION_NAMES.GITHUB_COPILOT
29424
+ )
29425
+ );
28450
29426
  const metadata = {};
28451
29427
  if (config.model) {
28452
29428
  metadata["github_copilot.model"] = config.model;
@@ -28780,19 +29756,24 @@ var LangSmithPlugin = class extends BasePlugin {
28780
29756
  const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
28781
29757
  const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
28782
29758
  const startTime = timestampSeconds(ownValue(run, "start_time"));
28783
- return startSpan({
28784
- name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
28785
- spanId: id,
28786
- parentSpanIds: {
28787
- parentSpanIds: parentId ? [parentId] : [],
28788
- rootSpanId: traceId
28789
- },
28790
- spanAttributes: {
28791
- type: mapRunType(ownValue(run, "run_type"))
28792
- },
28793
- ...startTime === void 0 ? {} : { startTime },
28794
- event: { id }
28795
- });
29759
+ return startSpan(
29760
+ withSpanInstrumentationName(
29761
+ {
29762
+ name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
29763
+ spanId: id,
29764
+ parentSpanIds: {
29765
+ parentSpanIds: parentId ? [parentId] : [],
29766
+ rootSpanId: traceId
29767
+ },
29768
+ spanAttributes: {
29769
+ type: mapRunType(ownValue(run, "run_type"))
29770
+ },
29771
+ ...startTime === void 0 ? {} : { startTime },
29772
+ event: { id }
29773
+ },
29774
+ INSTRUMENTATION_NAMES.LANGSMITH
29775
+ )
29776
+ );
28796
29777
  }
28797
29778
  logRun(span, run, previous, includeOutput) {
28798
29779
  const inputs = preferOwnValue(run, previous, "inputs");
@@ -29123,14 +30104,19 @@ function startPiPromptRun(event, onFinalize) {
29123
30104
  ...session.model?.id || agent.state?.model?.id ? { model: session.model?.id ?? agent.state?.model?.id } : {},
29124
30105
  ...event.moduleVersion ? { "pi_coding_agent.version": event.moduleVersion } : {}
29125
30106
  };
29126
- const span = startSpan({
29127
- event: {
29128
- input: extractPromptInput(event.arguments[0], event.arguments[1]),
29129
- metadata
29130
- },
29131
- name: "AgentSession.prompt",
29132
- spanAttributes: { type: "task" /* TASK */ }
29133
- });
30107
+ const span = startSpan(
30108
+ withSpanInstrumentationName(
30109
+ {
30110
+ event: {
30111
+ input: extractPromptInput(event.arguments[0], event.arguments[1]),
30112
+ metadata
30113
+ },
30114
+ name: "AgentSession.prompt",
30115
+ spanAttributes: { type: "task" /* TASK */ }
30116
+ },
30117
+ INSTRUMENTATION_NAMES.PI_CODING_AGENT
30118
+ )
30119
+ );
29134
30120
  const streamPatchState = installPiStreamPatch(agent);
29135
30121
  const options = event.arguments[1];
29136
30122
  const promptText = event.arguments[0];
@@ -29300,15 +30286,20 @@ async function startPiLlmSpan(state, model, context, options) {
29300
30286
  ...extractToolMetadata(context.tools),
29301
30287
  "pi_coding_agent.operation": "agent.streamFn"
29302
30288
  };
29303
- const span = startSpan({
29304
- event: {
29305
- input: processInputAttachments(normalizePiContextInput(context)),
29306
- metadata
29307
- },
29308
- name: getLlmSpanName(model),
29309
- parent: await state.span.export(),
29310
- spanAttributes: { type: "llm" /* LLM */ }
29311
- });
30289
+ const span = startSpan(
30290
+ withSpanInstrumentationName(
30291
+ {
30292
+ event: {
30293
+ input: processInputAttachments(normalizePiContextInput(context)),
30294
+ metadata
30295
+ },
30296
+ name: getLlmSpanName(model),
30297
+ parent: await state.span.export(),
30298
+ spanAttributes: { type: "llm" /* LLM */ }
30299
+ },
30300
+ INSTRUMENTATION_NAMES.PI_CODING_AGENT
30301
+ )
30302
+ );
29312
30303
  const llmState = {
29313
30304
  finalized: false,
29314
30305
  metadata,
@@ -29476,15 +30467,20 @@ async function startPiToolSpan(state, event) {
29476
30467
  "pi_coding_agent.tool.name": event.toolName
29477
30468
  };
29478
30469
  try {
29479
- const span = startSpan({
29480
- event: {
29481
- input: event.args,
29482
- metadata
29483
- },
29484
- name: event.toolName || "tool",
29485
- parent: await state.span.export(),
29486
- spanAttributes: { type: "tool" /* TOOL */ }
29487
- });
30470
+ const span = startSpan(
30471
+ withSpanInstrumentationName(
30472
+ {
30473
+ event: {
30474
+ input: event.args,
30475
+ metadata
30476
+ },
30477
+ name: event.toolName || "tool",
30478
+ parent: await state.span.export(),
30479
+ spanAttributes: { type: "tool" /* TOOL */ }
30480
+ },
30481
+ INSTRUMENTATION_NAMES.PI_CODING_AGENT
30482
+ )
30483
+ );
29488
30484
  state.activeToolSpans.set(event.toolCallId, {
29489
30485
  restoreAutoInstrumentation,
29490
30486
  span
@@ -30068,22 +31064,32 @@ function startAgentStream(event, activeChildParents) {
30068
31064
  );
30069
31065
  const span = parentSpan ? withCurrent(
30070
31066
  parentSpan,
30071
- () => startSpan({
30072
- event: {
30073
- input,
30074
- metadata
31067
+ () => startSpan(
31068
+ withSpanInstrumentationName(
31069
+ {
31070
+ event: {
31071
+ input,
31072
+ metadata
31073
+ },
31074
+ name: formatAgentSpanName(agent),
31075
+ spanAttributes: { type: "task" /* TASK */ }
31076
+ },
31077
+ INSTRUMENTATION_NAMES.STRANDS_AGENT_SDK
31078
+ )
31079
+ )
31080
+ ) : startSpan(
31081
+ withSpanInstrumentationName(
31082
+ {
31083
+ event: {
31084
+ input,
31085
+ metadata
31086
+ },
31087
+ name: formatAgentSpanName(agent),
31088
+ spanAttributes: { type: "task" /* TASK */ }
30075
31089
  },
30076
- name: formatAgentSpanName(agent),
30077
- spanAttributes: { type: "task" /* TASK */ }
30078
- })
30079
- ) : startSpan({
30080
- event: {
30081
- input,
30082
- metadata
30083
- },
30084
- name: formatAgentSpanName(agent),
30085
- spanAttributes: { type: "task" /* TASK */ }
30086
- });
31090
+ INSTRUMENTATION_NAMES.STRANDS_AGENT_SDK
31091
+ )
31092
+ );
30087
31093
  return {
30088
31094
  activeTools: /* @__PURE__ */ new Map(),
30089
31095
  attachmentCache,
@@ -30105,22 +31111,32 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30105
31111
  const input = processStrandsInputAttachments(event.arguments[0]);
30106
31112
  const span = parentSpan ? withCurrent(
30107
31113
  parentSpan,
30108
- () => startSpan({
30109
- event: {
30110
- input,
30111
- metadata
31114
+ () => startSpan(
31115
+ withSpanInstrumentationName(
31116
+ {
31117
+ event: {
31118
+ input,
31119
+ metadata
31120
+ },
31121
+ name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
31122
+ spanAttributes: { type: "task" /* TASK */ }
31123
+ },
31124
+ INSTRUMENTATION_NAMES.STRANDS_AGENT_SDK
31125
+ )
31126
+ )
31127
+ ) : startSpan(
31128
+ withSpanInstrumentationName(
31129
+ {
31130
+ event: {
31131
+ input,
31132
+ metadata
31133
+ },
31134
+ name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
31135
+ spanAttributes: { type: "task" /* TASK */ }
30112
31136
  },
30113
- name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
30114
- spanAttributes: { type: "task" /* TASK */ }
30115
- })
30116
- ) : startSpan({
30117
- event: {
30118
- input,
30119
- metadata
30120
- },
30121
- name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
30122
- spanAttributes: { type: "task" /* TASK */ }
30123
- });
31137
+ INSTRUMENTATION_NAMES.STRANDS_AGENT_SDK
31138
+ )
31139
+ );
30124
31140
  return {
30125
31141
  activeNodes: /* @__PURE__ */ new Map(),
30126
31142
  finalized: false,
@@ -30222,17 +31238,22 @@ function startModelSpan(state, event) {
30222
31238
  };
30223
31239
  const span = withCurrent(
30224
31240
  state.span,
30225
- () => startSpan({
30226
- event: {
30227
- input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
30228
- event.agent.messages,
30229
- state.attachmentCache
30230
- ) : void 0,
30231
- metadata
30232
- },
30233
- name: formatModelSpanName(model),
30234
- spanAttributes: { type: "llm" /* LLM */ }
30235
- })
31241
+ () => startSpan(
31242
+ withSpanInstrumentationName(
31243
+ {
31244
+ event: {
31245
+ input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
31246
+ event.agent.messages,
31247
+ state.attachmentCache
31248
+ ) : void 0,
31249
+ metadata
31250
+ },
31251
+ name: formatModelSpanName(model),
31252
+ spanAttributes: { type: "llm" /* LLM */ }
31253
+ },
31254
+ INSTRUMENTATION_NAMES.STRANDS_AGENT_SDK
31255
+ )
31256
+ )
30236
31257
  );
30237
31258
  state.activeModel = {
30238
31259
  metadata,
@@ -30284,20 +31305,25 @@ function startToolSpan2(state, event) {
30284
31305
  const name = extractToolName3(toolUse, event.tool);
30285
31306
  const span = withCurrent(
30286
31307
  state.span,
30287
- () => startSpan({
30288
- event: {
30289
- input: toolUse?.input,
30290
- metadata: {
30291
- "gen_ai.tool.call.id": toolUse?.toolUseId,
30292
- "gen_ai.tool.name": name,
30293
- "strands.operation": "tool.call",
30294
- "strands.tool.name": name,
30295
- provider: "strands"
30296
- }
30297
- },
30298
- name: `tool: ${name}`,
30299
- spanAttributes: { type: "tool" /* TOOL */ }
30300
- })
31308
+ () => startSpan(
31309
+ withSpanInstrumentationName(
31310
+ {
31311
+ event: {
31312
+ input: toolUse?.input,
31313
+ metadata: {
31314
+ "gen_ai.tool.call.id": toolUse?.toolUseId,
31315
+ "gen_ai.tool.name": name,
31316
+ "strands.operation": "tool.call",
31317
+ "strands.tool.name": name,
31318
+ provider: "strands"
31319
+ }
31320
+ },
31321
+ name: `tool: ${name}`,
31322
+ spanAttributes: { type: "tool" /* TOOL */ }
31323
+ },
31324
+ INSTRUMENTATION_NAMES.STRANDS_AGENT_SDK
31325
+ )
31326
+ )
30301
31327
  );
30302
31328
  state.activeTools.set(key, {
30303
31329
  span,
@@ -30368,11 +31394,16 @@ function startNodeSpan(state, event, activeChildParents) {
30368
31394
  };
30369
31395
  const span = withCurrent(
30370
31396
  state.span,
30371
- () => startSpan({
30372
- event: { metadata },
30373
- name: `node: ${nodeId}`,
30374
- spanAttributes: { type: "task" /* TASK */ }
30375
- })
31397
+ () => startSpan(
31398
+ withSpanInstrumentationName(
31399
+ {
31400
+ event: { metadata },
31401
+ name: `node: ${nodeId}`,
31402
+ spanAttributes: { type: "task" /* TASK */ }
31403
+ },
31404
+ INSTRUMENTATION_NAMES.STRANDS_AGENT_SDK
31405
+ )
31406
+ )
30376
31407
  );
30377
31408
  const nodeState = {
30378
31409
  ...child ? { child } : {},
@@ -31309,17 +32340,20 @@ var BraintrustObservabilityExporter = class {
31309
32340
  }
31310
32341
  onStart(exported) {
31311
32342
  if (this.spans.has(exported.id)) return;
31312
- const args = {
31313
- name: exported.name,
31314
- spanAttributes: { type: spanTypeFor(exported.type) },
31315
- startTime: epochSeconds(exported.startTime),
31316
- // Use the Mastra span id as the Braintrust row id so that
31317
- // `logFeedback({ id: <mastra span id> })` (and Mastra's score events)
31318
- // attach to the right row. Without this, `SpanImpl` auto-generates a
31319
- // row id (`this._id = eventId ?? idGenerator.getSpanId()`) that no
31320
- // external caller could know.
31321
- event: { id: exported.id }
31322
- };
32343
+ const args = withSpanInstrumentationName(
32344
+ {
32345
+ name: exported.name,
32346
+ spanAttributes: { type: spanTypeFor(exported.type) },
32347
+ startTime: epochSeconds(exported.startTime),
32348
+ // Use the Mastra span id as the Braintrust row id so that
32349
+ // `logFeedback({ id: <mastra span id> })` (and Mastra's score events)
32350
+ // attach to the right row. Without this, `SpanImpl` auto-generates a
32351
+ // row id (`this._id = eventId ?? idGenerator.getSpanId()`) that no
32352
+ // external caller could know.
32353
+ event: { id: exported.id }
32354
+ },
32355
+ INSTRUMENTATION_NAMES.MASTRA
32356
+ );
31323
32357
  const parentRecord = exported.parentSpanId ? this.spans.get(exported.parentSpanId) : void 0;
31324
32358
  if (!this.capturedParent) {
31325
32359
  const probe = currentSpan();
@@ -31623,7 +32657,13 @@ function configureNode() {
31623
32657
  isomorph_default.getPastNAncestors = getPastNAncestors;
31624
32658
  isomorph_default.getEnv = (name) => {
31625
32659
  const value = process.env[name];
31626
- return name === "BRAINTRUST_API_KEY" && !value?.trim() ? void 0 : value;
32660
+ if (name === "BRAINTRUST_API_KEY") {
32661
+ return value?.trim() ? value : void 0;
32662
+ }
32663
+ if ((name === "BRAINTRUST_ENVIRONMENT_TYPE" || name === "BRAINTRUST_ENVIRONMENT_NAME") && !value?.trim()) {
32664
+ return getNearestBraintrustEnvValue(name);
32665
+ }
32666
+ return value;
31627
32667
  };
31628
32668
  isomorph_default.getBraintrustApiKey = async () => {
31629
32669
  const value = process.env.BRAINTRUST_API_KEY;
@@ -31699,6 +32739,12 @@ function configureNode() {
31699
32739
  isomorph_default.gzip = promisify(zlib.gzip);
31700
32740
  isomorph_default.gunzip = promisify(zlib.gunzip);
31701
32741
  isomorph_default.hash = (data) => crypto.createHash("sha256").update(data).digest("hex");
32742
+ isomorph_default.hmacSha256 = (key, data) => crypto.createHmac("sha256", key).update(data).digest("hex");
32743
+ isomorph_default.timingSafeEqual = (left, right) => {
32744
+ const leftBuffer = Buffer.from(left);
32745
+ const rightBuffer = Buffer.from(right);
32746
+ return leftBuffer.length === rightBuffer.length && crypto.timingSafeEqual(leftBuffer, rightBuffer);
32747
+ };
31702
32748
  _internalSetInitialState();
31703
32749
  const disabled = readDisabledInstrumentationEnvConfig(
31704
32750
  isomorph_default.getEnv("BRAINTRUST_DISABLE_INSTRUMENTATION")
@@ -31708,6 +32754,24 @@ function configureNode() {
31708
32754
  }
31709
32755
  registry.enable();
31710
32756
  }
32757
+ function getNearestBraintrustEnvValue(name) {
32758
+ for (let dir = process.cwd(), depth = 0; depth <= BRAINTRUST_ENV_SEARCH_PARENT_LIMIT; dir = path.dirname(dir), depth++) {
32759
+ const envPath = path.join(dir, ".env.braintrust");
32760
+ try {
32761
+ const parsed = dotenv.parse(fsSync.readFileSync(envPath, "utf8"));
32762
+ const value = parsed[name];
32763
+ return value?.trim() ? value : void 0;
32764
+ } catch (e) {
32765
+ if (typeof e !== "object" || e === null || !("code" in e) || e.code !== "ENOENT") {
32766
+ return void 0;
32767
+ }
32768
+ }
32769
+ if (path.dirname(dir) === dir) {
32770
+ break;
32771
+ }
32772
+ }
32773
+ return void 0;
32774
+ }
31711
32775
 
31712
32776
  // src/wrappers/shared/format.ts
31713
32777
  function formatExperimentSummary(summary) {