@raindrop-ai/ai-sdk 0.0.9 → 0.0.11

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.
@@ -84,7 +84,7 @@ async function postJson(url, body, headers, opts) {
84
84
  // package.json
85
85
  var package_default = {
86
86
  name: "@raindrop-ai/ai-sdk",
87
- version: "0.0.9"};
87
+ version: "0.0.11"};
88
88
 
89
89
  // src/internal/version.ts
90
90
  var libraryName = package_default.name;
@@ -397,6 +397,9 @@ function base64Encode(bytes) {
397
397
  }
398
398
 
399
399
  // src/internal/otlp.ts
400
+ var SpanStatusCode = {
401
+ ERROR: 2
402
+ };
400
403
  function createSpanIds(parent) {
401
404
  const traceId = parent ? parent.traceIdB64 : base64Encode(randomBytes(16));
402
405
  const spanId = base64Encode(randomBytes(8));
@@ -449,6 +452,7 @@ function buildOtlpSpan(args) {
449
452
  };
450
453
  if (args.ids.parentSpanIdB64) span.parentSpanId = args.ids.parentSpanIdB64;
451
454
  if (attrs.length) span.attributes = attrs;
455
+ if (args.status) span.status = args.status;
452
456
  return span;
453
457
  }
454
458
  function buildExportTraceServiceRequest(spans) {
@@ -509,12 +513,18 @@ var TraceShipper = class {
509
513
  if ((_a = extra == null ? void 0 : extra.attributes) == null ? void 0 : _a.length) {
510
514
  span.attributes.push(...extra.attributes);
511
515
  }
516
+ let status;
517
+ if ((extra == null ? void 0 : extra.error) !== void 0) {
518
+ const message = extra.error instanceof Error ? extra.error.message : String(extra.error);
519
+ status = { code: SpanStatusCode.ERROR, message };
520
+ }
512
521
  const otlp = buildOtlpSpan({
513
522
  ids: span.ids,
514
523
  name: span.name,
515
524
  startTimeUnixNano: span.startTimeUnixNano,
516
525
  endTimeUnixNano: span.endTimeUnixNano,
517
- attributes: span.attributes
526
+ attributes: span.attributes,
527
+ status
518
528
  });
519
529
  this.enqueue(otlp);
520
530
  }
@@ -1245,6 +1255,23 @@ function attrsFromGenAiRequest(options) {
1245
1255
  }
1246
1256
 
1247
1257
  // src/internal/wrap/wrapAISDK.ts
1258
+ var AGENT_REPORTING_TOOL_NAME_DEFAULT = "__raindrop_report";
1259
+ var AGENT_REPORTING_SIGNALS_DEFAULT = {
1260
+ tool_failure: {
1261
+ description: "A tool call returned an error, timed out, or produced output that cannot be used to make progress.",
1262
+ sentiment: "NEGATIVE"
1263
+ },
1264
+ stuck_in_loop: {
1265
+ description: "The same approach has been attempted multiple times without meaningful progress.",
1266
+ sentiment: "NEGATIVE"
1267
+ },
1268
+ capability_gap: {
1269
+ description: "The task requires a tool, permission, or capability that is not available to the agent."
1270
+ }
1271
+ };
1272
+ 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.";
1273
+ var AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY = "noteworthy";
1274
+ var AGENT_REPORTING_NOTEWORTHY_DESCRIPTION = "Only when no specific category applies: flag that this turn is noteworthy for developer review.";
1248
1275
  var warnedMissingUserId = false;
1249
1276
  function warnMissingUserIdOnce() {
1250
1277
  if (warnedMissingUserId) return;
@@ -1300,6 +1327,188 @@ function mergeContexts(wrapTime, callTime) {
1300
1327
  }
1301
1328
  return result;
1302
1329
  }
1330
+ function normalizeSelfDiagnosticsSignals(signals) {
1331
+ if (!signals) return AGENT_REPORTING_SIGNALS_DEFAULT;
1332
+ const normalizedEntries = Object.entries(signals).map(([key, value]) => {
1333
+ var _a;
1334
+ const signalKey = key.trim();
1335
+ if (!signalKey || !value || typeof value !== "object") return void 0;
1336
+ const description = (_a = value.description) == null ? void 0 : _a.trim();
1337
+ if (!description) return void 0;
1338
+ const sentiment = value.sentiment;
1339
+ return [
1340
+ signalKey,
1341
+ {
1342
+ description,
1343
+ ...sentiment === "POSITIVE" || sentiment === "NEGATIVE" ? { sentiment } : {}
1344
+ }
1345
+ ];
1346
+ }).filter(
1347
+ (entry) => entry !== void 0
1348
+ );
1349
+ if (normalizedEntries.length === 0) return AGENT_REPORTING_SIGNALS_DEFAULT;
1350
+ return Object.fromEntries(normalizedEntries);
1351
+ }
1352
+ function normalizeSelfDiagnosticsConfig(options) {
1353
+ var _a, _b, _c;
1354
+ if (!(options == null ? void 0 : options.enabled)) return void 0;
1355
+ const signalDefinitions = normalizeSelfDiagnosticsSignals(options.signals);
1356
+ const configuredSignalKeys = Object.keys(signalDefinitions).filter(
1357
+ (signalKey) => signalKey !== AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY
1358
+ );
1359
+ const signalKeys = [...configuredSignalKeys, AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY];
1360
+ const signalDescriptions = {};
1361
+ const signalSentiments = {};
1362
+ for (const signalKey of signalKeys) {
1363
+ if (signalKey === AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY) {
1364
+ const noteworthyDefinition = signalDefinitions[AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY];
1365
+ signalDescriptions[signalKey] = ((_a = noteworthyDefinition == null ? void 0 : noteworthyDefinition.description) == null ? void 0 : _a.trim()) || AGENT_REPORTING_NOTEWORTHY_DESCRIPTION;
1366
+ signalSentiments[signalKey] = noteworthyDefinition == null ? void 0 : noteworthyDefinition.sentiment;
1367
+ continue;
1368
+ }
1369
+ const def = signalDefinitions[signalKey];
1370
+ if (!def) continue;
1371
+ signalDescriptions[signalKey] = def.description;
1372
+ signalSentiments[signalKey] = def.sentiment;
1373
+ }
1374
+ const customGuidanceText = ((_b = options.guidance) == null ? void 0 : _b.trim()) || "";
1375
+ const toolName = ((_c = options.toolName) == null ? void 0 : _c.trim()) || AGENT_REPORTING_TOOL_NAME_DEFAULT;
1376
+ const signalList = signalKeys.map((signalKey) => {
1377
+ const sentiment = signalSentiments[signalKey];
1378
+ const sentimentTag = sentiment ? ` [${sentiment.toLowerCase()}]` : "";
1379
+ return `- ${signalKey}: ${signalDescriptions[signalKey]}${sentimentTag}`;
1380
+ }).join("\n");
1381
+ const guidanceBlock = customGuidanceText ? `
1382
+ Additional guidance: ${customGuidanceText}
1383
+ ` : "";
1384
+ const toolDescription = `${AGENT_REPORTING_TOOL_PREAMBLE}
1385
+
1386
+ When to call:
1387
+ - The user reports something broken, failing, or not working as expected.
1388
+ - The user expresses frustration, anger, or threatens escalation.
1389
+ - You observe a product issue, billing problem, or data concern based on context.
1390
+ - The conversation reveals something unusual worth flagging for developer review.
1391
+
1392
+ Rules:
1393
+ 1. Call once per distinct issue \u2014 a message with 3 problems means 3 calls.
1394
+ 2. Pick the single best category per issue. Use noteworthy only when no specific category fits.
1395
+ 3. Do not fabricate issues. Only report what is evident from the conversation.
1396
+ ${guidanceBlock}
1397
+ Categories:
1398
+ ${signalList}`;
1399
+ return {
1400
+ toolName,
1401
+ toolDescription,
1402
+ signalKeys,
1403
+ signalKeySet: new Set(signalKeys),
1404
+ signalDescriptions,
1405
+ signalSentiments
1406
+ };
1407
+ }
1408
+ function resolveJsonSchemaFactory(aiSDK) {
1409
+ if (!isRecord(aiSDK) || !isFunction(aiSDK["jsonSchema"])) return void 0;
1410
+ return aiSDK["jsonSchema"];
1411
+ }
1412
+ function detectAISDKVersion(aiSDK) {
1413
+ if (!isRecord(aiSDK)) return "unknown";
1414
+ if (isFunction(aiSDK["jsonSchema"])) return "6";
1415
+ if (isFunction(aiSDK["tool"])) return "5";
1416
+ return "4";
1417
+ }
1418
+ function asVercelSchema(jsonSchemaObj) {
1419
+ const validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
1420
+ const schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
1421
+ return {
1422
+ [schemaSymbol]: true,
1423
+ [validatorSymbol]: true,
1424
+ _type: void 0,
1425
+ jsonSchema: jsonSchemaObj,
1426
+ validate: (value) => ({ success: true, value })
1427
+ };
1428
+ }
1429
+ function createSelfDiagnosticsTool(ctx) {
1430
+ const config = ctx.selfDiagnostics;
1431
+ if (!config) return void 0;
1432
+ const schema = {
1433
+ type: "object",
1434
+ additionalProperties: false,
1435
+ properties: {
1436
+ category: {
1437
+ type: "string",
1438
+ enum: config.signalKeys,
1439
+ description: "The single best-matching category from the list above."
1440
+ },
1441
+ detail: {
1442
+ type: "string",
1443
+ description: "One sentence of factual context: what happened and why it matters. Do not include PII or secrets."
1444
+ }
1445
+ },
1446
+ required: ["category", "detail"]
1447
+ };
1448
+ const parameters = asVercelSchema(schema);
1449
+ let inputSchema = parameters;
1450
+ if (ctx.jsonSchemaFactory) {
1451
+ try {
1452
+ inputSchema = ctx.jsonSchemaFactory(schema);
1453
+ } catch (e) {
1454
+ inputSchema = parameters;
1455
+ }
1456
+ }
1457
+ const execute = async (rawInput) => {
1458
+ var _a;
1459
+ const input = isRecord(rawInput) ? rawInput : void 0;
1460
+ const fallbackCategory = (_a = config.signalKeys[0]) != null ? _a : "unknown";
1461
+ const categoryCandidate = typeof (input == null ? void 0 : input["category"]) === "string" ? input["category"].trim() : void 0;
1462
+ const category = categoryCandidate && config.signalKeySet.has(categoryCandidate) ? categoryCandidate : fallbackCategory;
1463
+ const detail = typeof (input == null ? void 0 : input["detail"]) === "string" ? input["detail"].trim() : "";
1464
+ const signalDescription = config.signalDescriptions[category];
1465
+ const signalSentiment = config.signalSentiments[category];
1466
+ if (category === AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY) {
1467
+ void ctx.eventShipper.trackSignal({
1468
+ eventId: ctx.eventId,
1469
+ name: "agent:noteworthy",
1470
+ type: "agent_internal",
1471
+ properties: {
1472
+ source: "agent_flag_event_tool",
1473
+ reason: detail,
1474
+ severity: "medium",
1475
+ ai_sdk_version: ctx.aiSDKVersion
1476
+ }
1477
+ }).catch((err) => {
1478
+ if (ctx.debug) {
1479
+ const msg = err instanceof Error ? err.message : String(err);
1480
+ console.warn(`[raindrop-ai/ai-sdk] agentFlagEvent signal dispatch failed: ${msg}`);
1481
+ }
1482
+ });
1483
+ return { acknowledged: true, category };
1484
+ }
1485
+ void ctx.eventShipper.trackSignal({
1486
+ eventId: ctx.eventId,
1487
+ name: `agent:${category}`,
1488
+ type: "agent",
1489
+ sentiment: signalSentiment,
1490
+ properties: {
1491
+ source: "agent_reporting_tool",
1492
+ category,
1493
+ signal_description: signalDescription,
1494
+ ai_sdk_version: ctx.aiSDKVersion,
1495
+ ...detail ? { detail } : {}
1496
+ }
1497
+ }).catch((err) => {
1498
+ if (ctx.debug) {
1499
+ const msg = err instanceof Error ? err.message : String(err);
1500
+ console.warn(`[raindrop-ai/ai-sdk] selfDiagnostics signal dispatch failed: ${msg}`);
1501
+ }
1502
+ });
1503
+ return { acknowledged: true, category };
1504
+ };
1505
+ return {
1506
+ description: config.toolDescription,
1507
+ execute,
1508
+ parameters,
1509
+ inputSchema
1510
+ };
1511
+ }
1303
1512
  function getCurrentParentSpanContextSync() {
1304
1513
  return getContextManager().getParentSpanIds();
1305
1514
  }
@@ -1429,7 +1638,18 @@ function teeStreamObjectBaseStream(result) {
1429
1638
  }
1430
1639
  function setupOperation(params) {
1431
1640
  var _a, _b, _c;
1432
- const { operation, arg, inherited, aiSDK, options, traceShipper, sendTraces } = params;
1641
+ const {
1642
+ operation,
1643
+ arg,
1644
+ inherited,
1645
+ aiSDK,
1646
+ options,
1647
+ eventShipper,
1648
+ traceShipper,
1649
+ debug,
1650
+ selfDiagnostics,
1651
+ sendTraces
1652
+ } = params;
1433
1653
  const wrapTimeCtx = resolveContext(options.context, { operation, args: arg });
1434
1654
  const telemetry = extractExperimentalTelemetry(arg);
1435
1655
  const callTimeCtx = extractRaindropMetadata(telemetry == null ? void 0 : telemetry.metadata);
@@ -1468,12 +1688,18 @@ function setupOperation(params) {
1468
1688
  ]
1469
1689
  }) : void 0;
