@raindrop-ai/deep-agents 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.mts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +540 -100
- package/dist/index.mjs +545 -100
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2225,6 +2225,468 @@ function installTracingSuppressionHook() {
|
|
|
2225
2225
|
}
|
|
2226
2226
|
installTracingSuppressionHook();
|
|
2227
2227
|
|
|
2228
|
+
// src/conversation.ts
|
|
2229
|
+
import {
|
|
2230
|
+
isAIMessage,
|
|
2231
|
+
isBaseMessage,
|
|
2232
|
+
isChatMessage,
|
|
2233
|
+
isToolMessage
|
|
2234
|
+
} from "@langchain/core/messages";
|
|
2235
|
+
|
|
2236
|
+
// src/truncation.ts
|
|
2237
|
+
var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
|
|
2238
|
+
var DEFAULT_MAX_TEXT_FIELD_CHARS2 = 1e6;
|
|
2239
|
+
var MAX_DEPTH = 12;
|
|
2240
|
+
var configuredMaxTextFieldChars;
|
|
2241
|
+
function setMaxTextFieldChars(limit) {
|
|
2242
|
+
if (limit === void 0) return;
|
|
2243
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
|
|
2244
|
+
configuredMaxTextFieldChars = Math.floor(limit);
|
|
2245
|
+
} else {
|
|
2246
|
+
console.warn(`[raindrop-ai] maxTextFieldChars=${String(limit)} ignored; must be > 0`);
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
function otelEnvLimit() {
|
|
2250
|
+
if (typeof process === "undefined") return void 0;
|
|
2251
|
+
const raw = process.env?.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
|
2252
|
+
if (!raw) return void 0;
|
|
2253
|
+
const parsed = Number.parseInt(raw, 10);
|
|
2254
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
2255
|
+
}
|
|
2256
|
+
function eventMaxTextFieldChars() {
|
|
2257
|
+
return configuredMaxTextFieldChars ?? DEFAULT_MAX_TEXT_FIELD_CHARS2;
|
|
2258
|
+
}
|
|
2259
|
+
function spanAttributeLimit(limit) {
|
|
2260
|
+
const env = otelEnvLimit();
|
|
2261
|
+
return env !== void 0 && env < limit ? env : limit;
|
|
2262
|
+
}
|
|
2263
|
+
function effectiveMaxTextFieldChars() {
|
|
2264
|
+
return spanAttributeLimit(eventMaxTextFieldChars());
|
|
2265
|
+
}
|
|
2266
|
+
function truncateToLimit2(text, limit) {
|
|
2267
|
+
if (limit > TRUNCATION_MARKER2.length) {
|
|
2268
|
+
return text.slice(0, limit - TRUNCATION_MARKER2.length) + TRUNCATION_MARKER2;
|
|
2269
|
+
}
|
|
2270
|
+
return text.slice(0, limit);
|
|
2271
|
+
}
|
|
2272
|
+
function capText2(value, limit) {
|
|
2273
|
+
if (typeof value !== "string") return value;
|
|
2274
|
+
const max = limit ?? effectiveMaxTextFieldChars();
|
|
2275
|
+
if (value.length <= max) return value;
|
|
2276
|
+
return truncateToLimit2(value, max);
|
|
2277
|
+
}
|
|
2278
|
+
function boundedClone2(value, budget, depth) {
|
|
2279
|
+
if (budget.remaining <= 0) return TRUNCATION_MARKER2;
|
|
2280
|
+
if (typeof value === "string") {
|
|
2281
|
+
if (value.length > budget.remaining) {
|
|
2282
|
+
const taken = value.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
2283
|
+
budget.remaining = 0;
|
|
2284
|
+
return taken;
|
|
2285
|
+
}
|
|
2286
|
+
budget.remaining -= Math.max(value.length, 1);
|
|
2287
|
+
return value;
|
|
2288
|
+
}
|
|
2289
|
+
if (value === null || typeof value === "number" || typeof value === "boolean") {
|
|
2290
|
+
budget.remaining -= 8;
|
|
2291
|
+
return value;
|
|
2292
|
+
}
|
|
2293
|
+
if (typeof value === "bigint") return boundedClone2(value.toString(), budget, depth);
|
|
2294
|
+
if (typeof value !== "object") {
|
|
2295
|
+
budget.remaining -= 1;
|
|
2296
|
+
return value;
|
|
2297
|
+
}
|
|
2298
|
+
if (value instanceof Uint8Array) {
|
|
2299
|
+
const maxBytes = Math.max(0, Math.ceil(budget.remaining * 3 / 4));
|
|
2300
|
+
if (value.byteLength > maxBytes) {
|
|
2301
|
+
const taken = base64Encode(value.subarray(0, maxBytes)) + TRUNCATION_MARKER2;
|
|
2302
|
+
budget.remaining = 0;
|
|
2303
|
+
return taken;
|
|
2304
|
+
}
|
|
2305
|
+
const encoded = base64Encode(value);
|
|
2306
|
+
budget.remaining -= Math.max(encoded.length, 1);
|
|
2307
|
+
return encoded;
|
|
2308
|
+
}
|
|
2309
|
+
if (depth >= MAX_DEPTH) {
|
|
2310
|
+
budget.remaining -= 16;
|
|
2311
|
+
const name = value.constructor?.name ?? "object";
|
|
2312
|
+
return `<max depth: ${name}>`;
|
|
2313
|
+
}
|
|
2314
|
+
const toJSON = value.toJSON;
|
|
2315
|
+
if (typeof toJSON === "function") {
|
|
2316
|
+
budget.remaining -= 2;
|
|
2317
|
+
return boundedClone2(toJSON.call(value), budget, depth + 1);
|
|
2318
|
+
}
|
|
2319
|
+
if (Array.isArray(value)) {
|
|
2320
|
+
budget.remaining -= 2;
|
|
2321
|
+
const out2 = [];
|
|
2322
|
+
for (const item of value) {
|
|
2323
|
+
if (budget.remaining <= 0) {
|
|
2324
|
+
out2.push(TRUNCATION_MARKER2);
|
|
2325
|
+
break;
|
|
2326
|
+
}
|
|
2327
|
+
out2.push(boundedClone2(item, budget, depth + 1));
|
|
2328
|
+
}
|
|
2329
|
+
return out2;
|
|
2330
|
+
}
|
|
2331
|
+
budget.remaining -= 2;
|
|
2332
|
+
const out = {};
|
|
2333
|
+
for (const key in value) {
|
|
2334
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
2335
|
+
if (budget.remaining <= 0) {
|
|
2336
|
+
out["..."] = TRUNCATION_MARKER2;
|
|
2337
|
+
break;
|
|
2338
|
+
}
|
|
2339
|
+
let cappedKey = key;
|
|
2340
|
+
if (key.length > budget.remaining) {
|
|
2341
|
+
cappedKey = key.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
2342
|
+
budget.remaining = 0;
|
|
2343
|
+
out[cappedKey] = TRUNCATION_MARKER2;
|
|
2344
|
+
break;
|
|
2345
|
+
}
|
|
2346
|
+
budget.remaining -= Math.max(key.length, 1);
|
|
2347
|
+
out[cappedKey] = boundedClone2(value[key], budget, depth + 1);
|
|
2348
|
+
}
|
|
2349
|
+
return out;
|
|
2350
|
+
}
|
|
2351
|
+
function boundedStringify(value, limit) {
|
|
2352
|
+
const max = limit ?? effectiveMaxTextFieldChars();
|
|
2353
|
+
try {
|
|
2354
|
+
if (typeof value === "string") {
|
|
2355
|
+
const text2 = JSON.stringify(capText2(value, max));
|
|
2356
|
+
return text2.length <= max ? text2 : truncateToLimit2(text2, max);
|
|
2357
|
+
}
|
|
2358
|
+
const pruned = boundedClone2(value, { remaining: max + TRUNCATION_MARKER2.length + 256 }, 0);
|
|
2359
|
+
const text = JSON.stringify(pruned);
|
|
2360
|
+
if (text === void 0) return void 0;
|
|
2361
|
+
return text.length <= max ? text : truncateToLimit2(text, max);
|
|
2362
|
+
} catch {
|
|
2363
|
+
return void 0;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
// src/conversation.ts
|
|
2368
|
+
var CAPTURE_TRUNCATED_ROLE = "raindrop";
|
|
2369
|
+
var MESSAGE_OVERHEAD = 32;
|
|
2370
|
+
var PART_OVERHEAD = 24;
|
|
2371
|
+
var MAX_DEPTH2 = 12;
|
|
2372
|
+
function isRecord(value) {
|
|
2373
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2374
|
+
}
|
|
2375
|
+
function stringField(record, key) {
|
|
2376
|
+
const value = record[key];
|
|
2377
|
+
return typeof value === "string" ? value : void 0;
|
|
2378
|
+
}
|
|
2379
|
+
function takeText(text, budget) {
|
|
2380
|
+
if (text.length > budget.remaining) {
|
|
2381
|
+
const kept = text.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
2382
|
+
budget.remaining = 0;
|
|
2383
|
+
budget.truncated = true;
|
|
2384
|
+
return kept;
|
|
2385
|
+
}
|
|
2386
|
+
budget.remaining -= Math.max(text.length, 1);
|
|
2387
|
+
return text;
|
|
2388
|
+
}
|
|
2389
|
+
function reserve(text, budget) {
|
|
2390
|
+
if (text !== void 0) budget.remaining -= Math.max(text.length, 1);
|
|
2391
|
+
return text;
|
|
2392
|
+
}
|
|
2393
|
+
function takeValue(value, budget, depth) {
|
|
2394
|
+
if (typeof value === "string") return takeText(value, budget);
|
|
2395
|
+
if (value === null || typeof value === "number" || typeof value === "boolean") {
|
|
2396
|
+
budget.remaining -= 8;
|
|
2397
|
+
return value;
|
|
2398
|
+
}
|
|
2399
|
+
if (typeof value !== "object") {
|
|
2400
|
+
budget.remaining -= 1;
|
|
2401
|
+
return value;
|
|
2402
|
+
}
|
|
2403
|
+
if (depth >= MAX_DEPTH2) {
|
|
2404
|
+
budget.remaining -= TRUNCATION_MARKER2.length;
|
|
2405
|
+
budget.truncated = true;
|
|
2406
|
+
return TRUNCATION_MARKER2;
|
|
2407
|
+
}
|
|
2408
|
+
if ("toJSON" in value && typeof value.toJSON === "function") {
|
|
2409
|
+
return takeValue(value.toJSON(), budget, depth + 1);
|
|
2410
|
+
}
|
|
2411
|
+
if (Array.isArray(value)) {
|
|
2412
|
+
budget.remaining -= 2;
|
|
2413
|
+
const out2 = [];
|
|
2414
|
+
for (const item of value) {
|
|
2415
|
+
if (budget.remaining <= 0) {
|
|
2416
|
+
budget.truncated = true;
|
|
2417
|
+
out2.push(TRUNCATION_MARKER2);
|
|
2418
|
+
break;
|
|
2419
|
+
}
|
|
2420
|
+
out2.push(takeValue(item, budget, depth + 1));
|
|
2421
|
+
}
|
|
2422
|
+
return out2;
|
|
2423
|
+
}
|
|
2424
|
+
budget.remaining -= 2;
|
|
2425
|
+
const out = {};
|
|
2426
|
+
if (!isRecord(value)) return out;
|
|
2427
|
+
for (const key in value) {
|
|
2428
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
2429
|
+
if (budget.remaining <= 0) {
|
|
2430
|
+
budget.truncated = true;
|
|
2431
|
+
out["..."] = TRUNCATION_MARKER2;
|
|
2432
|
+
break;
|
|
2433
|
+
}
|
|
2434
|
+
budget.remaining -= Math.max(key.length, 1);
|
|
2435
|
+
out[key] = takeValue(value[key], budget, depth + 1);
|
|
2436
|
+
}
|
|
2437
|
+
return out;
|
|
2438
|
+
}
|
|
2439
|
+
function messageType(message) {
|
|
2440
|
+
return typeof message._getType === "function" ? message._getType() : void 0;
|
|
2441
|
+
}
|
|
2442
|
+
function textPart(text, budget) {
|
|
2443
|
+
return { type: "text", text: takeText(text, budget) };
|
|
2444
|
+
}
|
|
2445
|
+
function joinedText(content, budget) {
|
|
2446
|
+
const texts = [];
|
|
2447
|
+
for (const block of content) {
|
|
2448
|
+
if (budget.remaining <= 0) {
|
|
2449
|
+
budget.truncated = true;
|
|
2450
|
+
texts.push(TRUNCATION_MARKER2);
|
|
2451
|
+
break;
|
|
2452
|
+
}
|
|
2453
|
+
budget.remaining -= 1;
|
|
2454
|
+
if (!isRecord(block)) continue;
|
|
2455
|
+
const text = stringField(block, "text");
|
|
2456
|
+
if (text !== void 0) texts.push(takeText(text, budget));
|
|
2457
|
+
}
|
|
2458
|
+
return texts.join("\n");
|
|
2459
|
+
}
|
|
2460
|
+
function contentPart(block, budget) {
|
|
2461
|
+
budget.remaining -= PART_OVERHEAD;
|
|
2462
|
+
if (!isRecord(block)) return takeValue(block, budget, 0);
|
|
2463
|
+
const type = stringField(block, "type");
|
|
2464
|
+
const text = stringField(block, "text");
|
|
2465
|
+
if (type === "text" && text !== void 0) return textPart(text, budget);
|
|
2466
|
+
if (type === "image_url") {
|
|
2467
|
+
const imageUrl = block["image_url"];
|
|
2468
|
+
const url = typeof imageUrl === "string" ? imageUrl : isRecord(imageUrl) ? stringField(imageUrl, "url") : void 0;
|
|
2469
|
+
if (url !== void 0) return { type: "image", image: takeText(url, budget) };
|
|
2470
|
+
}
|
|
2471
|
+
if (type === "thinking") {
|
|
2472
|
+
const thinking = stringField(block, "thinking");
|
|
2473
|
+
if (thinking !== void 0) return { type: "reasoning", text: takeText(thinking, budget) };
|
|
2474
|
+
}
|
|
2475
|
+
if (type === "image" || type === "file" || type === "audio") {
|
|
2476
|
+
const mediaType = stringField(block, "mime_type");
|
|
2477
|
+
const sourceType = stringField(block, "source_type");
|
|
2478
|
+
const source = block["source"];
|
|
2479
|
+
if (sourceType === "text" && text !== void 0) return textPart(text, budget);
|
|
2480
|
+
const data = sourceType === "url" ? stringField(block, "url") : sourceType === "base64" ? stringField(block, "data") : isRecord(source) ? stringField(source, "url") ?? stringField(source, "data") : void 0;
|
|
2481
|
+
const sourceMediaType = mediaType ?? (isRecord(source) ? stringField(source, "media_type") : void 0);
|
|
2482
|
+
if (data !== void 0) {
|
|
2483
|
+
const filename = stringField(block, "filename");
|
|
2484
|
+
return type === "image" ? { type: "image", image: takeText(data, budget), mediaType: reserve(sourceMediaType, budget) } : {
|
|
2485
|
+
type: "file",
|
|
2486
|
+
data: takeText(data, budget),
|
|
2487
|
+
mediaType: reserve(sourceMediaType, budget),
|
|
2488
|
+
filename: reserve(filename, budget)
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
return takeValue(block, budget, 0);
|
|
2493
|
+
}
|
|
2494
|
+
function contentParts(content, budget, skipToolUseIds) {
|
|
2495
|
+
const parts = [];
|
|
2496
|
+
for (const block of content) {
|
|
2497
|
+
if (budget.remaining <= 0) {
|
|
2498
|
+
budget.truncated = true;
|
|
2499
|
+
parts.push({ type: "text", text: TRUNCATION_MARKER2 });
|
|
2500
|
+
break;
|
|
2501
|
+
}
|
|
2502
|
+
if (isRecord(block) && (block["type"] === "tool_use" || block["type"] === "tool_call")) {
|
|
2503
|
+
const id = stringField(block, "id");
|
|
2504
|
+
if (id !== void 0 && skipToolUseIds.has(id)) continue;
|
|
2505
|
+
}
|
|
2506
|
+
parts.push(contentPart(block, budget));
|
|
2507
|
+
}
|
|
2508
|
+
return parts;
|
|
2509
|
+
}
|
|
2510
|
+
function assistantMessage(message, budget, toolNames) {
|
|
2511
|
+
const toolCalls = isAIMessage(message) ? message.tool_calls ?? [] : [];
|
|
2512
|
+
if (toolCalls.length === 0 && typeof message.content === "string") {
|
|
2513
|
+
return { role: "assistant", content: takeText(message.content, budget) };
|
|
2514
|
+
}
|
|
2515
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2516
|
+
const callParts = [];
|
|
2517
|
+
for (const call of toolCalls) {
|
|
2518
|
+
if (budget.remaining <= 0) {
|
|
2519
|
+
budget.truncated = true;
|
|
2520
|
+
callParts.push({ type: "text", text: TRUNCATION_MARKER2 });
|
|
2521
|
+
break;
|
|
2522
|
+
}
|
|
2523
|
+
budget.remaining -= PART_OVERHEAD;
|
|
2524
|
+
if (call.id !== void 0) {
|
|
2525
|
+
ids.add(call.id);
|
|
2526
|
+
toolNames.set(call.id, call.name);
|
|
2527
|
+
}
|
|
2528
|
+
callParts.push({
|
|
2529
|
+
type: "tool-call",
|
|
2530
|
+
toolCallId: reserve(call.id, budget),
|
|
2531
|
+
toolName: reserve(call.name, budget),
|
|
2532
|
+
input: takeValue(call.args, budget, 0)
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
const content = typeof message.content === "string" ? message.content.length > 0 ? [textPart(message.content, budget)] : [] : contentParts(message.content, budget, ids);
|
|
2536
|
+
content.push(...callParts);
|
|
2537
|
+
return { role: "assistant", content };
|
|
2538
|
+
}
|
|
2539
|
+
function toolResultOutput(message, budget) {
|
|
2540
|
+
const failed = isToolMessage(message) && message.status === "error";
|
|
2541
|
+
if (typeof message.content === "string") {
|
|
2542
|
+
return { type: failed ? "error-text" : "text", value: takeText(message.content, budget) };
|
|
2543
|
+
}
|
|
2544
|
+
return { type: "content", value: contentParts(message.content, budget, /* @__PURE__ */ new Set()) };
|
|
2545
|
+
}
|
|
2546
|
+
function toolMessage(message, budget, toolNames) {
|
|
2547
|
+
const toolCallId = isToolMessage(message) ? message.tool_call_id : void 0;
|
|
2548
|
+
const toolName = message.name ?? (toolCallId !== void 0 ? toolNames.get(toolCallId) : void 0);
|
|
2549
|
+
budget.remaining -= PART_OVERHEAD;
|
|
2550
|
+
return {
|
|
2551
|
+
role: "tool",
|
|
2552
|
+
content: [{
|
|
2553
|
+
type: "tool-result",
|
|
2554
|
+
toolCallId: reserve(toolCallId, budget),
|
|
2555
|
+
toolName: reserve(toolName, budget),
|
|
2556
|
+
output: toolResultOutput(message, budget)
|
|
2557
|
+
}]
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
function modelMessage(message, budget, toolNames) {
|
|
2561
|
+
budget.remaining -= MESSAGE_OVERHEAD;
|
|
2562
|
+
switch (messageType(message)) {
|
|
2563
|
+
case "system":
|
|
2564
|
+
return {
|
|
2565
|
+
role: "system",
|
|
2566
|
+
content: typeof message.content === "string" ? takeText(message.content, budget) : joinedText(message.content, budget)
|
|
2567
|
+
};
|
|
2568
|
+
case "ai":
|
|
2569
|
+
return assistantMessage(message, budget, toolNames);
|
|
2570
|
+
case "tool":
|
|
2571
|
+
case "function":
|
|
2572
|
+
return toolMessage(message, budget, toolNames);
|
|
2573
|
+
case "generic": {
|
|
2574
|
+
const role = isChatMessage(message) ? message.role : void 0;
|
|
2575
|
+
if (role === "assistant" || role === "system") {
|
|
2576
|
+
return {
|
|
2577
|
+
role,
|
|
2578
|
+
content: typeof message.content === "string" ? takeText(message.content, budget) : joinedText(message.content, budget)
|
|
2579
|
+
};
|
|
2580
|
+
}
|
|
2581
|
+
return userMessage(message, budget);
|
|
2582
|
+
}
|
|
2583
|
+
default:
|
|
2584
|
+
return userMessage(message, budget);
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
function userMessage(message, budget) {
|
|
2588
|
+
return {
|
|
2589
|
+
role: "user",
|
|
2590
|
+
content: typeof message.content === "string" ? takeText(message.content, budget) : contentParts(message.content, budget, /* @__PURE__ */ new Set())
|
|
2591
|
+
};
|
|
2592
|
+
}
|
|
2593
|
+
function truncationRecord(omittedMessages) {
|
|
2594
|
+
return { role: CAPTURE_TRUNCATED_ROLE, truncated: true, marker: TRUNCATION_MARKER2, omittedMessages };
|
|
2595
|
+
}
|
|
2596
|
+
function encodeWithinLimit(items, limit, overflow, convert) {
|
|
2597
|
+
let textBudget = limit;
|
|
2598
|
+
for (let attempt = 0; attempt < 8 && textBudget >= 64; attempt++) {
|
|
2599
|
+
const budget = { remaining: textBudget, truncated: false };
|
|
2600
|
+
const out = [];
|
|
2601
|
+
let omitted = 0;
|
|
2602
|
+
for (let i = 0; i < items.length; i++) {
|
|
2603
|
+
if (overflow === "omit" && budget.remaining <= 0) {
|
|
2604
|
+
omitted = items.length - i;
|
|
2605
|
+
break;
|
|
2606
|
+
}
|
|
2607
|
+
out.push(convert(items[i], budget));
|
|
2608
|
+
}
|
|
2609
|
+
const truncated = budget.truncated || omitted > 0;
|
|
2610
|
+
if (truncated && overflow === "omit") out.push(truncationRecord(omitted));
|
|
2611
|
+
const json2 = JSON.stringify(out);
|
|
2612
|
+
if (json2.length <= limit) return { json: json2, truncated };
|
|
2613
|
+
const excess = json2.length - limit + 128;
|
|
2614
|
+
textBudget = Math.max(textBudget - excess, Math.floor(textBudget / 2));
|
|
2615
|
+
}
|
|
2616
|
+
if (overflow === "keep") return void 0;
|
|
2617
|
+
const json = JSON.stringify([truncationRecord(items.length)]);
|
|
2618
|
+
return json.length <= limit ? { json, truncated: true } : void 0;
|
|
2619
|
+
}
|
|
2620
|
+
function captureConversation(messages, limit) {
|
|
2621
|
+
if (messages.length === 0) return void 0;
|
|
2622
|
+
try {
|
|
2623
|
+
const toolNames = /* @__PURE__ */ new Map();
|
|
2624
|
+
return encodeWithinLimit(
|
|
2625
|
+
messages,
|
|
2626
|
+
limit,
|
|
2627
|
+
"omit",
|
|
2628
|
+
(message, budget) => modelMessage(message, budget, toolNames)
|
|
2629
|
+
);
|
|
2630
|
+
} catch {
|
|
2631
|
+
return void 0;
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
function capturePrompt(prompt, limit) {
|
|
2635
|
+
try {
|
|
2636
|
+
return encodeWithinLimit([prompt], limit, "omit", (text, budget) => {
|
|
2637
|
+
budget.remaining -= MESSAGE_OVERHEAD;
|
|
2638
|
+
return { role: "user", content: takeText(text, budget) };
|
|
2639
|
+
});
|
|
2640
|
+
} catch {
|
|
2641
|
+
return void 0;
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
function captureToolCalls(message, limit) {
|
|
2645
|
+
if (!isRecord(message) || !Array.isArray(message["tool_calls"])) return void 0;
|
|
2646
|
+
const calls = [];
|
|
2647
|
+
let structural = 0;
|
|
2648
|
+
for (const call of message["tool_calls"]) {
|
|
2649
|
+
structural += PART_OVERHEAD;
|
|
2650
|
+
if (isRecord(call)) {
|
|
2651
|
+
structural += (stringField(call, "id")?.length ?? 0) + (stringField(call, "name")?.length ?? 0);
|
|
2652
|
+
calls.push(call);
|
|
2653
|
+
}
|
|
2654
|
+
if (structural > limit) return void 0;
|
|
2655
|
+
}
|
|
2656
|
+
if (calls.length === 0) return void 0;
|
|
2657
|
+
try {
|
|
2658
|
+
return encodeWithinLimit(calls, limit, "keep", (call, budget) => {
|
|
2659
|
+
budget.remaining -= PART_OVERHEAD;
|
|
2660
|
+
return {
|
|
2661
|
+
toolCallId: reserve(stringField(call, "id"), budget),
|
|
2662
|
+
toolName: reserve(stringField(call, "name"), budget),
|
|
2663
|
+
input: takeValue(call["args"], budget, 0)
|
|
2664
|
+
};
|
|
2665
|
+
});
|
|
2666
|
+
} catch {
|
|
2667
|
+
return void 0;
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
function parseToolCallInput(input) {
|
|
2671
|
+
try {
|
|
2672
|
+
const parsed = JSON.parse(input);
|
|
2673
|
+
if (isRecord(parsed) && parsed["type"] === "tool_call" && "args" in parsed) {
|
|
2674
|
+
return { id: stringField(parsed, "id"), args: JSON.stringify(parsed["args"]) };
|
|
2675
|
+
}
|
|
2676
|
+
} catch {
|
|
2677
|
+
}
|
|
2678
|
+
return { args: input };
|
|
2679
|
+
}
|
|
2680
|
+
function unwrapToolOutput(output) {
|
|
2681
|
+
if (isBaseMessage(output)) {
|
|
2682
|
+
return {
|
|
2683
|
+
content: output.content,
|
|
2684
|
+
toolCallId: isToolMessage(output) ? output.tool_call_id : void 0
|
|
2685
|
+
};
|
|
2686
|
+
}
|
|
2687
|
+
return { content: output };
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2228
2690
|
// src/callback-handler.ts
|
|
2229
2691
|
function resolveEventId(source) {
|
|
2230
2692
|
if (typeof source !== "function") return randomUUID();
|
|
@@ -2242,32 +2704,38 @@ function isInternalName(name) {
|
|
|
2242
2704
|
if (name.startsWith("__") && name.endsWith("__")) return true;
|
|
2243
2705
|
return false;
|
|
2244
2706
|
}
|
|
2245
|
-
|
|
2246
|
-
function extractTextFromContent(content) {
|
|
2707
|
+
function extractTextFromContent(content, limit) {
|
|
2247
2708
|
if (content == null) return void 0;
|
|
2248
2709
|
if (typeof content === "string") return content;
|
|
2249
2710
|
if (Array.isArray(content)) {
|
|
2250
2711
|
const parts = [];
|
|
2712
|
+
let length = 0;
|
|
2251
2713
|
for (const part of content) {
|
|
2714
|
+
if (length > limit) break;
|
|
2715
|
+
length += 1;
|
|
2716
|
+
let text;
|
|
2252
2717
|
if (typeof part === "string") {
|
|
2253
|
-
|
|
2718
|
+
text = part;
|
|
2254
2719
|
} else if (part && typeof part === "object") {
|
|
2255
2720
|
const p = part;
|
|
2256
2721
|
if (typeof p.text === "string") {
|
|
2257
|
-
|
|
2722
|
+
text = p.text;
|
|
2258
2723
|
} else if (p.type === "text" && typeof p.content === "string") {
|
|
2259
|
-
|
|
2724
|
+
text = p.content;
|
|
2260
2725
|
}
|
|
2261
2726
|
}
|
|
2727
|
+
if (text === void 0) continue;
|
|
2728
|
+
parts.push(text.length > limit ? text.slice(0, limit + 1) : text);
|
|
2729
|
+
length += Math.max(text.length, 1);
|
|
2262
2730
|
}
|
|
2263
2731
|
if (parts.length > 0) return parts.join("\n");
|
|
2264
|
-
return
|
|
2732
|
+
return boundedStringify(content, limit);
|
|
2265
2733
|
}
|
|
2266
2734
|
if (typeof content === "object") {
|
|
2267
2735
|
const c = content;
|
|
2268
2736
|
if (typeof c.text === "string") return c.text;
|
|
2269
2737
|
if (typeof c.content === "string") return c.content;
|
|
2270
|
-
return
|
|
2738
|
+
return boundedStringify(content, limit);
|
|
2271
2739
|
}
|
|
2272
2740
|
return String(content);
|
|
2273
2741
|
}
|
|
@@ -2286,6 +2754,11 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2286
2754
|
this.eventName = opts.eventName;
|
|
2287
2755
|
this.eventIdSource = opts.eventId;
|
|
2288
2756
|
this.traceChains = opts.traceChains ?? true;
|
|
2757
|
+
this.configuredSpanMaxChars = opts.maxTextFieldChars ?? eventMaxTextFieldChars();
|
|
2758
|
+
this.eventMaxChars = opts.eventMaxTextFieldChars ?? eventMaxTextFieldChars();
|
|
2759
|
+
}
|
|
2760
|
+
get spanMaxChars() {
|
|
2761
|
+
return spanAttributeLimit(this.configuredSpanMaxChars);
|
|
2289
2762
|
}
|
|
2290
2763
|
getEventId(runId, parentRunId) {
|
|
2291
2764
|
const rootId = parentRunId ? this.rootRunIds.get(parentRunId) ?? parentRunId : runId;
|
|
@@ -2351,13 +2824,21 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2351
2824
|
if (this.spans.has(runId)) return;
|
|
2352
2825
|
const eventId = this.getEventId(runId, parentRunId);
|
|
2353
2826
|
const modelId = getName(llm, runName);
|
|
2827
|
+
const prompt = prompts[0] ?? "";
|
|
2354
2828
|
const span = this.traceShipper.startSpan({
|
|
2355
2829
|
name: "llm",
|
|
2356
2830
|
parent: this.getParent(parentRunId),
|
|
2357
2831
|
eventId,
|
|
2832
|
+
// `ai.generateText` classifies the span as an LLM generation at ingest
|
|
2833
|
+
// (a bare `llm`/`chat` operationId maps to INTERNAL and is skipped by
|
|
2834
|
+
// the rich-interaction extractor). `ai.prompt.messages` carries the
|
|
2835
|
+
// per-step trajectory so replay can see the history each step ran on.
|
|
2836
|
+
// A batch is a list of independent prompts; the span describes the
|
|
2837
|
+
// first one, whose response `handleLLMEnd` reports (`generations[0][0]`).
|
|
2358
2838
|
attributes: [
|
|
2359
2839
|
attrString("ai.model.provider", modelId),
|
|
2360
|
-
attrString("ai.operationId", "
|
|
2840
|
+
attrString("ai.operationId", "ai.generateText"),
|
|
2841
|
+
...promptAttributes(capturePrompt(prompt, this.spanMaxChars))
|
|
2361
2842
|
]
|
|
2362
2843
|
});
|
|
2363
2844
|
this.spans.set(runId, span);
|
|
@@ -2365,7 +2846,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2365
2846
|
userId: this.userId,
|
|
2366
2847
|
convoId: this.convoId,
|
|
2367
2848
|
eventName: this.eventName,
|
|
2368
|
-
input:
|
|
2849
|
+
input: capText2(prompt, this.eventMaxChars),
|
|
2369
2850
|
properties: buildProperties(tags, metadata),
|
|
2370
2851
|
isPending: true
|
|
2371
2852
|
});
|
|
@@ -2377,24 +2858,31 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2377
2858
|
if (this.spans.has(runId)) return;
|
|
2378
2859
|
const eventId = this.getEventId(runId, parentRunId);
|
|
2379
2860
|
const modelId = getName(llm, runName);
|
|
2861
|
+
const conversation = messages[0] ?? [];
|
|
2380
2862
|
const span = this.traceShipper.startSpan({
|
|
2381
2863
|
name: "llm",
|
|
2382
2864
|
parent: this.getParent(parentRunId),
|
|
2383
2865
|
eventId,
|
|
2866
|
+
// See handleLLMStart: the full history (historical tool calls and
|
|
2867
|
+
// their results included) goes on the span; the event `input` below
|
|
2868
|
+
// stays the latest human message. LangChain batches are a list of
|
|
2869
|
+
// independent conversations; the span describes the first one, the
|
|
2870
|
+
// same member `handleLLMEnd` reports the response of
|
|
2871
|
+
// (`generations[0][0]`), so history and response stay paired.
|
|
2384
2872
|
attributes: [
|
|
2385
2873
|
attrString("ai.model.provider", modelId),
|
|
2386
|
-
attrString("ai.operationId", "
|
|
2874
|
+
attrString("ai.operationId", "ai.generateText"),
|
|
2875
|
+
...promptAttributes(captureConversation(conversation, this.spanMaxChars))
|
|
2387
2876
|
]
|
|
2388
2877
|
});
|
|
2389
2878
|
this.spans.set(runId, span);
|
|
2390
|
-
const
|
|
2391
|
-
const userMessages = allMessages.filter((m) => {
|
|
2879
|
+
const userMessages = conversation.filter((m) => {
|
|
2392
2880
|
const role = m._getType?.() ?? "unknown";
|
|
2393
2881
|
return role === "human";
|
|
2394
2882
|
});
|
|
2395
|
-
const lastMsg = userMessages.length > 0 ? userMessages[userMessages.length - 1] :
|
|
2396
|
-
const extracted = lastMsg ? extractTextFromContent(lastMsg.content) : void 0;
|
|
2397
|
-
const inputText =
|
|
2883
|
+
const lastMsg = userMessages.length > 0 ? userMessages[userMessages.length - 1] : conversation[conversation.length - 1];
|
|
2884
|
+
const extracted = lastMsg ? extractTextFromContent(lastMsg.content, this.eventMaxChars) : void 0;
|
|
2885
|
+
const inputText = capText2(extracted, this.eventMaxChars);
|
|
2398
2886
|
await this.eventShipper.patch(eventId, {
|
|
2399
2887
|
userId: this.userId,
|
|
2400
2888
|
convoId: this.convoId,
|
|
@@ -2417,7 +2905,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2417
2905
|
await this.finalizeEventIfRoot(runId);
|
|
2418
2906
|
return;
|
|
2419
2907
|
}
|
|
2420
|
-
const meta = extractLLMMetadata(output);
|
|
2908
|
+
const meta = extractLLMMetadata(output, this.spanMaxChars);
|
|
2421
2909
|
const {
|
|
2422
2910
|
model,
|
|
2423
2911
|
promptTokens,
|
|
@@ -2425,11 +2913,17 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2425
2913
|
cachedTokens,
|
|
2426
2914
|
reasoningTokens,
|
|
2427
2915
|
finishReason,
|
|
2428
|
-
outputText
|
|
2916
|
+
outputText,
|
|
2917
|
+
toolCalls
|
|
2429
2918
|
} = meta;
|
|
2430
2919
|
this.traceShipper.endSpan(span, {
|
|
2431
2920
|
attributes: [
|
|
2432
2921
|
attrString("ai.response.model", model),
|
|
2922
|
+
attrString("ai.response.text", capText2(outputText, this.spanMaxChars)),
|
|
2923
|
+
// Tool calls requested by this step, with the ids the matching
|
|
2924
|
+
// `ai.toolCall` spans and the next step's history carry.
|
|
2925
|
+
attrString("ai.response.toolCalls", toolCalls?.json),
|
|
2926
|
+
attrString("ai.response.toolCalls.truncated", toolCalls?.truncated ? "true" : void 0),
|
|
2433
2927
|
attrInt("ai.usage.prompt_tokens", promptTokens),
|
|
2434
2928
|
attrInt("ai.usage.completion_tokens", completionTokens),
|
|
2435
2929
|
attrInt("ai.usage.cached_tokens", cachedTokens),
|
|
@@ -2441,9 +2935,8 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2441
2935
|
if (cachedTokens != null) properties["ai.usage.cached_tokens"] = cachedTokens;
|
|
2442
2936
|
if (reasoningTokens != null) properties["ai.usage.thoughts_tokens"] = reasoningTokens;
|
|
2443
2937
|
if (finishReason != null) properties["ai.finish_reason"] = finishReason;
|
|
2444
|
-
const cappedOutput = outputText !== void 0 ? truncate(outputText, CHAIN_TEXT_MAX_LEN) : void 0;
|
|
2445
2938
|
await this.finalizeEventIfRoot(runId, {
|
|
2446
|
-
output:
|
|
2939
|
+
output: capText2(outputText, this.eventMaxChars),
|
|
2447
2940
|
model,
|
|
2448
2941
|
usage: { promptTokens, completionTokens },
|
|
2449
2942
|
properties: Object.keys(properties).length > 0 ? properties : void 0
|
|
@@ -2539,14 +3032,16 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2539
3032
|
try {
|
|
2540
3033
|
const eventId = this.getEventId(runId, parentRunId);
|
|
2541
3034
|
const toolName = getName(tool, runName);
|
|
3035
|
+
const toolCall = parseToolCallInput(input);
|
|
2542
3036
|
const span = this.traceShipper.startSpan({
|
|
2543
3037
|
name: "tool",
|
|
2544
3038
|
parent: this.getParent(parentRunId),
|
|
2545
3039
|
eventId,
|
|
2546
3040
|
operationId: "ai.toolCall",
|
|
2547
3041
|
attributes: [
|
|
3042
|
+
attrString("ai.toolCall.id", toolCall.id),
|
|
2548
3043
|
attrString("ai.toolCall.name", toolName),
|
|
2549
|
-
attrString("
|
|
3044
|
+
attrString("ai.toolCall.args", capText2(toolCall.args, this.spanMaxChars))
|
|
2550
3045
|
]
|
|
2551
3046
|
});
|
|
2552
3047
|
this.spans.set(runId, span);
|
|
@@ -2561,9 +3056,14 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2561
3056
|
try {
|
|
2562
3057
|
const span = this.spans.get(runId);
|
|
2563
3058
|
if (span) {
|
|
2564
|
-
const
|
|
3059
|
+
const { content, toolCallId } = unwrapToolOutput(output);
|
|
3060
|
+
const result = typeof content === "string" ? capText2(content, this.spanMaxChars) : boundedStringify(content, this.spanMaxChars);
|
|
3061
|
+
const hasId = span.attributes.some((attr) => attr?.key === "ai.toolCall.id");
|
|
2565
3062
|
this.traceShipper.endSpan(span, {
|
|
2566
|
-
attributes: [
|
|
3063
|
+
attributes: [
|
|
3064
|
+
attrString("ai.toolCall.id", hasId ? void 0 : toolCallId),
|
|
3065
|
+
attrString("ai.toolCall.result", result)
|
|
3066
|
+
]
|
|
2567
3067
|
});
|
|
2568
3068
|
}
|
|
2569
3069
|
await this.finalizeEventIfRoot(runId);
|
|
@@ -2599,10 +3099,10 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
|
|
|
2599
3099
|
operationId: "ai.toolCall",
|
|
2600
3100
|
attributes: [
|
|
2601
3101
|
attrString("ai.toolCall.name", action.tool),
|
|
2602
|
-
attrString(
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
)
|
|
3102
|
+
attrString(
|
|
3103
|
+
"agent.tool_input",
|
|
3104
|
+
typeof action.toolInput === "string" ? capText2(action.toolInput, this.spanMaxChars) : boundedStringify(action.toolInput, this.spanMaxChars)
|
|
3105
|
+
)
|
|
2606
3106
|
]
|
|
2607
3107
|
});
|
|
2608
3108
|
this.spans.set(`${runId}:agent_action`, span);
|
|
@@ -2635,75 +3135,13 @@ function buildProperties(tags, metadata) {
|
|
|
2635
3135
|
if (metadata) Object.assign(props, metadata);
|
|
2636
3136
|
return props;
|
|
2637
3137
|
}
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
if (typeof value === "string") {
|
|
2644
|
-
if (value.length > budget.remaining) {
|
|
2645
|
-
const taken = value.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
|
|
2646
|
-
budget.remaining = 0;
|
|
2647
|
-
return taken;
|
|
2648
|
-
}
|
|
2649
|
-
budget.remaining -= Math.max(value.length, 1);
|
|
2650
|
-
return value;
|
|
2651
|
-
}
|
|
2652
|
-
if (value === null || typeof value === "number" || typeof value === "boolean") {
|
|
2653
|
-
budget.remaining -= 8;
|
|
2654
|
-
return value;
|
|
2655
|
-
}
|
|
2656
|
-
if (typeof value !== "object") {
|
|
2657
|
-
budget.remaining -= 8;
|
|
2658
|
-
return value;
|
|
2659
|
-
}
|
|
2660
|
-
if (depth >= MAX_BOUNDED_DEPTH) {
|
|
2661
|
-
budget.remaining -= 16;
|
|
2662
|
-
return `<max depth: ${TRUNCATION_MARKER2}>`;
|
|
2663
|
-
}
|
|
2664
|
-
const withToJson = value;
|
|
2665
|
-
if (typeof withToJson.toJSON === "function") {
|
|
2666
|
-
try {
|
|
2667
|
-
return boundedClone2(withToJson.toJSON(), budget, depth + 1);
|
|
2668
|
-
} catch {
|
|
2669
|
-
}
|
|
2670
|
-
}
|
|
2671
|
-
if (Array.isArray(value)) {
|
|
2672
|
-
const out2 = [];
|
|
2673
|
-
for (const item of value) {
|
|
2674
|
-
if (budget.remaining <= 0) {
|
|
2675
|
-
out2.push(TRUNCATION_MARKER2);
|
|
2676
|
-
break;
|
|
2677
|
-
}
|
|
2678
|
-
out2.push(boundedClone2(item, budget, depth + 1));
|
|
2679
|
-
}
|
|
2680
|
-
return out2;
|
|
2681
|
-
}
|
|
2682
|
-
const out = {};
|
|
2683
|
-
for (const key of Object.keys(value)) {
|
|
2684
|
-
if (budget.remaining <= 0) {
|
|
2685
|
-
out["..."] = TRUNCATION_MARKER2;
|
|
2686
|
-
break;
|
|
2687
|
-
}
|
|
2688
|
-
budget.remaining -= Math.max(key.length, 1);
|
|
2689
|
-
out[key] = boundedClone2(value[key], budget, depth + 1);
|
|
2690
|
-
}
|
|
2691
|
-
return out;
|
|
2692
|
-
}
|
|
2693
|
-
function safeStringify(value, limit = MAX_TEXT_FIELD_CHARS) {
|
|
2694
|
-
try {
|
|
2695
|
-
const pruned = boundedClone2(value, { remaining: limit + TRUNCATION_MARKER2.length + 256 }, 0);
|
|
2696
|
-
return JSON.stringify(pruned) ?? "";
|
|
2697
|
-
} catch {
|
|
2698
|
-
const fallback = String(value);
|
|
2699
|
-
return fallback.length > limit ? fallback.slice(0, limit) : fallback;
|
|
2700
|
-
}
|
|
2701
|
-
}
|
|
2702
|
-
function truncate(str, maxLen) {
|
|
2703
|
-
if (str.length <= maxLen) return str;
|
|
2704
|
-
return str.slice(0, maxLen - 3) + "...";
|
|
3138
|
+
function promptAttributes(capture) {
|
|
3139
|
+
return [
|
|
3140
|
+
attrString("ai.prompt.messages", capture?.json),
|
|
3141
|
+
attrString("ai.prompt.messages.truncated", capture?.truncated ? "true" : void 0)
|
|
3142
|
+
];
|
|
2705
3143
|
}
|
|
2706
|
-
function extractLLMMetadata(output) {
|
|
3144
|
+
function extractLLMMetadata(output, limit) {
|
|
2707
3145
|
const gen = output.generations?.[0]?.[0];
|
|
2708
3146
|
const message = gen?.message;
|
|
2709
3147
|
const responseMeta = message?.response_metadata;
|
|
@@ -2729,7 +3167,7 @@ function extractLLMMetadata(output) {
|
|
|
2729
3167
|
outputDetails?.reasoning ?? usage?.reasoning_tokens ?? usage?.thoughts_tokens
|
|
2730
3168
|
);
|
|
2731
3169
|
const finishReason = generationInfo?.finish_reason ?? responseMeta?.finish_reason ?? responseMeta?.stop_reason;
|
|
2732
|
-
const outputText = gen?.text ?? (typeof message?.content === "string" ? message.content : void 0) ?? (message?.content ? extractTextFromContent(message.content) : void 0);
|
|
3170
|
+
const outputText = gen?.text ?? (typeof message?.content === "string" ? message.content : void 0) ?? (message?.content ? extractTextFromContent(message.content, limit) : void 0);
|
|
2733
3171
|
return {
|
|
2734
3172
|
model,
|
|
2735
3173
|
promptTokens,
|
|
@@ -2737,7 +3175,8 @@ function extractLLMMetadata(output) {
|
|
|
2737
3175
|
cachedTokens,
|
|
2738
3176
|
reasoningTokens,
|
|
2739
3177
|
finishReason,
|
|
2740
|
-
outputText
|
|
3178
|
+
outputText,
|
|
3179
|
+
toolCalls: captureToolCalls(message, limit)
|
|
2741
3180
|
};
|
|
2742
3181
|
}
|
|
2743
3182
|
function asNumber(val) {
|
|
@@ -2749,7 +3188,7 @@ function asNumber(val) {
|
|
|
2749
3188
|
// package.json
|
|
2750
3189
|
var package_default = {
|
|
2751
3190
|
name: "@raindrop-ai/deep-agents",
|
|
2752
|
-
version: "0.1.
|
|
3191
|
+
version: "0.1.3",
|
|
2753
3192
|
description: "Raindrop integration for LangChain Deep Agents",
|
|
2754
3193
|
main: "dist/index.js",
|
|
2755
3194
|
module: "dist/index.mjs",
|
|
@@ -2822,6 +3261,8 @@ var libraryVersion = package_default.version;
|
|
|
2822
3261
|
function createRaindropDeepAgents(opts) {
|
|
2823
3262
|
const writeKey = opts.writeKey;
|
|
2824
3263
|
const enabled = !!writeKey;
|
|
3264
|
+
setMaxTextFieldChars(opts.maxTextFieldChars);
|
|
3265
|
+
const maxChars = eventMaxTextFieldChars();
|
|
2825
3266
|
if (!writeKey) {
|
|
2826
3267
|
console.warn(
|
|
2827
3268
|
"[raindrop-ai/deep-agents] writeKey not provided; telemetry shipping is disabled"
|
|
@@ -2837,7 +3278,8 @@ function createRaindropDeepAgents(opts) {
|
|
|
2837
3278
|
sdkName: "deep-agents",
|
|
2838
3279
|
libraryName,
|
|
2839
3280
|
libraryVersion,
|
|
2840
|
-
appGitContext
|
|
3281
|
+
appGitContext,
|
|
3282
|
+
maxTextFieldChars: maxChars
|
|
2841
3283
|
});
|
|
2842
3284
|
const traceShipper = new TraceShipper2({
|
|
2843
3285
|
writeKey,
|
|
@@ -2848,7 +3290,8 @@ function createRaindropDeepAgents(opts) {
|
|
|
2848
3290
|
sdkName: "deep-agents",
|
|
2849
3291
|
serviceName: "raindrop.deep-agents",
|
|
2850
3292
|
serviceVersion: libraryVersion,
|
|
2851
|
-
appGitContext
|
|
3293
|
+
appGitContext,
|
|
3294
|
+
maxTextFieldChars: maxChars
|
|
2852
3295
|
});
|
|
2853
3296
|
const handler = new RaindropDeepAgentsHandler({
|
|
2854
3297
|
eventShipper,
|
|
@@ -2857,7 +3300,9 @@ function createRaindropDeepAgents(opts) {
|
|
|
2857
3300
|
convoId: opts.convoId,
|
|
2858
3301
|
eventName: opts.eventName,
|
|
2859
3302
|
eventId: opts.eventId,
|
|
2860
|
-
traceChains: opts.traceChains
|
|
3303
|
+
traceChains: opts.traceChains,
|
|
3304
|
+
maxTextFieldChars: maxChars,
|
|
3305
|
+
eventMaxTextFieldChars: maxChars
|
|
2861
3306
|
});
|
|
2862
3307
|
return {
|
|
2863
3308
|
handler,
|