@raindrop-ai/deep-agents 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -63,7 +63,7 @@ function evalScopeAttributes() {
63
63
  return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
64
64
  }
65
65
 
66
- // ../core/dist/chunk-WJOR6M7H.js
66
+ // ../core/dist/chunk-I6TVJQEC.js
67
67
  var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
68
68
  function state() {
69
69
  const holder = globalThis;
@@ -2050,6 +2050,158 @@ var TraceShipper = class {
2050
2050
  }
2051
2051
  }
2052
2052
  };
2053
+ var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
2054
+ function isRecord(value) {
2055
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2056
+ }
2057
+ var JSON_SCHEMA_KEYS = [
2058
+ "type",
2059
+ "properties",
2060
+ "$schema",
2061
+ "$ref",
2062
+ "anyOf",
2063
+ "oneOf",
2064
+ "allOf",
2065
+ "enum",
2066
+ "const",
2067
+ "items",
2068
+ "additionalProperties",
2069
+ "required"
2070
+ ];
2071
+ function isJsonSchema(value) {
2072
+ if (!isRecord(value)) return false;
2073
+ if (typeof value["~standard"] === "object") return false;
2074
+ if (isRecord(value._def) || isRecord(value._zod)) return false;
2075
+ if (Object.keys(value).length === 0) return true;
2076
+ return JSON_SCHEMA_KEYS.some((key) => key in value);
2077
+ }
2078
+ function toJsonSchema(value, options) {
2079
+ if (value === void 0 || value === null) return void 0;
2080
+ if (isJsonSchema(value)) return value;
2081
+ if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
2082
+ if (isRecord(value) && isJsonSchema(value.json)) return value.json;
2083
+ if (options == null ? void 0 : options.schema) {
2084
+ try {
2085
+ return options.schema(value);
2086
+ } catch (e) {
2087
+ return void 0;
2088
+ }
2089
+ }
2090
+ return void 0;
2091
+ }
2092
+ function pickString(value) {
2093
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2094
+ }
2095
+ function functionTool(name, description, schema, options) {
2096
+ const tool = { type: "function", name };
2097
+ const desc = pickString(description);
2098
+ if (desc !== void 0) tool.description = desc;
2099
+ const inputSchema = toJsonSchema(schema, options);
2100
+ if (inputSchema !== void 0) tool.inputSchema = inputSchema;
2101
+ return tool;
2102
+ }
2103
+ function normalizeToolDeclaration(tool, options, fallbackName) {
2104
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2105
+ if (!isRecord(tool)) return void 0;
2106
+ if (tool.type === "provider-defined" || tool.type === "provider") {
2107
+ const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
2108
+ if (name2 === void 0) return void 0;
2109
+ const declaration = { type: "provider-defined", name: name2 };
2110
+ const id = pickString(tool.id);
2111
+ if (id !== void 0) declaration.id = id;
2112
+ if (isRecord(tool.args)) declaration.args = tool.args;
2113
+ return declaration;
2114
+ }
2115
+ if (isRecord(tool.toolSpec)) {
2116
+ const spec = tool.toolSpec;
2117
+ const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
2118
+ if (name2 === void 0) return void 0;
2119
+ return functionTool(name2, spec.description, spec.inputSchema, options);
2120
+ }
2121
+ if (isRecord(tool.function)) {
2122
+ const fn = tool.function;
2123
+ const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
2124
+ if (name2 === void 0) return void 0;
2125
+ return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
2126
+ }
2127
+ const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
2128
+ if (name === void 0) return void 0;
2129
+ const type = pickString(tool.type);
2130
+ if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
2131
+ if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
2132
+ return { type: "provider-defined", id: type, name };
2133
+ }
2134
+ }
2135
+ return functionTool(
2136
+ name,
2137
+ tool.description,
2138
+ (_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
2139
+ options
2140
+ );
2141
+ }
2142
+ var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
2143
+ function isGeminiToolGroup(tool) {
2144
+ if (Array.isArray(tool.functionDeclarations)) return true;
2145
+ const keys = Object.keys(tool);
2146
+ if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
2147
+ return keys.every((key) => isRecord(tool[key]));
2148
+ }
2149
+ function expandGeminiTool(tool, options) {
2150
+ const declarations = [];
2151
+ for (const [key, value] of Object.entries(tool)) {
2152
+ if (key === "functionDeclarations" && Array.isArray(value)) {
2153
+ for (const declaration of value) {
2154
+ const normalized = normalizeToolDeclaration(declaration, options);
2155
+ if (normalized) declarations.push(normalized);
2156
+ }
2157
+ } else if (isRecord(value)) {
2158
+ declarations.push({ type: "provider-defined", id: key, name: key, args: value });
2159
+ }
2160
+ }
2161
+ return declarations;
2162
+ }
2163
+ function normalizeToolDeclarations(tools, options) {
2164
+ if (tools === void 0 || tools === null) return void 0;
2165
+ if (Array.isArray(tools)) {
2166
+ return tools.flatMap((tool) => {
2167
+ if (isRecord(tool) && isGeminiToolGroup(tool)) {
2168
+ return expandGeminiTool(tool, options);
2169
+ }
2170
+ const declaration = normalizeToolDeclaration(tool, options);
2171
+ return declaration ? [declaration] : [];
2172
+ });
2173
+ }
2174
+ if (!isRecord(tools)) return void 0;
2175
+ return Object.entries(tools).flatMap(([key, tool]) => {
2176
+ const declaration = normalizeToolDeclaration(tool, options, key);
2177
+ return declaration ? [declaration] : [];
2178
+ });
2179
+ }
2180
+ function resolvePromptTools(args) {
2181
+ var _a;
2182
+ if (args.override !== void 0) {
2183
+ return (_a = normalizeToolDeclarations(args.override, args.options)) != null ? _a : [];
2184
+ }
2185
+ return normalizeToolDeclarations(args.inferred, args.options);
2186
+ }
2187
+ function promptToolsAttribute(tools) {
2188
+ const values = promptToolsAttributeValue(tools);
2189
+ if (values === void 0) return void 0;
2190
+ return {
2191
+ key: PROMPT_TOOLS_ATTRIBUTE,
2192
+ value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
2193
+ };
2194
+ }
2195
+ function promptToolsAttributeValue(tools) {
2196
+ if (tools === void 0) return void 0;
2197
+ return tools.map((tool) => {
2198
+ try {
2199
+ return JSON.stringify(tool);
2200
+ } catch (e) {
2201
+ return JSON.stringify({ type: tool.type, name: tool.name });
2202
+ }
2203
+ });
2204
+ }
2053
2205
 
