@librechat/agents 3.3.13 → 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 +121 -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/anthropic/index.cjs +35 -206
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +121 -241
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs +19 -12
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +3 -3
- package/dist/cjs/llm/invoke.cjs +2 -2
- package/dist/cjs/llm/mistral/index.cjs +26 -0
- package/dist/cjs/llm/mistral/index.cjs.map +1 -0
- package/dist/cjs/llm/openai/index.cjs +82 -80
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs +19 -19
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/stream/chunkAdapters.cjs +198 -0
- package/dist/cjs/llm/stream/chunkAdapters.cjs.map +1 -0
- package/dist/cjs/llm/stream/smoother.cjs +369 -0
- package/dist/cjs/llm/stream/smoother.cjs.map +1 -0
- package/dist/cjs/llm/vertexai/index.cjs +13 -1
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +25 -16
- 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 +664 -80
- 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/cjs/utils/tokens.cjs +76 -29
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +121 -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/anthropic/index.mjs +34 -205
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +120 -240
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +19 -12
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +2 -2
- package/dist/esm/llm/mistral/index.mjs +26 -0
- package/dist/esm/llm/mistral/index.mjs.map +1 -0
- package/dist/esm/llm/openai/index.mjs +82 -80
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs +3 -3
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/stream/chunkAdapters.mjs +195 -0
- package/dist/esm/llm/stream/chunkAdapters.mjs.map +1 -0
- package/dist/esm/llm/stream/smoother.mjs +365 -0
- package/dist/esm/llm/stream/smoother.mjs.map +1 -0
- package/dist/esm/llm/vertexai/index.mjs +13 -1
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +13 -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 +665 -81
- 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/esm/utils/tokens.mjs +76 -30
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +19 -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/index.d.ts +3 -0
- package/dist/types/llm/google/index.d.ts +2 -0
- package/dist/types/llm/mistral/index.d.ts +11 -0
- package/dist/types/llm/openai/index.d.ts +20 -4
- package/dist/types/llm/openrouter/index.d.ts +4 -1
- package/dist/types/llm/stream/chunkAdapters.d.ts +48 -0
- package/dist/types/llm/stream/smoother.d.ts +95 -0
- package/dist/types/llm/vertexai/index.d.ts +2 -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 +49 -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/dist/types/types/llm.d.ts +21 -14
- package/dist/types/utils/tokens.d.ts +10 -0
- package/package.json +6 -2
- package/src/graphs/Graph.ts +257 -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/index.ts +8 -0
- package/src/llm/anthropic/index.ts +85 -354
- package/src/llm/bedrock/index.ts +174 -390
- package/src/llm/bedrock/llm.spec.ts +2 -0
- package/src/llm/bedrock/streamSealDispatch.test.ts +76 -0
- package/src/llm/custom-chat-models.smoke.test.ts +16 -1
- package/src/llm/google/index.ts +17 -18
- package/src/llm/google/streamSmoothing.test.ts +121 -0
- package/src/llm/mistral/index.ts +33 -0
- package/src/llm/mistral/streamSmoothing.test.ts +97 -0
- package/src/llm/openai/deepseek.test.ts +56 -0
- package/src/llm/openai/index.ts +119 -126
- package/src/llm/openrouter/index.ts +4 -1
- package/src/llm/providers.ts +3 -3
- package/src/llm/stream/chunkAdapters.test.ts +202 -0
- package/src/llm/stream/chunkAdapters.ts +317 -0
- package/src/llm/stream/reassembly.test.ts +241 -0
- package/src/llm/stream/smoother.bench.test.ts +155 -0
- package/src/llm/stream/smoother.test.ts +519 -0
- package/src/llm/stream/smoother.ts +574 -0
- package/src/llm/vertexai/index.ts +17 -1
- package/src/llm/vertexai/streamSmoothing.test.ts +109 -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/specs/subagent.test.ts +44 -0
- package/src/specs/tokens.test.ts +159 -14
- 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 +590 -7
- 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 +1438 -136
- 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
- package/src/types/llm.ts +53 -36
- package/src/utils/tokens.ts +115 -30
|
@@ -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/index.d.ts
CHANGED
|
@@ -42,6 +42,9 @@ export { CustomOpenAIClient } from './llm/openai';
|
|
|
42
42
|
export { ChatOpenRouter } from './llm/openrouter';
|
|
43
43
|
export type { OpenRouterReasoning, OpenRouterReasoningEffort, ChatOpenRouterCallOptions, } from './llm/openrouter';
|
|
44
44
|
export { getChatModelClass } from './llm/providers';
|
|
45
|
+
export { CustomChatMistralAI } from './llm/mistral';
|
|
46
|
+
export { smoothStream, resolveStreamDelay, DEFAULT_STREAM_DELAY, computeAdaptivePieceSize, } from './llm/stream/smoother';
|
|
47
|
+
export type { SmoothItem, SmoothPiece } from './llm/stream/smoother';
|
|
45
48
|
export { FakeChatModel, createFakeStreamingLLM } from './llm/fake';
|
|
46
49
|
export { initializeModel } from './llm/init';
|
|
47
50
|
export { attemptInvoke, tryFallbackProviders } from './llm/invoke';
|
|
@@ -5,6 +5,7 @@ import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager
|
|
|
5
5
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
6
6
|
import type { GoogleClientOptions, GoogleThinkingConfig } from '@/types';
|
|
7
7
|
export declare class CustomChatGoogleGenerativeAI extends ChatGoogleGenerativeAI {
|
|
8
|
+
_lc_stream_delay: number;
|
|
8
9
|
thinkingConfig?: GoogleThinkingConfig;
|
|
9
10
|
includeServerSideToolInvocations?: boolean;
|
|
10
11
|
/**
|
|
@@ -21,4 +22,5 @@ export declare class CustomChatGoogleGenerativeAI extends ChatGoogleGenerativeAI
|
|
|
21
22
|
invocationParams(options?: this['ParsedCallOptions']): Omit<GenerateContentRequest, 'contents'>;
|
|
22
23
|
_generate(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): Promise<import('@langchain/core/outputs').ChatResult>;
|
|
23
24
|
_streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
25
|
+
private _streamProviderChunks;
|
|
24
26
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ChatMistralAI } from '@langchain/mistralai';
|
|
2
|
+
import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
|
|
3
|
+
import type { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
4
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
5
|
+
import type { MistralAIClientOptions } from '@/types';
|
|
6
|
+
export declare class CustomChatMistralAI extends ChatMistralAI {
|
|
7
|
+
_lc_stream_delay: number;
|
|
8
|
+
static lc_name(): 'LibreChatMistralAI';
|
|
9
|
+
constructor(fields?: MistralAIClientOptions);
|
|
10
|
+
_streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
11
|
+
}
|
|
@@ -10,6 +10,7 @@ import type { BindToolsInput } from '@langchain/core/language_models/chat_models
|
|
|
10
10
|
import type { ChatResult } from '@langchain/core/outputs';
|
|
11
11
|
import type { ChatXAIInput } from '@langchain/xai';
|
|
12
12
|
import type * as t from '@langchain/openai';
|
|
13
|
+
import type { SmoothItem } from '@/llm/stream/smoother';
|
|
13
14
|
import type { HeaderValue, HeadersLike } from './types';
|
|
14
15
|
import type { PromptCacheTtl } from '@/messages/cache';
|
|
15
16
|
export declare function isHeaders(headers: unknown): headers is Headers;
|
|
@@ -44,6 +45,21 @@ export declare function shouldIncludeEncryptedReasoning(model: string, params: {
|
|
|
44
45
|
export declare function getCacheWriteTokens(message: BaseMessage): number | undefined;
|
|
45
46
|
export declare function attachCacheWriteUsage(message: BaseMessage): void;
|
|
46
47
|
export declare function attachCacheWriteMetadata(response: OpenAIClient.Responses.Response): OpenAIClient.Responses.Response;
|
|
48
|
+
/**
|
|
49
|
+
* Classifies a generation chunk for the smoothing engine:
|
|
50
|
+
* - splittable: plain visible text (string content equal to `chunk.text`, no
|
|
51
|
+
* logprobs / finish_reason) — sliced adaptively at the pacing cadence.
|
|
52
|
+
* ANY logprobs value blocks splitting here (this family only attaches
|
|
53
|
+
* logprobs on request; the DeepSeek suite pins chunks with them staying
|
|
54
|
+
* intact) — deliberately stricter than `stream/chunkAdapters.ts`, where
|
|
55
|
+
* google-common's always-present empty logprobs must not block.
|
|
56
|
+
* - atomic: text- or reasoning-bearing chunks whose metadata cannot survive
|
|
57
|
+
* slicing — paced as one piece, never split (legacy parity: these were
|
|
58
|
+
* emitted whole but still paced).
|
|
59
|
+
* - passthrough: tool-call deltas, usage-only, finish_reason and other
|
|
60
|
+
* metadata chunks — strict FIFO, zero delay.
|
|
61
|
+
*/
|
|
62
|
+
export declare function toSmoothItem(chunk: ChatGenerationChunk): SmoothItem<ChatGenerationChunk>;
|
|
47
63
|
export declare function emitStreamChunkCallback(chunk: ChatGenerationChunk, runManager?: CallbackManagerForLLMRun): Promise<void>;
|
|
48
64
|
export declare function _convertToOpenAITool(tool: BindToolsInput, fields?: {
|
|
49
65
|
/**
|
|
@@ -61,7 +77,7 @@ export declare class CustomAzureOpenAIClient extends AzureOpenAIClient {
|
|
|
61
77
|
fetchWithTimeout(url: RequestInfo, init: RequestInit | undefined, ms: number, controller: AbortController): Promise<Response>;
|
|
62
78
|
}
|
|
63
79
|
export declare class ChatOpenAI extends OriginalChatOpenAI<t.ChatOpenAICallOptions> {
|
|
64
|
-
_lc_stream_delay
|
|
80
|
+
_lc_stream_delay: number;
|
|
65
81
|
constructor(fields?: LibreChatOpenAIFields & t.OpenAIChatInput['modelKwargs']);
|
|
66
82
|
get exposedClient(): CustomOpenAIClient;
|
|
67
83
|
static lc_name(): string;
|
|
@@ -81,7 +97,7 @@ export declare class ChatOpenAI extends OriginalChatOpenAI<t.ChatOpenAICallOptio
|
|
|
81
97
|
protected _streamRawResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
82
98
|
}
|
|
83
99
|
export declare class AzureChatOpenAI extends OriginalAzureChatOpenAI {
|
|
84
|
-
_lc_stream_delay
|
|
100
|
+
_lc_stream_delay: number;
|
|
85
101
|
constructor(fields?: LibreChatAzureOpenAIFields);
|
|
86
102
|
get exposedClient(): CustomOpenAIClient;
|
|
87
103
|
static lc_name(): 'LibreChatAzureOpenAI';
|
|
@@ -95,7 +111,7 @@ export declare class AzureChatOpenAI extends OriginalAzureChatOpenAI {
|
|
|
95
111
|
_streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
96
112
|
}
|
|
97
113
|
export declare class ChatDeepSeek extends OriginalChatDeepSeek {
|
|
98
|
-
_lc_stream_delay
|
|
114
|
+
_lc_stream_delay: number;
|
|
99
115
|
constructor(fields?: ConstructorParameters<typeof OriginalChatDeepSeek>[0] & {
|
|
100
116
|
_lc_stream_delay?: number;
|
|
101
117
|
});
|
|
@@ -139,7 +155,7 @@ export declare class ChatMoonshot extends ChatOpenAI {
|
|
|
139
155
|
static lc_name(): 'LibreChatMoonshot';
|
|
140
156
|
}
|
|
141
157
|
export declare class ChatXAI extends OriginalChatXAI {
|
|
142
|
-
_lc_stream_delay
|
|
158
|
+
_lc_stream_delay: number;
|
|
143
159
|
constructor(fields?: Partial<ChatXAIInput> & {
|
|
144
160
|
configuration?: {
|
|
145
161
|
baseURL?: string;
|
|
@@ -26,7 +26,10 @@ export interface ChatOpenRouterCallOptions extends Omit<ChatOpenAICallOptions, '
|
|
|
26
26
|
*/
|
|
27
27
|
promptCacheTtl?: PromptCacheTtl;
|
|
28
28
|
}
|
|
29
|
-
export type ChatOpenRouterInput = Partial<ChatOpenRouterCallOptions & OpenAIChatInput
|
|
29
|
+
export type ChatOpenRouterInput = Partial<ChatOpenRouterCallOptions & OpenAIChatInput> & {
|
|
30
|
+
/** Minimum delay in ms between visible streamed deltas (default 25; 0 disables). */
|
|
31
|
+
_lc_stream_delay?: number;
|
|
32
|
+
};
|
|
30
33
|
/** invocationParams return type extended with OpenRouter reasoning */
|
|
31
34
|
export type OpenRouterInvocationParams = Omit<OpenAIClient.Chat.ChatCompletionCreateParams, 'messages'> & {
|
|
32
35
|
reasoning?: OpenRouterReasoning;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AIMessageChunk } from '@langchain/core/messages';
|
|
2
|
+
import { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
3
|
+
import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
|
|
4
|
+
import type { SmoothItem, SmoothPiece } from '@/llm/stream/smoother';
|
|
5
|
+
/**
|
|
6
|
+
* Rebuilds a generation chunk carrying one piece of a split plain-text chunk.
|
|
7
|
+
* Unsplit pieces return the original chunk untouched, so disabled smoothing is
|
|
8
|
+
* byte-identical to no smoothing. Usage metadata, additional kwargs and
|
|
9
|
+
* response metadata survive only on the first piece: the aggregator merges
|
|
10
|
+
* dicts by concatenating string fields, so replicating them across pieces
|
|
11
|
+
* would duplicate reasoning text and scalar metadata once per piece.
|
|
12
|
+
*/
|
|
13
|
+
export declare function cloneGenerationChunkPiece(chunk: ChatGenerationChunk, piece: SmoothPiece): ChatGenerationChunk;
|
|
14
|
+
/**
|
|
15
|
+
* Chunks that pair visible text with reasoning payloads in
|
|
16
|
+
* `additional_kwargs` (Gemini thought summaries, reasoning_content deltas,
|
|
17
|
+
* OpenRouter reasoning_details) must pace whole: split pieces would each
|
|
18
|
+
* carry the same kwargs and downstream merging — the aggregator's dict merge
|
|
19
|
+
* or OpenRouter's reasoning_details accumulation — duplicates them once per
|
|
20
|
+
* piece.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Mixed text/tool-call deltas must never split: cloned pieces would each
|
|
24
|
+
* carry the same tool_call_chunks and downstream accumulation would corrupt
|
|
25
|
+
* the assembled tool arguments.
|
|
26
|
+
*/
|
|
27
|
+
export declare function hasToolCallChunks(message: AIMessageChunk): boolean;
|
|
28
|
+
export declare function hasReasoningKwargs(message: AIMessageChunk): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Extracts the visible reasoning text a kwargs-borne delta contributes, so
|
|
31
|
+
* reasoning-only chunks (Gemini thoughts, DeepSeek reasoning_content,
|
|
32
|
+
* OpenAI reasoning summaries, OpenRouter reasoning_details) pace atomically
|
|
33
|
+
* at the cadence instead of passing through unsmoothed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getReasoningKwargsText(message: AIMessageChunk): string;
|
|
36
|
+
export declare function toGenerationSmoothItem(chunk: ChatGenerationChunk, getAtomicText?: (message: AIMessageChunk) => string): SmoothItem<ChatGenerationChunk>;
|
|
37
|
+
/**
|
|
38
|
+
* Wraps a provider's raw chunk stream with adaptive smoothing and per-piece
|
|
39
|
+
* `handleLLMNewToken` dispatch. The raw stream must NOT dispatch runManager
|
|
40
|
+
* callbacks itself — callback-echo consumers would otherwise observe the
|
|
41
|
+
* unsmoothed deltas.
|
|
42
|
+
*/
|
|
43
|
+
export declare function smoothGenerationChunks({ chunks, delayMs, signal, runManager, }: {
|
|
44
|
+
chunks: AsyncGenerator<ChatGenerationChunk>;
|
|
45
|
+
delayMs: number;
|
|
46
|
+
signal?: AbortSignal;
|
|
47
|
+
runManager?: CallbackManagerForLLMRun;
|
|
48
|
+
}): AsyncGenerator<ChatGenerationChunk>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export declare const DEFAULT_STREAM_DELAY = 25;
|
|
2
|
+
export declare const SMOOTH_TARGET_LATENCY_MS = 250;
|
|
3
|
+
export declare const MAX_STREAM_QUEUE_CHUNKS = 256;
|
|
4
|
+
export declare const MAX_STREAM_QUEUE_TEXT_CHARS = 8192;
|
|
5
|
+
export declare const MAX_SMOOTH_ITEM_SEGMENT_CHARS = 4096;
|
|
6
|
+
export declare const STREAM_CHUNK_MIN_SIZE = 4;
|
|
7
|
+
export declare const STREAM_BOUNDARIES: ReadonlySet<string>;
|
|
8
|
+
export declare const STREAM_ABORT_MESSAGE = "AbortError: User aborted the request.";
|
|
9
|
+
export declare const STREAM_PRODUCER_FAILURE = "Stream producer failed.";
|
|
10
|
+
/**
|
|
11
|
+
* How long generator teardown waits for the background producer to observe a
|
|
12
|
+
* consumer close before abandoning it. Well-behaved streams settle in
|
|
13
|
+
* microseconds (the next enqueue throws); a stalled provider that ignores
|
|
14
|
+
* aborts otherwise blocks teardown — and abort propagation — indefinitely.
|
|
15
|
+
* An abandoned producer still self-terminates on its next enqueue attempt.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PRODUCER_CLOSE_GRACE_MS = 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Resolves a configured stream delay to its effective value (default 25ms;
|
|
20
|
+
* 0 disables smoothing). Non-finite inputs (NaN from a malformed config
|
|
21
|
+
* value, ±Infinity) normalize to the default rather than poisoning piece
|
|
22
|
+
* arithmetic downstream.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveStreamDelay(delay?: number): number;
|
|
25
|
+
export declare function isSignalAborted(signal?: AbortSignal): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* How far past the target size the word-boundary search may extend before
|
|
28
|
+
* hard-cutting. Natural language hits a boundary within a few characters;
|
|
29
|
+
* boundary-free runs (base64, minified data, long identifiers) must not
|
|
30
|
+
* stretch a piece — or an admission segment — arbitrarily far past its
|
|
31
|
+
* budget.
|
|
32
|
+
*/
|
|
33
|
+
export declare const STREAM_BOUNDARY_LOOKAHEAD_CHARS = 64;
|
|
34
|
+
export declare function findStreamChunkBoundary(text: string, minSize: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Backlog-proportional piece sizing: emit enough per tick that the current
|
|
37
|
+
* backlog drains in ~`targetLatencyMs`, so render lag stays pinned near the
|
|
38
|
+
* target regardless of how fast the provider streams. Token-sized arrivals
|
|
39
|
+
* never exceed the minimum piece, matching the legacy fixed-size splitter.
|
|
40
|
+
*/
|
|
41
|
+
export declare function computeAdaptivePieceSize(bufferedTextLength: number, tickMs: number, targetLatencyMs?: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* A cadence, not an additive sleep: time the consumer already spent since the
|
|
44
|
+
* last visible emission counts against the target delay, so slow downstream
|
|
45
|
+
* handlers never compound latency.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getCadencedStreamDelay({ targetDelay, lastVisibleTextAt, now, }: {
|
|
48
|
+
targetDelay: number;
|
|
49
|
+
lastVisibleTextAt?: number;
|
|
50
|
+
now: number;
|
|
51
|
+
}): number;
|
|
52
|
+
/** Abort-aware sleep that resolves (never rejects) on abort; callers re-check the signal. */
|
|
53
|
+
export declare function waitForStreamDelay(delay: number, signal?: AbortSignal): Promise<void>;
|
|
54
|
+
export type SmoothPiece = {
|
|
55
|
+
text: string;
|
|
56
|
+
isFirst: boolean;
|
|
57
|
+
isLast: boolean;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* One classified unit of provider stream output.
|
|
61
|
+
*
|
|
62
|
+
* - `smooth: true` — visible text, paced at the configured cadence and (unless
|
|
63
|
+
* `atomic`) sliced adaptively at dequeue time.
|
|
64
|
+
* - `atomic: true` — paced as a single piece, never split (text-bearing chunks
|
|
65
|
+
* whose metadata cannot survive slicing, e.g. logprobs / finish_reason).
|
|
66
|
+
* - `smooth: false` — passthrough: tool-call deltas, usage-only, id-only and
|
|
67
|
+
* seal chunks. Zero delay, strict FIFO with the text around them.
|
|
68
|
+
*
|
|
69
|
+
* `emit` builds the provider-specific output for one piece; `isFirst` lets
|
|
70
|
+
* providers keep usage_metadata on only the first piece of a split.
|
|
71
|
+
*/
|
|
72
|
+
export type SmoothItem<TEmit> = {
|
|
73
|
+
text: string;
|
|
74
|
+
smooth: boolean;
|
|
75
|
+
atomic?: boolean;
|
|
76
|
+
emit: (piece: SmoothPiece) => TEmit;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Bounded producer/consumer smoothing engine.
|
|
80
|
+
*
|
|
81
|
+
* The producer drains `source` eagerly into a bounded queue (the buffer is the
|
|
82
|
+
* backlog measurement adaptive sizing needs); at capacity it parks, applying
|
|
83
|
+
* backpressure to the underlying stream. The consumer emits paced pieces,
|
|
84
|
+
* decrementing the text budget and waking the producer *before* each cadenced
|
|
85
|
+
* sleep so the provider stream keeps being read during pacing.
|
|
86
|
+
*
|
|
87
|
+
* `delayMs <= 0` disables smoothing entirely: every item passes through FIFO,
|
|
88
|
+
* unsplit and undelayed.
|
|
89
|
+
*/
|
|
90
|
+
export declare function smoothStream<TEmit>({ source, delayMs, signal, abortUpstream, }: {
|
|
91
|
+
source: AsyncIterable<SmoothItem<TEmit>>;
|
|
92
|
+
delayMs: number;
|
|
93
|
+
signal?: AbortSignal;
|
|
94
|
+
abortUpstream?: () => void;
|
|
95
|
+
}): AsyncGenerator<TEmit>;
|
|
@@ -340,6 +340,7 @@ export declare function fixThoughtSignatures(contents: GeminiContent[], input: B
|
|
|
340
340
|
*/
|
|
341
341
|
export declare class ChatVertexAI extends ChatGoogle {
|
|
342
342
|
lc_namespace: string[];
|
|
343
|
+
_lc_stream_delay: number;
|
|
343
344
|
dynamicThinkingBudget: boolean;
|
|
344
345
|
thinkingConfig?: GoogleThinkingConfig;
|
|
345
346
|
static lc_name(): 'LibreChatVertexAI';
|
|
@@ -347,5 +348,6 @@ export declare class ChatVertexAI extends ChatGoogle {
|
|
|
347
348
|
constructor(fields?: VertexAIClientOptions);
|
|
348
349
|
invocationParams(options?: this['ParsedCallOptions'] | undefined): GoogleAIModelRequestParams;
|
|
349
350
|
_streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
|
|
351
|
+
private _streamRepairedChunks;
|
|
350
352
|
buildConnection(fields: VertexAIClientOptions | undefined, client: GoogleAbstractedClient): void;
|
|
351
353
|
}
|
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
|
|
@@ -192,6 +231,9 @@ export declare function summarizeEvent(eventName: string, data: unknown): string
|
|
|
192
231
|
* pure tool_use (e.g. the subagent hit `maxTurns` mid-tool-call), the walk
|
|
193
232
|
* continues to earlier AIMessages so partial progress is salvaged — this
|
|
194
233
|
* matches Claude Code's behavior in `agentToolUtils.finalizeAgentTool`.
|
|
234
|
+
* Consecutive streamed text-delta blocks with the same provider index are
|
|
235
|
+
* coalesced without adding whitespace. Annotation-only text blocks are
|
|
236
|
+
* ignored; complete text blocks and distinct delta indexes remain separated.
|
|
195
237
|
* Returns "Task completed" only when no AIMessage in the history contains
|
|
196
238
|
* any text.
|
|
197
239
|
*/
|
|
@@ -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;
|