@raindrop-ai/ai-sdk 0.0.18 → 0.0.19-beta.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.
@@ -791,7 +791,7 @@ async function* asyncGeneratorWithCurrent(span, gen) {
791
791
  // package.json
792
792
  var package_default = {
793
793
  name: "@raindrop-ai/ai-sdk",
794
- version: "0.0.18"};
794
+ version: "0.0.19-beta.2"};
795
795
 
796
796
  // src/internal/version.ts
797
797
  var libraryName = package_default.name;
@@ -810,19 +810,6 @@ var EventShipper2 = class extends EventShipper {
810
810
  }
811
811
  };
812
812
 
813
- // src/internal/traces.ts
814
- var TraceShipper2 = class extends TraceShipper {
815
- constructor(opts) {
816
- var _a, _b, _c;
817
- super({
818
- ...opts,
819
- sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
820
- serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.ai-sdk",
821
- serviceVersion: (_c = opts.serviceVersion) != null ? _c : libraryVersion
822
- });
823
- }
824
- };
825
-
826
813
  // src/internal/wrap/helpers.ts
827
814
  function isRecord(value) {
828
815
  return typeof value === "object" && value !== null;
@@ -1438,6 +1425,540 @@ function attrsFromGenAiRequest(options) {
1438
1425
  ];
1439
1426
  }
1440
1427
 
