@raindrop-ai/ai-sdk 0.3.1 → 0.3.2

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.
@@ -4,7 +4,69 @@ var async_hooks = require('async_hooks');
4
4
 
5
5
  // src/index.node.ts
6
6
 
7
- // ../core/dist/chunk-3V4MIA75.js
7
+ // ../core/dist/chunk-BYBMRLZM.js
8
+ var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
9
+ var PROBE_SCOPE = { correlationId: "" };
10
+ var EvalScopeStorage = class {
11
+ constructor() {
12
+ this._als = null;
13
+ this._probed = false;
14
+ }
15
+ maybeAdoptAsyncLocalStorage() {
16
+ if (this._probed) return;
17
+ this._probed = true;
18
+ try {
19
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
20
+ if (!Ctor) return;
21
+ const als = new Ctor();
22
+ als.run(PROBE_SCOPE, () => {
23
+ });
24
+ this._als = als;
25
+ } catch (e) {
26
+ this._als = null;
27
+ }
28
+ }
29
+ run(scope, callback) {
30
+ this.maybeAdoptAsyncLocalStorage();
31
+ if (this._als) return this._als.run(scope, callback);
32
+ const previous = this._syncScope;
33
+ this._syncScope = scope;
34
+ try {
35
+ return callback();
36
+ } finally {
37
+ this._syncScope = previous;
38
+ }
39
+ }
40
+ current() {
41
+ this.maybeAdoptAsyncLocalStorage();
42
+ if (this._als) return this._als.getStore();
43
+ return this._syncScope;
44
+ }
45
+ };
46
+ var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
47
+ function evalScopeStorage() {
48
+ const holder = globalThis;
49
+ let storage = holder[EVAL_SCOPE_STORAGE_KEY];
50
+ if (!storage) {
51
+ storage = new EvalScopeStorage();
52
+ holder[EVAL_SCOPE_STORAGE_KEY] = storage;
53
+ }
54
+ return storage;
55
+ }
56
+ function currentEvalScope() {
57
+ try {
58
+ return evalScopeStorage().current();
59
+ } catch (e) {
60
+ return void 0;
61
+ }
62
+ }
63
+ function evalScopeAttributes() {
64
+ const scope = currentEvalScope();
65
+ if (!scope) return {};
66
+ return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
67
+ }
68
+
69
+ // ../core/dist/chunk-T53LQAH7.js
8
70
  function normalizeFeatureFlags(input) {
9
71
  if (Array.isArray(input)) {
10
72
  return Object.fromEntries(input.map((name) => [name, "true"]));
@@ -499,6 +561,7 @@ async function postJson(url, body, headers, opts) {
499
561
  const resp = await runWithTracingSuppressed(
500
562
  () => fetch(url, {
501
563
  method: "POST",
564
+ redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
502
565
  headers: {
503
566
  "Content-Type": "application/json",
504
567
  ...headers
@@ -622,6 +685,55 @@ function buildExportTraceServiceRequest(spans, serviceName = "raindrop.core", se
622
685
  ]
623
686
  };
624
687
  }
688
+ var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
689
+ function state() {
690
+ const holder = globalThis;
691
+ let current = holder[STATE_KEY];
692
+ if (!current) {
693
+ let storage = null;
694
+ try {
695
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
696
+ if (Ctor) storage = new Ctor();
697
+ } catch (e) {
698
+ storage = null;
699
+ }
700
+ current = {
701
+ storage,
702
+ syncDestination: void 0,
703
+ spanDestinations: /* @__PURE__ */ new WeakMap()
704
+ };
705
+ holder[STATE_KEY] = current;
706
+ }
707
+ return current;
708
+ }
709
+ function currentReplayTraceDestination() {
710
+ var _a, _b;
711
+ const routing = state();
712
+ return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
713
+ }
714
+ function rememberReplayTraceDestination(span) {
715
+ const destination = currentReplayTraceDestination();
716
+ if (destination) state().spanDestinations.set(span, destination);
717
+ }
718
+ function copyReplayTraceDestination(source, target) {
719
+ const destination = state().spanDestinations.get(source);
720
+ if (destination) state().spanDestinations.set(target, destination);
721
+ }
722
+ function replayTraceDestinationFor(value) {
723
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
724
+ return void 0;
725
+ }
726
+ return state().spanDestinations.get(value);
727
+ }
728
+ function recordReplayExportedSpan(destination, spanId, traceId) {
729
+ var _a, _b;
730
+ if (!destination || !spanId || !traceId) return;
731
+ (_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
732
+ (_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
733
+ }
734
+ function replayTraceUrl(baseUrl) {
735
+ return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
736
+ }
625
737
  var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
626
738
  var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
627
739
  var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
@@ -687,31 +799,36 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
687
799
  function localDebuggerEnabled(baseUrl) {
688
800
  return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
689
801
  }
802
+ var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
690
803
  function mirrorTraceExportToLocalDebugger(body, options = {}) {
691
804
  var _a;
692
805
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
693
- if (!baseUrl) return;
694
- void postJson(`${baseUrl}traces`, body, {}, {
806
+ if (!baseUrl) return Promise.resolve();
807
+ return postJson(`${baseUrl}traces`, body, {}, {
695
808
  maxAttempts: 1,
696
809
  debug: (_a = options.debug) != null ? _a : false,
697
- sdkName: options.sdkName
810
+ sdkName: options.sdkName,
811
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
698
812
  }).catch(() => {
699
813
  });
700
814
  }
701
815
  function mirrorPartialEventToLocalDebugger(event, options = {}) {
702
816
  var _a;
703
817
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
704
- if (!baseUrl) return;
818
+ if (!baseUrl) return Promise.resolve();
705
819
  const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
706
- void postJson(`${baseUrl}events/track_partial`, event, headers, {
820
+ return postJson(`${baseUrl}events/track_partial`, event, headers, {
707
821
  maxAttempts: 1,
708
822
  debug: (_a = options.debug) != null ? _a : false,
709
- sdkName: options.sdkName
823
+ sdkName: options.sdkName,
824
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
710
825
  }).catch(() => {
711
826
  });
712
827
  }
713
828
  function sendLocalDebuggerLiveEvent(event, options = {}) {
714
829
  var _a, _b;
830
+ const destination = currentReplayTraceDestination();
831
+ if (destination && destination.kind !== "workshop") return;
715
832
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
716
833
  if (!baseUrl) return;
717
834
  void postJson(
@@ -883,6 +1000,15 @@ var EventShipper = class {
883
1000
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
884
1001
  if (!this.enabled) return;
885
1002
  if (!eventId || !eventId.trim()) return;
1003
+ const capturedSticky = this.sticky.get(eventId);
1004
+ const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
1005
+ const destination = currentReplayTraceDestination();
1006
+ const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
1007
+ if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
1008
+ if (patch.isPending === false) this.sticky.delete(eventId);
1009
+ else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
1010
+ return;
1011
+ }
886
1012
  const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
887
1013
  if (typeof patch.input === "string" && patch.input.length > maxChars) {
888
1014
  patch = { ...patch, input: capText(patch.input, maxChars) };
@@ -941,6 +1067,9 @@ var EventShipper = class {
941
1067
  try {
942
1068
  for (const t of this.timers.values()) clearTimeout(t);
943
1069
  this.timers.clear();
1070
+ for (const [eventId, sticky] of this.sticky) {
1071
+ if (sticky.replayOnly) this.sticky.delete(eventId);
1072
+ }
944
1073
  const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
945
1074
  if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
946
1075
  } finally {
@@ -950,6 +1079,8 @@ var EventShipper = class {
950
1079
  async trackSignal(signal) {
951
1080
  var _a, _b;
952
1081
  if (!this.enabled) return;
1082
+ const destination = currentReplayTraceDestination();
1083
+ if (destination && destination.kind !== "workshop") return;
953
1084
  const body = [
954
1085
  {
955
1086
  event_id: signal.eventId,
@@ -984,6 +1115,8 @@ var EventShipper = class {
984
1115
  }
985
1116
  async identify(users) {
986
1117
  if (!this.enabled) return;
1118
+ const destination = currentReplayTraceDestination();
1119
+ if (destination && destination.kind !== "workshop") return;
987
1120
  const list = Array.isArray(users) ? users : [users];
988
1121
  const body = list.filter((user) => {
989
1122
  if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
@@ -1036,8 +1169,9 @@ var EventShipper = class {
1036
1169
  this.buffers.delete(eventId);
1037
1170
  if (!accumulated) return;
1038
1171
  const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
1039
- const eventName = (_c = (_b = accumulated.eventName) != null ? _b : sticky.eventName) != null ? _c : this.defaultEventName;
1040
- const userId = (_d = accumulated.userId) != null ? _d : sticky.userId;
1172
+ const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
1173
+ const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
1174
+ const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
1041
1175
  if (!userId) {
1042
1176
  if (this.debug) {
1043
1177
  console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
@@ -1045,14 +1179,13 @@ var EventShipper = class {
1045
1179
  this.sticky.delete(eventId);
1046
1180
  return;
1047
1181
  }
1048
- const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
1182
+ const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
1049
1183
  let telemetryProperties = {};
1050
1184
  try {
1051
1185
  telemetryProperties = eventTelemetryProperties(accumulated);
1052
1186
  } catch (e) {
1053
1187
  }
1054
- const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
1055
- const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
1188
+ const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
1056
1189
  const payload = {
1057
1190
  event_id: eventId,
1058
1191
  user_id: userId,
@@ -1094,29 +1227,30 @@ var EventShipper = class {
1094
1227
  endpoint: url
1095
1228
  });
1096
1229
  }
1097
- if (this.localDebuggerUrl) {
1098
- mirrorPartialEventToLocalDebugger(payload, {
1099
- baseUrl: this.localDebuggerUrl,
1100
- writeKey: this.writeKey,
1101
- debug: this.debug,
1102
- sdkName: this.sdkName
1103
- });
1104
- }
1230
+ const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
1231
+ baseUrl: this.localDebuggerUrl,
1232
+ writeKey: this.writeKey,
1233
+ debug: this.debug,
1234
+ sdkName: this.sdkName
1235
+ }) : void 0;
1105
1236
  if (!this.writeKey) {
1106
1237
  if (!isPending) this.sticky.delete(eventId);
1238
+ if (mirror) await mirror;
1107
1239
  return;
1108
1240
  }
1109
1241
  const opts = this.requestOpts();
1110
1242
  if (!opts) {
1111
1243
  this.warnShutdownDrop(`track_partial ${eventId}`);
1112
1244
  if (!isPending) this.sticky.delete(eventId);
1245
+ if (mirror) await mirror;
1113
1246
  return;
1114
1247
  }
1115
1248
  const p = postJson(url, payload, this.requestHeaders(), opts);
1116
- this.inFlight.add(p);
1249
+ const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
1250
+ this.inFlight.add(combined);
1117
1251
  try {
1118
1252
  try {
1119
- await p;
1253
+ await combined;
1120
1254
  if (this.debug) {
1121
1255
  console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
1122
1256
  }
@@ -1128,7 +1262,7 @@ var EventShipper = class {
1128
1262
  );
1129
1263
  }
1130
1264
  } finally {
1131
- this.inFlight.delete(p);
1265
+ this.inFlight.delete(combined);
1132
1266
  }
1133
1267
  if (!isPending) {
1134
1268
  this.sticky.delete(eventId);
@@ -1476,7 +1610,10 @@ var TraceShipper = class {
1476
1610
  try {
1477
1611
  const result = this.transformSpanHook(current);
1478
1612
  if (result === null) return null;
1479
- if (result !== void 0) current = result;
1613
+ if (result !== void 0) {
1614
+ copyReplayTraceDestination(current, result);
1615
+ current = result;
1616
+ }
1480
1617
  } catch (err) {
1481
1618
  if (this.debug) {
1482
1619
  const msg = err instanceof Error ? err.message : String(err);
@@ -1486,13 +1623,19 @@ var TraceShipper = class {
1486
1623
  }
1487
1624
  }
1488
1625
  try {
1489
- current = normalizeModelUsageSpan(current);
1626
+ const normalized = normalizeModelUsageSpan(current);
1627
+ copyReplayTraceDestination(current, normalized);
1628
+ current = normalized;
1490
1629
  } catch (e) {
1491
1630
  }
1492
1631
  if (!this.disableDefaultRedaction) {
1493
- current = defaultTransformSpan(current);
1632
+ const redacted = defaultTransformSpan(current);
1633
+ copyReplayTraceDestination(current, redacted);
1634
+ current = redacted;
1494
1635
  }
1495
- return this.capSpanAttributes(current);
1636
+ const capped = this.capSpanAttributes(current);
1637
+ copyReplayTraceDestination(current, capped);
1638
+ return capped;
1496
1639
  }
1497
1640
  isDebugEnabled() {
1498
1641
  return this.debug;
@@ -1510,33 +1653,54 @@ var TraceShipper = class {
1510
1653
  const attrs = [
1511
1654
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1512
1655
  ...identityAttrs(args),
1513
- attrString("ai.operationId", args.operationId)
1656
+ attrString("ai.operationId", args.operationId),
1657
+ ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1514
1658
  ];
1515
1659
  if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
1516
- const span = { ids, name: args.name, startTimeUnixNano: started, attributes: attrs };
1517
- this.mirrorToLocalDebugger(
1518
- buildOtlpSpan({
1519
- ids: span.ids,
1520
- name: span.name,
1521
- startTimeUnixNano: span.startTimeUnixNano,
1522
- endTimeUnixNano: span.startTimeUnixNano,
1523
- // placeholder — will be updated on endSpan
1524
- attributes: span.attributes,
1525
- status: { code: SpanStatusCode.UNSET }
1526
- })
1527
- );
1660
+ const span = {
1661
+ ids,
1662
+ name: args.name,
1663
+ startTimeUnixNano: started,
1664
+ attributes: attrs
1665
+ };
1666
+ rememberReplayTraceDestination(span);
1667
+ const openSpan = buildOtlpSpan({
1668
+ ids: span.ids,
1669
+ name: span.name,
1670
+ startTimeUnixNano: span.startTimeUnixNano,
1671
+ endTimeUnixNano: span.startTimeUnixNano,
1672
+ // placeholder — will be updated on endSpan
1673
+ attributes: span.attributes,
1674
+ status: { code: SpanStatusCode.UNSET }
1675
+ });
1676
+ copyReplayTraceDestination(span, openSpan);
1677
+ this.mirrorToLocalDebugger(openSpan);
1528
1678
  return span;
1529
1679
  }
1530
- mirrorToLocalDebugger(span) {
1531
- if (!this.localDebuggerUrl) return;
1680
+ mirrorToLocalDebugger(span, completed = false) {
1681
+ const destination = replayTraceDestinationFor(span);
1682
+ if (destination && destination.kind !== "workshop") return;
1683
+ const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
1684
+ if (!localDebuggerUrl) return;
1532
1685
  const redacted = this.redactSpan(span);
1533
1686
  if (redacted === null) return;
1687
+ if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
1688
+ recordReplayExportedSpan(
1689
+ destination,
1690
+ base64ToHex(redacted.spanId),
1691
+ base64ToHex(redacted.traceId)
1692
+ );
1693
+ }
1534
1694
  const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
1535
- mirrorTraceExportToLocalDebugger(body, {
1536
- baseUrl: this.localDebuggerUrl,
1695
+ const p = mirrorTraceExportToLocalDebugger(body, {
1696
+ baseUrl: localDebuggerUrl,
1537
1697
  debug: false,
1538
1698
  sdkName: this.sdkName
1539
1699
  });
1700
+ this.inFlight.add(p);
1701
+ void p.finally(() => {
1702
+ this.inFlight.delete(p);
1703
+ });
1540
1704
  }
1541
1705
  endSpan(span, extra) {
1542
1706
  var _a, _b;
@@ -1558,15 +1722,17 @@ var TraceShipper = class {
1558
1722
  attributes: span.attributes,
1559
1723
  status
1560
1724
  });
1725
+ copyReplayTraceDestination(span, otlp);
1561
1726
  this.enqueue(otlp);
1562
- this.mirrorToLocalDebugger(otlp);
1727
+ this.mirrorToLocalDebugger(otlp, true);
1563
1728
  }
1564
1729
  createSpan(args) {
1565
1730
  var _a;
1566
1731
  const ids = createSpanIds(args.parent);
1567
1732
  const attrs = [
1568
1733
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1569
- ...identityAttrs(args)
1734
+ ...identityAttrs(args),
1735
+ ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1570
1736
  ];
1571
1737
  if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
1572
1738
  const otlp = buildOtlpSpan({
@@ -1577,8 +1743,9 @@ var TraceShipper = class {
1577
1743
  attributes: attrs,
1578
1744
  status: args.status
1579
1745
  });
1746
+ rememberReplayTraceDestination(otlp);
1580
1747
  this.enqueue(otlp);
1581
- this.mirrorToLocalDebugger(otlp);
1748
+ this.mirrorToLocalDebugger(otlp, true);
1582
1749
  }
1583
1750
  enqueue(span) {
1584
1751
  if (!this.enabled) return;
@@ -1592,6 +1759,13 @@ var TraceShipper = class {
1592
1759
  }
1593
1760
  const redacted = this.redactSpan(span);
1594
1761
  if (redacted === null) return;
1762
+ const destination = replayTraceDestinationFor(redacted);
1763
+ recordReplayExportedSpan(
1764
+ destination,
1765
+ base64ToHex(redacted.spanId),
1766
+ base64ToHex(redacted.traceId)
1767
+ );
1768
+ if ((destination == null ? void 0 : destination.kind) === "workshop") return;
1595
1769
  if (this.queue.length >= this.maxQueueSize) {
1596
1770
  this.queue.shift();
1597
1771
  }
@@ -1610,47 +1784,67 @@ var TraceShipper = class {
1610
1784
  }
1611
1785
  }
1612
1786
  async flush() {
1613
- if (!this.enabled) return;
1787
+ var _a;
1788
+ if (!this.enabled) {
1789
+ await Promise.all([...this.inFlight].map((p) => p.catch(() => {
1790
+ })));
1791
+ return;
1792
+ }
1614
1793
  if (this.timer) {
1615
1794
  clearTimeout(this.timer);
1616
1795
  this.timer = void 0;
1617
1796
  }
1618
1797
  while (this.queue.length > 0) {
1619
1798
  const batch = this.queue.splice(0, this.maxBatchSize);
1620
- if (!this.writeKey) continue;
1621
- const opts = this.requestOpts();
1622
- if (!opts) {
1623
- rateLimitedLog(
1624
- `${this.prefix}.shutdown_deadline`,
1625
- () => console.warn(
1626
- `${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
1627
- )
1628
- );
1629
- continue;
1799
+ const groups = /* @__PURE__ */ new Map();
1800
+ for (const span of batch) {
1801
+ const destination = replayTraceDestinationFor(span);
1802
+ const spans = groups.get(destination);
1803
+ if (spans) spans.push(span);
1804
+ else groups.set(destination, [span]);
1630
1805
  }
1631
- const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
1632
- const url = `${this.baseUrl}traces`;
1633
- if (this.debug) {
1634
- console.log(`${this.prefix} sending traces batch`, {
1635
- spans: batch.length,
1636
- endpoint: url
1637
- });
1638
- }
1639
- const p = postJson(url, body, this.requestHeaders(), opts);
1640
- this.inFlight.add(p);
1641
- try {
1642
- try {
1643
- await p;
1644
- if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
1645
- } catch (err) {
1646
- const msg = err instanceof Error ? err.message : String(err);
1806
+ for (const [destination, spans] of groups) {
1807
+ if (!destination && !this.writeKey) continue;
1808
+ if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
1809
+ const opts = this.requestOpts();
1810
+ if (!opts) {
1647
1811
  rateLimitedLog(
1648
- `${this.prefix}.send_spans_failed`,
1649
- () => console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`)
1812
+ `${this.prefix}.shutdown_deadline`,
1813
+ () => console.warn(
1814
+ `${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
1815
+ )
1650
1816
  );
1817
+ continue;
1818
+ }
1819
+ const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
1820
+ const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
1821
+ const headers = destination ? {
1822
+ Authorization: `Bearer ${destination.apiKey}`,
1823
+ "X-Raindrop-Replay-Id": destination.replayId,
1824
+ "X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
1825
+ } : this.requestHeaders();
1826
+ if (this.debug) {
1827
+ console.log(`${this.prefix} sending traces batch`, {
1828
+ spans: spans.length,
1829
+ endpoint: url
1830
+ });
1831
+ }
1832
+ const p = postJson(url, body, headers, opts);
1833
+ this.inFlight.add(p);
1834
+ try {
1835
+ try {
1836
+ await p;
1837
+ if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
1838
+ } catch (err) {
1839
+ const msg = err instanceof Error ? err.message : String(err);
1840
+ rateLimitedLog(
1841
+ `${this.prefix}.send_spans_failed`,
1842
+ () => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
1843
+ );
1844
+ }
1845
+ } finally {
1846
+ this.inFlight.delete(p);
1651
1847
  }
1652
- } finally {
1653
- this.inFlight.delete(p);
1654
1848
  }
1655
1849
  }
1656
1850
  }
@@ -1693,7 +1887,9 @@ var TraceShipper = class {
1693
1887
  if (!settled) {
1694
1888
  rateLimitedLog(
1695
1889
  `${this.prefix}.shutdown_deadline`,
1696
- () => console.warn(`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`)
1890
+ () => console.warn(
1891
+ `${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
1892
+ )
1697
1893
  );
1698
1894
  }
1699
1895
  } finally {
@@ -1788,7 +1984,8 @@ function withCurrent(span, callback) {
1788
1984
  return getContextManager().runInContext(span, callback);
1789
1985
  }
1790
1986
  async function getCurrentParentSpanContext() {
1791
- return getContextManager().getParentSpanIds();
1987
+ var _a, _b;
1988
+ return (_b = getContextManager().getParentSpanIds()) != null ? _b : (_a = currentReplayTraceDestination()) == null ? void 0 : _a.parentSpanContext;
1792
1989
  }
1793
1990
  async function runWithParentSpanContext(ctx, fn) {
1794
1991
  const cm = getContextManager();
@@ -1848,7 +2045,7 @@ installTracingSuppressionHook();
1848
2045
  // package.json
1849
2046
  var package_default = {
1850
2047
  name: "@raindrop-ai/ai-sdk",
1851
- version: "0.3.1"};
2048
+ version: "0.3.2"};
1852
2049
 
1853
2050
  // src/internal/version.ts
1854
2051
  var libraryName = package_default.name;
@@ -3374,13 +3571,13 @@ var RaindropTelemetryIntegration = class {
3374
3571
  };
3375
3572
  // ── onStepStart ─────────────────────────────────────────────────────────
3376
3573
  this.onStepStart = (event) => {
3377
- const state = this.getState(event.callId);
3378
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
3379
- const isStream = state.operationId === "ai.streamText" || state.operationId === "ai.streamObject";
3380
- const stepOperationId = isStream ? `${state.operationId}.doStream` : `${state.operationId}.doGenerate`;
3381
- const { operationName, resourceName } = opName(stepOperationId, state.functionId);
3574
+ const state2 = this.getState(event.callId);
3575
+ if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
3576
+ const isStream = state2.operationId === "ai.streamText" || state2.operationId === "ai.streamObject";
3577
+ const stepOperationId = isStream ? `${state2.operationId}.doStream` : `${state2.operationId}.doGenerate`;
3578
+ const { operationName, resourceName } = opName(stepOperationId, state2.functionId);
3382
3579
  const inputAttrs = [];
3383
- if (state.recordInputs) {
3580
+ if (state2.recordInputs) {
3384
3581
  if (event.promptMessages) {
3385
3582
  inputAttrs.push(attrString("ai.prompt.messages", safeJsonWithUint8(event.promptMessages)));
3386
3583
  }
@@ -3403,25 +3600,25 @@ var RaindropTelemetryIntegration = class {
3403
3600
  }
3404
3601
  const stepSpan = this.traceShipper.startSpan({
3405
3602
  name: stepOperationId,
3406
- parent: state.rootParent,
3407
- eventId: state.eventId,
3408
- ...state.identity,
3603
+ parent: state2.rootParent,
3604
+ eventId: state2.eventId,
3605
+ ...state2.identity,
3409
3606
  operationId: stepOperationId,
3410
3607
  attributes: [
3411
3608
  attrString("operation.name", operationName),
3412
3609
  attrString("resource.name", resourceName),
3413
- attrString("ai.telemetry.functionId", state.functionId),
3610
+ attrString("ai.telemetry.functionId", state2.functionId),
3414
3611
  ...attrsFromModelProvider(event.provider),
3415
3612
  attrString("ai.model.id", event.modelId),
3416
3613
  attrString(MODEL_USAGE_ATTRIBUTES.requestModel, event.modelId),
3417
3614
  ...inputAttrs,
3418
- ...handoffSpanAttrs(state.handoff)
3615
+ ...handoffSpanAttrs(state2.handoff)
3419
3616
  ]
3420
3617
  });
3421
- state.stepSpan = stepSpan;
3422
- state.stepParent = this.spanParentRef(stepSpan);
3423
- state.stepProvider = event.provider;
3424
- state.stepModelId = event.modelId;
3618
+ state2.stepSpan = stepSpan;
3619
+ state2.stepParent = this.spanParentRef(stepSpan);
3620
+ state2.stepProvider = event.provider;
3621
+ state2.stepModelId = event.modelId;
3425
3622
  };
3426
3623
  this.onToolExecutionStart = (event) => this.toolExecutionStart(event);
3427
3624
  this.onToolExecutionEnd = (event) => this.toolExecutionEnd(event);
@@ -3448,33 +3645,33 @@ var RaindropTelemetryIntegration = class {
3448
3645
  var _a, _b, _c, _d, _e;
3449
3646
  const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
3450
3647
  if (!callId) return;
3451
- const state = this.getState(callId);
3452
- if (!state) return;
3648
+ const state2 = this.getState(callId);
3649
+ if (!state2) return;
3453
3650
  const chunk = event.chunk;
3454
3651
  if (!chunk || typeof chunk !== "object") return;
3455
3652
  if (chunk.type === "text-delta") {
3456
3653
  const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
3457
3654
  if (typeof delta === "string") {
3458
- if (state.accumulatedText.length <= effectiveMaxTextFieldChars()) {
3459
- state.accumulatedText += delta;
3655
+ if (state2.accumulatedText.length <= effectiveMaxTextFieldChars()) {
3656
+ state2.accumulatedText += delta;
3460
3657
  }
3461
- this.emitLive(state, "text_delta", delta);
3658
+ this.emitLive(state2, "text_delta", delta);
3462
3659
  }
3463
3660
  } else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
3464
3661
  const text = (_e = (_d = chunk.textDelta) != null ? _d : chunk.text) != null ? _e : chunk.delta;
3465
3662
  if (typeof text === "string") {
3466
- this.emitLive(state, "reasoning_delta", text);
3663
+ this.emitLive(state2, "reasoning_delta", text);
3467
3664
  }
3468
3665
  }
3469
3666
  };
3470
3667
  // ── onStepFinish ────────────────────────────────────────────────────────
3471
3668
  this.onStepFinish = (event) => {
3472
3669
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
3473
- const state = this.getState(event.callId);
3474
- if (!(state == null ? void 0 : state.stepSpan)) return;
3475
- const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b : state.stepModelId;
3670
+ const state2 = this.getState(event.callId);
3671
+ if (!(state2 == null ? void 0 : state2.stepSpan)) return;
3672
+ const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b : state2.stepModelId;
3476
3673
  const outputAttrs = [];
3477
- if (state.recordOutputs) {
3674
+ if (state2.recordOutputs) {
3478
3675
  outputAttrs.push(
3479
3676
  attrString("ai.response.finishReason", event.finishReason),
3480
3677
  attrString("ai.response.text", capText2((_c = event.text) != null ? _c : void 0)),
@@ -3519,7 +3716,7 @@ var RaindropTelemetryIntegration = class {
3519
3716
  if (usage) {
3520
3717
  const usageMetrics = extractUsageMetricsFromUsage(
3521
3718
  usage,
3522
- state.stepProvider,
3719
+ state2.stepProvider,
3523
3720
  event.providerMetadata
3524
3721
  );
3525
3722
  outputAttrs.push(
@@ -3532,51 +3729,51 @@ var RaindropTelemetryIntegration = class {
3532
3729
  ...buildRawModelUsageAttributes(usageMetrics)
3533
3730
  );
3534
3731
  }
3535
- this.emitProviderExecutedToolSpans(event, state);
3536
- this.traceShipper.endSpan(state.stepSpan, { attributes: outputAttrs });
3537
- state.stepSpan = void 0;
3538
- state.stepParent = void 0;
3539
- state.stepProvider = void 0;
3540
- state.stepModelId = void 0;
3732
+ this.emitProviderExecutedToolSpans(event, state2);
3733
+ this.traceShipper.endSpan(state2.stepSpan, { attributes: outputAttrs });
3734
+ state2.stepSpan = void 0;
3735
+ state2.stepParent = void 0;
3736
+ state2.stepProvider = void 0;
3737
+ state2.stepModelId = void 0;
3541
3738
  };
3542
3739
  // ── onEmbedStart ────────────────────────────────────────────────────────
3543
3740
  this.onEmbedStart = (event) => {
3544
- const state = this.getState(event.callId);
3545
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
3546
- const { operationName, resourceName } = opName(event.operationId, state.functionId);
3547
- const inputAttrs = state.recordInputs ? [attrString("ai.values", safeJsonWithUint8(event.values))] : [];
3741
+ const state2 = this.getState(event.callId);
3742
+ if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
3743
+ const { operationName, resourceName } = opName(event.operationId, state2.functionId);
3744
+ const inputAttrs = state2.recordInputs ? [attrString("ai.values", safeJsonWithUint8(event.values))] : [];
3548
3745
  const embedSpan = this.traceShipper.startSpan({
3549
3746
  name: event.operationId,
3550
- parent: state.rootParent,
3551
- eventId: state.eventId,
3552
- ...state.identity,
3747
+ parent: state2.rootParent,
3748
+ eventId: state2.eventId,
3749
+ ...state2.identity,
3553
3750
  operationId: event.operationId,
3554
3751
  attributes: [
3555
3752
  attrString("operation.name", operationName),
3556
3753
  attrString("resource.name", resourceName),
3557
- attrString("ai.telemetry.functionId", state.functionId),
3754
+ attrString("ai.telemetry.functionId", state2.functionId),
3558
3755
  ...inputAttrs,
3559
- ...handoffSpanAttrs(state.handoff)
3756
+ ...handoffSpanAttrs(state2.handoff)
3560
3757
  ]
3561
3758
  });
3562
- state.embedSpans.set(event.embedCallId, embedSpan);
3759
+ state2.embedSpans.set(event.embedCallId, embedSpan);
3563
3760
  };
3564
3761
  // ── onEmbedFinish ───────────────────────────────────────────────────────
3565
3762
  this.onEmbedFinish = (event) => {
3566
3763
  var _a;
3567
- const state = this.getState(event.callId);
3568
- if (!state) return;
3569
- const embedSpan = state.embedSpans.get(event.embedCallId);
3764
+ const state2 = this.getState(event.callId);
3765
+ if (!state2) return;
3766
+ const embedSpan = state2.embedSpans.get(event.embedCallId);
3570
3767
  if (!embedSpan) return;
3571
3768
  const outputAttrs = [];
3572
- if (state.recordOutputs) {
3769
+ if (state2.recordOutputs) {
3573
3770
  outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embeddings)));
3574
3771
  }
3575
3772
  if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
3576
3773
  outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
3577
3774
  }
3578
3775
  this.traceShipper.endSpan(embedSpan, { attributes: outputAttrs });
3579
- state.embedSpans.delete(event.embedCallId);
3776
+ state2.embedSpans.delete(event.embedCallId);
3580
3777
  };
3581
3778
  // v7 canary.159 renamed `onEmbedFinish` -> `onEmbedEnd`. Both names forward
3582
3779
  // to the same implementation; the installed SDK only wires up whichever it
@@ -3584,16 +3781,16 @@ var RaindropTelemetryIntegration = class {
3584
3781
  this.onEmbedEnd = (event) => this.onEmbedFinish(event);
3585
3782
  // ── onFinish ────────────────────────────────────────────────────────────
3586
3783
  this.onFinish = (event) => {
3587
- const state = this.getState(event.callId);
3588
- if (!state) return;
3589
- const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
3784
+ const state2 = this.getState(event.callId);
3785
+ if (!state2) return;
3786
+ const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
3590
3787
  if (isEmbed) {
3591
- this.finishEmbed(event, state);
3788
+ this.finishEmbed(event, state2);
3592
3789
  } else {
3593
- this.finishGenerate(event, state);
3790
+ this.finishGenerate(event, state2);
3594
3791
  }
3595
- if (state.subagentToolCallSpan) {
3596
- this.traceShipper.endSpan(state.subagentToolCallSpan);
3792
+ if (state2.subagentToolCallSpan) {
3793
+ this.traceShipper.endSpan(state2.subagentToolCallSpan);
3597
3794
  }
3598
3795
  this.cleanup(event.callId);
3599
3796
  };
@@ -3608,42 +3805,42 @@ var RaindropTelemetryIntegration = class {
3608
3805
  var _a;
3609
3806
  const event = error;
3610
3807
  if (!(event == null ? void 0 : event.callId)) return;
3611
- const state = this.getState(event.callId);
3612
- if (!state) return;
3808
+ const state2 = this.getState(event.callId);
3809
+ if (!state2) return;
3613
3810
  const actualError = (_a = event.error) != null ? _a : error;
3614
- if (state.stepSpan) {
3615
- this.traceShipper.endSpan(state.stepSpan, { error: actualError });
3616
- state.stepProvider = void 0;
3617
- state.stepModelId = void 0;
3811
+ if (state2.stepSpan) {
3812
+ this.traceShipper.endSpan(state2.stepSpan, { error: actualError });
3813
+ state2.stepProvider = void 0;
3814
+ state2.stepModelId = void 0;
3618
3815
  }
3619
- for (const embedSpan of state.embedSpans.values()) {
3816
+ for (const embedSpan of state2.embedSpans.values()) {
3620
3817
  this.traceShipper.endSpan(embedSpan, { error: actualError });
3621
3818
  }
3622
- state.embedSpans.clear();
3623
- for (const toolCallId of state.parentContextToolCallIds) {
3819
+ state2.embedSpans.clear();
3820
+ for (const toolCallId of state2.parentContextToolCallIds) {
3624
3821
  this.priorParentContexts.delete(toolCallId);
3625
3822
  }
3626
- state.parentContextToolCallIds.clear();
3627
- for (const toolSpan of state.toolSpans.values()) {
3823
+ state2.parentContextToolCallIds.clear();
3824
+ for (const toolSpan of state2.toolSpans.values()) {
3628
3825
  this.traceShipper.endSpan(toolSpan, { error: actualError });
3629
3826
  }
3630
- state.toolSpans.clear();
3827
+ state2.toolSpans.clear();
3631
3828
  const abortReason = describeAbortReason(actualError);
3632
- if (state.rootSpan) {
3633
- this.traceShipper.endSpan(state.rootSpan, {
3829
+ if (state2.rootSpan) {
3830
+ this.traceShipper.endSpan(state2.rootSpan, {
3634
3831
  error: actualError,
3635
- attributes: this.abortOutcomeAttrs(state, abortReason, "error")
3832
+ attributes: this.abortOutcomeAttrs(state2, abortReason, "error")
3636
3833
  });
3637
3834
  }
3638
- if (state.subagentToolCallSpan) {
3639
- this.traceShipper.endSpan(state.subagentToolCallSpan, { error: actualError });
3835
+ if (state2.subagentToolCallSpan) {
3836
+ this.traceShipper.endSpan(state2.subagentToolCallSpan, { error: actualError });
3640
3837
  }
3641
- const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
3838
+ const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
3642
3839
  if (!isEmbed) {
3643
- const errorIsTheRunsOutcome = state.handoff !== void 0 && !state.nestedInEvent;
3840
+ const errorIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
3644
3841
  this.finalizeGenerateEvent(
3645
- state,
3646
- state.accumulatedText || void 0,
3842
+ state2,
3843
+ state2.accumulatedText || void 0,
3647
3844
  void 0,
3648
3845
  false,
3649
3846
  errorIsTheRunsOutcome ? { fallbackOutput: abortReason } : void 0
@@ -3662,51 +3859,51 @@ var RaindropTelemetryIntegration = class {
3662
3859
  this.onAbort = (event) => {
3663
3860
  const callId = event == null ? void 0 : event.callId;
3664
3861
  if (!callId) return;
3665
- const state = this.getState(callId);
3666
- if (!state) return;
3862
+ const state2 = this.getState(callId);
3863
+ if (!state2) return;
3667
3864
  const abortedAttr = attrString("ai.response.aborted", "true");
3668
- if (state.stepSpan) {
3669
- this.traceShipper.endSpan(state.stepSpan, { attributes: [abortedAttr] });
3670
- state.stepSpan = void 0;
3671
- state.stepParent = void 0;
3672
- state.stepProvider = void 0;
3673
- state.stepModelId = void 0;
3865
+ if (state2.stepSpan) {
3866
+ this.traceShipper.endSpan(state2.stepSpan, { attributes: [abortedAttr] });
3867
+ state2.stepSpan = void 0;
3868
+ state2.stepParent = void 0;
3869
+ state2.stepProvider = void 0;
3870
+ state2.stepModelId = void 0;
3674
3871
  }
3675
- for (const embedSpan of state.embedSpans.values()) {
3872
+ for (const embedSpan of state2.embedSpans.values()) {
3676
3873
  this.traceShipper.endSpan(embedSpan, { attributes: [abortedAttr] });
3677
3874
  }
3678
- state.embedSpans.clear();
3679
- for (const toolCallId of state.parentContextToolCallIds) {
3875
+ state2.embedSpans.clear();
3876
+ for (const toolCallId of state2.parentContextToolCallIds) {
3680
3877
  this.priorParentContexts.delete(toolCallId);
3681
3878
  }
3682
- state.parentContextToolCallIds.clear();
3683
- for (const toolSpan of state.toolSpans.values()) {
3879
+ state2.parentContextToolCallIds.clear();
3880
+ for (const toolSpan of state2.toolSpans.values()) {
3684
3881
  this.traceShipper.endSpan(toolSpan, { attributes: [abortedAttr] });
3685
3882
  }
3686
- state.toolSpans.clear();
3687
- const abortIsTheRunsOutcome = state.handoff !== void 0 && !state.nestedInEvent;
3688
- if (state.rootSpan) {
3689
- this.traceShipper.endSpan(state.rootSpan, {
3883
+ state2.toolSpans.clear();
3884
+ const abortIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
3885
+ if (state2.rootSpan) {
3886
+ this.traceShipper.endSpan(state2.rootSpan, {
3690
3887
  attributes: [
3691
3888
  abortedAttr,
3692
- attrInt("ai.toolCall.count", state.toolCallCount),
3889
+ attrInt("ai.toolCall.count", state2.toolCallCount),
3693
3890
  // An aborted detached child IS a cancelled sub-agent, and a cancelled
3694
3891
  // run is span-for-span identical to a finished one — spans close,
3695
3892
  // nothing errors, there is just no answer. So it is the one outcome
3696
3893
  // that has to be stated, and the child states it on itself.
3697
3894
  ...abortIsTheRunsOutcome ? cancelledSpanAttrs() : [],
3698
- ...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(state, SUBAGENT_CANCELLED_OUTPUT, "stop") : []
3895
+ ...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(state2, SUBAGENT_CANCELLED_OUTPUT, "stop") : []
3699
3896
  ]
3700
3897
  });
3701
3898
  }
3702
- if (state.subagentToolCallSpan) {
3703
- this.traceShipper.endSpan(state.subagentToolCallSpan, {
3899
+ if (state2.subagentToolCallSpan) {
3900
+ this.traceShipper.endSpan(state2.subagentToolCallSpan, {
3704
3901
  attributes: [abortedAttr]
3705
3902
  });
3706
3903
  }
3707
3904
  this.finalizeGenerateEvent(
3708
- state,
3709
- state.accumulatedText || void 0,
3905
+ state2,
3906
+ state2.accumulatedText || void 0,
3710
3907
  void 0,
3711
3908
  false,
3712
3909
  abortIsTheRunsOutcome ? {
@@ -3714,7 +3911,7 @@ var RaindropTelemetryIntegration = class {
3714
3911
  properties: { [HANDOFF_TERMINAL_PROPERTY_KEY]: HANDOFF_TERMINAL_CANCELLED }
3715
3912
  } : void 0
3716
3913
  );
3717
- if (abortIsTheRunsOutcome) this.subagents.noteSettled(state.eventId);
3914
+ if (abortIsTheRunsOutcome) this.subagents.noteSettled(state2.eventId);
3718
3915
  this.cleanup(callId);
3719
3916
  };
3720
3917
  // ── executeTool ─────────────────────────────────────────────────────────
@@ -3723,14 +3920,14 @@ var RaindropTelemetryIntegration = class {
3723
3920
  toolCallId,
3724
3921
  execute
3725
3922
  }) => {
3726
- const state = this.getState(callId);
3727
- const toolSpan = state == null ? void 0 : state.toolSpans.get(toolCallId);
3923
+ const state2 = this.getState(callId);
3924
+ const toolSpan = state2 == null ? void 0 : state2.toolSpans.get(toolCallId);
3728
3925
  if (!toolSpan) return execute();
3729
3926
  return runWithParentSpanContext(
3730
3927
  {
3731
3928
  traceIdB64: toolSpan.ids.traceIdB64,
3732
3929
  spanIdB64: toolSpan.ids.spanIdB64,
3733
- eventId: state.eventId
3930
+ eventId: state2.eventId
3734
3931
  },
3735
3932
  () => execute()
3736
3933
  );
@@ -3779,35 +3976,35 @@ var RaindropTelemetryIntegration = class {
3779
3976
  activeDispatch() {
3780
3977
  var _a;
3781
3978
  const parentTool = getCurrentParentToolContext();
3782
- let state = parentTool ? this.getState(parentTool.parentCallId) : void 0;
3979
+ let state2 = parentTool ? this.getState(parentTool.parentCallId) : void 0;
3783
3980
  const inheritedEventId = (_a = getContextManager().getParentSpanIds()) == null ? void 0 : _a.eventId;
3784
- if (!state && inheritedEventId) {
3981
+ if (!state2 && inheritedEventId) {
3785
3982
  for (const candidate of this.callStates.values()) {
3786
3983
  if (candidate.eventId === inheritedEventId) {
3787
- state = candidate;
3984
+ state2 = candidate;
3788
3985
  break;
3789
3986
  }
3790
3987
  }
3791
3988
  }
3792
- if (!state) return void 0;
3989
+ if (!state2) return void 0;
3793
3990
  return {
3794
- eventId: state.eventId,
3795
- userId: state.identity.userId,
3796
- convoId: state.identity.convoId,
3797
- dispatchSpan: parentTool ? state.toolSpans.get(parentTool.toolCallId) : void 0,
3798
- turnSpans: [state.rootSpan, state.stepSpan].filter(
3991
+ eventId: state2.eventId,
3992
+ userId: state2.identity.userId,
3993
+ convoId: state2.identity.convoId,
3994
+ dispatchSpan: parentTool ? state2.toolSpans.get(parentTool.toolCallId) : void 0,
3995
+ turnSpans: [state2.rootSpan, state2.stepSpan].filter(
3799
3996
  (span) => span !== void 0
3800
3997
  ),
3801
- recordInputs: state.recordInputs
3998
+ recordInputs: state2.recordInputs
3802
3999
  };
3803
4000
  }
3804
4001
  /** Spans still open for an event, so a late outcome can still be stated. */
3805
4002
  openSpansForEvent(eventId) {
3806
4003
  const spans = [];
3807
- for (const state of this.callStates.values()) {
3808
- if (state.eventId !== eventId) continue;
3809
- if (state.rootSpan) spans.push(state.rootSpan);
3810
- if (state.stepSpan) spans.push(state.stepSpan);
4004
+ for (const state2 of this.callStates.values()) {
4005
+ if (state2.eventId !== eventId) continue;
4006
+ if (state2.rootSpan) spans.push(state2.rootSpan);
4007
+ if (state2.stepSpan) spans.push(state2.stepSpan);
3811
4008
  }
3812
4009
  return spans;
3813
4010
  }
@@ -3827,10 +4024,10 @@ var RaindropTelemetryIntegration = class {
3827
4024
  * created from an LLM span with output, `ai.response.text` here would state
3828
4025
  * the run's outcome through the span while the turn is still working.
3829
4026
  */
3830
- abortOutcomeAttrs(state, reason, finishReason) {
3831
- if (!state.handoff || state.nestedInEvent) return [];
4027
+ abortOutcomeAttrs(state2, reason, finishReason) {
4028
+ if (!state2.handoff || state2.nestedInEvent) return [];
3832
4029
  return [
3833
- attrString("ai.response.text", capText2(state.accumulatedText || reason)),
4030
+ attrString("ai.response.text", capText2(state2.accumulatedText || reason)),
3834
4031
  attrString("ai.response.finishReason", finishReason)
3835
4032
  ];
3836
4033
  }
@@ -3844,19 +4041,19 @@ var RaindropTelemetryIntegration = class {
3844
4041
  spanParentRef(span) {
3845
4042
  return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
3846
4043
  }
3847
- emitLive(state, type, content, extra) {
4044
+ emitLive(state2, type, content, extra) {
3848
4045
  var _a, _b, _c, _d, _e, _f;
3849
- if (!localDebuggerEnabled() || !state.rootSpan) return;
3850
- const callMeta = this.extractRaindropMetadata(state.metadata);
4046
+ if (!localDebuggerEnabled() || !state2.rootSpan) return;
4047
+ const callMeta = this.extractRaindropMetadata(state2.metadata);
3851
4048
  sendLocalDebuggerLiveEvent({
3852
- traceId: state.rootSpan.ids.traceIdB64,
4049
+ traceId: state2.rootSpan.ids.traceIdB64,
3853
4050
  type,
3854
4051
  content,
3855
4052
  metadata: {
3856
4053
  userId: (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId,
3857
4054
  convoId: (_d = callMeta.convoId) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.convoId,
3858
4055
  eventName: (_f = callMeta.eventName) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.eventName,
3859
- eventId: state.eventId,
4056
+ eventId: state2.eventId,
3860
4057
  ...extra
3861
4058
  }
3862
4059
  });
@@ -3934,29 +4131,29 @@ var RaindropTelemetryIntegration = class {
3934
4131
  toolCallId: toolCall.toolCallId,
3935
4132
  toolName: toolCall.toolName
3936
4133
  });
3937
- const state = this.getState(event.callId);
3938
- state == null ? void 0 : state.parentContextToolCallIds.add(toolCall.toolCallId);
3939
- if (!(state == null ? void 0 : state.stepParent)) return;
3940
- const { operationName, resourceName } = opName("ai.toolCall", state.functionId);
3941
- const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
4134
+ const state2 = this.getState(event.callId);
4135
+ state2 == null ? void 0 : state2.parentContextToolCallIds.add(toolCall.toolCallId);
4136
+ if (!(state2 == null ? void 0 : state2.stepParent)) return;
4137
+ const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
4138
+ const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
3942
4139
  const toolSpan = this.traceShipper.startSpan({
3943
4140
  name: "ai.toolCall",
3944
- parent: state.stepParent,
3945
- eventId: state.eventId,
3946
- ...state.identity,
4141
+ parent: state2.stepParent,
4142
+ eventId: state2.eventId,
4143
+ ...state2.identity,
3947
4144
  operationId: "ai.toolCall",
3948
4145
  attributes: [
3949
4146
  attrString("operation.name", operationName),
3950
4147
  attrString("resource.name", resourceName),
3951
- attrString("ai.telemetry.functionId", state.functionId),
4148
+ attrString("ai.telemetry.functionId", state2.functionId),
3952
4149
  attrString("ai.toolCall.name", toolCall.toolName),
3953
4150
  attrString("ai.toolCall.id", toolCall.toolCallId),
3954
4151
  ...inputAttrs,
3955
- ...handoffSpanAttrs(state.handoff)
4152
+ ...handoffSpanAttrs(state2.handoff)
3956
4153
  ]
3957
4154
  });
3958
- state.toolSpans.set(toolCall.toolCallId, toolSpan);
3959
- this.emitLive(state, "tool_start", toolCall.toolName, { args: toolCall.input });
4155
+ state2.toolSpans.set(toolCall.toolCallId, toolSpan);
4156
+ this.emitLive(state2, "tool_start", toolCall.toolName, { args: toolCall.input });
3960
4157
  }
3961
4158
  toolExecutionEnd(event) {
3962
4159
  var _a;
@@ -3970,20 +4167,20 @@ var RaindropTelemetryIntegration = class {
3970
4167
  clearParentToolContext();
3971
4168
  }
3972
4169
  }
3973
- const state = this.getState(event.callId);
3974
- if (!state) return;
3975
- const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
4170
+ const state2 = this.getState(event.callId);
4171
+ if (!state2) return;
4172
+ const toolSpan = state2.toolSpans.get(event.toolCall.toolCallId);
3976
4173
  if (!toolSpan) return;
3977
- state.toolCallCount += 1;
4174
+ state2.toolCallCount += 1;
3978
4175
  const outcome = "toolOutput" in event ? event.toolOutput.type === "tool-result" ? { success: true, output: event.toolOutput.output } : { success: false, error: event.toolOutput.error } : event.success ? { success: true, output: event.output } : { success: false, error: event.error };
3979
4176
  if (outcome.success) {
3980
- const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(outcome.output))] : [];
4177
+ const outputAttrs = state2.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(outcome.output))] : [];
3981
4178
  this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
3982
4179
  } else {
3983
4180
  this.traceShipper.endSpan(toolSpan, { error: outcome.error });
3984
4181
  }
3985
- this.emitLive(state, "tool_result", event.toolCall.toolName);
3986
- state.toolSpans.delete(event.toolCall.toolCallId);
4182
+ this.emitLive(state2, "tool_result", event.toolCall.toolName);
4183
+ state2.toolSpans.delete(event.toolCall.toolCallId);
3987
4184
  }
3988
4185
  // ── provider-executed tool calls ─────────────────────────────────────────
3989
4186
  //
@@ -4002,8 +4199,8 @@ var RaindropTelemetryIntegration = class {
4002
4199
  //
4003
4200
  // Client-executed tools are excluded (`providerExecuted` falsy) — they were
4004
4201
  // already spanned during execution, so this never double-emits.
4005
- emitProviderExecutedToolSpans(event, state) {
4006
- if (!state.stepParent) return;
4202
+ emitProviderExecutedToolSpans(event, state2) {
4203
+ if (!state2.stepParent) return;
4007
4204
  const content = Array.isArray(event.content) ? event.content : [];
4008
4205
  const providerToolCalls = content.filter(
4009
4206
  (part) => (part == null ? void 0 : part.type) === "tool-call" && part.providerExecuted === true
@@ -4016,42 +4213,42 @@ var RaindropTelemetryIntegration = class {
4016
4213
  }
4017
4214
  }
4018
4215
  for (const call of providerToolCalls) {
4019
- const { operationName, resourceName } = opName("ai.toolCall", state.functionId);
4020
- const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(call.input))] : [];
4216
+ const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
4217
+ const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(call.input))] : [];
4021
4218
  const toolSpan = this.traceShipper.startSpan({
4022
4219
  name: "ai.toolCall",
4023
- parent: state.stepParent,
4024
- eventId: state.eventId,
4025
- ...state.identity,
4220
+ parent: state2.stepParent,
4221
+ eventId: state2.eventId,
4222
+ ...state2.identity,
4026
4223
  operationId: "ai.toolCall",
4027
4224
  attributes: [
4028
4225
  attrString("operation.name", operationName),
4029
4226
  attrString("resource.name", resourceName),
4030
- attrString("ai.telemetry.functionId", state.functionId),
4227
+ attrString("ai.telemetry.functionId", state2.functionId),
4031
4228
  attrString("ai.toolCall.name", call.toolName),
4032
4229
  attrString("ai.toolCall.id", call.toolCallId),
4033
4230
  attrString("ai.toolCall.providerExecuted", "true"),
4034
4231
  ...inputAttrs,
4035
- ...handoffSpanAttrs(state.handoff)
4232
+ ...handoffSpanAttrs(state2.handoff)
4036
4233
  ]
4037
4234
  });
4038
- state.toolCallCount += 1;
4039
- this.emitLive(state, "tool_start", call.toolName, { args: call.input });
4235
+ state2.toolCallCount += 1;
4236
+ this.emitLive(state2, "tool_start", call.toolName, { args: call.input });
4040
4237
  const resultPart = resultsByCallId.get(call.toolCallId);
4041
4238
  if ((resultPart == null ? void 0 : resultPart.type) === "tool-error") {
4042
4239
  this.traceShipper.endSpan(toolSpan, { error: resultPart.error });
4043
4240
  } else {
4044
- const outputAttrs = state.recordOutputs && resultPart && "output" in resultPart ? [attrString("ai.toolCall.result", safeJsonWithUint8(resultPart.output))] : [];
4241
+ const outputAttrs = state2.recordOutputs && resultPart && "output" in resultPart ? [attrString("ai.toolCall.result", safeJsonWithUint8(resultPart.output))] : [];
4045
4242
  this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
4046
4243
  }
4047
- this.emitLive(state, "tool_result", call.toolName);
4244
+ this.emitLive(state2, "tool_result", call.toolName);
4048
4245
  }
4049
4246
  }
4050
- finishGenerate(event, state) {
4247
+ finishGenerate(event, state2) {
4051
4248
  var _a, _b, _c, _d, _e, _f;
4052
- if (state.rootSpan) {
4249
+ if (state2.rootSpan) {
4053
4250
  const outputAttrs = [];
4054
- if (state.recordOutputs) {
4251
+ if (state2.recordOutputs) {
4055
4252
  outputAttrs.push(
4056
4253
  attrString("ai.response.finishReason", event.finishReason),
4057
4254
  attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
@@ -4092,12 +4289,12 @@ var RaindropTelemetryIntegration = class {
4092
4289
  attrInt("ai.usage.cachedInputTokens", usageMetrics.cachedInputTokens)
4093
4290
  );
4094
4291
  }
4095
- outputAttrs.push(attrInt("ai.toolCall.count", state.toolCallCount));
4096
- this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
4292
+ outputAttrs.push(attrInt("ai.toolCall.count", state2.toolCallCount));
4293
+ this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
4097
4294
  }
4098
4295
  this.finalizeGenerateEvent(
4099
- state,
4100
- (_e = event.text) != null ? _e : state.accumulatedText || void 0,
4296
+ state2,
4297
+ (_e = event.text) != null ? _e : state2.accumulatedText || void 0,
4101
4298
  (_f = event.response) == null ? void 0 : _f.modelId,
4102
4299
  hasUnresolvedToolApproval(event)
4103
4300
  );
@@ -4113,29 +4310,29 @@ var RaindropTelemetryIntegration = class {
4113
4310
  * is finalized by that resume — otherwise each execution would finalize the
4114
4311
  * same event ID into a separate canonical row.
4115
4312
  */
4116
- finalizeGenerateEvent(state, output, model, keepPending = false, detachedOutcome) {
4313
+ finalizeGenerateEvent(state2, output, model, keepPending = false, detachedOutcome) {
4117
4314
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
4118
- const suppressSubagentEvent = state.subagentName !== void 0 && state.subagentToolCallSpan !== void 0;
4315
+ const suppressSubagentEvent = state2.subagentName !== void 0 && state2.subagentToolCallSpan !== void 0;
4119
4316
  if (!this.sendEvents || suppressSubagentEvent) return;
4120
- if (this.subagents.wasSettledExplicitly(state.eventId)) return;
4121
- const callMeta = this.extractRaindropMetadata(state.metadata);
4317
+ if (this.subagents.wasSettledExplicitly(state2.eventId)) return;
4318
+ const callMeta = this.extractRaindropMetadata(state2.metadata);
4122
4319
  const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
4123
4320
  if (!userId) return;
4124
- const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state.operationId;
4321
+ const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state2.operationId;
4125
4322
  const cappedOutput = capText2(output);
4126
- const reportedOutput = state.handoff && detachedOutcome && !(cappedOutput == null ? void 0 : cappedOutput.trim()) ? detachedOutcome.fallbackOutput : cappedOutput;
4127
- const input = capText2(state.inputText);
4323
+ const reportedOutput = state2.handoff && detachedOutcome && !(cappedOutput == null ? void 0 : cappedOutput.trim()) ? detachedOutcome.fallbackOutput : cappedOutput;
4324
+ const input = capText2(state2.inputText);
4128
4325
  const properties = {
4129
4326
  ...(_f = this.defaultContext) == null ? void 0 : _f.properties,
4130
4327
  ...callMeta.properties,
4131
- ...state.handoff ? detachedOutcome == null ? void 0 : detachedOutcome.properties : void 0
4328
+ ...state2.handoff ? detachedOutcome == null ? void 0 : detachedOutcome.properties : void 0
4132
4329
  };
4133
4330
  const featureFlags = {
4134
4331
  ...((_g = this.defaultContext) == null ? void 0 : _g.featureFlags) ? normalizeFeatureFlags(this.defaultContext.featureFlags) : {},
4135
4332
  ...callMeta.featureFlags
4136
4333
  };
4137
4334
  const convoId = (_i = callMeta.convoId) != null ? _i : (_h = this.defaultContext) == null ? void 0 : _h.convoId;
4138
- void this.eventShipper.patch(state.eventId, {
4335
+ void this.eventShipper.patch(state2.eventId, {
4139
4336
  eventName,
4140
4337
  userId,
4141
4338
  convoId,
@@ -4153,12 +4350,12 @@ var RaindropTelemetryIntegration = class {
4153
4350
  }
4154
4351
  });
4155
4352
  }
4156
- finishEmbed(event, state) {
4353
+ finishEmbed(event, state2) {
4157
4354
  var _a;
4158
- if (!state.rootSpan) return;
4355
+ if (!state2.rootSpan) return;
4159
4356
  const outputAttrs = [];
4160
- const isMany = state.operationId === "ai.embedMany";
4161
- if (state.recordOutputs) {
4357
+ const isMany = state2.operationId === "ai.embedMany";
4358
+ if (state2.recordOutputs) {
4162
4359
  if (isMany) {
4163
4360
  outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embedding)));
4164
4361
  } else {
@@ -4168,7 +4365,7 @@ var RaindropTelemetryIntegration = class {
4168
4365
  if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
4169
4366
  outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
4170
4367
  }
4171
- this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
4368
+ this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
4172
4369
  }
4173
4370
  };
4174
4371