@librechat/agents 3.1.57 → 3.1.61
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 +326 -62
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +13 -0
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/events.cjs +7 -27
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +303 -222
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +4 -4
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +6 -2
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +60 -0
- package/dist/cjs/llm/init.cjs.map +1 -0
- package/dist/cjs/llm/invoke.cjs +90 -0
- package/dist/cjs/llm/invoke.cjs.map +1 -0
- package/dist/cjs/llm/openai/index.cjs +2 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/request.cjs +41 -0
- package/dist/cjs/llm/request.cjs.map +1 -0
- package/dist/cjs/main.cjs +40 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +76 -89
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/contextPruning.cjs +156 -0
- package/dist/cjs/messages/contextPruning.cjs.map +1 -0
- package/dist/cjs/messages/contextPruningSettings.cjs +53 -0
- package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -0
- package/dist/cjs/messages/core.cjs +23 -37
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +156 -11
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +1161 -49
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/reducer.cjs +87 -0
- package/dist/cjs/messages/reducer.cjs.map +1 -0
- package/dist/cjs/run.cjs +81 -42
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +54 -7
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/index.cjs +75 -0
- package/dist/cjs/summarization/index.cjs.map +1 -0
- package/dist/cjs/summarization/node.cjs +663 -0
- package/dist/cjs/summarization/node.cjs.map +1 -0
- package/dist/cjs/tools/ToolNode.cjs +16 -8
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +2 -0
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/utils/errors.cjs +115 -0
- package/dist/cjs/utils/errors.cjs.map +1 -0
- package/dist/cjs/utils/events.cjs +17 -0
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/cjs/utils/handlers.cjs +16 -0
- package/dist/cjs/utils/handlers.cjs.map +1 -1
- package/dist/cjs/utils/llm.cjs +10 -0
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +247 -14
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/cjs/utils/truncation.cjs +107 -0
- package/dist/cjs/utils/truncation.cjs.map +1 -0
- package/dist/esm/agents/AgentContext.mjs +325 -61
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +13 -0
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/events.mjs +8 -28
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +307 -226
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +4 -4
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +6 -2
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +58 -0
- package/dist/esm/llm/init.mjs.map +1 -0
- package/dist/esm/llm/invoke.mjs +87 -0
- package/dist/esm/llm/invoke.mjs.map +1 -0
- package/dist/esm/llm/openai/index.mjs +2 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/request.mjs +38 -0
- package/dist/esm/llm/request.mjs.map +1 -0
- package/dist/esm/main.mjs +13 -3
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +76 -89
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/contextPruning.mjs +154 -0
- package/dist/esm/messages/contextPruning.mjs.map +1 -0
- package/dist/esm/messages/contextPruningSettings.mjs +50 -0
- package/dist/esm/messages/contextPruningSettings.mjs.map +1 -0
- package/dist/esm/messages/core.mjs +23 -37
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +156 -11
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +1158 -52
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/reducer.mjs +83 -0
- package/dist/esm/messages/reducer.mjs.map +1 -0
- package/dist/esm/run.mjs +82 -43
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +54 -7
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/index.mjs +73 -0
- package/dist/esm/summarization/index.mjs.map +1 -0
- package/dist/esm/summarization/node.mjs +659 -0
- package/dist/esm/summarization/node.mjs.map +1 -0
- package/dist/esm/tools/ToolNode.mjs +16 -8
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +2 -0
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/utils/errors.mjs +111 -0
- package/dist/esm/utils/errors.mjs.map +1 -0
- package/dist/esm/utils/events.mjs +17 -1
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/esm/utils/handlers.mjs +16 -0
- package/dist/esm/utils/handlers.mjs.map +1 -1
- package/dist/esm/utils/llm.mjs +10 -1
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +245 -15
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/esm/utils/truncation.mjs +102 -0
- package/dist/esm/utils/truncation.mjs.map +1 -0
- package/dist/types/agents/AgentContext.d.ts +124 -6
- package/dist/types/common/enum.d.ts +14 -1
- package/dist/types/graphs/Graph.d.ts +22 -27
- package/dist/types/index.d.ts +5 -0
- package/dist/types/llm/init.d.ts +18 -0
- package/dist/types/llm/invoke.d.ts +48 -0
- package/dist/types/llm/request.d.ts +14 -0
- package/dist/types/messages/contextPruning.d.ts +42 -0
- package/dist/types/messages/contextPruningSettings.d.ts +44 -0
- package/dist/types/messages/core.d.ts +1 -1
- package/dist/types/messages/format.d.ts +17 -1
- package/dist/types/messages/index.d.ts +3 -0
- package/dist/types/messages/prune.d.ts +162 -1
- package/dist/types/messages/reducer.d.ts +18 -0
- package/dist/types/run.d.ts +12 -1
- package/dist/types/summarization/index.d.ts +20 -0
- package/dist/types/summarization/node.d.ts +29 -0
- package/dist/types/tools/ToolNode.d.ts +3 -1
- package/dist/types/types/graph.d.ts +44 -6
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/run.d.ts +30 -0
- package/dist/types/types/stream.d.ts +31 -4
- package/dist/types/types/summarize.d.ts +47 -0
- package/dist/types/types/tools.d.ts +7 -0
- package/dist/types/utils/errors.d.ts +28 -0
- package/dist/types/utils/events.d.ts +13 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/llm.d.ts +4 -0
- package/dist/types/utils/tokens.d.ts +14 -1
- package/dist/types/utils/truncation.d.ts +49 -0
- package/package.json +3 -3
- package/src/agents/AgentContext.ts +388 -58
- package/src/agents/__tests__/AgentContext.test.ts +265 -5
- package/src/common/enum.ts +13 -0
- package/src/events.ts +9 -39
- package/src/graphs/Graph.ts +468 -331
- package/src/index.ts +7 -0
- package/src/llm/anthropic/llm.spec.ts +3 -3
- package/src/llm/anthropic/utils/message_inputs.ts +6 -4
- package/src/llm/bedrock/llm.spec.ts +1 -1
- package/src/llm/bedrock/utils/message_inputs.ts +6 -2
- package/src/llm/init.ts +63 -0
- package/src/llm/invoke.ts +144 -0
- package/src/llm/request.ts +55 -0
- package/src/messages/__tests__/observationMasking.test.ts +221 -0
- package/src/messages/cache.ts +77 -102
- package/src/messages/contextPruning.ts +191 -0
- package/src/messages/contextPruningSettings.ts +90 -0
- package/src/messages/core.ts +32 -53
- package/src/messages/ensureThinkingBlock.test.ts +39 -39
- package/src/messages/format.ts +227 -15
- package/src/messages/formatAgentMessages.test.ts +511 -1
- package/src/messages/index.ts +3 -0
- package/src/messages/prune.ts +1548 -62
- package/src/messages/reducer.ts +22 -0
- package/src/run.ts +104 -51
- package/src/scripts/bedrock-merge-test.ts +1 -1
- package/src/scripts/test-thinking-handoff-bedrock.ts +1 -1
- package/src/scripts/test-thinking-handoff.ts +1 -1
- package/src/scripts/thinking-bedrock.ts +1 -1
- package/src/scripts/thinking.ts +1 -1
- package/src/specs/anthropic.simple.test.ts +1 -1
- package/src/specs/multi-agent-summarization.test.ts +396 -0
- package/src/specs/prune.test.ts +1196 -23
- package/src/specs/summarization-unit.test.ts +868 -0
- package/src/specs/summarization.test.ts +3827 -0
- package/src/specs/summarize-prune.test.ts +376 -0
- package/src/specs/thinking-handoff.test.ts +10 -10
- package/src/specs/thinking-prune.test.ts +7 -4
- package/src/specs/token-accounting-e2e.test.ts +1034 -0
- package/src/specs/token-accounting-pipeline.test.ts +882 -0
- package/src/specs/token-distribution-edge-case.test.ts +25 -26
- package/src/splitStream.test.ts +42 -33
- package/src/stream.ts +64 -11
- package/src/summarization/__tests__/aggregator.test.ts +153 -0
- package/src/summarization/__tests__/node.test.ts +708 -0
- package/src/summarization/__tests__/trigger.test.ts +50 -0
- package/src/summarization/index.ts +102 -0
- package/src/summarization/node.ts +982 -0
- package/src/tools/ToolNode.ts +25 -3
- package/src/types/graph.ts +62 -7
- package/src/types/index.ts +1 -0
- package/src/types/run.ts +32 -0
- package/src/types/stream.ts +45 -5
- package/src/types/summarize.ts +58 -0
- package/src/types/tools.ts +7 -0
- package/src/utils/errors.ts +117 -0
- package/src/utils/events.ts +31 -0
- package/src/utils/handlers.ts +18 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/llm.ts +12 -0
- package/src/utils/tokens.ts +336 -18
- package/src/utils/truncation.ts +124 -0
- package/src/scripts/image.ts +0 -180
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AIMessage, ToolMessage, BaseMessage, HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
2
2
|
import type { MessageContentImageUrl } from '@langchain/core/messages';
|
|
3
3
|
import type { MessageContentComplex, TPayload } from '@/types';
|
|
4
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
4
5
|
import { Providers } from '@/common';
|
|
5
6
|
interface MediaMessageParams {
|
|
6
7
|
message: {
|
|
@@ -108,6 +109,20 @@ export declare const labelContentByAgent: (contentParts: MessageContentComplex[]
|
|
|
108
109
|
export declare const formatAgentMessages: (payload: TPayload, indexTokenCountMap?: Record<number, number | undefined>, tools?: Set<string>) => {
|
|
109
110
|
messages: Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>;
|
|
110
111
|
indexTokenCountMap?: Record<number, number>;
|
|
112
|
+
/** Cross-run summary extracted from the payload. Should be forwarded to the
|
|
113
|
+
* agent run so it can be included in the system message via AgentContext. */
|
|
114
|
+
summary?: {
|
|
115
|
+
text: string;
|
|
116
|
+
tokenCount: number;
|
|
117
|
+
};
|
|
118
|
+
/** When a summary boundary sliced content from a message, the token count
|
|
119
|
+
* was proportionally reduced. Returned so the caller can log it. */
|
|
120
|
+
boundaryTokenAdjustment?: {
|
|
121
|
+
original: number;
|
|
122
|
+
adjusted: number;
|
|
123
|
+
remainingChars: number;
|
|
124
|
+
totalChars: number;
|
|
125
|
+
};
|
|
111
126
|
};
|
|
112
127
|
/**
|
|
113
128
|
* Adds a value at key 0 for system messages and shifts all key indices by one in an indexTokenCountMap.
|
|
@@ -131,7 +146,8 @@ export declare function shiftIndexTokenCountMap(indexTokenCountMap: Record<numbe
|
|
|
131
146
|
*
|
|
132
147
|
* @param messages - Array of messages to process
|
|
133
148
|
* @param provider - The provider being used (unused but kept for future compatibility)
|
|
149
|
+
* @param config - Optional RunnableConfig for structured agent logging
|
|
134
150
|
* @returns The messages array with tool sequences converted to buffer strings if necessary
|
|
135
151
|
*/
|
|
136
|
-
export declare function ensureThinkingBlockInMessages(messages: BaseMessage[], _provider: Providers): BaseMessage[];
|
|
152
|
+
export declare function ensureThinkingBlockInMessages(messages: BaseMessage[], _provider: Providers, config?: RunnableConfig): BaseMessage[];
|
|
137
153
|
export {};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { BaseMessage, UsageMetadata } from '@langchain/core/messages';
|
|
2
2
|
import type { TokenCounter } from '@/types/run';
|
|
3
|
+
import type { ContextPruningConfig } from '@/types/graph';
|
|
3
4
|
import { ContentTypes, Providers } from '@/common';
|
|
5
|
+
/** Default fraction of the token budget reserved as headroom (5 %). */
|
|
6
|
+
export declare const DEFAULT_RESERVE_RATIO = 0.05;
|
|
4
7
|
export type PruneMessagesFactoryParams = {
|
|
5
8
|
provider?: Providers;
|
|
6
9
|
maxTokens: number;
|
|
@@ -8,12 +11,90 @@ export type PruneMessagesFactoryParams = {
|
|
|
8
11
|
tokenCounter: TokenCounter;
|
|
9
12
|
indexTokenCountMap: Record<string, number | undefined>;
|
|
10
13
|
thinkingEnabled?: boolean;
|
|
14
|
+
/** Context pruning configuration for position-based tool result degradation. */
|
|
15
|
+
contextPruningConfig?: ContextPruningConfig;
|
|
16
|
+
/**
|
|
17
|
+
* When true, context pressure fading (pre-flight tool result truncation)
|
|
18
|
+
* is skipped. Summarization replaces pruning as the primary context
|
|
19
|
+
* management strategy — the summarizer needs full un-truncated tool results
|
|
20
|
+
* to produce an accurate summary. Hard pruning still runs as a fallback
|
|
21
|
+
* when summarization is skipped or capped.
|
|
22
|
+
*/
|
|
23
|
+
summarizationEnabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Returns the current instruction-token overhead (system message + tool schemas + summary).
|
|
26
|
+
* Called on each prune invocation so the budget reflects dynamic changes
|
|
27
|
+
* (e.g. summary added between turns). When messages don't include a leading
|
|
28
|
+
* SystemMessage, these tokens are subtracted from the available budget so
|
|
29
|
+
* the pruner correctly reserves space for the system prompt that will be
|
|
30
|
+
* prepended later by `buildSystemRunnable`.
|
|
31
|
+
*/
|
|
32
|
+
getInstructionTokens?: () => number;
|
|
33
|
+
/**
|
|
34
|
+
* Fraction of the effective token budget to reserve as headroom (0–1).
|
|
35
|
+
* When set, pruning triggers at `effectiveMax * (1 - reserveRatio)` instead of
|
|
36
|
+
* filling the context window to 100%. Defaults to 5 % (0.05) when omitted.
|
|
37
|
+
*/
|
|
38
|
+
reserveRatio?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Initial calibration ratio from a previous run's persisted contextMeta.
|
|
41
|
+
* Seeds the running EMA so new messages are scaled immediately instead
|
|
42
|
+
* of waiting for the first provider response. Ignored when <= 0.
|
|
43
|
+
*/
|
|
44
|
+
calibrationRatio?: number;
|
|
45
|
+
/** Optional diagnostic log callback wired by the graph for observability. */
|
|
46
|
+
log?: (level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: Record<string, unknown>) => void;
|
|
11
47
|
};
|
|
12
48
|
export type PruneMessagesParams = {
|
|
13
49
|
messages: BaseMessage[];
|
|
14
50
|
usageMetadata?: Partial<UsageMetadata>;
|
|
15
51
|
startType?: ReturnType<BaseMessage['getType']>;
|
|
52
|
+
/**
|
|
53
|
+
* Usage from the most recent LLM call only (not accumulated).
|
|
54
|
+
* When provided, calibration uses this instead of usageMetadata
|
|
55
|
+
* to avoid inflated ratios from N×cacheRead accumulation.
|
|
56
|
+
*/
|
|
57
|
+
lastCallUsage?: {
|
|
58
|
+
totalTokens: number;
|
|
59
|
+
inputTokens?: number;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Whether the token data is fresh (from a just-completed LLM call).
|
|
63
|
+
* When false, provider calibration is skipped to avoid applying
|
|
64
|
+
* stale ratios.
|
|
65
|
+
*/
|
|
66
|
+
totalTokensFresh?: boolean;
|
|
16
67
|
};
|
|
68
|
+
export declare function repairOrphanedToolMessages({ context, allMessages, tokenCounter, indexTokenCountMap, }: {
|
|
69
|
+
context: BaseMessage[];
|
|
70
|
+
allMessages: BaseMessage[];
|
|
71
|
+
tokenCounter: TokenCounter;
|
|
72
|
+
indexTokenCountMap: Record<string, number | undefined>;
|
|
73
|
+
}): {
|
|
74
|
+
context: BaseMessage[];
|
|
75
|
+
reclaimedTokens: number;
|
|
76
|
+
droppedOrphanCount: number;
|
|
77
|
+
/** Messages removed from context during orphan repair. These should be
|
|
78
|
+
* appended to `messagesToRefine` so that summarization can still see them
|
|
79
|
+
* (e.g. a ToolMessage whose parent AI was pruned). */
|
|
80
|
+
droppedMessages: BaseMessage[];
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Lightweight structural cleanup: strips orphan tool_use blocks from AI messages
|
|
84
|
+
* and drops orphan ToolMessages whose AI counterpart is missing.
|
|
85
|
+
*
|
|
86
|
+
* Unlike `repairOrphanedToolMessages`, this does NOT track tokens — it is
|
|
87
|
+
* intended as a final safety net in Graph.ts right before model invocation
|
|
88
|
+
* to prevent Anthropic/Bedrock structural validation errors.
|
|
89
|
+
*
|
|
90
|
+
* Uses duck-typing instead of `getType()` because messages at this stage
|
|
91
|
+
* may be plain objects (from LangGraph state serialization) rather than
|
|
92
|
+
* proper BaseMessage class instances.
|
|
93
|
+
*
|
|
94
|
+
* Includes a fast-path: if every tool_call has a matching tool_result and
|
|
95
|
+
* vice-versa, the original array is returned immediately with zero allocation.
|
|
96
|
+
*/
|
|
97
|
+
export declare function sanitizeOrphanToolBlocks(messages: BaseMessage[]): BaseMessage[];
|
|
17
98
|
/**
|
|
18
99
|
* Calculates the total tokens from a single usage object
|
|
19
100
|
*
|
|
@@ -34,7 +115,7 @@ export type PruningResult = {
|
|
|
34
115
|
* @param options Configuration options for processing messages
|
|
35
116
|
* @returns Object containing the message context, remaining tokens, messages not included, and summary index
|
|
36
117
|
*/
|
|
37
|
-
export declare function getMessagesWithinTokenLimit({ messages: _messages, maxContextTokens, indexTokenCountMap, startType: _startType, thinkingEnabled, tokenCounter, thinkingStartIndex: _thinkingStartIndex, reasoningType, }: {
|
|
118
|
+
export declare function getMessagesWithinTokenLimit({ messages: _messages, maxContextTokens, indexTokenCountMap, startType: _startType, thinkingEnabled, tokenCounter, thinkingStartIndex: _thinkingStartIndex, reasoningType, instructionTokens: _instructionTokens, }: {
|
|
38
119
|
messages: BaseMessage[];
|
|
39
120
|
maxContextTokens: number;
|
|
40
121
|
indexTokenCountMap: Record<string, number | undefined>;
|
|
@@ -43,9 +124,89 @@ export declare function getMessagesWithinTokenLimit({ messages: _messages, maxCo
|
|
|
43
124
|
tokenCounter: TokenCounter;
|
|
44
125
|
thinkingStartIndex?: number;
|
|
45
126
|
reasoningType?: ContentTypes.THINKING | ContentTypes.REASONING_CONTENT;
|
|
127
|
+
/**
|
|
128
|
+
* Token overhead for instructions (system message + tool schemas + summary)
|
|
129
|
+
* that are NOT included in `messages`. When messages[0] is already a
|
|
130
|
+
* SystemMessage the budget is deducted from its indexTokenCountMap entry
|
|
131
|
+
* as before; otherwise this value is subtracted from the available budget.
|
|
132
|
+
*/
|
|
133
|
+
instructionTokens?: number;
|
|
46
134
|
}): PruningResult;
|
|
47
135
|
export declare function checkValidNumber(value: unknown): value is number;
|
|
136
|
+
/**
|
|
137
|
+
* Observation masking: replaces consumed ToolMessage content with tight
|
|
138
|
+
* head+tail truncations that serve as informative placeholders.
|
|
139
|
+
*
|
|
140
|
+
* A ToolMessage is "consumed" when a subsequent AI message exists that is NOT
|
|
141
|
+
* purely tool calls — meaning the model has already read and acted on the
|
|
142
|
+
* result. Unconsumed results (the latest tool outputs the model hasn't
|
|
143
|
+
* responded to yet) are left intact so the model can still use them.
|
|
144
|
+
*
|
|
145
|
+
* AI messages are never masked — they contain the model's own reasoning and
|
|
146
|
+
* conclusions, which is what prevents the model from repeating work after
|
|
147
|
+
* its tool results are masked.
|
|
148
|
+
*
|
|
149
|
+
* @returns The number of tool messages that were masked.
|
|
150
|
+
*/
|
|
151
|
+
export declare function maskConsumedToolResults(params: {
|
|
152
|
+
messages: BaseMessage[];
|
|
153
|
+
indexTokenCountMap: Record<string, number | undefined>;
|
|
154
|
+
tokenCounter: TokenCounter;
|
|
155
|
+
/** Raw-space token budget available for all consumed tool results combined.
|
|
156
|
+
* When provided, the budget is distributed across consumed results weighted
|
|
157
|
+
* by recency (newest get the most, oldest get MASKED_RESULT_MAX_CHARS min).
|
|
158
|
+
* When omitted, falls back to a flat MASKED_RESULT_MAX_CHARS per result. */
|
|
159
|
+
availableRawBudget?: number;
|
|
160
|
+
/** When provided, original (pre-masking) content is stored here keyed by
|
|
161
|
+
* message index — only for entries that actually get truncated. */
|
|
162
|
+
originalContentStore?: Map<number, string>;
|
|
163
|
+
/** Called after storing content with the char length of the stored entry. */
|
|
164
|
+
onContentStored?: (charLength: number) => void;
|
|
165
|
+
}): number;
|
|
166
|
+
/**
|
|
167
|
+
* Pre-flight truncation: truncates oversized ToolMessage content before the
|
|
168
|
+
* main backward-iteration pruning runs. Unlike the ingestion guard (which caps
|
|
169
|
+
* at tool-execution time), pre-flight truncation applies per-turn based on the
|
|
170
|
+
* current context window budget (which may have shrunk due to growing conversation).
|
|
171
|
+
*
|
|
172
|
+
* After truncation, recounts tokens via tokenCounter and updates indexTokenCountMap
|
|
173
|
+
* so subsequent pruning works with accurate counts.
|
|
174
|
+
*
|
|
175
|
+
* @returns The number of tool messages that were truncated.
|
|
176
|
+
*/
|
|
177
|
+
export declare function preFlightTruncateToolResults(params: {
|
|
178
|
+
messages: BaseMessage[];
|
|
179
|
+
maxContextTokens: number;
|
|
180
|
+
indexTokenCountMap: Record<string, number | undefined>;
|
|
181
|
+
tokenCounter: TokenCounter;
|
|
182
|
+
}): number;
|
|
183
|
+
/**
|
|
184
|
+
* Pre-flight truncation: truncates oversized `tool_use` input fields in AI messages.
|
|
185
|
+
*
|
|
186
|
+
* Tool call inputs (arguments) can be very large — e.g., code evaluation payloads from
|
|
187
|
+
* MCP tools like chrome-devtools. Since these tool calls have already been executed,
|
|
188
|
+
* the model only needs a summary of what was called, not the full arguments. Truncating
|
|
189
|
+
* them before pruning can prevent entire messages from being dropped.
|
|
190
|
+
*
|
|
191
|
+
* Uses 15% of the context window (in estimated characters, ~4 chars/token) as the
|
|
192
|
+
* per-input cap, capped at 200K chars.
|
|
193
|
+
*
|
|
194
|
+
* @returns The number of AI messages that had tool_use inputs truncated.
|
|
195
|
+
*/
|
|
196
|
+
export declare function preFlightTruncateToolCallInputs(params: {
|
|
197
|
+
messages: BaseMessage[];
|
|
198
|
+
maxContextTokens: number;
|
|
199
|
+
indexTokenCountMap: Record<string, number | undefined>;
|
|
200
|
+
tokenCounter: TokenCounter;
|
|
201
|
+
}): number;
|
|
48
202
|
export declare function createPruneMessages(factoryParams: PruneMessagesFactoryParams): (params: PruneMessagesParams) => {
|
|
49
203
|
context: BaseMessage[];
|
|
50
204
|
indexTokenCountMap: Record<string, number | undefined>;
|
|
205
|
+
messagesToRefine?: BaseMessage[];
|
|
206
|
+
prePruneContextTokens?: number;
|
|
207
|
+
remainingContextTokens?: number;
|
|
208
|
+
contextPressure?: number;
|
|
209
|
+
originalToolContent?: Map<number, string>;
|
|
210
|
+
calibrationRatio?: number;
|
|
211
|
+
resolvedInstructionOverhead?: number;
|
|
51
212
|
};
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { BaseMessage, BaseMessageLike } from '@langchain/core/messages';
|
|
2
2
|
export declare const REMOVE_ALL_MESSAGES = "__remove_all__";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a message that instructs messagesStateReducer to remove ALL
|
|
5
|
+
* existing messages from state. Messages appearing after this one in
|
|
6
|
+
* the array become the new state.
|
|
7
|
+
*
|
|
8
|
+
* Usage (in a node return value):
|
|
9
|
+
* ```ts
|
|
10
|
+
* return { messages: [createRemoveAllMessage(), ...survivingMessages] };
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* This works because the reducer checks for `getType() === 'remove'`
|
|
14
|
+
* with `id === REMOVE_ALL_MESSAGES` and discards everything before it.
|
|
15
|
+
*
|
|
16
|
+
* NOTE: Uses RemoveMessage from @langchain/core with a sentinel id so
|
|
17
|
+
* the reducer can distinguish a "remove-all" marker from a single-message
|
|
18
|
+
* removal.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createRemoveAllMessage(): BaseMessage;
|
|
3
21
|
export type Messages = Array<BaseMessage | BaseMessageLike> | BaseMessage | BaseMessageLike;
|
|
4
22
|
/**
|
|
5
23
|
* Prebuilt reducer that combines returned messages.
|
package/dist/types/run.d.ts
CHANGED
|
@@ -10,21 +10,32 @@ export declare class Run<_T extends t.BaseGraphState> {
|
|
|
10
10
|
private tokenCounter?;
|
|
11
11
|
private handlerRegistry?;
|
|
12
12
|
private indexTokenCountMap?;
|
|
13
|
+
calibrationRatio: number;
|
|
13
14
|
graphRunnable?: t.CompiledStateWorkflow;
|
|
14
15
|
Graph: StandardGraph | MultiAgentGraph | undefined;
|
|
15
16
|
returnContent: boolean;
|
|
16
17
|
private skipCleanup;
|
|
18
|
+
private _streamResult;
|
|
17
19
|
private constructor();
|
|
18
20
|
private createLegacyGraph;
|
|
19
21
|
private createMultiAgentGraph;
|
|
20
22
|
static create<T extends t.BaseGraphState>(config: t.RunConfig): Promise<Run<T>>;
|
|
21
23
|
getRunMessages(): BaseMessage[] | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Returns the current calibration ratio (EMA of provider-vs-estimate token ratios).
|
|
26
|
+
* Hosts should persist this value and pass it back as `RunConfig.calibrationRatio`
|
|
27
|
+
* on the next run for the same conversation so the pruner starts with an accurate
|
|
28
|
+
* scaling factor instead of the default (1).
|
|
29
|
+
*/
|
|
30
|
+
getCalibrationRatio(): number;
|
|
31
|
+
getResolvedInstructionOverhead(): number | undefined;
|
|
32
|
+
getToolCount(): number;
|
|
22
33
|
/**
|
|
23
34
|
* Creates a custom event callback handler that intercepts custom events
|
|
24
35
|
* and processes them through our handler registry instead of EventStreamCallbackHandler
|
|
25
36
|
*/
|
|
26
37
|
private createCustomEventCallback;
|
|
27
|
-
processStream(inputs: t.IState,
|
|
38
|
+
processStream(inputs: t.IState, callerConfig: Partial<RunnableConfig> & {
|
|
28
39
|
version: 'v1' | 'v2';
|
|
29
40
|
run_id?: string;
|
|
30
41
|
}, streamOptions?: t.EventStreamOptions): Promise<MessageContentComplex[] | undefined>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SummarizationTrigger } from '@/types';
|
|
2
|
+
/**
|
|
3
|
+
* Determines whether summarization should be triggered based on the configured trigger
|
|
4
|
+
* and current context state.
|
|
5
|
+
*
|
|
6
|
+
* Default behavior (no trigger configured): returns `true` whenever messages were pruned.
|
|
7
|
+
* This is intentional — when an admin enables summarization without specifying a trigger,
|
|
8
|
+
* summarization fires on any context overflow that causes pruning.
|
|
9
|
+
*
|
|
10
|
+
* When a trigger IS configured but required runtime data is missing (e.g., maxContextTokens
|
|
11
|
+
* unavailable for a token_ratio trigger), returns `false` — we cannot evaluate the condition,
|
|
12
|
+
* so we do not fire.
|
|
13
|
+
*/
|
|
14
|
+
export declare function shouldTriggerSummarization(params: {
|
|
15
|
+
trigger?: SummarizationTrigger;
|
|
16
|
+
maxContextTokens?: number;
|
|
17
|
+
prePruneContextTokens?: number;
|
|
18
|
+
remainingContextTokens?: number;
|
|
19
|
+
messagesToRefineCount: number;
|
|
20
|
+
}): boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
2
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
3
|
+
import type { AgentContext } from '@/agents/AgentContext';
|
|
4
|
+
import type * as t from '@/types';
|
|
5
|
+
/** Structured checkpoint prompt for fresh summarization (no prior summary). */
|
|
6
|
+
export declare const DEFAULT_SUMMARIZATION_PROMPT = "Hold on, before you continue I need you to write me a checkpoint of everything so far. Your context window is filling up and this checkpoint replaces the messages above, so capture everything you need to pick right back up.\n\nDon't second-guess or fact-check anything you did, your tool results reflect exactly what happened. Just record what you did and what you observed. Only the checkpoint, don't respond to me or continue the conversation.\n\n## Checkpoint\n\n## Goal\nWhat I asked you to do and any sub-goals you identified.\n\n## Constraints & Preferences\nAny rules, preferences, or configuration I established.\n\n## Progress\n### Done\n- What you completed and the outcomes\n\n### In Progress\n- What you're currently working on\n\n## Key Decisions\nDecisions you made and why.\n\n## Next Steps\nConcrete task actions remaining, in priority order.\n\n## Critical Context\nExact identifiers, names, error messages, URLs, and details you need to preserve verbatim.\n\nRules:\n- Record what you did and observed, don't judge or re-evaluate it\n- For each tool call: the tool name, key inputs, and the outcome\n- Preserve exact identifiers, names, errors, and references verbatim\n- Short declarative sentences\n- Skip empty sections";
|
|
7
|
+
/** Prompt for re-compaction when a prior summary exists. */
|
|
8
|
+
export declare const DEFAULT_UPDATE_SUMMARIZATION_PROMPT = "Hold on again, update your checkpoint. Merge the new messages into your existing checkpoint and give me a single consolidated replacement.\n\nKeep it roughly the same length as your last checkpoint. Compress older details to make room for what's new, don't just append. Give recent actions more detail, compress older items to one-liners.\n\nDon't fact-check or second-guess anything, your tool results are ground truth. Only the checkpoint, don't respond to me or continue the conversation.\n\nRules:\n- Merge new progress into existing sections, don't duplicate headers\n- Compress older completed items into one-line entries\n- Move items from \"In Progress\" to \"Done\" when you completed them\n- Update \"Next Steps\" to reflect current task priorities.\n- For each new tool call: the tool name, key inputs, and the outcome\n- Preserve exact identifiers, names, errors, and references verbatim\n- Skip empty sections";
|
|
9
|
+
interface CreateSummarizeNodeParams {
|
|
10
|
+
agentContext: AgentContext;
|
|
11
|
+
graph: {
|
|
12
|
+
contentData: t.RunStep[];
|
|
13
|
+
contentIndexMap: Map<string, number>;
|
|
14
|
+
config?: RunnableConfig;
|
|
15
|
+
runId?: string;
|
|
16
|
+
isMultiAgent: boolean;
|
|
17
|
+
dispatchRunStep: (runStep: t.RunStep, config?: RunnableConfig) => Promise<void>;
|
|
18
|
+
dispatchRunStepCompleted: (stepId: string, result: t.StepCompleted, config?: RunnableConfig) => Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
generateStepId: (stepKey: string) => [string, number];
|
|
21
|
+
}
|
|
22
|
+
export declare function createSummarizeNode({ agentContext, graph, generateStepId, }: CreateSummarizeNodeParams): (state: {
|
|
23
|
+
messages: BaseMessage[];
|
|
24
|
+
summarizationRequest?: t.SummarizationNodeInput;
|
|
25
|
+
}, config?: RunnableConfig) => Promise<{
|
|
26
|
+
summarizationRequest: undefined;
|
|
27
|
+
messages?: BaseMessage[];
|
|
28
|
+
}>;
|
|
29
|
+
export {};
|
|
@@ -26,7 +26,9 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
26
26
|
private agentId?;
|
|
27
27
|
/** Tool names that bypass event dispatch and execute directly (e.g., graph-managed handoff tools) */
|
|
28
28
|
private directToolNames?;
|
|
29
|
-
|
|
29
|
+
/** Maximum characters allowed in a single tool result before truncation. */
|
|
30
|
+
private maxToolResultChars;
|
|
31
|
+
constructor({ tools, toolMap, name, tags, errorHandler, toolCallStepIds, handleToolErrors, loadRuntimeTools, toolRegistry, sessions, eventDrivenMode, agentId, directToolNames, maxContextTokens, maxToolResultChars, }: t.ToolNodeConstructorParams);
|
|
30
32
|
/**
|
|
31
33
|
* Returns cached programmatic tools, computing once on first access.
|
|
32
34
|
* Single iteration builds both toolMap and toolDefs simultaneously.
|
|
@@ -8,6 +8,7 @@ import type { ToolMap, ToolEndEvent, GenericTool, LCTool } from '@/types/tools';
|
|
|
8
8
|
import type { Providers, Callback, GraphNodeKeys } from '@/common';
|
|
9
9
|
import type { StandardGraph, MultiAgentGraph } from '@/graphs';
|
|
10
10
|
import type { ClientOptions } from '@/types/llm';
|
|
11
|
+
import type { SummarizationNodeInput, SummarizeCompleteEvent, SummarizationConfig, SummarizeStartEvent, SummarizeDeltaEvent } from '@/types/summarize';
|
|
11
12
|
import type { RunStep, RunStepDeltaEvent, MessageDeltaEvent, ReasoningDeltaEvent } from '@/types/stream';
|
|
12
13
|
import type { TokenCounter } from '@/types/run';
|
|
13
14
|
/** Interface for bound model with stream and invoke methods */
|
|
@@ -28,12 +29,23 @@ export type SystemCallbacks = {
|
|
|
28
29
|
export type BaseGraphState = {
|
|
29
30
|
messages: BaseMessage[];
|
|
30
31
|
};
|
|
32
|
+
export type AgentSubgraphState = BaseGraphState & {
|
|
33
|
+
summarizationRequest?: SummarizationNodeInput;
|
|
34
|
+
};
|
|
31
35
|
export type MultiAgentGraphState = BaseGraphState & {
|
|
32
36
|
agentMessages?: BaseMessage[];
|
|
33
37
|
};
|
|
34
38
|
export type IState = BaseGraphState;
|
|
39
|
+
export interface AgentLogEvent {
|
|
40
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
41
|
+
scope: 'prune' | 'summarize' | 'graph' | 'sanitize' | (string & {});
|
|
42
|
+
message: string;
|
|
43
|
+
data?: Record<string, unknown>;
|
|
44
|
+
runId?: string;
|
|
45
|
+
agentId?: string;
|
|
46
|
+
}
|
|
35
47
|
export interface EventHandler {
|
|
36
|
-
handle(event: string, data: StreamEventData | ModelEndData | RunStep | RunStepDeltaEvent | MessageDeltaEvent | ReasoningDeltaEvent | {
|
|
48
|
+
handle(event: string, data: StreamEventData | ModelEndData | RunStep | RunStepDeltaEvent | MessageDeltaEvent | ReasoningDeltaEvent | SummarizeStartEvent | SummarizeDeltaEvent | SummarizeCompleteEvent | AgentLogEvent | {
|
|
37
49
|
result: ToolEndEvent;
|
|
38
50
|
}, metadata?: Record<string, unknown>, graph?: StandardGraph | MultiAgentGraph): void | Promise<void>;
|
|
39
51
|
}
|
|
@@ -62,17 +74,16 @@ export type CompiledMultiAgentWorkflow = CompiledStateGraph<StateType<{
|
|
|
62
74
|
messages: BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
63
75
|
agentMessages: BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
64
76
|
}, StateDefinition>;
|
|
65
|
-
export type CompiledAgentWorfklow = CompiledStateGraph<{
|
|
66
|
-
messages: BaseMessage[];
|
|
67
|
-
}, {
|
|
68
|
-
messages?: BaseMessage[] | undefined;
|
|
69
|
-
}, '__start__' | `agent=${string}` | `tools=${string}`, {
|
|
77
|
+
export type CompiledAgentWorfklow = CompiledStateGraph<AgentSubgraphState, Partial<AgentSubgraphState>, '__start__' | `agent=${string}` | `tools=${string}` | `summarize=${string}`, {
|
|
70
78
|
messages: BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
79
|
+
summarizationRequest: BinaryOperatorAggregate<SummarizationNodeInput | undefined, SummarizationNodeInput | undefined>;
|
|
71
80
|
}, {
|
|
72
81
|
messages: BinaryOperatorAggregate<BaseMessage[], BaseMessage[]>;
|
|
82
|
+
summarizationRequest: BinaryOperatorAggregate<SummarizationNodeInput | undefined, SummarizationNodeInput | undefined>;
|
|
73
83
|
}, StateDefinition, {
|
|
74
84
|
[x: `agent=${string}`]: Partial<BaseGraphState>;
|
|
75
85
|
[x: `tools=${string}`]: any;
|
|
86
|
+
[x: `summarize=${string}`]: any;
|
|
76
87
|
}>;
|
|
77
88
|
export type SystemRunnable = Runnable<BaseMessage[], (BaseMessage | SystemMessage)[], RunnableConfig<Record<string, unknown>>> | undefined;
|
|
78
89
|
/**
|
|
@@ -201,6 +212,7 @@ export type StandardGraphInput = {
|
|
|
201
212
|
agents: AgentInputs[];
|
|
202
213
|
tokenCounter?: TokenCounter;
|
|
203
214
|
indexTokenCountMap?: Record<string, number>;
|
|
215
|
+
calibrationRatio?: number;
|
|
204
216
|
};
|
|
205
217
|
export type GraphEdge = {
|
|
206
218
|
/** Agent ID, use a list for multiple sources */
|
|
@@ -270,4 +282,30 @@ export interface AgentInputs {
|
|
|
270
282
|
* in tool binding without requiring tool_search.
|
|
271
283
|
*/
|
|
272
284
|
discoveredTools?: string[];
|
|
285
|
+
summarizationEnabled?: boolean;
|
|
286
|
+
summarizationConfig?: SummarizationConfig;
|
|
287
|
+
/** Cross-run summary from a previous run, forwarded from formatAgentMessages.
|
|
288
|
+
* Injected into the system message via AgentContext.buildInstructionsString(). */
|
|
289
|
+
initialSummary?: {
|
|
290
|
+
text: string;
|
|
291
|
+
tokenCount: number;
|
|
292
|
+
};
|
|
293
|
+
contextPruningConfig?: ContextPruningConfig;
|
|
294
|
+
maxToolResultChars?: number;
|
|
295
|
+
}
|
|
296
|
+
export interface ContextPruningConfig {
|
|
297
|
+
enabled?: boolean;
|
|
298
|
+
keepLastAssistants?: number;
|
|
299
|
+
softTrimRatio?: number;
|
|
300
|
+
hardClearRatio?: number;
|
|
301
|
+
minPrunableToolChars?: number;
|
|
302
|
+
softTrim?: {
|
|
303
|
+
maxChars?: number;
|
|
304
|
+
headChars?: number;
|
|
305
|
+
tailChars?: number;
|
|
306
|
+
};
|
|
307
|
+
hardClear?: {
|
|
308
|
+
enabled?: boolean;
|
|
309
|
+
placeholder?: string;
|
|
310
|
+
};
|
|
273
311
|
}
|
|
@@ -103,11 +103,41 @@ export type RunConfig = {
|
|
|
103
103
|
returnContent?: boolean;
|
|
104
104
|
tokenCounter?: TokenCounter;
|
|
105
105
|
indexTokenCountMap?: Record<string, number>;
|
|
106
|
+
/**
|
|
107
|
+
* Calibration ratio from a previous run's contextMeta.
|
|
108
|
+
* Seeds the pruner's EMA so new messages are scaled immediately.
|
|
109
|
+
*
|
|
110
|
+
* Hosts should persist the value returned by `Run.getCalibrationRatio()`
|
|
111
|
+
* after each run and pass it back here on subsequent runs for the same
|
|
112
|
+
* conversation. Without this, the EMA resets to 1 on every new Run instance.
|
|
113
|
+
*/
|
|
114
|
+
calibrationRatio?: number;
|
|
106
115
|
/** Skip post-stream cleanup (clearHeavyState) — useful for tests that inspect graph state after processStream */
|
|
107
116
|
skipCleanup?: boolean;
|
|
108
117
|
};
|
|
109
118
|
export type ProvidedCallbacks = (BaseCallbackHandler | CallbackHandlerMethods)[] | undefined;
|
|
110
119
|
export type TokenCounter = (message: BaseMessage) => number;
|
|
120
|
+
/** Structured breakdown of how context token budget is consumed. */
|
|
121
|
+
export type TokenBudgetBreakdown = {
|
|
122
|
+
/** Total context window budget (maxContextTokens). */
|
|
123
|
+
maxContextTokens: number;
|
|
124
|
+
/** Total instruction tokens (system + tools + summary). */
|
|
125
|
+
instructionTokens: number;
|
|
126
|
+
/** Tokens from the system message text alone. */
|
|
127
|
+
systemMessageTokens: number;
|
|
128
|
+
/** Tokens from tool schema definitions. */
|
|
129
|
+
toolSchemaTokens: number;
|
|
130
|
+
/** Tokens from the conversation summary. */
|
|
131
|
+
summaryTokens: number;
|
|
132
|
+
/** Number of registered tools. */
|
|
133
|
+
toolCount: number;
|
|
134
|
+
/** Number of messages in the conversation. */
|
|
135
|
+
messageCount: number;
|
|
136
|
+
/** Total tokens consumed by messages (excluding system). */
|
|
137
|
+
messageTokens: number;
|
|
138
|
+
/** Tokens available for messages after instructions. */
|
|
139
|
+
availableForMessages: number;
|
|
140
|
+
};
|
|
111
141
|
export type EventStreamOptions = {
|
|
112
142
|
callbacks?: g.ClientCallbacks;
|
|
113
143
|
keepContent?: boolean;
|
|
@@ -4,6 +4,7 @@ import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
|
|
|
4
4
|
import type { LLMResult, Generation } from '@langchain/core/outputs';
|
|
5
5
|
import type { AnthropicContentBlock } from '@/llm/anthropic/types';
|
|
6
6
|
import type { Command } from '@langchain/langgraph';
|
|
7
|
+
import type { SummarizeCompleteEvent } from '@/types/summarize';
|
|
7
8
|
import type { ToolEndEvent } from '@/types/tools';
|
|
8
9
|
import { StepTypes, ContentTypes, GraphEvents } from '@/common/enum';
|
|
9
10
|
export type HandleLLMEnd = (output: LLMResult, runId: string, parentRunId?: string, tags?: string[]) => void;
|
|
@@ -52,6 +53,7 @@ export type RunStep = {
|
|
|
52
53
|
index: number;
|
|
53
54
|
stepIndex?: number;
|
|
54
55
|
stepDetails: StepDetails;
|
|
56
|
+
summary?: SummaryContentBlock;
|
|
55
57
|
usage?: null | object;
|
|
56
58
|
};
|
|
57
59
|
/**
|
|
@@ -69,7 +71,11 @@ export interface RunStepDeltaEvent {
|
|
|
69
71
|
delta: ToolCallDelta;
|
|
70
72
|
}
|
|
71
73
|
export type StepDetails = MessageCreationDetails | ToolCallsDetails;
|
|
72
|
-
export type
|
|
74
|
+
export type SummaryCompleted = {
|
|
75
|
+
type: 'summary';
|
|
76
|
+
summary: SummaryContentBlock;
|
|
77
|
+
};
|
|
78
|
+
export type StepCompleted = ToolCallCompleted | SummaryCompleted;
|
|
73
79
|
export type MessageCreationDetails = {
|
|
74
80
|
type: StepTypes.MESSAGE_CREATION;
|
|
75
81
|
message_creation: {
|
|
@@ -116,6 +122,7 @@ export type ToolCallsDetails = {
|
|
|
116
122
|
export type ToolCallDelta = {
|
|
117
123
|
type: StepTypes;
|
|
118
124
|
tool_calls?: ToolCallChunk[];
|
|
125
|
+
summary?: SummaryContentBlock;
|
|
119
126
|
auth?: string;
|
|
120
127
|
expires_at?: number;
|
|
121
128
|
};
|
|
@@ -202,11 +209,25 @@ export type ReasoningDeltaUpdate = {
|
|
|
202
209
|
type: ContentTypes.THINK;
|
|
203
210
|
think: string;
|
|
204
211
|
};
|
|
205
|
-
export type ContentType = 'text' | 'image_url' | 'tool_call' | 'think' | string;
|
|
212
|
+
export type ContentType = 'text' | 'image_url' | 'tool_call' | 'think' | 'summary' | string;
|
|
206
213
|
export type ReasoningContentText = {
|
|
207
214
|
type: ContentTypes.THINK;
|
|
208
215
|
think: string;
|
|
209
216
|
};
|
|
217
|
+
export type SummaryBoundary = {
|
|
218
|
+
messageId: string;
|
|
219
|
+
contentIndex: number;
|
|
220
|
+
};
|
|
221
|
+
export type SummaryContentBlock = {
|
|
222
|
+
type: ContentTypes.SUMMARY;
|
|
223
|
+
content?: MessageContentComplex[];
|
|
224
|
+
tokenCount?: number;
|
|
225
|
+
boundary?: SummaryBoundary;
|
|
226
|
+
summaryVersion?: number;
|
|
227
|
+
model?: string;
|
|
228
|
+
provider?: string;
|
|
229
|
+
createdAt?: string;
|
|
230
|
+
};
|
|
210
231
|
/** Vertex AI / Google Common - Reasoning Content Block Format */
|
|
211
232
|
export type GoogleReasoningContentText = {
|
|
212
233
|
type: ContentTypes.REASONING;
|
|
@@ -258,7 +279,7 @@ export type ToolResultContent = {
|
|
|
258
279
|
input?: string | Record<string, unknown>;
|
|
259
280
|
index?: number;
|
|
260
281
|
};
|
|
261
|
-
export type MessageContentComplex = (ToolResultContent | ThinkingContentText | AgentUpdate | ToolCallContent | ReasoningContentText | MessageContentText | MessageContentImageUrl | (Record<string, any> & {
|
|
282
|
+
export type MessageContentComplex = (ToolResultContent | ThinkingContentText | SummaryContentBlock | AgentUpdate | ToolCallContent | ReasoningContentText | MessageContentText | MessageContentImageUrl | (Record<string, any> & {
|
|
262
283
|
type?: 'text' | 'image_url' | 'think' | 'thinking' | string;
|
|
263
284
|
}) | (Record<string, any> & {
|
|
264
285
|
type?: never;
|
|
@@ -297,9 +318,15 @@ export type SplitStreamHandlers = Partial<{
|
|
|
297
318
|
data: ReasoningDeltaEvent;
|
|
298
319
|
}) => void;
|
|
299
320
|
}>;
|
|
321
|
+
export type SummarizeDeltaData = {
|
|
322
|
+
id: string;
|
|
323
|
+
delta: {
|
|
324
|
+
summary: SummaryContentBlock;
|
|
325
|
+
};
|
|
326
|
+
};
|
|
300
327
|
export type ContentAggregator = ({ event, data, }: {
|
|
301
328
|
event: GraphEvents;
|
|
302
|
-
data: RunStep | MessageDeltaEvent | RunStepDeltaEvent | {
|
|
329
|
+
data: RunStep | AgentUpdate | MessageDeltaEvent | ReasoningDeltaEvent | RunStepDeltaEvent | SummarizeDeltaData | SummarizeCompleteEvent | {
|
|
303
330
|
result: ToolEndEvent;
|
|
304
331
|
};
|
|
305
332
|
}) => void;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SummaryContentBlock } from '@/types/stream';
|
|
2
|
+
import type { Providers } from '@/common';
|
|
3
|
+
export type SummarizationTrigger = {
|
|
4
|
+
type: 'token_ratio' | 'remaining_tokens' | 'messages_to_refine' | (string & {});
|
|
5
|
+
value: number;
|
|
6
|
+
};
|
|
7
|
+
export type SummarizationConfig = {
|
|
8
|
+
provider?: Providers;
|
|
9
|
+
model?: string;
|
|
10
|
+
parameters?: Record<string, unknown>;
|
|
11
|
+
prompt?: string;
|
|
12
|
+
updatePrompt?: string;
|
|
13
|
+
trigger?: SummarizationTrigger;
|
|
14
|
+
maxSummaryTokens?: number;
|
|
15
|
+
/** Fraction of the token budget reserved as headroom (0–1). Defaults to 0.05. */
|
|
16
|
+
reserveRatio?: number;
|
|
17
|
+
};
|
|
18
|
+
export interface SummarizeResult {
|
|
19
|
+
text: string;
|
|
20
|
+
tokenCount: number;
|
|
21
|
+
model?: string;
|
|
22
|
+
provider?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SummarizationNodeInput {
|
|
25
|
+
remainingContextTokens: number;
|
|
26
|
+
agentId: string;
|
|
27
|
+
}
|
|
28
|
+
export interface SummarizeStartEvent {
|
|
29
|
+
agentId: string;
|
|
30
|
+
provider: string;
|
|
31
|
+
model?: string;
|
|
32
|
+
messagesToRefineCount: number;
|
|
33
|
+
/** Which summarization cycle this is (1-based, increments each time summarization fires) */
|
|
34
|
+
summaryVersion: number;
|
|
35
|
+
}
|
|
36
|
+
export interface SummarizeDeltaEvent {
|
|
37
|
+
id: string;
|
|
38
|
+
delta: {
|
|
39
|
+
summary: SummaryContentBlock;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface SummarizeCompleteEvent {
|
|
43
|
+
id: string;
|
|
44
|
+
agentId: string;
|
|
45
|
+
summary?: SummaryContentBlock;
|
|
46
|
+
error?: string;
|
|
47
|
+
}
|
|
@@ -39,6 +39,13 @@ export type ToolNodeOptions = {
|
|
|
39
39
|
agentId?: string;
|
|
40
40
|
/** Tool names that must be executed directly (via runTool) even in event-driven mode (e.g., graph-managed handoff tools) */
|
|
41
41
|
directToolNames?: Set<string>;
|
|
42
|
+
/** Max context tokens for the agent — used to compute tool result truncation limits. */
|
|
43
|
+
maxContextTokens?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Maximum characters allowed in a single tool result before truncation.
|
|
46
|
+
* When provided, takes precedence over the value computed from maxContextTokens.
|
|
47
|
+
*/
|
|
48
|
+
maxToolResultChars?: number;
|
|
42
49
|
};
|
|
43
50
|
export type ToolNodeConstructorParams = ToolRefs & ToolNodeOptions;
|
|
44
51
|
export type ToolEndEvent = {
|