@raindrop-ai/ai-sdk 0.0.19 → 0.0.20

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.
@@ -730,7 +730,7 @@ async function* asyncGeneratorWithCurrent(span, gen) {
730
730
  // package.json
731
731
  var package_default = {
732
732
  name: "@raindrop-ai/ai-sdk",
733
- version: "0.0.19"};
733
+ version: "0.0.20"};
734
734
 
735
735
  // src/internal/version.ts
736
736
  var libraryName = package_default.name;
@@ -749,19 +749,6 @@ var EventShipper2 = class extends EventShipper {
749
749
  }
750
750
  };
751
751
 
752
- // src/internal/traces.ts
753
- var TraceShipper2 = class extends TraceShipper {
754
- constructor(opts) {
755
- var _a, _b, _c;
756
- super({
757
- ...opts,
758
- sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
759
- serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.ai-sdk",
760
- serviceVersion: (_c = opts.serviceVersion) != null ? _c : libraryVersion
761
- });
762
- }
763
- };
764
-
765
752
  // src/internal/wrap/helpers.ts
766
753
  function isRecord(value) {
767
754
  return typeof value === "object" && value !== null;
@@ -1383,6 +1370,549 @@ function attrsFromGenAiRequest(options) {
1383
1370
  ];
1384
1371
  }
1385
1372
 