1428
+ // src/internal/raindrop-telemetry-integration.ts
1429
+ var RaindropTelemetryIntegration = class {
1430
+ constructor(opts) {
1431
+ this.callStates = /* @__PURE__ */ new Map();
1432
+ // ── onStart ─────────────────────────────────────────────────────────────
1433
+ this.onStart = (event) => {
1434
+ var _a, _b, _c, _d;
1435
+ if (event.isEnabled !== true) return;
1436
+ const isEmbed = event.operationId === "ai.embed" || event.operationId === "ai.embedMany";
1437
+ const recordInputs = event.recordInputs !== false;
1438
+ const recordOutputs = event.recordOutputs !== false;
1439
+ const functionId = event.functionId;
1440
+ const metadata = event.metadata;
1441
+ const callMeta = this.extractRaindropMetadata(metadata);
1442
+ const inherited = getContextManager().getParentSpanIds();
1443
+ const eventIdGenerated = (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === "true" || (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === true;
1444
+ const explicitEventId = callMeta.eventId && !eventIdGenerated ? callMeta.eventId : void 0;
1445
+ const eventId = (_d = (_c = (_b = explicitEventId != null ? explicitEventId : (_a = this.defaultContext) == null ? void 0 : _a.eventId) != null ? _b : inherited == null ? void 0 : inherited.eventId) != null ? _c : callMeta.eventId) != null ? _d : randomUUID();
1446
+ const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
1447
+ const { operationName, resourceName } = opName(
1448
+ event.operationId,
1449
+ functionId
1450
+ );
1451
+ let rootSpan;
1452
+ if (this.sendTraces) {
1453
+ const promptAttrs = !isEmbed && recordInputs ? [
1454
+ attrString(
1455
+ "ai.prompt",
1456
+ safeJsonWithUint8({
1457
+ system: event.system,
1458
+ prompt: event.prompt,
1459
+ messages: event.messages
1460
+ })
1461
+ )
1462
+ ] : [];
1463
+ const embedAttrs = isEmbed && recordInputs ? event.operationId === "ai.embedMany" ? [
1464
+ attrString(
1465
+ "ai.values",
1466
+ safeJsonWithUint8(event.value)
1467
+ )
1468
+ ] : [attrString("ai.value", safeJsonWithUint8(event.value))] : [];
1469
+ rootSpan = this.traceShipper.startSpan({
1470
+ name: event.operationId,
1471
+ parent: inheritedParent,
1472
+ eventId,
1473
+ operationId: event.operationId,
1474
+ attributes: [
1475
+ attrString("operation.name", operationName),
1476
+ attrString("resource.name", resourceName),
1477
+ attrString("ai.telemetry.functionId", functionId),
1478
+ attrString("ai.model.provider", event.provider),
1479
+ attrString("ai.model.id", event.modelId),
1480
+ ...attrsFromTelemetryMetadata(metadata),
1481
+ ...promptAttrs,
1482
+ ...embedAttrs
1483
+ ]
1484
+ });
1485
+ }
1486
+ this.callStates.set(event.callId, {
1487
+ operationId: event.operationId,
1488
+ eventId,
1489
+ rootSpan,
1490
+ rootParent: rootSpan ? this.spanParentRef(rootSpan) : inheritedParent,
1491
+ stepSpan: void 0,
1492
+ stepParent: void 0,
1493
+ toolSpans: /* @__PURE__ */ new Map(),
1494
+ embedSpans: /* @__PURE__ */ new Map(),
1495
+ recordInputs,
1496
+ recordOutputs,
1497
+ functionId,
1498
+ metadata,
1499
+ accumulatedText: "",
1500
+ inputText: isEmbed ? void 0 : this.extractInputText(event),
1501
+ toolCallCount: 0
1502
+ });
1503
+ };
1504
+ // ── onStepStart ─────────────────────────────────────────────────────────
1505
+ this.onStepStart = (event) => {
1506
+ const state = this.getState(event.callId);
1507
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
1508
+ const isStream = state.operationId === "ai.streamText" || state.operationId === "ai.streamObject";
1509
+ const stepOperationId = isStream ? `${state.operationId}.doStream` : `${state.operationId}.doGenerate`;
1510
+ const { operationName, resourceName } = opName(
1511
+ stepOperationId,
1512
+ state.functionId
1513
+ );
1514
+ const inputAttrs = [];
1515
+ if (state.recordInputs) {
1516
+ if (event.promptMessages) {
1517
+ inputAttrs.push(
1518
+ attrString(
1519
+ "ai.prompt.messages",
1520
+ safeJsonWithUint8(event.promptMessages)
1521
+ )
1522
+ );
1523
+ }
1524
+ if (event.stepTools) {
1525
+ inputAttrs.push(
1526
+ attrStringArray(
1527
+ "ai.prompt.tools",
1528
+ event.stepTools.map((t) => JSON.stringify(t))
1529
+ )
1530
+ );
1531
+ }
1532
+ if (event.stepToolChoice != null) {
1533
+ inputAttrs.push(
1534
+ attrString(
1535
+ "ai.prompt.toolChoice",
1536
+ JSON.stringify(event.stepToolChoice)
1537
+ )
1538
+ );
1539
+ }
1540
+ }
1541
+ const stepSpan = this.traceShipper.startSpan({
1542
+ name: stepOperationId,
1543
+ parent: state.rootParent,
1544
+ eventId: state.eventId,
1545
+ operationId: stepOperationId,
1546
+ attributes: [
1547
+ attrString("operation.name", operationName),
1548
+ attrString("resource.name", resourceName),
1549
+ attrString("ai.telemetry.functionId", state.functionId),
1550
+ attrString("ai.model.provider", event.provider),
1551
+ attrString("ai.model.id", event.modelId),
1552
+ attrString("gen_ai.system", event.provider),
1553
+ attrString("gen_ai.request.model", event.modelId),
1554
+ ...inputAttrs
1555
+ ]
1556
+ });
1557
+ state.stepSpan = stepSpan;
1558
+ state.stepParent = this.spanParentRef(stepSpan);
1559
+ };
1560
+ // ── onToolCallStart ─────────────────────────────────────────────────────
1561
+ this.onToolCallStart = (event) => {
1562
+ const state = this.getState(event.callId);
1563
+ if (!(state == null ? void 0 : state.stepParent)) return;
1564
+ const { toolCall } = event;
1565
+ const { operationName, resourceName } = opName(
1566
+ "ai.toolCall",
1567
+ state.functionId
1568
+ );
1569
+ const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
1570
+ const toolSpan = this.traceShipper.startSpan({
1571
+ name: "ai.toolCall",
1572
+ parent: state.stepParent,
1573
+ eventId: state.eventId,
1574
+ operationId: "ai.toolCall",
1575
+ attributes: [
1576
+ attrString("operation.name", operationName),
1577
+ attrString("resource.name", resourceName),
1578
+ attrString("ai.telemetry.functionId", state.functionId),
1579
+ attrString("ai.toolCall.name", toolCall.toolName),
1580
+ attrString("ai.toolCall.id", toolCall.toolCallId),
1581
+ ...inputAttrs
1582
+ ]
1583
+ });
1584
+ state.toolSpans.set(toolCall.toolCallId, toolSpan);
1585
+ };
1586
+ // ── onToolCallFinish ────────────────────────────────────────────────────
1587
+ this.onToolCallFinish = (event) => {
1588
+ const state = this.getState(event.callId);
1589
+ if (!state) return;
1590
+ const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
1591
+ if (!toolSpan) return;
1592
+ state.toolCallCount += 1;
1593
+ if (event.success) {
1594
+ const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(event.output))] : [];
1595
+ this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
1596
+ } else {
1597
+ this.traceShipper.endSpan(toolSpan, { error: event.error });
1598
+ }
1599
+ state.toolSpans.delete(event.toolCall.toolCallId);
1600
+ };
1601
+ // ── onChunk (streaming) ─────────────────────────────────────────────────
1602
+ this.onChunk = (event) => {
1603
+ var _a, _b, _c;
1604
+ const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
1605
+ if (!callId) return;
1606
+ const state = this.getState(callId);
1607
+ if (!state) return;
1608
+ const chunk = event.chunk;
1609
+ if (!chunk || typeof chunk !== "object") return;
1610
+ if (chunk.type === "text-delta") {
1611
+ const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
1612
+ if (typeof delta === "string") {
1613
+ state.accumulatedText += delta;
1614
+ }
1615
+ }
1616
+ };
1617
+ // ── onStepFinish ────────────────────────────────────────────────────────
1618
+ this.onStepFinish = (event) => {
1619
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1620
+ const state = this.getState(event.callId);
1621
+ if (!(state == null ? void 0 : state.stepSpan)) return;
1622
+ const outputAttrs = [];
1623
+ if (state.recordOutputs) {
1624
+ outputAttrs.push(
1625
+ attrString("ai.response.finishReason", event.finishReason),
1626
+ attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
1627
+ attrString("ai.response.id", (_b = event.response) == null ? void 0 : _b.id),
1628
+ attrString("ai.response.model", (_c = event.response) == null ? void 0 : _c.modelId),
1629
+ attrString(
1630
+ "ai.response.timestamp",
1631
+ ((_d = event.response) == null ? void 0 : _d.timestamp) instanceof Date ? event.response.timestamp.toISOString() : (_e = event.response) == null ? void 0 : _e.timestamp
1632
+ ),
1633
+ attrString(
1634
+ "ai.response.providerMetadata",
1635
+ event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
1636
+ )
1637
+ );
1638
+ if (((_f = event.toolCalls) == null ? void 0 : _f.length) > 0) {
1639
+ outputAttrs.push(
1640
+ attrString(
1641
+ "ai.response.toolCalls",
1642
+ JSON.stringify(
1643
+ event.toolCalls.map((tc) => ({
1644
+ toolCallId: tc.toolCallId,
1645
+ toolName: tc.toolName,
1646
+ input: tc.input
1647
+ }))
1648
+ )
1649
+ )
1650
+ );
1651
+ }
1652
+ if (((_g = event.reasoning) == null ? void 0 : _g.length) > 0) {
1653
+ const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
1654
+ if (reasoningText) {
1655
+ outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
1656
+ }
1657
+ }
1658
+ }
1659
+ outputAttrs.push(
1660
+ attrStringArray("gen_ai.response.finish_reasons", [event.finishReason]),
1661
+ attrString("gen_ai.response.id", (_h = event.response) == null ? void 0 : _h.id),
1662
+ attrString("gen_ai.response.model", (_i = event.response) == null ? void 0 : _i.modelId)
1663
+ );
1664
+ const usage = event.usage;
1665
+ if (usage) {
1666
+ outputAttrs.push(
1667
+ attrInt("ai.usage.inputTokens", usage.inputTokens),
1668
+ attrInt("ai.usage.outputTokens", usage.outputTokens),
1669
+ attrInt("ai.usage.totalTokens", usage.totalTokens),
1670
+ attrInt("ai.usage.reasoningTokens", usage.reasoningTokens),
1671
+ attrInt("ai.usage.cachedInputTokens", usage.cachedInputTokens),
1672
+ attrInt("gen_ai.usage.input_tokens", usage.inputTokens),
1673
+ attrInt("gen_ai.usage.output_tokens", usage.outputTokens)
1674
+ );
1675
+ }
1676
+ this.traceShipper.endSpan(state.stepSpan, { attributes: outputAttrs });
1677
+ state.stepSpan = void 0;
1678
+ state.stepParent = void 0;
1679
+ };
1680
+ // ── onEmbedStart ────────────────────────────────────────────────────────
1681
+ this.onEmbedStart = (event) => {
1682
+ const state = this.getState(event.callId);
1683
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
1684
+ const { operationName, resourceName } = opName(
1685
+ event.operationId,
1686
+ state.functionId
1687
+ );
1688
+ const inputAttrs = state.recordInputs ? [
1689
+ attrString(
1690
+ "ai.values",
1691
+ safeJsonWithUint8(event.values)
1692
+ )
1693
+ ] : [];
1694
+ const embedSpan = this.traceShipper.startSpan({
1695
+ name: event.operationId,
1696
+ parent: state.rootParent,
1697
+ eventId: state.eventId,
1698
+ operationId: event.operationId,
1699
+ attributes: [
1700
+ attrString("operation.name", operationName),
1701
+ attrString("resource.name", resourceName),
1702
+ attrString("ai.telemetry.functionId", state.functionId),
1703
+ ...inputAttrs
1704
+ ]
1705
+ });
1706
+ state.embedSpans.set(event.embedCallId, embedSpan);
1707
+ };
1708
+ // ── onEmbedFinish ───────────────────────────────────────────────────────
1709
+ this.onEmbedFinish = (event) => {
1710
+ var _a;
1711
+ const state = this.getState(event.callId);
1712
+ if (!state) return;
1713
+ const embedSpan = state.embedSpans.get(event.embedCallId);
1714
+ if (!embedSpan) return;
1715
+ const outputAttrs = [];
1716
+ if (state.recordOutputs) {
1717
+ outputAttrs.push(
1718
+ attrString(
1719
+ "ai.embeddings",
1720
+ safeJsonWithUint8(event.embeddings)
1721
+ )
1722
+ );
1723
+ }
1724
+ if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
1725
+ outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
1726
+ }
1727
+ this.traceShipper.endSpan(embedSpan, { attributes: outputAttrs });
1728
+ state.embedSpans.delete(event.embedCallId);
1729
+ };
1730
+ // ── onFinish ────────────────────────────────────────────────────────────
1731
+ this.onFinish = (event) => {
1732
+ const state = this.getState(event.callId);
1733
+ if (!state) return;
1734
+ const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
1735
+ if (isEmbed) {
1736
+ this.finishEmbed(event, state);
1737
+ } else {
1738
+ this.finishGenerate(event, state);
1739
+ }
1740
+ this.cleanup(event.callId);
1741
+ };
1742
+ // ── onError ─────────────────────────────────────────────────────────────
1743
+ this.onError = (error) => {
1744
+ var _a;
1745
+ const event = error;
1746
+ if (!(event == null ? void 0 : event.callId)) return;
1747
+ const state = this.getState(event.callId);
1748
+ if (!state) return;
1749
+ const actualError = (_a = event.error) != null ? _a : error;
1750
+ if (state.stepSpan) {
1751
+ this.traceShipper.endSpan(state.stepSpan, { error: actualError });
1752
+ }
1753
+ for (const embedSpan of state.embedSpans.values()) {
1754
+ this.traceShipper.endSpan(embedSpan, { error: actualError });
1755
+ }
1756
+ state.embedSpans.clear();
1757
+ for (const toolSpan of state.toolSpans.values()) {
1758
+ this.traceShipper.endSpan(toolSpan, { error: actualError });
1759
+ }
1760
+ state.toolSpans.clear();
1761
+ if (state.rootSpan) {
1762
+ this.traceShipper.endSpan(state.rootSpan, { error: actualError });
1763
+ }
1764
+ this.cleanup(event.callId);
1765
+ };
1766
+ // ── executeTool ─────────────────────────────────────────────────────────
1767
+ this.executeTool = async ({
1768
+ callId,
1769
+ toolCallId,
1770
+ execute
1771
+ }) => {
1772
+ const state = this.getState(callId);
1773
+ const toolSpan = state == null ? void 0 : state.toolSpans.get(toolCallId);
1774
+ if (!toolSpan) return execute();
1775
+ return runWithParentSpanContext(
1776
+ {
1777
+ traceIdB64: toolSpan.ids.traceIdB64,
1778
+ spanIdB64: toolSpan.ids.spanIdB64,
1779
+ eventId: state.eventId
1780
+ },
1781
+ () => execute()
1782
+ );
1783
+ };
1784
+ this.traceShipper = opts.traceShipper;
1785
+ this.eventShipper = opts.eventShipper;
1786
+ this.sendTraces = opts.sendTraces !== false;
1787
+ this.sendEvents = opts.sendEvents !== false;
1788
+ this.debug = opts.debug === true;
1789
+ this.defaultContext = opts.context;
1790
+ }
1791
+ // ── helpers ──────────────────────────────────────────────────────────────
1792
+ getState(callId) {
1793
+ return this.callStates.get(callId);
1794
+ }
1795
+ cleanup(callId) {
1796
+ this.callStates.delete(callId);
1797
+ }
1798
+ spanParentRef(span) {
1799
+ return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
1800
+ }
1801
+ extractRaindropMetadata(metadata) {
1802
+ if (!metadata) return {};
1803
+ const result = {};
1804
+ const userId = metadata["raindrop.userId"];
1805
+ if (typeof userId === "string" && userId) result.userId = userId;
1806
+ const eventId = metadata["raindrop.eventId"];
1807
+ if (typeof eventId === "string" && eventId) result.eventId = eventId;
1808
+ const convoId = metadata["raindrop.convoId"];
1809
+ if (typeof convoId === "string" && convoId) result.convoId = convoId;
1810
+ const eventName = metadata["raindrop.eventName"];
1811
+ if (typeof eventName === "string" && eventName) result.eventName = eventName;
1812
+ const properties = metadata["raindrop.properties"];
1813
+ if (typeof properties === "string") {
1814
+ try {
1815
+ result.properties = JSON.parse(properties);
1816
+ } catch (e) {
1817
+ }
1818
+ } else if (properties && typeof properties === "object") {
1819
+ result.properties = properties;
1820
+ }
1821
+ return result;
1822
+ }
1823
+ /**
1824
+ * Extract the user-facing input text from an onStart event.
1825
+ * Mirrors the logic in the v4-v6 Proxy path (lastUserMessageTextFromArgs / extractInputFromArgs).
1826
+ */
1827
+ extractInputText(event) {
1828
+ if (typeof event.prompt === "string") return event.prompt;
1829
+ if (Array.isArray(event.messages)) {
1830
+ for (let i = event.messages.length - 1; i >= 0; i--) {
1831
+ const msg = event.messages[i];
1832
+ if ((msg == null ? void 0 : msg.role) === "user") {
1833
+ if (typeof msg.content === "string") return msg.content;
1834
+ if (Array.isArray(msg.content)) {
1835
+ const textPart = msg.content.find(
1836
+ (p) => (p == null ? void 0 : p.type) === "text" && typeof p.text === "string"
1837
+ );
1838
+ if (textPart) return textPart.text;
1839
+ }
1840
+ }
1841
+ }
1842
+ }
1843
+ return void 0;
1844
+ }
1845
+ finishGenerate(event, state) {
1846
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1847
+ if (state.rootSpan) {
1848
+ const outputAttrs = [];
1849
+ if (state.recordOutputs) {
1850
+ outputAttrs.push(
1851
+ attrString("ai.response.finishReason", event.finishReason),
1852
+ attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
1853
+ attrString(
1854
+ "ai.response.providerMetadata",
1855
+ event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
1856
+ )
1857
+ );
1858
+ if (((_b = event.toolCalls) == null ? void 0 : _b.length) > 0) {
1859
+ outputAttrs.push(
1860
+ attrString(
1861
+ "ai.response.toolCalls",
1862
+ JSON.stringify(
1863
+ event.toolCalls.map((tc) => ({
1864
+ toolCallId: tc.toolCallId,
1865
+ toolName: tc.toolName,
1866
+ input: tc.input
1867
+ }))
1868
+ )
1869
+ )
1870
+ );
1871
+ }
1872
+ if (((_c = event.reasoning) == null ? void 0 : _c.length) > 0) {
1873
+ const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
1874
+ if (reasoningText) {
1875
+ outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
1876
+ }
1877
+ }
1878
+ }
1879
+ const usage = (_d = event.totalUsage) != null ? _d : event.usage;
1880
+ if (usage) {
1881
+ outputAttrs.push(
1882
+ attrInt("ai.usage.inputTokens", usage.inputTokens),
1883
+ attrInt("ai.usage.outputTokens", usage.outputTokens),
1884
+ attrInt("ai.usage.totalTokens", usage.totalTokens),
1885
+ attrInt("ai.usage.reasoningTokens", usage.reasoningTokens),
1886
+ attrInt("ai.usage.cachedInputTokens", usage.cachedInputTokens)
1887
+ );
1888
+ }
1889
+ outputAttrs.push(
1890
+ attrInt("ai.toolCall.count", state.toolCallCount)
1891
+ );
1892
+ this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
1893
+ }
1894
+ if (this.sendEvents) {
1895
+ const callMeta = this.extractRaindropMetadata(state.metadata);
1896
+ const userId = (_f = callMeta.userId) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.userId;
1897
+ if (userId) {
1898
+ const eventName = (_i = (_h = callMeta.eventName) != null ? _h : (_g = this.defaultContext) == null ? void 0 : _g.eventName) != null ? _i : state.operationId;
1899
+ const output = (_j = event.text) != null ? _j : state.accumulatedText || void 0;
1900
+ const input = state.inputText;
1901
+ const model = (_k = event.response) == null ? void 0 : _k.modelId;
1902
+ const properties = {
1903
+ ...(_l = this.defaultContext) == null ? void 0 : _l.properties,
1904
+ ...callMeta.properties
1905
+ };
1906
+ const convoId = (_n = callMeta.convoId) != null ? _n : (_m = this.defaultContext) == null ? void 0 : _m.convoId;
1907
+ void this.eventShipper.patch(state.eventId, {
1908
+ eventName,
1909
+ userId,
1910
+ convoId,
1911
+ input,
1912
+ output,
1913
+ model,
1914
+ properties: Object.keys(properties).length > 0 ? properties : void 0,
1915
+ isPending: false
1916
+ }).catch((err) => {
1917
+ if (this.debug) {
1918
+ console.warn(
1919
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
1920
+ );
1921
+ }
1922
+ });
1923
+ }
1924
+ }
1925
+ }
1926
+ finishEmbed(event, state) {
1927
+ var _a;
1928
+ if (!state.rootSpan) return;
1929
+ const outputAttrs = [];
1930
+ const isMany = state.operationId === "ai.embedMany";
1931
+ if (state.recordOutputs) {
1932
+ if (isMany) {
1933
+ outputAttrs.push(
1934
+ attrString("ai.embeddings", safeJsonWithUint8(event.embedding))
1935
+ );
1936
+ } else {
1937
+ outputAttrs.push(
1938
+ attrString("ai.embedding", safeJsonWithUint8(event.embedding))
1939
+ );
1940
+ }
1941
+ }
1942
+ if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
1943
+ outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
1944
+ }
1945
+ this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
1946
+ }
1947
+ };
1948
+
1949
+ // src/internal/traces.ts
1950
+ var TraceShipper2 = class extends TraceShipper {
1951
+ constructor(opts) {
1952
+ var _a, _b, _c;
1953
+ super({
1954
+ ...opts,
1955
+ sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
1956
+ serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.ai-sdk",
1957
+ serviceVersion: (_c = opts.serviceVersion) != null ? _c : libraryVersion
1958
+ });
1959
+ }
1960
+ };
1961
+
1441
1962
  // src/internal/wrap/wrapAISDK.ts