2054
2206
  // ../core/dist/index.node.js
2055
2207
  import { AsyncLocalStorage } from "async_hooks";
@@ -2225,7 +2377,475 @@ function installTracingSuppressionHook() {
2225
2377
  }
2226
2378
  installTracingSuppressionHook();
2227
2379
 
2380
+ // src/conversation.ts
2381
+ import {
2382
+ isAIMessage,
2383
+ isBaseMessage,
2384
+ isChatMessage,
2385
+ isToolMessage
2386
+ } from "@langchain/core/messages";
2387
+
2388
+ // src/truncation.ts
2389
+ var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
2390
+ var DEFAULT_MAX_TEXT_FIELD_CHARS2 = 1e6;
2391
+ var MAX_DEPTH = 12;
2392
+ var configuredMaxTextFieldChars;
2393
+ function setMaxTextFieldChars(limit) {
2394
+ if (limit === void 0) return;
2395
+ if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
2396
+ configuredMaxTextFieldChars = Math.floor(limit);
2397
+ } else {
2398
+ console.warn(`[raindrop-ai] maxTextFieldChars=${String(limit)} ignored; must be > 0`);
2399
+ }
2400
+ }
2401
+ function otelEnvLimit() {
2402
+ if (typeof process === "undefined") return void 0;
2403
+ const raw = process.env?.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
2404
+ if (!raw) return void 0;
2405
+ const parsed = Number.parseInt(raw, 10);
2406
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
2407
+ }
2408
+ function eventMaxTextFieldChars() {
2409
+ return configuredMaxTextFieldChars ?? DEFAULT_MAX_TEXT_FIELD_CHARS2;
2410
+ }
2411
+ function spanAttributeLimit(limit) {
2412
+ const env = otelEnvLimit();
2413
+ return env !== void 0 && env < limit ? env : limit;
2414
+ }
2415
+ function effectiveMaxTextFieldChars() {
2416
+ return spanAttributeLimit(eventMaxTextFieldChars());
2417
+ }
2418
+ function truncateToLimit2(text, limit) {
2419
+ if (limit > TRUNCATION_MARKER2.length) {
2420
+ return text.slice(0, limit - TRUNCATION_MARKER2.length) + TRUNCATION_MARKER2;
2421
+ }
2422
+ return text.slice(0, limit);
2423
+ }
2424
+ function capText2(value, limit) {
2425
+ if (typeof value !== "string") return value;
2426
+ const max = limit ?? effectiveMaxTextFieldChars();
2427
+ if (value.length <= max) return value;
2428
+ return truncateToLimit2(value, max);
2429
+ }
2430
+ function boundedClone2(value, budget, depth) {
2431
+ if (budget.remaining <= 0) return TRUNCATION_MARKER2;
2432
+ if (typeof value === "string") {
2433
+ if (value.length > budget.remaining) {
2434
+ const taken = value.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
2435
+ budget.remaining = 0;
2436
+ return taken;
2437
+ }
2438
+ budget.remaining -= Math.max(value.length, 1);
2439
+ return value;
2440
+ }
2441
+ if (value === null || typeof value === "number" || typeof value === "boolean") {
2442
+ budget.remaining -= 8;
2443
+ return value;
2444
+ }
2445
+ if (typeof value === "bigint") return boundedClone2(value.toString(), budget, depth);
2446
+ if (typeof value !== "object") {
2447
+ budget.remaining -= 1;
2448
+ return value;
2449
+ }
2450
+ if (value instanceof Uint8Array) {
2451
+ const maxBytes = Math.max(0, Math.ceil(budget.remaining * 3 / 4));
2452
+ if (value.byteLength > maxBytes) {
2453
+ const taken = base64Encode(value.subarray(0, maxBytes)) + TRUNCATION_MARKER2;
2454
+ budget.remaining = 0;
2455
+ return taken;
2456
+ }
2457
+ const encoded = base64Encode(value);
2458
+ budget.remaining -= Math.max(encoded.length, 1);
2459
+ return encoded;
2460
+ }
2461
+ if (depth >= MAX_DEPTH) {
2462
+ budget.remaining -= 16;
2463
+ const name = value.constructor?.name ?? "object";
2464
+ return `<max depth: ${name}>`;
2465
+ }
2466
+ const toJSON = value.toJSON;
2467
+ if (typeof toJSON === "function") {
2468
+ budget.remaining -= 2;
2469
+ return boundedClone2(toJSON.call(value), budget, depth + 1);
2470
+ }
2471
+ if (Array.isArray(value)) {
2472
+ budget.remaining -= 2;
2473
+ const out2 = [];
2474
+ for (const item of value) {
2475
+ if (budget.remaining <= 0) {
2476
+ out2.push(TRUNCATION_MARKER2);
2477
+ break;
2478
+ }
2479
+ out2.push(boundedClone2(item, budget, depth + 1));
2480
+ }
2481
+ return out2;
2482
+ }
2483
+ budget.remaining -= 2;
2484
+ const out = {};
2485
+ for (const key in value) {
2486
+ if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
2487
+ if (budget.remaining <= 0) {
2488
+ out["..."] = TRUNCATION_MARKER2;
2489
+ break;
2490
+ }
2491
+ let cappedKey = key;
2492
+ if (key.length > budget.remaining) {
2493
+ cappedKey = key.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
2494
+ budget.remaining = 0;
2495
+ out[cappedKey] = TRUNCATION_MARKER2;
2496
+ break;
2497
+ }
2498
+ budget.remaining -= Math.max(key.length, 1);
2499
+ out[cappedKey] = boundedClone2(value[key], budget, depth + 1);
2500
+ }
2501
+ return out;
2502
+ }
2503
+ function boundedStringify(value, limit) {
2504
+ const max = limit ?? effectiveMaxTextFieldChars();
2505
+ try {
2506
+ if (typeof value === "string") {
2507
+ const text2 = JSON.stringify(capText2(value, max));
2508
+ return text2.length <= max ? text2 : truncateToLimit2(text2, max);
2509
+ }
2510
+ const pruned = boundedClone2(value, { remaining: max + TRUNCATION_MARKER2.length + 256 }, 0);
2511
+ const text = JSON.stringify(pruned);
2512
+ if (text === void 0) return void 0;
2513
+ return text.length <= max ? text : truncateToLimit2(text, max);
2514
+ } catch {
2515
+ return void 0;
2516
+ }
2517
+ }
2518
+
2519
+ // src/conversation.ts
2520
+ var CAPTURE_TRUNCATED_ROLE = "raindrop";
2521
+ var MESSAGE_OVERHEAD = 32;
2522
+ var PART_OVERHEAD = 24;
2523
+ var MAX_DEPTH2 = 12;
2524
+ function isRecord2(value) {
2525
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2526
+ }
2527
+ function stringField(record, key) {
2528
+ const value = record[key];
2529
+ return typeof value === "string" ? value : void 0;
2530
+ }
2531
+ function takeText(text, budget) {
2532
+ if (text.length > budget.remaining) {
2533
+ const kept = text.slice(0, Math.max(0, budget.remaining)) + TRUNCATION_MARKER2;
2534
+ budget.remaining = 0;
2535
+ budget.truncated = true;
2536
+ return kept;
2537
+ }
2538
+ budget.remaining -= Math.max(text.length, 1);
2539
+ return text;
2540
+ }
2541
+ function reserve(text, budget) {
2542
+ if (text !== void 0) budget.remaining -= Math.max(text.length, 1);
2543
+ return text;
2544
+ }
2545
+ function takeValue(value, budget, depth) {
2546
+ if (typeof value === "string") return takeText(value, budget);
2547
+ if (value === null || typeof value === "number" || typeof value === "boolean") {
2548
+ budget.remaining -= 8;
2549
+ return value;
2550
+ }
2551
+ if (typeof value !== "object") {
2552
+ budget.remaining -= 1;
2553
+ return value;
2554
+ }
2555
+ if (depth >= MAX_DEPTH2) {
2556
+ budget.remaining -= TRUNCATION_MARKER2.length;
2557
+ budget.truncated = true;
2558
+ return TRUNCATION_MARKER2;
2559
+ }
2560
+ if ("toJSON" in value && typeof value.toJSON === "function") {
2561
+ return takeValue(value.toJSON(), budget, depth + 1);
2562
+ }
2563
+ if (Array.isArray(value)) {
2564
+ budget.remaining -= 2;
2565
+ const out2 = [];
2566
+ for (const item of value) {
2567
+ if (budget.remaining <= 0) {
2568
+ budget.truncated = true;
2569
+ out2.push(TRUNCATION_MARKER2);
2570
+ break;
2571
+ }
2572
+ out2.push(takeValue(item, budget, depth + 1));
2573
+ }
2574
+ return out2;
2575
+ }
2576
+ budget.remaining -= 2;
2577
+ const out = {};
2578
+ if (!isRecord2(value)) return out;
2579
+ for (const key in value) {
2580
+ if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
2581
+ if (budget.remaining <= 0) {
2582
+ budget.truncated = true;
2583
+ out["..."] = TRUNCATION_MARKER2;
2584
+ break;
2585
+ }
2586
+ budget.remaining -= Math.max(key.length, 1);
2587
+ out[key] = takeValue(value[key], budget, depth + 1);
2588
+ }
2589
+ return out;
2590
+ }
2591
+ function messageType(message) {
2592
+ return typeof message._getType === "function" ? message._getType() : void 0;
2593
+ }
2594
+ function textPart(text, budget) {
2595
+ return { type: "text", text: takeText(text, budget) };
2596
+ }
2597
+ function joinedText(content, budget) {
2598
+ const texts = [];
2599
+ for (const block of content) {
2600
+ if (budget.remaining <= 0) {
2601
+ budget.truncated = true;
2602
+ texts.push(TRUNCATION_MARKER2);
2603
+ break;
2604
+ }
2605
+ budget.remaining -= 1;
2606
+ if (!isRecord2(block)) continue;
2607
+ const text = stringField(block, "text");
2608
+ if (text !== void 0) texts.push(takeText(text, budget));
2609
+ }
2610
+ return texts.join("\n");
2611
+ }
2612
+ function contentPart(block, budget) {
2613
+ budget.remaining -= PART_OVERHEAD;
2614
+ if (!isRecord2(block)) return takeValue(block, budget, 0);
2615
+ const type = stringField(block, "type");
2616
+ const text = stringField(block, "text");
2617
+ if (type === "text" && text !== void 0) return textPart(text, budget);
2618
+ if (type === "image_url") {
2619
+ const imageUrl = block["image_url"];
2620
+ const url = typeof imageUrl === "string" ? imageUrl : isRecord2(imageUrl) ? stringField(imageUrl, "url") : void 0;
2621
+ if (url !== void 0) return { type: "image", image: takeText(url, budget) };
2622
+ }
2623
+ if (type === "thinking") {
2624
+ const thinking = stringField(block, "thinking");
2625
+ if (thinking !== void 0) return { type: "reasoning", text: takeText(thinking, budget) };
2626
+ }
2627
+ if (type === "image" || type === "file" || type === "audio") {
2628
+ const mediaType = stringField(block, "mime_type");
2629
+ const sourceType = stringField(block, "source_type");
2630
+ const source = block["source"];
2631
+ if (sourceType === "text" && text !== void 0) return textPart(text, budget);
2632
+ const data = sourceType === "url" ? stringField(block, "url") : sourceType === "base64" ? stringField(block, "data") : isRecord2(source) ? stringField(source, "url") ?? stringField(source, "data") : void 0;
2633
+ const sourceMediaType = mediaType ?? (isRecord2(source) ? stringField(source, "media_type") : void 0);
2634
+ if (data !== void 0) {
2635
+ const filename = stringField(block, "filename");
2636
+ return type === "image" ? { type: "image", image: takeText(data, budget), mediaType: reserve(sourceMediaType, budget) } : {
2637
+ type: "file",
2638
+ data: takeText(data, budget),
2639
+ mediaType: reserve(sourceMediaType, budget),
2640
+ filename: reserve(filename, budget)
2641
+ };
2642
+ }
2643
+ }
2644
+ return takeValue(block, budget, 0);
2645
+ }
2646
+ function contentParts(content, budget, skipToolUseIds) {
2647
+ const parts = [];
2648
+ for (const block of content) {
2649
+ if (budget.remaining <= 0) {
2650
+ budget.truncated = true;
2651
+ parts.push({ type: "text", text: TRUNCATION_MARKER2 });
2652
+ break;
2653
+ }
2654
+ if (isRecord2(block) && (block["type"] === "tool_use" || block["type"] === "tool_call")) {
2655
+ const id = stringField(block, "id");
2656
+ if (id !== void 0 && skipToolUseIds.has(id)) continue;
2657
+ }
2658
+ parts.push(contentPart(block, budget));
2659
+ }
2660
+ return parts;
2661
+ }
2662
+ function assistantMessage(message, budget, toolNames) {
2663
+ const toolCalls = isAIMessage(message) ? message.tool_calls ?? [] : [];
2664
+ if (toolCalls.length === 0 && typeof message.content === "string") {
2665
+ return { role: "assistant", content: takeText(message.content, budget) };
2666
+ }
2667
+ const ids = /* @__PURE__ */ new Set();
2668
+ const callParts = [];
2669
+ for (const call of toolCalls) {
2670
+ if (budget.remaining <= 0) {
2671
+ budget.truncated = true;
2672
+ callParts.push({ type: "text", text: TRUNCATION_MARKER2 });
2673
+ break;
2674
+ }
2675
+ budget.remaining -= PART_OVERHEAD;
2676
+ if (call.id !== void 0) {
2677
+ ids.add(call.id);
2678
+ toolNames.set(call.id, call.name);
2679
+ }
2680
+ callParts.push({
2681
+ type: "tool-call",
2682
+ toolCallId: reserve(call.id, budget),
2683
+ toolName: reserve(call.name, budget),
2684
+ input: takeValue(call.args, budget, 0)
2685
+ });
2686
+ }
2687
+ const content = typeof message.content === "string" ? message.content.length > 0 ? [textPart(message.content, budget)] : [] : contentParts(message.content, budget, ids);
2688
+ content.push(...callParts);
2689
+ return { role: "assistant", content };
2690
+ }
2691
+ function toolResultOutput(message, budget) {
2692
+ const failed = isToolMessage(message) && message.status === "error";
2693
+ if (typeof message.content === "string") {
2694
+ return { type: failed ? "error-text" : "text", value: takeText(message.content, budget) };
2695
+ }
2696
+ return { type: "content", value: contentParts(message.content, budget, /* @__PURE__ */ new Set()) };
2697
+ }
2698
+ function toolMessage(message, budget, toolNames) {
2699
+ const toolCallId = isToolMessage(message) ? message.tool_call_id : void 0;
2700
+ const toolName = message.name ?? (toolCallId !== void 0 ? toolNames.get(toolCallId) : void 0);
2701
+ budget.remaining -= PART_OVERHEAD;
2702
+ return {
2703
+ role: "tool",
2704
+ content: [{
2705
+ type: "tool-result",
2706
+ toolCallId: reserve(toolCallId, budget),
2707
+ toolName: reserve(toolName, budget),
2708
+ output: toolResultOutput(message, budget)
2709
+ }]
2710
+ };
2711
+ }
2712
+ function modelMessage(message, budget, toolNames) {
2713
+ budget.remaining -= MESSAGE_OVERHEAD;
2714
+ switch (messageType(message)) {
2715
+ case "system":
2716
+ return {
2717
+ role: "system",
2718
+ content: typeof message.content === "string" ? takeText(message.content, budget) : joinedText(message.content, budget)
2719
+ };
2720
+ case "ai":
2721
+ return assistantMessage(message, budget, toolNames);
2722
+ case "tool":
2723
+ case "function":
2724
+ return toolMessage(message, budget, toolNames);
2725
+ case "generic": {
2726
+ const role = isChatMessage(message) ? message.role : void 0;
2727
+ if (role === "assistant" || role === "system") {
2728
+ return {
2729
+ role,
2730
+ content: typeof message.content === "string" ? takeText(message.content, budget) : joinedText(message.content, budget)
2731
+ };
2732
+ }
2733
+ return userMessage(message, budget);
2734
+ }
2735
+ default:
2736
+ return userMessage(message, budget);
2737
+ }
2738
+ }
2739
+ function userMessage(message, budget) {
2740
+ return {
2741
+ role: "user",
2742
+ content: typeof message.content === "string" ? takeText(message.content, budget) : contentParts(message.content, budget, /* @__PURE__ */ new Set())
2743
+ };
2744
+ }
2745
+ function truncationRecord(omittedMessages) {
2746
+ return { role: CAPTURE_TRUNCATED_ROLE, truncated: true, marker: TRUNCATION_MARKER2, omittedMessages };
2747
+ }
2748
+ function encodeWithinLimit(items, limit, overflow, convert) {
2749
+ let textBudget = limit;
2750
+ for (let attempt = 0; attempt < 8 && textBudget >= 64; attempt++) {
2751
+ const budget = { remaining: textBudget, truncated: false };
2752
+ const out = [];
2753
+ let omitted = 0;
2754
+ for (let i = 0; i < items.length; i++) {
2755
+ if (overflow === "omit" && budget.remaining <= 0) {
2756
+ omitted = items.length - i;
2757
+ break;
2758
+ }
2759
+ out.push(convert(items[i], budget));
2760
+ }
2761
+ const truncated = budget.truncated || omitted > 0;
2762
+ if (truncated && overflow === "omit") out.push(truncationRecord(omitted));
2763
+ const json2 = JSON.stringify(out);
2764
+ if (json2.length <= limit) return { json: json2, truncated };
2765
+ const excess = json2.length - limit + 128;
2766
+ textBudget = Math.max(textBudget - excess, Math.floor(textBudget / 2));
2767
+ }
2768
+ if (overflow === "keep") return void 0;
2769
+ const json = JSON.stringify([truncationRecord(items.length)]);
2770
+ return json.length <= limit ? { json, truncated: true } : void 0;
2771
+ }
2772
+ function captureConversation(messages, limit) {
2773
+ if (messages.length === 0) return void 0;
2774
+ try {
2775
+ const toolNames = /* @__PURE__ */ new Map();
2776
+ return encodeWithinLimit(
2777
+ messages,
2778
+ limit,
2779
+ "omit",
2780
+ (message, budget) => modelMessage(message, budget, toolNames)
2781
+ );
2782
+ } catch {
2783
+ return void 0;
2784
+ }
2785
+ }
2786
+ function capturePrompt(prompt, limit) {
2787
+ try {
2788
+ return encodeWithinLimit([prompt], limit, "omit", (text, budget) => {
2789
+ budget.remaining -= MESSAGE_OVERHEAD;
2790
+ return { role: "user", content: takeText(text, budget) };
2791
+ });
2792
+ } catch {
2793
+ return void 0;
2794
+ }
2795
+ }
2796
+ function captureToolCalls(message, limit) {
2797
+ if (!isRecord2(message) || !Array.isArray(message["tool_calls"])) return void 0;
2798
+ const calls = [];
2799
+ let structural = 0;
2800
+ for (const call of message["tool_calls"]) {
2801
+ structural += PART_OVERHEAD;
2802
+ if (isRecord2(call)) {
2803
+ structural += (stringField(call, "id")?.length ?? 0) + (stringField(call, "name")?.length ?? 0);
2804
+ calls.push(call);
2805
+ }
2806
+ if (structural > limit) return void 0;
2807
+ }
2808
+ if (calls.length === 0) return void 0;
2809
+ try {
2810
+ return encodeWithinLimit(calls, limit, "keep", (call, budget) => {
2811
+ budget.remaining -= PART_OVERHEAD;
2812
+ return {
2813
+ toolCallId: reserve(stringField(call, "id"), budget),
2814
+ toolName: reserve(stringField(call, "name"), budget),
2815
+ input: takeValue(call["args"], budget, 0)
2816
+ };
2817
+ });
2818
+ } catch {
2819
+ return void 0;
2820
+ }
2821
+ }
2822
+ function parseToolCallInput(input) {
2823
+ try {
2824
+ const parsed = JSON.parse(input);
2825
+ if (isRecord2(parsed) && parsed["type"] === "tool_call" && "args" in parsed) {
2826
+ return { id: stringField(parsed, "id"), args: JSON.stringify(parsed["args"]) };
2827
+ }
2828
+ } catch {
2829
+ }
2830
+ return { args: input };
2831
+ }
2832
+ function unwrapToolOutput(output) {
2833
+ if (isBaseMessage(output)) {
2834
+ return {
2835
+ content: output.content,
2836
+ toolCallId: isToolMessage(output) ? output.tool_call_id : void 0
2837
+ };
2838
+ }
2839
+ return { content: output };
2840
+ }
2841
+
2228
2842
  // src/callback-handler.ts
