@raindrop-ai/ai-sdk 0.0.8 → 0.0.10

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.d.ts CHANGED
@@ -127,6 +127,48 @@ type EventMetadataOptions = {
127
127
  * ```
128
128
  */
129
129
  declare function eventMetadata(options: EventMetadataOptions): Record<string, string>;
130
+ type AgentCallMetadata = ReturnType<typeof eventMetadata>;
131
+ type NormalizeUnknownAgentOptions<T> = T extends {
132
+ options: infer CallOptions;
133
+ } ? unknown extends CallOptions ? Omit<T, "options"> & {
134
+ options?: never;
135
+ } : T : T;
136
+ /**
137
+ * Wraps an agent instance type so `generate()` and `stream()` accept optional
138
+ * Raindrop call metadata while preserving original return types.
139
+ */
140
+ type AgentWithMetadata<A> = A extends {
141
+ generate: (...args: infer GenerateArgs) => infer GenerateReturn;
142
+ stream: (...args: infer StreamArgs) => infer StreamReturn;
143
+ } ? Omit<A, "generate" | "stream"> & {
144
+ generate(...args: GenerateArgs extends [infer Options, ...infer Rest] ? [NormalizeUnknownAgentOptions<Options> & {
145
+ metadata?: AgentCallMetadata;
146
+ }, ...Rest] : GenerateArgs): GenerateReturn;
147
+ stream(...args: StreamArgs extends [infer Options, ...infer Rest] ? [NormalizeUnknownAgentOptions<Options> & {
148
+ metadata?: AgentCallMetadata;
149
+ }, ...Rest] : StreamArgs): StreamReturn;
150
+ } : A;
151
+ /**
152
+ * Structural wrapper type for AI SDK modules.
153
+ *
154
+ * - AI SDK v6: rewrites `ToolLoopAgent` constructor instance methods to accept
155
+ * `metadata` on `generate/stream`.
156
+ * - AI SDK v4/v5: no `ToolLoopAgent` export, so the type is unchanged.
157
+ */
158
+ type WrappedAISDK<T extends object> = T extends {
159
+ ToolLoopAgent: abstract new (...args: any[]) => any;
160
+ } ? Omit<T, "ToolLoopAgent"> & {
161
+ ToolLoopAgent: new (...args: ConstructorParameters<T["ToolLoopAgent"]>) => AgentWithMetadata<InstanceType<T["ToolLoopAgent"]>>;
162
+ } : T;
163
+ /**
164
+ * Backward-compatible alias for wrapped AI SDK module types.
165
+ *
166
+ * This alias intentionally avoids referencing `import("ai")` to satisfy type
167
+ * resolution without requiring `ai` to be installed.
168
+ *
169
+ * Prefer `WrappedAISDK<typeof ai>` in app code when you have an `ai` import.
170
+ */
171
+ type WrappedAI<T extends object = any> = WrappedAISDK<T>;
130
172
  type Attachment = {
131
173
  attachment_id?: string;
132
174
  name?: string;
@@ -139,7 +181,11 @@ type Attachment = {
139
181
  type: "text" | "image" | "iframe";
140
182
  });
141
183
  type RaindropAISDKOptions = {
142
- writeKey: string;
184
+ /**
185
+ * API write key. If omitted, telemetry shipping is disabled but `wrap()` is
186
+ * still available for a consistent integration surface.
187
+ */
188
+ writeKey?: string;
143
189
  endpoint?: string;
144
190
  traces?: {
145
191
  enabled?: boolean;
@@ -192,6 +238,38 @@ type AISDKMessage = {
192
238
  * - at the end with appended response messages (assistant/tool, incl tool-call + tool-result parts)
193
239
  */
194
240
  type EventBuilder = (messages: AISDKMessage[]) => void | BuildEventPatch;
241
+ type SelfDiagnosticsSignalDefinition = {
242
+ /**
243
+ * Human-readable meaning of this signal.
244
+ * Used in the injected tool schema and stored in signal properties.
245
+ */
246
+ description: string;
247
+ /**
248
+ * Optional default sentiment for this signal key.
249
+ * This can help dashboards classify negative/positive programmatic signals.
250
+ */
251
+ sentiment?: "POSITIVE" | "NEGATIVE";
252
+ };
253
+ type SelfDiagnosticsSignalDefinitions = Record<string, SelfDiagnosticsSignalDefinition>;
254
+ type SelfDiagnosticsOptions = {
255
+ /** Enable automatic injection of the self diagnostics tool. Default: false */
256
+ enabled?: boolean;
257
+ /**
258
+ * Signal keys and descriptions exposed to the model.
259
+ * Defaults to a built-in set when omitted.
260
+ */
261
+ signals?: SelfDiagnosticsSignalDefinitions;
262
+ /**
263
+ * Optional extra guidance for when the model should emit self diagnostics.
264
+ * The SDK still generates a full tool prompt from `signals`.
265
+ */
266
+ guidance?: string;
267
+ /**
268
+ * Optional tool name override for the injected self diagnostics tool.
269
+ * Defaults to "__raindrop_report".
270
+ */
271
+ toolName?: string;
272
+ };
195
273
  type WrapAISDKOptions = {
196
274
  context: RaindropAISDKContext | ((info: {
197
275
  operation: string;
@@ -199,6 +277,7 @@ type WrapAISDKOptions = {
199
277
  }) => RaindropAISDKContext);
200
278
  buildEvent?: EventBuilder;
201
279
  autoAttachment?: boolean;
280
+ selfDiagnostics?: SelfDiagnosticsOptions;
202
281
  send?: {
203
282
  events?: boolean;
204
283
  traces?: boolean;
@@ -217,7 +296,7 @@ type EventPatch = {
217
296
  timestamp?: string;
218
297
  };
219
298
  type RaindropAISDKClient = {
220
- wrap<T extends object>(aiSDK: T, options?: WrapAISDKOptions): T;
299
+ wrap<T extends object>(aiSDK: T, options?: WrapAISDKOptions): WrappedAISDK<T>;
221
300
  events: {
222
301
  patch(eventId: string, patch: EventPatch): Promise<void>;
223
302
  addAttachments(eventId: string, attachments: Attachment[]): Promise<void>;
@@ -235,7 +314,7 @@ type RaindropAISDKClient = {
235
314
  track(signal: {
236
315
  eventId: string;
237
316
  name: "thumbs_up" | "thumbs_down" | string;
238
- type?: "default" | "feedback" | "edit";
317
+ type?: "default" | "feedback" | "edit" | "standard" | "agent" | "agent_internal";
239
318
  sentiment?: "POSITIVE" | "NEGATIVE";
240
319
  timestamp?: string;
241
320
  properties?: Record<string, unknown>;
@@ -249,4 +328,4 @@ type RaindropAISDKClient = {
249
328
  };
250
329
  declare function createRaindropAISDK(opts: RaindropAISDKOptions): RaindropAISDKClient;
251
330
 
252
- export { type AISDKMessage, type Attachment, type BuildEventPatch, ContextManager, type ContextSpan, type EventBuilder, type EventMetadataOptions, type IdentifyInput, type RaindropAISDKClient, type RaindropAISDKContext, type RaindropAISDKOptions, type WrapAISDKOptions, _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, getContextManager, withCurrent };
331
+ export { type AISDKMessage, type AgentCallMetadata, type AgentWithMetadata, type Attachment, type BuildEventPatch, ContextManager, type ContextSpan, type EventBuilder, type EventMetadataOptions, type IdentifyInput, type RaindropAISDKClient, type RaindropAISDKContext, type RaindropAISDKOptions, type SelfDiagnosticsOptions, type SelfDiagnosticsSignalDefinition, type SelfDiagnosticsSignalDefinitions, type WrapAISDKOptions, type WrappedAI, type WrappedAISDK, _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, getContextManager, withCurrent };
package/dist/index.js CHANGED
@@ -86,7 +86,7 @@ async function postJson(url, body, headers, opts) {
86
86
  // package.json
87
87
  var package_default = {
88
88
  name: "@raindrop-ai/ai-sdk",
89
- version: "0.0.8"};
89
+ version: "0.0.10"};
90
90
 
91
91
  // src/internal/version.ts
92
92
  var libraryName = package_default.name;
@@ -120,13 +120,15 @@ var EventShipper = class {
120
120
  this.sticky = /* @__PURE__ */ new Map();
121
121
  this.timers = /* @__PURE__ */ new Map();
122
122
  this.inFlight = /* @__PURE__ */ new Set();
123
- var _a, _b;
124
- if (!opts.writeKey) throw new Error("[raindrop-ai/ai-sdk] writeKey is required");
125
- this.writeKey = opts.writeKey;
126
- this.baseUrl = (_a = formatEndpoint(opts.endpoint)) != null ? _a : "https://api.raindrop.ai/v1/";
123
+ var _a, _b, _c;
124
+ if (opts.enabled && !opts.writeKey) {
125
+ throw new Error("[raindrop-ai/ai-sdk] writeKey is required when events are enabled");
126
+ }
127
+ this.writeKey = (_a = opts.writeKey) != null ? _a : "";
128
+ this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
127
129
  this.enabled = opts.enabled;
128
130
  this.debug = opts.debug;
129
- this.partialFlushMs = (_b = opts.partialFlushMs) != null ? _b : 1e3;
131
+ this.partialFlushMs = (_c = opts.partialFlushMs) != null ? _c : 1e3;
130
132
  this.context = getRuntimeContext();
131
133
  }
132
134
  isDebugEnabled() {
@@ -474,16 +476,18 @@ var TraceShipper = class {
474
476
  constructor(opts) {
475
477
  this.queue = [];
476
478
  this.inFlight = /* @__PURE__ */ new Set();
477
- var _a, _b, _c, _d;
478
- if (!opts.writeKey) throw new Error("[raindrop-ai/ai-sdk] writeKey is required");
479
- this.writeKey = opts.writeKey;
480
- this.baseUrl = (_a = formatEndpoint(opts.endpoint)) != null ? _a : "https://api.raindrop.ai/v1/";
479
+ var _a, _b, _c, _d, _e;
480
+ if (opts.enabled && !opts.writeKey) {
481
+ throw new Error("[raindrop-ai/ai-sdk] writeKey is required when traces are enabled");
482
+ }
483
+ this.writeKey = (_a = opts.writeKey) != null ? _a : "";
484
+ this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
481
485
  this.enabled = opts.enabled;
482
486
  this.debug = opts.debug;
483
487
  this.debugSpans = opts.debugSpans === true;
484
- this.flushIntervalMs = (_b = opts.flushIntervalMs) != null ? _b : 1e3;
485
- this.maxBatchSize = (_c = opts.maxBatchSize) != null ? _c : 50;
486
- this.maxQueueSize = (_d = opts.maxQueueSize) != null ? _d : 5e3;
488
+ this.flushIntervalMs = (_c = opts.flushIntervalMs) != null ? _c : 1e3;
489
+ this.maxBatchSize = (_d = opts.maxBatchSize) != null ? _d : 50;
490
+ this.maxQueueSize = (_e = opts.maxQueueSize) != null ? _e : 5e3;
487
491
  }
488
492
  isDebugEnabled() {
489
493
  return this.debug;
@@ -1243,6 +1247,23 @@ function attrsFromGenAiRequest(options) {
1243
1247
  }
1244
1248
 
1245
1249
  // src/internal/wrap/wrapAISDK.ts
1250
+ var AGENT_REPORTING_TOOL_NAME_DEFAULT = "__raindrop_report";
1251
+ var AGENT_REPORTING_SIGNALS_DEFAULT = {
1252
+ tool_failure: {
1253
+ description: "A tool call returned an error, timed out, or produced output that cannot be used to make progress.",
1254
+ sentiment: "NEGATIVE"
1255
+ },
1256
+ stuck_in_loop: {
1257
+ description: "The same approach has been attempted multiple times without meaningful progress.",
1258
+ sentiment: "NEGATIVE"
1259
+ },
1260
+ capability_gap: {
1261
+ description: "The task requires a tool, permission, or capability that is not available to the agent."
1262
+ }
1263
+ };
1264
+ var AGENT_REPORTING_TOOL_PREAMBLE = "IMPORTANT: Before responding to the user, scan the conversation for any issues listed in the categories below. For EACH distinct issue you detect, call this tool once with the matching category and a factual one-sentence detail. Multiple issues = multiple calls. This tool is invisible to the user \u2014 never mention it or its output.";
1265
+ var AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY = "noteworthy";
1266
+ var AGENT_REPORTING_NOTEWORTHY_DESCRIPTION = "Only when no specific category applies: flag that this turn is noteworthy for developer review.";
1246
1267
  var warnedMissingUserId = false;
1247
1268
  function warnMissingUserIdOnce() {
1248
1269
  if (warnedMissingUserId) return;
@@ -1254,6 +1275,14 @@ function warnMissingUserIdOnce() {
1254
1275
  function _resetWarnedMissingUserId() {
1255
1276
  warnedMissingUserId = false;
1256
1277
  }
1278
+ function extractRaindropCallOptions(options) {
1279
+ if (!isRecord(options)) return {};
1280
+ const em = options["metadata"];
1281
+ if (isRecord(em)) return extractRaindropMetadata(em);
1282
+ const telemetry = extractExperimentalTelemetry(options);
1283
+ if (telemetry == null ? void 0 : telemetry.metadata) return extractRaindropMetadata(telemetry.metadata);
1284
+ return {};
1285
+ }
1257
1286
  function extractRaindropMetadata(metadata) {
1258
1287
  if (!metadata || typeof metadata !== "object") return {};
1259
1288
  const result = {};
@@ -1290,6 +1319,188 @@ function mergeContexts(wrapTime, callTime) {
1290
1319
  }
1291
1320
  return result;
1292
1321
  }
1322
+ function normalizeSelfDiagnosticsSignals(signals) {
1323
+ if (!signals) return AGENT_REPORTING_SIGNALS_DEFAULT;
1324
+ const normalizedEntries = Object.entries(signals).map(([key, value]) => {
1325
+ var _a;
1326
+ const signalKey = key.trim();
1327
+ if (!signalKey || !value || typeof value !== "object") return void 0;
1328
+ const description = (_a = value.description) == null ? void 0 : _a.trim();
1329
+ if (!description) return void 0;
1330
+ const sentiment = value.sentiment;
1331
+ return [
1332
+ signalKey,
1333
+ {
1334
+ description,
1335
+ ...sentiment === "POSITIVE" || sentiment === "NEGATIVE" ? { sentiment } : {}
1336
+ }
1337
+ ];
1338
+ }).filter(
1339
+ (entry) => entry !== void 0
1340
+ );
1341
+ if (normalizedEntries.length === 0) return AGENT_REPORTING_SIGNALS_DEFAULT;
1342
+ return Object.fromEntries(normalizedEntries);
1343
+ }
1344
+ function normalizeSelfDiagnosticsConfig(options) {
1345
+ var _a, _b, _c;
1346
+ if (!(options == null ? void 0 : options.enabled)) return void 0;
1347
+ const signalDefinitions = normalizeSelfDiagnosticsSignals(options.signals);
1348
+ const configuredSignalKeys = Object.keys(signalDefinitions).filter(
1349
+ (signalKey) => signalKey !== AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY
1350
+ );
1351
+ const signalKeys = [...configuredSignalKeys, AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY];
1352
+ const signalDescriptions = {};
1353
+ const signalSentiments = {};
1354
+ for (const signalKey of signalKeys) {
1355
+ if (signalKey === AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY) {
1356
+ const noteworthyDefinition = signalDefinitions[AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY];
1357
+ signalDescriptions[signalKey] = ((_a = noteworthyDefinition == null ? void 0 : noteworthyDefinition.description) == null ? void 0 : _a.trim()) || AGENT_REPORTING_NOTEWORTHY_DESCRIPTION;
1358
+ signalSentiments[signalKey] = noteworthyDefinition == null ? void 0 : noteworthyDefinition.sentiment;
1359
+ continue;
1360
+ }
1361
+ const def = signalDefinitions[signalKey];
1362
+ if (!def) continue;
1363
+ signalDescriptions[signalKey] = def.description;
1364
+ signalSentiments[signalKey] = def.sentiment;
1365
+ }
1366
+ const customGuidanceText = ((_b = options.guidance) == null ? void 0 : _b.trim()) || "";
1367
+ const toolName = ((_c = options.toolName) == null ? void 0 : _c.trim()) || AGENT_REPORTING_TOOL_NAME_DEFAULT;
1368
+ const signalList = signalKeys.map((signalKey) => {
1369
+ const sentiment = signalSentiments[signalKey];
1370
+ const sentimentTag = sentiment ? ` [${sentiment.toLowerCase()}]` : "";
1371
+ return `- ${signalKey}: ${signalDescriptions[signalKey]}${sentimentTag}`;
1372
+ }).join("\n");
1373
+ const guidanceBlock = customGuidanceText ? `
1374
+ Additional guidance: ${customGuidanceText}
1375
+ ` : "";
1376
+ const toolDescription = `${AGENT_REPORTING_TOOL_PREAMBLE}
1377
+
1378
+ When to call:
1379
+ - The user reports something broken, failing, or not working as expected.
1380
+ - The user expresses frustration, anger, or threatens escalation.
1381
+ - You observe a product issue, billing problem, or data concern based on context.
1382
+ - The conversation reveals something unusual worth flagging for developer review.
1383
+
1384
+ Rules:
1385
+ 1. Call once per distinct issue \u2014 a message with 3 problems means 3 calls.
1386
+ 2. Pick the single best category per issue. Use noteworthy only when no specific category fits.
1387
+ 3. Do not fabricate issues. Only report what is evident from the conversation.
1388
+ ${guidanceBlock}
1389
+ Categories:
1390
+ ${signalList}`;
1391
+ return {
1392
+ toolName,
1393
+ toolDescription,
1394
+ signalKeys,
1395
+ signalKeySet: new Set(signalKeys),
1396
+ signalDescriptions,
1397
+ signalSentiments
1398
+ };
1399
+ }
1400
+ function resolveJsonSchemaFactory(aiSDK) {
1401
+ if (!isRecord(aiSDK) || !isFunction(aiSDK["jsonSchema"])) return void 0;
1402
+ return aiSDK["jsonSchema"];
1403
+ }
1404
+ function detectAISDKVersion(aiSDK) {
1405
+ if (!isRecord(aiSDK)) return "unknown";
1406
+ if (isFunction(aiSDK["jsonSchema"])) return "6";
1407
+ if (isFunction(aiSDK["tool"])) return "5";
1408
+ return "4";
1409
+ }
1410
+ function asVercelSchema(jsonSchemaObj) {
1411
+ const validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
1412
+ const schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
1413
+ return {
1414
+ [schemaSymbol]: true,
1415
+ [validatorSymbol]: true,
1416
+ _type: void 0,
1417
+ jsonSchema: jsonSchemaObj,
1418
+ validate: (value) => ({ success: true, value })
1419
+ };
1420
+ }
1421
+ function createSelfDiagnosticsTool(ctx) {
1422
+ const config = ctx.selfDiagnostics;
1423
+ if (!config) return void 0;
1424
+ const schema = {
1425
+ type: "object",
1426
+ additionalProperties: false,
1427
+ properties: {
1428
+ category: {
1429
+ type: "string",
1430
+ enum: config.signalKeys,
1431
+ description: "The single best-matching category from the list above."
1432
+ },
1433
+ detail: {
1434
+ type: "string",
1435
+ description: "One sentence of factual context: what happened and why it matters. Do not include PII or secrets."
1436
+ }
1437
+ },
1438
+ required: ["category", "detail"]
1439
+ };
1440
+ const parameters = asVercelSchema(schema);
1441
+ let inputSchema = parameters;
1442
+ if (ctx.jsonSchemaFactory) {
1443
+ try {
1444
+ inputSchema = ctx.jsonSchemaFactory(schema);
1445
+ } catch (e) {
1446
+ inputSchema = parameters;
1447
+ }
1448
+ }
1449
+ const execute = async (rawInput) => {
1450
+ var _a;
1451
+ const input = isRecord(rawInput) ? rawInput : void 0;
1452
+ const fallbackCategory = (_a = config.signalKeys[0]) != null ? _a : "unknown";
1453
+ const categoryCandidate = typeof (input == null ? void 0 : input["category"]) === "string" ? input["category"].trim() : void 0;
1454
+ const category = categoryCandidate && config.signalKeySet.has(categoryCandidate) ? categoryCandidate : fallbackCategory;
1455
+ const detail = typeof (input == null ? void 0 : input["detail"]) === "string" ? input["detail"].trim() : "";
1456
+ const signalDescription = config.signalDescriptions[category];
1457
+ const signalSentiment = config.signalSentiments[category];
1458
+ if (category === AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY) {
1459
+ void ctx.eventShipper.trackSignal({
1460
+ eventId: ctx.eventId,
1461
+ name: "agent:noteworthy",
1462
+ type: "agent_internal",
1463
+ properties: {
1464
+ source: "agent_flag_event_tool",
1465
+ reason: detail,
1466
+ severity: "medium",
1467
+ ai_sdk_version: ctx.aiSDKVersion
1468
+ }
1469
+ }).catch((err) => {
1470
+ if (ctx.debug) {
1471
+ const msg = err instanceof Error ? err.message : String(err);
1472
+ console.warn(`[raindrop-ai/ai-sdk] agentFlagEvent signal dispatch failed: ${msg}`);
1473
+ }
1474
+ });
1475
+ return { acknowledged: true, category };
1476
+ }
1477
+ void ctx.eventShipper.trackSignal({
1478
+ eventId: ctx.eventId,
1479
+ name: `agent:${category}`,
1480
+ type: "agent",
1481
+ sentiment: signalSentiment,
1482
+ properties: {
1483
+ source: "agent_reporting_tool",
1484
+ category,
1485
+ signal_description: signalDescription,
1486
+ ai_sdk_version: ctx.aiSDKVersion,
1487
+ ...detail ? { detail } : {}
1488
+ }
1489
+ }).catch((err) => {
1490
+ if (ctx.debug) {
1491
+ const msg = err instanceof Error ? err.message : String(err);
1492
+ console.warn(`[raindrop-ai/ai-sdk] selfDiagnostics signal dispatch failed: ${msg}`);
1493
+ }
1494
+ });
1495
+ return { acknowledged: true, category };
1496
+ };
1497
+ return {
1498
+ description: config.toolDescription,
1499
+ execute,
1500
+ parameters,
1501
+ inputSchema
1502
+ };
1503
+ }
1293
1504
  function getCurrentParentSpanContextSync() {
1294
1505
  return getContextManager().getParentSpanIds();
1295
1506
  }
@@ -1419,7 +1630,18 @@ function teeStreamObjectBaseStream(result) {
1419
1630
  }
1420
1631
  function setupOperation(params) {
1421
1632
  var _a, _b, _c;
1422
- const { operation, arg, inherited, aiSDK, options, traceShipper, sendTraces } = params;
1633
+ const {
1634
+ operation,
1635
+ arg,
1636
+ inherited,
1637
+ aiSDK,
1638
+ options,
1639
+ eventShipper,
1640
+ traceShipper,
1641
+ debug,
1642
+ selfDiagnostics,
1643
+ sendTraces
1644
+ } = params;
1423
1645
  const wrapTimeCtx = resolveContext(options.context, { operation, args: arg });
1424
1646
  const telemetry = extractExperimentalTelemetry(arg);
1425
1647
  const callTimeCtx = extractRaindropMetadata(telemetry == null ? void 0 : telemetry.metadata);
@@ -1458,12 +1680,18 @@ function setupOperation(params) {
1458
1680
  ]
1459
1681
  }) : void 0;
1460
1682
  const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
1683
+ const operationSelfDiagnostics = isObjectOperation(operation) ? void 0 : selfDiagnostics;
1461
1684
  const wrapCtx = {
1462
1685
  eventId,
1463
1686
  telemetry,
1464
1687
  sendTraces,
1688
+ debug,
1689
+ eventShipper,
1465
1690
  traceShipper,
1466
- rootParentForChildren
1691
+ rootParentForChildren,
1692
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
1693
+ selfDiagnostics: operationSelfDiagnostics,
1694
+ aiSDKVersion: detectAISDKVersion(aiSDK)
1467
1695
  };
1468
1696
  const toolCalls = [];
1469
1697
  const argsWithWrappedTools = wrapTools(arg, wrapCtx, toolCalls);
@@ -1533,12 +1761,7 @@ function createFinalize(params) {
1533
1761
  attrInt("ai.usage.reasoningTokens", usage == null ? void 0 : usage.reasoningTokens),
1534
1762
  attrInt("ai.usage.cachedInputTokens", usage == null ? void 0 : usage.cachedInputTokens),
1535
1763
  attrInt("ai.toolCall.count", setup.toolCalls.length),
1536
- ...error ? [
1537
- attrString(
1538
- "error.message",
1539
- error instanceof Error ? error.message : String(error)
1540
- )
1541
- ] : []
1764
+ ...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
1542
1765
  ]
1543
1766
  });
1544
1767
  }
@@ -1573,6 +1796,7 @@ function executeStreamingOperation(params) {
1573
1796
  deps,
1574
1797
  sendEvents,
1575
1798
  sendTraces,
1799
+ selfDiagnostics,
1576
1800
  autoAttachmentEnabled,
1577
1801
  debug
1578
1802
  } = params;
@@ -1582,7 +1806,10 @@ function executeStreamingOperation(params) {
1582
1806
  inherited: getCurrentParentSpanContextSync(),
1583
1807
  aiSDK,
1584
1808
  options: deps.options,
1809
+ eventShipper: deps.eventShipper,
1585
1810
  traceShipper: deps.traceShipper,
1811
+ debug,
1812
+ selfDiagnostics,
1586
1813
  sendTraces
1587
1814
  });
1588
1815
  const finalize = createFinalize({
@@ -1627,6 +1854,7 @@ async function executeNonStreamingOperation(params) {
1627
1854
  deps,
1628
1855
  sendEvents,
1629
1856
  sendTraces,
1857
+ selfDiagnostics,
1630
1858
  autoAttachmentEnabled,
1631
1859
  debug
1632
1860
  } = params;
@@ -1637,7 +1865,10 @@ async function executeNonStreamingOperation(params) {
1637
1865
  inherited,
1638
1866
  aiSDK,
1639
1867
  options: deps.options,
1868
+ eventShipper: deps.eventShipper,
1640
1869
  traceShipper: deps.traceShipper,
1870
+ debug,
1871
+ selfDiagnostics,
1641
1872
  sendTraces
1642
1873
  });
1643
1874
  const finalize = createFinalize({
@@ -1680,13 +1911,14 @@ function wrapAISDK(aiSDK, deps) {
1680
1911
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1681
1912
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
1682
1913
  const autoAttachmentEnabled = deps.options.autoAttachment !== false;
1914
+ const selfDiagnostics = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
1683
1915
  const proxyTarget = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
1684
1916
  return new Proxy(proxyTarget, {
1685
1917
  get(target, prop, receiver) {
1686
1918
  const original = Reflect.get(target, prop, receiver);
1687
1919
  if (typeof prop === "string" && agentClasses.has(prop) && isAgentClass(original)) {
1688
1920
  if (debug) console.log(`[raindrop-ai/ai-sdk] Wrapping Agent class: ${prop}`);
1689
- return wrapAgentClass(original, aiSDK, deps, debug);
1921
+ return wrapAgentClass(original, aiSDK, deps, debug, selfDiagnostics);
1690
1922
  }
1691
1923
  if (typeof prop !== "string" || !instrumentedOps.has(prop) || !isFunction(original)) {
1692
1924
  return original;
@@ -1704,6 +1936,7 @@ function wrapAISDK(aiSDK, deps) {
1704
1936
  deps,
1705
1937
  sendEvents,
1706
1938
  sendTraces,
1939
+ selfDiagnostics,
1707
1940
  autoAttachmentEnabled,
1708
1941
  debug
1709
1942
  });
@@ -1717,6 +1950,7 @@ function wrapAISDK(aiSDK, deps) {
1717
1950
  deps,
1718
1951
  sendEvents,
1719
1952
  sendTraces,
1953
+ selfDiagnostics,
1720
1954
  autoAttachmentEnabled,
1721
1955
  debug
1722
1956
  });
@@ -1724,7 +1958,7 @@ function wrapAISDK(aiSDK, deps) {
1724
1958
  }
1725
1959
  });
1726
1960
  }
1727
- function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1961
+ function wrapAgentClass(AgentClass, aiSDK, deps, debug, selfDiagnostics) {
1728
1962
  return new Proxy(AgentClass, {
1729
1963
  construct(target, args, newTarget) {
1730
1964
  const instance = Reflect.construct(target, args, newTarget);
@@ -1743,7 +1977,8 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1743
1977
  className,
1744
1978
  aiSDK,
1745
1979
  deps,
1746
- debug
1980
+ debug,
1981
+ selfDiagnostics
1747
1982
  );
1748
1983
  }
1749
1984
  if (prop === "stream" && isFunction(original)) {
@@ -1755,7 +1990,8 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1755
1990
  className,
1756
1991
  aiSDK,
1757
1992
  deps,
1758
- debug
1993
+ debug,
1994
+ selfDiagnostics
1759
1995
  );
1760
1996
  }
1761
1997
  return original;
@@ -1764,7 +2000,7 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1764
2000
  }
1765
2001
  });
1766
2002
  }
1767
- function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK, deps, debug) {
2003
+ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
1768
2004
  var _a, _b;
1769
2005
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1770
2006
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
@@ -1776,7 +2012,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1776
2012
  const operation = `${className}.generate`;
1777
2013
  const wrapTimeCtx = resolveContext(deps.options.context, { operation, args: mergedArgs });
1778
2014
  const telemetry = extractExperimentalTelemetry(mergedArgs);
1779
- const callTimeCtx = extractRaindropMetadata(telemetry == null ? void 0 : telemetry.metadata);
2015
+ const callTimeCtx = extractRaindropCallOptions(mergedArgs);
1780
2016
  const mergedCtx = mergeContexts(wrapTimeCtx, callTimeCtx);
1781
2017
  if (!mergedCtx.userId) warnMissingUserIdOnce();
1782
2018
  const inherited = await getCurrentParentSpanContext();
@@ -1817,8 +2053,13 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1817
2053
  eventId,
1818
2054
  telemetry,
1819
2055
  sendTraces,
2056
+ debug,
2057
+ eventShipper: deps.eventShipper,
1820
2058
  traceShipper: deps.traceShipper,
1821
- rootParentForChildren
2059
+ rootParentForChildren,
2060
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
2061
+ selfDiagnostics,
2062
+ aiSDKVersion: detectAISDKVersion(aiSDK)
1822
2063
  };
1823
2064
  const toolCalls = [];
1824
2065
  const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
@@ -1952,7 +2193,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1952
2193
  }
1953
2194
  };
1954
2195
  }
1955
- function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps, debug) {
2196
+ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
1956
2197
  var _a, _b;
1957
2198
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1958
2199
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
@@ -1964,7 +2205,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
1964
2205
  const operation = `${className}.stream`;
1965
2206
  const wrapTimeCtx = resolveContext(deps.options.context, { operation, args: mergedArgs });
1966
2207
  const telemetry = extractExperimentalTelemetry(mergedArgs);
1967
- const callTimeCtx = extractRaindropMetadata(telemetry == null ? void 0 : telemetry.metadata);
2208
+ const callTimeCtx = extractRaindropCallOptions(mergedArgs);
1968
2209
  const mergedCtx = mergeContexts(wrapTimeCtx, callTimeCtx);
1969
2210
  if (!mergedCtx.userId) warnMissingUserIdOnce();
1970
2211
  const inherited = await getCurrentParentSpanContext();
@@ -2005,8 +2246,13 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
2005
2246
  eventId,
2006
2247
  telemetry,
2007
2248
  sendTraces,
2249
+ debug,
2250
+ eventShipper: deps.eventShipper,
2008
2251
  traceShipper: deps.traceShipper,
2009
- rootParentForChildren
2252
+ rootParentForChildren,
2253
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
2254
+ selfDiagnostics,
2255
+ aiSDKVersion: detectAISDKVersion(aiSDK)
2010
2256
  };
2011
2257
  const toolCalls = [];
2012
2258
  const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
@@ -2146,8 +2392,22 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
2146
2392
  };
2147
2393
  }
2148
2394
  function wrapTools(args, ctx, toolCalls) {
2149
- if (!isRecord(args) || !("tools" in args) || !isRecord(args["tools"])) return args;
2150
- const tools = args["tools"];
2395
+ if (!isRecord(args)) return args;
2396
+ const tools = isRecord(args["tools"]) ? { ...args["tools"] } : {};
2397
+ if (ctx.selfDiagnostics) {
2398
+ const reportToolName = ctx.selfDiagnostics.toolName;
2399
+ if (!(reportToolName in tools)) {
2400
+ const reportTool = createSelfDiagnosticsTool(ctx);
2401
+ if (reportTool !== void 0) {
2402
+ tools[reportToolName] = reportTool;
2403
+ }
2404
+ } else if (ctx.debug) {
2405
+ console.warn(
2406
+ `[raindrop-ai/ai-sdk] selfDiagnostics skipped: tool name collision for "${reportToolName}"`
2407
+ );
2408
+ }
2409
+ }
2410
+ if (Object.keys(tools).length === 0) return args;
2151
2411
  const wrapped = {};
2152
2412
  for (const [name, tool] of Object.entries(tools)) {
2153
2413
  wrapped[name] = wrapToolExecute(name, tool, ctx, toolCalls);
@@ -2634,18 +2894,26 @@ function envDebugEnabled() {
2634
2894
  }
2635
2895
  function createRaindropAISDK(opts) {
2636
2896
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2637
- const eventsEnabled = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
2638
- const tracesEnabled = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
2897
+ const writeKey = opts.writeKey;
2898
+ const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
2899
+ const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
2900
+ const eventsEnabled = eventsRequested && !!writeKey;
2901
+ const tracesEnabled = tracesRequested && !!writeKey;
2639
2902
  const envDebug = envDebugEnabled();
2903
+ if (!writeKey && (eventsRequested || tracesRequested)) {
2904
+ console.warn(
2905
+ "[raindrop-ai/ai-sdk] writeKey not provided; telemetry shipping is disabled"
2906
+ );
2907
+ }
2640
2908
  const eventShipper = new EventShipper({
2641
- writeKey: opts.writeKey,
2909
+ writeKey,
2642
2910
  endpoint: opts.endpoint,
2643
2911
  enabled: eventsEnabled,
2644
2912
  debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
2645
2913
  partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs
2646
2914
  });
2647
2915
  const traceShipper = new TraceShipper({
2648
- writeKey: opts.writeKey,
2916
+ writeKey,
2649
2917
  endpoint: opts.endpoint,
2650
2918
  enabled: tracesEnabled,
2651
2919
  debug: ((_e = opts.traces) == null ? void 0 : _e.debug) === true || envDebug,
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export { _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, getContextManager, withCurrent } from './chunk-NFWQZOEK.mjs';
1
+ export { _resetWarnedMissingUserId, createRaindropAISDK, currentSpan, eventMetadata, getContextManager, withCurrent } from './chunk-ZVQRZCBO.mjs';