1373
+ // src/internal/raindrop-telemetry-integration.ts
1374
+ var RaindropTelemetryIntegration = class {
1375
+ constructor(opts) {
1376
+ this.callStates = /* @__PURE__ */ new Map();
1377
+ // ── onStart ─────────────────────────────────────────────────────────────
1378
+ this.onStart = (event) => {
1379
+ var _a, _b, _c, _d;
1380
+ if (event.isEnabled !== true) return;
1381
+ const isEmbed = event.operationId === "ai.embed" || event.operationId === "ai.embedMany";
1382
+ const recordInputs = event.recordInputs !== false;
1383
+ const recordOutputs = event.recordOutputs !== false;
1384
+ const functionId = event.functionId;
1385
+ const metadata = event.metadata;
1386
+ const callMeta = this.extractRaindropMetadata(metadata);
1387
+ const inherited = getContextManager().getParentSpanIds();
1388
+ const eventIdGenerated = (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === "true" || (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === true;
1389
+ const explicitEventId = callMeta.eventId && !eventIdGenerated ? callMeta.eventId : void 0;
1390
+ 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();
1391
+ const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
1392
+ const { operationName, resourceName } = opName(
1393
+ event.operationId,
1394
+ functionId
1395
+ );
1396
+ let rootSpan;
1397
+ if (this.sendTraces) {
1398
+ const promptAttrs = !isEmbed && recordInputs ? [
1399
+ attrString(
1400
+ "ai.prompt",
1401
+ safeJsonWithUint8({
1402
+ system: event.system,
1403
+ prompt: event.prompt,
1404
+ messages: event.messages
1405
+ })
1406
+ )
1407
+ ] : [];
1408
+ const embedAttrs = isEmbed && recordInputs ? event.operationId === "ai.embedMany" ? [
1409
+ attrString(
1410
+ "ai.values",
1411
+ safeJsonWithUint8(event.value)
1412
+ )
1413
+ ] : [attrString("ai.value", safeJsonWithUint8(event.value))] : [];
1414
+ rootSpan = this.traceShipper.startSpan({
1415
+ name: event.operationId,
1416
+ parent: inheritedParent,
1417
+ eventId,
1418
+ operationId: event.operationId,
1419
+ attributes: [
1420
+ attrString("operation.name", operationName),
1421
+ attrString("resource.name", resourceName),
1422
+ attrString("ai.telemetry.functionId", functionId),
1423
+ attrString("ai.model.provider", event.provider),
1424
+ attrString("ai.model.id", event.modelId),
1425
+ // Filter out raindrop.eventId from metadata attrs since TraceShipper
1426
+ // already sets it via the eventId arg. Without this, eventMetadata()'s
1427
+ // auto-generated ID would duplicate and override the resolved one.
1428
+ ...attrsFromTelemetryMetadata(
1429
+ metadata ? Object.fromEntries(
1430
+ Object.entries(metadata).filter(
1431
+ ([k]) => k !== "raindrop.eventId" && k !== "raindrop.internal.eventIdGenerated"
1432
+ )
1433
+ ) : void 0
1434
+ ),
1435
+ ...promptAttrs,
1436
+ ...embedAttrs
1437
+ ]
1438
+ });
1439
+ }
1440
+ this.callStates.set(event.callId, {
1441
+ operationId: event.operationId,
1442
+ eventId,
1443
+ rootSpan,
1444
+ rootParent: rootSpan ? this.spanParentRef(rootSpan) : inheritedParent,
1445
+ stepSpan: void 0,
1446
+ stepParent: void 0,
1447
+ toolSpans: /* @__PURE__ */ new Map(),
1448
+ embedSpans: /* @__PURE__ */ new Map(),
1449
+ recordInputs,
1450
+ recordOutputs,
1451
+ functionId,
1452
+ metadata,
1453
+ accumulatedText: "",
1454
+ inputText: isEmbed ? void 0 : this.extractInputText(event),
1455
+ toolCallCount: 0
1456
+ });
1457
+ };
1458
+ // ── onStepStart ─────────────────────────────────────────────────────────
1459
+ this.onStepStart = (event) => {
1460
+ const state = this.getState(event.callId);
1461
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
1462
+ const isStream = state.operationId === "ai.streamText" || state.operationId === "ai.streamObject";
1463
+ const stepOperationId = isStream ? `${state.operationId}.doStream` : `${state.operationId}.doGenerate`;
1464
+ const { operationName, resourceName } = opName(
1465
+ stepOperationId,
1466
+ state.functionId
1467
+ );
1468
+ const inputAttrs = [];
1469
+ if (state.recordInputs) {
1470
+ if (event.promptMessages) {
1471
+ inputAttrs.push(
1472
+ attrString(
1473
+ "ai.prompt.messages",
1474
+ safeJsonWithUint8(event.promptMessages)
1475
+ )
1476
+ );
1477
+ }
1478
+ if (event.stepTools) {
1479
+ inputAttrs.push(
1480
+ attrStringArray(
1481
+ "ai.prompt.tools",
1482
+ event.stepTools.map((t) => JSON.stringify(t))
1483
+ )
1484
+ );
1485
+ }
1486
+ if (event.stepToolChoice != null) {
1487
+ inputAttrs.push(
1488
+ attrString(
1489
+ "ai.prompt.toolChoice",
1490
+ JSON.stringify(event.stepToolChoice)
1491
+ )
1492
+ );
1493
+ }
1494
+ }
1495
+ const stepSpan = this.traceShipper.startSpan({
1496
+ name: stepOperationId,
1497
+ parent: state.rootParent,
1498
+ eventId: state.eventId,
1499
+ operationId: stepOperationId,
1500
+ attributes: [
1501
+ attrString("operation.name", operationName),
1502
+ attrString("resource.name", resourceName),
1503
+ attrString("ai.telemetry.functionId", state.functionId),
1504
+ attrString("ai.model.provider", event.provider),
1505
+ attrString("ai.model.id", event.modelId),
1506
+ attrString("gen_ai.system", event.provider),
1507
+ attrString("gen_ai.request.model", event.modelId),
1508
+ ...inputAttrs
1509
+ ]
1510
+ });
1511
+ state.stepSpan = stepSpan;
1512
+ state.stepParent = this.spanParentRef(stepSpan);
1513
+ };
1514
+ // ── onToolCallStart ─────────────────────────────────────────────────────
1515
+ this.onToolCallStart = (event) => {
1516
+ const state = this.getState(event.callId);
1517
+ if (!(state == null ? void 0 : state.stepParent)) return;
1518
+ const { toolCall } = event;
1519
+ const { operationName, resourceName } = opName(
1520
+ "ai.toolCall",
1521
+ state.functionId
1522
+ );
1523
+ const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
1524
+ const toolSpan = this.traceShipper.startSpan({
1525
+ name: "ai.toolCall",
1526
+ parent: state.stepParent,
1527
+ eventId: state.eventId,
1528
+ operationId: "ai.toolCall",
1529
+ attributes: [
1530
+ attrString("operation.name", operationName),
1531
+ attrString("resource.name", resourceName),
1532
+ attrString("ai.telemetry.functionId", state.functionId),
1533
+ attrString("ai.toolCall.name", toolCall.toolName),
1534
+ attrString("ai.toolCall.id", toolCall.toolCallId),
1535
+ ...inputAttrs
1536
+ ]
1537
+ });
1538
+ state.toolSpans.set(toolCall.toolCallId, toolSpan);
1539
+ };
1540
+ // ── onToolCallFinish ────────────────────────────────────────────────────
1541
+ this.onToolCallFinish = (event) => {
1542
+ const state = this.getState(event.callId);
1543
+ if (!state) return;
1544
+ const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
1545
+ if (!toolSpan) return;
1546
+ state.toolCallCount += 1;
1547
+ if (event.success) {
1548
+ const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(event.output))] : [];
1549
+ this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
1550
+ } else {
1551
+ this.traceShipper.endSpan(toolSpan, { error: event.error });
1552
+ }
1553
+ state.toolSpans.delete(event.toolCall.toolCallId);
1554
+ };
1555
+ // ── onChunk (streaming) ─────────────────────────────────────────────────
1556
+ this.onChunk = (event) => {
1557
+ var _a, _b, _c;
1558
+ const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
1559
+ if (!callId) return;
1560
+ const state = this.getState(callId);
1561
+ if (!state) return;
1562
+ const chunk = event.chunk;
1563
+ if (!chunk || typeof chunk !== "object") return;
1564
+ if (chunk.type === "text-delta") {
1565
+ const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
1566
+ if (typeof delta === "string") {
1567
+ state.accumulatedText += delta;
1568
+ }
1569
+ }
1570
+ };
1571
+ // ── onStepFinish ────────────────────────────────────────────────────────
1572
+ this.onStepFinish = (event) => {
1573
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1574
+ const state = this.getState(event.callId);
1575
+ if (!(state == null ? void 0 : state.stepSpan)) return;
1576
+ const outputAttrs = [];
1577
+ if (state.recordOutputs) {
1578
+ outputAttrs.push(
1579
+ attrString("ai.response.finishReason", event.finishReason),
1580
+ attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
1581
+ attrString("ai.response.id", (_b = event.response) == null ? void 0 : _b.id),
1582
+ attrString("ai.response.model", (_c = event.response) == null ? void 0 : _c.modelId),
1583
+ attrString(
1584
+ "ai.response.timestamp",
1585
+ ((_d = event.response) == null ? void 0 : _d.timestamp) instanceof Date ? event.response.timestamp.toISOString() : (_e = event.response) == null ? void 0 : _e.timestamp
1586
+ ),
1587
+ attrString(
1588
+ "ai.response.providerMetadata",
1589
+ event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
1590
+ )
1591
+ );
1592
+ if (((_f = event.toolCalls) == null ? void 0 : _f.length) > 0) {
1593
+ outputAttrs.push(
1594
+ attrString(
1595
+ "ai.response.toolCalls",
1596
+ JSON.stringify(
1597
+ event.toolCalls.map((tc) => ({
1598
+ toolCallId: tc.toolCallId,
1599
+ toolName: tc.toolName,
1600
+ input: tc.input
1601
+ }))
1602
+ )
1603
+ )
1604
+ );
1605
+ }
1606
+ if (((_g = event.reasoning) == null ? void 0 : _g.length) > 0) {
1607
+ const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
1608
+ if (reasoningText) {
1609
+ outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
1610
+ }
1611
+ }
1612
+ }
1613
+ outputAttrs.push(
1614
+ attrStringArray("gen_ai.response.finish_reasons", [event.finishReason]),
1615
+ attrString("gen_ai.response.id", (_h = event.response) == null ? void 0 : _h.id),
1616
+ attrString("gen_ai.response.model", (_i = event.response) == null ? void 0 : _i.modelId)
1617
+ );
1618
+ const usage = event.usage;
1619
+ if (usage) {
1620
+ outputAttrs.push(
1621
+ attrInt("ai.usage.inputTokens", usage.inputTokens),
1622
+ attrInt("ai.usage.outputTokens", usage.outputTokens),
1623
+ attrInt("ai.usage.totalTokens", usage.totalTokens),
1624
+ attrInt("ai.usage.reasoningTokens", usage.reasoningTokens),
1625
+ attrInt("ai.usage.cachedInputTokens", usage.cachedInputTokens),
1626
+ attrInt("gen_ai.usage.input_tokens", usage.inputTokens),
1627
+ attrInt("gen_ai.usage.output_tokens", usage.outputTokens)
1628
+ );
1629
+ }
1630
+ this.traceShipper.endSpan(state.stepSpan, { attributes: outputAttrs });
1631
+ state.stepSpan = void 0;
1632
+ state.stepParent = void 0;
1633
+ };
1634
+ // ── onEmbedStart ────────────────────────────────────────────────────────
1635
+ this.onEmbedStart = (event) => {
1636
+ const state = this.getState(event.callId);
1637
+ if (!(state == null ? void 0 : state.rootSpan) || !state.rootParent) return;
1638
+ const { operationName, resourceName } = opName(
1639
+ event.operationId,
1640
+ state.functionId
1641
+ );
1642
+ const inputAttrs = state.recordInputs ? [
1643
+ attrString(
1644
+ "ai.values",
1645
+ safeJsonWithUint8(event.values)
1646
+ )
1647
+ ] : [];
1648
+ const embedSpan = this.traceShipper.startSpan({
1649
+ name: event.operationId,
1650
+ parent: state.rootParent,
1651
+ eventId: state.eventId,
1652
+ operationId: event.operationId,
1653
+ attributes: [
1654
+ attrString("operation.name", operationName),
1655
+ attrString("resource.name", resourceName),
1656
+ attrString("ai.telemetry.functionId", state.functionId),
1657
+ ...inputAttrs
1658
+ ]
1659
+ });
1660
+ state.embedSpans.set(event.embedCallId, embedSpan);
1661
+ };
1662
+ // ── onEmbedFinish ───────────────────────────────────────────────────────
1663
+ this.onEmbedFinish = (event) => {
1664
+ var _a;
1665
+ const state = this.getState(event.callId);
1666
+ if (!state) return;
1667
+ const embedSpan = state.embedSpans.get(event.embedCallId);
1668
+ if (!embedSpan) return;
1669
+ const outputAttrs = [];
1670
+ if (state.recordOutputs) {
1671
+ outputAttrs.push(
1672
+ attrString(
1673
+ "ai.embeddings",
1674
+ safeJsonWithUint8(event.embeddings)
1675
+ )
1676
+ );
1677
+ }
1678
+ if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
1679
+ outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
1680
+ }
1681
+ this.traceShipper.endSpan(embedSpan, { attributes: outputAttrs });
1682
+ state.embedSpans.delete(event.embedCallId);
1683
+ };
1684
+ // ── onFinish ────────────────────────────────────────────────────────────
1685
+ this.onFinish = (event) => {
1686
+ const state = this.getState(event.callId);
1687
+ if (!state) return;
1688
+ const isEmbed = state.operationId === "ai.embed" || state.operationId === "ai.embedMany";
1689
+ if (isEmbed) {
1690
+ this.finishEmbed(event, state);
1691
+ } else {
1692
+ this.finishGenerate(event, state);
1693
+ }
1694
+ this.cleanup(event.callId);
1695
+ };
1696
+ // ── onError ─────────────────────────────────────────────────────────────
1697
+ this.onError = (error) => {
1698
+ var _a;
1699
+ const event = error;
1700
+ if (!(event == null ? void 0 : event.callId)) return;
1701
+ const state = this.getState(event.callId);
1702
+ if (!state) return;
1703
+ const actualError = (_a = event.error) != null ? _a : error;
1704
+ if (state.stepSpan) {
1705
+ this.traceShipper.endSpan(state.stepSpan, { error: actualError });
1706
+ }
1707
+ for (const embedSpan of state.embedSpans.values()) {
1708
+ this.traceShipper.endSpan(embedSpan, { error: actualError });
1709
+ }
1710
+ state.embedSpans.clear();
1711
+ for (const toolSpan of state.toolSpans.values()) {
1712
+ this.traceShipper.endSpan(toolSpan, { error: actualError });
1713
+ }
1714
+ state.toolSpans.clear();
1715
+ if (state.rootSpan) {
1716
+ this.traceShipper.endSpan(state.rootSpan, { error: actualError });
1717
+ }
1718
+ this.cleanup(event.callId);
1719
+ };
1720
+ // ── executeTool ─────────────────────────────────────────────────────────
1721
+ this.executeTool = async ({
1722
+ callId,
1723
+ toolCallId,
1724
+ execute
1725
+ }) => {
1726
+ const state = this.getState(callId);
1727
+ const toolSpan = state == null ? void 0 : state.toolSpans.get(toolCallId);
1728
+ if (!toolSpan) return execute();
1729
+ return runWithParentSpanContext(
1730
+ {
1731
+ traceIdB64: toolSpan.ids.traceIdB64,
1732
+ spanIdB64: toolSpan.ids.spanIdB64,
1733
+ eventId: state.eventId
1734
+ },
1735
+ () => execute()
1736
+ );
1737
+ };
1738
+ this.traceShipper = opts.traceShipper;
1739
+ this.eventShipper = opts.eventShipper;
1740
+ this.sendTraces = opts.sendTraces !== false;
1741
+ this.sendEvents = opts.sendEvents !== false;
1742
+ this.debug = opts.debug === true;
1743
+ this.defaultContext = opts.context;
1744
+ }
1745
+ // ── helpers ──────────────────────────────────────────────────────────────
1746
+ getState(callId) {
1747
+ return this.callStates.get(callId);
1748
+ }
1749
+ cleanup(callId) {
1750
+ this.callStates.delete(callId);
1751
+ }
1752
+ spanParentRef(span) {
1753
+ return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
1754
+ }
1755
+ extractRaindropMetadata(metadata) {
1756
+ if (!metadata) return {};
1757
+ const result = {};
1758
+ const userId = metadata["raindrop.userId"];
1759
+ if (typeof userId === "string" && userId) result.userId = userId;
1760
+ const eventId = metadata["raindrop.eventId"];
1761
+ if (typeof eventId === "string" && eventId) result.eventId = eventId;
1762
+ const convoId = metadata["raindrop.convoId"];
1763
+ if (typeof convoId === "string" && convoId) result.convoId = convoId;
1764
+ const eventName = metadata["raindrop.eventName"];
1765
+ if (typeof eventName === "string" && eventName) result.eventName = eventName;
1766
+ const properties = metadata["raindrop.properties"];
1767
+ if (typeof properties === "string") {
1768
+ try {
1769
+ result.properties = JSON.parse(properties);
1770
+ } catch (e) {
1771
+ }
1772
+ } else if (properties && typeof properties === "object") {
1773
+ result.properties = properties;
1774
+ }
1775
+ return result;
1776
+ }
1777
+ /**
1778
+ * Extract the user-facing input text from an onStart event.
1779
+ * Mirrors the logic in the v4-v6 Proxy path (lastUserMessageTextFromArgs / extractInputFromArgs).
1780
+ */
1781
+ extractInputText(event) {
1782
+ if (typeof event.prompt === "string") return event.prompt;
1783
+ if (Array.isArray(event.messages)) {
1784
+ for (let i = event.messages.length - 1; i >= 0; i--) {
1785
+ const msg = event.messages[i];
1786
+ if ((msg == null ? void 0 : msg.role) === "user") {
1787
+ if (typeof msg.content === "string") return msg.content;
1788
+ if (Array.isArray(msg.content)) {
1789
+ const textPart = msg.content.find(
1790
+ (p) => (p == null ? void 0 : p.type) === "text" && typeof p.text === "string"
1791
+ );
1792
+ if (textPart) return textPart.text;
1793
+ }
1794
+ }
1795
+ }
1796
+ }
1797
+ return void 0;
1798
+ }
1799
+ finishGenerate(event, state) {
1800
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1801
+ if (state.rootSpan) {
1802
+ const outputAttrs = [];
1803
+ if (state.recordOutputs) {
1804
+ outputAttrs.push(
1805
+ attrString("ai.response.finishReason", event.finishReason),
1806
+ attrString("ai.response.text", (_a = event.text) != null ? _a : void 0),
1807
+ attrString(
1808
+ "ai.response.providerMetadata",
1809
+ event.providerMetadata ? safeJsonWithUint8(event.providerMetadata) : void 0
1810
+ )
1811
+ );
1812
+ if (((_b = event.toolCalls) == null ? void 0 : _b.length) > 0) {
1813
+ outputAttrs.push(
1814
+ attrString(
1815
+ "ai.response.toolCalls",
1816
+ JSON.stringify(
1817
+ event.toolCalls.map((tc) => ({
1818
+ toolCallId: tc.toolCallId,
1819
+ toolName: tc.toolName,
1820
+ input: tc.input
1821
+ }))
1822
+ )
1823
+ )
1824
+ );
1825
+ }
1826
+ if (((_c = event.reasoning) == null ? void 0 : _c.length) > 0) {
1827
+ const reasoningText = event.reasoning.filter((part) => "text" in part).map((part) => part.text).join("\n");
1828
+ if (reasoningText) {
1829
+ outputAttrs.push(attrString("ai.response.reasoning", reasoningText));
1830
+ }
1831
+ }
1832
+ }
1833
+ const usage = (_d = event.totalUsage) != null ? _d : event.usage;
1834
+ if (usage) {
1835
+ outputAttrs.push(
1836
+ attrInt("ai.usage.inputTokens", usage.inputTokens),
1837
+ attrInt("ai.usage.outputTokens", usage.outputTokens),
1838
+ attrInt("ai.usage.totalTokens", usage.totalTokens),
1839
+ attrInt("ai.usage.reasoningTokens", usage.reasoningTokens),
1840
+ attrInt("ai.usage.cachedInputTokens", usage.cachedInputTokens)
1841
+ );
1842
+ }
1843
+ outputAttrs.push(
1844
+ attrInt("ai.toolCall.count", state.toolCallCount)
1845
+ );
1846
+ this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
1847
+ }
1848
+ if (this.sendEvents) {
1849
+ const callMeta = this.extractRaindropMetadata(state.metadata);
1850
+ const userId = (_f = callMeta.userId) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.userId;
1851
+ if (userId) {
1852
+ const eventName = (_i = (_h = callMeta.eventName) != null ? _h : (_g = this.defaultContext) == null ? void 0 : _g.eventName) != null ? _i : state.operationId;
1853
+ const output = (_j = event.text) != null ? _j : state.accumulatedText || void 0;
1854
+ const input = state.inputText;
1855
+ const model = (_k = event.response) == null ? void 0 : _k.modelId;
1856
+ const properties = {
1857
+ ...(_l = this.defaultContext) == null ? void 0 : _l.properties,
1858
+ ...callMeta.properties
1859
+ };
1860
+ const convoId = (_n = callMeta.convoId) != null ? _n : (_m = this.defaultContext) == null ? void 0 : _m.convoId;
1861
+ void this.eventShipper.patch(state.eventId, {
1862
+ eventName,
1863
+ userId,
1864
+ convoId,
1865
+ input,
1866
+ output,
1867
+ model,
1868
+ properties: Object.keys(properties).length > 0 ? properties : void 0,
1869
+ isPending: false
1870
+ }).catch((err) => {
1871
+ if (this.debug) {
1872
+ console.warn(
1873
+ `[raindrop-ai/ai-sdk] event patch failed: ${err instanceof Error ? err.message : err}`
1874
+ );
1875
+ }
1876
+ });
1877
+ }
1878
+ }
1879
+ }
1880
+ finishEmbed(event, state) {
1881
+ var _a;
1882
+ if (!state.rootSpan) return;
1883
+ const outputAttrs = [];
1884
+ const isMany = state.operationId === "ai.embedMany";
1885
+ if (state.recordOutputs) {
1886
+ if (isMany) {
1887
+ outputAttrs.push(
1888
+ attrString("ai.embeddings", safeJsonWithUint8(event.embedding))
1889
+ );
1890
+ } else {
1891
+ outputAttrs.push(
1892
+ attrString("ai.embedding", safeJsonWithUint8(event.embedding))
1893
+ );
1894
+ }
1895
+ }
1896
+ if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
1897
+ outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
1898
+ }
1899
+ this.traceShipper.endSpan(state.rootSpan, { attributes: outputAttrs });
1900
+ }
1901
+ };
1902
+
1903
+ // src/internal/traces.ts
1904
+ var TraceShipper2 = class extends TraceShipper {
1905
+ constructor(opts) {
1906
+ var _a, _b, _c;
1907
+ super({
1908
+ ...opts,
1909
+ sdkName: (_a = opts.sdkName) != null ? _a : "ai-sdk",
1910
+ serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.ai-sdk",
1911
+ serviceVersion: (_c = opts.serviceVersion) != null ? _c : libraryVersion
1912
+ });
1913
+ }
1914
+ };
1915
+
1386
1916
  // src/internal/wrap/wrapAISDK.ts