1470
1690
  const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
1691
+ const operationSelfDiagnostics = isObjectOperation(operation) ? void 0 : selfDiagnostics;
1471
1692
  const wrapCtx = {
1472
1693
  eventId,
1473
1694
  telemetry,
1474
1695
  sendTraces,
1696
+ debug,
1697
+ eventShipper,
1475
1698
  traceShipper,
1476
- rootParentForChildren
1699
+ rootParentForChildren,
1700
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
1701
+ selfDiagnostics: operationSelfDiagnostics,
1702
+ aiSDKVersion: detectAISDKVersion(aiSDK)
1477
1703
  };
1478
1704
  const toolCalls = [];
1479
1705
  const argsWithWrappedTools = wrapTools(arg, wrapCtx, toolCalls);
@@ -1543,13 +1769,9 @@ function createFinalize(params) {
1543
1769
  attrInt("ai.usage.reasoningTokens", usage == null ? void 0 : usage.reasoningTokens),
1544
1770
  attrInt("ai.usage.cachedInputTokens", usage == null ? void 0 : usage.cachedInputTokens),
1545
1771
  attrInt("ai.toolCall.count", setup.toolCalls.length),
1546
- ...error ? [
1547
- attrString(
1548
- "error.message",
1549
- error instanceof Error ? error.message : String(error)
1550
- )
1551
- ] : []
1552
- ]
1772
+ ...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
1773
+ ],
1774
+ error
1553
1775
  });
