@librechat/agents 3.1.68 → 3.1.71-dev.0
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/cjs/agents/AgentContext.cjs +23 -3
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +16 -1
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +136 -0
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/hooks/HookRegistry.cjs +162 -0
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -0
- package/dist/cjs/hooks/executeHooks.cjs +276 -0
- package/dist/cjs/hooks/executeHooks.cjs.map +1 -0
- package/dist/cjs/hooks/matchers.cjs +256 -0
- package/dist/cjs/hooks/matchers.cjs.map +1 -0
- package/dist/cjs/hooks/types.cjs +27 -0
- package/dist/cjs/hooks/types.cjs.map +1 -0
- package/dist/cjs/main.cjs +57 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +74 -12
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +9 -2
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +115 -0
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +44 -0
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/BashExecutor.cjs +208 -0
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -0
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +287 -0
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -0
- package/dist/cjs/tools/CodeExecutor.cjs +0 -9
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +7 -23
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ReadFile.cjs +43 -0
- package/dist/cjs/tools/ReadFile.cjs.map +1 -0
- package/dist/cjs/tools/SkillTool.cjs +50 -0
- package/dist/cjs/tools/SkillTool.cjs.map +1 -0
- package/dist/cjs/tools/SubagentTool.cjs +92 -0
- package/dist/cjs/tools/SubagentTool.cjs.map +1 -0
- package/dist/cjs/tools/ToolNode.cjs +746 -174
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/ToolSearch.cjs +2 -13
- package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
- package/dist/cjs/tools/skillCatalog.cjs +84 -0
- package/dist/cjs/tools/skillCatalog.cjs.map +1 -0
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +511 -0
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -0
- package/dist/cjs/tools/toolOutputReferences.cjs +475 -0
- package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -0
- package/dist/cjs/utils/truncation.cjs +28 -0
- package/dist/cjs/utils/truncation.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +23 -3
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +15 -2
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +136 -0
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/hooks/HookRegistry.mjs +160 -0
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -0
- package/dist/esm/hooks/executeHooks.mjs +273 -0
- package/dist/esm/hooks/executeHooks.mjs.map +1 -0
- package/dist/esm/hooks/matchers.mjs +251 -0
- package/dist/esm/hooks/matchers.mjs.map +1 -0
- package/dist/esm/hooks/types.mjs +25 -0
- package/dist/esm/hooks/types.mjs.map +1 -0
- package/dist/esm/main.mjs +13 -2
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +66 -4
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +9 -2
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +115 -0
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +44 -0
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/BashExecutor.mjs +200 -0
- package/dist/esm/tools/BashExecutor.mjs.map +1 -0
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +278 -0
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -0
- package/dist/esm/tools/CodeExecutor.mjs +0 -9
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +8 -24
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ReadFile.mjs +38 -0
- package/dist/esm/tools/ReadFile.mjs.map +1 -0
- package/dist/esm/tools/SkillTool.mjs +45 -0
- package/dist/esm/tools/SkillTool.mjs.map +1 -0
- package/dist/esm/tools/SubagentTool.mjs +85 -0
- package/dist/esm/tools/SubagentTool.mjs.map +1 -0
- package/dist/esm/tools/ToolNode.mjs +748 -176
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/ToolSearch.mjs +3 -14
- package/dist/esm/tools/ToolSearch.mjs.map +1 -1
- package/dist/esm/tools/skillCatalog.mjs +82 -0
- package/dist/esm/tools/skillCatalog.mjs.map +1 -0
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +505 -0
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -0
- package/dist/esm/tools/toolOutputReferences.mjs +468 -0
- package/dist/esm/tools/toolOutputReferences.mjs.map +1 -0
- package/dist/esm/utils/truncation.mjs +27 -1
- package/dist/esm/utils/truncation.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +6 -0
- package/dist/types/common/enum.d.ts +10 -2
- package/dist/types/graphs/Graph.d.ts +23 -0
- package/dist/types/hooks/HookRegistry.d.ts +56 -0
- package/dist/types/hooks/executeHooks.d.ts +79 -0
- package/dist/types/hooks/index.d.ts +6 -0
- package/dist/types/hooks/matchers.d.ts +95 -0
- package/dist/types/hooks/types.d.ts +320 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/messages/format.d.ts +2 -1
- package/dist/types/run.d.ts +2 -0
- package/dist/types/summarization/node.d.ts +2 -0
- package/dist/types/tools/BashExecutor.d.ts +76 -0
- package/dist/types/tools/BashProgrammaticToolCalling.d.ts +72 -0
- package/dist/types/tools/ProgrammaticToolCalling.d.ts +4 -9
- package/dist/types/tools/ReadFile.d.ts +28 -0
- package/dist/types/tools/SkillTool.d.ts +40 -0
- package/dist/types/tools/SubagentTool.d.ts +36 -0
- package/dist/types/tools/ToolNode.d.ts +109 -4
- package/dist/types/tools/ToolSearch.d.ts +2 -2
- package/dist/types/tools/skillCatalog.d.ts +19 -0
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +137 -0
- package/dist/types/tools/subagent/index.d.ts +2 -0
- package/dist/types/tools/toolOutputReferences.d.ts +205 -0
- package/dist/types/types/graph.d.ts +61 -2
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/run.d.ts +28 -0
- package/dist/types/types/skill.d.ts +9 -0
- package/dist/types/types/tools.d.ts +108 -10
- package/dist/types/utils/truncation.d.ts +21 -0
- package/package.json +5 -1
- package/src/agents/AgentContext.ts +26 -2
- package/src/common/enum.ts +15 -1
- package/src/graphs/Graph.ts +161 -0
- package/src/hooks/HookRegistry.ts +208 -0
- package/src/hooks/__tests__/HookRegistry.test.ts +190 -0
- package/src/hooks/__tests__/compactHooks.test.ts +214 -0
- package/src/hooks/__tests__/executeHooks.test.ts +1013 -0
- package/src/hooks/__tests__/integration.test.ts +337 -0
- package/src/hooks/__tests__/matchers.test.ts +238 -0
- package/src/hooks/__tests__/toolHooks.test.ts +669 -0
- package/src/hooks/executeHooks.ts +375 -0
- package/src/hooks/index.ts +57 -0
- package/src/hooks/matchers.ts +280 -0
- package/src/hooks/types.ts +404 -0
- package/src/index.ts +10 -0
- package/src/messages/format.ts +74 -4
- package/src/messages/formatAgentMessages.skills.test.ts +334 -0
- package/src/messages/prune.ts +9 -2
- package/src/run.ts +130 -0
- package/src/scripts/multi-agent-subagent.ts +246 -0
- package/src/scripts/programmatic_exec.ts +1 -10
- package/src/scripts/subagent-event-driven-debug.ts +190 -0
- package/src/scripts/subagent-tools-debug.ts +160 -0
- package/src/scripts/test_code_api.ts +0 -7
- package/src/scripts/tool_search.ts +1 -10
- package/src/specs/prune.test.ts +413 -0
- package/src/specs/subagent.test.ts +305 -0
- package/src/summarization/node.ts +53 -0
- package/src/tools/BashExecutor.ts +238 -0
- package/src/tools/BashProgrammaticToolCalling.ts +381 -0
- package/src/tools/CodeExecutor.ts +0 -11
- package/src/tools/ProgrammaticToolCalling.ts +4 -29
- package/src/tools/ReadFile.ts +39 -0
- package/src/tools/SkillTool.ts +46 -0
- package/src/tools/SubagentTool.ts +100 -0
- package/src/tools/ToolNode.ts +999 -214
- package/src/tools/ToolSearch.ts +3 -19
- package/src/tools/__tests__/BashExecutor.test.ts +36 -0
- package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.ts +7 -8
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +0 -1
- package/src/tools/__tests__/ReadFile.test.ts +44 -0
- package/src/tools/__tests__/SkillTool.test.ts +442 -0
- package/src/tools/__tests__/SubagentExecutor.test.ts +1148 -0
- package/src/tools/__tests__/SubagentTool.test.ts +149 -0
- package/src/tools/__tests__/ToolNode.outputReferences.test.ts +1395 -0
- package/src/tools/__tests__/ToolNode.session.test.ts +12 -12
- package/src/tools/__tests__/ToolSearch.integration.test.ts +7 -8
- package/src/tools/__tests__/skillCatalog.test.ts +161 -0
- package/src/tools/__tests__/subagentHooks.test.ts +215 -0
- package/src/tools/__tests__/toolOutputReferences.test.ts +415 -0
- package/src/tools/skillCatalog.ts +126 -0
- package/src/tools/subagent/SubagentExecutor.ts +676 -0
- package/src/tools/subagent/index.ts +13 -0
- package/src/tools/toolOutputReferences.ts +590 -0
- package/src/types/graph.ts +80 -1
- package/src/types/index.ts +1 -0
- package/src/types/run.ts +28 -0
- package/src/types/skill.ts +11 -0
- package/src/types/tools.ts +112 -10
- package/src/utils/__tests__/truncation.test.ts +66 -0
- package/src/utils/truncation.ts +30 -0
package/src/types/run.ts
CHANGED
|
@@ -11,6 +11,8 @@ import type * as s from '@/types/stream';
|
|
|
11
11
|
import type * as e from '@/common/enum';
|
|
12
12
|
import type * as g from '@/types/graph';
|
|
13
13
|
import type * as l from '@/types/llm';
|
|
14
|
+
import type { ToolSessionMap, ToolOutputReferencesConfig } from '@/types/tools';
|
|
15
|
+
import type { HookRegistry } from '@/hooks';
|
|
14
16
|
|
|
15
17
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
18
|
export type ZodObjectAny = z.ZodObject<any, any, any, any>;
|
|
@@ -112,6 +114,18 @@ export type RunConfig = {
|
|
|
112
114
|
runId: string;
|
|
113
115
|
graphConfig: LegacyGraphConfig | StandardGraphConfig | MultiAgentGraphConfig;
|
|
114
116
|
customHandlers?: Record<string, g.EventHandler>;
|
|
117
|
+
/**
|
|
118
|
+
* Pre-constructed hook registry for this run. Hooks fire at lifecycle
|
|
119
|
+
* points in `processStream` (RunStart, UserPromptSubmit, Stop,
|
|
120
|
+
* StopFailure) and around tool calls (PreToolUse, PostToolUse,
|
|
121
|
+
* PostToolUseFailure, PermissionDenied).
|
|
122
|
+
*
|
|
123
|
+
* Pass `undefined` (the default) to skip all hook dispatch. When a
|
|
124
|
+
* registry is provided, the run attaches it to the `Graph` so internal
|
|
125
|
+
* nodes can fire hooks too, and clears the session in the `finally`
|
|
126
|
+
* block to prevent leaks.
|
|
127
|
+
*/
|
|
128
|
+
hooks?: HookRegistry;
|
|
115
129
|
returnContent?: boolean;
|
|
116
130
|
tokenCounter?: TokenCounter;
|
|
117
131
|
indexTokenCountMap?: Record<string, number>;
|
|
@@ -126,6 +140,20 @@ export type RunConfig = {
|
|
|
126
140
|
calibrationRatio?: number;
|
|
127
141
|
/** Skip post-stream cleanup (clearHeavyState) — useful for tests that inspect graph state after processStream */
|
|
128
142
|
skipCleanup?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Initial session state to seed the Graph's ToolSessionMap.
|
|
145
|
+
* Used to carry over code environment sessions from skill file priming
|
|
146
|
+
* at run start, so ToolNode can inject session_id + files into tool calls.
|
|
147
|
+
*/
|
|
148
|
+
initialSessions?: ToolSessionMap;
|
|
149
|
+
/**
|
|
150
|
+
* Run-scoped tool output reference configuration. When `enabled` is
|
|
151
|
+
* `true`, tool outputs are registered under stable keys
|
|
152
|
+
* (`tool<idx>turn<turn>`) and subsequent tool calls can pipe previous
|
|
153
|
+
* outputs into their arguments via `{{tool<idx>turn<turn>}}`
|
|
154
|
+
* placeholders. Disabled by default so existing runs are unaffected.
|
|
155
|
+
*/
|
|
156
|
+
toolOutputReferences?: ToolOutputReferencesConfig;
|
|
129
157
|
};
|
|
130
158
|
|
|
131
159
|
export type ProvidedCallbacks =
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/types/skill.ts
|
|
2
|
+
|
|
3
|
+
/** Minimal skill metadata for catalog assembly. The host provides these from its own data layer. */
|
|
4
|
+
export type SkillCatalogEntry = {
|
|
5
|
+
/** Kebab-case identifier (what the model passes to SkillTool) */
|
|
6
|
+
name: string;
|
|
7
|
+
/** One-line description for the catalog listing */
|
|
8
|
+
description: string;
|
|
9
|
+
/** Optional human-readable label (UI only, not shown to model) */
|
|
10
|
+
displayTitle?: string;
|
|
11
|
+
};
|
package/src/types/tools.ts
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import type { StructuredToolInterface } from '@langchain/core/tools';
|
|
3
3
|
import type { RunnableToolLike } from '@langchain/core/runnables';
|
|
4
4
|
import type { ToolCall } from '@langchain/core/messages/tool';
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
5
|
+
import type { HookRegistry } from '@/hooks';
|
|
6
|
+
import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
|
|
7
|
+
import type { MessageContentComplex, ToolErrorData } from './stream';
|
|
7
8
|
|
|
8
9
|
/** Replacement type for `import type { ToolCall } from '@langchain/core/messages/tool'` in order to have stringified args typed */
|
|
9
10
|
export type CustomToolCall = {
|
|
@@ -49,6 +50,12 @@ export type ToolNodeOptions = {
|
|
|
49
50
|
agentId?: string;
|
|
50
51
|
/** Tool names that must be executed directly (via runTool) even in event-driven mode (e.g., graph-managed handoff tools) */
|
|
51
52
|
directToolNames?: Set<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Hook registry for PreToolUse/PostToolUse lifecycle hooks.
|
|
55
|
+
* Only fires for event-driven tool calls (`dispatchToolEvents`). Tools
|
|
56
|
+
* routed through `directToolNames` bypass hook dispatch entirely.
|
|
57
|
+
*/
|
|
58
|
+
hookRegistry?: HookRegistry;
|
|
52
59
|
/** Max context tokens for the agent — used to compute tool result truncation limits. */
|
|
53
60
|
maxContextTokens?: number;
|
|
54
61
|
/**
|
|
@@ -56,6 +63,22 @@ export type ToolNodeOptions = {
|
|
|
56
63
|
* When provided, takes precedence over the value computed from maxContextTokens.
|
|
57
64
|
*/
|
|
58
65
|
maxToolResultChars?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Run-scoped tool output reference configuration. When `enabled` is
|
|
68
|
+
* `true`, ToolNode registers successful outputs and substitutes
|
|
69
|
+
* `{{tool<idx>turn<turn>}}` placeholders found in string args.
|
|
70
|
+
*
|
|
71
|
+
* Ignored when `toolOutputRegistry` is also provided (host-supplied
|
|
72
|
+
* registry wins).
|
|
73
|
+
*/
|
|
74
|
+
toolOutputReferences?: ToolOutputReferencesConfig;
|
|
75
|
+
/**
|
|
76
|
+
* Pre-constructed registry instance shared across ToolNodes for the
|
|
77
|
+
* run. Graphs pass the same registry to every ToolNode they compile
|
|
78
|
+
* so cross-agent `{{tool<i>turn<n>}}` substitutions resolve. Takes
|
|
79
|
+
* precedence over `toolOutputReferences` when both are set.
|
|
80
|
+
*/
|
|
81
|
+
toolOutputRegistry?: ToolOutputReferenceRegistry;
|
|
59
82
|
};
|
|
60
83
|
|
|
61
84
|
export type ToolNodeConstructorParams = ToolRefs & ToolNodeOptions;
|
|
@@ -81,9 +104,7 @@ export type CodeExecutionToolParams =
|
|
|
81
104
|
| {
|
|
82
105
|
session_id?: string;
|
|
83
106
|
user_id?: string;
|
|
84
|
-
apiKey?: string;
|
|
85
107
|
files?: CodeEnvFile[];
|
|
86
|
-
[EnvVar.CODE_API_KEY]?: string;
|
|
87
108
|
};
|
|
88
109
|
|
|
89
110
|
export type FileRef = {
|
|
@@ -186,6 +207,26 @@ export type ToolExecuteBatchRequest = {
|
|
|
186
207
|
reject: (error: Error) => void;
|
|
187
208
|
};
|
|
188
209
|
|
|
210
|
+
/**
|
|
211
|
+
* A message injected into graph state by any tool execution handler.
|
|
212
|
+
* Generic mechanism: any tool returning `injectedMessages` in its `ToolExecuteResult`
|
|
213
|
+
* will have these appended to state after the ToolMessage for this call.
|
|
214
|
+
*/
|
|
215
|
+
export type InjectedMessage = {
|
|
216
|
+
/** 'user' for skill body injection, 'system' for context hints.
|
|
217
|
+
* Both are converted to HumanMessage at runtime; the original role
|
|
218
|
+
* is preserved in additional_kwargs.role. */
|
|
219
|
+
role: 'user' | 'system';
|
|
220
|
+
/** Message content: string for simple text, array for complex multi-part content */
|
|
221
|
+
content: string | MessageContentComplex[];
|
|
222
|
+
/** When true, the message is framework-internal: not shown in UI, not counted as a user turn */
|
|
223
|
+
isMeta?: boolean;
|
|
224
|
+
/** Origin tag for downstream consumers (UI, pruner, compaction) */
|
|
225
|
+
source?: 'skill' | 'hook' | 'system';
|
|
226
|
+
/** Only set when source is 'skill', for compaction preservation */
|
|
227
|
+
skillName?: string;
|
|
228
|
+
};
|
|
229
|
+
|
|
189
230
|
/** Result for a single tool call in event-driven execution */
|
|
190
231
|
export type ToolExecuteResult = {
|
|
191
232
|
/** Matches ToolCallRequest.id */
|
|
@@ -198,11 +239,72 @@ export type ToolExecuteResult = {
|
|
|
198
239
|
status: 'success' | 'error';
|
|
199
240
|
/** Error message if status is 'error' */
|
|
200
241
|
errorMessage?: string;
|
|
242
|
+
/**
|
|
243
|
+
* Messages to inject into graph state after the ToolMessage for this call.
|
|
244
|
+
* Placed after tool results to respect provider message ordering (tool_call -> tool_result adjacency).
|
|
245
|
+
* The host's message formatter may merge injected user messages with the preceding tool_result turn.
|
|
246
|
+
* Generic mechanism: any tool execution handler can use this.
|
|
247
|
+
*/
|
|
248
|
+
injectedMessages?: InjectedMessage[];
|
|
201
249
|
};
|
|
202
250
|
|
|
203
251
|
/** Map of tool names to tool definitions */
|
|
204
252
|
export type LCToolRegistry = Map<string, LCTool>;
|
|
205
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Run-scoped configuration for tool output references.
|
|
256
|
+
*
|
|
257
|
+
* When enabled, each successful tool result is registered under a stable
|
|
258
|
+
* key (`tool<idx>turn<turn>`). Later tool calls can pipe a previous
|
|
259
|
+
* output into their arguments by including the literal placeholder
|
|
260
|
+
* `{{tool<idx>turn<turn>}}` anywhere in a string argument; ToolNode
|
|
261
|
+
* substitutes it with the stored output immediately before invoking
|
|
262
|
+
* the tool.
|
|
263
|
+
*
|
|
264
|
+
* The registry stores the *raw, untruncated* tool output (subject to
|
|
265
|
+
* its own size caps) so a later substitution can pipe the full payload
|
|
266
|
+
* into the next tool even when the LLM only saw a head+tail-truncated
|
|
267
|
+
* preview in `ToolMessage.content`. Size limits are decoupled from the
|
|
268
|
+
* LLM-visible truncation budget and default to 5 MB total.
|
|
269
|
+
*
|
|
270
|
+
* Known limitations:
|
|
271
|
+
* - Tools that return a `ToolMessage` with array-type content
|
|
272
|
+
* (multi-part content blocks such as text + image) are not
|
|
273
|
+
* registered and cannot be cited via `{{tool<i>turn<n>}}`. A
|
|
274
|
+
* warning is logged so the missing reference is visible.
|
|
275
|
+
* - When a `PostToolUse` hook replaces `ToolMessage.content`, the
|
|
276
|
+
* *post-hook* content is what gets stored in the registry (and
|
|
277
|
+
* what the model sees), so `{{…}}` substitutions deliver the
|
|
278
|
+
* hooked output rather than the raw tool return. This matches the
|
|
279
|
+
* hook's "authoritative" role for output shaping.
|
|
280
|
+
*/
|
|
281
|
+
export type ToolOutputReferencesConfig = {
|
|
282
|
+
/** Enable the registry and placeholder substitution. Defaults to `false`. */
|
|
283
|
+
enabled?: boolean;
|
|
284
|
+
/**
|
|
285
|
+
* Maximum characters stored (and substituted) per registered output.
|
|
286
|
+
* Applied to the *raw* output before storage. Defaults to
|
|
287
|
+
* `HARD_MAX_TOOL_RESULT_CHARS` (~400 KB) — matching the
|
|
288
|
+
* LLM-visible tool-result truncation budget, which is also a safe
|
|
289
|
+
* payload size for shell `ARG_MAX` limits when a `{{…}}` expansion
|
|
290
|
+
* gets piped into a bash `command`. Hosts that want to preserve
|
|
291
|
+
* fuller fidelity (for example for non-bash API consumers) can
|
|
292
|
+
* raise this up to `maxTotalSize` (defaults to 5 MB) — be aware
|
|
293
|
+
* that large single-output substitutions may exceed shell
|
|
294
|
+
* argument-size limits on typical Linux/macOS.
|
|
295
|
+
*/
|
|
296
|
+
maxOutputSize?: number;
|
|
297
|
+
/**
|
|
298
|
+
* Hard cap on total characters retained across all registered outputs
|
|
299
|
+
* for the run. When exceeded, the oldest entries are evicted FIFO
|
|
300
|
+
* until the total fits. The effective per-output cap is
|
|
301
|
+
* `min(maxOutputSize, maxTotalSize)` so a single stored output can
|
|
302
|
+
* never exceed the aggregate bound. Defaults to
|
|
303
|
+
* `calculateMaxTotalToolOutputSize(maxOutputSize)` (5 MB).
|
|
304
|
+
*/
|
|
305
|
+
maxTotalSize?: number;
|
|
306
|
+
};
|
|
307
|
+
|
|
206
308
|
export type ProgrammaticCache = { toolMap: ToolMap; toolDefs: LCTool[] };
|
|
207
309
|
|
|
208
310
|
/** Search mode: code_interpreter uses external sandbox, local uses safe substring matching */
|
|
@@ -213,7 +315,6 @@ export type McpNameFormat = 'full' | 'base';
|
|
|
213
315
|
|
|
214
316
|
/** Parameters for creating a Tool Search tool */
|
|
215
317
|
export type ToolSearchParams = {
|
|
216
|
-
apiKey?: string;
|
|
217
318
|
toolRegistry?: LCToolRegistry;
|
|
218
319
|
onlyDeferred?: boolean;
|
|
219
320
|
baseUrl?: string;
|
|
@@ -223,7 +324,6 @@ export type ToolSearchParams = {
|
|
|
223
324
|
mcpServer?: string | string[];
|
|
224
325
|
/** Format for MCP tool names: 'full' (tool_mcp_server) or 'base' (tool only). Default: 'full' */
|
|
225
326
|
mcpNameFormat?: McpNameFormat;
|
|
226
|
-
[key: string]: unknown;
|
|
227
327
|
};
|
|
228
328
|
|
|
229
329
|
/** Simplified tool metadata for search purposes */
|
|
@@ -318,12 +418,16 @@ export type ProgrammaticExecutionArtifact = {
|
|
|
318
418
|
files?: FileRefs;
|
|
319
419
|
};
|
|
320
420
|
|
|
421
|
+
/** Parameters for creating a bash execution tool (same API as CodeExecutor, bash-only) */
|
|
422
|
+
export type BashExecutionToolParams = CodeExecutionToolParams;
|
|
423
|
+
|
|
424
|
+
/** Parameters for creating a bash programmatic tool calling tool (same API as PTC, bash-only) */
|
|
425
|
+
export type BashProgrammaticToolCallingParams = ProgrammaticToolCallingParams;
|
|
426
|
+
|
|
321
427
|
/**
|
|
322
428
|
* Initialization parameters for the PTC tool
|
|
323
429
|
*/
|
|
324
430
|
export type ProgrammaticToolCallingParams = {
|
|
325
|
-
/** Code API key (or use CODE_API_KEY env var) */
|
|
326
|
-
apiKey?: string;
|
|
327
431
|
/** Code API base URL (or use CODE_BASEURL env var) */
|
|
328
432
|
baseUrl?: string;
|
|
329
433
|
/** Safety limit for round-trips (default: 20) */
|
|
@@ -332,8 +436,6 @@ export type ProgrammaticToolCallingParams = {
|
|
|
332
436
|
proxy?: string;
|
|
333
437
|
/** Enable debug logging (or set PTC_DEBUG=true env var) */
|
|
334
438
|
debug?: boolean;
|
|
335
|
-
/** Environment variable key for API key */
|
|
336
|
-
[key: string]: unknown;
|
|
337
439
|
};
|
|
338
440
|
|
|
339
441
|
// ============================================================================
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { describe, it, expect } from '@jest/globals';
|
|
2
|
+
import {
|
|
3
|
+
HARD_MAX_TOOL_RESULT_CHARS,
|
|
4
|
+
HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE,
|
|
5
|
+
calculateMaxToolResultChars,
|
|
6
|
+
calculateMaxTotalToolOutputSize,
|
|
7
|
+
} from '@/utils/truncation';
|
|
8
|
+
|
|
9
|
+
describe('truncation helpers', () => {
|
|
10
|
+
describe('calculateMaxToolResultChars', () => {
|
|
11
|
+
it('returns the hard cap when context tokens are missing', () => {
|
|
12
|
+
expect(calculateMaxToolResultChars()).toBe(HARD_MAX_TOOL_RESULT_CHARS);
|
|
13
|
+
expect(calculateMaxToolResultChars(undefined)).toBe(
|
|
14
|
+
HARD_MAX_TOOL_RESULT_CHARS
|
|
15
|
+
);
|
|
16
|
+
expect(calculateMaxToolResultChars(0)).toBe(HARD_MAX_TOOL_RESULT_CHARS);
|
|
17
|
+
expect(calculateMaxToolResultChars(-100)).toBe(
|
|
18
|
+
HARD_MAX_TOOL_RESULT_CHARS
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('computes 30% of context-window characters for normal inputs', () => {
|
|
23
|
+
// 100k tokens * 0.3 = 30k tokens * 4 chars/token = 120k chars
|
|
24
|
+
expect(calculateMaxToolResultChars(100_000)).toBe(120_000);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('clamps to the hard cap for large context windows', () => {
|
|
28
|
+
// 1M tokens * 0.3 * 4 = 1.2M chars, exceeds 400k cap
|
|
29
|
+
expect(calculateMaxToolResultChars(1_000_000)).toBe(
|
|
30
|
+
HARD_MAX_TOOL_RESULT_CHARS
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('calculateMaxTotalToolOutputSize', () => {
|
|
36
|
+
it('returns the absolute hard cap when no per-output is provided', () => {
|
|
37
|
+
expect(calculateMaxTotalToolOutputSize()).toBe(
|
|
38
|
+
HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE
|
|
39
|
+
);
|
|
40
|
+
expect(calculateMaxTotalToolOutputSize(0)).toBe(
|
|
41
|
+
HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE
|
|
42
|
+
);
|
|
43
|
+
expect(calculateMaxTotalToolOutputSize(-1)).toBe(
|
|
44
|
+
HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('doubles the per-output cap by default', () => {
|
|
49
|
+
expect(calculateMaxTotalToolOutputSize(100_000)).toBe(200_000);
|
|
50
|
+
expect(calculateMaxTotalToolOutputSize(1)).toBe(2);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('clamps the doubled value to HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE', () => {
|
|
54
|
+
// 4M * 2 = 8M, exceeds 5M
|
|
55
|
+
expect(calculateMaxTotalToolOutputSize(4_000_000)).toBe(
|
|
56
|
+
HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE
|
|
57
|
+
);
|
|
58
|
+
// Right at the boundary: 2.5M * 2 = 5M (no clamp).
|
|
59
|
+
expect(calculateMaxTotalToolOutputSize(2_500_000)).toBe(5_000_000);
|
|
60
|
+
// Just past it: 2_500_001 * 2 = 5_000_002 -> clamped.
|
|
61
|
+
expect(calculateMaxTotalToolOutputSize(2_500_001)).toBe(
|
|
62
|
+
HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
package/src/utils/truncation.ts
CHANGED
|
@@ -12,6 +12,16 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export const HARD_MAX_TOOL_RESULT_CHARS = 400_000;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Absolute hard cap on the aggregate size (characters) of all registered
|
|
17
|
+
* tool outputs kept for `{{tool<i>turn<n>}}` substitution. Set at 5 MB
|
|
18
|
+
* because the registry stores *raw, untruncated* tool output — full
|
|
19
|
+
* fidelity for piping into downstream bash/jq — so the budget needs
|
|
20
|
+
* enough headroom to keep a handful of large responses without
|
|
21
|
+
* ballooning unbounded.
|
|
22
|
+
*/
|
|
23
|
+
export const HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE = 5_000_000;
|
|
24
|
+
|
|
15
25
|
/**
|
|
16
26
|
* Computes the dynamic max tool result size based on the model's context window.
|
|
17
27
|
* Uses 30% of the context window (in estimated characters, ~4 chars/token)
|
|
@@ -32,6 +42,26 @@ export function calculateMaxToolResultChars(
|
|
|
32
42
|
);
|
|
33
43
|
}
|
|
34
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Computes the default aggregate size (characters) for the tool output
|
|
47
|
+
* reference registry based on the per-output budget. Mirrors
|
|
48
|
+
* `calculateMaxToolResultChars`'s shape: a multiple of the per-output
|
|
49
|
+
* cap, clamped to `HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE`.
|
|
50
|
+
*
|
|
51
|
+
* @param maxOutputSize - Per-output maximum characters (e.g., the
|
|
52
|
+
* ToolNode's `maxToolResultChars`). When omitted or non-positive,
|
|
53
|
+
* falls back to the absolute total cap.
|
|
54
|
+
* @returns Maximum total characters retained across the registry.
|
|
55
|
+
*/
|
|
56
|
+
export function calculateMaxTotalToolOutputSize(
|
|
57
|
+
maxOutputSize?: number
|
|
58
|
+
): number {
|
|
59
|
+
if (maxOutputSize == null || maxOutputSize <= 0) {
|
|
60
|
+
return HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE;
|
|
61
|
+
}
|
|
62
|
+
return Math.min(maxOutputSize * 2, HARD_MAX_TOTAL_TOOL_OUTPUT_SIZE);
|
|
63
|
+
}
|
|
64
|
+
|
|
35
65
|
/**
|
|
36
66
|
* Truncates a tool-call input (the arguments/payload of a tool_use block)
|
|
37
67
|
* using head+tail strategy. Returns an object with `_truncated` (the
|