@raindrop-ai/ai-sdk 0.0.25 → 0.0.27

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/README.md CHANGED
@@ -117,7 +117,7 @@ await raindrop.flush();
117
117
 
118
118
  ### AI SDK v7+ native telemetry (opt-in)
119
119
 
120
- On AI SDK v7+, you can use the native `TelemetryIntegration` callback interface instead of Proxy wrapping. This avoids Proxy overhead and works with all AI SDK entry points (including `ToolLoopAgent`).
120
+ On AI SDK v7+, you can use the native `Telemetry` callback interface (formerly `TelemetryIntegration` before beta.111) instead of Proxy wrapping. This avoids Proxy overhead and works with all AI SDK entry points (including `ToolLoopAgent`).
121
121
 
122
122
  ```ts
123
123
  // Option A: wrap() with nativeTelemetry flag
@@ -127,15 +127,41 @@ const { generateText } = raindrop.wrap(ai, {
127
127
  });
128
128
 
129
129
  // Option B: direct registration (no wrap needed)
130
- import { registerTelemetryIntegration } from "ai";
130
+ // - registerTelemetry on AI SDK v7 beta.111+
131
+ // - registerTelemetryIntegration on older v7 betas
132
+ import { registerTelemetry } from "ai";
131
133
 
132
- registerTelemetryIntegration(
134
+ registerTelemetry(
133
135
  raindrop.createTelemetryIntegration({ userId: "user_123" })
134
136
  );
135
137
  ```
136
138
 
137
139
  Setting `nativeTelemetry: true` on pre-v7 throws a clear error. The Proxy path remains the default and supports features not yet available on the native path (`buildEvent`, output attachment extraction).
138
140
 