1554
1776
  }
1555
1777
  if (sendEvents) {
@@ -1583,6 +1805,7 @@ function executeStreamingOperation(params) {
1583
1805
  deps,
1584
1806
  sendEvents,
1585
1807
  sendTraces,
1808
+ selfDiagnostics,
1586
1809
  autoAttachmentEnabled,
1587
1810
  debug
1588
1811
  } = params;
@@ -1592,7 +1815,10 @@ function executeStreamingOperation(params) {
1592
1815
  inherited: getCurrentParentSpanContextSync(),
1593
1816
  aiSDK,
1594
1817
  options: deps.options,
1818
+ eventShipper: deps.eventShipper,
1595
1819
  traceShipper: deps.traceShipper,
1820
+ debug,
1821
+ selfDiagnostics,
1596
1822
  sendTraces
1597
1823
  });
1598
1824
  const finalize = createFinalize({
@@ -1637,6 +1863,7 @@ async function executeNonStreamingOperation(params) {
1637
1863
  deps,
1638
1864
  sendEvents,
1639
1865
  sendTraces,
1866
+ selfDiagnostics,
1640
1867
  autoAttachmentEnabled,
1641
1868
  debug
1642
1869
  } = params;
@@ -1647,7 +1874,10 @@ async function executeNonStreamingOperation(params) {
1647
1874
  inherited,
1648
1875
  aiSDK,
1649
1876
  options: deps.options,
1877
+ eventShipper: deps.eventShipper,
1650
1878
  traceShipper: deps.traceShipper,
1879
+ debug,
1880
+ selfDiagnostics,
1651
1881
  sendTraces
1652
1882
  });
1653
1883
  const finalize = createFinalize({
@@ -1690,13 +1920,14 @@ function wrapAISDK(aiSDK, deps) {
1690
1920
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1691
1921
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
1692
1922
  const autoAttachmentEnabled = deps.options.autoAttachment !== false;
1923
+ const selfDiagnostics = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
1693
1924
  const proxyTarget = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
1694
1925
  return new Proxy(proxyTarget, {
1695
1926
  get(target, prop, receiver) {
1696
1927
  const original = Reflect.get(target, prop, receiver);
1697
1928
  if (typeof prop === "string" && agentClasses.has(prop) && isAgentClass(original)) {
1698
1929
  if (debug) console.log(`[raindrop-ai/ai-sdk] Wrapping Agent class: ${prop}`);
1699
- return wrapAgentClass(original, aiSDK, deps, debug);
1930
+ return wrapAgentClass(original, aiSDK, deps, debug, selfDiagnostics);
1700
1931
  }
1701
1932
  if (typeof prop !== "string" || !instrumentedOps.has(prop) || !isFunction(original)) {
1702
1933
  return original;
@@ -1714,6 +1945,7 @@ function wrapAISDK(aiSDK, deps) {
1714
1945
  deps,
1715
1946
  sendEvents,
1716
1947
  sendTraces,
1948
+ selfDiagnostics,
1717
1949
  autoAttachmentEnabled,
1718
1950
  debug
1719
1951
  });
@@ -1727,6 +1959,7 @@ function wrapAISDK(aiSDK, deps) {
1727
1959
  deps,
1728
1960
  sendEvents,
1729
1961
  sendTraces,
1962
+ selfDiagnostics,
1730
1963
  autoAttachmentEnabled,
1731
1964
  debug
1732
1965
  });
@@ -1734,7 +1967,7 @@ function wrapAISDK(aiSDK, deps) {
1734
1967
  }
1735
1968
  });
1736
1969
  }
1737
- function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1970
+ function wrapAgentClass(AgentClass, aiSDK, deps, debug, selfDiagnostics) {
1738
1971
  return new Proxy(AgentClass, {
1739
1972
  construct(target, args, newTarget) {
1740
1973
  const instance = Reflect.construct(target, args, newTarget);
@@ -1753,7 +1986,8 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1753
1986
  className,
1754
1987
  aiSDK,
1755
1988
  deps,
1756
- debug
1989
+ debug,
1990
+ selfDiagnostics
1757
1991
  );
1758
1992
  }
1759
1993
  if (prop === "stream" && isFunction(original)) {
@@ -1765,7 +1999,8 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1765
1999
  className,
1766
2000
  aiSDK,
1767
2001
  deps,
1768
- debug
2002
+ debug,
2003
+ selfDiagnostics
1769
2004
  );
1770
2005
  }
1771
2006
  return original;
@@ -1774,7 +2009,7 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
1774
2009
  }
1775
2010
  });
1776
2011
  }