2843
+ function inferInvocationTools(extraParams) {
2844
+ const params = extraParams?.invocation_params;
2845
+ if (typeof params !== "object" || params === null) return void 0;
2846
+ const record = { ...params };
2847
+ return record.tools ?? record.functions;
2848
+ }
2229
2849
  function resolveEventId(source) {
2230
2850
  if (typeof source !== "function") return randomUUID();
2231
2851
  try {
@@ -2242,32 +2862,38 @@ function isInternalName(name) {
2242
2862
  if (name.startsWith("__") && name.endsWith("__")) return true;
2243
2863
  return false;
2244
2864
  }
2245
- var CHAIN_TEXT_MAX_LEN = 8192;
2246
- function extractTextFromContent(content) {
2865
+ function extractTextFromContent(content, limit) {
2247
2866
  if (content == null) return void 0;
2248
2867
  if (typeof content === "string") return content;
2249
2868
  if (Array.isArray(content)) {
2250
2869
  const parts = [];
2870
+ let length = 0;
2251
2871
  for (const part of content) {
2872
+ if (length > limit) break;
2873
+ length += 1;
2874
+ let text;
2252
2875
  if (typeof part === "string") {
2253
- parts.push(part);
2876
+ text = part;
2254
2877
  } else if (part && typeof part === "object") {
2255
2878
  const p = part;
2256
2879
  if (typeof p.text === "string") {
2257
- parts.push(p.text);
2880
+ text = p.text;
2258
2881
  } else if (p.type === "text" && typeof p.content === "string") {
2259
- parts.push(p.content);
2882
+ text = p.content;
2260
2883
  }
2261
2884
  }
2885
+ if (text === void 0) continue;
2886
+ parts.push(text.length > limit ? text.slice(0, limit + 1) : text);
2887
+ length += Math.max(text.length, 1);
2262
2888
  }
2263
2889
  if (parts.length > 0) return parts.join("\n");
2264
- return safeStringify(content, CHAIN_TEXT_MAX_LEN);
2890
+ return boundedStringify(content, limit);
2265
2891
  }
2266
2892
  if (typeof content === "object") {
2267
2893
  const c = content;
2268
2894
  if (typeof c.text === "string") return c.text;
2269
2895
  if (typeof c.content === "string") return c.content;
2270
- return safeStringify(content, CHAIN_TEXT_MAX_LEN);
2896
+ return boundedStringify(content, limit);
2271
2897
  }
2272
2898
  return String(content);
2273
2899
  }
@@ -2286,6 +2912,17 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2286
2912
  this.eventName = opts.eventName;
2287
2913
  this.eventIdSource = opts.eventId;
2288
2914
  this.traceChains = opts.traceChains ?? true;
2915
+ this.configuredSpanMaxChars = opts.maxTextFieldChars ?? eventMaxTextFieldChars();
2916
+ this.eventMaxChars = opts.eventMaxTextFieldChars ?? eventMaxTextFieldChars();
2917
+ this.promptTools = opts.tools;
2918
+ }
2919
+ promptToolsAttribute(extraParams) {
2920
+ return promptToolsAttribute(
2921
+ resolvePromptTools({ override: this.promptTools, inferred: inferInvocationTools(extraParams) })
2922
+ );
2923
+ }
2924
+ get spanMaxChars() {
2925
+ return spanAttributeLimit(this.configuredSpanMaxChars);
2289
2926
  }
2290
2927
  getEventId(runId, parentRunId) {
2291
2928
  const rootId = parentRunId ? this.rootRunIds.get(parentRunId) ?? parentRunId : runId;
@@ -2346,18 +2983,27 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2346
2983
  // ---------------------------------------------------------------------------
2347
2984
  // LLM events
2348
2985
  // ---------------------------------------------------------------------------
2349
- async handleLLMStart(llm, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
2986
+ async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName) {
2350
2987
  try {
2351
2988
  if (this.spans.has(runId)) return;
2352
2989
  const eventId = this.getEventId(runId, parentRunId);
2353
2990
  const modelId = getName(llm, runName);
2991
+ const prompt = prompts[0] ?? "";
2354
2992
  const span = this.traceShipper.startSpan({
2355
2993
  name: "llm",
2356
2994
  parent: this.getParent(parentRunId),
2357
2995
  eventId,
2996
+ // `ai.generateText` classifies the span as an LLM generation at ingest
2997
+ // (a bare `llm`/`chat` operationId maps to INTERNAL and is skipped by
2998
+ // the rich-interaction extractor). `ai.prompt.messages` carries the
2999
+ // per-step trajectory so replay can see the history each step ran on.
3000
+ // A batch is a list of independent prompts; the span describes the
3001
+ // first one, whose response `handleLLMEnd` reports (`generations[0][0]`).
2358
3002
  attributes: [
2359
3003
  attrString("ai.model.provider", modelId),
2360
- attrString("ai.operationId", "llm")
3004
+ attrString("ai.operationId", "ai.generateText"),
3005
+ ...promptAttributes(capturePrompt(prompt, this.spanMaxChars)),
3006
+ this.promptToolsAttribute(extraParams)
2361
3007
  ]
2362
3008
  });
2363
3009
  this.spans.set(runId, span);
@@ -2365,36 +3011,44 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2365
3011
  userId: this.userId,
2366
3012
  convoId: this.convoId,
2367
3013
  eventName: this.eventName,
2368
- input: truncate(prompts.join("\n"), CHAIN_TEXT_MAX_LEN),
3014
+ input: capText2(prompt, this.eventMaxChars),
2369
3015
  properties: buildProperties(tags, metadata),
2370
3016
  isPending: true
2371
3017
  });
2372
3018
  } catch {
2373
3019
  }
2374
3020
  }
2375
- async handleChatModelStart(llm, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
3021
+ async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
2376
3022
  try {
2377
3023
  if (this.spans.has(runId)) return;
2378
3024
  const eventId = this.getEventId(runId, parentRunId);
2379
3025
  const modelId = getName(llm, runName);
3026
+ const conversation = messages[0] ?? [];
2380
3027
  const span = this.traceShipper.startSpan({
2381
3028
  name: "llm",
2382
3029
  parent: this.getParent(parentRunId),
2383
3030
  eventId,
3031
+ // See handleLLMStart: the full history (historical tool calls and
3032
+ // their results included) goes on the span; the event `input` below
3033
+ // stays the latest human message. LangChain batches are a list of
3034
+ // independent conversations; the span describes the first one, the
3035
+ // same member `handleLLMEnd` reports the response of
3036
+ // (`generations[0][0]`), so history and response stay paired.
2384
3037
  attributes: [
2385
3038
  attrString("ai.model.provider", modelId),
2386
- attrString("ai.operationId", "chat")
3039
+ attrString("ai.operationId", "ai.generateText"),
3040
+ ...promptAttributes(captureConversation(conversation, this.spanMaxChars)),
3041
+ this.promptToolsAttribute(extraParams)
2387
3042
  ]
2388
3043
  });
2389
3044
  this.spans.set(runId, span);
2390
- const allMessages = messages.flat();
2391
- const userMessages = allMessages.filter((m) => {
3045
+ const userMessages = conversation.filter((m) => {
2392
3046
  const role = m._getType?.() ?? "unknown";
2393
3047
  return role === "human";
2394
3048
  });
2395
- const lastMsg = userMessages.length > 0 ? userMessages[userMessages.length - 1] : allMessages[allMessages.length - 1];
2396
- const extracted = lastMsg ? extractTextFromContent(lastMsg.content) : void 0;
2397
- const inputText = extracted !== void 0 ? truncate(extracted, CHAIN_TEXT_MAX_LEN) : void 0;
3049
+ const lastMsg = userMessages.length > 0 ? userMessages[userMessages.length - 1] : conversation[conversation.length - 1];
3050
+ const extracted = lastMsg ? extractTextFromContent(lastMsg.content, this.eventMaxChars) : void 0;
3051
+ const inputText = capText2(extracted, this.eventMaxChars);
2398
3052
  await this.eventShipper.patch(eventId, {
2399
3053
  userId: this.userId,
2400
3054
  convoId: this.convoId,
@@ -2417,7 +3071,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2417
3071
  await this.finalizeEventIfRoot(runId);
2418
3072
  return;
2419
3073
  }
2420
- const meta = extractLLMMetadata(output);
3074
+ const meta = extractLLMMetadata(output, this.spanMaxChars);
2421
3075
  const {
2422
3076
  model,
2423
3077
  promptTokens,
@@ -2425,11 +3079,17 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2425
3079
  cachedTokens,
2426
3080
  reasoningTokens,
2427
3081
  finishReason,
2428
- outputText
3082
+ outputText,
3083
+ toolCalls
2429
3084
  } = meta;
2430
3085
  this.traceShipper.endSpan(span, {
2431
3086
  attributes: [
2432
3087
  attrString("ai.response.model", model),
3088
+ attrString("ai.response.text", capText2(outputText, this.spanMaxChars)),
3089
+ // Tool calls requested by this step, with the ids the matching
3090
+ // `ai.toolCall` spans and the next step's history carry.
3091
+ attrString("ai.response.toolCalls", toolCalls?.json),
3092
+ attrString("ai.response.toolCalls.truncated", toolCalls?.truncated ? "true" : void 0),
2433
3093
  attrInt("ai.usage.prompt_tokens", promptTokens),
2434
3094
  attrInt("ai.usage.completion_tokens", completionTokens),
2435
3095
  attrInt("ai.usage.cached_tokens", cachedTokens),
@@ -2441,9 +3101,8 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2441
3101
  if (cachedTokens != null) properties["ai.usage.cached_tokens"] = cachedTokens;
2442
3102
  if (reasoningTokens != null) properties["ai.usage.thoughts_tokens"] = reasoningTokens;
2443
3103
  if (finishReason != null) properties["ai.finish_reason"] = finishReason;
2444
- const cappedOutput = outputText !== void 0 ? truncate(outputText, CHAIN_TEXT_MAX_LEN) : void 0;
2445
3104
  await this.finalizeEventIfRoot(runId, {
2446
- output: cappedOutput,
3105
+ output: capText2(outputText, this.eventMaxChars),
2447
3106
  model,
2448
3107
  usage: { promptTokens, completionTokens },
2449
3108
  properties: Object.keys(properties).length > 0 ? properties : void 0
@@ -2539,14 +3198,16 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2539
3198
  try {
2540
3199
  const eventId = this.getEventId(runId, parentRunId);
2541
3200
  const toolName = getName(tool, runName);
3201
+ const toolCall = parseToolCallInput(input);
2542
3202
  const span = this.traceShipper.startSpan({
2543
3203
  name: "tool",
2544
3204
  parent: this.getParent(parentRunId),
2545
3205
  eventId,
2546
3206
  operationId: "ai.toolCall",
2547
3207
  attributes: [
3208
+ attrString("ai.toolCall.id", toolCall.id),
2548
3209
  attrString("ai.toolCall.name", toolName),
2549
- attrString("tool.input", truncate(input, 4096))
3210
+ attrString("ai.toolCall.args", capText2(toolCall.args, this.spanMaxChars))
2550
3211
  ]
2551
3212
  });
2552
3213
  this.spans.set(runId, span);
@@ -2561,9 +3222,14 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2561
3222
  try {
2562
3223
  const span = this.spans.get(runId);
2563
3224
  if (span) {
2564
- const outputStr = typeof output === "string" ? output : safeStringify(output, 4096);
3225
+ const { content, toolCallId } = unwrapToolOutput(output);
3226
+ const result = typeof content === "string" ? capText2(content, this.spanMaxChars) : boundedStringify(content, this.spanMaxChars);
3227
+ const hasId = span.attributes.some((attr) => attr?.key === "ai.toolCall.id");
2565
3228
  this.traceShipper.endSpan(span, {
2566
- attributes: [attrString("tool.output", truncate(outputStr, 4096))]
3229
+ attributes: [
3230
+ attrString("ai.toolCall.id", hasId ? void 0 : toolCallId),
3231
+ attrString("ai.toolCall.result", result)
3232
+ ]
2567
3233
  });
2568
3234
  }
2569
3235
  await this.finalizeEventIfRoot(runId);
@@ -2599,10 +3265,10 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2599
3265
  operationId: "ai.toolCall",
2600
3266
  attributes: [
2601
3267
  attrString("ai.toolCall.name", action.tool),
2602
- attrString("agent.tool_input", truncate(
2603
- typeof action.toolInput === "string" ? action.toolInput : safeStringify(action.toolInput, 4096),
2604
- 4096
2605
- ))
3268
+ attrString(
3269
+ "agent.tool_input",
3270
+ typeof action.toolInput === "string" ? capText2(action.toolInput, this.spanMaxChars) : boundedStringify(action.toolInput, this.spanMaxChars)
3271
+ )
2606
3272
  ]
2607
3273
  });
2608
3274
  this.spans.set(`${runId}:agent_action`, span);
@@ -2635,75 +3301,13 @@ function buildProperties(tags, metadata) {
2635
3301
  if (metadata) Object.assign(props, metadata);
2636
3302
  return props;
2637
3303
  }
2638
- var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
2639
- var MAX_TEXT_FIELD_CHARS = 1e6;
2640
- var MAX_BOUNDED_DEPTH = 12;
2641
- function boundedClone2(value, budget, depth) {
2642
- if (budget.remaining <= 0) return TRUNCATION_MARKER2;
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) + "...";
3304
+ function promptAttributes(capture) {
3305
+ return [
3306
+ attrString("ai.prompt.messages", capture?.json),
3307
+ attrString("ai.prompt.messages.truncated", capture?.truncated ? "true" : void 0)
3308
+ ];
2705
3309
  }
2706
- function extractLLMMetadata(output) {
3310
+ function extractLLMMetadata(output, limit) {
2707
3311
  const gen = output.generations?.[0]?.[0];
2708
3312
  const message = gen?.message;
2709
3313
  const responseMeta = message?.response_metadata;
@@ -2729,7 +3333,7 @@ function extractLLMMetadata(output) {
2729
3333
  outputDetails?.reasoning ?? usage?.reasoning_tokens ?? usage?.thoughts_tokens
2730
3334
  );
2731
3335
  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);
3336
+ const outputText = gen?.text ?? (typeof message?.content === "string" ? message.content : void 0) ?? (message?.content ? extractTextFromContent(message.content, limit) : void 0);
2733
3337
  return {
2734
3338
  model,
2735
3339
  promptTokens,
@@ -2737,7 +3341,8 @@ function extractLLMMetadata(output) {
2737
3341
  cachedTokens,
2738
3342
  reasoningTokens,
2739
3343
  finishReason,
2740
- outputText
3344
+ outputText,
3345
+ toolCalls: captureToolCalls(message, limit)
2741
3346
  };
2742
3347
  }
2743
3348
  function asNumber(val) {
@@ -2749,7 +3354,7 @@ function asNumber(val) {
2749
3354
  // package.json
2750
3355
  var package_default = {
2751
3356
  name: "@raindrop-ai/deep-agents",
2752
- version: "0.1.2",
3357
+ version: "0.1.4",
2753
3358
  description: "Raindrop integration for LangChain Deep Agents",
2754
3359
  main: "dist/index.js",
2755
3360
  module: "dist/index.mjs",
@@ -2822,6 +3427,8 @@ var libraryVersion = package_default.version;
2822
3427
  function createRaindropDeepAgents(opts) {
2823
3428
  const writeKey = opts.writeKey;
2824
3429
  const enabled = !!writeKey;
3430
+ setMaxTextFieldChars(opts.maxTextFieldChars);
3431
+ const maxChars = eventMaxTextFieldChars();
2825
3432
  if (!writeKey) {
2826
3433
  console.warn(
2827
3434
  "[raindrop-ai/deep-agents] writeKey not provided; telemetry shipping is disabled"
@@ -2837,7 +3444,8 @@ function createRaindropDeepAgents(opts) {
2837
3444
  sdkName: "deep-agents",
2838
3445
  libraryName,
2839
3446
  libraryVersion,
2840
- appGitContext
3447
+ appGitContext,
3448
+ maxTextFieldChars: maxChars
2841
3449
  });
2842
3450
  const traceShipper = new TraceShipper2({
2843
3451
  writeKey,
@@ -2848,7 +3456,8 @@ function createRaindropDeepAgents(opts) {
2848
3456
  sdkName: "deep-agents",
2849
3457
  serviceName: "raindrop.deep-agents",
2850
3458
  serviceVersion: libraryVersion,
2851
- appGitContext
3459
+ appGitContext,
3460
+ maxTextFieldChars: maxChars
2852
3461
  });
2853
3462
  const handler = new RaindropDeepAgentsHandler({
2854
3463
  eventShipper,
@@ -2857,7 +3466,10 @@ function createRaindropDeepAgents(opts) {
2857
3466
  convoId: opts.convoId,
2858
3467
  eventName: opts.eventName,
2859
3468
  eventId: opts.eventId,
2860
- traceChains: opts.traceChains
3469
+ traceChains: opts.traceChains,
3470
+ maxTextFieldChars: maxChars,
3471
+ eventMaxTextFieldChars: maxChars,
3472
+ tools: opts.tools
2861
3473
  });
2862
3474
  return {
2863
3475
  handler,
@@ -2904,6 +3516,7 @@ function createRaindropDeepAgents(opts) {
2904
3516
  };
2905
3517
  }
2906
3518
  export {
3519
+ PROMPT_TOOLS_ATTRIBUTE,
2907
3520
  RaindropDeepAgentsHandler,
2908
3521
  createRaindropDeepAgents
2909
3522
  };