@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/{chunk-NFWQZOEK.mjs → chunk-ZVQRZCBO.mjs} +305 -37
- package/dist/index.d.mts +83 -4
- package/dist/index.d.ts +83 -4
- package/dist/index.js +305 -37
- package/dist/index.mjs +1 -1
- package/dist/index.node.d.mts +1 -1
- package/dist/index.node.d.ts +1 -1
- package/dist/index.node.js +305 -37
- package/dist/index.node.mjs +1 -1
- package/dist/index.workers.d.mts +1 -1
- package/dist/index.workers.d.ts +1 -1
- package/dist/index.workers.js +305 -37
- package/dist/index.workers.mjs +1 -1
- package/package.json +5 -1
|
@@ -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.
|
|
87
|
+
version: "0.0.10"};
|
|
88
88
|
|
|
89
89
|
// src/internal/version.ts
|
|
90
90
|
var libraryName = package_default.name;
|
|
@@ -118,13 +118,15 @@ var EventShipper = class {
|
|
|
118
118
|
this.sticky = /* @__PURE__ */ new Map();
|
|
119
119
|
this.timers = /* @__PURE__ */ new Map();
|
|
120
120
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
121
|
-
var _a, _b;
|
|
122
|
-
if (!opts.writeKey)
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
var _a, _b, _c;
|
|
122
|
+
if (opts.enabled && !opts.writeKey) {
|
|
123
|
+
throw new Error("[raindrop-ai/ai-sdk] writeKey is required when events are enabled");
|
|
124
|
+
}
|
|
125
|
+
this.writeKey = (_a = opts.writeKey) != null ? _a : "";
|
|
126
|
+
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
125
127
|
this.enabled = opts.enabled;
|
|
126
128
|
this.debug = opts.debug;
|
|
127
|
-
this.partialFlushMs = (
|
|
129
|
+
this.partialFlushMs = (_c = opts.partialFlushMs) != null ? _c : 1e3;
|
|
128
130
|
this.context = getRuntimeContext();
|
|
129
131
|
}
|
|
130
132
|
isDebugEnabled() {
|
|
@@ -472,16 +474,18 @@ var TraceShipper = class {
|
|
|
472
474
|
constructor(opts) {
|
|
473
475
|
this.queue = [];
|
|
474
476
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
475
|
-
var _a, _b, _c, _d;
|
|
476
|
-
if (!opts.writeKey)
|
|
477
|
-
|
|
478
|
-
|
|
477
|
+
var _a, _b, _c, _d, _e;
|
|
478
|
+
if (opts.enabled && !opts.writeKey) {
|
|
479
|
+
throw new Error("[raindrop-ai/ai-sdk] writeKey is required when traces are enabled");
|
|
480
|
+
}
|
|
481
|
+
this.writeKey = (_a = opts.writeKey) != null ? _a : "";
|
|
482
|
+
this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
|
|
479
483
|
this.enabled = opts.enabled;
|
|
480
484
|
this.debug = opts.debug;
|
|
481
485
|
this.debugSpans = opts.debugSpans === true;
|
|
482
|
-
this.flushIntervalMs = (
|
|
483
|
-
this.maxBatchSize = (
|
|
484
|
-
this.maxQueueSize = (
|
|
486
|
+
this.flushIntervalMs = (_c = opts.flushIntervalMs) != null ? _c : 1e3;
|
|
487
|
+
this.maxBatchSize = (_d = opts.maxBatchSize) != null ? _d : 50;
|
|
488
|
+
this.maxQueueSize = (_e = opts.maxQueueSize) != null ? _e : 5e3;
|
|
485
489
|
}
|
|
486
490
|
isDebugEnabled() {
|
|
487
491
|
return this.debug;
|
|
@@ -1241,6 +1245,23 @@ function attrsFromGenAiRequest(options) {
|
|
|
1241
1245
|
}
|
|
1242
1246
|
|
|
1243
1247
|
// src/internal/wrap/wrapAISDK.ts
|
|
1248
|
+
var AGENT_REPORTING_TOOL_NAME_DEFAULT = "__raindrop_report";
|
|
1249
|
+
var AGENT_REPORTING_SIGNALS_DEFAULT = {
|
|
1250
|
+
tool_failure: {
|
|
1251
|
+
description: "A tool call returned an error, timed out, or produced output that cannot be used to make progress.",
|
|
1252
|
+
sentiment: "NEGATIVE"
|
|
1253
|
+
},
|
|
1254
|
+
stuck_in_loop: {
|
|
1255
|
+
description: "The same approach has been attempted multiple times without meaningful progress.",
|
|
1256
|
+
sentiment: "NEGATIVE"
|
|
1257
|
+
},
|
|
1258
|
+
capability_gap: {
|
|
1259
|
+
description: "The task requires a tool, permission, or capability that is not available to the agent."
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
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.";
|
|
1263
|
+
var AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY = "noteworthy";
|
|
1264
|
+
var AGENT_REPORTING_NOTEWORTHY_DESCRIPTION = "Only when no specific category applies: flag that this turn is noteworthy for developer review.";
|
|
1244
1265
|
var warnedMissingUserId = false;
|
|
1245
1266
|
function warnMissingUserIdOnce() {
|
|
1246
1267
|
if (warnedMissingUserId) return;
|
|
@@ -1252,6 +1273,14 @@ function warnMissingUserIdOnce() {
|
|
|
1252
1273
|
function _resetWarnedMissingUserId() {
|
|
1253
1274
|
warnedMissingUserId = false;
|
|
1254
1275
|
}
|
|
1276
|
+
function extractRaindropCallOptions(options) {
|
|
1277
|
+
if (!isRecord(options)) return {};
|
|
1278
|
+
const em = options["metadata"];
|
|
1279
|
+
if (isRecord(em)) return extractRaindropMetadata(em);
|
|
1280
|
+
const telemetry = extractExperimentalTelemetry(options);
|
|
1281
|
+
if (telemetry == null ? void 0 : telemetry.metadata) return extractRaindropMetadata(telemetry.metadata);
|
|
1282
|
+
return {};
|
|
1283
|
+
}
|
|
1255
1284
|
function extractRaindropMetadata(metadata) {
|
|
1256
1285
|
if (!metadata || typeof metadata !== "object") return {};
|
|
1257
1286
|
const result = {};
|
|
@@ -1288,6 +1317,188 @@ function mergeContexts(wrapTime, callTime) {
|
|
|
1288
1317
|
}
|
|
1289
1318
|
return result;
|
|
1290
1319
|
}
|
|
1320
|
+
function normalizeSelfDiagnosticsSignals(signals) {
|
|
1321
|
+
if (!signals) return AGENT_REPORTING_SIGNALS_DEFAULT;
|
|
1322
|
+
const normalizedEntries = Object.entries(signals).map(([key, value]) => {
|
|
1323
|
+
var _a;
|
|
1324
|
+
const signalKey = key.trim();
|
|
1325
|
+
if (!signalKey || !value || typeof value !== "object") return void 0;
|
|
1326
|
+
const description = (_a = value.description) == null ? void 0 : _a.trim();
|
|
1327
|
+
if (!description) return void 0;
|
|
1328
|
+
const sentiment = value.sentiment;
|
|
1329
|
+
return [
|
|
1330
|
+
signalKey,
|
|
1331
|
+
{
|
|
1332
|
+
description,
|
|
1333
|
+
...sentiment === "POSITIVE" || sentiment === "NEGATIVE" ? { sentiment } : {}
|
|
1334
|
+
}
|
|
1335
|
+
];
|
|
1336
|
+
}).filter(
|
|
1337
|
+
(entry) => entry !== void 0
|
|
1338
|
+
);
|
|
1339
|
+
if (normalizedEntries.length === 0) return AGENT_REPORTING_SIGNALS_DEFAULT;
|
|
1340
|
+
return Object.fromEntries(normalizedEntries);
|
|
1341
|
+
}
|
|
1342
|
+
function normalizeSelfDiagnosticsConfig(options) {
|
|
1343
|
+
var _a, _b, _c;
|
|
1344
|
+
if (!(options == null ? void 0 : options.enabled)) return void 0;
|
|
1345
|
+
const signalDefinitions = normalizeSelfDiagnosticsSignals(options.signals);
|
|
1346
|
+
const configuredSignalKeys = Object.keys(signalDefinitions).filter(
|
|
1347
|
+
(signalKey) => signalKey !== AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY
|
|
1348
|
+
);
|
|
1349
|
+
const signalKeys = [...configuredSignalKeys, AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY];
|
|
1350
|
+
const signalDescriptions = {};
|
|
1351
|
+
const signalSentiments = {};
|
|
1352
|
+
for (const signalKey of signalKeys) {
|
|
1353
|
+
if (signalKey === AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY) {
|
|
1354
|
+
const noteworthyDefinition = signalDefinitions[AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY];
|
|
1355
|
+
signalDescriptions[signalKey] = ((_a = noteworthyDefinition == null ? void 0 : noteworthyDefinition.description) == null ? void 0 : _a.trim()) || AGENT_REPORTING_NOTEWORTHY_DESCRIPTION;
|
|
1356
|
+
signalSentiments[signalKey] = noteworthyDefinition == null ? void 0 : noteworthyDefinition.sentiment;
|
|
1357
|
+
continue;
|
|
1358
|
+
}
|
|
1359
|
+
const def = signalDefinitions[signalKey];
|
|
1360
|
+
if (!def) continue;
|
|
1361
|
+
signalDescriptions[signalKey] = def.description;
|
|
1362
|
+
signalSentiments[signalKey] = def.sentiment;
|
|
1363
|
+
}
|
|
1364
|
+
const customGuidanceText = ((_b = options.guidance) == null ? void 0 : _b.trim()) || "";
|
|
1365
|
+
const toolName = ((_c = options.toolName) == null ? void 0 : _c.trim()) || AGENT_REPORTING_TOOL_NAME_DEFAULT;
|
|
1366
|
+
const signalList = signalKeys.map((signalKey) => {
|
|
1367
|
+
const sentiment = signalSentiments[signalKey];
|
|
1368
|
+
const sentimentTag = sentiment ? ` [${sentiment.toLowerCase()}]` : "";
|
|
1369
|
+
return `- ${signalKey}: ${signalDescriptions[signalKey]}${sentimentTag}`;
|
|
1370
|
+
}).join("\n");
|
|
1371
|
+
const guidanceBlock = customGuidanceText ? `
|
|
1372
|
+
Additional guidance: ${customGuidanceText}
|
|
1373
|
+
` : "";
|
|
1374
|
+
const toolDescription = `${AGENT_REPORTING_TOOL_PREAMBLE}
|
|
1375
|
+
|
|
1376
|
+
When to call:
|
|
1377
|
+
- The user reports something broken, failing, or not working as expected.
|
|
1378
|
+
- The user expresses frustration, anger, or threatens escalation.
|
|
1379
|
+
- You observe a product issue, billing problem, or data concern based on context.
|
|
1380
|
+
- The conversation reveals something unusual worth flagging for developer review.
|
|
1381
|
+
|
|
1382
|
+
Rules:
|
|
1383
|
+
1. Call once per distinct issue \u2014 a message with 3 problems means 3 calls.
|
|
1384
|
+
2. Pick the single best category per issue. Use noteworthy only when no specific category fits.
|
|
1385
|
+
3. Do not fabricate issues. Only report what is evident from the conversation.
|
|
1386
|
+
${guidanceBlock}
|
|
1387
|
+
Categories:
|
|
1388
|
+
${signalList}`;
|
|
1389
|
+
return {
|
|
1390
|
+
toolName,
|
|
1391
|
+
toolDescription,
|
|
1392
|
+
signalKeys,
|
|
1393
|
+
signalKeySet: new Set(signalKeys),
|
|
1394
|
+
signalDescriptions,
|
|
1395
|
+
signalSentiments
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
function resolveJsonSchemaFactory(aiSDK) {
|
|
1399
|
+
if (!isRecord(aiSDK) || !isFunction(aiSDK["jsonSchema"])) return void 0;
|
|
1400
|
+
return aiSDK["jsonSchema"];
|
|
1401
|
+
}
|
|
1402
|
+
function detectAISDKVersion(aiSDK) {
|
|
1403
|
+
if (!isRecord(aiSDK)) return "unknown";
|
|
1404
|
+
if (isFunction(aiSDK["jsonSchema"])) return "6";
|
|
1405
|
+
if (isFunction(aiSDK["tool"])) return "5";
|
|
1406
|
+
return "4";
|
|
1407
|
+
}
|
|
1408
|
+
function asVercelSchema(jsonSchemaObj) {
|
|
1409
|
+
const validatorSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.validator");
|
|
1410
|
+
const schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
|
|
1411
|
+
return {
|
|
1412
|
+
[schemaSymbol]: true,
|
|
1413
|
+
[validatorSymbol]: true,
|
|
1414
|
+
_type: void 0,
|
|
1415
|
+
jsonSchema: jsonSchemaObj,
|
|
1416
|
+
validate: (value) => ({ success: true, value })
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
function createSelfDiagnosticsTool(ctx) {
|
|
1420
|
+
const config = ctx.selfDiagnostics;
|
|
1421
|
+
if (!config) return void 0;
|
|
1422
|
+
const schema = {
|
|
1423
|
+
type: "object",
|
|
1424
|
+
additionalProperties: false,
|
|
1425
|
+
properties: {
|
|
1426
|
+
category: {
|
|
1427
|
+
type: "string",
|
|
1428
|
+
enum: config.signalKeys,
|
|
1429
|
+
description: "The single best-matching category from the list above."
|
|
1430
|
+
},
|
|
1431
|
+
detail: {
|
|
1432
|
+
type: "string",
|
|
1433
|
+
description: "One sentence of factual context: what happened and why it matters. Do not include PII or secrets."
|
|
1434
|
+
}
|
|
1435
|
+
},
|
|
1436
|
+
required: ["category", "detail"]
|
|
1437
|
+
};
|
|
1438
|
+
const parameters = asVercelSchema(schema);
|
|
1439
|
+
let inputSchema = parameters;
|
|
1440
|
+
if (ctx.jsonSchemaFactory) {
|
|
1441
|
+
try {
|
|
1442
|
+
inputSchema = ctx.jsonSchemaFactory(schema);
|
|
1443
|
+
} catch (e) {
|
|
1444
|
+
inputSchema = parameters;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
const execute = async (rawInput) => {
|
|
1448
|
+
var _a;
|
|
1449
|
+
const input = isRecord(rawInput) ? rawInput : void 0;
|
|
1450
|
+
const fallbackCategory = (_a = config.signalKeys[0]) != null ? _a : "unknown";
|
|
1451
|
+
const categoryCandidate = typeof (input == null ? void 0 : input["category"]) === "string" ? input["category"].trim() : void 0;
|
|
1452
|
+
const category = categoryCandidate && config.signalKeySet.has(categoryCandidate) ? categoryCandidate : fallbackCategory;
|
|
1453
|
+
const detail = typeof (input == null ? void 0 : input["detail"]) === "string" ? input["detail"].trim() : "";
|
|
1454
|
+
const signalDescription = config.signalDescriptions[category];
|
|
1455
|
+
const signalSentiment = config.signalSentiments[category];
|
|
1456
|
+
if (category === AGENT_REPORTING_NOTEWORTHY_SIGNAL_KEY) {
|
|
1457
|
+
void ctx.eventShipper.trackSignal({
|
|
1458
|
+
eventId: ctx.eventId,
|
|
1459
|
+
name: "agent:noteworthy",
|
|
1460
|
+
type: "agent_internal",
|
|
1461
|
+
properties: {
|
|
1462
|
+
source: "agent_flag_event_tool",
|
|
1463
|
+
reason: detail,
|
|
1464
|
+
severity: "medium",
|
|
1465
|
+
ai_sdk_version: ctx.aiSDKVersion
|
|
1466
|
+
}
|
|
1467
|
+
}).catch((err) => {
|
|
1468
|
+
if (ctx.debug) {
|
|
1469
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1470
|
+
console.warn(`[raindrop-ai/ai-sdk] agentFlagEvent signal dispatch failed: ${msg}`);
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
return { acknowledged: true, category };
|
|
1474
|
+
}
|
|
1475
|
+
void ctx.eventShipper.trackSignal({
|
|
1476
|
+
eventId: ctx.eventId,
|
|
1477
|
+
name: `agent:${category}`,
|
|
1478
|
+
type: "agent",
|
|
1479
|
+
sentiment: signalSentiment,
|
|
1480
|
+
properties: {
|
|
1481
|
+
source: "agent_reporting_tool",
|
|
1482
|
+
category,
|
|
1483
|
+
signal_description: signalDescription,
|
|
1484
|
+
ai_sdk_version: ctx.aiSDKVersion,
|
|
1485
|
+
...detail ? { detail } : {}
|
|
1486
|
+
}
|
|
1487
|
+
}).catch((err) => {
|
|
1488
|
+
if (ctx.debug) {
|
|
1489
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1490
|
+
console.warn(`[raindrop-ai/ai-sdk] selfDiagnostics signal dispatch failed: ${msg}`);
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
return { acknowledged: true, category };
|
|
1494
|
+
};
|
|
1495
|
+
return {
|
|
1496
|
+
description: config.toolDescription,
|
|
1497
|
+
execute,
|
|
1498
|
+
parameters,
|
|
1499
|
+
inputSchema
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1291
1502
|
function getCurrentParentSpanContextSync() {
|
|
1292
1503
|
return getContextManager().getParentSpanIds();
|
|
1293
1504
|
}
|
|
@@ -1417,7 +1628,18 @@ function teeStreamObjectBaseStream(result) {
|
|
|
1417
1628
|
}
|
|
1418
1629
|
function setupOperation(params) {
|
|
1419
1630
|
var _a, _b, _c;
|
|
1420
|
-
const {
|
|
1631
|
+
const {
|
|
1632
|
+
operation,
|
|
1633
|
+
arg,
|
|
1634
|
+
inherited,
|
|
1635
|
+
aiSDK,
|
|
1636
|
+
options,
|
|
1637
|
+
eventShipper,
|
|
1638
|
+
traceShipper,
|
|
1639
|
+
debug,
|
|
1640
|
+
selfDiagnostics,
|
|
1641
|
+
sendTraces
|
|
1642
|
+
} = params;
|
|
1421
1643
|
const wrapTimeCtx = resolveContext(options.context, { operation, args: arg });
|
|
1422
1644
|
const telemetry = extractExperimentalTelemetry(arg);
|
|
1423
1645
|
const callTimeCtx = extractRaindropMetadata(telemetry == null ? void 0 : telemetry.metadata);
|
|
@@ -1456,12 +1678,18 @@ function setupOperation(params) {
|
|
|
1456
1678
|
]
|
|
1457
1679
|
}) : void 0;
|
|
1458
1680
|
const rootParentForChildren = rootSpan ? { traceIdB64: rootSpan.ids.traceIdB64, spanIdB64: rootSpan.ids.spanIdB64 } : inheritedParent;
|
|
1681
|
+
const operationSelfDiagnostics = isObjectOperation(operation) ? void 0 : selfDiagnostics;
|
|
1459
1682
|
const wrapCtx = {
|
|
1460
1683
|
eventId,
|
|
1461
1684
|
telemetry,
|
|
1462
1685
|
sendTraces,
|
|
1686
|
+
debug,
|
|
1687
|
+
eventShipper,
|
|
1463
1688
|
traceShipper,
|
|
1464
|
-
rootParentForChildren
|
|
1689
|
+
rootParentForChildren,
|
|
1690
|
+
jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
|
|
1691
|
+
selfDiagnostics: operationSelfDiagnostics,
|
|
1692
|
+
aiSDKVersion: detectAISDKVersion(aiSDK)
|
|
1465
1693
|
};
|
|
1466
1694
|
const toolCalls = [];
|
|
1467
1695
|
const argsWithWrappedTools = wrapTools(arg, wrapCtx, toolCalls);
|
|
@@ -1531,12 +1759,7 @@ function createFinalize(params) {
|
|
|
1531
1759
|
attrInt("ai.usage.reasoningTokens", usage == null ? void 0 : usage.reasoningTokens),
|
|
1532
1760
|
attrInt("ai.usage.cachedInputTokens", usage == null ? void 0 : usage.cachedInputTokens),
|
|
1533
1761
|
attrInt("ai.toolCall.count", setup.toolCalls.length),
|
|
1534
|
-
...error ? [
|
|
1535
|
-
attrString(
|
|
1536
|
-
"error.message",
|
|
1537
|
-
error instanceof Error ? error.message : String(error)
|
|
1538
|
-
)
|
|
1539
|
-
] : []
|
|
1762
|
+
...error ? [attrString("error.message", error instanceof Error ? error.message : String(error))] : []
|
|
1540
1763
|
]
|
|
1541
1764
|
});
|
|
1542
1765
|
}
|
|
@@ -1571,6 +1794,7 @@ function executeStreamingOperation(params) {
|
|
|
1571
1794
|
deps,
|
|
1572
1795
|
sendEvents,
|
|
1573
1796
|
sendTraces,
|
|
1797
|
+
selfDiagnostics,
|
|
1574
1798
|
autoAttachmentEnabled,
|
|
1575
1799
|
debug
|
|
1576
1800
|
} = params;
|
|
@@ -1580,7 +1804,10 @@ function executeStreamingOperation(params) {
|
|
|
1580
1804
|
inherited: getCurrentParentSpanContextSync(),
|
|
1581
1805
|
aiSDK,
|
|
1582
1806
|
options: deps.options,
|
|
1807
|
+
eventShipper: deps.eventShipper,
|
|
1583
1808
|
traceShipper: deps.traceShipper,
|
|
1809
|
+
debug,
|
|
1810
|
+
selfDiagnostics,
|
|
1584
1811
|
sendTraces
|
|
1585
1812
|
});
|
|
1586
1813
|
const finalize = createFinalize({
|
|
@@ -1625,6 +1852,7 @@ async function executeNonStreamingOperation(params) {
|
|
|
1625
1852
|
deps,
|
|
1626
1853
|
sendEvents,
|
|
1627
1854
|
sendTraces,
|
|
1855
|
+
selfDiagnostics,
|
|
1628
1856
|
autoAttachmentEnabled,
|
|
1629
1857
|
debug
|
|
1630
1858
|
} = params;
|
|
@@ -1635,7 +1863,10 @@ async function executeNonStreamingOperation(params) {
|
|
|
1635
1863
|
inherited,
|
|
1636
1864
|
aiSDK,
|
|
1637
1865
|
options: deps.options,
|
|
1866
|
+
eventShipper: deps.eventShipper,
|
|
1638
1867
|
traceShipper: deps.traceShipper,
|
|
1868
|
+
debug,
|
|
1869
|
+
selfDiagnostics,
|
|
1639
1870
|
sendTraces
|
|
1640
1871
|
});
|
|
1641
1872
|
const finalize = createFinalize({
|
|
@@ -1678,13 +1909,14 @@ function wrapAISDK(aiSDK, deps) {
|
|
|
1678
1909
|
const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
|
|
1679
1910
|
const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
|
|
1680
1911
|
const autoAttachmentEnabled = deps.options.autoAttachment !== false;
|
|
1912
|
+
const selfDiagnostics = normalizeSelfDiagnosticsConfig(deps.options.selfDiagnostics);
|
|
1681
1913
|
const proxyTarget = isModuleNamespace(aiSDK) ? Object.setPrototypeOf({}, aiSDK) : aiSDK;
|
|
1682
1914
|
return new Proxy(proxyTarget, {
|
|
1683
1915
|
get(target, prop, receiver) {
|
|
1684
1916
|
const original = Reflect.get(target, prop, receiver);
|
|
1685
1917
|
if (typeof prop === "string" && agentClasses.has(prop) && isAgentClass(original)) {
|
|
1686
1918
|
if (debug) console.log(`[raindrop-ai/ai-sdk] Wrapping Agent class: ${prop}`);
|
|
1687
|
-
return wrapAgentClass(original, aiSDK, deps, debug);
|
|
1919
|
+
return wrapAgentClass(original, aiSDK, deps, debug, selfDiagnostics);
|
|
1688
1920
|
}
|
|
1689
1921
|
if (typeof prop !== "string" || !instrumentedOps.has(prop) || !isFunction(original)) {
|
|
1690
1922
|
return original;
|
|
@@ -1702,6 +1934,7 @@ function wrapAISDK(aiSDK, deps) {
|
|
|
1702
1934
|
deps,
|
|
1703
1935
|
sendEvents,
|
|
1704
1936
|
sendTraces,
|
|
1937
|
+
selfDiagnostics,
|
|
1705
1938
|
autoAttachmentEnabled,
|
|
1706
1939
|
debug
|
|
1707
1940
|
});
|
|
@@ -1715,6 +1948,7 @@ function wrapAISDK(aiSDK, deps) {
|
|
|
1715
1948
|
deps,
|
|
1716
1949
|
sendEvents,
|
|
1717
1950
|
sendTraces,
|
|
1951
|
+
selfDiagnostics,
|
|
1718
1952
|
autoAttachmentEnabled,
|
|
1719
1953
|
debug
|
|
1720
1954
|
});
|
|
@@ -1722,7 +1956,7 @@ function wrapAISDK(aiSDK, deps) {
|
|
|
1722
1956
|
}
|
|
1723
1957
|
});
|
|
1724
1958
|
}
|
|
1725
|
-
function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
|
|
1959
|
+
function wrapAgentClass(AgentClass, aiSDK, deps, debug, selfDiagnostics) {
|
|
1726
1960
|
return new Proxy(AgentClass, {
|
|
1727
1961
|
construct(target, args, newTarget) {
|
|
1728
1962
|
const instance = Reflect.construct(target, args, newTarget);
|
|
@@ -1741,7 +1975,8 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
|
|
|
1741
1975
|
className,
|
|
1742
1976
|
aiSDK,
|
|
1743
1977
|
deps,
|
|
1744
|
-
debug
|
|
1978
|
+
debug,
|
|
1979
|
+
selfDiagnostics
|
|
1745
1980
|
);
|
|
1746
1981
|
}
|
|
1747
1982
|
if (prop === "stream" && isFunction(original)) {
|
|
@@ -1753,7 +1988,8 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
|
|
|
1753
1988
|
className,
|
|
1754
1989
|
aiSDK,
|
|
1755
1990
|
deps,
|
|
1756
|
-
debug
|
|
1991
|
+
debug,
|
|
1992
|
+
selfDiagnostics
|
|
1757
1993
|
);
|
|
1758
1994
|
}
|
|
1759
1995
|
return original;
|
|
@@ -1762,7 +1998,7 @@ function wrapAgentClass(AgentClass, aiSDK, deps, debug) {
|
|
|
1762
1998
|
}
|
|
1763
1999
|
});
|
|
1764
2000
|
}
|
|
1765
|
-
function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK, deps, debug) {
|
|
2001
|
+
function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
|
|
1766
2002
|
var _a, _b;
|
|
1767
2003
|
const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
|
|
1768
2004
|
const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
|
|
@@ -1774,7 +2010,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
1774
2010
|
const operation = `${className}.generate`;
|
|
1775
2011
|
const wrapTimeCtx = resolveContext(deps.options.context, { operation, args: mergedArgs });
|
|
1776
2012
|
const telemetry = extractExperimentalTelemetry(mergedArgs);
|
|
1777
|
-
const callTimeCtx =
|
|
2013
|
+
const callTimeCtx = extractRaindropCallOptions(mergedArgs);
|
|
1778
2014
|
const mergedCtx = mergeContexts(wrapTimeCtx, callTimeCtx);
|
|
1779
2015
|
if (!mergedCtx.userId) warnMissingUserIdOnce();
|
|
1780
2016
|
const inherited = await getCurrentParentSpanContext();
|
|
@@ -1815,8 +2051,13 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
1815
2051
|
eventId,
|
|
1816
2052
|
telemetry,
|
|
1817
2053
|
sendTraces,
|
|
2054
|
+
debug,
|
|
2055
|
+
eventShipper: deps.eventShipper,
|
|
1818
2056
|
traceShipper: deps.traceShipper,
|
|
1819
|
-
rootParentForChildren
|
|
2057
|
+
rootParentForChildren,
|
|
2058
|
+
jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
|
|
2059
|
+
selfDiagnostics,
|
|
2060
|
+
aiSDKVersion: detectAISDKVersion(aiSDK)
|
|
1820
2061
|
};
|
|
1821
2062
|
const toolCalls = [];
|
|
1822
2063
|
const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
|
|
@@ -1950,7 +2191,7 @@ function wrapAgentGenerate(generate, instance, agentSettings, className, aiSDK,
|
|
|
1950
2191
|
}
|
|
1951
2192
|
};
|
|
1952
2193
|
}
|
|
1953
|
-
function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps, debug) {
|
|
2194
|
+
function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps, debug, selfDiagnostics) {
|
|
1954
2195
|
var _a, _b;
|
|
1955
2196
|
const sendEvents = ((_a = deps.options.send) == null ? void 0 : _a.events) !== false;
|
|
1956
2197
|
const sendTraces = ((_b = deps.options.send) == null ? void 0 : _b.traces) !== false;
|
|
@@ -1962,7 +2203,7 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
1962
2203
|
const operation = `${className}.stream`;
|
|
1963
2204
|
const wrapTimeCtx = resolveContext(deps.options.context, { operation, args: mergedArgs });
|
|
1964
2205
|
const telemetry = extractExperimentalTelemetry(mergedArgs);
|
|
1965
|
-
const callTimeCtx =
|
|
2206
|
+
const callTimeCtx = extractRaindropCallOptions(mergedArgs);
|
|
1966
2207
|
const mergedCtx = mergeContexts(wrapTimeCtx, callTimeCtx);
|
|
1967
2208
|
if (!mergedCtx.userId) warnMissingUserIdOnce();
|
|
1968
2209
|
const inherited = await getCurrentParentSpanContext();
|
|
@@ -2003,8 +2244,13 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
2003
2244
|
eventId,
|
|
2004
2245
|
telemetry,
|
|
2005
2246
|
sendTraces,
|
|
2247
|
+
debug,
|
|
2248
|
+
eventShipper: deps.eventShipper,
|
|
2006
2249
|
traceShipper: deps.traceShipper,
|
|
2007
|
-
rootParentForChildren
|
|
2250
|
+
rootParentForChildren,
|
|
2251
|
+
jsonSchemaFactory: resolveJsonSchemaFactory(aiSDK),
|
|
2252
|
+
selfDiagnostics,
|
|
2253
|
+
aiSDKVersion: detectAISDKVersion(aiSDK)
|
|
2008
2254
|
};
|
|
2009
2255
|
const toolCalls = [];
|
|
2010
2256
|
const mergedArgsWithWrappedTools = wrapTools(mergedArgs, wrapCtx, toolCalls);
|
|
@@ -2144,8 +2390,22 @@ function wrapAgentStream(stream, instance, agentSettings, className, aiSDK, deps
|
|
|
2144
2390
|
};
|
|
2145
2391
|
}
|
|
2146
2392
|
function wrapTools(args, ctx, toolCalls) {
|
|
2147
|
-
if (!isRecord(args)
|
|
2148
|
-
const tools = args["tools"];
|
|
2393
|
+
if (!isRecord(args)) return args;
|
|
2394
|
+
const tools = isRecord(args["tools"]) ? { ...args["tools"] } : {};
|
|
2395
|
+
if (ctx.selfDiagnostics) {
|
|
2396
|
+
const reportToolName = ctx.selfDiagnostics.toolName;
|
|
2397
|
+
if (!(reportToolName in tools)) {
|
|
2398
|
+
const reportTool = createSelfDiagnosticsTool(ctx);
|
|
2399
|
+
if (reportTool !== void 0) {
|
|
2400
|
+
tools[reportToolName] = reportTool;
|
|
2401
|
+
}
|
|
2402
|
+
} else if (ctx.debug) {
|
|
2403
|
+
console.warn(
|
|
2404
|
+
`[raindrop-ai/ai-sdk] selfDiagnostics skipped: tool name collision for "${reportToolName}"`
|
|
2405
|
+
);
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
if (Object.keys(tools).length === 0) return args;
|
|
2149
2409
|
const wrapped = {};
|
|
2150
2410
|
for (const [name, tool] of Object.entries(tools)) {
|
|
2151
2411
|
wrapped[name] = wrapToolExecute(name, tool, ctx, toolCalls);
|
|
@@ -2632,18 +2892,26 @@ function envDebugEnabled() {
|
|
|
2632
2892
|
}
|
|
2633
2893
|
function createRaindropAISDK(opts) {
|
|
2634
2894
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2635
|
-
const
|
|
2636
|
-
const
|
|
2895
|
+
const writeKey = opts.writeKey;
|
|
2896
|
+
const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
|
|
2897
|
+
const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
|
|
2898
|
+
const eventsEnabled = eventsRequested && !!writeKey;
|
|
2899
|
+
const tracesEnabled = tracesRequested && !!writeKey;
|
|
2637
2900
|
const envDebug = envDebugEnabled();
|
|
2901
|
+
if (!writeKey && (eventsRequested || tracesRequested)) {
|
|
2902
|
+
console.warn(
|
|
2903
|
+
"[raindrop-ai/ai-sdk] writeKey not provided; telemetry shipping is disabled"
|
|
2904
|
+
);
|
|
2905
|
+
}
|
|
2638
2906
|
const eventShipper = new EventShipper({
|
|
2639
|
-
writeKey
|
|
2907
|
+
writeKey,
|
|
2640
2908
|
endpoint: opts.endpoint,
|
|
2641
2909
|
enabled: eventsEnabled,
|
|
2642
2910
|
debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
|
|
2643
2911
|
partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs
|
|
2644
2912
|
});
|
|
2645
2913
|
const traceShipper = new TraceShipper({
|
|
2646
|
-
writeKey
|
|
2914
|
+
writeKey,
|
|
2647
2915
|
endpoint: opts.endpoint,
|
|
2648
2916
|
enabled: tracesEnabled,
|
|
2649
2917
|
debug: ((_e = opts.traces) == null ? void 0 : _e.debug) === true || envDebug,
|
package/dist/index.d.mts
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
|
-
|
|
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 };
|