1777
- function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK, deps, debug) {
2012
+ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
1778
2013
  var _a, _b;
1779
2014
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1780
2015
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
@@ -1827,8 +2062,13 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1827
2062
  eventId,
1828
2063
  telemetry,
1829
2064
  sendTraces,
2065
+ debug,
2066
+ eventShipper: deps.eventShipper,
1830
2067
  traceShipper: deps.traceShipper,
1831
- rootParentForChildren
2068
+ rootParentForChildren,
2069
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
2070
+ selfDiagnostics,
2071
+ aiSDKVersion: detectAISDKVersion(aiSDK)
1832
2072
  };
1833
2073
  const toolCalls = [];
1834
2074
  const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
@@ -1887,7 +2127,8 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1887
2127
  error instanceof Error ? error.message : String(error)
1888
2128
  )
1889
2129
  ] : []
1890
- ]
2130
+ ],
2131
+ error
1891
2132
  });
1892
2133
  }
1893
2134
  if (sendEvents) {
@@ -1962,7 +2203,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
1962
2203
  }
1963
2204
  };
1964
2205
  }
1965
- function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps, debug) {
2206
+ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
1966
2207
  var _a, _b;
1967
2208
  const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
1968
2209
  const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
@@ -2015,8 +2256,13 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
2015
2256
  eventId,
2016
2257
  telemetry,
2017
2258
  sendTraces,
2259
+ debug,
2260
+ eventShipper: deps.eventShipper,
2018
2261
  traceShipper: deps.traceShipper,
2019
- rootParentForChildren
2262
+ rootParentForChildren,
2263
+ jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
2264
+ selfDiagnostics,
2265
+ aiSDKVersion: detectAISDKVersion(aiSDK)
2020
2266
  };
