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