@librechat/agents 3.2.31 → 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 -696
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -252
- 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 +308 -401
- 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 -1382
- 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 -690
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -249
- 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 +308 -399
- 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 -1378
- 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/messages/format.d.ts +5 -0
- package/dist/types/tools/search/tool.d.ts +17 -0
- package/dist/types/tools/search/types.d.ts +4 -0
- package/package.json +11 -17
- package/src/llm/anthropic/llm.spec.ts +36 -0
- package/src/llm/anthropic/utils/message_inputs.ts +45 -3
- package/src/llm/anthropic/utils/message_outputs.ts +6 -2
- package/src/llm/anthropic/utils/streaming-tool-input.test.ts +186 -0
- package/src/messages/cache.test.ts +122 -0
- package/src/messages/cache.ts +25 -1
- package/src/messages/format.ts +9 -0
- package/src/messages/formatAgentMessages.skills.test.ts +100 -0
- 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
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { AIMessage, HumanMessage } from '@langchain/core/messages';
|
|
3
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
4
|
+
import { _convertMessagesToAnthropicPayload } from './message_inputs';
|
|
5
|
+
import { _makeMessageChunkFromAnthropicEvent } from './message_outputs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Regression for @langchain/core >= 1.1.46 streaming aggregation: a tool call's
|
|
9
|
+
* input_json_delta is kept as a separate content block and v1-cast to a `text`
|
|
10
|
+
* block carrying `input` but no `text`, leaving the sibling tool_use block with an
|
|
11
|
+
* empty inline input. The assembled arguments live on `message.tool_calls`.
|
|
12
|
+
* Re-serializing such a message previously threw "Unsupported message content format".
|
|
13
|
+
*/
|
|
14
|
+
describe('_convertMessagesToAnthropicPayload — aggregated streaming tool input', () => {
|
|
15
|
+
const buildHistory = (): BaseMessage[] => [
|
|
16
|
+
new HumanMessage('what is 12345 * 6789?'),
|
|
17
|
+
new AIMessage({
|
|
18
|
+
content: [
|
|
19
|
+
{ type: 'text', text: 'Let me calculate that.' },
|
|
20
|
+
// tool_use block left with empty inline input by aggregation
|
|
21
|
+
{
|
|
22
|
+
type: 'tool_use',
|
|
23
|
+
id: 'toolu_calc',
|
|
24
|
+
name: 'calculator',
|
|
25
|
+
input: '',
|
|
26
|
+
index: 0,
|
|
27
|
+
} as any,
|
|
28
|
+
// orphaned input delta, v1-cast to `text` with `input` and no `text`
|
|
29
|
+
{ type: 'text', index: 0, input: '{"input": "12345 * 6789"}' } as any,
|
|
30
|
+
],
|
|
31
|
+
tool_calls: [
|
|
32
|
+
{
|
|
33
|
+
id: 'toolu_calc',
|
|
34
|
+
name: 'calculator',
|
|
35
|
+
args: { input: '12345 * 6789' },
|
|
36
|
+
type: 'tool_call',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
}),
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
it('does not throw on the orphaned text-with-input block', () => {
|
|
43
|
+
expect(() => _convertMessagesToAnthropicPayload(buildHistory())).not.toThrow();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('restores tool_use input from message.tool_calls and drops the orphan block', () => {
|
|
47
|
+
const payload = _convertMessagesToAnthropicPayload(buildHistory());
|
|
48
|
+
const assistant = payload.messages.find((m: any) => m.role === 'assistant');
|
|
49
|
+
expect(assistant).toBeDefined();
|
|
50
|
+
const blocks = assistant!.content as any[];
|
|
51
|
+
|
|
52
|
+
const toolUse = blocks.find((b) => b.type === 'tool_use');
|
|
53
|
+
expect(toolUse).toMatchObject({
|
|
54
|
+
type: 'tool_use',
|
|
55
|
+
id: 'toolu_calc',
|
|
56
|
+
name: 'calculator',
|
|
57
|
+
input: { input: '12345 * 6789' },
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// No leftover delta: no text block carrying `input`, no input_json_delta.
|
|
61
|
+
expect(
|
|
62
|
+
blocks.find(
|
|
63
|
+
(b) => (b.type === 'text' && 'input' in b) || b.type === 'input_json_delta'
|
|
64
|
+
)
|
|
65
|
+
).toBeUndefined();
|
|
66
|
+
|
|
67
|
+
// The real assistant text is preserved.
|
|
68
|
+
expect(
|
|
69
|
+
blocks.some((b) => b.type === 'text' && b.text === 'Let me calculate that.')
|
|
70
|
+
).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('does not overwrite a tool_use block that already has inline input', () => {
|
|
74
|
+
const history: BaseMessage[] = [
|
|
75
|
+
new HumanMessage('hi'),
|
|
76
|
+
new AIMessage({
|
|
77
|
+
content: [
|
|
78
|
+
{
|
|
79
|
+
type: 'tool_use',
|
|
80
|
+
id: 'toolu_x',
|
|
81
|
+
name: 'calculator',
|
|
82
|
+
input: { input: '2 + 2' },
|
|
83
|
+
} as any,
|
|
84
|
+
],
|
|
85
|
+
tool_calls: [
|
|
86
|
+
{
|
|
87
|
+
id: 'toolu_x',
|
|
88
|
+
name: 'calculator',
|
|
89
|
+
args: { input: '999' },
|
|
90
|
+
type: 'tool_call',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
}),
|
|
94
|
+
];
|
|
95
|
+
const payload = _convertMessagesToAnthropicPayload(history);
|
|
96
|
+
const assistant = payload.messages.find((m: any) => m.role === 'assistant');
|
|
97
|
+
const toolUse = (assistant!.content as any[]).find((b) => b.type === 'tool_use');
|
|
98
|
+
expect(toolUse.input).toEqual({ input: '2 + 2' });
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Adapted from @langchain/anthropic's
|
|
102
|
+
// "partial tool input is correctly merged before calling Anthropic API".
|
|
103
|
+
it('merges sibling input_json_delta blocks into tool_use input (persisted, no tool_calls)', () => {
|
|
104
|
+
const messages: BaseMessage[] = [
|
|
105
|
+
new HumanMessage('What\'s the weather in Seattle tomorrow?'),
|
|
106
|
+
new AIMessage({
|
|
107
|
+
content: [
|
|
108
|
+
{ type: 'text', index: 1, text: 'I need to call the get_weather tool' },
|
|
109
|
+
{ type: 'tool_use', index: 2, name: 'get_weather', id: 'tool_call_id', input: '' },
|
|
110
|
+
{ type: 'input_json_delta', index: 2, input: '{"city": "' },
|
|
111
|
+
{ type: 'input_json_delta', index: 2, input: 'Seattle", "da' },
|
|
112
|
+
{ type: 'input_json_delta', index: 2, input: 'te": "to' },
|
|
113
|
+
{ type: 'input_json_delta', index: 2, input: 'morrow"}' },
|
|
114
|
+
] as any,
|
|
115
|
+
}),
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
const payload = _convertMessagesToAnthropicPayload(messages);
|
|
119
|
+
const assistant = payload.messages.find((m: any) => m.role === 'assistant');
|
|
120
|
+
const blocks = assistant!.content as any[];
|
|
121
|
+
expect(blocks.filter((b) => b.type === 'input_json_delta')).toHaveLength(0);
|
|
122
|
+
const toolUse = blocks.find((b) => b.type === 'tool_use');
|
|
123
|
+
expect(toolUse).toMatchObject({
|
|
124
|
+
type: 'tool_use',
|
|
125
|
+
name: 'get_weather',
|
|
126
|
+
id: 'tool_call_id',
|
|
127
|
+
input: { city: 'Seattle', date: 'tomorrow' },
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('_makeMessageChunkFromAnthropicEvent — streamed tool input merges into content', () => {
|
|
133
|
+
const fields = { streamUsage: true, coerceContentToString: false };
|
|
134
|
+
|
|
135
|
+
it('emits input deltas without a type so aggregation merges them into the tool_use block', () => {
|
|
136
|
+
const events: any[] = [
|
|
137
|
+
{
|
|
138
|
+
type: 'content_block_start',
|
|
139
|
+
index: 0,
|
|
140
|
+
content_block: { type: 'tool_use', id: 'toolu_1', name: 'calculator', input: {} },
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: 'content_block_delta',
|
|
144
|
+
index: 0,
|
|
145
|
+
delta: { type: 'input_json_delta', partial_json: '{"input"' },
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
type: 'content_block_delta',
|
|
149
|
+
index: 0,
|
|
150
|
+
delta: { type: 'input_json_delta', partial_json: ': "2 + 2"}' },
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
const chunks = events
|
|
154
|
+
.map((e) => _makeMessageChunkFromAnthropicEvent(e, fields)?.chunk)
|
|
155
|
+
.filter((c): c is NonNullable<typeof c> => c != null);
|
|
156
|
+
|
|
157
|
+
// input-delta chunks must not carry a `type` (so core merges them by index
|
|
158
|
+
// into the sibling tool_use/server_tool_use block rather than orphaning them)
|
|
159
|
+
const deltaBlocks = chunks
|
|
160
|
+
.slice(1)
|
|
161
|
+
.flatMap((c) => (Array.isArray(c.content) ? (c.content as any[]) : []))
|
|
162
|
+
.filter((b) => 'input' in b);
|
|
163
|
+
expect(deltaBlocks.length).toBeGreaterThan(0);
|
|
164
|
+
deltaBlocks.forEach((b) => expect('type' in b).toBe(false));
|
|
165
|
+
|
|
166
|
+
// aggregate the chunks the way core does during streaming
|
|
167
|
+
const merged = chunks.reduce((acc, c) => acc.concat(c));
|
|
168
|
+
const blocks = merged.content as any[];
|
|
169
|
+
|
|
170
|
+
const toolUse = blocks.find((b) => b.type === 'tool_use');
|
|
171
|
+
expect(toolUse).toMatchObject({ type: 'tool_use', id: 'toolu_1', name: 'calculator' });
|
|
172
|
+
const parsed =
|
|
173
|
+
typeof toolUse.input === 'string' ? JSON.parse(toolUse.input) : toolUse.input;
|
|
174
|
+
expect(parsed).toEqual({ input: '2 + 2' });
|
|
175
|
+
|
|
176
|
+
// no orphaned delta block survives aggregation
|
|
177
|
+
expect(blocks.filter((b) => b.type !== 'tool_use' && 'input' in b)).toHaveLength(0);
|
|
178
|
+
|
|
179
|
+
// tool_calls remain correctly aggregated
|
|
180
|
+
expect(merged.tool_calls?.[0]).toMatchObject({
|
|
181
|
+
id: 'toolu_1',
|
|
182
|
+
name: 'calculator',
|
|
183
|
+
args: { input: '2 + 2' },
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
});
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
stripBedrockCacheControl,
|
|
14
14
|
addBedrockCacheControl,
|
|
15
15
|
addCacheControl,
|
|
16
|
+
addCacheControlToStablePrefixMessages,
|
|
16
17
|
} from './cache';
|
|
17
18
|
import { _convertMessagesToOpenAIParams } from '@/llm/openai/utils';
|
|
18
19
|
import { toLangChainContent } from './langchain';
|
|
@@ -767,6 +768,127 @@ describe('addBedrockCacheControl (Bedrock cache checkpoints)', () => {
|
|
|
767
768
|
});
|
|
768
769
|
});
|
|
769
770
|
|
|
771
|
+
describe('synthetic skill/meta messages are not cache-anchored', () => {
|
|
772
|
+
const hasAnthropicMarker = (m: BaseMessage): boolean =>
|
|
773
|
+
Array.isArray(m.content) &&
|
|
774
|
+
m.content.some((block) => 'cache_control' in block);
|
|
775
|
+
|
|
776
|
+
const hasBedrockCachePoint = (m: BaseMessage): boolean =>
|
|
777
|
+
Array.isArray(m.content) &&
|
|
778
|
+
m.content.some((block) => 'cachePoint' in block);
|
|
779
|
+
|
|
780
|
+
const skillBody = (skillName: string, content = 'SKILL BODY'): HumanMessage =>
|
|
781
|
+
new HumanMessage({
|
|
782
|
+
content,
|
|
783
|
+
additional_kwargs: { isMeta: true, source: 'skill', skillName },
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
it('Anthropic: skips a trailing synthetic skill message; markers land on the real user messages', () => {
|
|
787
|
+
const messages: BaseMessage[] = [
|
|
788
|
+
new HumanMessage('First real question'),
|
|
789
|
+
new AIMessage('Answer'),
|
|
790
|
+
new HumanMessage('Second real question'),
|
|
791
|
+
skillBody('pdf-analyzer'),
|
|
792
|
+
];
|
|
793
|
+
|
|
794
|
+
const result = addCacheControl<BaseMessage>(messages);
|
|
795
|
+
|
|
796
|
+
expect(hasAnthropicMarker(result[3])).toBe(false);
|
|
797
|
+
expect(hasAnthropicMarker(result[2])).toBe(true);
|
|
798
|
+
expect(hasAnthropicMarker(result[0])).toBe(true);
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
it('Anthropic: strips a stale marker from a synthetic skill message without re-adding one', () => {
|
|
802
|
+
const stale = new HumanMessage({
|
|
803
|
+
content: toLangChainContent([
|
|
804
|
+
{
|
|
805
|
+
type: 'text',
|
|
806
|
+
text: 'SKILL BODY',
|
|
807
|
+
cache_control: { type: 'ephemeral' },
|
|
808
|
+
} as MessageContentComplex,
|
|
809
|
+
]),
|
|
810
|
+
additional_kwargs: {
|
|
811
|
+
isMeta: true,
|
|
812
|
+
source: 'skill',
|
|
813
|
+
skillName: 'pdf-analyzer',
|
|
814
|
+
},
|
|
815
|
+
});
|
|
816
|
+
const messages: BaseMessage[] = [
|
|
817
|
+
new HumanMessage('Real question'),
|
|
818
|
+
new AIMessage('Answer'),
|
|
819
|
+
stale,
|
|
820
|
+
];
|
|
821
|
+
|
|
822
|
+
const result = addCacheControl<BaseMessage>(messages);
|
|
823
|
+
|
|
824
|
+
expect(hasAnthropicMarker(result[2])).toBe(false);
|
|
825
|
+
expect(hasAnthropicMarker(result[0])).toBe(true);
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
it('Anthropic: detects skill messages by additional_kwargs.source even without isMeta', () => {
|
|
829
|
+
const messages: BaseMessage[] = [
|
|
830
|
+
new HumanMessage('Real question'),
|
|
831
|
+
new AIMessage('Answer'),
|
|
832
|
+
new HumanMessage({
|
|
833
|
+
content: 'SKILL BODY',
|
|
834
|
+
additional_kwargs: { source: 'skill', skillName: 'pdf-analyzer' },
|
|
835
|
+
}),
|
|
836
|
+
];
|
|
837
|
+
|
|
838
|
+
const result = addCacheControl<BaseMessage>(messages);
|
|
839
|
+
|
|
840
|
+
expect(hasAnthropicMarker(result[2])).toBe(false);
|
|
841
|
+
expect(hasAnthropicMarker(result[0])).toBe(true);
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
it('Bedrock: skips a trailing synthetic skill message; cachePoints land on the real user messages', () => {
|
|
845
|
+
const messages: BaseMessage[] = [
|
|
846
|
+
new HumanMessage('First real question'),
|
|
847
|
+
new AIMessage('Answer'),
|
|
848
|
+
new HumanMessage('Second real question'),
|
|
849
|
+
skillBody('pdf-analyzer'),
|
|
850
|
+
];
|
|
851
|
+
|
|
852
|
+
const result = addBedrockCacheControl<BaseMessage>(messages);
|
|
853
|
+
|
|
854
|
+
expect(hasBedrockCachePoint(result[3])).toBe(false);
|
|
855
|
+
expect(hasBedrockCachePoint(result[2])).toBe(true);
|
|
856
|
+
expect(hasBedrockCachePoint(result[0])).toBe(true);
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
it('stable-prefix fallback: anchors the real user message, not a synthetic skill message', () => {
|
|
860
|
+
// Mirrors AgentContext's dynamic-tail path: the only assistant message is a
|
|
861
|
+
// skill-only tool call (no text), so the assistant-only pass adds no marker
|
|
862
|
+
// and the cacheable fallback runs. It must skip the reconstructed skill
|
|
863
|
+
// HumanMessage and anchor the real user message instead.
|
|
864
|
+
const messages: BaseMessage[] = [
|
|
865
|
+
new HumanMessage('Real stable question'),
|
|
866
|
+
new AIMessage({
|
|
867
|
+
content: toLangChainContent([
|
|
868
|
+
{
|
|
869
|
+
type: 'tool_use',
|
|
870
|
+
id: 'call_1',
|
|
871
|
+
name: 'skill',
|
|
872
|
+
input: { skillName: 'pdf-analyzer' },
|
|
873
|
+
} as MessageContentComplex,
|
|
874
|
+
]),
|
|
875
|
+
tool_calls: [
|
|
876
|
+
{ id: 'call_1', name: 'skill', args: { skillName: 'pdf-analyzer' } },
|
|
877
|
+
],
|
|
878
|
+
}),
|
|
879
|
+
skillBody('pdf-analyzer'),
|
|
880
|
+
];
|
|
881
|
+
|
|
882
|
+
const result = addCacheControlToStablePrefixMessages<BaseMessage>(
|
|
883
|
+
messages,
|
|
884
|
+
2
|
|
885
|
+
);
|
|
886
|
+
|
|
887
|
+
expect(hasAnthropicMarker(result[2])).toBe(false);
|
|
888
|
+
expect(hasAnthropicMarker(result[0])).toBe(true);
|
|
889
|
+
});
|
|
890
|
+
});
|
|
891
|
+
|
|
770
892
|
describe('stripAnthropicCacheControl', () => {
|
|
771
893
|
it('removes cache_control fields from content blocks', () => {
|
|
772
894
|
const messages: TestMsg[] = [
|
package/src/messages/cache.ts
CHANGED
|
@@ -182,6 +182,7 @@ export function addCacheControl<T extends AnthropicMessage | BaseMessage>(
|
|
|
182
182
|
const needsCacheAdd =
|
|
183
183
|
userMessagesModified < 2 &&
|
|
184
184
|
isUserMessage &&
|
|
185
|
+
!isSyntheticMetaMessage(originalMessage) &&
|
|
185
186
|
(typeof content === 'string' || hasArrayContent);
|
|
186
187
|
|
|
187
188
|
// Skip messages that don't need any work
|
|
@@ -263,6 +264,26 @@ function getMessageRole(message: MessageWithContent): string | undefined {
|
|
|
263
264
|
return undefined;
|
|
264
265
|
}
|
|
265
266
|
|
|
267
|
+
const SKILL_MESSAGE_SOURCE = 'skill';
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Synthetic skill/meta messages (reconstructed skill bodies, primed SKILL.md
|
|
271
|
+
* instructions) are re-injected every turn and are not stable conversation
|
|
272
|
+
* turns. They must not anchor a fresh prompt-cache marker — doing so pins the
|
|
273
|
+
* cache to a volatile/duplicated prefix. Stale markers are still stripped from
|
|
274
|
+
* them; only the *adding* of new markers is suppressed. Detected via
|
|
275
|
+
* `additional_kwargs.isMeta === true` or `additional_kwargs.source === 'skill'`.
|
|
276
|
+
*/
|
|
277
|
+
function isSyntheticMetaMessage(message: MessageWithContent): boolean {
|
|
278
|
+
const { additional_kwargs: kwargs } = message as {
|
|
279
|
+
additional_kwargs?: { isMeta?: unknown; source?: unknown };
|
|
280
|
+
};
|
|
281
|
+
if (kwargs == null) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
return kwargs.isMeta === true || kwargs.source === SKILL_MESSAGE_SOURCE;
|
|
285
|
+
}
|
|
286
|
+
|
|
266
287
|
function isCacheableConversationMessage(message: MessageWithContent): boolean {
|
|
267
288
|
const role = getMessageRole(message);
|
|
268
289
|
return (
|
|
@@ -305,7 +326,9 @@ function addCacheControlToRecentMessages<
|
|
|
305
326
|
const content = originalMessage.content;
|
|
306
327
|
const hasArrayContent = Array.isArray(content);
|
|
307
328
|
const canAddCache =
|
|
308
|
-
cachePointsAdded < maxCachePoints &&
|
|
329
|
+
cachePointsAdded < maxCachePoints &&
|
|
330
|
+
canUseMessage(originalMessage) &&
|
|
331
|
+
!isSyntheticMetaMessage(originalMessage);
|
|
309
332
|
|
|
310
333
|
if (!canAddCache && !hasArrayContent) {
|
|
311
334
|
continue;
|
|
@@ -536,6 +559,7 @@ export function addBedrockCacheControl<
|
|
|
536
559
|
isUserMessage &&
|
|
537
560
|
!isToolMessage &&
|
|
538
561
|
!isEmptyString &&
|
|
562
|
+
!isSyntheticMetaMessage(originalMessage) &&
|
|
539
563
|
(typeof content === 'string' || hasArrayContent);
|
|
540
564
|
|
|
541
565
|
if (!needsCacheAdd && !hasArrayContent && !hasSerializationProps) {
|
package/src/messages/format.ts
CHANGED
|
@@ -334,6 +334,10 @@ interface FormatAssistantMessageOptions {
|
|
|
334
334
|
|
|
335
335
|
interface FormatAgentMessagesOptions {
|
|
336
336
|
provider?: Providers;
|
|
337
|
+
/** Skill names already primed fresh this turn (manual/always-apply). Their
|
|
338
|
+
* historical `skill` tool_calls are not reconstructed into a HumanMessage,
|
|
339
|
+
* so the same SKILL.md body is not injected twice in one request. */
|
|
340
|
+
skipSkillBodyNames?: Set<string>;
|
|
337
341
|
}
|
|
338
342
|
|
|
339
343
|
function extractReasoningContent(
|
|
@@ -1159,6 +1163,7 @@ function extractSkillName(args: unknown): string | undefined {
|
|
|
1159
1163
|
* @param indexTokenCountMap - Optional map of message indices to token counts.
|
|
1160
1164
|
* @param tools - Optional set of tool names that are allowed in the request.
|
|
1161
1165
|
* @param skills - Optional map of skill name to body for reconstructing skill HumanMessages.
|
|
1166
|
+
* @param options - Optional formatting options (provider, skipSkillBodyNames).
|
|
1162
1167
|
* @returns - Object containing formatted messages and updated indexTokenCountMap if provided.
|
|
1163
1168
|
*/
|
|
1164
1169
|
export const formatAgentMessages = (
|
|
@@ -1445,7 +1450,11 @@ export const formatAgentMessages = (
|
|
|
1445
1450
|
const endMessageIndex = messages.length;
|
|
1446
1451
|
|
|
1447
1452
|
if (pendingSkillNames?.size != null && pendingSkillNames.size > 0) {
|
|
1453
|
+
const skipSkillBodyNames = options?.skipSkillBodyNames;
|
|
1448
1454
|
for (const skillName of pendingSkillNames) {
|
|
1455
|
+
if (skipSkillBodyNames != null && skipSkillBodyNames.has(skillName)) {
|
|
1456
|
+
continue;
|
|
1457
|
+
}
|
|
1449
1458
|
const body = skills?.get(skillName) ?? '';
|
|
1450
1459
|
if (body) {
|
|
1451
1460
|
messages.push(
|
|
@@ -410,4 +410,104 @@ describe('formatAgentMessages skill body reconstruction', () => {
|
|
|
410
410
|
expect(assistantTotal).toBe(500);
|
|
411
411
|
});
|
|
412
412
|
});
|
|
413
|
+
|
|
414
|
+
describe('skipSkillBodyNames (fresh-prime dedupe)', () => {
|
|
415
|
+
const tools = new Set([Constants.SKILL_TOOL]);
|
|
416
|
+
|
|
417
|
+
const injectedSkillBodies = (
|
|
418
|
+
messages: ReturnType<typeof formatAgentMessages>['messages']
|
|
419
|
+
) =>
|
|
420
|
+
messages.filter(
|
|
421
|
+
(m) =>
|
|
422
|
+
m instanceof HumanMessage &&
|
|
423
|
+
(m as HumanMessage).additional_kwargs.source === 'skill'
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
it('does NOT reconstruct body when skill name is in skipSkillBodyNames', () => {
|
|
427
|
+
const payload: TPayload = [
|
|
428
|
+
{ role: 'user', content: 'Review my code' },
|
|
429
|
+
{
|
|
430
|
+
role: 'assistant',
|
|
431
|
+
content: [skillToolCall('call_1', 'code-review')],
|
|
432
|
+
},
|
|
433
|
+
];
|
|
434
|
+
|
|
435
|
+
const { messages } = formatAgentMessages(
|
|
436
|
+
payload,
|
|
437
|
+
undefined,
|
|
438
|
+
tools,
|
|
439
|
+
skillBodies,
|
|
440
|
+
{ skipSkillBodyNames: new Set(['code-review']) }
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
expect(injectedSkillBodies(messages)).toHaveLength(0);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
it('reconstructs only names NOT in skipSkillBodyNames', () => {
|
|
447
|
+
const payload: TPayload = [
|
|
448
|
+
{ role: 'user', content: 'Go' },
|
|
449
|
+
{
|
|
450
|
+
role: 'assistant',
|
|
451
|
+
content: [
|
|
452
|
+
skillToolCall('call_1', 'pdf-analyzer'),
|
|
453
|
+
skillToolCall('call_2', 'code-review'),
|
|
454
|
+
],
|
|
455
|
+
},
|
|
456
|
+
];
|
|
457
|
+
|
|
458
|
+
const { messages } = formatAgentMessages(
|
|
459
|
+
payload,
|
|
460
|
+
undefined,
|
|
461
|
+
tools,
|
|
462
|
+
skillBodies,
|
|
463
|
+
{ skipSkillBodyNames: new Set(['code-review']) }
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
const injected = injectedSkillBodies(messages);
|
|
467
|
+
expect(injected).toHaveLength(1);
|
|
468
|
+
expect((injected[0] as HumanMessage).additional_kwargs.skillName).toBe(
|
|
469
|
+
'pdf-analyzer'
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
it('reconstructs normally when skipSkillBodyNames is empty', () => {
|
|
474
|
+
const payload: TPayload = [
|
|
475
|
+
{ role: 'user', content: 'Review my code' },
|
|
476
|
+
{
|
|
477
|
+
role: 'assistant',
|
|
478
|
+
content: [skillToolCall('call_1', 'code-review')],
|
|
479
|
+
},
|
|
480
|
+
];
|
|
481
|
+
|
|
482
|
+
const { messages } = formatAgentMessages(
|
|
483
|
+
payload,
|
|
484
|
+
undefined,
|
|
485
|
+
tools,
|
|
486
|
+
skillBodies,
|
|
487
|
+
{ skipSkillBodyNames: new Set() }
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
expect(injectedSkillBodies(messages)).toHaveLength(1);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it('skips in the non-tools-filtering path too', () => {
|
|
494
|
+
const payload: TPayload = [
|
|
495
|
+
{ role: 'user', content: 'Review my code' },
|
|
496
|
+
{
|
|
497
|
+
role: 'assistant',
|
|
498
|
+
content: [skillToolCall('call_1', 'code-review')],
|
|
499
|
+
},
|
|
500
|
+
];
|
|
501
|
+
|
|
502
|
+
const { messages } = formatAgentMessages(
|
|
503
|
+
payload,
|
|
504
|
+
undefined,
|
|
505
|
+
undefined,
|
|
506
|
+
skillBodies,
|
|
507
|
+
{ skipSkillBodyNames: new Set(['code-review']) }
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
expect(injectedSkillBodies(messages)).toHaveLength(0);
|
|
511
|
+
});
|
|
512
|
+
});
|
|
413
513
|
});
|
|
@@ -240,7 +240,15 @@ export function expandHighlights(
|
|
|
240
240
|
!result.highlights ||
|
|
241
241
|
result.highlights.length === 0
|
|
242
242
|
) {
|
|
243
|
-
|
|
243
|
+
if (result.content == null && result.references == null) {
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
/** Raw scraped content must never leave this function — without
|
|
247
|
+
* highlights to expand, strip it instead of passing it downstream */
|
|
248
|
+
const strippedResult = { ...result };
|
|
249
|
+
delete strippedResult.content;
|
|
250
|
+
delete strippedResult.references;
|
|
251
|
+
return strippedResult;
|
|
244
252
|
}
|
|
245
253
|
|
|
246
254
|
// Create a shallow copy with expanded highlights
|
|
@@ -66,6 +66,25 @@ const chunker = {
|
|
|
66
66
|
},
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
const DEFAULT_MAX_CONTENT_LENGTH = 50000;
|
|
70
|
+
|
|
71
|
+
/** Resolves the per-source scraped content cap from config, the
|
|
72
|
+
* `SEARCH_MAX_CONTENT_LENGTH` env var, or the default (50,000 chars) */
|
|
73
|
+
function resolveMaxContentLength(maxContentLength?: number): number {
|
|
74
|
+
if (maxContentLength != null && maxContentLength > 0) {
|
|
75
|
+
return maxContentLength;
|
|
76
|
+
}
|
|
77
|
+
const envValue = Number(process.env.SEARCH_MAX_CONTENT_LENGTH);
|
|
78
|
+
if (Number.isFinite(envValue) && envValue > 0) {
|
|
79
|
+
return envValue;
|
|
80
|
+
}
|
|
81
|
+
return DEFAULT_MAX_CONTENT_LENGTH;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function truncateContent(content: string, maxLength: number): string {
|
|
85
|
+
return content.length > maxLength ? content.slice(0, maxLength) : content;
|
|
86
|
+
}
|
|
87
|
+
|
|
69
88
|
function createSourceUpdateCallback(sourceMap: Map<string, t.ValidSource>) {
|
|
70
89
|
return (link: string, update?: Partial<t.ValidSource>): void => {
|
|
71
90
|
const source = sourceMap.get(link);
|
|
@@ -83,12 +102,14 @@ const getHighlights = async ({
|
|
|
83
102
|
content,
|
|
84
103
|
reranker,
|
|
85
104
|
topResults = 5,
|
|
105
|
+
maxContentLength = DEFAULT_MAX_CONTENT_LENGTH,
|
|
86
106
|
logger,
|
|
87
107
|
}: {
|
|
88
108
|
content: string;
|
|
89
109
|
query: string;
|
|
90
110
|
reranker?: BaseReranker;
|
|
91
111
|
topResults?: number;
|
|
112
|
+
maxContentLength?: number;
|
|
92
113
|
logger?: t.Logger;
|
|
93
114
|
}): Promise<t.Highlight[] | undefined> => {
|
|
94
115
|
const logger_ = logger || createDefaultLogger();
|
|
@@ -103,7 +124,9 @@ const getHighlights = async ({
|
|
|
103
124
|
}
|
|
104
125
|
|
|
105
126
|
try {
|
|
106
|
-
const documents = await chunker.splitText(
|
|
127
|
+
const documents = await chunker.splitText(
|
|
128
|
+
truncateContent(content, maxContentLength)
|
|
129
|
+
);
|
|
107
130
|
if (Array.isArray(documents)) {
|
|
108
131
|
return await reranker.rerank(query, documents, topResults);
|
|
109
132
|
} else {
|
|
@@ -457,6 +480,7 @@ export const createSourceProcessor = (
|
|
|
457
480
|
logger,
|
|
458
481
|
} = config;
|
|
459
482
|
|
|
483
|
+
const maxContentLength = resolveMaxContentLength(config.maxContentLength);
|
|
460
484
|
const logger_ = logger || createDefaultLogger();
|
|
461
485
|
const scraper = scraperInstance;
|
|
462
486
|
|
|
@@ -475,7 +499,7 @@ export const createSourceProcessor = (
|
|
|
475
499
|
url,
|
|
476
500
|
references,
|
|
477
501
|
attribution,
|
|
478
|
-
content: chunker.cleanText(content),
|
|
502
|
+
content: truncateContent(chunker.cleanText(content), maxContentLength),
|
|
479
503
|
};
|
|
480
504
|
}
|
|
481
505
|
|
|
@@ -498,6 +522,7 @@ export const createSourceProcessor = (
|
|
|
498
522
|
query,
|
|
499
523
|
reranker,
|
|
500
524
|
content: result.content,
|
|
525
|
+
maxContentLength,
|
|
501
526
|
logger: logger_,
|
|
502
527
|
});
|
|
503
528
|
if (onGetHighlights) {
|
|
@@ -606,7 +631,20 @@ export const createSourceProcessor = (
|
|
|
606
631
|
images: [],
|
|
607
632
|
relatedSearches: [],
|
|
608
633
|
};
|
|
609
|
-
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (
|
|
637
|
+
result.data.topStories != null &&
|
|
638
|
+
result.data.topStories.length > numElements
|
|
639
|
+
) {
|
|
640
|
+
/** Merged news results can far exceed the requested source count;
|
|
641
|
+
* every entry is formatted into the LLM output, so cap them up
|
|
642
|
+
* front — before any early return below and before scraping
|
|
643
|
+
* entries the cap would discard */
|
|
644
|
+
result.data.topStories = result.data.topStories.slice(0, numElements);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
if (!result.data.organic) {
|
|
610
648
|
return result.data;
|
|
611
649
|
}
|
|
612
650
|
|