2021
2267
  const toolCalls = [];
2022
2268
  const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
@@ -2075,7 +2321,8 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
2075
2321
  error instanceof Error ? error.message : String(error)
2076
2322
  )
2077
2323
  ] : []
2078
- ]
2324
+ ],
2325
+ error
2079
2326
  });
2080
2327
  }
2081
2328
  if (sendEvents) {
@@ -2156,8 +2403,22 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
2156
2403
  };
2157
2404
  }
2158
2405
  function wrapTools(args, ctx, toolCalls) {
2159
- if (!isRecord(args) || !("tools" in args) || !isRecord(args["tools"])) return args;
2160
- const tools = args["tools"];
2406
+ if (!isRecord(args)) return args;
2407
+ const tools = isRecord(args["tools"]) ? { ...args["tools"] } : {};
2408
+ if (ctx.selfDiagnostics) {
2409
+ const reportToolName = ctx.selfDiagnostics.toolName;
2410
+ if (!(reportToolName in tools)) {
2411
+ const reportTool = createSelfDiagnosticsTool(ctx);
2412
+ if (reportTool !== void 0) {
2413
+ tools[reportToolName] = reportTool;
2414
+ }
2415
+ } else if (ctx.debug) {
2416
+ console.warn(
2417
+ `[raindrop-ai/ai-sdk] selfDiagnostics skipped: tool name collision for "${reportToolName}"`
2418
+ );
2419
+ }
2420
+ }
2421
+ if (Object.keys(tools).length === 0) return args;
2161
2422
  const wrapped = {};
2162
2423
  for (const [name, tool] of Object.entries(tools)) {
2163
2424
  wrapped[name] = wrapToolExecute(name, tool, ctx, toolCalls);
@@ -2194,7 +2455,8 @@ function wrapToolExecute(name, tool, ctx, toolCalls) {
2194
2455
  ctx.traceShipper.endSpan(span, {
2195
2456
  attributes: [
2196
2457
  attrString("error.message", error instanceof Error ? error.message : String(error))
2197
- ]
2458
+ ],
2459
+ error
2198
2460
  });
2199
2461
  } else {
2200
2462
  ctx.traceShipper.endSpan(span, {
@@ -2307,7 +2569,8 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
2307
2569
  "error.message",
2308
2570
  error instanceof Error ? error.message : String(error)
2309
2571
  )
2310
- ]
2572
+ ],
2573
+ error
2311
2574
  });
