@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.
@@ -1,6 +1,68 @@
1
1
  import { AsyncLocalStorage } from 'async_hooks';
2
2
 
3
- // ../core/dist/chunk-3V4MIA75.js
3
+ // ../core/dist/chunk-BYBMRLZM.js
4
+ var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
5
+ var PROBE_SCOPE = { correlationId: "" };
6
+ var EvalScopeStorage = class {
7
+ constructor() {
8
+ this._als = null;
9
+ this._probed = false;
10
+ }
11
+ maybeAdoptAsyncLocalStorage() {
12
+ if (this._probed) return;
13
+ this._probed = true;
14
+ try {
15
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
16
+ if (!Ctor) return;
17
+ const als = new Ctor();
18
+ als.run(PROBE_SCOPE, () => {
19
+ });
20
+ this._als = als;
21
+ } catch (e) {
22
+ this._als = null;
23
+ }
24
+ }
25
+ run(scope, callback) {
26
+ this.maybeAdoptAsyncLocalStorage();
27
+ if (this._als) return this._als.run(scope, callback);
28
+ const previous = this._syncScope;
29
+ this._syncScope = scope;
30
+ try {
31
+ return callback();
32
+ } finally {
33
+ this._syncScope = previous;
34
+ }
35
+ }
36
+ current() {
37
+ this.maybeAdoptAsyncLocalStorage();
38
+ if (this._als) return this._als.getStore();
39
+ return this._syncScope;
40
+ }
41
+ };
42
+ var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
43
+ function evalScopeStorage() {
44
+ const holder = globalThis;
45
+ let storage = holder[EVAL_SCOPE_STORAGE_KEY];
46
+ if (!storage) {
47
+ storage = new EvalScopeStorage();
48
+ holder[EVAL_SCOPE_STORAGE_KEY] = storage;
49
+ }
50
+ return storage;
51
+ }
52
+ function currentEvalScope() {
53
+ try {
54
+ return evalScopeStorage().current();
55
+ } catch (e) {
56
+ return void 0;
57
+ }
58
+ }
59
+ function evalScopeAttributes() {
60
+ const scope = currentEvalScope();
61
+ if (!scope) return {};
62
+ return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
63
+ }
64
+
65
+ // ../core/dist/chunk-T53LQAH7.js
4
66
  function normalizeFeatureFlags(input) {
5
67
  if (Array.isArray(input)) {
6
68
  return Object.fromEntries(input.map((name) => [name, "true"]));
@@ -495,6 +557,7 @@ async function postJson(url, body, headers, opts) {
495
557
  const resp = await runWithTracingSuppressed(
496
558
  () => fetch(url, {
497
559
  method: "POST",
560
+ redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
498
561
  headers: {
499
562
  "Content-Type": "application/json",
500
563
  ...headers
@@ -618,6 +681,55 @@ function buildExportTraceServiceRequest(spans, serviceName = "raindrop.core", se
618
681
  ]
619
682
  };
620
683
  }
684
+ var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
685
+ function state() {
686
+ const holder = globalThis;
687
+ let current = holder[STATE_KEY];
688
+ if (!current) {
689
+ let storage = null;
690
+ try {
691
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
692
+ if (Ctor) storage = new Ctor();
693
+ } catch (e) {
694
+ storage = null;
695
+ }
696
+ current = {
697
+ storage,
698
+ syncDestination: void 0,
699
+ spanDestinations: /* @__PURE__ */ new WeakMap()
700
+ };
701
+ holder[STATE_KEY] = current;
702
+ }
703
+ return current;
704
+ }
705
+ function currentReplayTraceDestination() {
706
+ var _a, _b;
707
+ const routing = state();
708
+ return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
709
+ }
710
+ function rememberReplayTraceDestination(span) {
711
+ const destination = currentReplayTraceDestination();
712
+ if (destination) state().spanDestinations.set(span, destination);
713
+ }
714
+ function copyReplayTraceDestination(source, target) {
715
+ const destination = state().spanDestinations.get(source);
716
+ if (destination) state().spanDestinations.set(target, destination);
717
+ }
718
+ function replayTraceDestinationFor(value) {
719
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
720
+ return void 0;
721
+ }
722
+ return state().spanDestinations.get(value);
723
+ }
724
+ function recordReplayExportedSpan(destination, spanId, traceId) {
725
+ var _a, _b;
726
+ if (!destination || !spanId || !traceId) return;
727
+ (_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
728
+ (_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
729
+ }
730
+ function replayTraceUrl(baseUrl) {
731
+ return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
732
+ }
621
733
  var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
622
734
  var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
623
735
  var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
@@ -683,31 +795,36 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
683
795
  function localDebuggerEnabled(baseUrl) {
684
796
  return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
685
797
  }
798
+ var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
686
799
  function mirrorTraceExportToLocalDebugger(body, options = {}) {
687
800
  var _a;
688
801
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
689
- if (!baseUrl) return;
690
- void postJson(`${baseUrl}traces`, body, {}, {
802
+ if (!baseUrl) return Promise.resolve();
803
+ return postJson(`${baseUrl}traces`, body, {}, {
691
804
  maxAttempts: 1,
692
805
  debug: (_a = options.debug) != null ? _a : false,
693
- sdkName: options.sdkName
806
+ sdkName: options.sdkName,
807
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
694
808
  }).catch(() => {
695
809
  });
696
810
  }
697
811
  function mirrorPartialEventToLocalDebugger(event, options = {}) {
698
812
  var _a;
699
813
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
700
- if (!baseUrl) return;
814
+ if (!baseUrl) return Promise.resolve();
701
815
  const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
702
- void postJson(`${baseUrl}events/track_partial`, event, headers, {
816
+ return postJson(`${baseUrl}events/track_partial`, event, headers, {
703
817
  maxAttempts: 1,
704
818
  debug: (_a = options.debug) != null ? _a : false,
705
- sdkName: options.sdkName
819
+ sdkName: options.sdkName,
820
+ timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
706
821
  }).catch(() => {
707
822
  });
708
823
  }
709
824
  function sendLocalDebuggerLiveEvent(event, options = {}) {
710
825
  var _a, _b;
826
+ const destination = currentReplayTraceDestination();
827
+ if (destination && destination.kind !== "workshop") return;
711
828
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
712
829
  if (!baseUrl) return;
713
830
  void postJson(
@@ -879,6 +996,15 @@ var EventShipper = class {
879
996
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
880
997
  if (!this.enabled) return;
881
998
  if (!eventId || !eventId.trim()) return;
999
+ const capturedSticky = this.sticky.get(eventId);
1000
+ const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
1001
+ const destination = currentReplayTraceDestination();
1002
+ const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
1003
+ if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
1004
+ if (patch.isPending === false) this.sticky.delete(eventId);
1005
+ else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
1006
+ return;
1007
+ }
882
1008
  const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
883
1009
  if (typeof patch.input === "string" && patch.input.length > maxChars) {
884
1010
  patch = { ...patch, input: capText(patch.input, maxChars) };
@@ -937,6 +1063,9 @@ var EventShipper = class {
937
1063
  try {
938
1064
  for (const t of this.timers.values()) clearTimeout(t);
939
1065
  this.timers.clear();
1066
+ for (const [eventId, sticky] of this.sticky) {
1067
+ if (sticky.replayOnly) this.sticky.delete(eventId);
1068
+ }
940
1069
  const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
941
1070
  if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
942
1071
  } finally {
@@ -946,6 +1075,8 @@ var EventShipper = class {
946
1075
  async trackSignal(signal) {
947
1076
  var _a, _b;
948
1077
  if (!this.enabled) return;
1078
+ const destination = currentReplayTraceDestination();
1079
+ if (destination && destination.kind !== "workshop") return;
949
1080
  const body = [
950
1081
  {
951
1082
  event_id: signal.eventId,
@@ -980,6 +1111,8 @@ var EventShipper = class {
980
1111
  }
981
1112
  async identify(users) {
982
1113
  if (!this.enabled) return;
1114
+ const destination = currentReplayTraceDestination();
1115
+ if (destination && destination.kind !== "workshop") return;
983
1116
  const list = Array.isArray(users) ? users : [users];
984
1117
  const body = list.filter((user) => {
985
1118
  if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
@@ -1032,8 +1165,9 @@ var EventShipper = class {
1032
1165
  this.buffers.delete(eventId);
1033
1166
  if (!accumulated) return;
1034
1167
  const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
1035
- const eventName = (_c = (_b = accumulated.eventName) != null ? _b : sticky.eventName) != null ? _c : this.defaultEventName;
1036
- const userId = (_d = accumulated.userId) != null ? _d : sticky.userId;
1168
+ const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
1169
+ const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
1170
+ const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
1037
1171
  if (!userId) {
1038
1172
  if (this.debug) {
1039
1173
  console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
@@ -1041,14 +1175,13 @@ var EventShipper = class {
1041
1175
  this.sticky.delete(eventId);
1042
1176
  return;
1043
1177
  }
1044
- const { wizardSession, ...restProperties } = (_e = accumulated.properties) != null ? _e : {};
1178
+ const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
1045
1179
  let telemetryProperties = {};
1046
1180
  try {
1047
1181
  telemetryProperties = eventTelemetryProperties(accumulated);
1048
1182
  } catch (e) {
1049
1183
  }
1050
- const convoId = (_f = accumulated.convoId) != null ? _f : sticky.convoId;
1051
- const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
1184
+ const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
1052
1185
  const payload = {
1053
1186
  event_id: eventId,
1054
1187
  user_id: userId,
@@ -1090,29 +1223,30 @@ var EventShipper = class {
1090
1223
  endpoint: url
1091
1224
  });
1092
1225
  }
1093
- if (this.localDebuggerUrl) {
1094
- mirrorPartialEventToLocalDebugger(payload, {
1095
- baseUrl: this.localDebuggerUrl,
1096
- writeKey: this.writeKey,
1097
- debug: this.debug,
1098
- sdkName: this.sdkName
1099
- });
1100
- }
1226
+ const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
1227
+ baseUrl: this.localDebuggerUrl,
1228
+ writeKey: this.writeKey,
1229
+ debug: this.debug,
1230
+ sdkName: this.sdkName
1231
+ }) : void 0;
1101
1232
  if (!this.writeKey) {
1102
1233
  if (!isPending) this.sticky.delete(eventId);
1234
+ if (mirror) await mirror;
1103
1235
  return;
1104
1236
  }
1105
1237
  const opts = this.requestOpts();
1106
1238
  if (!opts) {
1107
1239
  this.warnShutdownDrop(`track_partial ${eventId}`);
1108
1240
  if (!isPending) this.sticky.delete(eventId);
1241
+ if (mirror) await mirror;
1109
1242
  return;
1110
1243
  }
1111
1244
  const p = postJson(url, payload, this.requestHeaders(), opts);
1112
- this.inFlight.add(p);
1245
+ const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
1246
+ this.inFlight.add(combined);
1113
1247
  try {
1114
1248
  try {
1115
- await p;
1249
+ await combined;
1116
1250
  if (this.debug) {
1117
1251
  console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
1118
1252
  }
@@ -1124,7 +1258,7 @@ var EventShipper = class {
1124
1258
  );
1125
1259
  }
1126
1260
  } finally {
1127
- this.inFlight.delete(p);
1261
+ this.inFlight.delete(combined);
1128
1262
  }
1129
1263
  if (!isPending) {
1130
1264
  this.sticky.delete(eventId);
@@ -1472,7 +1606,10 @@ var TraceShipper = class {
1472
1606
  try {
1473
1607
  const result = this.transformSpanHook(current);
1474
1608
  if (result === null) return null;
1475
- if (result !== void 0) current = result;
1609
+ if (result !== void 0) {
1610
+ copyReplayTraceDestination(current, result);
1611
+ current = result;
1612
+ }
1476
1613
  } catch (err) {
1477
1614
  if (this.debug) {
1478
1615
  const msg = err instanceof Error ? err.message : String(err);
@@ -1482,13 +1619,19 @@ var TraceShipper = class {
1482
1619
  }
1483
1620
  }
1484
1621
  try {
1485
- current = normalizeModelUsageSpan(current);
1622
+ const normalized = normalizeModelUsageSpan(current);
1623
+ copyReplayTraceDestination(current, normalized);
1624
+ current = normalized;
1486
1625
  } catch (e) {
1487
1626
  }
1488
1627
  if (!this.disableDefaultRedaction) {
1489
- current = defaultTransformSpan(current);
1628
+ const redacted = defaultTransformSpan(current);
1629
+ copyReplayTraceDestination(current, redacted);
1630
+ current = redacted;
1490
1631
  }
1491
- return this.capSpanAttributes(current);
1632
+ const capped = this.capSpanAttributes(current);
1633
+ copyReplayTraceDestination(current, capped);
1634
+ return capped;
1492
1635
  }
1493
1636
  isDebugEnabled() {
1494
1637
  return this.debug;
@@ -1506,33 +1649,54 @@ var TraceShipper = class {
1506
1649
  const attrs = [
1507
1650
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1508
1651
  ...identityAttrs(args),
1509
- attrString("ai.operationId", args.operationId)
1652
+ attrString("ai.operationId", args.operationId),
1653
+ ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1510
1654
  ];
1511
1655
  if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
1512
- const span = { ids, name: args.name, startTimeUnixNano: started, attributes: attrs };
1513
- this.mirrorToLocalDebugger(
1514
- buildOtlpSpan({
1515
- ids: span.ids,
1516
- name: span.name,
1517
- startTimeUnixNano: span.startTimeUnixNano,
1518
- endTimeUnixNano: span.startTimeUnixNano,
1519
- // placeholder — will be updated on endSpan
1520
- attributes: span.attributes,
1521
- status: { code: SpanStatusCode.UNSET }
1522
- })
1523
- );
1656
+ const span = {
1657
+ ids,
1658
+ name: args.name,
1659
+ startTimeUnixNano: started,
1660
+ attributes: attrs
1661
+ };
1662
+ rememberReplayTraceDestination(span);
1663
+ const openSpan = buildOtlpSpan({
1664
+ ids: span.ids,
1665
+ name: span.name,
1666
+ startTimeUnixNano: span.startTimeUnixNano,
1667
+ endTimeUnixNano: span.startTimeUnixNano,
1668
+ // placeholder — will be updated on endSpan
1669
+ attributes: span.attributes,
1670
+ status: { code: SpanStatusCode.UNSET }
1671
+ });
1672
+ copyReplayTraceDestination(span, openSpan);
1673
+ this.mirrorToLocalDebugger(openSpan);
1524
1674
  return span;
1525
1675
  }
1526
- mirrorToLocalDebugger(span) {
1527
- if (!this.localDebuggerUrl) return;
1676
+ mirrorToLocalDebugger(span, completed = false) {
1677
+ const destination = replayTraceDestinationFor(span);
1678
+ if (destination && destination.kind !== "workshop") return;
1679
+ const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
1680
+ if (!localDebuggerUrl) return;
1528
1681
  const redacted = this.redactSpan(span);
1529
1682
  if (redacted === null) return;
1683
+ if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
1684
+ recordReplayExportedSpan(
1685
+ destination,
1686
+ base64ToHex(redacted.spanId),
1687
+ base64ToHex(redacted.traceId)
1688
+ );
1689
+ }
1530
1690
  const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
1531
- mirrorTraceExportToLocalDebugger(body, {
1532
- baseUrl: this.localDebuggerUrl,
1691
+ const p = mirrorTraceExportToLocalDebugger(body, {
1692
+ baseUrl: localDebuggerUrl,
1533
1693
  debug: false,
1534
1694
  sdkName: this.sdkName
1535
1695
  });
1696
+ this.inFlight.add(p);
1697
+ void p.finally(() => {
1698
+ this.inFlight.delete(p);
1699
+ });
1536
1700
  }
1537
1701
  endSpan(span, extra) {
1538
1702
  var _a, _b;
@@ -1554,15 +1718,17 @@ var TraceShipper = class {
1554
1718
  attributes: span.attributes,
1555
1719
  status
1556
1720
  });
1721
+ copyReplayTraceDestination(span, otlp);
1557
1722
  this.enqueue(otlp);
1558
- this.mirrorToLocalDebugger(otlp);
1723
+ this.mirrorToLocalDebugger(otlp, true);
1559
1724
  }
1560
1725
  createSpan(args) {
1561
1726
  var _a;
1562
1727
  const ids = createSpanIds(args.parent);
1563
1728
  const attrs = [
1564
1729
  attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
1565
- ...identityAttrs(args)
1730
+ ...identityAttrs(args),
1731
+ ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1566
1732
  ];
1567
1733
  if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
1568
1734
  const otlp = buildOtlpSpan({
@@ -1573,8 +1739,9 @@ var TraceShipper = class {
1573
1739
  attributes: attrs,
1574
1740
  status: args.status
1575
1741
  });
1742
+ rememberReplayTraceDestination(otlp);
1576
1743
  this.enqueue(otlp);
1577
- this.mirrorToLocalDebugger(otlp);
1744
+ this.mirrorToLocalDebugger(otlp, true);
1578
1745
  }
1579
1746
  enqueue(span) {
1580
1747
  if (!this.enabled) return;
@@ -1588,6 +1755,13 @@ var TraceShipper = class {
1588
1755
  }
1589
1756
  const redacted = this.redactSpan(span);
1590
1757
  if (redacted === null) return;
1758
+ const destination = replayTraceDestinationFor(redacted);
1759
+ recordReplayExportedSpan(
1760
+ destination,
1761
+ base64ToHex(redacted.spanId),
1762
+ base64ToHex(redacted.traceId)
1763
+ );
1764
+ if ((destination == null ? void 0 : destination.kind) === "workshop") return;
1591
1765
  if (this.queue.length >= this.maxQueueSize) {
1592
1766
  this.queue.shift();
1593
1767
  }
@@ -1606,47 +1780,67 @@ var TraceShipper = class {
1606
1780
  }
1607
1781
  }
1608
1782
  async flush() {
1609
- if (!this.enabled) return;
1783
+ var _a;
1784
+ if (!this.enabled) {
1785
+ await Promise.all([...this.inFlight].map((p) => p.catch(() => {
1786
+ })));
1787
+ return;
1788
+ }
1610
1789
  if (this.timer) {
1611
1790
  clearTimeout(this.timer);
1612
1791
  this.timer = void 0;
1613
1792
  }
1614
1793
  while (this.queue.length > 0) {
1615
1794
  const batch = this.queue.splice(0, this.maxBatchSize);
1616
- if (!this.writeKey) continue;
1617
- const opts = this.requestOpts();
1618
- if (!opts) {
1619
- rateLimitedLog(
1620
- `${this.prefix}.shutdown_deadline`,
1621
- () => console.warn(
1622
- `${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
1623
- )
1624
- );
1625
- continue;
1795
+ const groups = /* @__PURE__ */ new Map();
1796
+ for (const span of batch) {
1797
+ const destination = replayTraceDestinationFor(span);
1798
+ const spans = groups.get(destination);
1799
+ if (spans) spans.push(span);
1800
+ else groups.set(destination, [span]);
1626
1801
  }
1627
- const body = buildExportTraceServiceRequest(batch, this.serviceName, this.serviceVersion);
1628
- const url = `${this.baseUrl}traces`;
1629
- if (this.debug) {
1630
- console.log(`${this.prefix} sending traces batch`, {
1631
- spans: batch.length,
1632
- endpoint: url
1633
- });
1634
- }
1635
- const p = postJson(url, body, this.requestHeaders(), opts);
1636
- this.inFlight.add(p);
1637
- try {
1638
- try {
1639
- await p;
1640
- if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
1641
- } catch (err) {
1642
- const msg = err instanceof Error ? err.message : String(err);
1802
+ for (const [destination, spans] of groups) {
1803
+ if (!destination && !this.writeKey) continue;
1804
+ if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
1805
+ const opts = this.requestOpts();
1806
+ if (!opts) {
1643
1807
  rateLimitedLog(
1644
- `${this.prefix}.send_spans_failed`,
1645
- () => console.warn(`${this.prefix} failed to send ${batch.length} spans: ${msg}`)
1808
+ `${this.prefix}.shutdown_deadline`,
1809
+ () => console.warn(
1810
+ `${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
1811
+ )
1646
1812
  );
1813
+ continue;
1814
+ }
1815
+ const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
1816
+ const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
1817
+ const headers = destination ? {
1818
+ Authorization: `Bearer ${destination.apiKey}`,
1819
+ "X-Raindrop-Replay-Id": destination.replayId,
1820
+ "X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
1821
+ } : this.requestHeaders();
1822
+ if (this.debug) {
1823
+ console.log(`${this.prefix} sending traces batch`, {
1824
+ spans: spans.length,
1825
+ endpoint: url
1826
+ });
1827
+ }
1828
+ const p = postJson(url, body, headers, opts);
1829
+ this.inFlight.add(p);
1830
+ try {
1831
+ try {
1832
+ await p;
1833
+ if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
1834
+ } catch (err) {
1835
+ const msg = err instanceof Error ? err.message : String(err);
1836
+ rateLimitedLog(
1837
+ `${this.prefix}.send_spans_failed`,
1838
+ () => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
1839
+ );
1840
+ }
1841
+ } finally {
1842
+ this.inFlight.delete(p);
1647
1843
  }
1648
- } finally {
1649
- this.inFlight.delete(p);
1650
1844
  }
1651
1845
  }
1652
1846
  }
@@ -1689,7 +1883,9 @@ var TraceShipper = class {
1689
1883
  if (!settled) {
1690
1884
  rateLimitedLog(
1691
1885
  `${this.prefix}.shutdown_deadline`,
1692
- () => console.warn(`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`)
1886
+ () => console.warn(
1887
+ `${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
1888
+ )
1693
1889
  );
1694
1890
  }
1695
1891
  } finally {
@@ -1784,7 +1980,8 @@ function withCurrent(span, callback) {
1784
1980
  return getContextManager().runInContext(span, callback);
1785
1981
  }
1786
1982
  async function getCurrentParentSpanContext() {
1787
- return getContextManager().getParentSpanIds();
1983
+ var _a, _b;
1984
+ return (_b = getContextManager().getParentSpanIds()) != null ? _b : (_a = currentReplayTraceDestination()) == null ? void 0 : _a.parentSpanContext;
1788
1985
  }
1789
1986
  async function runWithParentSpanContext(ctx, fn) {
1790
1987
  const cm = getContextManager();
@@ -3348,13 +3545,13 @@ var RaindropTelemetryIntegration = class {
3348
3545
  };
3349
3546
  // ── onStepStart ─────────────────────────────────────────────────────────
3350
3547
  this.onStepStart = (event) => {
3351
- const state = this.getState(event.callId);
3352
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
3353
- const isStream = state.operationId === "ai.streamText" || state.operationId === "ai.streamObject";
3354
- const stepOperationId = isStream ? `${state.operationId}.doStream` : `${state.operationId}.doGenerate`;
3355
- const { operationName, resourceName } = opName(stepOperationId, state.functionId);
3548
+ const state2 = this.getState(event.callId);
3549
+ if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
3550
+ const isStream = state2.operationId === "ai.streamText" || state2.operationId === "ai.streamObject";
3551
+ const stepOperationId = isStream ? `${state2.operationId}.doStream` : `${state2.operationId}.doGenerate`;
3552
+ const { operationName, resourceName } = opName(stepOperationId, state2.functionId);
3356
3553
  const inputAttrs = [];
3357
- if (state.recordInputs) {
3554
+ if (state2.recordInputs) {
3358
3555
  if (event.promptMessages) {
3359
3556
  inputAttrs.push(attrString("ai.prompt.messages", safeJsonWithUint8(event.promptMessages)));
3360
3557
  }
@@ -3377,25 +3574,25 @@ var RaindropTelemetryIntegration = class {
3377
3574
  }
3378
3575
  const stepSpan = this.traceShipper.startSpan({
3379
3576
  name: stepOperationId,
3380
- parent: state.rootParent,
3381
- eventId: state.eventId,
3382
- ...state.identity,
3577
+ parent: state2.rootParent,
3578
+ eventId: state2.eventId,
3579
+ ...state2.identity,
3383
3580
  operationId: stepOperationId,
3384
3581
  attributes: [
3385
3582
  attrString("operation.name", operationName),
3386
3583
  attrString("resource.name", resourceName),
3387
- attrString("ai.telemetry.functionId", state.functionId),
3584
+ attrString("ai.telemetry.functionId", state2.functionId),
3388
3585
  ...attrsFromModelProvider(event.provider),
3389
3586
  attrString("ai.model.id", event.modelId),
3390
3587
  attrString(MODEL_USAGE_ATTRIBUTES.requestModel, event.modelId),
3391
3588
  ...inputAttrs,
3392
- ...handoffSpanAttrs(state.handoff)
3589
+ ...handoffSpanAttrs(state2.handoff)
3393
3590
  ]
3394
3591
  });
3395
- state.stepSpan = stepSpan;
3396
- state.stepParent = this.spanParentRef(stepSpan);
3397
- state.stepProvider = event.provider;
3398
- state.stepModelId = event.modelId;
3592
+ state2.stepSpan = stepSpan;
3593
+ state2.stepParent = this.spanParentRef(stepSpan);
3594
+ state2.stepProvider = event.provider;
3595
+ state2.stepModelId = event.modelId;
3399
3596
  };
3400
3597
  this.onToolExecutionStart = (event) => this.toolExecutionStart(event);
3401
3598
  this.onToolExecutionEnd = (event) => this.toolExecutionEnd(event);
@@ -3422,33 +3619,33 @@ var RaindropTelemetryIntegration = class {
3422
3619
  var _a, _b, _c, _d, _e;
3423
3620
  const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
3424
3621
  if (!callId) return;
3425
- const state = this.getState(callId);
3426
- if (!state) return;
3622
+ const state2 = this.getState(callId);
3623
+ if (!state2) return;
3427
3624
  const chunk = event.chunk;
3428
3625
  if (!chunk || typeof chunk !== "object") return;
3429
3626
  if (chunk.type === "text-delta") {
3430
3627
  const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
3431
3628
  if (typeof delta === "string") {
3432
- if (state.accumulatedText.length <= effectiveMaxTextFieldChars()) {
3433
- state.accumulatedText += delta;
3629
+ if (state2.accumulatedText.length <= effectiveMaxTextFieldChars()) {
3630
+ state2.accumulatedText += delta;
3434
3631
  }
3435
- this.emitLive(state, "text_delta", delta);
3632
+ this.emitLive(state2, "text_delta", delta);
3436
3633
  }
3437
3634
  } else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
3438
3635
  const text = (_e = (_d = chunk.textDelta) != null ? _d : chunk.text) != null ? _e : chunk.delta;
3439
3636
  if (typeof text === "string") {
3440
- this.emitLive(state, "reasoning_delta", text);
3637
+ this.emitLive(state2, "reasoning_delta", text);
3441
3638
  }
3442
3639
  }
3443
3640
  };
3444
3641
  // ── onStepFinish ────────────────────────────────────────────────────────
3445
3642
  this.onStepFinish = (event) => {
3446
3643
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
3447
- const state = this.getState(event.callId);
3448
- if (!(state == null ? void 0 : state.stepSpan)) return;
3449
- const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b : state.stepModelId;
3644
+ const state2 = this.getState(event.callId);
3645
+ if (!(state2 == null ? void 0 : state2.stepSpan)) return;
3646
+ const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b : state2.stepModelId;
3450
3647
  const outputAttrs = [];
3451
- if (state.recordOutputs) {
3648
+ if (state2.recordOutputs) {
3452
3649
  outputAttrs.push(
3453
3650
  attrString("ai.response.finishReason", event.finishReason),
3454
3651
  attrString("ai.response.text", capText2((_c = event.text) != null ? _c : void 0)),
@@ -3493,7 +3690,7 @@ var RaindropTelemetryIntegration = class {
3493
3690
  if (usage) {
3494
3691
  const usageMetrics = extractUsageMetricsFromUsage(
3495
3692
  usage,
3496
- state.stepProvider,
3693
+ state2.stepProvider,
3497
3694
  event.providerMetadata
3498
3695
  );
3499
3696
  outputAttrs.push(
@@ -3506,51 +3703,51 @@ var RaindropTelemetryIntegration = class {
3506
3703
  ...buildRawModelUsageAttributes(usageMetrics)
3507
3704
  );
3508
3705
  }
3509
- this.emitProviderExecutedToolSpans(event, state);
3510
- this.traceShipper.endSpan(state.stepSpan, { attributes: outputAttrs });
3511
- state.stepSpan = void 0;
3512
- state.stepParent = void 0;
3513
- state.stepProvider = void 0;
3514
- state.stepModelId = void 0;
3706
+ this.emitProviderExecutedToolSpans(event, state2);
3707
+ this.traceShipper.endSpan(state2.stepSpan, { attributes: outputAttrs });
3708
+ state2.stepSpan = void 0;
3709
+ state2.stepParent = void 0;
3710
+ state2.stepProvider = void 0;
3711
+ state2.stepModelId = void 0;
3515
3712
  };
3516
3713
  // ── onEmbedStart ────────────────────────────────────────────────────────
3517
3714
  this.onEmbedStart = (event) => {
3518
- const state = this.getState(event.callId);
3519
- if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
3520
- const { operationName, resourceName } = opName(event.operationId, state.functionId);
3521
- const inputAttrs = state.recordInputs ? [attrString("ai.values", safeJsonWithUint8(event.values))] : [];
3715
+ const state2 = this.getState(event.callId);
3716
+ if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
3717
+ const { operationName, resourceName } = opName(event.operationId, state2.functionId);
3718
+ const inputAttrs = state2.recordInputs ? [attrString("ai.values", safeJsonWithUint8(event.values))] : [];
3522
3719
  const embedSpan = this.traceShipper.startSpan({
3523
3720
  name: event.operationId,
3524
- parent: state.rootParent,
3525
- eventId: state.eventId,
3526
- ...state.identity,
3721
+ parent: state2.rootParent,
3722
+ eventId: state2.eventId,
3723
+ ...state2.identity,
3527
3724
  operationId: event.operationId,
3528
3725
  attributes: [
3529
3726
  attrString("operation.name", operationName),
3530
3727
  attrString("resource.name", resourceName),
3531
- attrString("ai.telemetry.functionId", state.functionId),
3728
+ attrString("ai.telemetry.functionId", state2.functionId),
3532
3729
  ...inputAttrs,
3533
- ...handoffSpanAttrs(state.handoff)
3730
+ ...handoffSpanAttrs(state2.handoff)
3534
3731
  ]
3535
3732
  });
3536
- state.embedSpans.set(event.embedCallId, embedSpan);
3733
+ state2.embedSpans.set(event.embedCallId, embedSpan);
3537
3734
  };
3538
3735
  // ── onEmbedFinish ───────────────────────────────────────────────────────
3539
3736
  this.onEmbedFinish = (event) => {
3540
3737
  var _a;
3541
- const state = this.getState(event.callId);
3542
- if (!state) return;
3543
- const embedSpan = state.embedSpans.get(event.embedCallId);
3738
+ const state2 = this.getState(event.callId);
3739
+ if (!state2) return;
3740
+ const embedSpan = state2.embedSpans.get(event.embedCallId);
3544
3741
  if (!embedSpan) return;
3545
3742
  const outputAttrs = [];
3546
- if (state.recordOutputs) {
3743
+ if (state2.recordOutputs) {
3547
3744
  outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embeddings)));
3548
3745
  }
3549
3746
  if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
3550
3747
  outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
3551
3748
  }
3552
3749
  this.traceShipper.endSpan(embedSpan, { attributes: outputAttrs });
3553
- state.embedSpans.delete(event.embedCallId);
3750
+ state2.embedSpans.delete(event.embedCallId);
3554
3751
  };
3555
3752
  // v7 canary.159 renamed `onEmbedFinish` -> `onEmbedEnd`. Both names forward
3556
3753
  // to the same implementation; the installed SDK only wires up whichever it
@@ -3558,16 +3755,16 @@ var RaindropTelemetryIntegration = class {
3558
3755
  this.onEmbedEnd = (event) => this.onEmbedFinish(event);
3559
3756
  // ── onFinish ────────────────────────────────────────────────────────────
3560
3757
  this.onFinish = (event) => {
3561
- const state = this.getState(event.callId);
3562
- if (!state) return;
3563
- const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
3758
+ const state2 = this.getState(event.callId);
3759
+ if (!state2) return;
3760
+ const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
3564
3761
  if (isEmbed) {
3565
- this.finishEmbed(event, state);
3762
+ this.finishEmbed(event, state2);
3566
3763
  } else {
3567
- this.finishGenerate(event, state);
3764
+ this.finishGenerate(event, state2);
3568
3765
  }
3569
- if (state.subagentToolCallSpan) {
3570
- this.traceShipper.endSpan(state.subagentToolCallSpan);
3766
+ if (state2.subagentToolCallSpan) {
3767
+ this.traceShipper.endSpan(state2.subagentToolCallSpan);
3571
3768
  }
3572
3769
  this.cleanup(event.callId);
3573
3770
  };
@@ -3582,42 +3779,42 @@ var RaindropTelemetryIntegration = class {
3582
3779
  var _a;
3583
3780
  const event = error;
3584
3781
  if (!(event == null ? void 0 : event.callId)) return;
3585
- const state = this.getState(event.callId);
3586
- if (!state) return;
3782
+ const state2 = this.getState(event.callId);
3783
+ if (!state2) return;
3587
3784
  const actualError = (_a = event.error) != null ? _a : error;
3588
- if (state.stepSpan) {
3589
- this.traceShipper.endSpan(state.stepSpan, { error: actualError });
3590
- state.stepProvider = void 0;
3591
- state.stepModelId = void 0;
3785
+ if (state2.stepSpan) {
3786
+ this.traceShipper.endSpan(state2.stepSpan, { error: actualError });
3787
+ state2.stepProvider = void 0;
3788
+ state2.stepModelId = void 0;
3592
3789
  }
3593
- for (const embedSpan of state.embedSpans.values()) {
3790
+ for (const embedSpan of state2.embedSpans.values()) {
3594
3791
  this.traceShipper.endSpan(embedSpan, { error: actualError });
3595
3792
  }
3596
- state.embedSpans.clear();
3597
- for (const toolCallId of state.parentContextToolCallIds) {
3793
+ state2.embedSpans.clear();
3794
+ for (const toolCallId of state2.parentContextToolCallIds) {
3598
3795
  this.priorParentContexts.delete(toolCallId);
3599
3796
  }
3600
- state.parentContextToolCallIds.clear();
3601
- for (const toolSpan of state.toolSpans.values()) {
3797
+ state2.parentContextToolCallIds.clear();
3798
+ for (const toolSpan of state2.toolSpans.values()) {
3602
3799
  this.traceShipper.endSpan(toolSpan, { error: actualError });
3603
3800
  }
3604
- state.toolSpans.clear();
3801
+ state2.toolSpans.clear();
3605
3802
  const abortReason = describeAbortReason(actualError);
3606
- if (state.rootSpan) {
3607
- this.traceShipper.endSpan(state.rootSpan, {
3803
+ if (state2.rootSpan) {
3804
+ this.traceShipper.endSpan(state2.rootSpan, {
3608
3805
  error: actualError,
3609
- attributes: this.abortOutcomeAttrs(state, abortReason, "error")
3806
+ attributes: this.abortOutcomeAttrs(state2, abortReason, "error")
3610
3807
  });
3611
3808
  }
3612
- if (state.subagentToolCallSpan) {
3613
- this.traceShipper.endSpan(state.subagentToolCallSpan, { error: actualError });
3809
+ if (state2.subagentToolCallSpan) {
3810
+ this.traceShipper.endSpan(state2.subagentToolCallSpan, { error: actualError });
3614
3811
  }
3615
- const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
3812
+ const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
3616
3813
  if (!isEmbed) {
3617
- const errorIsTheRunsOutcome = state.handoff !== void 0 && !state.nestedInEvent;
3814
+ const errorIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
3618
3815
  this.finalizeGenerateEvent(
3619
- state,
3620
- state.accumulatedText || void 0,
3816
+ state2,
3817
+ state2.accumulatedText || void 0,
3621
3818
  void 0,
3622
3819
  false,
3623
3820
  errorIsTheRunsOutcome ? { fallbackOutput: abortReason } : void 0
@@ -3636,51 +3833,51 @@ var RaindropTelemetryIntegration = class {
3636
3833
  this.onAbort = (event) => {
3637
3834
  const callId = event == null ? void 0 : event.callId;
3638
3835
  if (!callId) return;
3639
- const state = this.getState(callId);
3640
- if (!state) return;
3836
+ const state2 = this.getState(callId);
3837
+ if (!state2) return;
3641
3838
  const abortedAttr = attrString("ai.response.aborted", "true");
3642
- if (state.stepSpan) {
3643
- this.traceShipper.endSpan(state.stepSpan, { attributes: [abortedAttr] });
3644
- state.stepSpan = void 0;
3645
- state.stepParent = void 0;
3646
- state.stepProvider = void 0;
3647
- state.stepModelId = void 0;
3839
+ if (state2.stepSpan) {
3840
+ this.traceShipper.endSpan(state2.stepSpan, { attributes: [abortedAttr] });
3841
+ state2.stepSpan = void 0;
3842
+ state2.stepParent = void 0;
3843
+ state2.stepProvider = void 0;
3844
+ state2.stepModelId = void 0;
3648
3845
  }
3649
- for (const embedSpan of state.embedSpans.values()) {
3846
+ for (const embedSpan of state2.embedSpans.values()) {
3650
3847
  this.traceShipper.endSpan(embedSpan, { attributes: [abortedAttr] });
3651
3848
  }
3652
- state.embedSpans.clear();
3653
- for (const toolCallId of state.parentContextToolCallIds) {
3849
+ state2.embedSpans.clear();
3850
+ for (const toolCallId of state2.parentContextToolCallIds) {
3654
3851
  this.priorParentContexts.delete(toolCallId);
3655
3852
  }
3656
- state.parentContextToolCallIds.clear();
3657
- for (const toolSpan of state.toolSpans.values()) {
3853
+ state2.parentContextToolCallIds.clear();
3854
+ for (const toolSpan of state2.toolSpans.values()) {
3658
3855
  this.traceShipper.endSpan(toolSpan, { attributes: [abortedAttr] });
3659
3856
  }
3660
- state.toolSpans.clear();
3661
- const abortIsTheRunsOutcome = state.handoff !== void 0 && !state.nestedInEvent;
3662
- if (state.rootSpan) {
3663
- this.traceShipper.endSpan(state.rootSpan, {
3857
+ state2.toolSpans.clear();
3858
+ const abortIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
3859
+ if (state2.rootSpan) {
3860
+ this.traceShipper.endSpan(state2.rootSpan, {
3664
3861
  attributes: [
3665
3862
  abortedAttr,
3666
- attrInt("ai.toolCall.count", state.toolCallCount),
3863
+ attrInt("ai.toolCall.count", state2.toolCallCount),
3667
3864
  // An aborted detached child IS a cancelled sub-agent, and a cancelled
3668
3865
  // run is span-for-span identical to a finished one — spans close,
3669
3866
  // nothing errors, there is just no answer. So it is the one outcome
3670
3867
  // that has to be stated, and the child states it on itself.
3671
3868
  ...abortIsTheRunsOutcome ? cancelledSpanAttrs() : [],
3672
- ...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(state, SUBAGENT_CANCELLED_OUTPUT, "stop") : []
3869
+ ...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(state2, SUBAGENT_CANCELLED_OUTPUT, "stop") : []
3673
3870
  ]
3674
3871
  });
3675
3872
  }
3676
- if (state.subagentToolCallSpan) {
3677
- this.traceShipper.endSpan(state.subagentToolCallSpan, {
3873
+ if (state2.subagentToolCallSpan) {
3874
+ this.traceShipper.endSpan(state2.subagentToolCallSpan, {
3678
3875
  attributes: [abortedAttr]
3679
3876
  });
3680
3877
  }
3681
3878
  this.finalizeGenerateEvent(
3682
- state,
3683
- state.accumulatedText || void 0,
3879
+ state2,
3880
+ state2.accumulatedText || void 0,
3684
3881
  void 0,
3685
3882
  false,
3686
3883
  abortIsTheRunsOutcome ? {
@@ -3688,7 +3885,7 @@ var RaindropTelemetryIntegration = class {
3688
3885
  properties: { [HANDOFF_TERMINAL_PROPERTY_KEY]: HANDOFF_TERMINAL_CANCELLED }
3689
3886
  } : void 0
3690
3887
  );
3691
- if (abortIsTheRunsOutcome) this.subagents.noteSettled(state.eventId);
3888
+ if (abortIsTheRunsOutcome) this.subagents.noteSettled(state2.eventId);
3692
3889
  this.cleanup(callId);
3693
3890
  };
3694
3891
  // ── executeTool ─────────────────────────────────────────────────────────
@@ -3697,14 +3894,14 @@ var RaindropTelemetryIntegration = class {
3697
3894
  toolCallId,
3698
3895
  execute
3699
3896
  }) => {
3700
- const state = this.getState(callId);
3701
- const toolSpan = state == null ? void 0 : state.toolSpans.get(toolCallId);
3897
+ const state2 = this.getState(callId);
3898
+ const toolSpan = state2 == null ? void 0 : state2.toolSpans.get(toolCallId);
3702
3899
  if (!toolSpan) return execute();
3703
3900
  return runWithParentSpanContext(
3704
3901
  {
3705
3902
  traceIdB64: toolSpan.ids.traceIdB64,
3706
3903
  spanIdB64: toolSpan.ids.spanIdB64,
3707
- eventId: state.eventId
3904
+ eventId: state2.eventId
3708
3905
  },
3709
3906
  () => execute()
3710
3907
  );
@@ -3753,35 +3950,35 @@ var RaindropTelemetryIntegration = class {
3753
3950
  activeDispatch() {
3754
3951
  var _a;
3755
3952
  const parentTool = getCurrentParentToolContext();
3756
- let state = parentTool ? this.getState(parentTool.parentCallId) : void 0;
3953
+ let state2 = parentTool ? this.getState(parentTool.parentCallId) : void 0;
3757
3954
  const inheritedEventId = (_a = getContextManager().getParentSpanIds()) == null ? void 0 : _a.eventId;
3758
- if (!state && inheritedEventId) {
3955
+ if (!state2 && inheritedEventId) {
3759
3956
  for (const candidate of this.callStates.values()) {
3760
3957
  if (candidate.eventId === inheritedEventId) {
3761
- state = candidate;
3958
+ state2 = candidate;
3762
3959
  break;
3763
3960
  }
3764
3961
  }
3765
3962
  }
3766
- if (!state) return void 0;
3963
+ if (!state2) return void 0;
3767
3964
  return {
3768
- eventId: state.eventId,
3769
- userId: state.identity.userId,
3770
- convoId: state.identity.convoId,
3771
- dispatchSpan: parentTool ? state.toolSpans.get(parentTool.toolCallId) : void 0,
3772
- turnSpans: [state.rootSpan, state.stepSpan].filter(
3965
+ eventId: state2.eventId,
3966
+ userId: state2.identity.userId,
3967
+ convoId: state2.identity.convoId,
3968
+ dispatchSpan: parentTool ? state2.toolSpans.get(parentTool.toolCallId) : void 0,
3969
+ turnSpans: [state2.rootSpan, state2.stepSpan].filter(
3773
3970
  (span) => span !== void 0
3774
3971
  ),
3775
- recordInputs: state.recordInputs
3972
+ recordInputs: state2.recordInputs
3776
3973
  };
3777
3974
  }
3778
3975
  /** Spans still open for an event, so a late outcome can still be stated. */
3779
3976
  openSpansForEvent(eventId) {
3780
3977
  const spans = [];
3781
- for (const state of this.callStates.values()) {
3782
- if (state.eventId !== eventId) continue;
3783
- if (state.rootSpan) spans.push(state.rootSpan);
3784
- if (state.stepSpan) spans.push(state.stepSpan);
3978
+ for (const state2 of this.callStates.values()) {
3979
+ if (state2.eventId !== eventId) continue;
3980
+ if (state2.rootSpan) spans.push(state2.rootSpan);
3981
+ if (state2.stepSpan) spans.push(state2.stepSpan);
3785
3982
  }
3786
3983
  return spans;
3787
3984
  }
@@ -3801,10 +3998,10 @@ var RaindropTelemetryIntegration = class {
3801
3998
  * created from an LLM span with output, `ai.response.text` here would state
3802
3999
  * the run's outcome through the span while the turn is still working.
3803
4000
  */
3804
- abortOutcomeAttrs(state, reason, finishReason) {
3805
- if (!state.handoff || state.nestedInEvent) return [];
4001
+ abortOutcomeAttrs(state2, reason, finishReason) {
4002
+ if (!state2.handoff || state2.nestedInEvent) return [];
3806
4003
  return [
3807
- attrString("ai.response.text", capText2(state.accumulatedText || reason)),
4004
+ attrString("ai.response.text", capText2(state2.accumulatedText || reason)),
3808
4005
  attrString("ai.response.finishReason", finishReason)
3809
4006
  ];
3810
4007
  }
@@ -3818,19 +4015,19 @@ var RaindropTelemetryIntegration = class {
3818
4015
  spanParentRef(span) {
3819
4016
  return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
3820
4017
  }
3821
- emitLive(state, type, content, extra) {
4018
+ emitLive(state2, type, content, extra) {
3822
4019
  var _a, _b, _c, _d, _e, _f;
3823
- if (!localDebuggerEnabled() || !state.rootSpan) return;
3824
- const callMeta = this.extractRaindropMetadata(state.metadata);
4020
+ if (!localDebuggerEnabled() || !state2.rootSpan) return;
4021
+ const callMeta = this.extractRaindropMetadata(state2.metadata);
3825
4022
  sendLocalDebuggerLiveEvent({
3826
- traceId: state.rootSpan.ids.traceIdB64,
4023
+ traceId: state2.rootSpan.ids.traceIdB64,
3827
4024
  type,
3828
4025
  content,
3829
4026
  metadata: {
3830
4027
  userId: (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId,
3831
4028
  convoId: (_d = callMeta.convoId) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.convoId,
3832
4029
  eventName: (_f = callMeta.eventName) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.eventName,
3833
- eventId: state.eventId,
4030
+ eventId: state2.eventId,
3834
4031
  ...extra
3835
4032
  }
3836
4033
  });
@@ -3908,29 +4105,29 @@ var RaindropTelemetryIntegration = class {
3908
4105
  toolCallId: toolCall.toolCallId,
3909
4106
  toolName: toolCall.toolName
3910
4107
  });
3911
- const state = this.getState(event.callId);
3912
- state == null ? void 0 : state.parentContextToolCallIds.add(toolCall.toolCallId);
3913
- if (!(state == null ? void 0 : state.stepParent)) return;
3914
- const { operationName, resourceName } = opName("ai.toolCall", state.functionId);
3915
- const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
4108
+ const state2 = this.getState(event.callId);
4109
+ state2 == null ? void 0 : state2.parentContextToolCallIds.add(toolCall.toolCallId);
4110
+ if (!(state2 == null ? void 0 : state2.stepParent)) return;
4111
+ const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
4112
+ const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
3916
4113
  const toolSpan = this.traceShipper.startSpan({
3917
4114
  name: "ai.toolCall",
3918
- parent: state.stepParent,
3919
- eventId: state.eventId,
3920
- ...state.identity,
4115
+ parent: state2.stepParent,
4116
+ eventId: state2.eventId,
4117
+ ...state2.identity,
3921
4118
  operationId: "ai.toolCall",
3922
4119
  attributes: [
3923
4120
  attrString("operation.name", operationName),
3924
4121
  attrString("resource.name", resourceName),
3925
- attrString("ai.telemetry.functionId", state.functionId),
4122
+ attrString("ai.telemetry.functionId", state2.functionId),
3926
4123
  attrString("ai.toolCall.name", toolCall.toolName),
3927
4124
  attrString("ai.toolCall.id", toolCall.toolCallId),
3928
4125
  ...inputAttrs,
3929
- ...handoffSpanAttrs(state.handoff)
4126
+ ...handoffSpanAttrs(state2.handoff)
3930
4127
  ]
3931
4128
  });
3932
- state.toolSpans.set(toolCall.toolCallId, toolSpan);
3933
- this.emitLive(state, "tool_start", toolCall.toolName, { args: toolCall.input });
4129
+ state2.toolSpans.set(toolCall.toolCallId, toolSpan);
4130
+ this.emitLive(state2, "tool_start", toolCall.toolName, { args: toolCall.input });
3934
4131
  }
3935
4132
  toolExecutionEnd(event) {
3936
4133
  var _a;
@@ -3944,20 +4141,20 @@ var RaindropTelemetryIntegration = class {
3944
4141
  clearParentToolContext();
3945
4142
  }
3946
4143
  }
3947
- const state = this.getState(event.callId);
3948
- if (!state) return;
3949
- const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
4144
+ const state2 = this.getState(event.callId);
4145
+ if (!state2) return;
4146
+ const toolSpan = state2.toolSpans.get(event.toolCall.toolCallId);
3950
4147
  if (!toolSpan) return;
3951
- state.toolCallCount += 1;
4148
+ state2.toolCallCount += 1;
3952
4149
  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 };
3953
4150
  if (outcome.success) {
3954
- const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(outcome.output))] : [];
4151
+ const outputAttrs = state2.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(outcome.output))] : [];
3955
4152
  this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
3956
4153
  } else {
3957
4154
  this.traceShipper.endSpan(toolSpan, { error: outcome.error });
3958
4155
  }
3959
- this.emitLive(state, "tool_result", event.toolCall.toolName);
3960
- state.toolSpans.delete(event.toolCall.toolCallId);
4156
+ this.emitLive(state2, "tool_result", event.toolCall.toolName);
4157
+ state2.toolSpans.delete(event.toolCall.toolCallId);
3961
4158
  }
3962
4159
  // ── provider-executed tool calls ─────────────────────────────────────────
3963
4160
  //
@@ -3976,8 +4173,8 @@ var RaindropTelemetryIntegration = class {
3976
4173
  //
3977
4174
  // Client-executed tools are excluded (`providerExecuted` falsy) — they were
3978
4175
  // already spanned during execution, so this never double-emits.
3979
- emitProviderExecutedToolSpans(event, state) {
3980
- if (!state.stepParent) return;
4176
+ emitProviderExecutedToolSpans(event, state2) {
4177
+ if (!state2.stepParent) return;
3981
4178
  const content = Array.isArray(event.content) ? event.content : [];
3982
4179
  const providerToolCalls = content.filter(
3983
4180
  (part) => (part == null ? void 0 : part.type) === "tool-call" && part.providerExecuted === true
@@ -3990,42 +4187,42 @@ var RaindropTelemetryIntegration = class {
3990
4187
  }
3991
4188
  }
3992
4189
  for (const call of providerToolCalls) {
3993
- const { operationName, resourceName } = opName("ai.toolCall", state.functionId);
3994
- const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(call.input))] : [];
4190
+ const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
4191
+ const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(call.input))] : [];
3995
4192
  const toolSpan = this.traceShipper.startSpan({
3996
4193
  name: "ai.toolCall",
3997
- parent: state.stepParent,
3998
- eventId: state.eventId,
3999
- ...state.identity,
4194
+ parent: state2.stepParent,
4195
+ eventId: state2.eventId,
4196
+ ...state2.identity,
4000
4197
  operationId: "ai.toolCall",
4001
4198
  attributes: [
4002
4199
  attrString("operation.name", operationName),
4003
4200
  attrString("resource.name", resourceName),
4004
- attrString("ai.telemetry.functionId", state.functionId),
4201
+ attrString("ai.telemetry.functionId", state2.functionId),
4005
4202
  attrString("ai.toolCall.name", call.toolName),
4006
4203
  attrString("ai.toolCall.id", call.toolCallId),
4007
4204
  attrString("ai.toolCall.providerExecuted", "true"),
4008
4205
  ...inputAttrs,
4009
- ...handoffSpanAttrs(state.handoff)
4206
+ ...handoffSpanAttrs(state2.handoff)
4010
4207
  ]
4011
4208
  });
4012
- state.toolCallCount += 1;
4013
- this.emitLive(state, "tool_start", call.toolName, { args: call.input });
4209
+ state2.toolCallCount += 1;
4210
+ this.emitLive(state2, "tool_start", call.toolName, { args: call.input });
4014
4211
  const resultPart = resultsByCallId.get(call.toolCallId);
4015
4212
  if ((resultPart == null ? void 0 : resultPart.type) === "tool-error") {
4016
4213
  this.traceShipper.endSpan(toolSpan, { error: resultPart.error });
4017
4214
  } else {
4018
- const outputAttrs = state.recordOutputs && resultPart && "output" in resultPart ? [attrString("ai.toolCall.result", safeJsonWithUint8(resultPart.output))] : [];
4215
+ const outputAttrs = state2.recordOutputs && resultPart && "output" in resultPart ? [attrString("ai.toolCall.result", safeJsonWithUint8(resultPart.output))] : [];
4019
4216
  this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
4020
4217
  }
4021
- this.emitLive(state, "tool_result", call.toolName);
4218
+ this.emitLive(state2, "tool_result", call.toolName);
4022
4219
  }
4023
4220
  }
4024
- finishGenerate(event, state) {
4221
+ finishGenerate(event, state2) {
4025
4222
  var _a, _b, _c, _d, _e, _f;
4026
- if (state.rootSpan) {
4223
+ if (state2.rootSpan) {
4027
4224
  const outputAttrs = [];
4028
- if (state.recordOutputs) {
4225
+ if (state2.recordOutputs) {
4029
4226
  outputAttrs.push(
4030
4227
  attrString("ai.response.finishReason", event.finishReason),
4031
4228
  attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
@@ -4066,12 +4263,12 @@ var RaindropTelemetryIntegration = class {
4066
4263
  attrInt("ai.usage.cachedInputTokens", usageMetrics.cachedInputTokens)
4067
4264
  );
4068
4265
  }
4069
- outputAttrs.push(attrInt("ai.toolCall.count", state.toolCallCount));
4070
- this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
4266
+ outputAttrs.push(attrInt("ai.toolCall.count", state2.toolCallCount));
4267
+ this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
4071
4268
  }
4072
4269
  this.finalizeGenerateEvent(
4073
- state,
4074
- (_e = event.text) != null ? _e : state.accumulatedText || void 0,
4270
+ state2,
4271
+ (_e = event.text) != null ? _e : state2.accumulatedText || void 0,
4075
4272
  (_f = event.response) == null ? void 0 : _f.modelId,
4076
4273
  hasUnresolvedToolApproval(event)
4077
4274
  );
@@ -4087,29 +4284,29 @@ var RaindropTelemetryIntegration = class {
4087
4284
  * is finalized by that resume — otherwise each execution would finalize the
4088
4285
  * same event ID into a separate canonical row.
4089
4286
  */
4090
- finalizeGenerateEvent(state, output, model, keepPending = false, detachedOutcome) {
4287
+ finalizeGenerateEvent(state2, output, model, keepPending = false, detachedOutcome) {
4091
4288
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
4092
- const suppressSubagentEvent = state.subagentName !== void 0 && state.subagentToolCallSpan !== void 0;
4289
+ const suppressSubagentEvent = state2.subagentName !== void 0 && state2.subagentToolCallSpan !== void 0;
4093
4290
  if (!this.sendEvents || suppressSubagentEvent) return;
4094
- if (this.subagents.wasSettledExplicitly(state.eventId)) return;
4095
- const callMeta = this.extractRaindropMetadata(state.metadata);
4291
+ if (this.subagents.wasSettledExplicitly(state2.eventId)) return;
4292
+ const callMeta = this.extractRaindropMetadata(state2.metadata);
4096
4293
  const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
4097
4294
  if (!userId) return;
4098
- const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state.operationId;
4295
+ const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state2.operationId;
4099
4296
  const cappedOutput = capText2(output);
4100
- const reportedOutput = state.handoff && detachedOutcome && !(cappedOutput == null ? void 0 : cappedOutput.trim()) ? detachedOutcome.fallbackOutput : cappedOutput;
4101
- const input = capText2(state.inputText);
4297
+ const reportedOutput = state2.handoff && detachedOutcome && !(cappedOutput == null ? void 0 : cappedOutput.trim()) ? detachedOutcome.fallbackOutput : cappedOutput;
4298
+ const input = capText2(state2.inputText);
4102
4299
  const properties = {
4103
4300
  ...(_f = this.defaultContext) == null ? void 0 : _f.properties,
4104
4301
  ...callMeta.properties,
4105
- ...state.handoff ? detachedOutcome == null ? void 0 : detachedOutcome.properties : void 0
4302
+ ...state2.handoff ? detachedOutcome == null ? void 0 : detachedOutcome.properties : void 0
4106
4303
  };
4107
4304
  const featureFlags = {
4108
4305
  ...((_g = this.defaultContext) == null ? void 0 : _g.featureFlags) ? normalizeFeatureFlags(this.defaultContext.featureFlags) : {},
4109
4306
  ...callMeta.featureFlags
4110
4307
  };
4111
4308
  const convoId = (_i = callMeta.convoId) != null ? _i : (_h = this.defaultContext) == null ? void 0 : _h.convoId;
4112
- void this.eventShipper.patch(state.eventId, {
4309
+ void this.eventShipper.patch(state2.eventId, {
4113
4310
  eventName,
4114
4311
  userId,
4115
4312
  convoId,
@@ -4127,12 +4324,12 @@ var RaindropTelemetryIntegration = class {
4127
4324
  }
4128
4325
  });
4129
4326
  }
4130
- finishEmbed(event, state) {
4327
+ finishEmbed(event, state2) {
4131
4328
  var _a;
4132
- if (!state.rootSpan) return;
4329
+ if (!state2.rootSpan) return;
4133
4330
  const outputAttrs = [];
4134
- const isMany = state.operationId === "ai.embedMany";
4135
- if (state.recordOutputs) {
4331
+ const isMany = state2.operationId === "ai.embedMany";
4332
+ if (state2.recordOutputs) {
4136
4333
  if (isMany) {
4137
4334
  outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embedding)));
4138
4335
  } else {
@@ -4142,7 +4339,7 @@ var RaindropTelemetryIntegration = class {
4142
4339
  if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
4143
4340
  outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
4144
4341
  }
4145
- this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
4342
+ this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
4146
4343
  }
4147
4344
  };
4148
4345
 
@@ -6255,7 +6452,7 @@ function mergeAttachments(...groups) {
6255
6452
  // package.json
6256
6453
  var package_default = {
6257
6454
  name: "@raindrop-ai/ai-sdk",
6258
- version: "0.3.1"};
6455
+ version: "0.3.2"};
6259
6456
 
6260
6457
  // src/internal/version.ts
6261
6458
  var libraryName = package_default.name;