1387
1917
  var AGENT_REPORTING_TOOL_NAME_DEFAULT = "__raindrop_report";
1388
1918
  var AGENT_REPORTING_SIGNALS_DEFAULT = {
@@ -1592,6 +2122,9 @@ function detectAISDKVersion(aiSDK) {
1592
2122
  if (isFunction(aiSDK["tool"])) return "5";
1593
2123
  return "4";
1594
2124
  }
2125
+ function hasStructuredTelemetryEvents(aiSDK) {
2126
+ return isRecord(aiSDK) && isFunction(aiSDK["registerTelemetryIntegration"]) && isFunction(aiSDK["experimental_streamModelCall"]);
2127
+ }
1595
2128
  function asVercelSchema(jsonSchemaObj) {
1596
2129
  const validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
1597
2130
  const schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
@@ -2174,8 +2707,99 @@ async function executeNonStreamingOperation(params) {
2174
2707
  }
2175
2708
  }
2176
2709
  function wrapAISDK(aiSDK, deps) {
2177
- var _a, _b;
2710
+ var _a, _b, _c, _d;
2178
2711
  const debug = deps.eventShipper.isDebugEnabled() || deps.traceShipper.isDebugEnabled();
2712
+ if (deps.options.nativeTelemetry === true) {
2713
+ if (!hasStructuredTelemetryEvents(aiSDK)) {
2714
+ throw new Error(
2715
+ "[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."
2716
+ );
2717
+ }
2718
+ }
2719
+ const useNative = deps.options.nativeTelemetry === true;
2720
+ if (useNative) {
2721
+ const wrapTimeCtx = resolveContext(deps.options.context, { operation: "wrap", args: void 0 });
2722
+ const integration = new RaindropTelemetryIntegration({
2723
+ traceShipper: deps.traceShipper,
2724
+ eventShipper: deps.eventShipper,
2725
+ sendTraces: ((_a = deps.options.send) == null ? void 0 : _a.traces) !== false,
2726
+ sendEvents: ((_b = deps.options.send) == null ? void 0 : _b.events) !== false,
2727
+ debug,
2728
+ context: {
2729
+ userId: wrapTimeCtx.userId,
2730
+ eventId: wrapTimeCtx.eventId,
2731
+ eventName: wrapTimeCtx.eventName,
2732
+ convoId: wrapTimeCtx.convoId,
2733
+ properties: wrapTimeCtx.properties
2734
+ }
2735
+ });
2736
+ const registerFn = aiSDK["registerTelemetryIntegration"];
2737
+ if (isFunction(registerFn)) {
2738
+ registerFn(integration);
2739
+ }
2740
+ if (debug) {
2741
+ console.log("[raindrop-ai/ai-sdk] nativeTelemetry: registered RaindropTelemetryIntegration (no Proxy)");
2742
+ }
2743
+ const selfDiagnostics2 = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
2744
+ if (selfDiagnostics2) {
2745
+ const textOps = /* @__PURE__ */ new Set(["generateText", "streamText"]);
2746
+ const jsonSchemaFactory = resolveJsonSchemaFactory(aiSDK);
2747
+ const proxyTarget2 = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
2748
+ return new Proxy(proxyTarget2, {
2749
+ get(target, prop, receiver) {
2750
+ const original = Reflect.get(target, prop, receiver);
2751
+ if (typeof prop !== "string" || !textOps.has(prop) || !isFunction(original)) {
2752
+ return original;
2753
+ }
2754
+ return (...callArgs) => {
2755
+ var _a2;
2756
+ const arg = callArgs[0];
2757
+ if (!isRecord(arg)) return original.call(aiSDK, ...callArgs);
2758
+ const telemetry = extractExperimentalTelemetry(arg);
2759
+ const callMeta = (telemetry == null ? void 0 : telemetry.metadata) ? extractRaindropMetadata(telemetry.metadata) : {};
2760
+ const perCallEventIdExplicit = (_a2 = callMeta.eventId) != null ? _a2 : wrapTimeCtx.eventId;
2761
+ const perCallEventId = perCallEventIdExplicit != null ? perCallEventIdExplicit : randomUUID();
2762
+ const perCallEventIdGenerated = !perCallEventIdExplicit;
2763
+ const perCallCtx = {
2764
+ eventId: perCallEventId,
2765
+ telemetry,
2766
+ sendTraces: false,
2767
+ debug,
2768
+ eventShipper: deps.eventShipper,
2769
+ traceShipper: deps.traceShipper,
2770
+ rootParentForChildren: void 0,
2771
+ jsonSchemaFactory,
2772
+ selfDiagnostics: selfDiagnostics2,
2773
+ aiSDKVersion: "7"
2774
+ };
2775
+ const tools = isRecord(arg["tools"]) ? { ...arg["tools"] } : {};
2776
+ const toolName = selfDiagnostics2.toolName;
2777
+ if (!(toolName in tools)) {
2778
+ const reportTool = createSelfDiagnosticsTool(perCallCtx);
2779
+ if (reportTool) tools[toolName] = reportTool;
2780
+ }
2781
+ const existingTelemetry = isRecord(arg["experimental_telemetry"]) ? arg["experimental_telemetry"] : {};
2782
+ const existingMetadata = isRecord(existingTelemetry["metadata"]) ? existingTelemetry["metadata"] : {};
2783
+ const mergedMetadata = existingMetadata["raindrop.eventId"] ? existingMetadata : {
2784
+ ...existingMetadata,
2785
+ "raindrop.eventId": perCallEventId,
2786
+ ...perCallEventIdGenerated ? { "raindrop.internal.eventIdGenerated": "true" } : {}
2787
+ };
2788
+ callArgs[0] = {
2789
+ ...arg,
2790
+ tools,
2791
+ experimental_telemetry: {
2792
+ ...existingTelemetry,
2793
+ metadata: mergedMetadata
2794
+ }
2795
+ };
2796
+ return original.call(aiSDK, ...callArgs);
2797
+ };
2798
+ }
2799
+ });
2800
+ }
2801
+ return aiSDK;
2802
+ }
2179
2803
  const instrumentedOps = /* @__PURE__ */ new Set([
2180
2804
  "generateText",
2181
2805
  "streamText",
@@ -2183,8 +2807,8 @@ function wrapAISDK(aiSDK, deps) {
2183
2807
  "streamObject"
2184
2808
  ]);
2185
2809
  const agentClasses = /* @__PURE__ */ new Set(["Agent", "Experimental_Agent", "ToolLoopAgent"]);
2186
- const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
2187
- const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
2810
+ const sendEvents = ((_c = deps.options.send) == null ? void 0 : _c.events) !== false;
2811
+ const sendTraces = ((_d = deps.options.send) == null ? void 0 : _d.traces) !== false;
2188
2812
  const autoAttachmentEnabled = deps.options.autoAttachment !== false;
2189
2813
  const selfDiagnostics = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
2190
2814
  const proxyTarget = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
@@ -3278,6 +3902,16 @@ function createRaindropAISDK(opts) {
3278
3902
  traceShipper
3279
3903
  });
3280
3904
  },
3905
+ createTelemetryIntegration(context) {
3906
+ return new RaindropTelemetryIntegration({
3907
+ traceShipper,
3908
+ eventShipper,
3909
+ sendTraces: tracesEnabled,
3910
+ sendEvents: eventsEnabled,
3911
+ debug: envDebug,
3912
+ context
3913
+ });
3914
+ },
3281
3915
  events: {
3282
3916
  async patch(eventId, patch) {
3283
3917
  await eventShipper.patch(eventId, patch);
@@ -3311,4 +3945,4 @@ function createRaindropAISDK(opts) {
3311
3945
  };
3312
3946
  }
3313
3947
 
3314
- export { _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, eventMetadataFromChatRequest, getContextManager, withCurrent };
3948
+ export { RaindropTelemetryIntegration, _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, eventMetadataFromChatRequest, getContextManager, withCurrent };