@librechat/agents 3.3.3 → 3.3.5
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 +2 -1
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/constants.cjs +21 -0
- package/dist/cjs/common/constants.cjs.map +1 -1
- package/dist/cjs/events.cjs +10 -1
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +793 -111
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +3 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/hooks/HookRegistry.cjs +25 -0
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
- package/dist/cjs/hooks/index.cjs +12 -0
- package/dist/cjs/hooks/index.cjs.map +1 -1
- package/dist/cjs/hooks/types.cjs +1 -0
- package/dist/cjs/hooks/types.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +8 -0
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +79 -6
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +38 -13
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +19 -7
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/invoke.cjs +331 -5
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +41 -5
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +25 -4
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +4 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/preempt.cjs +132 -0
- package/dist/cjs/llm/preempt.cjs.map +1 -0
- package/dist/cjs/main.cjs +36 -5
- package/dist/cjs/messages/alternation.cjs +92 -0
- package/dist/cjs/messages/alternation.cjs.map +1 -0
- package/dist/cjs/messages/cache.cjs +54 -33
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/contextPruning.cjs +17 -43
- package/dist/cjs/messages/contextPruning.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +315 -23
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +290 -60
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/handoffCue.cjs +63 -0
- package/dist/cjs/messages/handoffCue.cjs.map +1 -0
- package/dist/cjs/messages/index.cjs +4 -1
- package/dist/cjs/messages/injected.cjs +60 -0
- package/dist/cjs/messages/injected.cjs.map +1 -0
- package/dist/cjs/messages/prune.cjs +503 -127
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +80 -7
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/handlers.cjs +18 -9
- package/dist/cjs/session/handlers.cjs.map +1 -1
- package/dist/cjs/stream.cjs +35 -10
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +28 -14
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +56 -63
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/search/keenable-scraper.cjs +90 -0
- package/dist/cjs/tools/search/keenable-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +9 -1
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/toolOutputReferences.cjs +6 -0
- package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +1 -1
- package/dist/cjs/utils/llm.cjs +1 -1
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +307 -20
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/cjs/utils/toolContent.cjs +1514 -0
- package/dist/cjs/utils/toolContent.cjs.map +1 -0
- package/dist/esm/agents/AgentContext.mjs +2 -1
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/constants.mjs +19 -1
- package/dist/esm/common/constants.mjs.map +1 -1
- package/dist/esm/events.mjs +10 -1
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +798 -116
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +3 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/hooks/HookRegistry.mjs +25 -0
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
- package/dist/esm/hooks/index.mjs +12 -1
- package/dist/esm/hooks/index.mjs.map +1 -1
- package/dist/esm/hooks/types.mjs +1 -0
- package/dist/esm/hooks/types.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +9 -1
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +79 -6
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +38 -13
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +19 -7
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/invoke.mjs +332 -8
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +41 -5
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +25 -4
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +4 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/preempt.mjs +131 -0
- package/dist/esm/llm/preempt.mjs.map +1 -0
- package/dist/esm/main.mjs +14 -11
- package/dist/esm/messages/alternation.mjs +91 -0
- package/dist/esm/messages/alternation.mjs.map +1 -0
- package/dist/esm/messages/cache.mjs +55 -34
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/contextPruning.mjs +17 -43
- package/dist/esm/messages/contextPruning.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +305 -24
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +290 -61
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/handoffCue.mjs +61 -0
- package/dist/esm/messages/handoffCue.mjs.map +1 -0
- package/dist/esm/messages/index.mjs +4 -1
- package/dist/esm/messages/injected.mjs +60 -0
- package/dist/esm/messages/injected.mjs.map +1 -0
- package/dist/esm/messages/prune.mjs +500 -128
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +80 -7
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/handlers.mjs +19 -10
- package/dist/esm/session/handlers.mjs.map +1 -1
- package/dist/esm/stream.mjs +34 -11
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +28 -14
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +56 -63
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/search/keenable-scraper.mjs +88 -0
- package/dist/esm/tools/search/keenable-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +9 -1
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/toolOutputReferences.mjs +6 -0
- package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +1 -1
- package/dist/esm/utils/llm.mjs +1 -1
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +307 -21
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/esm/utils/toolContent.mjs +1503 -0
- package/dist/esm/utils/toolContent.mjs.map +1 -0
- package/dist/types/common/constants.d.ts +18 -0
- package/dist/types/graphs/Graph.d.ts +139 -2
- package/dist/types/hooks/HookRegistry.d.ts +15 -0
- package/dist/types/hooks/index.d.ts +12 -1
- package/dist/types/hooks/types.d.ts +45 -6
- package/dist/types/index.d.ts +1 -1
- package/dist/types/llm/invoke.d.ts +34 -1
- package/dist/types/llm/openai/index.d.ts +4 -0
- package/dist/types/llm/openai/utils/index.d.ts +2 -0
- package/dist/types/llm/openrouter/index.d.ts +5 -0
- package/dist/types/llm/preempt.d.ts +40 -0
- package/dist/types/messages/alternation.d.ts +23 -0
- package/dist/types/messages/contextPruning.d.ts +2 -1
- package/dist/types/messages/core.d.ts +36 -0
- package/dist/types/messages/format.d.ts +6 -0
- package/dist/types/messages/handoffCue.d.ts +40 -0
- package/dist/types/messages/index.d.ts +3 -0
- package/dist/types/messages/injected.d.ts +3 -0
- package/dist/types/messages/prune.d.ts +16 -12
- package/dist/types/run.d.ts +7 -0
- package/dist/types/stream.d.ts +14 -0
- package/dist/types/tools/ToolNode.d.ts +0 -7
- package/dist/types/tools/search/keenable-scraper.d.ts +15 -0
- package/dist/types/tools/search/types.d.ts +31 -2
- package/dist/types/types/graph.d.ts +8 -1
- package/dist/types/types/run.d.ts +65 -0
- package/dist/types/types/stream.d.ts +1 -26
- package/dist/types/utils/tokens.d.ts +7 -0
- package/dist/types/utils/toolContent.d.ts +107 -0
- package/package.json +1 -1
- package/src/__tests__/stream.eagerEventExecution.test.ts +74 -0
- package/src/agents/AgentContext.ts +1 -0
- package/src/{splitStream.test.ts → aggregator.test.ts} +59 -666
- package/src/common/constants.ts +21 -0
- package/src/events.ts +15 -1
- package/src/graphs/Graph.ts +1261 -198
- package/src/graphs/MultiAgentGraph.ts +6 -1
- package/src/graphs/__tests__/Graph.contextOverflow.test.ts +1139 -4
- package/src/graphs/__tests__/Graph.preemptSignal.test.ts +126 -0
- package/src/hooks/HookRegistry.ts +40 -0
- package/src/hooks/__tests__/preemptBoundary.test.ts +152 -0
- package/src/hooks/index.ts +16 -2
- package/src/hooks/types.ts +47 -3
- package/src/index.ts +1 -1
- package/src/langfuse.ts +26 -1
- package/src/llm/anthropic/utils/message_inputs.ts +158 -12
- package/src/llm/anthropic/utils/tool-id-normalization.test.ts +109 -0
- package/src/llm/bedrock/utils/message_inputs.test.ts +131 -1
- package/src/llm/bedrock/utils/message_inputs.ts +100 -24
- package/src/llm/bedrock/utils/toolResultCachePoint.test.ts +15 -0
- package/src/llm/google/utils/common.test.ts +75 -9
- package/src/llm/google/utils/common.ts +34 -3
- package/src/llm/invoke.alternation.test.ts +87 -0
- package/src/llm/invoke.handoffCue.test.ts +112 -0
- package/src/llm/invoke.test.ts +488 -0
- package/src/llm/invoke.ts +611 -8
- package/src/llm/openai/index.ts +106 -6
- package/src/llm/openai/utils/index.ts +109 -53
- package/src/llm/openai/utils/messages.test.ts +330 -1
- package/src/llm/openrouter/index.ts +12 -2
- package/src/llm/openrouter/reasoning.test.ts +314 -0
- package/src/llm/preempt.test.ts +323 -0
- package/src/llm/preempt.ts +178 -0
- package/src/messages/__tests__/observationMasking.test.ts +93 -2
- package/src/messages/alternation.test.ts +212 -0
- package/src/messages/alternation.ts +112 -0
- package/src/messages/cache.tail.test.ts +193 -0
- package/src/messages/cache.test.ts +113 -0
- package/src/messages/cache.ts +92 -60
- package/src/messages/contextPruning.test.ts +184 -0
- package/src/messages/contextPruning.ts +49 -42
- package/src/messages/core.ts +653 -40
- package/src/messages/ensureThinkingBlock.test.ts +49 -1
- package/src/messages/foldToollessToolBlocks.test.ts +163 -5
- package/src/messages/format.ts +454 -91
- package/src/messages/formatAgentMessages.steer.test.ts +267 -0
- package/src/messages/formatAgentMessages.test.ts +604 -14
- package/src/messages/formatAgentMessages.tools.test.ts +103 -0
- package/src/messages/handoffCue.test.ts +96 -0
- package/src/messages/handoffCue.ts +78 -0
- package/src/messages/index.ts +3 -0
- package/src/messages/injected.test.ts +90 -0
- package/src/messages/injected.ts +74 -0
- package/src/messages/prune.ts +996 -183
- package/src/run.ts +91 -6
- package/src/scripts/preempt-probe.ts +330 -0
- package/src/scripts/preempt-scenarios.ts +388 -0
- package/src/session/handlers.ts +32 -12
- package/src/specs/handoffCue.test.ts +165 -0
- package/src/specs/langfuse-callbacks.test.ts +352 -2
- package/src/specs/preemptSeal.test.ts +309 -0
- package/src/specs/prune.test.ts +1083 -6
- package/src/specs/summarization-unit.test.ts +105 -0
- package/src/specs/tokens.test.ts +609 -32
- package/src/stream.dispatch.test.ts +63 -0
- package/src/stream.ts +59 -23
- package/src/summarization/__tests__/node.test.ts +77 -0
- package/src/summarization/node.ts +46 -18
- package/src/tools/ToolNode.ts +150 -99
- package/src/tools/__tests__/ToolNode.onResultCompletion.test.ts +148 -1
- package/src/tools/__tests__/ToolNode.outputReferences.test.ts +112 -3
- package/src/tools/__tests__/annotateMessagesForLLM.test.ts +32 -0
- package/src/tools/__tests__/directToolHooks.test.ts +255 -7
- package/src/tools/search/keenable-scraper.test.ts +153 -0
- package/src/tools/search/keenable-scraper.ts +137 -0
- package/src/tools/search/tool.ts +13 -2
- package/src/tools/search/types.ts +50 -3
- package/src/tools/toolOutputReferences.ts +6 -0
- package/src/types/graph.ts +12 -1
- package/src/types/run.ts +67 -0
- package/src/types/stream.ts +1 -42
- package/src/utils/llm.test.ts +18 -0
- package/src/utils/llm.ts +4 -1
- package/src/utils/tokens.ts +586 -31
- package/src/utils/toolContent.test.ts +1432 -0
- package/src/utils/toolContent.ts +2707 -0
- package/dist/cjs/splitStream.cjs +0 -151
- package/dist/cjs/splitStream.cjs.map +0 -1
- package/dist/esm/splitStream.mjs +0 -150
- package/dist/esm/splitStream.mjs.map +0 -1
- package/dist/types/mockStream.d.ts +0 -32
- package/dist/types/splitStream.d.ts +0 -37
- package/src/mockStream.ts +0 -99
- package/src/splitStream.ts +0 -234
|
@@ -8,7 +8,7 @@ import type { InjectedMessage } from '@/types/tools';
|
|
|
8
8
|
* `docs/hooks-design-report.md` §3.2 for the mapping to existing
|
|
9
9
|
* `@librechat/agents` emission points.
|
|
10
10
|
*/
|
|
11
|
-
export declare const HOOK_EVENTS: readonly ["RunStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "PermissionDenied", "SubagentStart", "SubagentStop", "Stop", "StopFailure", "PreCompact", "PostCompact"];
|
|
11
|
+
export declare const HOOK_EVENTS: readonly ["RunStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "PreemptBoundary", "PermissionDenied", "SubagentStart", "SubagentStop", "Stop", "StopFailure", "PreCompact", "PostCompact"];
|
|
12
12
|
export type HookEvent = (typeof HOOK_EVENTS)[number];
|
|
13
13
|
/** Tool-gating decision; executeHooks folds with `deny > ask > allow` precedence. */
|
|
14
14
|
export type ToolDecision = 'allow' | 'deny' | 'ask';
|
|
@@ -117,6 +117,38 @@ export interface PostToolBatchHookInput extends BaseHookInput {
|
|
|
117
117
|
/** All tool calls (and their outcomes) from this batch, in batch order. */
|
|
118
118
|
entries: PostToolBatchEntry[];
|
|
119
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Fires when a cooperative preemption seals the model stream mid-generation
|
|
122
|
+
* — the second injection boundary, and the only one that exists during a
|
|
123
|
+
* long text answer with no tool calls in it.
|
|
124
|
+
*
|
|
125
|
+
* Order: fires after the model stream is sealed and BEFORE the next model
|
|
126
|
+
* call. The `injectedMessages` a hook returns here are appended verbatim and
|
|
127
|
+
* the agent node self-loops. Returning nothing is a valid outcome (the host's
|
|
128
|
+
* queue was cancelled or already drained): the run stops honestly rather than
|
|
129
|
+
* self-looping into an empty turn.
|
|
130
|
+
*
|
|
131
|
+
* The sealed turn is NOT yet observable from graph state when this fires.
|
|
132
|
+
* Dispatch happens inside the agent node, and only the outer graph's reducer
|
|
133
|
+
* writes `StandardGraph.messages` — which cannot run until the node returns.
|
|
134
|
+
* A hook calling `Run.getRunMessages()` here sees the state as of the last
|
|
135
|
+
* completed superstep, so the sealed text is absent. `PostToolBatch` behaves
|
|
136
|
+
* the same way: a tool-boundary hook cannot see the assistant turn that
|
|
137
|
+
* requested the tool. This is a property of the single-node outer graph, not
|
|
138
|
+
* of preemption, and committing first would mean returning from the node and
|
|
139
|
+
* re-entering — precisely what the self-loop exists to avoid.
|
|
140
|
+
*
|
|
141
|
+
* A hook that needs the sealed text should therefore not go looking for it in
|
|
142
|
+
* graph state. Decide from the host's own queue, or read it after the run.
|
|
143
|
+
*
|
|
144
|
+
* Requires `RunConfig.preemption`. This event is deliberately NOT
|
|
145
|
+
* result-altering, so registering it never disables eager tool execution.
|
|
146
|
+
*/
|
|
147
|
+
export interface PreemptBoundaryHookInput extends BaseHookInput {
|
|
148
|
+
hook_event_name: 'PreemptBoundary';
|
|
149
|
+
/** 1-based index of this seal within the run. */
|
|
150
|
+
sealCount: number;
|
|
151
|
+
}
|
|
120
152
|
export interface PermissionDeniedHookInput extends BaseHookInput {
|
|
121
153
|
hook_event_name: 'PermissionDenied';
|
|
122
154
|
toolName: string;
|
|
@@ -170,7 +202,7 @@ export interface PostCompactHookInput extends BaseHookInput {
|
|
|
170
202
|
messagesAfterCount: number;
|
|
171
203
|
}
|
|
172
204
|
/** Discriminated union of every hook input shape. */
|
|
173
|
-
export type HookInput = RunStartHookInput | UserPromptSubmitHookInput | PreToolUseHookInput | PostToolUseHookInput | PostToolUseFailureHookInput | PostToolBatchHookInput | PermissionDeniedHookInput | SubagentStartHookInput | SubagentStopHookInput | StopHookInput | StopFailureHookInput | PreCompactHookInput | PostCompactHookInput;
|
|
205
|
+
export type HookInput = RunStartHookInput | UserPromptSubmitHookInput | PreToolUseHookInput | PostToolUseHookInput | PostToolUseFailureHookInput | PostToolBatchHookInput | PreemptBoundaryHookInput | PermissionDeniedHookInput | SubagentStartHookInput | SubagentStopHookInput | StopHookInput | StopFailureHookInput | PreCompactHookInput | PostCompactHookInput;
|
|
174
206
|
/** Compile-time map from event name to its input shape. */
|
|
175
207
|
export type HookInputByEvent = {
|
|
176
208
|
RunStart: RunStartHookInput;
|
|
@@ -179,6 +211,7 @@ export type HookInputByEvent = {
|
|
|
179
211
|
PostToolUse: PostToolUseHookInput;
|
|
180
212
|
PostToolUseFailure: PostToolUseFailureHookInput;
|
|
181
213
|
PostToolBatch: PostToolBatchHookInput;
|
|
214
|
+
PreemptBoundary: PreemptBoundaryHookInput;
|
|
182
215
|
PermissionDenied: PermissionDeniedHookInput;
|
|
183
216
|
SubagentStart: SubagentStartHookInput;
|
|
184
217
|
SubagentStop: SubagentStopHookInput;
|
|
@@ -196,14 +229,18 @@ export interface BaseHookOutput {
|
|
|
196
229
|
additionalContext?: string;
|
|
197
230
|
/**
|
|
198
231
|
* Messages to inject into graph state, one `HumanMessage` per entry
|
|
199
|
-
* (converted via `
|
|
232
|
+
* (converted via `convertInjectedMessages`, which preserves
|
|
200
233
|
* `role`/`source`/`isMeta` in `additional_kwargs`). Unlike
|
|
201
234
|
* `additionalContext` — which is consolidated across hooks into a single
|
|
202
235
|
* system-flavored message — each entry keeps its own identity and role,
|
|
203
236
|
* making this the channel for injecting verbatim user speech (e.g. a
|
|
204
237
|
* mid-run steering message). Accumulated across hooks in registration
|
|
205
|
-
* order.
|
|
206
|
-
*
|
|
238
|
+
* order.
|
|
239
|
+
*
|
|
240
|
+
* Consumed at exactly two dispatch sites, both of which run the same
|
|
241
|
+
* converter so the emitted shapes cannot drift: `PostToolBatch` (the tool
|
|
242
|
+
* boundary) and `PreemptBoundary` (a cooperative mid-generation seal).
|
|
243
|
+
* Every other event ignores the field.
|
|
207
244
|
*/
|
|
208
245
|
injectedMessages?: InjectedMessage[];
|
|
209
246
|
/** True to prevent the next model turn. Any hook can set this. */
|
|
@@ -305,6 +342,7 @@ export interface PostToolUseHookOutput extends BaseHookOutput {
|
|
|
305
342
|
}
|
|
306
343
|
export type PostToolUseFailureHookOutput = BaseHookOutput;
|
|
307
344
|
export type PostToolBatchHookOutput = BaseHookOutput;
|
|
345
|
+
export type PreemptBoundaryHookOutput = BaseHookOutput;
|
|
308
346
|
export type PermissionDeniedHookOutput = BaseHookOutput;
|
|
309
347
|
export interface SubagentStartHookOutput extends BaseHookOutput {
|
|
310
348
|
decision?: ToolDecision;
|
|
@@ -326,6 +364,7 @@ export type HookOutputByEvent = {
|
|
|
326
364
|
PostToolUse: PostToolUseHookOutput;
|
|
327
365
|
PostToolUseFailure: PostToolUseFailureHookOutput;
|
|
328
366
|
PostToolBatch: PostToolBatchHookOutput;
|
|
367
|
+
PreemptBoundary: PreemptBoundaryHookOutput;
|
|
329
368
|
PermissionDenied: PermissionDeniedHookOutput;
|
|
330
369
|
SubagentStart: SubagentStartHookOutput;
|
|
331
370
|
SubagentStop: SubagentStopHookOutput;
|
|
@@ -335,7 +374,7 @@ export type HookOutputByEvent = {
|
|
|
335
374
|
PostCompact: PostCompactHookOutput;
|
|
336
375
|
};
|
|
337
376
|
/** Superset output shape used by the executor's fold loop. */
|
|
338
|
-
export type HookOutput = RunStartHookOutput | UserPromptSubmitHookOutput | PreToolUseHookOutput | PostToolUseHookOutput | PostToolUseFailureHookOutput | PostToolBatchHookOutput | PermissionDeniedHookOutput | SubagentStartHookOutput | SubagentStopHookOutput | StopHookOutput | StopFailureHookOutput | PreCompactHookOutput | PostCompactHookOutput;
|
|
377
|
+
export type HookOutput = RunStartHookOutput | UserPromptSubmitHookOutput | PreToolUseHookOutput | PostToolUseHookOutput | PostToolUseFailureHookOutput | PostToolBatchHookOutput | PreemptBoundaryHookOutput | PermissionDeniedHookOutput | SubagentStartHookOutput | SubagentStopHookOutput | StopHookOutput | StopFailureHookOutput | PreCompactHookOutput | PostCompactHookOutput;
|
|
339
378
|
/**
|
|
340
379
|
* A hook callback is a plain async function registered against a specific
|
|
341
380
|
* event. The `signal` is always supplied by `executeHooks` and combines the
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './run';
|
|
2
2
|
export * from './stream';
|
|
3
|
-
export * from './splitStream';
|
|
4
3
|
export * from './events';
|
|
5
4
|
export * from './messages';
|
|
6
5
|
export * from './graphs';
|
|
@@ -45,4 +44,5 @@ export { getChatModelClass } from './llm/providers';
|
|
|
45
44
|
export { FakeChatModel, createFakeStreamingLLM } from './llm/fake';
|
|
46
45
|
export { initializeModel } from './llm/init';
|
|
47
46
|
export { attemptInvoke, tryFallbackProviders } from './llm/invoke';
|
|
47
|
+
export { canSealPreempt } from './llm/preempt';
|
|
48
48
|
export { isThinkingEnabled, getMaxOutputTokensKey } from './llm/request';
|
|
@@ -41,6 +41,26 @@ export type InvokeContext = NonNullable<Parameters<ChatModelStreamHandler['handl
|
|
|
41
41
|
* When provided, replaces the default `ChatModelStreamHandler`.
|
|
42
42
|
*/
|
|
43
43
|
export type OnChunk = (chunk: AIMessageChunk) => void | Promise<void>;
|
|
44
|
+
export declare function usesNativeOpenAIResponses(model: t.ChatModel, provider: Providers, callOptions?: unknown): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Produces the exact provider-facing message representation before a model
|
|
47
|
+
* adapter serializes it. This is shared by invocation and Graph's final budget
|
|
48
|
+
* guard so structured tool output cannot grow after the payload was measured.
|
|
49
|
+
*/
|
|
50
|
+
export declare function projectMessagesForProvider({ model, messages, provider, maxToolResultChars, callOptions, }: {
|
|
51
|
+
model: t.ChatModel;
|
|
52
|
+
messages: BaseMessage[];
|
|
53
|
+
provider: Providers;
|
|
54
|
+
maxToolResultChars?: number;
|
|
55
|
+
callOptions?: unknown;
|
|
56
|
+
}): BaseMessage[];
|
|
57
|
+
/**
|
|
58
|
+
* The serving model's id, read through the same wrapper stack
|
|
59
|
+
* `collectModelCallbackSources` walks — `bindTools` returns a
|
|
60
|
+
* `RunnableBinding` and a system runnable pipes a `RunnableSequence`, and
|
|
61
|
+
* neither exposes the chat model's `model` at the top level.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveServingModelId(model: unknown): string | undefined;
|
|
44
64
|
/**
|
|
45
65
|
* Invokes a chat model with the given messages, handling both streaming and
|
|
46
66
|
* non-streaming paths.
|
|
@@ -85,7 +105,7 @@ export declare function getFallbackOverflowCandidates(error: unknown): FallbackO
|
|
|
85
105
|
* behind a later unrelated error would surface a dead end instead. Ordinary
|
|
86
106
|
* failures still throw last-error-wins.
|
|
87
107
|
*/
|
|
88
|
-
export declare function tryFallbackProviders({ fallbacks, tools, messages, config, primaryError, context, onChunk, overflowContext, }: {
|
|
108
|
+
export declare function tryFallbackProviders({ fallbacks, tools, messages, config, primaryError, context, onChunk, overflowContext, prepareProviderMessages, }: {
|
|
89
109
|
fallbacks: t.FallbackConfig[];
|
|
90
110
|
tools?: t.GraphTools;
|
|
91
111
|
messages: BaseMessage[];
|
|
@@ -100,4 +120,17 @@ export declare function tryFallbackProviders({ fallbacks, tools, messages, confi
|
|
|
100
120
|
* be dropped in favour of whichever failure came last.
|
|
101
121
|
*/
|
|
102
122
|
overflowContext?: ContextOverflowContext;
|
|
123
|
+
/**
|
|
124
|
+
* Optional final payload guard used by Graph. It receives the initialized,
|
|
125
|
+
* tool-bound fallback model so Responses-vs-Chat projection is exact before
|
|
126
|
+
* the fallback request is measured and sent.
|
|
127
|
+
*/
|
|
128
|
+
prepareProviderMessages?: (input: {
|
|
129
|
+
model: t.ChatModel;
|
|
130
|
+
messages: BaseMessage[];
|
|
131
|
+
provider: Providers;
|
|
132
|
+
clientOptions?: t.ClientOptions;
|
|
133
|
+
maxContextTokens?: number;
|
|
134
|
+
config?: RunnableConfig;
|
|
135
|
+
}) => BaseMessage[] | Promise<BaseMessage[]>;
|
|
103
136
|
}): Promise<Partial<t.BaseGraphState> | undefined>;
|
|
@@ -11,6 +11,7 @@ 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
13
|
import type { HeaderValue, HeadersLike } from './types';
|
|
14
|
+
import type { PromptCacheTtl } from '@/messages/cache';
|
|
14
15
|
export declare function isHeaders(headers: unknown): headers is Headers;
|
|
15
16
|
export declare function normalizeHeaders(headers: HeadersLike): Record<string, HeaderValue | readonly HeaderValue[]>;
|
|
16
17
|
type OpenAICoreRequestOptions = OpenAIClient.RequestOptions;
|
|
@@ -20,6 +21,9 @@ type LibreChatOpenAIFields = t.ChatOpenAIFields & {
|
|
|
20
21
|
includeReasoningContent?: boolean;
|
|
21
22
|
includeReasoningDetails?: boolean;
|
|
22
23
|
convertReasoningDetailsToContent?: boolean;
|
|
24
|
+
preserveToolCacheControl?: boolean;
|
|
25
|
+
responsesPromptCache?: boolean;
|
|
26
|
+
responsesPromptCacheTtl?: PromptCacheTtl;
|
|
23
27
|
promptCacheExplicit?: boolean;
|
|
24
28
|
safety_identifier?: string;
|
|
25
29
|
};
|
|
@@ -22,6 +22,8 @@ export interface ConvertMessagesOptions {
|
|
|
22
22
|
includeReasoningDetails?: boolean;
|
|
23
23
|
/** Convert reasoning_details to content blocks for Claude (requires content array format) */
|
|
24
24
|
convertReasoningDetailsToContent?: boolean;
|
|
25
|
+
/** Preserve OpenRouter's canonical cache-decorated tool text block. */
|
|
26
|
+
preserveToolCacheControl?: boolean;
|
|
25
27
|
}
|
|
26
28
|
export declare function _convertMessagesToOpenAIParams(messages: BaseMessage[], model?: string, options?: ConvertMessagesOptions): OpenAICompletionParam[];
|
|
27
29
|
export declare function _convertMessagesToOpenAIResponsesParams(messages: BaseMessage[], model?: string, zdrEnabled?: boolean): ResponsesInputItem[];
|
|
@@ -16,6 +16,7 @@ export interface ChatOpenRouterCallOptions extends Omit<ChatOpenAICallOptions, '
|
|
|
16
16
|
include_reasoning?: boolean;
|
|
17
17
|
reasoning?: OpenRouterReasoning;
|
|
18
18
|
modelKwargs?: OpenAIChatInput['modelKwargs'];
|
|
19
|
+
useResponsesApi?: boolean;
|
|
19
20
|
promptCache?: boolean;
|
|
20
21
|
/**
|
|
21
22
|
* Prompt-cache breakpoint TTL. Defaults to `'1h'` (extended cache) when
|
|
@@ -29,6 +30,10 @@ export type ChatOpenRouterInput = Partial<ChatOpenRouterCallOptions & OpenAIChat
|
|
|
29
30
|
/** invocationParams return type extended with OpenRouter reasoning */
|
|
30
31
|
export type OpenRouterInvocationParams = Omit<OpenAIClient.Chat.ChatCompletionCreateParams, 'messages'> & {
|
|
31
32
|
reasoning?: OpenRouterReasoning;
|
|
33
|
+
cache_control?: {
|
|
34
|
+
type: 'ephemeral';
|
|
35
|
+
ttl?: '1h';
|
|
36
|
+
};
|
|
32
37
|
};
|
|
33
38
|
type InvocationParamsExtra = {
|
|
34
39
|
streaming?: boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AIMessageChunk } from '@langchain/core/messages';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a host-supplied seal budget.
|
|
4
|
+
*
|
|
5
|
+
* Read in two places that interpret it differently — a numeric comparison in
|
|
6
|
+
* the seal gate and an addition into the recursion limit — so a value like
|
|
7
|
+
* `1.5` would permit two seals while reserving fractional headroom, `NaN`
|
|
8
|
+
* would poison the recursion limit outright, and `Infinity` would remove both
|
|
9
|
+
* bounds at once. Normalizing once keeps the two readings in agreement.
|
|
10
|
+
*
|
|
11
|
+
* `0` is honored as a deliberate "never seal"; anything not finite falls back
|
|
12
|
+
* to the default rather than silently disabling the feature.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveMaxSeals(maxSeals: number | undefined): number;
|
|
15
|
+
/**
|
|
16
|
+
* Cooperative mid-generation seal gate. Returns true ONLY when sealing here
|
|
17
|
+
* yields a message sequence valid on EVERY supported provider:
|
|
18
|
+
* - non-whitespace TEXT content, so the FIRST injected user turn is preceded
|
|
19
|
+
* by a non-empty assistant turn — no empty-content 400s. Note this says
|
|
20
|
+
* nothing about adjacency AMONG several injected turns: a boundary that
|
|
21
|
+
* drains two steers emits two consecutive user messages, which strict
|
|
22
|
+
* providers reject. That is normalized at the provider-facing hop by
|
|
23
|
+
* `coalesceAdjacentUserTurns`, not here;
|
|
24
|
+
* - no tool call in flight, so no `tool_use` can be orphaned AND no eagerly
|
|
25
|
+
* prestarted execution can be stripped out from under the model.
|
|
26
|
+
*
|
|
27
|
+
* Anthropic's server-side tools need no check of their own. Every
|
|
28
|
+
* `server_tool_use` content block also emits a `tool_call_chunk`
|
|
29
|
+
* (`_makeMessageChunkFromAnthropicEvent`), and `concat` keeps that chunk on
|
|
30
|
+
* the accumulated message for the remainder of the turn, so the tool-call
|
|
31
|
+
* gates below already cover it. The practical consequence is worth stating
|
|
32
|
+
* plainly: once a turn starts a web search it is no longer preemptible, and
|
|
33
|
+
* a queued message waits for the ordinary tool boundary instead.
|
|
34
|
+
*
|
|
35
|
+
* Nothing is stripped and nothing is repaired: when the accumulated shape is
|
|
36
|
+
* not already safe the stream simply runs on, and whatever the host queued
|
|
37
|
+
* lands at the next tool boundary instead. Chunks accumulate monotonically
|
|
38
|
+
* through `concat`, so an unsafe shape can never be observed at a seal point.
|
|
39
|
+
*/
|
|
40
|
+
export declare function canSealPreempt(chunk: AIMessageChunk | undefined): boolean;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
2
|
+
import { Providers } from '@/common';
|
|
3
|
+
/**
|
|
4
|
+
* Providers whose APIs specify strict user/assistant alternation. Mistral
|
|
5
|
+
* rejects consecutive user turns outright. Bedrock's Converse API documents
|
|
6
|
+
* the alternation requirement across many model families; enforcement varies
|
|
7
|
+
* by family — Claude on Converse currently tolerates adjacent user turns
|
|
8
|
+
* (verified live, 2026-07-28) — so the payload is normalized for all of them
|
|
9
|
+
* rather than betting on per-family leniency. Anthropic's own Messages API,
|
|
10
|
+
* OpenAI and Gemini all accept consecutive user turns, so they are
|
|
11
|
+
* deliberately absent.
|
|
12
|
+
*/
|
|
13
|
+
export declare const strictAlternationProviders: ReadonlySet<Providers>;
|
|
14
|
+
/**
|
|
15
|
+
* Merges runs of consecutive human turns into one, for providers that reject
|
|
16
|
+
* them. Purely a wire-shaping pass: it returns a new array of new messages,
|
|
17
|
+
* so graph state and the host's persisted messages keep the per-message
|
|
18
|
+
* identity that steer rendering and the trailing-steer anchor rely on.
|
|
19
|
+
*
|
|
20
|
+
* Tool-result turns are excluded — the converters merge those themselves, and
|
|
21
|
+
* combining one with a text turn would orphan the pairing.
|
|
22
|
+
*/
|
|
23
|
+
export declare function coalesceAdjacentUserTurns(messages: BaseMessage[]): BaseMessage[];
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* - Hard-clear: Replace entire content with a placeholder.
|
|
10
10
|
*
|
|
11
11
|
* Messages in the "protected zone" (recent assistant turns, system/pre-first-human
|
|
12
|
-
* messages
|
|
12
|
+
* messages) are never pruned. Atomic media/resource blocks are preserved when
|
|
13
|
+
* they fit; oversized inline payloads are replaced with bounded placeholders.
|
|
13
14
|
*/
|
|
14
15
|
import { type BaseMessage } from '@langchain/core/messages';
|
|
15
16
|
import type { ContextPruningSettings } from './contextPruningSettings';
|
|
@@ -9,6 +9,42 @@ export declare function getConverseOverrideMessage({ userMessage, lastMessageX,
|
|
|
9
9
|
export declare function modifyDeltaProperties(provider: Providers, obj?: AIMessageChunk): AIMessageChunk | undefined;
|
|
10
10
|
export declare function formatAnthropicMessage(message: AIMessageChunk): AIMessage;
|
|
11
11
|
export declare function convertMessagesToContent(messages: BaseMessage[]): t.MessageContentComplex[];
|
|
12
|
+
/**
|
|
13
|
+
* Drops incomplete streamed text-input fragments that some providers retain
|
|
14
|
+
* beside the assembled parsed tool call. They are neither user-visible text
|
|
15
|
+
* nor valid content blocks for a subsequent provider.
|
|
16
|
+
*/
|
|
17
|
+
export declare function projectToolStreamContentForProvider(messages: BaseMessage[]): BaseMessage[];
|
|
18
|
+
/** Projects OpenAI-compatible tool content without changing parsed call parents. */
|
|
19
|
+
export declare function projectOpenAIToolMessageContent(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
20
|
+
/** Projects an actual OpenAI-compatible Chat attempt and removes cache metadata. */
|
|
21
|
+
export declare function projectOpenAIChatToolMessageContent(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
22
|
+
/** Preserves OpenRouter's cache-decorated text blocks for a Chat attempt. */
|
|
23
|
+
export declare function projectOpenRouterToolMessageContent(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
24
|
+
/** Projects Responses tool content and collapses parsed/raw computer-call mirrors. */
|
|
25
|
+
export declare function projectOpenAIResponsesToolMessageContent(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
26
|
+
/** Removes Anthropic/OpenRouter cache metadata before unsupported providers run. */
|
|
27
|
+
export declare function projectCacheControlledToolOutputsToText(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
28
|
+
/** Unwraps a canonical single text block after provider cache markers are removed. */
|
|
29
|
+
export declare function projectSingleTextToolOutputsToText(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
30
|
+
/** Serializes provider-neutral structured tool outputs without media pairing. */
|
|
31
|
+
export declare function projectStructuredToolOutputsToText(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
32
|
+
/**
|
|
33
|
+
* Non-Responses providers cannot consume native computer screenshots. Keep
|
|
34
|
+
* the tool-call structure intact, but replace screenshot bytes with a bounded
|
|
35
|
+
* text marker at the actual invocation boundary.
|
|
36
|
+
*/
|
|
37
|
+
export declare function projectComputerCallOutputsToText(messages: BaseMessage[]): BaseMessage[];
|
|
38
|
+
export declare function projectAnthropicArtifactContent(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
39
|
+
/**
|
|
40
|
+
* Mutating compatibility wrapper retained for existing package consumers.
|
|
41
|
+
* New provider-call paths should use `projectAnthropicArtifactContent`.
|
|
42
|
+
*/
|
|
12
43
|
export declare function formatAnthropicArtifactContent(messages: BaseMessage[]): void;
|
|
44
|
+
export declare function projectArtifactPayload(messages: BaseMessage[], maxChars?: number): BaseMessage[];
|
|
45
|
+
/**
|
|
46
|
+
* Mutating compatibility wrapper retained for existing package consumers.
|
|
47
|
+
* New provider-call paths should use `projectArtifactPayload`.
|
|
48
|
+
*/
|
|
13
49
|
export declare function formatArtifactPayload(messages: BaseMessage[]): void;
|
|
14
50
|
export declare function findLastIndex<T>(array: T[], predicate: (value: T) => boolean): number;
|
|
@@ -151,6 +151,12 @@ export declare const formatAgentMessages: (payload: TPayload, indexTokenCountMap
|
|
|
151
151
|
* @returns A new map with the system message at index 0 and all other indices shifted by 1
|
|
152
152
|
*/
|
|
153
153
|
export declare function shiftIndexTokenCountMap(indexTokenCountMap: Record<number, number>, instructionsTokenCount: number): Record<number, number>;
|
|
154
|
+
/**
|
|
155
|
+
* Identifies provider-context placeholders created by this module without
|
|
156
|
+
* trusting user-controlled content prefixes or leaking marker metadata onto
|
|
157
|
+
* the provider wire.
|
|
158
|
+
*/
|
|
159
|
+
export declare function isSyntheticProviderContextMessage(message: BaseMessage): boolean;
|
|
154
160
|
/**
|
|
155
161
|
* Ensures compatibility when switching from a non-thinking agent to a thinking-enabled agent.
|
|
156
162
|
* Converts AI messages with tool calls (that lack thinking/reasoning blocks) into buffer strings,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
2
|
+
/**
|
|
3
|
+
* Bracketed-meta convention, like the handoff path's
|
|
4
|
+
* `[Processed tool result and transferring to …]` bridge. The wording makes
|
|
5
|
+
* two things unambiguous to the model: the assistant turn above is FINISHED,
|
|
6
|
+
* and it belongs to a previous stage — so the successor answers as itself
|
|
7
|
+
* instead of continuing someone else's sentence.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PREDECESSOR_HANDOFF_CUE: string;
|
|
10
|
+
/**
|
|
11
|
+
* Appends a user-turn handoff cue when a payload ends with an assistant turn
|
|
12
|
+
* that THIS RUN produced — which only happens when a different agent in a
|
|
13
|
+
* multi-agent workflow produced it (an agent's own self-loops always re-enter
|
|
14
|
+
* on a tool result or an injected user turn).
|
|
15
|
+
*
|
|
16
|
+
* Why: providers with prefill semantics (Anthropic, Bedrock-Claude) treat a
|
|
17
|
+
* trailing assistant message as a prefill and CONTINUE it. A bare direct-edge
|
|
18
|
+
* successor therefore speaks in its predecessor's voice — or, when the
|
|
19
|
+
* trailing turn reads complete (a preemption steer's short resume, say),
|
|
20
|
+
* returns empty content (danny-avila/agents#345, reproduced live 3/3).
|
|
21
|
+
* Handoff edges with instructions and prompt-instruction edges already break
|
|
22
|
+
* the prefill with a user turn; this closes the same gap for bare edges.
|
|
23
|
+
*
|
|
24
|
+
* Fail-safe OFF by provenance: the trailing payload message must be one the
|
|
25
|
+
* run itself produced (`isRunProduced`, backed by the graph's run-produced id
|
|
26
|
+
* set — immune to summarization compaction, which rewrites the live array
|
|
27
|
+
* and stales index-based boundaries). Host-supplied trailing assistant
|
|
28
|
+
* turns (deliberate prefill flows) never match — the run has not produced
|
|
29
|
+
* them — so single-agent prefill behavior is untouched. Wire-only: the cue is
|
|
30
|
+
* appended to the provider projection, never to graph state or host history.
|
|
31
|
+
*/
|
|
32
|
+
export declare function appendPredecessorHandoffCue(messages: BaseMessage[], isRunProduced: ((message: BaseMessage) => boolean) | undefined): BaseMessage[];
|
|
33
|
+
/**
|
|
34
|
+
* Strips a trailing handoff cue. The counterpart for the serving-provider
|
|
35
|
+
* funnel: an Anthropic-like PRIMARY bakes the cue into its measured payload,
|
|
36
|
+
* and a tolerant fallback (OpenAI, Mistral, Bedrock-Nova) re-sending that
|
|
37
|
+
* payload must not ship the Claude-only synthetic turn. Identity on the
|
|
38
|
+
* no-op path.
|
|
39
|
+
*/
|
|
40
|
+
export declare function removePredecessorHandoffCue(messages: BaseMessage[]): BaseMessage[];
|
|
@@ -7,6 +7,9 @@ export * from './cache';
|
|
|
7
7
|
export * from './anthropicToolCache';
|
|
8
8
|
export * from './content';
|
|
9
9
|
export * from './tools';
|
|
10
|
+
export * from './injected';
|
|
11
|
+
export * from './alternation';
|
|
12
|
+
export * from './handoffCue';
|
|
10
13
|
export * from './contextPruning';
|
|
11
14
|
export * from './contextPruningSettings';
|
|
12
15
|
export * from './reducer';
|
|
@@ -4,6 +4,8 @@ import type { TokenCounter } from '@/types/run';
|
|
|
4
4
|
import { ContentTypes, Providers } from '@/common';
|
|
5
5
|
/** Default fraction of the token budget reserved as headroom (5 %). */
|
|
6
6
|
export declare const DEFAULT_RESERVE_RATIO = 0.05;
|
|
7
|
+
/** Provider framing reserved for the assistant reply label. */
|
|
8
|
+
export declare const REPLY_PRIMER_TOKENS = 3;
|
|
7
9
|
/** Hard cap for the originalToolContent store (~2 MB estimated from char length). */
|
|
8
10
|
export declare const ORIGINAL_CONTENT_MAX_CHARS = 2000000;
|
|
9
11
|
/**
|
|
@@ -25,6 +27,8 @@ export declare function clampCalibrationRatio(ratio: number): number;
|
|
|
25
27
|
export type PruneMessagesFactoryParams = {
|
|
26
28
|
provider?: Providers;
|
|
27
29
|
maxTokens: number;
|
|
30
|
+
/** Per-tool-result character cap applied while reconciling cached counts. */
|
|
31
|
+
maxToolResultChars?: number;
|
|
28
32
|
startIndex: number;
|
|
29
33
|
tokenCounter: TokenCounter;
|
|
30
34
|
indexTokenCountMap: Record<string, number | undefined>;
|
|
@@ -113,7 +117,7 @@ export declare function repairOrphanedToolMessages({ context, allMessages, token
|
|
|
113
117
|
* Includes a fast-path: if every tool_call has a matching tool_result and
|
|
114
118
|
* vice-versa, the original array is returned immediately with zero allocation.
|
|
115
119
|
*/
|
|
116
|
-
export declare function sanitizeOrphanToolBlocks(messages: BaseMessage[]): BaseMessage[];
|
|
120
|
+
export declare function sanitizeOrphanToolBlocks(messages: BaseMessage[], onMessageCloned?: (source: BaseMessage, clone: BaseMessage) => void): BaseMessage[];
|
|
117
121
|
/**
|
|
118
122
|
* Calculates the total tokens from a single usage object
|
|
119
123
|
*
|
|
@@ -200,18 +204,18 @@ export declare function preFlightTruncateToolResults(params: {
|
|
|
200
204
|
tokenCounter: TokenCounter;
|
|
201
205
|
}): number;
|
|
202
206
|
/**
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* @returns The number of AI messages that had tool_use inputs truncated.
|
|
207
|
+
* Serializes one structured tool-call input as valid, bounded JSON without
|
|
208
|
+
* invoking user-defined accessors or `toJSON`.
|
|
209
|
+
*/
|
|
210
|
+
export declare function serializeToolCallInput(input: unknown, maxChars?: number): string;
|
|
211
|
+
/** Per-input cap: 15% of context at ~4 chars/token, never above 200K chars. */
|
|
212
|
+
export declare function calculateMaxToolCallInputChars(maxContextTokens?: number): number;
|
|
213
|
+
/**
|
|
214
|
+
* Projects historical tool-call inputs into a provider-safe bounded form.
|
|
215
|
+
* Returns the original array when no message changes and otherwise clones only
|
|
216
|
+
* the array and AI messages whose inline input or `tool_calls` args changed.
|
|
214
217
|
*/
|
|
218
|
+
export declare function projectToolCallInputs(messages: BaseMessage[], maxInputChars: number): BaseMessage[];
|
|
215
219
|
export declare function preFlightTruncateToolCallInputs(params: {
|
|
216
220
|
messages: BaseMessage[];
|
|
217
221
|
maxContextTokens: number;
|
package/dist/types/run.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
17
17
|
private interruptingToolNames?;
|
|
18
18
|
private toolExecution?;
|
|
19
19
|
private subagentUsageSink?;
|
|
20
|
+
private preemption?;
|
|
20
21
|
private indexTokenCountMap?;
|
|
21
22
|
calibrationRatio: number;
|
|
22
23
|
graphRunnable?: t.CompiledStateWorkflow;
|
|
@@ -109,6 +110,12 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
109
110
|
*/
|
|
110
111
|
getCalibrationRatio(): number;
|
|
111
112
|
getResolvedInstructionOverhead(): number | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* Cooperative-seal counters for this run. `emptyBoundaries` is the one to
|
|
115
|
+
* watch: it counts seals whose `PreemptBoundary` produced nothing to
|
|
116
|
+
* inject, which ends the turn early and leaves the answer unfinished.
|
|
117
|
+
*/
|
|
118
|
+
getPreemptStats(): t.PreemptStats;
|
|
112
119
|
getToolCount(): number;
|
|
113
120
|
/**
|
|
114
121
|
* Creates a custom event callback handler that intercepts custom events
|
package/dist/types/stream.d.ts
CHANGED
|
@@ -8,7 +8,21 @@ export declare function getChunkContent({ chunk, provider, reasoningKey, }: {
|
|
|
8
8
|
provider?: Providers;
|
|
9
9
|
reasoningKey: 'reasoning_content' | 'reasoning';
|
|
10
10
|
}): string | t.MessageContentComplex[] | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Brands a handler as one that dispatches content parts for the SDK — either
|
|
13
|
+
* `ChatModelStreamHandler` itself or a wrapper forwarding to one.
|
|
14
|
+
*
|
|
15
|
+
* Identity alone is not a usable contract here. Hosts compose and wrap
|
|
16
|
+
* handlers (`composeEventHandlers`, `createRunHandlers`), and every wrapper
|
|
17
|
+
* fails `instanceof` while still driving the same dispatch. A brand survives
|
|
18
|
+
* wrapping, so "does this handler own content-part dispatch" can be answered
|
|
19
|
+
* about a value the SDK did not construct.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SDK_STREAM_DISPATCH: unique symbol;
|
|
22
|
+
/** True when `handler` is, or forwards to, the SDK's stream dispatcher. */
|
|
23
|
+
export declare function dispatchesChatModelStream(handler?: t.EventHandler): boolean;
|
|
11
24
|
export declare class ChatModelStreamHandler implements t.EventHandler {
|
|
25
|
+
readonly [SDK_STREAM_DISPATCH] = true;
|
|
12
26
|
handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: StandardGraph): Promise<void>;
|
|
13
27
|
handleReasoning(chunk: Partial<AIMessageChunk>, agentContext: AgentContext): void;
|
|
14
28
|
}
|
|
@@ -401,13 +401,6 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
401
401
|
* actually dispatched so the caller can fall back to batch-time emission.
|
|
402
402
|
*/
|
|
403
403
|
private dispatchEarlyToolCompletion;
|
|
404
|
-
/**
|
|
405
|
-
* Converts InjectedMessage instances to LangChain HumanMessage objects.
|
|
406
|
-
* Both 'user' and 'system' roles become HumanMessage to avoid provider
|
|
407
|
-
* rejections (Anthropic/Google reject non-leading SystemMessages).
|
|
408
|
-
* The original role is preserved in additional_kwargs for downstream consumers.
|
|
409
|
-
*/
|
|
410
|
-
private convertInjectedMessages;
|
|
411
404
|
/**
|
|
412
405
|
* Execute a group of direct (in-process) tool calls with interrupt-safe
|
|
413
406
|
* ordering, returning outputs aligned 1:1 with `directCalls`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type * as t from './types';
|
|
2
|
+
export declare class KeenableScraper implements t.BaseScraper {
|
|
3
|
+
private apiKey;
|
|
4
|
+
private apiUrl;
|
|
5
|
+
private timeout;
|
|
6
|
+
private attributionTitle;
|
|
7
|
+
private logger;
|
|
8
|
+
constructor(config?: t.KeenableScraperConfig);
|
|
9
|
+
private buildHeaders;
|
|
10
|
+
scrapeUrl(url: string, options?: t.KeenableScrapeOptions): Promise<[string, t.KeenableScrapeResponse]>;
|
|
11
|
+
scrapeUrls(urls: string[], options?: t.KeenableScrapeOptions): Promise<Array<[string, t.KeenableScrapeResponse]>>;
|
|
12
|
+
extractContent(response: t.KeenableScrapeResponse): [string, undefined | t.References];
|
|
13
|
+
extractMetadata(response: t.KeenableScrapeResponse): t.GenericScrapeMetadata;
|
|
14
|
+
}
|
|
15
|
+
export declare const createKeenableScraper: (config?: t.KeenableScraperConfig) => KeenableScraper;
|
|
@@ -3,7 +3,7 @@ import type { Logger as WinstonLogger } from 'winston';
|
|
|
3
3
|
import type { BaseReranker } from './rerankers';
|
|
4
4
|
import { DATE_RANGE } from './schema';
|
|
5
5
|
export type SearchProvider = 'serper' | 'searxng' | 'tavily' | 'keenable' | 'crw';
|
|
6
|
-
export type ScraperProvider = 'firecrawl' | 'serper' | 'tavily' | 'crw';
|
|
6
|
+
export type ScraperProvider = 'firecrawl' | 'serper' | 'tavily' | 'crw' | 'keenable';
|
|
7
7
|
export type RerankerType = 'infinity' | 'jina' | 'cohere' | 'none';
|
|
8
8
|
export interface Highlight {
|
|
9
9
|
score: number;
|
|
@@ -172,6 +172,34 @@ export interface KeenableSearchResult {
|
|
|
172
172
|
export interface KeenableSearchResponse {
|
|
173
173
|
results?: KeenableSearchResult[];
|
|
174
174
|
}
|
|
175
|
+
export interface KeenableScraperConfig {
|
|
176
|
+
apiKey?: string;
|
|
177
|
+
/** Override the fetch endpoint base (default: public keyless, keyed when a
|
|
178
|
+
* key is set). Env fallback: KEENABLE_FETCH_URL. */
|
|
179
|
+
apiUrl?: string;
|
|
180
|
+
timeout?: number;
|
|
181
|
+
logger?: Logger;
|
|
182
|
+
/** Sent as the X-Keenable-Title attribution header. Defaults to "LibreChat". */
|
|
183
|
+
attributionTitle?: string;
|
|
184
|
+
}
|
|
185
|
+
export type KeenableScrapeOptions = Omit<KeenableScraperConfig, 'apiKey' | 'apiUrl' | 'logger'>;
|
|
186
|
+
/** Raw JSON shape returned by GET /v1/fetch{,/public}?url=... */
|
|
187
|
+
export interface KeenableFetchResult {
|
|
188
|
+
url?: string;
|
|
189
|
+
title?: string;
|
|
190
|
+
content?: string;
|
|
191
|
+
description?: string;
|
|
192
|
+
}
|
|
193
|
+
export interface KeenableScrapeResponse {
|
|
194
|
+
success: boolean;
|
|
195
|
+
data?: {
|
|
196
|
+
content: string;
|
|
197
|
+
title?: string;
|
|
198
|
+
description?: string;
|
|
199
|
+
url?: string;
|
|
200
|
+
};
|
|
201
|
+
error?: string;
|
|
202
|
+
}
|
|
175
203
|
export type References = {
|
|
176
204
|
links: MediaReference[];
|
|
177
205
|
images: MediaReference[];
|
|
@@ -272,6 +300,7 @@ export type Logger = WinstonLogger;
|
|
|
272
300
|
export interface SearchToolConfig extends SearchConfig, ProcessSourcesConfig, FirecrawlConfig {
|
|
273
301
|
tavilyScraperOptions?: TavilyScraperConfig;
|
|
274
302
|
crwScraperOptions?: CrwScraperConfig;
|
|
303
|
+
keenableScraperOptions?: KeenableScraperConfig;
|
|
275
304
|
/** Max chars of highlight content this tool feeds the MODEL per search (the
|
|
276
305
|
* dominant, otherwise-unbounded part of the output). Distinct from
|
|
277
306
|
* `maxContentLength`, which caps scraped/reranked content per source — full
|
|
@@ -303,7 +332,7 @@ export type UsedReferences = {
|
|
|
303
332
|
originalIndex: number;
|
|
304
333
|
reference: MediaReference;
|
|
305
334
|
}[];
|
|
306
|
-
export type AnyScraperResponse = FirecrawlScrapeResponse | SerperScrapeResponse | TavilyScrapeResponse | CrwScrapeResponse;
|
|
335
|
+
export type AnyScraperResponse = FirecrawlScrapeResponse | SerperScrapeResponse | TavilyScrapeResponse | CrwScrapeResponse | KeenableScrapeResponse;
|
|
307
336
|
/** Base Scraper Interface */
|
|
308
337
|
export interface BaseScraper {
|
|
309
338
|
scrapeUrl(url: string, options?: unknown): Promise<[string, AnyScraperResponse]>;
|
|
@@ -7,7 +7,7 @@ import type { GoogleAIToolType } from '@langchain/google-common';
|
|
|
7
7
|
import type { SummarizationNodeInput, SummarizeCompleteEvent, SummarizationConfig, SummarizeStartEvent, SummarizeDeltaEvent } from '@/types/summarize';
|
|
8
8
|
import type { ToolMap, ToolEndEvent, GenericTool, LCTool, ToolExecuteBatchRequest } from '@/types/tools';
|
|
9
9
|
import type { RunStep, RunStepDeltaEvent, MessageDeltaEvent, ReasoningDeltaEvent } from '@/types/stream';
|
|
10
|
-
import type { TokenCounter, TokenBudgetBreakdown } from '@/types/run';
|
|
10
|
+
import type { TokenCounter, StreamPreemption, TokenBudgetBreakdown } from '@/types/run';
|
|
11
11
|
import type { Providers, Callback, GraphNodeKeys } from '@/common';
|
|
12
12
|
import type { StandardGraph, MultiAgentGraph } from '@/graphs';
|
|
13
13
|
import type { ClientOptions } from '@/types/llm';
|
|
@@ -243,6 +243,13 @@ export type StandardGraphInput = {
|
|
|
243
243
|
* hook inputs carry only `executingAgentId`.
|
|
244
244
|
*/
|
|
245
245
|
subagentScope?: boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Cooperative preemption, forwarded from `RunConfig.preemption`. Only ever
|
|
248
|
+
* set on the top-level graph: a steer targets the conversation, so subagent
|
|
249
|
+
* children must run to completion and `buildChildInputs` does not propagate
|
|
250
|
+
* this field.
|
|
251
|
+
*/
|
|
252
|
+
preemption?: StreamPreemption;
|
|
246
253
|
};
|
|
247
254
|
export type GraphEdge = {
|
|
248
255
|
/** Agent ID, use a list for multiple sources */
|