@librechat/agents 3.4.0 → 3.4.1
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/graphs/Graph.cjs +111 -27
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/hooks/HookRegistry.cjs +83 -0
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
- package/dist/cjs/hooks/executeHooks.cjs +60 -14
- package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
- package/dist/cjs/hooks/index.cjs.map +1 -1
- package/dist/cjs/hooks/types.cjs +2 -0
- package/dist/cjs/hooks/types.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +3 -3
- package/dist/cjs/llm/invoke.cjs +2 -2
- package/dist/cjs/main.cjs +14 -13
- package/dist/cjs/messages/format.cjs +40 -23
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/run.cjs +82 -15
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/AgentSession.cjs +37 -2
- package/dist/cjs/session/AgentSession.cjs.map +1 -1
- package/dist/cjs/stream.cjs +1 -1
- package/dist/cjs/summarization/node.cjs +6 -3
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/BashExecutor.cjs +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +1 -1
- package/dist/cjs/tools/ToolNode.cjs +316 -94
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/ToolSearch.cjs +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +630 -78
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentReplay.cjs +175 -0
- package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -0
- package/dist/cjs/tools/toolOutputReferences.cjs +20 -0
- package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +2 -2
- package/dist/esm/graphs/Graph.mjs +111 -27
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/hooks/HookRegistry.mjs +83 -0
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
- package/dist/esm/hooks/executeHooks.mjs +60 -14
- package/dist/esm/hooks/executeHooks.mjs.map +1 -1
- package/dist/esm/hooks/index.mjs.map +1 -1
- package/dist/esm/hooks/types.mjs +2 -1
- package/dist/esm/hooks/types.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +2 -2
- package/dist/esm/main.mjs +11 -11
- package/dist/esm/messages/format.mjs +40 -23
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/run.mjs +83 -16
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/AgentSession.mjs +37 -2
- package/dist/esm/session/AgentSession.mjs.map +1 -1
- package/dist/esm/stream.mjs +1 -1
- package/dist/esm/summarization/node.mjs +6 -3
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/BashExecutor.mjs +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +1 -1
- package/dist/esm/tools/ToolNode.mjs +317 -95
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/ToolSearch.mjs +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +631 -79
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentReplay.mjs +168 -0
- package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -0
- package/dist/esm/tools/toolOutputReferences.mjs +20 -0
- package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +2 -2
- package/dist/types/graphs/Graph.d.ts +16 -1
- package/dist/types/hooks/HookRegistry.d.ts +10 -1
- package/dist/types/hooks/executeHooks.d.ts +5 -1
- package/dist/types/hooks/index.d.ts +2 -2
- package/dist/types/hooks/types.d.ts +12 -0
- package/dist/types/run.d.ts +4 -1
- package/dist/types/session/AgentSession.d.ts +1 -0
- package/dist/types/tools/ToolNode.d.ts +23 -15
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +46 -7
- package/dist/types/tools/subagent/SubagentReplay.d.ts +81 -0
- package/dist/types/tools/toolOutputReferences.d.ts +12 -0
- package/dist/types/types/graph.d.ts +5 -5
- package/dist/types/types/hitl.d.ts +15 -0
- package/package.json +6 -2
- package/src/graphs/Graph.ts +246 -52
- package/src/graphs/__tests__/Graph.breakerLifecycle.test.ts +48 -9
- package/src/graphs/__tests__/Graph.contextOverflow.test.ts +1 -1
- package/src/graphs/__tests__/Graph.subagentResumeState.test.ts +80 -0
- package/src/hooks/HookRegistry.ts +151 -1
- package/src/hooks/__tests__/HookRegistry.test.ts +96 -0
- package/src/hooks/__tests__/executeHooks.test.ts +160 -0
- package/src/hooks/executeHooks.ts +133 -15
- package/src/hooks/index.ts +3 -1
- package/src/hooks/types.ts +16 -0
- package/src/messages/format.ts +54 -26
- package/src/messages/formatAgentMessages.reducer.test.ts +162 -0
- package/src/messages/formatAgentMessages.steer.test.ts +16 -11
- package/src/messages/formatAgentMessages.test.ts +7 -2
- package/src/run.ts +164 -18
- package/src/session/AgentSession.ts +52 -2
- package/src/session/__tests__/JsonlSessionStore.test.ts +53 -0
- package/src/summarization/__tests__/node.test.ts +32 -14
- package/src/summarization/node.ts +15 -11
- package/src/tools/ToolNode.ts +631 -157
- package/src/tools/__tests__/SubagentExecutor.test.ts +542 -6
- package/src/tools/__tests__/SubagentReplay.test.ts +300 -0
- package/src/tools/__tests__/ToolNode.breakerSignal.test.ts +208 -2
- package/src/tools/__tests__/directToolHITLResumeScope.test.ts +486 -2
- package/src/tools/__tests__/hitl.test.ts +234 -5
- package/src/tools/__tests__/subagentHooks.test.ts +1040 -62
- package/src/tools/__tests__/toolOutputReferences.test.ts +19 -2
- package/src/tools/subagent/SubagentExecutor.ts +1369 -131
- package/src/tools/subagent/SubagentReplay.ts +575 -0
- package/src/tools/toolOutputReferences.ts +40 -1
- package/src/types/graph.ts +5 -5
- package/src/types/hitl.ts +16 -0
|
@@ -9,6 +9,7 @@ import type { InjectedMessage } from '@/types/tools';
|
|
|
9
9
|
* `@librechat/agents` emission points.
|
|
10
10
|
*/
|
|
11
11
|
export declare const HOOK_EVENTS: readonly ["RunStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "PreemptBoundary", "PermissionDenied", "SubagentStart", "SubagentStop", "Stop", "StopFailure", "PreCompact", "PostCompact"];
|
|
12
|
+
export declare const TOOL_APPROVAL_EXECUTION_SCOPE_CONFIG_KEY = "__librechat_tool_approval_execution_scope";
|
|
12
13
|
export type HookEvent = (typeof HOOK_EVENTS)[number];
|
|
13
14
|
/** Tool-gating decision; executeHooks folds with `deny > ask > allow` precedence. */
|
|
14
15
|
export type ToolDecision = 'allow' | 'deny' | 'ask';
|
|
@@ -331,6 +332,17 @@ export interface PreToolUseHookOutput extends BaseHookOutput {
|
|
|
331
332
|
*/
|
|
332
333
|
allowedDecisions?: ReadonlyArray<'approve' | 'reject' | 'edit' | 'respond'>;
|
|
333
334
|
}
|
|
335
|
+
/** Stable identity for replaying a consumed one-shot tool approval. */
|
|
336
|
+
export interface ToolApprovalReplayKey {
|
|
337
|
+
executionScope: string;
|
|
338
|
+
agentId: string;
|
|
339
|
+
toolUseId: string;
|
|
340
|
+
}
|
|
341
|
+
/** Checkpoint-safe copy of a consumed one-shot approval contribution. */
|
|
342
|
+
export interface ToolApprovalReplaySnapshot {
|
|
343
|
+
key: ToolApprovalReplayKey;
|
|
344
|
+
result: AggregatedHookResult;
|
|
345
|
+
}
|
|
334
346
|
export interface PostToolUseHookOutput extends BaseHookOutput {
|
|
335
347
|
/**
|
|
336
348
|
* Replacement tool output. Flows through the aggregated result so the
|
package/dist/types/run.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { BaseMessage } from '@langchain/core/messages';
|
|
1
2
|
import { Command } from '@langchain/langgraph';
|
|
2
|
-
import type { MessageContentComplex
|
|
3
|
+
import type { MessageContentComplex } from '@langchain/core/messages';
|
|
3
4
|
import type * as t from '@/types';
|
|
4
5
|
import { MultiAgentGraph } from '@/graphs/MultiAgentGraph';
|
|
5
6
|
import { StandardGraph } from '@/graphs/Graph';
|
|
@@ -103,6 +104,7 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
103
104
|
private runPreStreamHooks;
|
|
104
105
|
static create<T extends t.BaseGraphState>(config: t.RunConfig): Promise<Run<T>>;
|
|
105
106
|
getRunMessages(): BaseMessage[] | undefined;
|
|
107
|
+
getChildCheckpointThreadIds(): string[];
|
|
106
108
|
/**
|
|
107
109
|
* Returns a defensive snapshot of tools discovered by the current run.
|
|
108
110
|
* Pass an agent id for that context, or omit it for the ordered union across
|
|
@@ -220,6 +222,7 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
220
222
|
*/
|
|
221
223
|
resume<TResume = t.ToolApprovalDecision[] | t.ToolApprovalDecisionMap>(resumeValue: TResume, callerConfig: t.RunStreamConfig, streamOptions?: t.EventStreamOptions, commandOptions?: Pick<ConstructorParameters<typeof Command>[0], 'update' | 'goto'>): Promise<MessageContentComplex[] | undefined>;
|
|
222
224
|
private resolveInterruptResumeConfig;
|
|
225
|
+
private restoreInterruptFromCheckpoint;
|
|
223
226
|
private createSystemCallback;
|
|
224
227
|
getCallbacks(clientCallbacks: t.ClientCallbacks): t.SystemCallbacks;
|
|
225
228
|
generateTitle({ provider, inputText, contentParts, titlePrompt, clientOptions, chainOptions, skipLanguage, titleMethod, titlePromptTemplate, }: t.RunTitleOptions): Promise<{
|
|
@@ -16,6 +16,7 @@ export declare class AgentSession {
|
|
|
16
16
|
getLatestCheckpoint(options?: AgentSessionCheckpointLookupOptions): Promise<AgentSessionCheckpointReference | undefined>;
|
|
17
17
|
private hasCheckpointState;
|
|
18
18
|
private recordCheckpoint;
|
|
19
|
+
private recordChildCheckpointThreads;
|
|
19
20
|
private getCheckpointThreadIds;
|
|
20
21
|
private resetCheckpointThreads;
|
|
21
22
|
private runInternal;
|
|
@@ -3,6 +3,7 @@ import { END, Command, MessagesAnnotation } from '@langchain/langgraph';
|
|
|
3
3
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
4
4
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
5
5
|
import type { ToolOutputResolveView, ResolvedArgsByCallId } from '@/tools/toolOutputReferences';
|
|
6
|
+
import type { SubagentToolNodeResumeState } from '@/tools/subagent/SubagentReplay';
|
|
6
7
|
import type * as t from '@/types';
|
|
7
8
|
import { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
|
|
8
9
|
import { RunnableCallable } from '@/utils';
|
|
@@ -50,6 +51,8 @@ type RunToolBatchContext<T = unknown> = {
|
|
|
50
51
|
* contract for hosts relying on it for policy / recovery guidance.
|
|
51
52
|
*/
|
|
52
53
|
additionalContextsSink?: string[];
|
|
54
|
+
/** Stable identity of the assistant tool-call batch across HITL replay. */
|
|
55
|
+
replayBatchKey?: string;
|
|
53
56
|
/**
|
|
54
57
|
* Graph state the ToolNode was invoked with, threaded from `run()`
|
|
55
58
|
* so `tool.invoke` can forward it as langgraph 1.4's `runtime.state`
|
|
@@ -113,6 +116,10 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
113
116
|
* the Run ends.
|
|
114
117
|
*/
|
|
115
118
|
private directPathTurns;
|
|
119
|
+
/** Terminal results from interrupting siblings that must survive a
|
|
120
|
+
* LangGraph replay of the containing ToolNode. Includes the sidecar data
|
|
121
|
+
* the fresh batch needs for hook-context injection and completion events. */
|
|
122
|
+
private settledInterruptingResults;
|
|
116
123
|
/** Tool registry for filtering (lazy computation of programmatic maps) */
|
|
117
124
|
private toolRegistry?;
|
|
118
125
|
/** Cached programmatic tools (computed once on first PTC call) */
|
|
@@ -240,12 +247,11 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
240
247
|
private shouldHandleUnknownHandoffLocally;
|
|
241
248
|
private getUnknownToolErrorMessage;
|
|
242
249
|
/**
|
|
243
|
-
* Flush
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* call IDs (Codex P2 #33). Hosts can also call this directly if
|
|
250
|
+
* Flush per-Run direct replay state. Called by the Graph at end-of-Run via
|
|
251
|
+
* `clearHeavyState`. The state intentionally survives `run()` re-entry so
|
|
252
|
+
* interrupt + resume keeps both original turn slots and terminal sibling
|
|
253
|
+
* outputs, but it would otherwise grow linearly and could collide across
|
|
254
|
+
* Runs if a provider reused call IDs. Hosts can also call this directly if
|
|
249
255
|
* they reuse a ToolNode across batches outside of a Graph.
|
|
250
256
|
*/
|
|
251
257
|
clearDirectPathTurns(): void;
|
|
@@ -259,6 +265,8 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
259
265
|
* @returns A ReadonlyMap where keys are tool names and values are their usage counts.
|
|
260
266
|
*/
|
|
261
267
|
getToolUsageCounts(): ReadonlyMap<string, number>;
|
|
268
|
+
createSubagentResumeState(): SubagentToolNodeResumeState;
|
|
269
|
+
restoreSubagentResumeState(state: SubagentToolNodeResumeState): void;
|
|
262
270
|
private recordToolUsageTurn;
|
|
263
271
|
private recordEventToolPlanningTurn;
|
|
264
272
|
/**
|
|
@@ -296,9 +304,9 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
296
304
|
* `blockDirectCall`, `respond` returns the host-supplied
|
|
297
305
|
* `responseText` as a synthetic success ToolMessage,
|
|
298
306
|
* `edit` re-runs with edited args. LangGraph re-enters
|
|
299
|
-
* ToolNode.run from the start on resume
|
|
300
|
-
* again
|
|
301
|
-
*
|
|
307
|
+
* ToolNode.run from the start on resume. Reusable hooks fire
|
|
308
|
+
* again; a consumed one-shot hook replays its pending approval
|
|
309
|
+
* result. In both cases `interrupt()` consumes the resume value.
|
|
302
310
|
* • When HITL is off: collapses to a fail-closed deny (matches
|
|
303
311
|
* the rest of the SDK's HITL-disabled default). One-time
|
|
304
312
|
* warning logged so hosts notice the gap.
|
|
@@ -465,16 +473,16 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
465
473
|
* call throws a `GraphInterrupt`, the `await` below rejects and unwinds the
|
|
466
474
|
* whole ToolNode *before* any non-interrupting sibling has started — so a
|
|
467
475
|
* sibling with real side effects (send_email, billing) never executes on
|
|
468
|
-
* the first pass.
|
|
469
|
-
*
|
|
470
|
-
*
|
|
476
|
+
* the first pass. Terminal interrupting siblings are cached by call id, so
|
|
477
|
+
* LangGraph replay reuses their complete lifecycle output instead of
|
|
478
|
+
* repeating model calls, hooks, or side effects.
|
|
471
479
|
*
|
|
472
480
|
* Without this ordering, a flat `Promise.all` starts every sibling
|
|
473
481
|
* concurrently, so a non-idempotent sibling can complete its side effect
|
|
474
482
|
* before the interrupt unwinds and then run a SECOND time on resume — the
|
|
475
|
-
* duplicate side effect this method exists to prevent.
|
|
476
|
-
*
|
|
477
|
-
*
|
|
483
|
+
* duplicate side effect this method exists to prevent. A tool that actually
|
|
484
|
+
* suspends re-enters until it reaches a terminal result; siblings that
|
|
485
|
+
* already settled do not re-enter.
|
|
478
486
|
*
|
|
479
487
|
* `batchIndices[i]` is `directCalls[i]`'s position within the parent
|
|
480
488
|
* ToolNode batch (used for `{{tool<i>turn<n>}}` registration); it is
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
1
|
+
import { BaseMessage } from '@langchain/core/messages';
|
|
2
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
3
|
+
import type { ToolCall } from '@langchain/core/messages/tool';
|
|
4
|
+
import type { AgentInputs, HumanInTheLoopConfig, StandardGraphInput, ResolvedSubagentConfig, SubagentConfig, SubagentUsageSink, TokenCounter } from '@/types';
|
|
5
|
+
import type { SubagentResumeManifest, SettledSubagentToolOutput } from './SubagentReplay';
|
|
3
6
|
import type { HookRegistry } from '@/hooks';
|
|
4
7
|
import type { AgentContext } from '@/agents/AgentContext';
|
|
5
8
|
import type { StandardGraph } from '@/graphs/Graph';
|
|
@@ -34,11 +37,12 @@ export type SubagentExecuteParams = {
|
|
|
34
37
|
*
|
|
35
38
|
* Inheritance details (verified empirically against LangGraph):
|
|
36
39
|
* - host-set keys propagate as-is into the child's tool dispatches;
|
|
37
|
-
* - `thread_id`
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
40
|
+
* - with nested HITL enabled, `thread_id` is replaced with a stable
|
|
41
|
+
* child checkpoint id derived from the parent's durable thread id,
|
|
42
|
+
* checkpoint fork, parent agent id, and spawning tool call id so parent
|
|
43
|
+
* and child checkpoints cannot collide, sibling parent forks stay
|
|
44
|
+
* isolated, and reconstruction returns to the same child checkpoint;
|
|
45
|
+
* parent-scoped hook lookup remains keyed by the inherited `run_id`;
|
|
42
46
|
* - `parent_run_id` propagates when the host put it on parent's
|
|
43
47
|
* configurable;
|
|
44
48
|
* - `run_id` is *overwritten by the LangGraph runtime* at child
|
|
@@ -95,6 +99,11 @@ export type SubagentExecutorOptions = {
|
|
|
95
99
|
* revert to the defaults.
|
|
96
100
|
*/
|
|
97
101
|
streamLimits?: StandardGraphInput['streamLimits'];
|
|
102
|
+
humanInTheLoop?: HumanInTheLoopConfig;
|
|
103
|
+
/** Shared durable saver used to recover outer tool lifecycle results before
|
|
104
|
+
* parent hooks re-enter after a process rebuild. Narrowed structurally at
|
|
105
|
+
* construction because graph compile options also permit framework flags. */
|
|
106
|
+
checkpointer?: unknown;
|
|
98
107
|
/** Remaining nesting budget. 0 or negative blocks execution. */
|
|
99
108
|
maxDepth?: number;
|
|
100
109
|
/**
|
|
@@ -143,9 +152,18 @@ export declare class SubagentExecutor {
|
|
|
143
152
|
private readonly langfuse?;
|
|
144
153
|
private readonly tokenCounter?;
|
|
145
154
|
private readonly streamLimits?;
|
|
155
|
+
private readonly humanInTheLoop?;
|
|
156
|
+
private readonly checkpointer?;
|
|
146
157
|
private readonly maxDepth;
|
|
147
158
|
private readonly createChildGraph;
|
|
148
159
|
private readonly usageSink?;
|
|
160
|
+
private readonly checkpointThreadIds;
|
|
161
|
+
private readonly startedChildRuns;
|
|
162
|
+
private readonly completedChildRuns;
|
|
163
|
+
private readonly completedChildResults;
|
|
164
|
+
private readonly childExecutionIdentities;
|
|
165
|
+
private readonly activeChildRuns;
|
|
166
|
+
private replayCheckpointWorkflow?;
|
|
149
167
|
private readonly resolveParentHandlerRegistry?;
|
|
150
168
|
constructor(options: SubagentExecutorOptions);
|
|
151
169
|
/** The breaker controller current for this execution — read per spawn
|
|
@@ -157,6 +175,27 @@ export declare class SubagentExecutor {
|
|
|
157
175
|
private composeChildSignal;
|
|
158
176
|
/** Snapshot of the parent's registry at the moment a subagent is dispatched. */
|
|
159
177
|
private getParentHandlerRegistry;
|
|
178
|
+
/**
|
|
179
|
+
* Keeps the original child thread as an immutable resume source once a
|
|
180
|
+
* different parent Run reconstructs it. Each rebuilt parent gets a private
|
|
181
|
+
* checkpoint fork, while the persisted child run ID remains stable for
|
|
182
|
+
* activity and usage correlation across the interrupt boundary.
|
|
183
|
+
*/
|
|
184
|
+
private resolveChildExecutionIdentity;
|
|
185
|
+
/** Captures one exact checkpoint head per namespace for a child thread. */
|
|
186
|
+
private getLatestCheckpointSnapshot;
|
|
187
|
+
/** Copies exact checkpoint lineages, including pending task writes. */
|
|
188
|
+
private forkCheckpointSnapshot;
|
|
189
|
+
private createResumeManifest;
|
|
190
|
+
getResumeManifest(parentToolCallIds?: ReadonlySet<string>): Promise<SubagentResumeManifest | undefined>;
|
|
191
|
+
getChildCheckpointThreadIds(): string[];
|
|
192
|
+
resetCheckpointThreadIds(): void;
|
|
193
|
+
private getGraphChildCheckpointThreadIds;
|
|
194
|
+
private clearChildGraph;
|
|
195
|
+
clearHeavyState(): void;
|
|
196
|
+
getSettledToolOutput(call: ToolCall, config: RunnableConfig): Promise<SettledSubagentToolOutput | undefined>;
|
|
197
|
+
persistSettledToolOutput(call: ToolCall, config: RunnableConfig, settled: SettledSubagentToolOutput): Promise<void>;
|
|
198
|
+
private persistChildCheckpointMarker;
|
|
160
199
|
execute(params: SubagentExecuteParams): Promise<SubagentExecuteResult>;
|
|
161
200
|
/**
|
|
162
201
|
* Emits a single {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope through the
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ToolCall, ToolMessage } from '@langchain/core/messages/tool';
|
|
2
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
3
|
+
import type { ToolOutputReferenceState } from '@/tools/toolOutputReferences';
|
|
4
|
+
import type { ToolApprovalReplaySnapshot } from '@/hooks';
|
|
5
|
+
import type { ToolSessionContext } from '@/types';
|
|
6
|
+
export declare const SUBAGENT_RESUME_MANIFEST_CONFIG_KEY = "__librechat_subagent_resume_manifest";
|
|
7
|
+
export declare const SUBAGENT_RESUME_ATTEMPT_CONFIG_KEY = "__librechat_subagent_resume_attempt";
|
|
8
|
+
export declare const SUBAGENT_PARENT_BATCH_CONFIG_KEY = "__librechat_subagent_parent_batch";
|
|
9
|
+
export interface SubagentCheckpointReference {
|
|
10
|
+
threadId: string;
|
|
11
|
+
checkpointId: string;
|
|
12
|
+
checkpointNs: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SubagentToolCallStepReference {
|
|
15
|
+
toolCallId: string;
|
|
16
|
+
stepId: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SubagentToolSessionReference {
|
|
19
|
+
toolName: string;
|
|
20
|
+
context: ToolSessionContext;
|
|
21
|
+
}
|
|
22
|
+
export interface SubagentToolNodeResumeState {
|
|
23
|
+
stateKey: string;
|
|
24
|
+
toolUsageCounts: Array<{
|
|
25
|
+
toolName: string;
|
|
26
|
+
count: number;
|
|
27
|
+
}>;
|
|
28
|
+
directPathTurns: Array<{
|
|
29
|
+
toolCallId: string;
|
|
30
|
+
turn: number;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
export interface SubagentEagerToolUsageState {
|
|
34
|
+
agentId: string;
|
|
35
|
+
toolUsageCounts: Array<{
|
|
36
|
+
toolName: string;
|
|
37
|
+
count: number;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export interface SubagentGraphResumeState {
|
|
41
|
+
toolCallSteps: SubagentToolCallStepReference[];
|
|
42
|
+
toolSessions: SubagentToolSessionReference[];
|
|
43
|
+
toolNodes: SubagentToolNodeResumeState[];
|
|
44
|
+
eagerToolUsage: SubagentEagerToolUsageState[];
|
|
45
|
+
eagerToolSuppressions: string[];
|
|
46
|
+
toolOutputReferences?: ToolOutputReferenceState;
|
|
47
|
+
}
|
|
48
|
+
/** Private checkpoint payload linking a parent pause to an exact child state. */
|
|
49
|
+
export interface SubagentResumeExecution {
|
|
50
|
+
parentToolCallId: string;
|
|
51
|
+
childRunId: string;
|
|
52
|
+
approvalExecutionScope: string;
|
|
53
|
+
checkpoints: SubagentCheckpointReference[];
|
|
54
|
+
graphState: SubagentGraphResumeState;
|
|
55
|
+
approvalReplays: ToolApprovalReplaySnapshot[];
|
|
56
|
+
descendant?: SubagentResumeManifest;
|
|
57
|
+
}
|
|
58
|
+
/** Private checkpoint payload linking a parent pause to every child state. */
|
|
59
|
+
export interface SubagentResumeManifest {
|
|
60
|
+
version: 1;
|
|
61
|
+
executions: SubagentResumeExecution[];
|
|
62
|
+
}
|
|
63
|
+
export declare function getSubagentResumeManifest(payload: unknown): SubagentResumeManifest | undefined;
|
|
64
|
+
export declare function requireValidSubagentResumeManifest(payload: unknown): SubagentResumeManifest | undefined;
|
|
65
|
+
export declare function attachSubagentResumeManifest(payload: unknown, manifest: SubagentResumeManifest): object;
|
|
66
|
+
export declare function stripSubagentResumeManifest(payload: unknown): unknown;
|
|
67
|
+
export declare const SUBAGENT_REPLAY_CONTROLLER: unique symbol;
|
|
68
|
+
export type SettledSubagentToolOutput = {
|
|
69
|
+
output: ToolMessage;
|
|
70
|
+
additionalContexts: string[];
|
|
71
|
+
resolvedArgs?: Record<string, unknown>;
|
|
72
|
+
referenceContent?: string;
|
|
73
|
+
};
|
|
74
|
+
export interface SubagentReplayController {
|
|
75
|
+
getResumeManifest?(parentToolCallIds?: ReadonlySet<string>): Promise<SubagentResumeManifest | undefined>;
|
|
76
|
+
getSettledOutput(call: ToolCall, config: RunnableConfig): Promise<SettledSubagentToolOutput | undefined>;
|
|
77
|
+
persistSettledOutput(call: ToolCall, config: RunnableConfig, settled: SettledSubagentToolOutput): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
export type ReplayableSubagentTool = {
|
|
80
|
+
[SUBAGENT_REPLAY_CONTROLLER]?: SubagentReplayController;
|
|
81
|
+
};
|
|
@@ -53,6 +53,14 @@ export type ToolOutputReferenceRegistryOptions = {
|
|
|
53
53
|
*/
|
|
54
54
|
maxActiveRuns?: number;
|
|
55
55
|
};
|
|
56
|
+
export interface ToolOutputReferenceState {
|
|
57
|
+
entries: Array<{
|
|
58
|
+
key: string;
|
|
59
|
+
value: string;
|
|
60
|
+
}>;
|
|
61
|
+
turnCounter: number;
|
|
62
|
+
warnedNonStringTools: string[];
|
|
63
|
+
}
|
|
56
64
|
/**
|
|
57
65
|
* Result of resolving placeholders in tool args.
|
|
58
66
|
*/
|
|
@@ -189,6 +197,10 @@ export declare class ToolOutputReferenceRegistry {
|
|
|
189
197
|
* completed.
|
|
190
198
|
*/
|
|
191
199
|
snapshot(runId: string | undefined): ToolOutputResolveView;
|
|
200
|
+
/** Captures the checkpoint-safe state needed to resume one run bucket. */
|
|
201
|
+
snapshotState(runId: string | undefined): ToolOutputReferenceState;
|
|
202
|
+
/** Restores a checkpointed run bucket under the current resume scope. */
|
|
203
|
+
restoreState(runId: string | undefined, state: ToolOutputReferenceState): void;
|
|
192
204
|
private resolveAgainst;
|
|
193
205
|
private transform;
|
|
194
206
|
private replaceInString;
|
|
@@ -524,11 +524,11 @@ export interface AgentInputs {
|
|
|
524
524
|
* raise a LangGraph `interrupt()` (e.g. a tool built on `askUserQuestion()`) —
|
|
525
525
|
* the host-side event handler runs outside the graph task, where `interrupt()`
|
|
526
526
|
* throws. Do NOT also list these tools in `toolDefinitions` (they would be bound
|
|
527
|
-
* twice). NOT inherited by SELF-SPAWNED subagent children
|
|
528
|
-
* shallow
|
|
529
|
-
*
|
|
530
|
-
* `
|
|
531
|
-
*
|
|
527
|
+
* twice). NOT inherited by SELF-SPAWNED subagent children: `buildChildInputs`
|
|
528
|
+
* scrubs the shallow-spread parent copy so parent-scoped direct tools are not
|
|
529
|
+
* exposed to a child implicitly. An EXPLICIT child config that lists its own
|
|
530
|
+
* `graphTools` keeps them; with HITL enabled, those tools share the parent's
|
|
531
|
+
* checkpointer and may pause and resume inside the child graph.
|
|
532
532
|
*
|
|
533
533
|
* Deliberately `GenericTool[]`, not `GraphTools`: the wider union admits
|
|
534
534
|
* schema-only shapes (OpenAI `BindToolsInput`, Google tool objects) that
|
|
@@ -97,6 +97,17 @@ export type ToolApprovalDecisionMap = Record<string, ToolApprovalDecision>;
|
|
|
97
97
|
* below; this type alias is primarily an integration-layer contract.
|
|
98
98
|
*/
|
|
99
99
|
export type HumanInterruptType = 'tool_approval' | 'ask_user_question';
|
|
100
|
+
/** Identifies an interrupt that originated inside a checkpointed subagent. */
|
|
101
|
+
export interface SubagentInterruptScope {
|
|
102
|
+
/** Child execution run id used by subagent update and usage events. */
|
|
103
|
+
run_id: string;
|
|
104
|
+
/** Child agent id that owns the interrupted tool call. */
|
|
105
|
+
agent_id: string;
|
|
106
|
+
/** Configured subagent type selected by the parent tool call. */
|
|
107
|
+
subagent_type: string;
|
|
108
|
+
/** Parent `subagent` tool call that launched this child. */
|
|
109
|
+
parent_tool_call_id?: string;
|
|
110
|
+
}
|
|
100
111
|
/**
|
|
101
112
|
* Structured payload the SDK passes to `interrupt()` when one or more
|
|
102
113
|
* pending tool calls require host approval. All `ask`-decision tool calls
|
|
@@ -110,6 +121,10 @@ export interface ToolApprovalInterruptPayload {
|
|
|
110
121
|
type: 'tool_approval';
|
|
111
122
|
action_requests: ToolApprovalRequest[];
|
|
112
123
|
review_configs: ToolApprovalReviewConfig[];
|
|
124
|
+
/** Hook-registry session whose policy raised this interrupt. */
|
|
125
|
+
hook_session_id?: string;
|
|
126
|
+
/** Present when the approval request was bridged from a child graph. */
|
|
127
|
+
subagent?: SubagentInterruptScope;
|
|
113
128
|
}
|
|
114
129
|
/**
|
|
115
130
|
* Pre-defined option the user can pick when answering an
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@librechat/agents",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.1",
|
|
4
|
+
"reova": {
|
|
5
|
+
"enabled": true,
|
|
6
|
+
"endpoint": "https://telemetry.reo.dev/data"
|
|
7
|
+
},
|
|
4
8
|
"main": "./dist/cjs/main.cjs",
|
|
5
9
|
"module": "./dist/esm/main.mjs",
|
|
6
10
|
"types": "./dist/types/index.d.ts",
|
|
@@ -248,7 +252,7 @@
|
|
|
248
252
|
"nanoid": "^3.3.7",
|
|
249
253
|
"okapibm25": "^1.4.1",
|
|
250
254
|
"openai": "^6.46.0",
|
|
251
|
-
"
|
|
255
|
+
"reova": "^0.4.1",
|
|
252
256
|
"socks-proxy-agent": "^8.0.5",
|
|
253
257
|
"uuid": "^11.1.1"
|
|
254
258
|
},
|