@librechat/agents 3.2.32 → 3.2.33
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/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/cjs/agents/AgentContext.cjs +844 -1046
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/constants.cjs +13 -13
- package/dist/cjs/common/constants.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +233 -240
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/common/index.cjs +2 -0
- package/dist/cjs/events.cjs +121 -169
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +1389 -1807
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +713 -945
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/graphs/index.cjs +2 -0
- package/dist/cjs/hitl/askUserQuestion.cjs +60 -62
- package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
- package/dist/cjs/hitl/index.cjs +1 -0
- package/dist/cjs/hooks/HookRegistry.cjs +176 -202
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
- package/dist/cjs/hooks/createToolPolicyHook.cjs +71 -101
- package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
- package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +170 -273
- package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
- package/dist/cjs/hooks/executeHooks.cjs +227 -282
- package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
- package/dist/cjs/hooks/index.cjs +6 -0
- package/dist/cjs/hooks/matchers.cjs +196 -230
- package/dist/cjs/hooks/matchers.cjs.map +1 -1
- package/dist/cjs/hooks/types.cjs +24 -24
- package/dist/cjs/hooks/types.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +110 -137
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/langchain/google-common.cjs +0 -3
- package/dist/cjs/langchain/index.cjs +80 -43
- package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
- package/dist/cjs/langchain/messages/tool.cjs +0 -3
- package/dist/cjs/langchain/messages.cjs +35 -18
- package/dist/cjs/langchain/openai.cjs +0 -3
- package/dist/cjs/langchain/prompts.cjs +5 -8
- package/dist/cjs/langchain/runnables.cjs +11 -10
- package/dist/cjs/langchain/tools.cjs +14 -11
- package/dist/cjs/langchain/utils/env.cjs +5 -8
- package/dist/cjs/langfuse.cjs +60 -79
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +267 -399
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/index.cjs +432 -562
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs +23 -47
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +441 -731
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -256
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/output_parsers.cjs +2 -0
- package/dist/cjs/llm/anthropic/utils/tools.cjs +12 -26
- package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +195 -240
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/toolCache.cjs +84 -106
- package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/index.cjs +2 -0
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +357 -620
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +105 -149
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/fake.cjs +86 -96
- package/dist/cjs/llm/fake.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs +183 -237
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +398 -674
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/zod_to_genai_parameters.cjs +2 -0
- package/dist/cjs/llm/init.cjs +44 -53
- package/dist/cjs/llm/init.cjs.map +1 -1
- package/dist/cjs/llm/invoke.cjs +142 -182
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +991 -1276
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +189 -316
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +102 -153
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/toolCache.cjs +35 -44
- package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs +29 -37
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/request.cjs +20 -33
- package/dist/cjs/llm/request.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +427 -453
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +547 -528
- package/dist/cjs/messages/anthropicToolCache.cjs +68 -119
- package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +305 -418
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/content.cjs +36 -49
- package/dist/cjs/messages/content.cjs.map +1 -1
- package/dist/cjs/messages/contextPruning.cjs +112 -145
- package/dist/cjs/messages/contextPruning.cjs.map +1 -1
- package/dist/cjs/messages/contextPruningSettings.cjs +36 -46
- package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +256 -397
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +904 -1387
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/ids.cjs +16 -20
- package/dist/cjs/messages/ids.cjs.map +1 -1
- package/dist/cjs/messages/index.cjs +12 -0
- package/dist/cjs/messages/langchain.cjs +18 -18
- package/dist/cjs/messages/langchain.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +1054 -1517
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/recency.cjs +77 -95
- package/dist/cjs/messages/recency.cjs.map +1 -1
- package/dist/cjs/messages/reducer.cjs +63 -78
- package/dist/cjs/messages/reducer.cjs.map +1 -1
- package/dist/cjs/messages/tools.cjs +51 -79
- package/dist/cjs/messages/tools.cjs.map +1 -1
- package/dist/cjs/openai/index.cjs +171 -217
- package/dist/cjs/openai/index.cjs.map +1 -1
- package/dist/cjs/responses/index.cjs +302 -391
- package/dist/cjs/responses/index.cjs.map +1 -1
- package/dist/cjs/run.cjs +903 -1113
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/AgentSession.cjs +805 -986
- package/dist/cjs/session/AgentSession.cjs.map +1 -1
- package/dist/cjs/session/JsonlSessionStore.cjs +327 -410
- package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
- package/dist/cjs/session/handlers.cjs +192 -208
- package/dist/cjs/session/handlers.cjs.map +1 -1
- package/dist/cjs/session/ids.cjs +9 -10
- package/dist/cjs/session/ids.cjs.map +1 -1
- package/dist/cjs/session/index.cjs +4 -0
- package/dist/cjs/session/messageSerialization.cjs +94 -156
- package/dist/cjs/session/messageSerialization.cjs.map +1 -1
- package/dist/cjs/splitStream.cjs +147 -206
- package/dist/cjs/splitStream.cjs.map +1 -1
- package/dist/cjs/stream.cjs +856 -1344
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/index.cjs +57 -101
- package/dist/cjs/summarization/index.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +643 -796
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/BashExecutor.cjs +110 -136
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +165 -245
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/Calculator.cjs +36 -57
- package/dist/cjs/tools/Calculator.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +126 -168
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/CodeSessionFileSummary.cjs +36 -46
- package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +459 -649
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ReadFile.cjs +17 -20
- package/dist/cjs/tools/ReadFile.cjs.map +1 -1
- package/dist/cjs/tools/SkillTool.cjs +26 -27
- package/dist/cjs/tools/SkillTool.cjs.map +1 -1
- package/dist/cjs/tools/SubagentTool.cjs +59 -61
- package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +2109 -2686
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/ToolSearch.cjs +663 -825
- package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +248 -340
- package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +170 -197
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +425 -520
- package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +91 -124
- package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/index.cjs +4 -0
- package/dist/cjs/tools/eagerEventExecution.cjs +75 -99
- package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +200 -262
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/tools/local/CompileCheckTool.cjs +150 -212
- package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
- package/dist/cjs/tools/local/FileCheckpointer.cjs +77 -85
- package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalCodingTools.cjs +763 -1022
- package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs +666 -941
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalExecutionTools.cjs +49 -92
- package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +286 -354
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/attachments.cjs +108 -165
- package/dist/cjs/tools/local/attachments.cjs.map +1 -1
- package/dist/cjs/tools/local/bashAst.cjs +99 -113
- package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
- package/dist/cjs/tools/local/editStrategies.cjs +126 -169
- package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
- package/dist/cjs/tools/local/index.cjs +12 -0
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +136 -218
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/tools/local/syntaxCheck.cjs +142 -161
- package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
- package/dist/cjs/tools/local/textEncoding.cjs +25 -23
- package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
- package/dist/cjs/tools/local/workspaceFS.cjs +38 -46
- package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
- package/dist/cjs/tools/ptcTimeout.cjs +27 -47
- package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
- package/dist/cjs/tools/schema.cjs +24 -23
- package/dist/cjs/tools/schema.cjs.map +1 -1
- package/dist/cjs/tools/search/anthropic.cjs +24 -33
- package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
- package/dist/cjs/tools/search/content.cjs +95 -137
- package/dist/cjs/tools/search/content.cjs.map +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs +141 -172
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/format.cjs +128 -196
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/highlights.cjs +165 -232
- package/dist/cjs/tools/search/highlights.cjs.map +1 -1
- package/dist/cjs/tools/search/index.cjs +2 -0
- package/dist/cjs/tools/search/rerankers.cjs +151 -174
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/schema.cjs +40 -39
- package/dist/cjs/tools/search/schema.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +428 -530
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/serper-scraper.cjs +106 -127
- package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
- package/dist/cjs/tools/search/tavily-scraper.cjs +129 -181
- package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
- package/dist/cjs/tools/search/tavily-search.cjs +295 -359
- package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +260 -299
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +74 -117
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/tools/skillCatalog.cjs +54 -72
- package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
- package/dist/cjs/tools/streamedToolCallSeals.cjs +19 -36
- package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +612 -771
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/tools/subagent/index.cjs +1 -0
- package/dist/cjs/tools/toolOutputReferences.cjs +523 -630
- package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
- package/dist/cjs/utils/callbacks.cjs +11 -21
- package/dist/cjs/utils/callbacks.cjs.map +1 -1
- package/dist/cjs/utils/errors.cjs +70 -95
- package/dist/cjs/utils/errors.cjs.map +1 -1
- package/dist/cjs/utils/events.cjs +32 -42
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/cjs/utils/graph.cjs +8 -12
- package/dist/cjs/utils/graph.cjs.map +1 -1
- package/dist/cjs/utils/handlers.cjs +60 -82
- package/dist/cjs/utils/handlers.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +9 -0
- package/dist/cjs/utils/llm.cjs +19 -27
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/misc.cjs +30 -46
- package/dist/cjs/utils/misc.cjs.map +1 -1
- package/dist/cjs/utils/run.cjs +50 -66
- package/dist/cjs/utils/run.cjs.map +1 -1
- package/dist/cjs/utils/schema.cjs +11 -19
- package/dist/cjs/utils/schema.cjs.map +1 -1
- package/dist/cjs/utils/title.cjs +71 -106
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +186 -283
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/cjs/utils/truncation.cjs +95 -114
- package/dist/cjs/utils/truncation.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +844 -1044
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/constants.mjs +13 -11
- package/dist/esm/common/constants.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +221 -238
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/common/index.mjs +3 -0
- package/dist/esm/events.mjs +121 -167
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +1388 -1804
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +713 -943
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/graphs/index.mjs +3 -0
- package/dist/esm/hitl/askUserQuestion.mjs +60 -60
- package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
- package/dist/esm/hitl/index.mjs +2 -0
- package/dist/esm/hooks/HookRegistry.mjs +176 -200
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
- package/dist/esm/hooks/createToolPolicyHook.mjs +71 -99
- package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
- package/dist/esm/hooks/createWorkspacePolicyHook.mjs +170 -271
- package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
- package/dist/esm/hooks/executeHooks.mjs +227 -280
- package/dist/esm/hooks/executeHooks.mjs.map +1 -1
- package/dist/esm/hooks/index.mjs +7 -0
- package/dist/esm/hooks/matchers.mjs +196 -228
- package/dist/esm/hooks/matchers.mjs.map +1 -1
- package/dist/esm/hooks/types.mjs +24 -22
- package/dist/esm/hooks/types.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +109 -132
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/langchain/google-common.mjs +1 -2
- package/dist/esm/langchain/index.mjs +5 -5
- package/dist/esm/langchain/language_models/chat_models.mjs +1 -2
- package/dist/esm/langchain/messages/tool.mjs +1 -2
- package/dist/esm/langchain/messages.mjs +2 -2
- package/dist/esm/langchain/openai.mjs +1 -2
- package/dist/esm/langchain/prompts.mjs +2 -2
- package/dist/esm/langchain/runnables.mjs +2 -2
- package/dist/esm/langchain/tools.mjs +2 -2
- package/dist/esm/langchain/utils/env.mjs +2 -2
- package/dist/esm/langfuse.mjs +60 -76
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +267 -395
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
- package/dist/esm/llm/anthropic/index.mjs +432 -559
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs +23 -45
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +439 -725
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -253
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/output_parsers.mjs +3 -0
- package/dist/esm/llm/anthropic/utils/tools.mjs +12 -24
- package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +195 -238
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/toolCache.mjs +84 -104
- package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/index.mjs +3 -0
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +357 -618
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs +105 -147
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/fake.mjs +86 -94
- package/dist/esm/llm/fake.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +183 -235
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +397 -666
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/google/utils/zod_to_genai_parameters.mjs +3 -0
- package/dist/esm/llm/init.mjs +44 -51
- package/dist/esm/llm/init.mjs.map +1 -1
- package/dist/esm/llm/invoke.mjs +142 -180
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +991 -1271
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +188 -312
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +102 -151
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/toolCache.mjs +35 -42
- package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs +29 -34
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/request.mjs +20 -31
- package/dist/esm/llm/request.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +427 -449
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +99 -87
- package/dist/esm/messages/anthropicToolCache.mjs +68 -117
- package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +305 -416
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/content.mjs +36 -47
- package/dist/esm/messages/content.mjs.map +1 -1
- package/dist/esm/messages/contextPruning.mjs +112 -143
- package/dist/esm/messages/contextPruning.mjs.map +1 -1
- package/dist/esm/messages/contextPruningSettings.mjs +36 -44
- package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +254 -393
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +902 -1383
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/ids.mjs +16 -18
- package/dist/esm/messages/ids.mjs.map +1 -1
- package/dist/esm/messages/index.mjs +13 -0
- package/dist/esm/messages/langchain.mjs +18 -16
- package/dist/esm/messages/langchain.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +1053 -1514
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/recency.mjs +77 -93
- package/dist/esm/messages/recency.mjs.map +1 -1
- package/dist/esm/messages/reducer.mjs +63 -76
- package/dist/esm/messages/reducer.mjs.map +1 -1
- package/dist/esm/messages/tools.mjs +49 -75
- package/dist/esm/messages/tools.mjs.map +1 -1
- package/dist/esm/openai/index.mjs +170 -215
- package/dist/esm/openai/index.mjs.map +1 -1
- package/dist/esm/responses/index.mjs +301 -389
- package/dist/esm/responses/index.mjs.map +1 -1
- package/dist/esm/run.mjs +903 -1111
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/AgentSession.mjs +806 -985
- package/dist/esm/session/AgentSession.mjs.map +1 -1
- package/dist/esm/session/JsonlSessionStore.mjs +326 -407
- package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
- package/dist/esm/session/handlers.mjs +192 -206
- package/dist/esm/session/handlers.mjs.map +1 -1
- package/dist/esm/session/ids.mjs +9 -8
- package/dist/esm/session/ids.mjs.map +1 -1
- package/dist/esm/session/index.mjs +5 -0
- package/dist/esm/session/messageSerialization.mjs +94 -154
- package/dist/esm/session/messageSerialization.mjs.map +1 -1
- package/dist/esm/splitStream.mjs +147 -204
- package/dist/esm/splitStream.mjs.map +1 -1
- package/dist/esm/stream.mjs +854 -1341
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/index.mjs +57 -99
- package/dist/esm/summarization/index.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +640 -790
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/BashExecutor.mjs +103 -129
- package/dist/esm/tools/BashExecutor.mjs.map +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +162 -239
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/Calculator.mjs +34 -36
- package/dist/esm/tools/Calculator.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +123 -164
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/CodeSessionFileSummary.mjs +36 -44
- package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +454 -644
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ReadFile.mjs +17 -18
- package/dist/esm/tools/ReadFile.mjs.map +1 -1
- package/dist/esm/tools/SkillTool.mjs +26 -25
- package/dist/esm/tools/SkillTool.mjs.map +1 -1
- package/dist/esm/tools/SubagentTool.mjs +59 -59
- package/dist/esm/tools/SubagentTool.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +2107 -2684
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/ToolSearch.mjs +659 -804
- package/dist/esm/tools/ToolSearch.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +248 -338
- package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +170 -195
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +424 -517
- package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +91 -122
- package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/index.mjs +5 -0
- package/dist/esm/tools/eagerEventExecution.mjs +75 -96
- package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +200 -260
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/tools/local/CompileCheckTool.mjs +150 -210
- package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
- package/dist/esm/tools/local/FileCheckpointer.mjs +77 -83
- package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
- package/dist/esm/tools/local/LocalCodingTools.mjs +760 -1017
- package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
- package/dist/esm/tools/local/LocalExecutionEngine.mjs +663 -936
- package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
- package/dist/esm/tools/local/LocalExecutionTools.mjs +49 -90
- package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +283 -349
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/attachments.mjs +108 -163
- package/dist/esm/tools/local/attachments.mjs.map +1 -1
- package/dist/esm/tools/local/bashAst.mjs +99 -111
- package/dist/esm/tools/local/bashAst.mjs.map +1 -1
- package/dist/esm/tools/local/editStrategies.mjs +126 -167
- package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
- package/dist/esm/tools/local/index.mjs +13 -0
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +136 -216
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
- package/dist/esm/tools/local/syntaxCheck.mjs +138 -155
- package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
- package/dist/esm/tools/local/textEncoding.mjs +25 -21
- package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
- package/dist/esm/tools/local/workspaceFS.mjs +38 -44
- package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
- package/dist/esm/tools/ptcTimeout.mjs +27 -42
- package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
- package/dist/esm/tools/schema.mjs +24 -21
- package/dist/esm/tools/schema.mjs.map +1 -1
- package/dist/esm/tools/search/anthropic.mjs +24 -31
- package/dist/esm/tools/search/anthropic.mjs.map +1 -1
- package/dist/esm/tools/search/content.mjs +93 -116
- package/dist/esm/tools/search/content.mjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs +139 -169
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/format.mjs +128 -194
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/highlights.mjs +165 -230
- package/dist/esm/tools/search/highlights.mjs.map +1 -1
- package/dist/esm/tools/search/index.mjs +3 -0
- package/dist/esm/tools/search/rerankers.mjs +149 -168
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/schema.mjs +39 -37
- package/dist/esm/tools/search/schema.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +426 -528
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/serper-scraper.mjs +104 -124
- package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
- package/dist/esm/tools/search/tavily-scraper.mjs +127 -178
- package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
- package/dist/esm/tools/search/tavily-search.mjs +293 -357
- package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +259 -297
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +74 -115
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/tools/skillCatalog.mjs +54 -70
- package/dist/esm/tools/skillCatalog.mjs.map +1 -1
- package/dist/esm/tools/streamedToolCallSeals.mjs +19 -31
- package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +612 -768
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/tools/subagent/index.mjs +2 -0
- package/dist/esm/tools/toolOutputReferences.mjs +523 -624
- package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
- package/dist/esm/utils/callbacks.mjs +11 -19
- package/dist/esm/utils/callbacks.mjs.map +1 -1
- package/dist/esm/utils/errors.mjs +70 -93
- package/dist/esm/utils/errors.mjs.map +1 -1
- package/dist/esm/utils/events.mjs +32 -40
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/esm/utils/graph.mjs +8 -10
- package/dist/esm/utils/graph.mjs.map +1 -1
- package/dist/esm/utils/handlers.mjs +60 -80
- package/dist/esm/utils/handlers.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +10 -0
- package/dist/esm/utils/llm.mjs +19 -25
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/misc.mjs +30 -44
- package/dist/esm/utils/misc.mjs.map +1 -1
- package/dist/esm/utils/run.mjs +50 -64
- package/dist/esm/utils/run.mjs.map +1 -1
- package/dist/esm/utils/schema.mjs +11 -17
- package/dist/esm/utils/schema.mjs.map +1 -1
- package/dist/esm/utils/title.mjs +71 -104
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +186 -281
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/esm/utils/truncation.mjs +95 -112
- package/dist/esm/utils/truncation.mjs.map +1 -1
- package/dist/types/tools/search/tool.d.ts +17 -0
- package/dist/types/tools/search/types.d.ts +4 -0
- package/package.json +4 -10
- package/src/tools/search/highlights.ts +9 -1
- package/src/tools/search/search.ts +41 -3
- package/src/tools/search/source-processing.test.ts +373 -0
- package/src/tools/search/tool.ts +22 -2
- package/src/tools/search/types.ts +4 -0
- package/dist/cjs/langchain/google-common.cjs.map +0 -1
- package/dist/cjs/langchain/index.cjs.map +0 -1
- package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
- package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
- package/dist/cjs/langchain/messages.cjs.map +0 -1
- package/dist/cjs/langchain/openai.cjs.map +0 -1
- package/dist/cjs/langchain/prompts.cjs.map +0 -1
- package/dist/cjs/langchain/runnables.cjs.map +0 -1
- package/dist/cjs/langchain/tools.cjs.map +0 -1
- package/dist/cjs/langchain/utils/env.cjs.map +0 -1
- package/dist/cjs/main.cjs.map +0 -1
- package/dist/esm/langchain/google-common.mjs.map +0 -1
- package/dist/esm/langchain/index.mjs.map +0 -1
- package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
- package/dist/esm/langchain/messages/tool.mjs.map +0 -1
- package/dist/esm/langchain/messages.mjs.map +0 -1
- package/dist/esm/langchain/openai.mjs.map +0 -1
- package/dist/esm/langchain/prompts.mjs.map +0 -1
- package/dist/esm/langchain/runnables.mjs.map +0 -1
- package/dist/esm/langchain/tools.mjs.map +0 -1
- package/dist/esm/langchain/utils/env.mjs.map +0 -1
- package/dist/esm/main.mjs.map +0 -1
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { emitAgentLog, safeDispatchCustomEvent } from
|
|
4
|
-
import {
|
|
5
|
-
import { createRemoveAllMessage } from
|
|
6
|
-
import { splitAtRecencyBoundary } from
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import "../common/enum.mjs";
|
|
2
|
+
import "../common/index.mjs";
|
|
3
|
+
import { emitAgentLog, safeDispatchCustomEvent } from "../utils/events.mjs";
|
|
4
|
+
import { addCacheControl } from "../messages/cache.mjs";
|
|
5
|
+
import { createRemoveAllMessage } from "../messages/reducer.mjs";
|
|
6
|
+
import { splitAtRecencyBoundary } from "../messages/recency.mjs";
|
|
7
|
+
import { getChunkContent } from "../stream.mjs";
|
|
8
|
+
import { executeHooks } from "../hooks/executeHooks.mjs";
|
|
9
|
+
import "../hooks/index.mjs";
|
|
10
|
+
import { initializeModel } from "../llm/init.mjs";
|
|
11
|
+
import { attemptInvoke, tryFallbackProviders } from "../llm/invoke.mjs";
|
|
12
|
+
import { getMaxOutputTokensKey } from "../llm/request.mjs";
|
|
13
|
+
import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
|
|
14
|
+
//#region src/summarization/node.ts
|
|
15
|
+
const SUMMARIZATION_PARAM_KEYS = new Set(["maxSummaryTokens"]);
|
|
15
16
|
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
* Default number of recent user-led turns preserved verbatim during
|
|
18
|
+
* compaction. A turn begins at a HumanMessage and includes every
|
|
19
|
+
* following AIMessage and ToolMessage up to the next HumanMessage.
|
|
20
|
+
* The most recent turn is always retained regardless of this value;
|
|
21
|
+
* the default of `2` additionally keeps the prior exchange so the
|
|
22
|
+
* model has fresh context on what just happened. Setting
|
|
23
|
+
* `retainRecent.turns` to `0` reverts to the legacy "summarize every
|
|
24
|
+
* message" behavior.
|
|
25
|
+
*/
|
|
25
26
|
const DEFAULT_RETAIN_RECENT_TURNS = 2;
|
|
26
27
|
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
* Token overhead of the XML wrapper + instruction text added around the
|
|
29
|
+
* summary at injection time in AgentContext.buildSystemRunnable:
|
|
30
|
+
* `<summary>\n${text}\n</summary>\n\nYour context window was compacted...`
|
|
31
|
+
* ~33 tokens on Anthropic, ~24-27 on OpenAI. Using 33 as a safe ceiling.
|
|
32
|
+
*/
|
|
32
33
|
const SUMMARY_WRAPPER_OVERHEAD_TOKENS = 33;
|
|
33
34
|
/** Structured checkpoint prompt for fresh summarization (no prior summary). */
|
|
34
35
|
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.
|
|
@@ -81,819 +82,668 @@ Rules:
|
|
|
81
82
|
- Preserve exact identifiers, names, errors, and references verbatim
|
|
82
83
|
- Skip empty sections`;
|
|
83
84
|
function separateParameters(parameters) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
llmParams[key] = value;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return { llmParams, maxSummaryTokens };
|
|
85
|
+
const llmParams = {};
|
|
86
|
+
let maxSummaryTokens;
|
|
87
|
+
for (const [key, value] of Object.entries(parameters)) if (SUMMARIZATION_PARAM_KEYS.has(key)) {
|
|
88
|
+
if (key === "maxSummaryTokens" && typeof value === "number" && value > 0) maxSummaryTokens = value;
|
|
89
|
+
} else llmParams[key] = value;
|
|
90
|
+
return {
|
|
91
|
+
llmParams,
|
|
92
|
+
maxSummaryTokens
|
|
93
|
+
};
|
|
99
94
|
}
|
|
100
95
|
/**
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
96
|
+
* Generates a structural metadata summary without making an LLM call.
|
|
97
|
+
* Used as a last-resort fallback when all summarization attempts fail.
|
|
98
|
+
* Preserves tool names and message counts so the agent retains basic context.
|
|
99
|
+
*/
|
|
105
100
|
function generateMetadataStub(messages) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
for (const tc of msg.tool_calls) {
|
|
119
|
-
toolNames.add(tc.name);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const countParts = Object.entries(counts)
|
|
124
|
-
.map(([role, count]) => `${count} ${role}`)
|
|
125
|
-
.join(', ');
|
|
126
|
-
const lines = [
|
|
127
|
-
`[Metadata summary: ${messages.length} messages (${countParts})]`,
|
|
128
|
-
];
|
|
129
|
-
if (toolNames.size > 0) {
|
|
130
|
-
lines.push(`[Tools used: ${Array.from(toolNames).join(', ')}]`);
|
|
131
|
-
}
|
|
132
|
-
return lines.join('\n');
|
|
101
|
+
const counts = {};
|
|
102
|
+
const toolNames = /* @__PURE__ */ new Set();
|
|
103
|
+
for (const msg of messages) {
|
|
104
|
+
const role = msg.getType();
|
|
105
|
+
counts[role] = (counts[role] ?? 0) + 1;
|
|
106
|
+
if (role === "tool" && msg.name != null && msg.name !== "") toolNames.add(msg.name);
|
|
107
|
+
if (role === "ai" && msg instanceof AIMessage && msg.tool_calls && msg.tool_calls.length > 0) for (const tc of msg.tool_calls) toolNames.add(tc.name);
|
|
108
|
+
}
|
|
109
|
+
const countParts = Object.entries(counts).map(([role, count]) => `${count} ${role}`).join(", ");
|
|
110
|
+
const lines = [`[Metadata summary: ${messages.length} messages (${countParts})]`];
|
|
111
|
+
if (toolNames.size > 0) lines.push(`[Tools used: ${Array.from(toolNames).join(", ")}]`);
|
|
112
|
+
return lines.join("\n");
|
|
133
113
|
}
|
|
134
114
|
/** Maximum number of tool failures to include in the enrichment section. */
|
|
135
115
|
const MAX_TOOL_FAILURES = 8;
|
|
136
116
|
/** Maximum chars per failure summary line. */
|
|
137
117
|
const MAX_TOOL_FAILURE_CHARS = 240;
|
|
138
118
|
/**
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
119
|
+
* Extracts failed tool results from messages and formats them as a structured
|
|
120
|
+
* section. LLMs often omit specific failure details (exit codes, error messages)
|
|
121
|
+
* from their summaries, this mechanical enrichment guarantees they survive.
|
|
122
|
+
*/
|
|
143
123
|
function extractToolFailuresSection(messages) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
: JSON.stringify(toolMsg.content);
|
|
166
|
-
const normalized = content.replace(/\s+/g, ' ').trim();
|
|
167
|
-
const summary = normalized.length > MAX_TOOL_FAILURE_CHARS
|
|
168
|
-
? `${normalized.slice(0, MAX_TOOL_FAILURE_CHARS - 3)}...`
|
|
169
|
-
: normalized;
|
|
170
|
-
failures.push({ toolName, summary });
|
|
171
|
-
}
|
|
172
|
-
if (failures.length === 0) {
|
|
173
|
-
return '';
|
|
174
|
-
}
|
|
175
|
-
const lines = failures
|
|
176
|
-
.slice(0, MAX_TOOL_FAILURES)
|
|
177
|
-
.map((f) => `- ${f.toolName}: ${f.summary}`);
|
|
178
|
-
if (failures.length > MAX_TOOL_FAILURES) {
|
|
179
|
-
lines.push(`- ...and ${failures.length - MAX_TOOL_FAILURES} more`);
|
|
180
|
-
}
|
|
181
|
-
return `\n\n## Tool Failures\n${lines.join('\n')}`;
|
|
124
|
+
const failures = [];
|
|
125
|
+
const seen = /* @__PURE__ */ new Set();
|
|
126
|
+
for (const msg of messages) {
|
|
127
|
+
if (msg.getType() !== "tool") continue;
|
|
128
|
+
const toolMsg = msg;
|
|
129
|
+
if (toolMsg.status !== "error") continue;
|
|
130
|
+
const callId = toolMsg.tool_call_id;
|
|
131
|
+
if (callId && seen.has(callId)) continue;
|
|
132
|
+
if (callId) seen.add(callId);
|
|
133
|
+
const toolName = toolMsg.name ?? "tool";
|
|
134
|
+
const normalized = (typeof toolMsg.content === "string" ? toolMsg.content : JSON.stringify(toolMsg.content)).replace(/\s+/g, " ").trim();
|
|
135
|
+
const summary = normalized.length > MAX_TOOL_FAILURE_CHARS ? `${normalized.slice(0, MAX_TOOL_FAILURE_CHARS - 3)}...` : normalized;
|
|
136
|
+
failures.push({
|
|
137
|
+
toolName,
|
|
138
|
+
summary
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (failures.length === 0) return "";
|
|
142
|
+
const lines = failures.slice(0, MAX_TOOL_FAILURES).map((f) => `- ${f.toolName}: ${f.summary}`);
|
|
143
|
+
if (failures.length > MAX_TOOL_FAILURES) lines.push(`- ...and ${failures.length - MAX_TOOL_FAILURES} more`);
|
|
144
|
+
return `\n\n## Tool Failures\n${lines.join("\n")}`;
|
|
182
145
|
}
|
|
183
146
|
/**
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
147
|
+
* Appends mechanical enrichment sections to an LLM-generated summary.
|
|
148
|
+
* Tool failures are appended verbatim because LLMs often omit specific
|
|
149
|
+
* error details from their summaries.
|
|
150
|
+
*/
|
|
188
151
|
function enrichSummary(summaryText, messages) {
|
|
189
|
-
|
|
152
|
+
return summaryText + extractToolFailuresSection(messages);
|
|
190
153
|
}
|
|
191
154
|
/**
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
155
|
+
* Restores pre-masking tool content onto the messages array using
|
|
156
|
+
* `pendingOriginalToolContent` stored on AgentContext. Only allocates
|
|
157
|
+
* a new array when there are entries to restore; otherwise returns the
|
|
158
|
+
* input reference unchanged.
|
|
159
|
+
*/
|
|
197
160
|
function restoreOriginalToolContent(messages, originalToolContent) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return restored;
|
|
161
|
+
if (originalToolContent == null || originalToolContent.size === 0) return messages;
|
|
162
|
+
const restored = [...messages];
|
|
163
|
+
for (const [idx, content] of originalToolContent) {
|
|
164
|
+
const msg = restored[idx];
|
|
165
|
+
if (msg instanceof ToolMessage) restored[idx] = new ToolMessage({
|
|
166
|
+
content,
|
|
167
|
+
tool_call_id: msg.tool_call_id,
|
|
168
|
+
name: msg.name,
|
|
169
|
+
id: msg.id,
|
|
170
|
+
additional_kwargs: msg.additional_kwargs,
|
|
171
|
+
response_metadata: msg.response_metadata
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return restored;
|
|
216
175
|
}
|
|
217
176
|
/** Assembles the summarization model's client options from agent and config. */
|
|
218
177
|
function buildSummarizationClientConfig(agentContext, summarizationConfig) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
provider,
|
|
244
|
-
modelName,
|
|
245
|
-
clientOptions,
|
|
246
|
-
effectiveMaxSummaryTokens,
|
|
247
|
-
promptText,
|
|
248
|
-
updatePromptText,
|
|
249
|
-
};
|
|
178
|
+
const provider = summarizationConfig?.provider ?? agentContext.provider;
|
|
179
|
+
const modelName = summarizationConfig?.model;
|
|
180
|
+
const parameters = summarizationConfig?.parameters ?? {};
|
|
181
|
+
const promptText = summarizationConfig?.prompt ?? DEFAULT_SUMMARIZATION_PROMPT;
|
|
182
|
+
const updatePromptText = summarizationConfig?.updatePrompt ?? DEFAULT_UPDATE_SUMMARIZATION_PROMPT;
|
|
183
|
+
const { llmParams, maxSummaryTokens: paramMaxSummaryTokens } = separateParameters(parameters);
|
|
184
|
+
const clientOptions = {
|
|
185
|
+
...provider === agentContext.provider && agentContext.clientOptions ? { ...agentContext.clientOptions } : {},
|
|
186
|
+
...llmParams
|
|
187
|
+
};
|
|
188
|
+
if (modelName != null && modelName !== "") {
|
|
189
|
+
clientOptions.model = modelName;
|
|
190
|
+
clientOptions.modelName = modelName;
|
|
191
|
+
}
|
|
192
|
+
const effectiveMaxSummaryTokens = paramMaxSummaryTokens ?? summarizationConfig?.maxSummaryTokens;
|
|
193
|
+
if (effectiveMaxSummaryTokens != null) clientOptions[getMaxOutputTokensKey(provider)] = effectiveMaxSummaryTokens;
|
|
194
|
+
return {
|
|
195
|
+
provider,
|
|
196
|
+
modelName,
|
|
197
|
+
clientOptions,
|
|
198
|
+
effectiveMaxSummaryTokens,
|
|
199
|
+
promptText,
|
|
200
|
+
updatePromptText
|
|
201
|
+
};
|
|
250
202
|
}
|
|
251
203
|
/** Computes the token count for a summary, preferring provider output tokens when available. */
|
|
252
204
|
function computeSummaryTokenCount(summaryText, summaryUsage, tokenCounter) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (tokenCounter) {
|
|
258
|
-
return (tokenCounter(new SystemMessage(summaryText)) +
|
|
259
|
-
SUMMARY_WRAPPER_OVERHEAD_TOKENS);
|
|
260
|
-
}
|
|
261
|
-
return 0;
|
|
205
|
+
const providerOutputTokens = Number(summaryUsage?.output_tokens) || 0;
|
|
206
|
+
if (providerOutputTokens > 0) return providerOutputTokens + SUMMARY_WRAPPER_OVERHEAD_TOKENS;
|
|
207
|
+
if (tokenCounter) return tokenCounter(new SystemMessage(summaryText)) + SUMMARY_WRAPPER_OVERHEAD_TOKENS;
|
|
208
|
+
return 0;
|
|
262
209
|
}
|
|
263
210
|
/** Constructs the SummaryContentBlock persisted in the run step and dispatched to events. */
|
|
264
211
|
function buildSummaryBlock(params) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
createdAt: new Date().toISOString(),
|
|
282
|
-
};
|
|
212
|
+
return {
|
|
213
|
+
type: "summary",
|
|
214
|
+
content: [{
|
|
215
|
+
type: "text",
|
|
216
|
+
text: params.summaryText
|
|
217
|
+
}],
|
|
218
|
+
tokenCount: params.tokenCount,
|
|
219
|
+
summaryVersion: params.summaryVersion,
|
|
220
|
+
boundary: {
|
|
221
|
+
messageId: params.stepId,
|
|
222
|
+
contentIndex: params.stepIndex
|
|
223
|
+
},
|
|
224
|
+
model: params.modelName,
|
|
225
|
+
provider: params.provider,
|
|
226
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
227
|
+
};
|
|
283
228
|
}
|
|
284
229
|
/**
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
230
|
+
* Extracts an HTTP status code from a thrown LLM-provider error. Returns
|
|
231
|
+
* `undefined` for non-object values (including `null` or `undefined`, both
|
|
232
|
+
* valid `throw` targets in JS) so callers never dereference a nullish
|
|
233
|
+
* value.
|
|
234
|
+
*/
|
|
290
235
|
function extractHttpStatus(err) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
const response = errRecord.response;
|
|
304
|
-
if (response != null && typeof response === 'object') {
|
|
305
|
-
const nested = response.status;
|
|
306
|
-
if (typeof nested === 'number') {
|
|
307
|
-
return nested;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
return undefined;
|
|
236
|
+
if (err == null || typeof err !== "object") return;
|
|
237
|
+
const errRecord = err;
|
|
238
|
+
const direct = errRecord.status;
|
|
239
|
+
if (typeof direct === "number") return direct;
|
|
240
|
+
const statusCode = errRecord.statusCode;
|
|
241
|
+
if (typeof statusCode === "number") return statusCode;
|
|
242
|
+
const response = errRecord.response;
|
|
243
|
+
if (response != null && typeof response === "object") {
|
|
244
|
+
const nested = response.status;
|
|
245
|
+
if (typeof nested === "number") return nested;
|
|
246
|
+
}
|
|
311
247
|
}
|
|
312
248
|
/**
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
249
|
+
* Formats a provider-level error for logging. Returns both a human-readable
|
|
250
|
+
* suffix (safe to include in the message string so it survives any host-side
|
|
251
|
+
* formatter) and a structured metadata bag for rich log backends.
|
|
252
|
+
*/
|
|
317
253
|
function describeProviderError(err, provider, modelName) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
data,
|
|
336
|
-
};
|
|
254
|
+
const providerLabel = `${provider}/${modelName ?? "(no-model)"}`;
|
|
255
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
256
|
+
const data = {
|
|
257
|
+
provider,
|
|
258
|
+
model: modelName
|
|
259
|
+
};
|
|
260
|
+
if (err instanceof Error) {
|
|
261
|
+
data.errorName = err.name;
|
|
262
|
+
data.errorStack = err.stack;
|
|
263
|
+
}
|
|
264
|
+
const status = extractHttpStatus(err);
|
|
265
|
+
const statusSuffix = status != null ? ` (HTTP ${status})` : "";
|
|
266
|
+
if (status != null) data.status = status;
|
|
267
|
+
return {
|
|
268
|
+
suffix: `[${providerLabel}]${statusSuffix}: ${errMsg}`,
|
|
269
|
+
data
|
|
270
|
+
};
|
|
337
271
|
}
|
|
338
272
|
/**
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
273
|
+
* Formats an exhausted-fallback error. `tryFallbackProviders` throws the
|
|
274
|
+
* last fallback provider's error, which may be from any of the configured
|
|
275
|
+
* fallbacks — not the primary — so we label the log with the list of
|
|
276
|
+
* fallback providers attempted rather than mis-attributing to the primary.
|
|
277
|
+
*
|
|
278
|
+
* Entries in `fallbacks` are normally strongly typed, but we defend against
|
|
279
|
+
* malformed runtime config (null/undefined entries, missing `provider`
|
|
280
|
+
* field) so a recoverable summarization failure is never promoted to an
|
|
281
|
+
* uncaught exception from inside the logging path.
|
|
282
|
+
*/
|
|
349
283
|
function describeFallbackError(err, fallbacks) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
const status = extractHttpStatus(err);
|
|
375
|
-
const statusSuffix = status != null ? ` (HTTP ${status})` : '';
|
|
376
|
-
if (status != null) {
|
|
377
|
-
data.status = status;
|
|
378
|
-
}
|
|
379
|
-
return {
|
|
380
|
-
suffix: `[${label}]${statusSuffix}: ${errMsg}`,
|
|
381
|
-
data,
|
|
382
|
-
};
|
|
284
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
285
|
+
const list = Array.isArray(fallbacks) ? fallbacks : [];
|
|
286
|
+
const providerNames = list.map((f) => {
|
|
287
|
+
if (f == null || typeof f !== "object") return;
|
|
288
|
+
const raw = f.provider;
|
|
289
|
+
return raw != null ? String(raw) : void 0;
|
|
290
|
+
}).filter((p) => typeof p === "string");
|
|
291
|
+
const label = providerNames.length > 0 ? `fallbacks=[${providerNames.join(",")}]` : "no-fallbacks";
|
|
292
|
+
const data = {
|
|
293
|
+
fallbackProviders: providerNames,
|
|
294
|
+
fallbackCount: list.length
|
|
295
|
+
};
|
|
296
|
+
if (err instanceof Error) {
|
|
297
|
+
data.errorName = err.name;
|
|
298
|
+
data.errorStack = err.stack;
|
|
299
|
+
}
|
|
300
|
+
const status = extractHttpStatus(err);
|
|
301
|
+
const statusSuffix = status != null ? ` (HTTP ${status})` : "";
|
|
302
|
+
if (status != null) data.status = status;
|
|
303
|
+
return {
|
|
304
|
+
suffix: `[${label}]${statusSuffix}: ${errMsg}`,
|
|
305
|
+
data
|
|
306
|
+
};
|
|
383
307
|
}
|
|
384
308
|
/**
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
309
|
+
* Runs the summarization LLM call with primary + fallback providers,
|
|
310
|
+
* falling back to a metadata stub when all calls fail.
|
|
311
|
+
*/
|
|
388
312
|
async function executeSummarizationWithFallback(params) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const fbDescribed = describeFallbackError(fbErr, fallbacks);
|
|
454
|
-
log('warn', `Fallback providers also failed ${fbDescribed.suffix}`, {
|
|
455
|
-
...fbDescribed.data,
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
if (!summaryText) {
|
|
460
|
-
log('warn', `Summarization failed, falling back to metadata stub ${primaryDescribed.suffix}`, {
|
|
461
|
-
...primaryDescribed.data,
|
|
462
|
-
messagesToRefineCount: messages.length,
|
|
463
|
-
});
|
|
464
|
-
summaryText = generateMetadataStub(messages);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
return { text: summaryText, usage: summaryUsage };
|
|
313
|
+
const { agentContext, messages, clientConfig, summarizeConfig, stepId, usePromptCache, log } = params;
|
|
314
|
+
const priorSummaryText = agentContext.getSummaryText()?.trim() ?? "";
|
|
315
|
+
let summaryText = "";
|
|
316
|
+
let summaryUsage;
|
|
317
|
+
try {
|
|
318
|
+
const result = await summarizeWithCacheHit({
|
|
319
|
+
model: initializeModel({
|
|
320
|
+
provider: clientConfig.provider,
|
|
321
|
+
clientOptions: clientConfig.clientOptions,
|
|
322
|
+
tools: agentContext.getToolsForBinding()
|
|
323
|
+
}),
|
|
324
|
+
messages,
|
|
325
|
+
promptText: clientConfig.promptText,
|
|
326
|
+
updatePromptText: clientConfig.updatePromptText,
|
|
327
|
+
priorSummaryText,
|
|
328
|
+
config: summarizeConfig,
|
|
329
|
+
stepId,
|
|
330
|
+
provider: clientConfig.provider,
|
|
331
|
+
reasoningKey: agentContext.reasoningKey,
|
|
332
|
+
usePromptCache,
|
|
333
|
+
log
|
|
334
|
+
});
|
|
335
|
+
summaryText = result.text;
|
|
336
|
+
summaryUsage = result.usage;
|
|
337
|
+
} catch (primaryError) {
|
|
338
|
+
const primaryDescribed = describeProviderError(primaryError, clientConfig.provider, clientConfig.modelName);
|
|
339
|
+
log("error", `Summarization LLM call failed ${primaryDescribed.suffix}`, {
|
|
340
|
+
...primaryDescribed.data,
|
|
341
|
+
messagesToRefineCount: messages.length
|
|
342
|
+
});
|
|
343
|
+
const rawFallbacks = clientConfig.clientOptions?.fallbacks;
|
|
344
|
+
const fallbacks = Array.isArray(rawFallbacks) ? rawFallbacks : [];
|
|
345
|
+
if (fallbacks.length > 0) try {
|
|
346
|
+
const onChunk = createSummarizationChunkHandler({
|
|
347
|
+
stepId,
|
|
348
|
+
config: traceConfig(summarizeConfig, "cache_hit_compaction"),
|
|
349
|
+
provider: clientConfig.provider,
|
|
350
|
+
reasoningKey: agentContext.reasoningKey
|
|
351
|
+
});
|
|
352
|
+
const fbMsg = (await tryFallbackProviders({
|
|
353
|
+
fallbacks,
|
|
354
|
+
tools: agentContext.getToolsForBinding(),
|
|
355
|
+
messages: [...messages, new HumanMessage(buildSummarizationInstruction(clientConfig.promptText, clientConfig.updatePromptText, priorSummaryText))],
|
|
356
|
+
config: traceConfig(summarizeConfig, "cache_hit_compaction"),
|
|
357
|
+
primaryError,
|
|
358
|
+
onChunk
|
|
359
|
+
}))?.messages?.[0];
|
|
360
|
+
if (fbMsg) summaryText = extractResponseText(fbMsg);
|
|
361
|
+
} catch (fbErr) {
|
|
362
|
+
const fbDescribed = describeFallbackError(fbErr, fallbacks);
|
|
363
|
+
log("warn", `Fallback providers also failed ${fbDescribed.suffix}`, { ...fbDescribed.data });
|
|
364
|
+
}
|
|
365
|
+
if (!summaryText) {
|
|
366
|
+
log("warn", `Summarization failed, falling back to metadata stub ${primaryDescribed.suffix}`, {
|
|
367
|
+
...primaryDescribed.data,
|
|
368
|
+
messagesToRefineCount: messages.length
|
|
369
|
+
});
|
|
370
|
+
summaryText = generateMetadataStub(messages);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
text: summaryText,
|
|
375
|
+
usage: summaryUsage
|
|
376
|
+
};
|
|
468
377
|
}
|
|
469
378
|
/** Dispatches run step completion, ON_SUMMARIZE_COMPLETE, and rebuilds token map. */
|
|
470
379
|
async function dispatchCompletionEvents(params) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
summary: summaryText,
|
|
507
|
-
messagesAfterCount,
|
|
508
|
-
},
|
|
509
|
-
sessionId,
|
|
510
|
-
}).catch(() => {
|
|
511
|
-
/* PostCompact is observational — swallow errors */
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
agentContext.rebuildTokenMapAfterSummarization({});
|
|
380
|
+
const { graph, runnableConfig, stepId, summaryBlock, agentContext, runStep, summaryUsage, agentId, messagesAfterCount } = params;
|
|
381
|
+
runStep.summary = summaryBlock;
|
|
382
|
+
if (summaryUsage) runStep.usage = {
|
|
383
|
+
prompt_tokens: Number(summaryUsage.input_tokens) || 0,
|
|
384
|
+
completion_tokens: Number(summaryUsage.output_tokens) || 0,
|
|
385
|
+
total_tokens: (Number(summaryUsage.input_tokens) || 0) + (Number(summaryUsage.output_tokens) || 0)
|
|
386
|
+
};
|
|
387
|
+
await graph.dispatchRunStepCompleted(stepId, {
|
|
388
|
+
type: "summary",
|
|
389
|
+
summary: summaryBlock
|
|
390
|
+
}, runnableConfig);
|
|
391
|
+
if (runnableConfig) await safeDispatchCustomEvent("on_summarize_complete", {
|
|
392
|
+
id: stepId,
|
|
393
|
+
agentId,
|
|
394
|
+
summary: summaryBlock
|
|
395
|
+
}, runnableConfig);
|
|
396
|
+
const sessionId = graph.runId ?? "";
|
|
397
|
+
if (graph.hookRegistry?.hasHookFor("PostCompact", sessionId) === true) {
|
|
398
|
+
const threadId = (runnableConfig?.configurable)?.thread_id;
|
|
399
|
+
const firstBlock = summaryBlock.content?.[0];
|
|
400
|
+
const summaryText = firstBlock != null && typeof firstBlock === "object" && "text" in firstBlock && typeof firstBlock.text === "string" ? firstBlock.text : "";
|
|
401
|
+
await executeHooks({
|
|
402
|
+
registry: graph.hookRegistry,
|
|
403
|
+
input: {
|
|
404
|
+
hook_event_name: "PostCompact",
|
|
405
|
+
runId: sessionId,
|
|
406
|
+
threadId,
|
|
407
|
+
agentId,
|
|
408
|
+
summary: summaryText,
|
|
409
|
+
messagesAfterCount
|
|
410
|
+
},
|
|
411
|
+
sessionId
|
|
412
|
+
}).catch(() => {});
|
|
413
|
+
}
|
|
414
|
+
agentContext.rebuildTokenMapAfterSummarization({});
|
|
515
415
|
}
|
|
516
|
-
function createSummarizeNode({ agentContext, graph, generateStepId
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
* masked stubs (since `setSummary` clears `pruneMessages`, and the
|
|
736
|
-
* fresh pruner at the next turn has no record of prior masks).
|
|
737
|
-
* Entries for indices < `tailStartIndex` belong to messages we just
|
|
738
|
-
* summarized — they are no longer reachable so they are dropped.
|
|
739
|
-
*/
|
|
740
|
-
if (originalPending != null && originalPending.size > 0) {
|
|
741
|
-
const tailPending = new Map();
|
|
742
|
-
for (const [idx, content] of originalPending) {
|
|
743
|
-
if (idx >= tailStartIndex) {
|
|
744
|
-
tailPending.set(idx - tailStartIndex, content);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
agentContext.pendingOriginalToolContent =
|
|
748
|
-
tailPending.size > 0 ? tailPending : undefined;
|
|
749
|
-
}
|
|
750
|
-
else {
|
|
751
|
-
agentContext.pendingOriginalToolContent = undefined;
|
|
752
|
-
}
|
|
753
|
-
return {
|
|
754
|
-
summarizationRequest: undefined,
|
|
755
|
-
messages: messagesToRetain.length > 0
|
|
756
|
-
? [createRemoveAllMessage(), ...messagesToRetain]
|
|
757
|
-
: [createRemoveAllMessage()],
|
|
758
|
-
};
|
|
759
|
-
};
|
|
416
|
+
function createSummarizeNode({ agentContext, graph, generateStepId }) {
|
|
417
|
+
return async (state, config) => {
|
|
418
|
+
const request = state.summarizationRequest;
|
|
419
|
+
if (request == null) return { summarizationRequest: void 0 };
|
|
420
|
+
const maxCtx = agentContext.maxContextTokens ?? 0;
|
|
421
|
+
if (maxCtx > 0 && agentContext.instructionTokens >= maxCtx) {
|
|
422
|
+
emitAgentLog(config, "warn", "summarize", "Summarization skipped, instructions exceed context budget. Reduce the number of tools or increase maxContextTokens.", {
|
|
423
|
+
instructionTokens: agentContext.instructionTokens,
|
|
424
|
+
maxContextTokens: maxCtx,
|
|
425
|
+
breakdown: agentContext.formatTokenBudgetBreakdown()
|
|
426
|
+
}, {
|
|
427
|
+
runId: graph.runId,
|
|
428
|
+
agentId: request.agentId
|
|
429
|
+
});
|
|
430
|
+
return { summarizationRequest: void 0 };
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Capture the original-tool-content map locally before doing the
|
|
434
|
+
* split. We need it in three places: to restore the head for
|
|
435
|
+
* summarizer quality, to leave intact on the skip path (state is
|
|
436
|
+
* unchanged), and — critically — to carry forward the tail-relevant
|
|
437
|
+
* entries on the summarize-fired path. Clearing it eagerly here
|
|
438
|
+
* would lose the originals for masked tool messages that the
|
|
439
|
+
* recency window keeps in the tail; a future summarization could
|
|
440
|
+
* then only summarize the masked stub instead of the full payload.
|
|
441
|
+
*/
|
|
442
|
+
const originalPending = agentContext.pendingOriginalToolContent;
|
|
443
|
+
const restoredMessages = restoreOriginalToolContent(state.messages, originalPending);
|
|
444
|
+
const runnableConfig = config ?? graph.config;
|
|
445
|
+
const retainRecent = agentContext.summarizationConfig?.retainRecent;
|
|
446
|
+
const { head: messagesToRefine, tailStartIndex } = splitAtRecencyBoundary(restoredMessages, {
|
|
447
|
+
turns: retainRecent?.turns ?? DEFAULT_RETAIN_RECENT_TURNS,
|
|
448
|
+
tokens: retainRecent?.tokens,
|
|
449
|
+
tokenCounter: agentContext.tokenCounter
|
|
450
|
+
});
|
|
451
|
+
/**
|
|
452
|
+
* Use the *masked* messages for the retained tail so that any
|
|
453
|
+
* truncation prune applied to oversized ToolMessage content stays
|
|
454
|
+
* truncated in live state. The summarizer above reads the restored
|
|
455
|
+
* (full-content) head for summary quality, but reinjecting restored
|
|
456
|
+
* tool payloads into state would defeat masking and bloat the
|
|
457
|
+
* checkpoint, forcing more expensive re-pruning on later turns.
|
|
458
|
+
* `restoreOriginalToolContent` returns an array with identical
|
|
459
|
+
* length and structure to `state.messages` (replacements only at
|
|
460
|
+
* specific indices), so the same tailStartIndex slices both arrays
|
|
461
|
+
* at the same turn boundary.
|
|
462
|
+
*/
|
|
463
|
+
const messagesToRetain = state.messages.slice(tailStartIndex);
|
|
464
|
+
if (messagesToRefine.length === 0) {
|
|
465
|
+
/**
|
|
466
|
+
* Recency window covers the entire conversation — there is no
|
|
467
|
+
* older content to summarize. Skipping prevents the model from
|
|
468
|
+
* destroying the user's most recent message (e.g. a large pasted
|
|
469
|
+
* payload on the first turn) by replacing it with a generic
|
|
470
|
+
* checkpoint summary. Mark the trigger so the same unchanged
|
|
471
|
+
* state is not re-evaluated on the next prune cycle.
|
|
472
|
+
*/
|
|
473
|
+
emitAgentLog(config, "debug", "summarize", "Summarization skipped — recency window retains all messages", {
|
|
474
|
+
messagesRetained: messagesToRetain.length,
|
|
475
|
+
retainTurns: retainRecent?.turns ?? DEFAULT_RETAIN_RECENT_TURNS
|
|
476
|
+
}, {
|
|
477
|
+
runId: graph.runId,
|
|
478
|
+
agentId: request.agentId
|
|
479
|
+
});
|
|
480
|
+
agentContext.markSummarizationTriggered(state.messages.length);
|
|
481
|
+
return { summarizationRequest: void 0 };
|
|
482
|
+
}
|
|
483
|
+
const clientConfig = buildSummarizationClientConfig(agentContext, agentContext.summarizationConfig);
|
|
484
|
+
const [stepId, stepIndex] = generateStepId(`summarize-${request.agentId}`);
|
|
485
|
+
const placeholderSummary = {
|
|
486
|
+
type: "summary",
|
|
487
|
+
model: clientConfig.modelName,
|
|
488
|
+
provider: clientConfig.provider
|
|
489
|
+
};
|
|
490
|
+
const runStep = {
|
|
491
|
+
stepIndex,
|
|
492
|
+
id: stepId,
|
|
493
|
+
type: "message_creation",
|
|
494
|
+
index: graph.contentData.length,
|
|
495
|
+
stepDetails: {
|
|
496
|
+
type: "message_creation",
|
|
497
|
+
message_creation: { message_id: stepId }
|
|
498
|
+
},
|
|
499
|
+
summary: placeholderSummary,
|
|
500
|
+
usage: null
|
|
501
|
+
};
|
|
502
|
+
if (graph.runId != null && graph.runId !== "") runStep.runId = graph.runId;
|
|
503
|
+
if (graph.isMultiAgent && agentContext.agentId) runStep.agentId = agentContext.agentId;
|
|
504
|
+
await graph.dispatchRunStep(runStep, runnableConfig);
|
|
505
|
+
if (runnableConfig) await safeDispatchCustomEvent("on_summarize_start", {
|
|
506
|
+
agentId: request.agentId,
|
|
507
|
+
provider: clientConfig.provider,
|
|
508
|
+
model: clientConfig.modelName,
|
|
509
|
+
messagesToRefineCount: messagesToRefine.length,
|
|
510
|
+
summaryVersion: agentContext.summaryVersion + 1
|
|
511
|
+
}, runnableConfig);
|
|
512
|
+
const sessionId = graph.runId ?? "";
|
|
513
|
+
if (graph.hookRegistry?.hasHookFor("PreCompact", sessionId) === true) {
|
|
514
|
+
const threadId = (runnableConfig?.configurable)?.thread_id;
|
|
515
|
+
await executeHooks({
|
|
516
|
+
registry: graph.hookRegistry,
|
|
517
|
+
input: {
|
|
518
|
+
hook_event_name: "PreCompact",
|
|
519
|
+
runId: sessionId,
|
|
520
|
+
threadId,
|
|
521
|
+
agentId: request.agentId,
|
|
522
|
+
messagesBeforeCount: messagesToRefine.length,
|
|
523
|
+
trigger: agentContext.summarizationConfig?.trigger?.type ?? "default"
|
|
524
|
+
},
|
|
525
|
+
sessionId
|
|
526
|
+
}).catch(() => {});
|
|
527
|
+
}
|
|
528
|
+
const isSelfSummarizeModel = clientConfig.provider === agentContext.provider;
|
|
529
|
+
const hasPromptCache = isSelfSummarizeModel && agentContext.clientOptions?.promptCache === true;
|
|
530
|
+
const log = (level, message, data) => {
|
|
531
|
+
emitAgentLog(runnableConfig, level, "summarize", message, data, {
|
|
532
|
+
runId: graph.runId,
|
|
533
|
+
agentId: request.agentId
|
|
534
|
+
});
|
|
535
|
+
};
|
|
536
|
+
log("debug", "Summarization starting", {
|
|
537
|
+
messagesToRefineCount: messagesToRefine.length,
|
|
538
|
+
hasPriorSummary: (agentContext.getSummaryText()?.trim() ?? "") !== "",
|
|
539
|
+
summaryVersion: agentContext.summaryVersion + 1,
|
|
540
|
+
isSelfSummarize: isSelfSummarizeModel,
|
|
541
|
+
hasPromptCache,
|
|
542
|
+
provider: clientConfig.provider
|
|
543
|
+
});
|
|
544
|
+
const { text: rawText, usage: summaryUsage } = await executeSummarizationWithFallback({
|
|
545
|
+
agentContext,
|
|
546
|
+
messages: messagesToRefine,
|
|
547
|
+
clientConfig,
|
|
548
|
+
summarizeConfig: config ? {
|
|
549
|
+
...config,
|
|
550
|
+
metadata: {
|
|
551
|
+
...config.metadata,
|
|
552
|
+
agent_id: request.agentId,
|
|
553
|
+
summarization_provider: clientConfig.provider,
|
|
554
|
+
summarization_model: clientConfig.modelName
|
|
555
|
+
}
|
|
556
|
+
} : void 0,
|
|
557
|
+
stepId,
|
|
558
|
+
usePromptCache: isSelfSummarizeModel && hasPromptCache,
|
|
559
|
+
log
|
|
560
|
+
});
|
|
561
|
+
if (!rawText) {
|
|
562
|
+
agentContext.markSummarizationTriggered(0);
|
|
563
|
+
if (runnableConfig) await safeDispatchCustomEvent("on_summarize_complete", {
|
|
564
|
+
id: stepId,
|
|
565
|
+
agentId: request.agentId,
|
|
566
|
+
error: "Summarization produced empty output"
|
|
567
|
+
}, runnableConfig);
|
|
568
|
+
return { summarizationRequest: void 0 };
|
|
569
|
+
}
|
|
570
|
+
const summaryText = enrichSummary(rawText, messagesToRefine);
|
|
571
|
+
const tokenCount = computeSummaryTokenCount(summaryText, summaryUsage, agentContext.tokenCounter);
|
|
572
|
+
agentContext.setSummary(summaryText, tokenCount);
|
|
573
|
+
log("info", "Summary persisted");
|
|
574
|
+
log("debug", "Summary details", {
|
|
575
|
+
summaryTokens: tokenCount,
|
|
576
|
+
textLength: summaryText.length,
|
|
577
|
+
messagesCompacted: messagesToRefine.length,
|
|
578
|
+
summaryVersion: agentContext.summaryVersion,
|
|
579
|
+
...summaryUsage != null ? {
|
|
580
|
+
input_tokens: summaryUsage.input_tokens,
|
|
581
|
+
output_tokens: summaryUsage.output_tokens,
|
|
582
|
+
cache_read: summaryUsage.input_token_details?.cache_read,
|
|
583
|
+
cache_creation: summaryUsage.input_token_details?.cache_creation
|
|
584
|
+
} : {}
|
|
585
|
+
});
|
|
586
|
+
await dispatchCompletionEvents({
|
|
587
|
+
graph,
|
|
588
|
+
runnableConfig,
|
|
589
|
+
stepId,
|
|
590
|
+
summaryBlock: buildSummaryBlock({
|
|
591
|
+
summaryText,
|
|
592
|
+
tokenCount,
|
|
593
|
+
stepId,
|
|
594
|
+
stepIndex: runStep.index,
|
|
595
|
+
modelName: clientConfig.modelName,
|
|
596
|
+
provider: clientConfig.provider,
|
|
597
|
+
summaryVersion: agentContext.summaryVersion
|
|
598
|
+
}),
|
|
599
|
+
agentContext,
|
|
600
|
+
runStep,
|
|
601
|
+
summaryUsage,
|
|
602
|
+
agentId: request.agentId,
|
|
603
|
+
messagesAfterCount: messagesToRetain.length
|
|
604
|
+
});
|
|
605
|
+
/**
|
|
606
|
+
* `dispatchCompletionEvents` calls `rebuildTokenMapAfterSummarization({})`
|
|
607
|
+
* which resets the dedupe baseline to 0 — correct under the legacy
|
|
608
|
+
* "remove-all only" shape where no messages survived, but stale once
|
|
609
|
+
* the recency window keeps a tail. Realign the baseline to the
|
|
610
|
+
* surviving tail length so a subsequent prune cycle on the unchanged
|
|
611
|
+
* tail short-circuits via `shouldSkipSummarization` instead of
|
|
612
|
+
* looping back into another summarize call.
|
|
613
|
+
*/
|
|
614
|
+
agentContext.markSummarizationTriggered(messagesToRetain.length);
|
|
615
|
+
/**
|
|
616
|
+
* Carry forward the original-content entries that correspond to the
|
|
617
|
+
* retained tail, reindexed for the post-removeAll state where tail
|
|
618
|
+
* messages start at index 0. Without this, a future summarization
|
|
619
|
+
* that pulls these tail messages into its head would only see the
|
|
620
|
+
* masked stubs (since `setSummary` clears `pruneMessages`, and the
|
|
621
|
+
* fresh pruner at the next turn has no record of prior masks).
|
|
622
|
+
* Entries for indices < `tailStartIndex` belong to messages we just
|
|
623
|
+
* summarized — they are no longer reachable so they are dropped.
|
|
624
|
+
*/
|
|
625
|
+
if (originalPending != null && originalPending.size > 0) {
|
|
626
|
+
const tailPending = /* @__PURE__ */ new Map();
|
|
627
|
+
for (const [idx, content] of originalPending) if (idx >= tailStartIndex) tailPending.set(idx - tailStartIndex, content);
|
|
628
|
+
agentContext.pendingOriginalToolContent = tailPending.size > 0 ? tailPending : void 0;
|
|
629
|
+
} else agentContext.pendingOriginalToolContent = void 0;
|
|
630
|
+
return {
|
|
631
|
+
summarizationRequest: void 0,
|
|
632
|
+
messages: messagesToRetain.length > 0 ? [createRemoveAllMessage(), ...messagesToRetain] : [createRemoveAllMessage()]
|
|
633
|
+
};
|
|
634
|
+
};
|
|
760
635
|
}
|
|
761
636
|
/** Extracts text from an LLM response, skipping reasoning/thinking blocks. */
|
|
762
637
|
function extractResponseText(response) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
779
|
-
const rec = block;
|
|
780
|
-
if (rec.type === ContentTypes.THINKING ||
|
|
781
|
-
rec.type === ContentTypes.REASONING_CONTENT ||
|
|
782
|
-
rec.type === 'redacted_thinking') {
|
|
783
|
-
continue;
|
|
784
|
-
}
|
|
785
|
-
if (rec.type === 'text' && typeof rec.text === 'string') {
|
|
786
|
-
parts.push(rec.text);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
return parts.join('').trim();
|
|
638
|
+
const { content } = response;
|
|
639
|
+
if (typeof content === "string") return content.trim();
|
|
640
|
+
if (!Array.isArray(content)) return "";
|
|
641
|
+
const parts = [];
|
|
642
|
+
for (const block of content) {
|
|
643
|
+
if (typeof block === "string") {
|
|
644
|
+
parts.push(block);
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
if (block == null || typeof block !== "object") continue;
|
|
648
|
+
const rec = block;
|
|
649
|
+
if (rec.type === "thinking" || rec.type === "reasoning_content" || rec.type === "redacted_thinking") continue;
|
|
650
|
+
if (rec.type === "text" && typeof rec.text === "string") parts.push(rec.text);
|
|
651
|
+
}
|
|
652
|
+
return parts.join("").trim();
|
|
790
653
|
}
|
|
791
654
|
function buildSummarizationInstruction(promptText, updatePromptText, priorSummaryText) {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
const parts = [effectivePrompt];
|
|
796
|
-
if (priorSummaryText) {
|
|
797
|
-
parts.push(`\n\n<previous-summary>\n${priorSummaryText}\n</previous-summary>`);
|
|
798
|
-
}
|
|
799
|
-
return parts.join('');
|
|
655
|
+
const parts = [priorSummaryText ? updatePromptText ?? promptText : promptText];
|
|
656
|
+
if (priorSummaryText) parts.push(`\n\n<previous-summary>\n${priorSummaryText}\n</previous-summary>`);
|
|
657
|
+
return parts.join("");
|
|
800
658
|
}
|
|
801
659
|
/** Creates an `onChunk` callback that dispatches `ON_SUMMARIZE_DELTA` events for streaming. */
|
|
802
|
-
function createSummarizationChunkHandler({ stepId, config, provider, reasoningKey =
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
},
|
|
825
|
-
}, config);
|
|
826
|
-
};
|
|
660
|
+
function createSummarizationChunkHandler({ stepId, config, provider, reasoningKey = "reasoning_content" }) {
|
|
661
|
+
if (stepId == null || stepId === "" || !config) return;
|
|
662
|
+
return (chunk) => {
|
|
663
|
+
const raw = getChunkContent({
|
|
664
|
+
chunk,
|
|
665
|
+
provider,
|
|
666
|
+
reasoningKey
|
|
667
|
+
});
|
|
668
|
+
if (raw == null || typeof raw === "string" && !raw) return;
|
|
669
|
+
safeDispatchCustomEvent("on_summarize_delta", {
|
|
670
|
+
id: stepId,
|
|
671
|
+
delta: { summary: {
|
|
672
|
+
type: "summary",
|
|
673
|
+
content: typeof raw === "string" ? [{
|
|
674
|
+
type: "text",
|
|
675
|
+
text: raw
|
|
676
|
+
}] : raw,
|
|
677
|
+
provider: String(config.metadata?.summarization_provider ?? ""),
|
|
678
|
+
model: String(config.metadata?.summarization_model ?? "")
|
|
679
|
+
} }
|
|
680
|
+
}, config);
|
|
681
|
+
};
|
|
827
682
|
}
|
|
828
683
|
function traceConfig(config, stage) {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
684
|
+
if (!config) return;
|
|
685
|
+
return {
|
|
686
|
+
...config,
|
|
687
|
+
runName: `summarization:${stage}`,
|
|
688
|
+
metadata: {
|
|
689
|
+
...config.metadata,
|
|
690
|
+
summarization: true,
|
|
691
|
+
stage
|
|
692
|
+
}
|
|
693
|
+
};
|
|
837
694
|
}
|
|
838
695
|
/**
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
async function summarizeWithCacheHit({ model, messages, promptText, updatePromptText, priorSummaryText, config, stepId, provider, reasoningKey, usePromptCache, log
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
...(cacheDetails?.cache_read != null || cacheDetails?.cache_creation != null
|
|
889
|
-
? {
|
|
890
|
-
'input_token_details.cache_read': cacheDetails.cache_read,
|
|
891
|
-
'input_token_details.cache_creation': cacheDetails.cache_creation,
|
|
892
|
-
}
|
|
893
|
-
: {}),
|
|
894
|
-
});
|
|
895
|
-
return { text, usage };
|
|
696
|
+
* Cache-friendly compaction: sends raw conversation messages with the
|
|
697
|
+
* summarization instruction appended as the final HumanMessage.
|
|
698
|
+
* Providers with prompt caching get a cache hit on the system prompt +
|
|
699
|
+
* tool definitions prefix.
|
|
700
|
+
*/
|
|
701
|
+
async function summarizeWithCacheHit({ model, messages, promptText, updatePromptText, priorSummaryText, config, stepId, provider, reasoningKey, usePromptCache, log }) {
|
|
702
|
+
const instruction = buildSummarizationInstruction(promptText, updatePromptText, priorSummaryText);
|
|
703
|
+
const fullMessages = [...messages, new HumanMessage(instruction)];
|
|
704
|
+
const responseMsg = (await attemptInvoke({
|
|
705
|
+
model,
|
|
706
|
+
messages: usePromptCache === true ? addCacheControl(fullMessages) : fullMessages,
|
|
707
|
+
provider,
|
|
708
|
+
onChunk: createSummarizationChunkHandler({
|
|
709
|
+
stepId,
|
|
710
|
+
config: traceConfig(config, "cache_hit_compaction"),
|
|
711
|
+
provider,
|
|
712
|
+
reasoningKey
|
|
713
|
+
})
|
|
714
|
+
}, traceConfig(config, "cache_hit_compaction"))).messages?.[0];
|
|
715
|
+
const text = responseMsg ? extractResponseText(responseMsg) : "";
|
|
716
|
+
let usage;
|
|
717
|
+
let usageSource = "none";
|
|
718
|
+
if (responseMsg != null && "usage_metadata" in responseMsg && responseMsg.usage_metadata != null) {
|
|
719
|
+
usage = responseMsg.usage_metadata;
|
|
720
|
+
usageSource = "usage_metadata";
|
|
721
|
+
} else if (responseMsg != null) {
|
|
722
|
+
const raw = (responseMsg.response_metadata?.metadata)?.usage;
|
|
723
|
+
if (raw != null) {
|
|
724
|
+
usage = {
|
|
725
|
+
input_tokens: Number(raw.inputTokens) || void 0,
|
|
726
|
+
output_tokens: Number(raw.outputTokens) || void 0
|
|
727
|
+
};
|
|
728
|
+
usageSource = "response_metadata";
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
const cacheDetails = usage?.input_token_details;
|
|
732
|
+
log?.("debug", "Summarization LLM usage", {
|
|
733
|
+
source: usageSource,
|
|
734
|
+
input_tokens: usage?.input_tokens,
|
|
735
|
+
output_tokens: usage?.output_tokens,
|
|
736
|
+
...cacheDetails?.cache_read != null || cacheDetails?.cache_creation != null ? {
|
|
737
|
+
"input_token_details.cache_read": cacheDetails.cache_read,
|
|
738
|
+
"input_token_details.cache_creation": cacheDetails.cache_creation
|
|
739
|
+
} : {}
|
|
740
|
+
});
|
|
741
|
+
return {
|
|
742
|
+
text,
|
|
743
|
+
usage
|
|
744
|
+
};
|
|
896
745
|
}
|
|
746
|
+
//#endregion
|
|
747
|
+
export { createSummarizeNode };
|
|
897
748
|
|
|
898
|
-
|
|
899
|
-
//# sourceMappingURL=node.mjs.map
|
|
749
|
+
//# sourceMappingURL=node.mjs.map
|