1442
1963
  var AGENT_REPORTING_TOOL_NAME_DEFAULT = "__raindrop_report";
1443
1964
  var AGENT_REPORTING_SIGNALS_DEFAULT = {
@@ -1647,6 +2168,9 @@ function detectAISDKVersion(aiSDK) {
1647
2168
  if (isFunction(aiSDK["tool"])) return "5";
1648
2169
  return "4";
1649
2170
  }
2171
+ function hasStructuredTelemetryEvents(aiSDK) {
2172
+ return isRecord(aiSDK) && isFunction(aiSDK["registerTelemetryIntegration"]) && isFunction(aiSDK["experimental_streamModelCall"]);
2173
+ }
1650
2174
  function asVercelSchema(jsonSchemaObj) {
1651
2175
  const validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
1652
2176
  const schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
@@ -2229,8 +2753,93 @@ async function executeNonStreamingOperation(params) {
2229
2753
  }
2230
2754
  }
2231
2755
  function wrapAISDK(aiSDK, deps) {
2232
- var _a, _b;
2756
+ var _a, _b, _c, _d;
2233
2757
  const debug = deps.eventShipper.isDebugEnabled() || deps.traceShipper.isDebugEnabled();
2758
+ if (deps.options.nativeTelemetry === true) {
2759
+ if (!hasStructuredTelemetryEvents(aiSDK)) {
2760
+ throw new Error(
2761
+ "[raindrop-ai/ai-sdk] nativeTelemetry requires AI SDK v7+. The AI SDK module passed to wrap() does not support structured telemetry events. Remove nativeTelemetry or upgrade to AI SDK v7."
2762
+ );
2763
+ }
2764
+ }
2765
+ const useNative = deps.options.nativeTelemetry === true;
2766
+ if (useNative) {
2767
+ const wrapTimeCtx = resolveContext(deps.options.context, { operation: "wrap", args: void 0 });
2768
+ const integration = new RaindropTelemetryIntegration({
2769
+ traceShipper: deps.traceShipper,
2770
+ eventShipper: deps.eventShipper,
2771
+ sendTraces: ((_a = deps.options.send) == null ? void 0 : _a.traces) !== false,
2772
+ sendEvents: ((_b = deps.options.send) == null ? void 0 : _b.events) !== false,
2773
+ debug,
2774
+ context: {
2775
+ userId: wrapTimeCtx.userId,
2776
+ eventId: wrapTimeCtx.eventId,
2777
+ eventName: wrapTimeCtx.eventName,
2778
+ convoId: wrapTimeCtx.convoId,
2779
+ properties: wrapTimeCtx.properties
2780
+ }
2781
+ });
2782
+ const registerFn = aiSDK["registerTelemetryIntegration"];
2783
+ if (isFunction(registerFn)) {
2784
+ registerFn(integration);
2785
+ }
2786
+ if (debug) {
2787
+ console.log("[raindrop-ai/ai-sdk] nativeTelemetry: registered RaindropTelemetryIntegration (no Proxy)");
2788
+ }
2789
+ const selfDiagnostics2 = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
2790
+ if (selfDiagnostics2) {
2791
+ const textOps = /* @__PURE__ */ new Set(["generateText", "streamText"]);
2792
+ const jsonSchemaFactory = resolveJsonSchemaFactory(aiSDK);
2793
+ const proxyTarget2 = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
2794
+ return new Proxy(proxyTarget2, {
2795
+ get(target, prop, receiver) {
2796
+ const original = Reflect.get(target, prop, receiver);
2797
+ if (typeof prop !== "string" || !textOps.has(prop) || !isFunction(original)) {
2798
+ return original;
2799
+ }
2800
+ return (...callArgs) => {
2801
+ var _a2, _b2;
2802
+ const arg = callArgs[0];
2803
+ if (!isRecord(arg)) return original.call(aiSDK, ...callArgs);
2804
+ const telemetry = extractExperimentalTelemetry(arg);
2805
+ const callMeta = (telemetry == null ? void 0 : telemetry.metadata) ? extractRaindropMetadata(telemetry.metadata) : {};
2806
+ const perCallEventId = (_b2 = (_a2 = callMeta.eventId) != null ? _a2 : wrapTimeCtx.eventId) != null ? _b2 : randomUUID();
2807
+ const perCallCtx = {
2808
+ eventId: perCallEventId,
2809
+ telemetry,
2810
+ sendTraces: false,
2811
+ debug,
2812
+ eventShipper: deps.eventShipper,
2813
+ traceShipper: deps.traceShipper,
2814
+ rootParentForChildren: void 0,
2815
+ jsonSchemaFactory,
2816
+ selfDiagnostics: selfDiagnostics2,
2817
+ aiSDKVersion: "7"
2818
+ };
2819
+ const tools = isRecord(arg["tools"]) ? { ...arg["tools"] } : {};
2820
+ const toolName = selfDiagnostics2.toolName;
2821
+ if (!(toolName in tools)) {
2822
+ const reportTool = createSelfDiagnosticsTool(perCallCtx);
2823
+ if (reportTool) tools[toolName] = reportTool;
2824
+ }
2825
+ const existingTelemetry = isRecord(arg["experimental_telemetry"]) ? arg["experimental_telemetry"] : {};
2826
+ const existingMetadata = isRecord(existingTelemetry["metadata"]) ? existingTelemetry["metadata"] : {};
2827
+ const mergedMetadata = existingMetadata["raindrop.eventId"] ? existingMetadata : { ...existingMetadata, "raindrop.eventId": perCallEventId };
2828
+ callArgs[0] = {
2829
+ ...arg,
2830
+ tools,
2831
+ experimental_telemetry: {
2832
+ ...existingTelemetry,
2833
+ metadata: mergedMetadata
2834
+ }
2835
+ };
2836
+ return original.call(aiSDK, ...callArgs);
2837
+ };
2838
+ }
2839
+ });
2840
+ }
2841
+ return aiSDK;
2842
+ }
2234
2843
  const instrumentedOps = /* @__PURE__ */ new Set([
2235
2844
  "generateText",
2236
2845
  "streamText",
@@ -2238,8 +2847,8 @@ function wrapAISDK(aiSDK, deps) {
2238
2847
  "streamObject"
2239
2848
  ]);
2240
2849
  const agentClasses = /* @__PURE__ */ new Set(["Agent", "Experimental_Agent", "ToolLoopAgent"]);
2241
- const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
2242
- const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
2850
+ const sendEvents = ((_c = deps.options.send) == null ? void 0 : _c.events) !== false;
2851
+ const sendTraces = ((_d = deps.options.send) == null ? void 0 : _d.traces) !== false;
2243
2852
  const autoAttachmentEnabled = deps.options.autoAttachment !== false;
2244
2853
  const selfDiagnostics = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
2245
2854
  const proxyTarget = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
@@ -3333,6 +3942,16 @@ function createRaindropAISDK(opts) {
3333
3942
  traceShipper
3334
3943
  });
3335
3944
  },
3945
+ createTelemetryIntegration(context) {
3946
+ return new RaindropTelemetryIntegration({
3947
+ traceShipper,
3948
+ eventShipper,
3949
+ sendTraces: tracesEnabled,
3950
+ sendEvents: eventsEnabled,
3951
+ debug: envDebug,
3952
+ context
3953
+ });
3954
+ },
3336
3955
  events: {
3337
3956
  async patch(eventId, patch) {
3338
3957
  await eventShipper.patch(eventId, patch);
@@ -3371,6 +3990,7 @@ if (!globalThis.RAINDROP_ASYNC_LOCAL_STORAGE) {
3371
3990
  globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
3372
3991
  }
3373
3992
 
3993
+ exports.RaindropTelemetryIntegration = RaindropTelemetryIntegration;
3374
3994
  exports._resetWarnedMissingUserId = _resetWarnedMissingUserId;
3375
3995
  exports.createRaindropAISDK = createRaindropAISDK;
3376
3996
  exports.currentSpan = currentSpan;