141
+ #### Per-call routing on AI SDK v7 beta.94+
142
+
143
+ `eventMetadata()` keeps working on every published v7 beta:
144
+
145
+ ```ts
146
+ const result = await generateText({
147
+ model,
148
+ prompt,
149
+ experimental_telemetry: {
150
+ isEnabled: true,
151
+ metadata: eventMetadata({
152
+ userId: "u_42",
153
+ eventName: "chat-turn",
154
+ eventId: "evt_abc",
155
+ convoId: "conv_xyz",
156
+ }),
157
+ },
158
+ });
159
+ ```
160
+
161
+ AI SDK v7 beta.94 (vercel/ai #14503) removed the `metadata` field from `TelemetryOptions`, and integration callbacks no longer receive it via `event.metadata`. Going through `wrap({ nativeTelemetry: true })` still routes per-call `userId` / `eventName` / `eventId` / `convoId` / `properties` correctly: the wrapper extracts them from the call's `experimental_telemetry.metadata` (or `telemetry.metadata`) before delegating, and exposes them to the integration via an `AsyncLocalStorage` slot.
162
+
163
+ If you are bypassing `wrap()` and registering an integration manually, use the helpers exported from this package (`runWithRaindropCallMetadata`, `readRaindropCallMetadataFromArgs`, `getCurrentRaindropCallMetadata`) to plumb per-call metadata through your own call sites.
164
+
139
165
  If `userId` is missing from both `wrap()` context and `eventMetadata()`, the SDK logs a warning (once) and skips sending events.
140
166
 
141
167
  ## Runtime support
@@ -188,7 +214,7 @@ This package is tested against multiple Vercel AI SDK versions:
188
214
  | v4.x | ✅ Supported | Proxy |
189
215
  | v5.x | ✅ Supported | Proxy |
190
216
  | v6.x | ✅ Supported | Proxy |
191
- | v7.x (beta) | ✅ Supported | Proxy (default) or native `TelemetryIntegration` (opt-in) |
217
+ | v7.x (beta) | ✅ Supported | Proxy (default) or native `Telemetry` (opt-in, formerly `TelemetryIntegration` pre-beta.111). Verified against beta.116. |
192
218
 
193
219
  ### Version Differences Handled
194
220
 
@@ -1,6 +1,6 @@
1
1
  import { AsyncLocalStorage } from 'async_hooks';
2
2
 
3
- // ../core/dist/chunk-4UCYIEH4.js
3
+ // ../core/dist/chunk-LMIWKHOH.js
4
4
  function getCrypto() {
5
5
  const c = globalThis.crypto;
6
6
  return c;
@@ -470,29 +470,70 @@ var EventShipper = class {
470
470
  }
471
471
  };
472
472
  var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
473
+ var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
474
+ var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
475
+ function readEnvVar(name) {
476
+ var _a;
477
+ try {
478
+ const env = (_a = globalThis == null ? void 0 : globalThis.process) == null ? void 0 : _a.env;
479
+ if (env && typeof env[name] === "string" && env[name].length > 0) {
480
+ return env[name];
481
+ }
482
+ } catch (e) {
483
+ }
484
+ return void 0;
485
+ }
486
+ function readWorkshopEnv() {
487
+ const raw = readEnvVar(WORKSHOP_ENV_VAR);
488
+ if (raw === void 0) return void 0;
489
+ const trimmed = raw.trim();
490
+ if (trimmed.length === 0) return void 0;
491
+ if (/^https?:\/\//i.test(trimmed)) return { url: trimmed };
492
+ if (/^(1|true|yes|on)$/i.test(trimmed)) return "enable";
493
+ if (/^(0|false|no|off)$/i.test(trimmed)) return "disable";
494
+ return void 0;
495
+ }
496
+ function isLocalDevHost(hostname) {
497
+ if (!hostname) return false;
498
+ if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "0.0.0.0" || hostname === "::1") {
499
+ return true;
500
+ }
501
+ if (hostname.endsWith(".localhost")) return true;
502
+ return false;
503
+ }
504
+ function readRuntimeHostname() {
505
+ try {
506
+ const loc = globalThis == null ? void 0 : globalThis.location;
507
+ if (loc && typeof loc.hostname === "string" && loc.hostname.length > 0) {
508
+ return loc.hostname;
509
+ }
510
+ } catch (e) {
511
+ }
512
+ return void 0;
513
+ }
514
+ function shouldAutoEnableLocalWorkshop() {
515
+ if (isLocalDevHost(readRuntimeHostname())) return true;
516
+ if (readEnvVar("NODE_ENV") === "development") return true;
517
+ return false;
518
+ }
473
519
  function resolveLocalDebuggerBaseUrl(baseUrl) {
474
520
  var _a, _b, _c;
475
- const resolved = (_b = baseUrl != null ? baseUrl : typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a[LOCAL_DEBUGGER_ENV_VAR] : void 0) != null ? _b : null;
476
- return resolved ? (_c = formatEndpoint(resolved)) != null ? _c : null : null;
521
+ if (baseUrl === null) return null;
522
+ if (typeof baseUrl === "string" && baseUrl.length > 0) {
523
+ return (_a = formatEndpoint(baseUrl)) != null ? _a : null;
524
+ }
525
+ const explicitUrlEnv = readEnvVar(LOCAL_DEBUGGER_ENV_VAR);
526
+ if (explicitUrlEnv) return (_b = formatEndpoint(explicitUrlEnv)) != null ? _b : null;
527
+ const workshopEnv = readWorkshopEnv();
528
+ if (workshopEnv === "disable") return null;
529
+ if (workshopEnv === "enable") return DEFAULT_LOCAL_WORKSHOP_URL;
530
+ if (workshopEnv && "url" in workshopEnv) return (_c = formatEndpoint(workshopEnv.url)) != null ? _c : null;
531
+ if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
532
+ return null;
477
533
  }
478
534
  function localDebuggerEnabled(baseUrl) {
479
535
  return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
480
536
  }
481
- function normalizeLocalDebuggerLiveEventType(type) {
482
- switch (type) {
483
- case "text-delta":
484
- return "text_delta";
485
- case "reasoning":
486
- case "reasoning-delta":
487
- return "reasoning_delta";
488
- case "tool-call":
489
- return "tool_start";
490
- case "tool-result":
491
- return "tool_result";
492
- default:
493
- return type;
494
- }
495
- }
496
537
  function mirrorTraceExportToLocalDebugger(body, options = {}) {
497
538
  var _a;
498
539
  const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
@@ -512,7 +553,7 @@ function sendLocalDebuggerLiveEvent(event, options = {}) {
512
553
  `${baseUrl}live`,
513
554
  {
514
555
  ...event,
515
- type: normalizeLocalDebuggerLiveEventType(event.type),
556
+ type: event.type,
516
557
  timestamp: (_a = event.timestamp) != null ? _a : Date.now()
517
558
  },
518
559
  {},
@@ -528,7 +569,7 @@ var TraceShipper = class {
528
569
  constructor(opts) {
529
570
  this.queue = [];
530
571
  this.inFlight = /* @__PURE__ */ new Set();
531
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
572
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
532
573
  this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
533
574
  this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
534
575
  this.enabled = opts.enabled !== false;
@@ -541,12 +582,9 @@ var TraceShipper = class {
541
582
  this.prefix = `[raindrop-ai/${this.sdkName}]`;
542
583
  this.serviceName = (_g = opts.serviceName) != null ? _g : "raindrop.core";
543
584
  this.serviceVersion = (_h = opts.serviceVersion) != null ? _h : "0.0.0";
544
- const localDebugger = typeof process !== "undefined" ? (_i = process.env) == null ? void 0 : _i.RAINDROP_LOCAL_DEBUGGER : void 0;
545
- if (localDebugger) {
546
- this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(localDebugger)) != null ? _j : void 0;
547
- if (this.debug) {
548
- console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
549
- }
585
+ this.localDebuggerUrl = (_i = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _i : void 0;
586
+ if (this.debug && this.localDebuggerUrl) {
587
+ console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
550
588
  }
551
589
  }
552
590
  isDebugEnabled() {
@@ -1451,6 +1489,77 @@ function attrsFromGenAiRequest(options) {
1451
1489
  ];
1452
1490
  }
1453
1491
 
1492
+ // src/internal/call-metadata.ts
1493
+ var SyncFallbackStorage = class {
1494
+ constructor() {
1495
+ this._stack = [];
1496
+ }
1497
+ getStore() {
1498
+ return this._stack[this._stack.length - 1];
1499
+ }
1500
+ run(store, callback) {
1501
+ this._stack.push(store);
1502
+ try {
1503
+ return callback();
1504
+ } finally {
1505
+ this._stack.pop();
1506
+ }
1507
+ }
1508
+ };
1509
+ var _storage = null;
1510
+ function getStorage() {
1511
+ if (_storage) return _storage;
1512
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
1513
+ _storage = Ctor ? new Ctor() : new SyncFallbackStorage();
1514
+ return _storage;
1515
+ }
1516
+ function _resetRaindropCallMetadataStorage() {
1517
+ _storage = null;
1518
+ }
1519
+ function getCurrentRaindropCallMetadata() {
1520
+ return getStorage().getStore();
1521
+ }
1522
+ function runWithRaindropCallMetadata(metadata, fn) {
1523
+ return getStorage().run(metadata, fn);
1524
+ }
1525
+ function readRaindropCallMetadataFromArgs(args) {
1526
+ var _a;
1527
+ if (args.length === 0) return void 0;
1528
+ const first = args[0];
1529
+ if (!isRecord(first)) return void 0;
1530
+ const topLevel = isRecord(first["metadata"]) ? first["metadata"] : void 0;
1531
+ const stable = isRecord(first["telemetry"]) ? first["telemetry"]["metadata"] : void 0;
1532
+ const stableMetadata = isRecord(stable) ? stable : void 0;
1533
+ const exp = extractExperimentalTelemetry(first);
1534
+ const expMetadata = (exp == null ? void 0 : exp.metadata) && typeof exp.metadata === "object" ? exp.metadata : void 0;
1535
+ const raw = (_a = topLevel != null ? topLevel : stableMetadata) != null ? _a : expMetadata;
1536
+ if (!raw) return void 0;
1537
+ const meta = { rawMetadata: raw };
1538
+ const userId = raw["raindrop.userId"];
1539
+ if (typeof userId === "string" && userId) meta.userId = userId;
1540
+ const eventId = raw["raindrop.eventId"];
1541
+ if (typeof eventId === "string" && eventId) meta.eventId = eventId;
1542
+ const eventIdGenerated = raw["raindrop.internal.eventIdGenerated"];
1543
+ if (eventIdGenerated === true || eventIdGenerated === "true" || eventIdGenerated === "1") {
1544
+ meta.eventIdGenerated = true;
1545
+ }
1546
+ const convoId = raw["raindrop.convoId"];
1547
+ if (typeof convoId === "string" && convoId) meta.convoId = convoId;
1548
+ const eventName = raw["raindrop.eventName"];
1549
+ if (typeof eventName === "string" && eventName) meta.eventName = eventName;
1550
+ const properties = raw["raindrop.properties"];
1551
+ if (typeof properties === "string") {
1552
+ try {
1553
+ const parsed = JSON.parse(properties);
1554
+ if (parsed && typeof parsed === "object") meta.properties = parsed;
1555
+ } catch (e) {
1556
+ }
1557
+ } else if (properties && typeof properties === "object") {
1558
+ meta.properties = properties;
1559
+ }
1560
+ return meta;
1561
+ }
1562
+
1454
1563
  // src/internal/raindrop-telemetry-integration.ts
1455
1564
  var RaindropTelemetryIntegration = class {
1456
1565
  constructor(opts) {
@@ -1458,15 +1567,17 @@ var RaindropTelemetryIntegration = class {
1458
1567
  // ── onStart ─────────────────────────────────────────────────────────────
1459
1568
  this.onStart = (event) => {
1460
1569
  var _a, _b, _c, _d;
1461
- if (event.isEnabled !== true) return;
1570
+ if (event.isEnabled === false) return;
1462
1571
  const isEmbed = event.operationId === "ai.embed" || event.operationId === "ai.embedMany";
1463
1572
  const recordInputs = event.recordInputs !== false;
1464
1573
  const recordOutputs = event.recordOutputs !== false;
1465
1574
  const functionId = event.functionId;
1466
- const metadata = event.metadata;
1575
+ const eventMetadata2 = event.metadata;
1576
+ const callContextMetadata = getCurrentRaindropCallMetadata();
1577
+ const metadata = eventMetadata2 != null ? eventMetadata2 : callContextMetadata == null ? void 0 : callContextMetadata.rawMetadata;
1467
1578
  const callMeta = this.extractRaindropMetadata(metadata);
1468
1579
  const inherited = getContextManager().getParentSpanIds();
1469
- const eventIdGenerated = (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === "true" || (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === true;
1580
+ const eventIdGenerated = (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === "true" || (metadata == null ? void 0 : metadata["raindrop.internal.eventIdGenerated"]) === true || (callContextMetadata == null ? void 0 : callContextMetadata.eventIdGenerated) === true;
1470
1581
  const explicitEventId = callMeta.eventId && !eventIdGenerated ? callMeta.eventId : void 0;
1471
1582
  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();
1472
1583
  const inheritedParent = inherited && inherited.eventId === eventId ? { traceIdB64: inherited.traceIdB64, spanIdB64: inherited.spanIdB64 } : void 0;
@@ -1592,48 +1703,25 @@ var RaindropTelemetryIntegration = class {
1592
1703
  state.stepSpan = stepSpan;
1593
1704
  state.stepParent = this.spanParentRef(stepSpan);
1594
1705
  };
1595
- // ── onToolCallStart ─────────────────────────────────────────────────────
1596
- this.onToolCallStart = (event) => {
1597
- const state = this.getState(event.callId);
1598
- if (!(state == null ? void 0 : state.stepParent)) return;
1599
- const { toolCall } = event;
1600
- const { operationName, resourceName } = opName(
1601
- "ai.toolCall",
1602
- state.functionId
1603
- );
1604
- const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
1605
- const toolSpan = this.traceShipper.startSpan({
1606
- name: "ai.toolCall",
1607
- parent: state.stepParent,
1608
- eventId: state.eventId,
1609
- operationId: "ai.toolCall",
1610
- attributes: [
1611
- attrString("operation.name", operationName),
1612
- attrString("resource.name", resourceName),
1613
- attrString("ai.telemetry.functionId", state.functionId),
1614
- attrString("ai.toolCall.name", toolCall.toolName),
1615
- attrString("ai.toolCall.id", toolCall.toolCallId),
1616
- ...inputAttrs
1617
- ]
1618
- });
1619
- state.toolSpans.set(toolCall.toolCallId, toolSpan);
1620
- this.emitLive(state, "tool_start", toolCall.toolName, { args: toolCall.input });
1706
+ this.onToolExecutionStart = (event) => this.toolExecutionStart(event);
1707
+ this.onToolExecutionEnd = (event) => this.toolExecutionEnd(event);
1708
+ // Older v7 betas (< beta.111) emit these names. Kept as thin aliases so
1709
+ // applications pinned to those betas continue to work.
1710
+ this.onToolCallStart = (event) => this.toolExecutionStart(event);
1711
+ this.onToolCallFinish = (event) => this.toolExecutionEnd(event);
1712
+ // ── language-model call (v7 beta.111+) ─────────────────────────────────
1713
+ //
1714
+ // `onLanguageModelCallStart` / `onLanguageModelCallEnd` are scoped to the
1715
+ // model invocation only and exclude later client-side tool execution.
1716
+ // Raindrop already spans at the operation + step level, so these are
1717
+ // intentional no-ops — declared so the dispatcher's `mergeCallbacks` sees
1718
+ // them and so we don't accidentally rely on them later.
1719
+ //
1720
+ // Defined as no-ops rather than omitted so adding logic here later is a
1721
+ // strictly additive change.
1722
+ this.onLanguageModelCallStart = (_event) => {
1621
1723
  };
1622
- // ── onToolCallFinish ────────────────────────────────────────────────────
1623
- this.onToolCallFinish = (event) => {
1624
- const state = this.getState(event.callId);
1625
- if (!state) return;
1626
- const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
1627
- if (!toolSpan) return;
1628
- state.toolCallCount += 1;
1629
- if (event.success) {
1630
- const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(event.output))] : [];
1631
- this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
1632
- } else {
1633
- this.traceShipper.endSpan(toolSpan, { error: event.error });
1634
- }
1635
- this.emitLive(state, "tool_result", event.toolCall.toolName);
1636
- state.toolSpans.delete(event.toolCall.toolCallId);
1724
+ this.onLanguageModelCallEnd = (_event) => {
1637
1725
  };
1638
1726
  // ── onChunk (streaming) ─────────────────────────────────────────────────
1639
1727
  this.onChunk = (event) => {
@@ -1902,6 +1990,53 @@ var RaindropTelemetryIntegration = class {
1902
1990
  }
1903
1991
  return void 0;
1904
1992
  }
1993
+ // ── tool execution start / end ──────────────────────────────────────────
1994
+ //
1995
+ // v7 < beta.111 dispatched `onToolCallStart` / `onToolCallFinish`.
1996
+ // v7 >= beta.111 renamed them to `onToolExecutionStart` / `onToolExecutionEnd`
1997
+ // (see https://github.com/vercel/ai/pull/14589). Event shape is identical.
1998
+ // Both names are exposed and forward to a single implementation.
1999
+ toolExecutionStart(event) {
2000
+ const state = this.getState(event.callId);
2001
+ if (!(state == null ? void 0 : state.stepParent)) return;
2002
+ const { toolCall } = event;
2003
+ const { operationName, resourceName } = opName(
2004
+ "ai.toolCall",
2005
+ state.functionId
2006
+ );
2007
+ const inputAttrs = state.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
2008
+ const toolSpan = this.traceShipper.startSpan({
2009
+ name: "ai.toolCall",
2010
+ parent: state.stepParent,
2011
+ eventId: state.eventId,
2012
+ operationId: "ai.toolCall",
2013
+ attributes: [
2014
+ attrString("operation.name", operationName),
2015
+ attrString("resource.name", resourceName),
2016
+ attrString("ai.telemetry.functionId", state.functionId),
2017
+ attrString("ai.toolCall.name", toolCall.toolName),
2018
+ attrString("ai.toolCall.id", toolCall.toolCallId),
2019
+ ...inputAttrs
2020
+ ]
2021
+ });
2022
+ state.toolSpans.set(toolCall.toolCallId, toolSpan);
2023
+ this.emitLive(state, "tool_start", toolCall.toolName, { args: toolCall.input });
2024
+ }
2025
+ toolExecutionEnd(event) {
2026
+ const state = this.getState(event.callId);
2027
+ if (!state) return;
2028
+ const toolSpan = state.toolSpans.get(event.toolCall.toolCallId);
2029
+ if (!toolSpan) return;
2030
+ state.toolCallCount += 1;
2031
+ if (event.success) {
2032
+ const outputAttrs = state.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(event.output))] : [];
2033
+ this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
2034
+ } else {
2035
+ this.traceShipper.endSpan(toolSpan, { error: event.error });
2036
+ }
2037
+ this.emitLive(state, "tool_result", event.toolCall.toolName);
2038
+ state.toolSpans.delete(event.toolCall.toolCallId);
2039
+ }
1905
2040
  finishGenerate(event, state) {
1906
2041
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1907
2042
  if (state.rootSpan) {
@@ -2216,7 +2351,16 @@ function detectAISDKVersion(aiSDK) {
2216
2351
  return "4";
2217
2352
  }
2218
2353
  function hasStructuredTelemetryEvents(aiSDK) {
2219
- return isRecord(aiSDK) && isFunction(aiSDK["registerTelemetryIntegration"]) && isFunction(aiSDK["experimental_streamModelCall"]);
2354
+ if (!isRecord(aiSDK)) return false;
2355
+ const hasRegister = isFunction(aiSDK["registerTelemetry"]) || isFunction(aiSDK["registerTelemetryIntegration"]);
2356
+ const hasV7Marker = isFunction(aiSDK["experimental_streamLanguageModelCall"]) || isFunction(aiSDK["experimental_streamModelCall"]);
2357
+ return hasRegister && hasV7Marker;
2358
+ }
2359
+ function resolveRegisterTelemetry(aiSDK) {
2360
+ var _a;
2361
+ if (!isRecord(aiSDK)) return void 0;
2362
+ const fn = (_a = aiSDK["registerTelemetry"]) != null ? _a : aiSDK["registerTelemetryIntegration"];
2363
+ return isFunction(fn) ? fn : void 0;
2220
2364
  }
2221
2365
  function asVercelSchema(jsonSchemaObj) {
2222
2366
  const validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
@@ -2857,31 +3001,44 @@ function wrapAISDK(aiSDK, deps) {
2857
3001
  properties: wrapTimeCtx.properties
2858
3002
  }
2859
3003
  });
2860
- const registerFn = aiSDK["registerTelemetryIntegration"];
2861
- if (isFunction(registerFn)) {
3004
+ const registerFn = resolveRegisterTelemetry(aiSDK);
3005
+ if (registerFn) {
2862
3006
  registerFn(integration);
2863
3007
  }
2864
3008
  if (debug) {
2865
- console.log("[raindrop-ai/ai-sdk] nativeTelemetry: registered RaindropTelemetryIntegration (no Proxy)");
3009
+ console.log(
3010
+ "[raindrop-ai/ai-sdk] nativeTelemetry: registered RaindropTelemetryIntegration (Proxy installed for per-call metadata propagation)"
3011
+ );
2866
3012
  }
2867
3013
  const selfDiagnostics2 = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
2868
- if (selfDiagnostics2) {
2869
- const textOps = /* @__PURE__ */ new Set(["generateText", "streamText"]);
2870
- const jsonSchemaFactory = resolveJsonSchemaFactory(aiSDK);
2871
- const proxyTarget2 = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
2872
- return new Proxy(proxyTarget2, {
2873
- get(target, prop, receiver) {
2874
- const original = Reflect.get(target, prop, receiver);
2875
- if (typeof prop !== "string" || !textOps.has(prop) || !isFunction(original)) {
2876
- return original;
2877
- }
2878
- return (...callArgs) => {
2879
- var _a2;
2880
- const arg = callArgs[0];
2881
- if (!isRecord(arg)) return original.call(aiSDK, ...callArgs);
3014
+ const jsonSchemaFactory = selfDiagnostics2 ? resolveJsonSchemaFactory(aiSDK) : void 0;
3015
+ const metadataAwareOps = /* @__PURE__ */ new Set([
3016
+ "generateText",
3017
+ "streamText",
3018
+ "generateObject",
3019
+ "streamObject",
3020
+ "embed",
3021
+ "embedMany",
3022
+ "rerank"
3023
+ ]);
3024
+ const selfDiagnosticsOps = /* @__PURE__ */ new Set(["generateText", "streamText"]);
3025
+ const proxyTarget2 = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
3026
+ return new Proxy(proxyTarget2, {
3027
+ get(target, prop, receiver) {
3028
+ const original = Reflect.get(target, prop, receiver);
3029
+ if (typeof prop !== "string" || !metadataAwareOps.has(prop) || !isFunction(original)) {
3030
+ return original;
3031
+ }
3032
+ const propName = prop;
3033
+ return (...callArgs) => {
3034
+ var _a2, _b2, _c2;
3035
+ const arg = callArgs[0];
3036
+ const callMetadata = readRaindropCallMetadataFromArgs(callArgs);
3037
+ const callOriginal = () => original.call(aiSDK, ...callArgs);
3038
+ if (selfDiagnostics2 && selfDiagnosticsOps.has(propName) && isRecord(arg)) {
2882
3039
  const telemetry = extractExperimentalTelemetry(arg);
2883
3040
  const callMeta = (telemetry == null ? void 0 : telemetry.metadata) ? extractRaindropMetadata(telemetry.metadata) : {};
2884
- const perCallEventIdExplicit = (_a2 = callMeta.eventId) != null ? _a2 : wrapTimeCtx.eventId;
3041
+ const perCallEventIdExplicit = (_b2 = (_a2 = callMetadata == null ? void 0 : callMetadata.eventId) != null ? _a2 : callMeta.eventId) != null ? _b2 : wrapTimeCtx.eventId;
2885
3042
  const perCallEventId = perCallEventIdExplicit != null ? perCallEventIdExplicit : randomUUID();
2886
3043
  const perCallEventIdGenerated = !perCallEventIdExplicit;
2887
3044
  const perCallCtx = {
@@ -2918,12 +3075,25 @@ function wrapAISDK(aiSDK, deps) {
2918
3075
  metadata: mergedMetadata
2919
3076
  }
2920
3077
  };
2921
- return original.call(aiSDK, ...callArgs);
2922
- };
2923
- }
2924
- });
2925
- }
2926
- return aiSDK;
3078
+ const mergedAlsMetadata = {
3079
+ ...callMetadata != null ? callMetadata : {},
3080
+ eventId: perCallEventId,
3081
+ eventIdGenerated: perCallEventIdGenerated || (callMetadata == null ? void 0 : callMetadata.eventIdGenerated),
3082
+ rawMetadata: {
3083
+ ...(_c2 = callMetadata == null ? void 0 : callMetadata.rawMetadata) != null ? _c2 : {},
3084
+ "raindrop.eventId": perCallEventId,
3085
+ ...perCallEventIdGenerated ? { "raindrop.internal.eventIdGenerated": "true" } : {}
3086
+ }
3087
+ };
3088
+ return runWithRaindropCallMetadata(mergedAlsMetadata, callOriginal);
3089
+ }
3090
+ if (callMetadata) {
3091
+ return runWithRaindropCallMetadata(callMetadata, callOriginal);
3092
+ }
3093
+ return callOriginal();
3094
+ };
3095
+ }
3096
+ });
2927
3097
  }
2928
3098
  const instrumentedOps = /* @__PURE__ */ new Set([
2929
3099
  "generateText",
@@ -4007,7 +4177,7 @@ function extractNestedTokens(usage, key) {
4007
4177
  // package.json
4008
4178
  var package_default = {
4009
4179
  name: "@raindrop-ai/ai-sdk",
4010
- version: "0.0.25"};
4180
+ version: "0.0.27"};
4011
4181
 
4012
4182
  // src/internal/version.ts
4013
4183
  var libraryName = package_default.name;
@@ -4113,6 +4283,7 @@ function createRaindropAISDK(opts) {
4113
4283
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
4114
4284
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs
4115
4285
  });
4286
+ const localDebuggerUrl = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
4116
4287
  const traceShipper = new TraceShipper2({
4117
4288
  writeKey,
4118
4289
  endpoint: opts.endpoint,
@@ -4121,7 +4292,8 @@ function createRaindropAISDK(opts) {
4121
4292
  debugSpans: ((_f = opts.traces) == null ? void 0 : _f.debugSpans) === true || envDebug,
4122
4293
  flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
4123
4294
  maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
4124
- maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize
4295
+ maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
4296
+ localDebuggerUrl
4125
4297
  });
4126
4298
  return {
4127
4299
  wrap(aiSDK, options) {
@@ -4244,4 +4416,4 @@ function createRaindropAISDK(opts) {
4244
4416
  };
4245
4417
  }
4246
4418
 
4247
- export { RaindropTelemetryIntegration, _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, eventMetadataFromChatRequest, getContextManager, withCurrent };
4419
+ export { RaindropTelemetryIntegration, _resetRaindropCallMetadataStorage, _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, eventMetadataFromChatRequest, getContextManager, getCurrentRaindropCallMetadata, readRaindropCallMetadataFromArgs, runWithRaindropCallMetadata, withCurrent };