2312
2575
  throw error;
2313
2576
  }
@@ -2341,7 +2604,8 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
2341
2604
  "error.message",
2342
2605
  error instanceof Error ? error.message : String(error)
2343
2606
  )
2344
- ]
2607
+ ],
2608
+ error
2345
2609
  });
2346
2610
  throw error;
2347
2611
  }
@@ -2395,7 +2659,8 @@ function wrapModel(args, aiSDK, outerOperationId, ctx) {
2395
2659
  error instanceof Error ? error.message : String(error)
2396
2660
  )
2397
2661
  ] : []
2398
- ]
2662
+ ],
2663
+ error
2399
2664
  });
2400
2665
  };
2401
2666
  const wrappedStream = new RS({
package/dist/index.d.mts CHANGED
@@ -238,6 +238,38 @@ type AISDKMessage = {
238
238
  * - at the end with appended response messages (assistant/tool, incl tool-call + tool-result parts)
239
239
  */
240
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
+ };
241
273
  type WrapAISDKOptions = {
242
274
  context: RaindropAISDKContext | ((info: {
243
275
  operation: string;
@@ -245,6 +277,7 @@ type WrapAISDKOptions = {
245
277
  }) => RaindropAISDKContext);
246
278
  buildEvent?: EventBuilder;
247
279
  autoAttachment?: boolean;
280
+ selfDiagnostics?: SelfDiagnosticsOptions;
248
281
  send?: {
249
282
  events?: boolean;
250
283
  traces?: boolean;
@@ -281,7 +314,7 @@ type RaindropAISDKClient = {
281
314
  track(signal: {
282
315
  eventId: string;
283
316
  name: "thumbs_up" | "thumbs_down" | string;
284
- type?: "default" | "feedback" | "edit";
317
+ type?: "default" | "feedback" | "edit" | "standard" | "agent" | "agent_internal";
285
318
  sentiment?: "POSITIVE" | "NEGATIVE";
286
319
  timestamp?: string;
287
320
  properties?: Record<string, unknown>;
@@ -295,4 +328,4 @@ type RaindropAISDKClient = {
295
328
  };
296
329
  declare function createRaindropAISDK(opts: RaindropAISDKOptions): RaindropAISDKClient;
297
330
 
298
- 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 WrapAISDKOptions, type WrappedAI, type WrappedAISDK, _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.d.ts CHANGED
@@ -238,6 +238,38 @@ type AISDKMessage = {
238
238
  * - at the end with appended response messages (assistant/tool, incl tool-call + tool-result parts)
239
239
  */
240
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
+ };
241
273
  type WrapAISDKOptions = {
242
274
  context: RaindropAISDKContext | ((info: {
243
275
  operation: string;
@@ -245,6 +277,7 @@ type WrapAISDKOptions = {
245
277
  }) => RaindropAISDKContext);
246
278
  buildEvent?: EventBuilder;
247
279
  autoAttachment?: boolean;
280
+ selfDiagnostics?: SelfDiagnosticsOptions;
248
281
  send?: {
249
282
  events?: boolean;
250
283
  traces?: boolean;
@@ -281,7 +314,7 @@ type RaindropAISDKClient = {
281
314
  track(signal: {
282
315
  eventId: string;
283
316
  name: "thumbs_up" | "thumbs_down" | string;
284
- type?: "default" | "feedback" | "edit";
317
+ type?: "default" | "feedback" | "edit" | "standard" | "agent" | "agent_internal";
285
318
  sentiment?: "POSITIVE" | "NEGATIVE";
286
319
  timestamp?: string;
287
320
  properties?: Record<string, unknown>;
@@ -295,4 +328,4 @@ type RaindropAISDKClient = {
295
328
  };
296
329
  declare function createRaindropAISDK(opts: RaindropAISDKOptions): RaindropAISDKClient;
297
330
 
298
- 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 WrapAISDKOptions, type WrappedAI, type WrappedAISDK, _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 };