@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,1456 +1,975 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { toLangChainContent, toLangChainMessageFields } from
|
|
4
|
-
import {
|
|
5
|
-
import { emitAgentLog } from
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import "../common/enum.mjs";
|
|
2
|
+
import "../common/index.mjs";
|
|
3
|
+
import { toLangChainContent, toLangChainMessageFields } from "./langchain.mjs";
|
|
4
|
+
import { normalizeAnthropicToolCallId } from "../llm/anthropic/utils/message_inputs.mjs";
|
|
5
|
+
import { emitAgentLog } from "../utils/events.mjs";
|
|
6
|
+
import { AIMessage, AIMessageChunk, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
|
|
7
|
+
//#region src/messages/format.ts
|
|
8
8
|
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const formatMediaMessage = ({ message, endpoint, mediaParts
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return result;
|
|
9
|
+
* Formats a message with media content (images, documents, videos, audios) to API payload format.
|
|
10
|
+
*
|
|
11
|
+
* @param params - The parameters for formatting.
|
|
12
|
+
* @returns - The formatted message.
|
|
13
|
+
*/
|
|
14
|
+
const formatMediaMessage = ({ message, endpoint, mediaParts }) => {
|
|
15
|
+
const result = {
|
|
16
|
+
...message,
|
|
17
|
+
content: []
|
|
18
|
+
};
|
|
19
|
+
if (endpoint === "anthropic") {
|
|
20
|
+
result.content = [...mediaParts, {
|
|
21
|
+
type: "text",
|
|
22
|
+
text: message.content
|
|
23
|
+
}];
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
result.content = [{
|
|
27
|
+
type: "text",
|
|
28
|
+
text: message.content
|
|
29
|
+
}, ...mediaParts];
|
|
30
|
+
return result;
|
|
32
31
|
};
|
|
33
32
|
function withMessageRole(message, role) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
return roleMessage;
|
|
33
|
+
const roleMessage = message;
|
|
34
|
+
if (roleMessage.role === role) return roleMessage;
|
|
35
|
+
Object.defineProperty(roleMessage, "role", {
|
|
36
|
+
value: role,
|
|
37
|
+
writable: true,
|
|
38
|
+
enumerable: false,
|
|
39
|
+
configurable: true
|
|
40
|
+
});
|
|
41
|
+
return roleMessage;
|
|
45
42
|
}
|
|
46
43
|
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const formatMessage = ({ message, userName, endpoint, assistantName, langChain = false
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const mediaParts = [];
|
|
94
|
-
if (Array.isArray(documents) && documents.length > 0) {
|
|
95
|
-
mediaParts.push(...documents);
|
|
96
|
-
}
|
|
97
|
-
if (Array.isArray(videos) && videos.length > 0) {
|
|
98
|
-
mediaParts.push(...videos);
|
|
99
|
-
}
|
|
100
|
-
if (Array.isArray(audios) && audios.length > 0) {
|
|
101
|
-
mediaParts.push(...audios);
|
|
102
|
-
}
|
|
103
|
-
if (Array.isArray(image_urls) && image_urls.length > 0) {
|
|
104
|
-
mediaParts.push(...image_urls);
|
|
105
|
-
}
|
|
106
|
-
if (mediaParts.length > 0 && role === 'user') {
|
|
107
|
-
const mediaMessage = formatMediaMessage({
|
|
108
|
-
message: {
|
|
109
|
-
...formattedMessage,
|
|
110
|
-
content: typeof formattedMessage.content === 'string'
|
|
111
|
-
? formattedMessage.content
|
|
112
|
-
: '',
|
|
113
|
-
},
|
|
114
|
-
mediaParts,
|
|
115
|
-
endpoint,
|
|
116
|
-
});
|
|
117
|
-
if (!langChain) {
|
|
118
|
-
return mediaMessage;
|
|
119
|
-
}
|
|
120
|
-
return withMessageRole(new HumanMessage(toLangChainMessageFields(mediaMessage)), 'user');
|
|
121
|
-
}
|
|
122
|
-
if (!langChain) {
|
|
123
|
-
return formattedMessage;
|
|
124
|
-
}
|
|
125
|
-
if (role === 'user') {
|
|
126
|
-
return withMessageRole(new HumanMessage(toLangChainMessageFields(formattedMessage)), 'user');
|
|
127
|
-
}
|
|
128
|
-
else if (role === 'assistant') {
|
|
129
|
-
return withMessageRole(new AIMessage(toLangChainMessageFields(formattedMessage)), 'assistant');
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
return withMessageRole(new SystemMessage(toLangChainMessageFields(formattedMessage)), 'system');
|
|
133
|
-
}
|
|
44
|
+
* Formats a message to OpenAI payload format based on the provided options.
|
|
45
|
+
*
|
|
46
|
+
* @param params - The parameters for formatting.
|
|
47
|
+
* @returns - The formatted message.
|
|
48
|
+
*/
|
|
49
|
+
const formatMessage = ({ message, userName, endpoint, assistantName, langChain = false }) => {
|
|
50
|
+
let { role: _role, _name, sender, text, content: _content, lc_id } = message;
|
|
51
|
+
if (lc_id && lc_id[2] && !langChain) _role = {
|
|
52
|
+
SystemMessage: "system",
|
|
53
|
+
HumanMessage: "user",
|
|
54
|
+
AIMessage: "assistant"
|
|
55
|
+
}[lc_id[2]] || _role;
|
|
56
|
+
const role = _role ?? (sender != null && sender && sender.toLowerCase() === "user" ? "user" : "assistant");
|
|
57
|
+
const formattedMessage = {
|
|
58
|
+
role,
|
|
59
|
+
content: _content ?? text ?? ""
|
|
60
|
+
};
|
|
61
|
+
if (_name != null && _name) formattedMessage.name = _name;
|
|
62
|
+
if (userName != null && userName && formattedMessage.role === "user") formattedMessage.name = userName;
|
|
63
|
+
if (assistantName != null && assistantName && formattedMessage.role === "assistant") formattedMessage.name = assistantName;
|
|
64
|
+
if (formattedMessage.name != null && formattedMessage.name) {
|
|
65
|
+
formattedMessage.name = formattedMessage.name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
66
|
+
if (formattedMessage.name.length > 64) formattedMessage.name = formattedMessage.name.substring(0, 64);
|
|
67
|
+
}
|
|
68
|
+
const { image_urls, documents, videos, audios } = message;
|
|
69
|
+
const mediaParts = [];
|
|
70
|
+
if (Array.isArray(documents) && documents.length > 0) mediaParts.push(...documents);
|
|
71
|
+
if (Array.isArray(videos) && videos.length > 0) mediaParts.push(...videos);
|
|
72
|
+
if (Array.isArray(audios) && audios.length > 0) mediaParts.push(...audios);
|
|
73
|
+
if (Array.isArray(image_urls) && image_urls.length > 0) mediaParts.push(...image_urls);
|
|
74
|
+
if (mediaParts.length > 0 && role === "user") {
|
|
75
|
+
const mediaMessage = formatMediaMessage({
|
|
76
|
+
message: {
|
|
77
|
+
...formattedMessage,
|
|
78
|
+
content: typeof formattedMessage.content === "string" ? formattedMessage.content : ""
|
|
79
|
+
},
|
|
80
|
+
mediaParts,
|
|
81
|
+
endpoint
|
|
82
|
+
});
|
|
83
|
+
if (!langChain) return mediaMessage;
|
|
84
|
+
return withMessageRole(new HumanMessage(toLangChainMessageFields(mediaMessage)), "user");
|
|
85
|
+
}
|
|
86
|
+
if (!langChain) return formattedMessage;
|
|
87
|
+
if (role === "user") return withMessageRole(new HumanMessage(toLangChainMessageFields(formattedMessage)), "user");
|
|
88
|
+
else if (role === "assistant") return withMessageRole(new AIMessage(toLangChainMessageFields(formattedMessage)), "assistant");
|
|
89
|
+
else return withMessageRole(new SystemMessage(toLangChainMessageFields(formattedMessage)), "system");
|
|
134
90
|
};
|
|
135
91
|
/**
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
92
|
+
* Formats an array of messages for LangChain.
|
|
93
|
+
*
|
|
94
|
+
* @param messages - The array of messages to format.
|
|
95
|
+
* @param formatOptions - The options for formatting each message.
|
|
96
|
+
* @returns - The array of formatted LangChain messages.
|
|
97
|
+
*/
|
|
142
98
|
const formatLangChainMessages = (messages, formatOptions) => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
});
|
|
99
|
+
return messages.map((msg) => {
|
|
100
|
+
return formatMessage({
|
|
101
|
+
...formatOptions,
|
|
102
|
+
message: msg,
|
|
103
|
+
langChain: true
|
|
104
|
+
});
|
|
105
|
+
});
|
|
151
106
|
};
|
|
152
107
|
/**
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
108
|
+
* Formats a LangChain message object by merging properties from `lc_kwargs` or `kwargs` and `additional_kwargs`.
|
|
109
|
+
*
|
|
110
|
+
* @param message - The message object to format.
|
|
111
|
+
* @returns - The formatted LangChain message.
|
|
112
|
+
*/
|
|
158
113
|
const formatFromLangChain = (message) => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
};
|
|
114
|
+
const { additional_kwargs = {}, ...message_kwargs } = message.lc_kwargs ?? message.kwargs ?? {};
|
|
115
|
+
return {
|
|
116
|
+
...message_kwargs,
|
|
117
|
+
...additional_kwargs
|
|
118
|
+
};
|
|
165
119
|
};
|
|
166
120
|
function extractReasoningContent(part) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
return '';
|
|
121
|
+
if (part == null || typeof part !== "object") return "";
|
|
122
|
+
if (part.type === "think") {
|
|
123
|
+
const think = part.think;
|
|
124
|
+
return typeof think === "string" ? think : "";
|
|
125
|
+
}
|
|
126
|
+
if (part.type === "thinking") {
|
|
127
|
+
const thinking = part.thinking;
|
|
128
|
+
return typeof thinking === "string" ? thinking : "";
|
|
129
|
+
}
|
|
130
|
+
if (part.type === "reasoning") {
|
|
131
|
+
const reasoning = part.reasoning;
|
|
132
|
+
return typeof reasoning === "string" ? reasoning : "";
|
|
133
|
+
}
|
|
134
|
+
if (part.type === "reasoning_content") {
|
|
135
|
+
const reasoningText = part.reasoningText;
|
|
136
|
+
return typeof reasoningText.text === "string" ? reasoningText.text : "";
|
|
137
|
+
}
|
|
138
|
+
return "";
|
|
187
139
|
}
|
|
188
140
|
function parseServerToolInput(args) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
: {};
|
|
197
|
-
}
|
|
198
|
-
catch {
|
|
199
|
-
return {};
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return args != null && typeof args === 'object' ? args : {};
|
|
141
|
+
if (typeof args === "string") try {
|
|
142
|
+
const parsed = JSON.parse(args);
|
|
143
|
+
return parsed != null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
144
|
+
} catch {
|
|
145
|
+
return {};
|
|
146
|
+
}
|
|
147
|
+
return args != null && typeof args === "object" ? args : {};
|
|
203
148
|
}
|
|
204
149
|
function getTextContent(part) {
|
|
205
|
-
|
|
206
|
-
|
|
150
|
+
const { text } = part;
|
|
151
|
+
return typeof text === "string" ? text : "";
|
|
207
152
|
}
|
|
208
153
|
function hasMeaningfulAssistantContent(part) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
part.type === ContentTypes.ERROR ||
|
|
214
|
-
part.type === ContentTypes.AGENT_UPDATE ||
|
|
215
|
-
part.type === ContentTypes.SUMMARY) {
|
|
216
|
-
return false;
|
|
217
|
-
}
|
|
218
|
-
if (part.type === ContentTypes.THINK ||
|
|
219
|
-
part.type === ContentTypes.THINKING ||
|
|
220
|
-
part.type === ContentTypes.REASONING ||
|
|
221
|
-
part.type === ContentTypes.REASONING_CONTENT ||
|
|
222
|
-
part.type === 'redacted_thinking') {
|
|
223
|
-
return extractReasoningContent(part).trim().length > 0;
|
|
224
|
-
}
|
|
225
|
-
return part.type != null && part.type !== '';
|
|
154
|
+
if (part.type === "text") return getTextContent(part).trim().length > 0;
|
|
155
|
+
if (part.type === "tool_call" || part.type === "error" || part.type === "agent_update" || part.type === "summary") return false;
|
|
156
|
+
if (part.type === "think" || part.type === "thinking" || part.type === "reasoning" || part.type === "reasoning_content" || part.type === "redacted_thinking") return extractReasoningContent(part).trim().length > 0;
|
|
157
|
+
return part.type != null && part.type !== "";
|
|
226
158
|
}
|
|
227
159
|
function getToolUseId(part) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
return part.tool_use_id;
|
|
160
|
+
if (!("tool_use_id" in part) || typeof part.tool_use_id !== "string") return;
|
|
161
|
+
return part.tool_use_id;
|
|
232
162
|
}
|
|
233
163
|
function isValidServerToolResult(part) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
const { content } = part;
|
|
240
|
-
return (Array.isArray(content) ||
|
|
241
|
-
(content != null &&
|
|
242
|
-
typeof content === 'object' &&
|
|
243
|
-
'type' in content &&
|
|
244
|
-
content.type === 'web_search_tool_result_error'));
|
|
164
|
+
if (getToolUseId(part)?.startsWith("srvtoolu_") !== true || !("content" in part)) return false;
|
|
165
|
+
const { content } = part;
|
|
166
|
+
return Array.isArray(content) || content != null && typeof content === "object" && "type" in content && content.type === "web_search_tool_result_error";
|
|
245
167
|
}
|
|
246
168
|
function getToolCallId(part) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const id = part.tool_call?.id;
|
|
251
|
-
return typeof id === 'string' && id !== '' ? id : undefined;
|
|
169
|
+
if (part.type !== "tool_call") return;
|
|
170
|
+
const id = part.tool_call?.id;
|
|
171
|
+
return typeof id === "string" && id !== "" ? id : void 0;
|
|
252
172
|
}
|
|
253
173
|
function hasToolCallOutput(part) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const output = part.tool_call?.output;
|
|
258
|
-
return output != null && output !== '';
|
|
174
|
+
if (part.type !== "tool_call") return false;
|
|
175
|
+
const output = part.tool_call?.output;
|
|
176
|
+
return output != null && output !== "";
|
|
259
177
|
}
|
|
260
178
|
/**
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
179
|
+
* Helper function to format an assistant message
|
|
180
|
+
* @param message The message to format
|
|
181
|
+
* @param options Optional formatting options
|
|
182
|
+
* @returns Array of formatted messages
|
|
183
|
+
*/
|
|
266
184
|
function formatAssistantMessage(message, options) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
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
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
-
if (!lastAIMessage) {
|
|
426
|
-
// "Heal" the payload by creating an AIMessage to precede the tool call
|
|
427
|
-
lastAIMessage = createAIMessage('');
|
|
428
|
-
formattedMessages.push(lastAIMessage);
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
attachPendingReasoningContent(lastAIMessage);
|
|
432
|
-
}
|
|
433
|
-
const tool_call = _tool_call;
|
|
434
|
-
// TODO: investigate; args as dictionary may need to be providers-or-tool-specific
|
|
435
|
-
let args = _args;
|
|
436
|
-
try {
|
|
437
|
-
if (typeof _args === 'string') {
|
|
438
|
-
args = JSON.parse(_args);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
catch {
|
|
442
|
-
if (typeof _args === 'string') {
|
|
443
|
-
args = { input: _args };
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
tool_call.args = args;
|
|
447
|
-
if (options?.provider === Providers.ANTHROPIC &&
|
|
448
|
-
Array.isArray(lastAIMessage.content)) {
|
|
449
|
-
const content = lastAIMessage.content;
|
|
450
|
-
content.push({
|
|
451
|
-
type: 'tool_use',
|
|
452
|
-
id: normalizeAnthropicToolCallId(tool_call.id ?? ''),
|
|
453
|
-
name: tool_call.name,
|
|
454
|
-
input: args,
|
|
455
|
-
});
|
|
456
|
-
lastAIMessage.content = content;
|
|
457
|
-
}
|
|
458
|
-
else {
|
|
459
|
-
if (!lastAIMessage.tool_calls) {
|
|
460
|
-
lastAIMessage.tool_calls = [];
|
|
461
|
-
}
|
|
462
|
-
lastAIMessage.tool_calls.push(tool_call);
|
|
463
|
-
}
|
|
464
|
-
formattedMessages.push(withMessageRole(new ToolMessage({
|
|
465
|
-
tool_call_id: tool_call.id ?? '',
|
|
466
|
-
name: tool_call.name,
|
|
467
|
-
content: output != null ? output : '',
|
|
468
|
-
}), 'tool'));
|
|
469
|
-
}
|
|
470
|
-
else if (part.type === ContentTypes.THINK ||
|
|
471
|
-
part.type === ContentTypes.THINKING ||
|
|
472
|
-
part.type === ContentTypes.REASONING ||
|
|
473
|
-
part.type === ContentTypes.REASONING_CONTENT ||
|
|
474
|
-
part.type === 'redacted_thinking') {
|
|
475
|
-
hasReasoning = true;
|
|
476
|
-
pendingReasoningContent += extractReasoningContent(part);
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
else if (part.type === ContentTypes.ERROR ||
|
|
480
|
-
part.type === ContentTypes.AGENT_UPDATE ||
|
|
481
|
-
part.type === ContentTypes.SUMMARY) {
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
else {
|
|
485
|
-
if (part.type === ContentTypes.TEXT && !getTextContent(part).trim()) {
|
|
486
|
-
continue;
|
|
487
|
-
}
|
|
488
|
-
currentContent.push(part);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
for (const content of pendingServerToolUses.values()) {
|
|
492
|
-
currentContent.push(content);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
if (hasReasoning && currentContent.length > 0) {
|
|
496
|
-
let content = '';
|
|
497
|
-
for (const part of currentContent) {
|
|
498
|
-
if (part.type !== ContentTypes.TEXT) {
|
|
499
|
-
formattedMessages.push(createAIMessage(toLangChainContent(currentContent)));
|
|
500
|
-
return formattedMessages;
|
|
501
|
-
}
|
|
502
|
-
content += `${getTextContent(part)}\n`;
|
|
503
|
-
}
|
|
504
|
-
content = content.trim();
|
|
505
|
-
if (content) {
|
|
506
|
-
formattedMessages.push(createAIMessage(content));
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
else if (currentContent.length > 0) {
|
|
510
|
-
formattedMessages.push(createAIMessage(toLangChainContent(currentContent)));
|
|
511
|
-
}
|
|
512
|
-
return formattedMessages;
|
|
185
|
+
const formattedMessages = [];
|
|
186
|
+
let currentContent = [];
|
|
187
|
+
let lastAIMessage = null;
|
|
188
|
+
let hasReasoning = false;
|
|
189
|
+
let pendingReasoningContent = "";
|
|
190
|
+
const emittedServerToolUseIds = /* @__PURE__ */ new Set();
|
|
191
|
+
const pendingServerToolUses = /* @__PURE__ */ new Map();
|
|
192
|
+
const shouldPreserveReasoningContent = options?.preserveReasoningContent === true;
|
|
193
|
+
const serverToolResultIds = /* @__PURE__ */ new Set();
|
|
194
|
+
const preferredToolCallParts = /* @__PURE__ */ new Map();
|
|
195
|
+
const takePendingReasoningContent = () => {
|
|
196
|
+
if (!shouldPreserveReasoningContent || !pendingReasoningContent) return;
|
|
197
|
+
const reasoningContent = pendingReasoningContent;
|
|
198
|
+
pendingReasoningContent = "";
|
|
199
|
+
return reasoningContent;
|
|
200
|
+
};
|
|
201
|
+
const createAIMessage = (content) => {
|
|
202
|
+
const reasoningContent = takePendingReasoningContent();
|
|
203
|
+
return withMessageRole(new AIMessage({
|
|
204
|
+
content,
|
|
205
|
+
...reasoningContent != null && { additional_kwargs: { reasoning_content: reasoningContent } }
|
|
206
|
+
}), "assistant");
|
|
207
|
+
};
|
|
208
|
+
const attachPendingReasoningContent = (aiMessage) => {
|
|
209
|
+
const reasoningContent = takePendingReasoningContent();
|
|
210
|
+
if (reasoningContent == null) return;
|
|
211
|
+
aiMessage.additional_kwargs.reasoning_content = typeof aiMessage.additional_kwargs.reasoning_content === "string" ? `${aiMessage.additional_kwargs.reasoning_content}${reasoningContent}` : reasoningContent;
|
|
212
|
+
};
|
|
213
|
+
const flushPendingServerToolUse = (toolUseId) => {
|
|
214
|
+
for (const [id, content] of pendingServerToolUses) {
|
|
215
|
+
pendingServerToolUses.delete(id);
|
|
216
|
+
if (id === toolUseId) {
|
|
217
|
+
currentContent.push(content);
|
|
218
|
+
emittedServerToolUseIds.add(id);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
if (Array.isArray(message.content)) {
|
|
224
|
+
const contentParts = message.content;
|
|
225
|
+
for (const part of contentParts) {
|
|
226
|
+
if (part == null) continue;
|
|
227
|
+
if (isValidServerToolResult(part)) serverToolResultIds.add(getToolUseId(part) ?? "");
|
|
228
|
+
if (options?.provider === "anthropic") {
|
|
229
|
+
const toolCallId = getToolCallId(part);
|
|
230
|
+
if (toolCallId == null) continue;
|
|
231
|
+
const preferredPart = preferredToolCallParts.get(toolCallId);
|
|
232
|
+
if (preferredPart == null || !hasToolCallOutput(preferredPart) && hasToolCallOutput(part)) preferredToolCallParts.set(toolCallId, part);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
for (const part of contentParts) {
|
|
236
|
+
if (part == null) continue;
|
|
237
|
+
const toolUseId = getToolUseId(part);
|
|
238
|
+
if (toolUseId != null) {
|
|
239
|
+
const isServerToolResult = isValidServerToolResult(part);
|
|
240
|
+
if (toolUseId.startsWith("srvtoolu_") && !isServerToolResult) continue;
|
|
241
|
+
flushPendingServerToolUse(toolUseId);
|
|
242
|
+
if (isServerToolResult) {
|
|
243
|
+
currentContent.push(part);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
} else if (hasMeaningfulAssistantContent(part)) {
|
|
247
|
+
for (const id of pendingServerToolUses.keys()) if (!serverToolResultIds.has(id)) pendingServerToolUses.delete(id);
|
|
248
|
+
}
|
|
249
|
+
if (part.type === "text" && part.tool_call_ids) {
|
|
250
|
+
if (currentContent.length > 0) {
|
|
251
|
+
if (currentContent.some((content) => content.type !== "text")) {
|
|
252
|
+
currentContent.push(part);
|
|
253
|
+
lastAIMessage = createAIMessage(toLangChainContent(currentContent));
|
|
254
|
+
formattedMessages.push(lastAIMessage);
|
|
255
|
+
currentContent = [];
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
let content = currentContent.reduce((acc, curr) => {
|
|
259
|
+
if (curr.type === "text") return `${acc}${getTextContent(curr)}\n`;
|
|
260
|
+
return acc;
|
|
261
|
+
}, "");
|
|
262
|
+
content = `${content}\n${getTextContent(part)}`.trim();
|
|
263
|
+
lastAIMessage = createAIMessage(content);
|
|
264
|
+
formattedMessages.push(lastAIMessage);
|
|
265
|
+
currentContent = [];
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
lastAIMessage = createAIMessage(getTextContent(part));
|
|
269
|
+
formattedMessages.push(lastAIMessage);
|
|
270
|
+
} else if (part.type === "tool_call") {
|
|
271
|
+
if (part.tool_call == null) continue;
|
|
272
|
+
const toolCallId = getToolCallId(part);
|
|
273
|
+
if (options?.provider === "anthropic" && toolCallId != null && preferredToolCallParts.get(toolCallId) !== part) continue;
|
|
274
|
+
const { output, args: _args, ..._tool_call } = part.tool_call;
|
|
275
|
+
if (_tool_call.name == null || _tool_call.name === "" && (output == null || output === "")) continue;
|
|
276
|
+
if (options?.provider === "anthropic" && typeof _tool_call.id === "string" && _tool_call.id.startsWith("srvtoolu_")) {
|
|
277
|
+
if (!serverToolResultIds.has(_tool_call.id) && options.preserveUnpairedServerToolUses !== true) continue;
|
|
278
|
+
if (emittedServerToolUseIds.has(_tool_call.id) || pendingServerToolUses.has(_tool_call.id)) continue;
|
|
279
|
+
pendingServerToolUses.set(_tool_call.id, {
|
|
280
|
+
type: "server_tool_use",
|
|
281
|
+
id: _tool_call.id,
|
|
282
|
+
name: _tool_call.name,
|
|
283
|
+
input: parseServerToolInput(_args)
|
|
284
|
+
});
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (!lastAIMessage) {
|
|
288
|
+
lastAIMessage = createAIMessage("");
|
|
289
|
+
formattedMessages.push(lastAIMessage);
|
|
290
|
+
} else attachPendingReasoningContent(lastAIMessage);
|
|
291
|
+
const tool_call = _tool_call;
|
|
292
|
+
let args = _args;
|
|
293
|
+
try {
|
|
294
|
+
if (typeof _args === "string") args = JSON.parse(_args);
|
|
295
|
+
} catch {
|
|
296
|
+
if (typeof _args === "string") args = { input: _args };
|
|
297
|
+
}
|
|
298
|
+
tool_call.args = args;
|
|
299
|
+
if (options?.provider === "anthropic" && Array.isArray(lastAIMessage.content)) {
|
|
300
|
+
const content = lastAIMessage.content;
|
|
301
|
+
content.push({
|
|
302
|
+
type: "tool_use",
|
|
303
|
+
id: normalizeAnthropicToolCallId(tool_call.id ?? ""),
|
|
304
|
+
name: tool_call.name,
|
|
305
|
+
input: args
|
|
306
|
+
});
|
|
307
|
+
lastAIMessage.content = content;
|
|
308
|
+
} else {
|
|
309
|
+
if (!lastAIMessage.tool_calls) lastAIMessage.tool_calls = [];
|
|
310
|
+
lastAIMessage.tool_calls.push(tool_call);
|
|
311
|
+
}
|
|
312
|
+
formattedMessages.push(withMessageRole(new ToolMessage({
|
|
313
|
+
tool_call_id: tool_call.id ?? "",
|
|
314
|
+
name: tool_call.name,
|
|
315
|
+
content: output != null ? output : ""
|
|
316
|
+
}), "tool"));
|
|
317
|
+
} else if (part.type === "think" || part.type === "thinking" || part.type === "reasoning" || part.type === "reasoning_content" || part.type === "redacted_thinking") {
|
|
318
|
+
hasReasoning = true;
|
|
319
|
+
pendingReasoningContent += extractReasoningContent(part);
|
|
320
|
+
continue;
|
|
321
|
+
} else if (part.type === "error" || part.type === "agent_update" || part.type === "summary") continue;
|
|
322
|
+
else {
|
|
323
|
+
if (part.type === "text" && !getTextContent(part).trim()) continue;
|
|
324
|
+
currentContent.push(part);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
for (const content of pendingServerToolUses.values()) currentContent.push(content);
|
|
328
|
+
}
|
|
329
|
+
if (hasReasoning && currentContent.length > 0) {
|
|
330
|
+
let content = "";
|
|
331
|
+
for (const part of currentContent) {
|
|
332
|
+
if (part.type !== "text") {
|
|
333
|
+
formattedMessages.push(createAIMessage(toLangChainContent(currentContent)));
|
|
334
|
+
return formattedMessages;
|
|
335
|
+
}
|
|
336
|
+
content += `${getTextContent(part)}\n`;
|
|
337
|
+
}
|
|
338
|
+
content = content.trim();
|
|
339
|
+
if (content) formattedMessages.push(createAIMessage(content));
|
|
340
|
+
} else if (currentContent.length > 0) formattedMessages.push(createAIMessage(toLangChainContent(currentContent)));
|
|
341
|
+
return formattedMessages;
|
|
513
342
|
}
|
|
514
343
|
function getSourceMessageId(message) {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
const normalized = candidate.trim();
|
|
521
|
-
return normalized.length > 0 ? normalized : undefined;
|
|
344
|
+
const candidate = message.messageId ?? message.id;
|
|
345
|
+
if (typeof candidate !== "string") return;
|
|
346
|
+
const normalized = candidate.trim();
|
|
347
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
522
348
|
}
|
|
523
349
|
/**
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
350
|
+
* Labels all agent content for parallel patterns (fan-out/fan-in)
|
|
351
|
+
* Groups consecutive content by agent and wraps with clear labels
|
|
352
|
+
*/
|
|
527
353
|
function labelAllAgentContent(contentParts, agentIdMap, agentNames) {
|
|
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
|
-
else {
|
|
570
|
-
// No agent ID, pass through as-is
|
|
571
|
-
result.push(...agentContentBuffer);
|
|
572
|
-
}
|
|
573
|
-
agentContentBuffer = [];
|
|
574
|
-
};
|
|
575
|
-
for (let i = 0; i < contentParts.length; i++) {
|
|
576
|
-
const part = contentParts[i];
|
|
577
|
-
const agentId = agentIdMap[i];
|
|
578
|
-
// If agent changed, flush previous buffer
|
|
579
|
-
if (agentId !== currentAgentId && currentAgentId !== undefined) {
|
|
580
|
-
flushAgentBuffer();
|
|
581
|
-
}
|
|
582
|
-
currentAgentId = agentId;
|
|
583
|
-
agentContentBuffer.push(part);
|
|
584
|
-
}
|
|
585
|
-
// Flush any remaining content
|
|
586
|
-
flushAgentBuffer();
|
|
587
|
-
return result;
|
|
354
|
+
const result = [];
|
|
355
|
+
let currentAgentId;
|
|
356
|
+
let agentContentBuffer = [];
|
|
357
|
+
const flushAgentBuffer = () => {
|
|
358
|
+
if (agentContentBuffer.length === 0) return;
|
|
359
|
+
if (currentAgentId != null && currentAgentId !== "") {
|
|
360
|
+
const agentName = (agentNames?.[currentAgentId] ?? "") || currentAgentId;
|
|
361
|
+
const formattedParts = [];
|
|
362
|
+
formattedParts.push(`--- ${agentName} ---`);
|
|
363
|
+
for (const part of agentContentBuffer) if (part.type === "think") {
|
|
364
|
+
const thinkContent = part.think || "";
|
|
365
|
+
if (thinkContent) formattedParts.push(`${agentName}: ${JSON.stringify({
|
|
366
|
+
type: "think",
|
|
367
|
+
think: thinkContent
|
|
368
|
+
})}`);
|
|
369
|
+
} else if (part.type === "text") {
|
|
370
|
+
const textContent = part.text ?? "";
|
|
371
|
+
if (textContent) formattedParts.push(`${agentName}: ${textContent}`);
|
|
372
|
+
} else if (part.type === "tool_call") formattedParts.push(`${agentName}: ${JSON.stringify({
|
|
373
|
+
type: "tool_call",
|
|
374
|
+
tool_call: part.tool_call
|
|
375
|
+
})}`);
|
|
376
|
+
formattedParts.push(`--- End of ${agentName} ---`);
|
|
377
|
+
result.push({
|
|
378
|
+
type: "text",
|
|
379
|
+
text: formattedParts.join("\n\n")
|
|
380
|
+
});
|
|
381
|
+
} else result.push(...agentContentBuffer);
|
|
382
|
+
agentContentBuffer = [];
|
|
383
|
+
};
|
|
384
|
+
for (let i = 0; i < contentParts.length; i++) {
|
|
385
|
+
const part = contentParts[i];
|
|
386
|
+
const agentId = agentIdMap[i];
|
|
387
|
+
if (agentId !== currentAgentId && currentAgentId !== void 0) flushAgentBuffer();
|
|
388
|
+
currentAgentId = agentId;
|
|
389
|
+
agentContentBuffer.push(part);
|
|
390
|
+
}
|
|
391
|
+
flushAgentBuffer();
|
|
392
|
+
return result;
|
|
588
393
|
}
|
|
589
394
|
/**
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
395
|
+
* Groups content parts by agent and formats them with agent labels
|
|
396
|
+
* This preprocesses multi-agent content to prevent identity confusion
|
|
397
|
+
*
|
|
398
|
+
* @param contentParts - The content parts from a run
|
|
399
|
+
* @param agentIdMap - Map of content part index to agent ID
|
|
400
|
+
* @param agentNames - Optional map of agent ID to display name
|
|
401
|
+
* @param options - Configuration options
|
|
402
|
+
* @param options.labelNonTransferContent - If true, labels all agent transitions (for parallel patterns)
|
|
403
|
+
* @returns Modified content parts with agent labels where appropriate
|
|
404
|
+
*/
|
|
600
405
|
const labelContentByAgent = (contentParts, agentIdMap, agentNames, options) => {
|
|
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
|
-
else {
|
|
658
|
-
// Not from a transfer, add as-is
|
|
659
|
-
result.push(...agentContentBuffer);
|
|
660
|
-
}
|
|
661
|
-
agentContentBuffer = [];
|
|
662
|
-
transferToolCallIndex = undefined;
|
|
663
|
-
transferToolCallId = undefined;
|
|
664
|
-
};
|
|
665
|
-
for (let i = 0; i < contentParts.length; i++) {
|
|
666
|
-
const part = contentParts[i];
|
|
667
|
-
const agentId = agentIdMap[i];
|
|
668
|
-
// Check if this is a transfer tool call
|
|
669
|
-
const isTransferTool = (part.type === ContentTypes.TOOL_CALL &&
|
|
670
|
-
part.tool_call?.name?.startsWith('lc_transfer_to_')) ??
|
|
671
|
-
false;
|
|
672
|
-
// If agent changed, flush previous buffer
|
|
673
|
-
if (agentId !== currentAgentId && currentAgentId !== undefined) {
|
|
674
|
-
flushAgentBuffer();
|
|
675
|
-
}
|
|
676
|
-
currentAgentId = agentId;
|
|
677
|
-
if (isTransferTool) {
|
|
678
|
-
// Flush any existing buffer first
|
|
679
|
-
flushAgentBuffer();
|
|
680
|
-
// Add the transfer tool call to result
|
|
681
|
-
result.push(part);
|
|
682
|
-
// Mark that the next agent's content should be captured
|
|
683
|
-
transferToolCallIndex = result.length - 1;
|
|
684
|
-
transferToolCallId = part.tool_call?.id;
|
|
685
|
-
currentAgentId = undefined; // Reset to capture the next agent
|
|
686
|
-
}
|
|
687
|
-
else {
|
|
688
|
-
agentContentBuffer.push(part);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
flushAgentBuffer();
|
|
692
|
-
return result;
|
|
406
|
+
if (!agentIdMap || Object.keys(agentIdMap).length === 0) return contentParts;
|
|
407
|
+
if (options?.labelNonTransferContent === true) return labelAllAgentContent(contentParts, agentIdMap, agentNames);
|
|
408
|
+
const result = [];
|
|
409
|
+
let currentAgentId;
|
|
410
|
+
let agentContentBuffer = [];
|
|
411
|
+
let transferToolCallIndex;
|
|
412
|
+
let transferToolCallId;
|
|
413
|
+
const flushAgentBuffer = () => {
|
|
414
|
+
if (agentContentBuffer.length === 0) return;
|
|
415
|
+
if (currentAgentId != null && currentAgentId !== "" && transferToolCallIndex !== void 0) {
|
|
416
|
+
const agentName = (agentNames?.[currentAgentId] ?? "") || currentAgentId;
|
|
417
|
+
const formattedParts = [];
|
|
418
|
+
formattedParts.push(`--- Transfer to ${agentName} ---`);
|
|
419
|
+
for (const part of agentContentBuffer) if (part.type === "think") formattedParts.push(`${agentName}: ${JSON.stringify({
|
|
420
|
+
type: "think",
|
|
421
|
+
think: part.think
|
|
422
|
+
})}`);
|
|
423
|
+
else if ("text" in part && part.type === "text") {
|
|
424
|
+
const textContent = part.text ?? "";
|
|
425
|
+
if (textContent) formattedParts.push(`${agentName}: ${JSON.stringify({
|
|
426
|
+
type: "text",
|
|
427
|
+
text: textContent
|
|
428
|
+
})}`);
|
|
429
|
+
} else if (part.type === "tool_call") formattedParts.push(`${agentName}: ${JSON.stringify({
|
|
430
|
+
type: "tool_call",
|
|
431
|
+
tool_call: part.tool_call
|
|
432
|
+
})}`);
|
|
433
|
+
formattedParts.push(`--- End of ${agentName} response ---`);
|
|
434
|
+
if (transferToolCallIndex < result.length) {
|
|
435
|
+
const transferToolCall = result[transferToolCallIndex];
|
|
436
|
+
if (transferToolCall.type === "tool_call" && transferToolCall.tool_call?.id === transferToolCallId) transferToolCall.tool_call.output = formattedParts.join("\n\n");
|
|
437
|
+
}
|
|
438
|
+
} else result.push(...agentContentBuffer);
|
|
439
|
+
agentContentBuffer = [];
|
|
440
|
+
transferToolCallIndex = void 0;
|
|
441
|
+
transferToolCallId = void 0;
|
|
442
|
+
};
|
|
443
|
+
for (let i = 0; i < contentParts.length; i++) {
|
|
444
|
+
const part = contentParts[i];
|
|
445
|
+
const agentId = agentIdMap[i];
|
|
446
|
+
const isTransferTool = (part.type === "tool_call" && part.tool_call?.name?.startsWith("lc_transfer_to_")) ?? false;
|
|
447
|
+
if (agentId !== currentAgentId && currentAgentId !== void 0) flushAgentBuffer();
|
|
448
|
+
currentAgentId = agentId;
|
|
449
|
+
if (isTransferTool) {
|
|
450
|
+
flushAgentBuffer();
|
|
451
|
+
result.push(part);
|
|
452
|
+
transferToolCallIndex = result.length - 1;
|
|
453
|
+
transferToolCallId = part.tool_call?.id;
|
|
454
|
+
currentAgentId = void 0;
|
|
455
|
+
} else agentContentBuffer.push(part);
|
|
456
|
+
}
|
|
457
|
+
flushAgentBuffer();
|
|
458
|
+
return result;
|
|
693
459
|
};
|
|
694
460
|
/** Extracts tool names from a tool_search output JSON string. */
|
|
695
461
|
function extractToolNamesFromSearchOutput(output) {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
const jsonMatch = output.match(/\{[\s\S]*\}/);
|
|
709
|
-
if (jsonMatch) {
|
|
710
|
-
try {
|
|
711
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
712
|
-
if (typeof parsed === 'object' &&
|
|
713
|
-
parsed !== null &&
|
|
714
|
-
Array.isArray(parsed.tools)) {
|
|
715
|
-
return parsed.tools
|
|
716
|
-
.map((t) => t.name)
|
|
717
|
-
.filter((name) => typeof name === 'string');
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
catch {
|
|
721
|
-
/* ignore */
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
return [];
|
|
462
|
+
try {
|
|
463
|
+
const parsed = JSON.parse(output);
|
|
464
|
+
if (typeof parsed === "object" && parsed !== null && Array.isArray(parsed.tools)) return parsed.tools.map((t) => t.name).filter((name) => typeof name === "string");
|
|
465
|
+
} catch {
|
|
466
|
+
/** Output may have warnings prepended, try to find JSON within it */
|
|
467
|
+
const jsonMatch = output.match(/\{[\s\S]*\}/);
|
|
468
|
+
if (jsonMatch) try {
|
|
469
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
470
|
+
if (typeof parsed === "object" && parsed !== null && Array.isArray(parsed.tools)) return parsed.tools.map((t) => t.name).filter((name) => typeof name === "string");
|
|
471
|
+
} catch {}
|
|
472
|
+
}
|
|
473
|
+
return [];
|
|
726
474
|
}
|
|
727
475
|
function getLatestSummaryBoundary(payload) {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
749
|
-
if (summaryText.length === 0) {
|
|
750
|
-
continue;
|
|
751
|
-
}
|
|
752
|
-
summaryBoundary = {
|
|
753
|
-
messageIndex: i,
|
|
754
|
-
contentIndex: j,
|
|
755
|
-
text: summaryText,
|
|
756
|
-
tokenCount: typeof summaryPart.tokenCount === 'number' &&
|
|
757
|
-
Number.isFinite(summaryPart.tokenCount)
|
|
758
|
-
? summaryPart.tokenCount
|
|
759
|
-
: 0,
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
return summaryBoundary;
|
|
476
|
+
let summaryBoundary;
|
|
477
|
+
for (let i = 0; i < payload.length; i++) {
|
|
478
|
+
const message = payload[i];
|
|
479
|
+
if (!Array.isArray(message.content)) continue;
|
|
480
|
+
for (let j = 0; j < message.content.length; j++) {
|
|
481
|
+
const part = message.content[j];
|
|
482
|
+
if (part == null || part.type !== "summary") continue;
|
|
483
|
+
const summaryPart = part;
|
|
484
|
+
let summaryText = (summaryPart.content ?? []).map((block) => "text" in block ? block.text : "").join("").trim();
|
|
485
|
+
if (summaryText.length === 0 && typeof summaryPart.text === "string") summaryText = summaryPart.text.trim();
|
|
486
|
+
if (summaryText.length === 0) continue;
|
|
487
|
+
summaryBoundary = {
|
|
488
|
+
messageIndex: i,
|
|
489
|
+
contentIndex: j,
|
|
490
|
+
text: summaryText,
|
|
491
|
+
tokenCount: typeof summaryPart.tokenCount === "number" && Number.isFinite(summaryPart.tokenCount) ? summaryPart.tokenCount : 0
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return summaryBoundary;
|
|
764
496
|
}
|
|
765
497
|
function applySummaryBoundary(message, messageIndex, summaryBoundary) {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
!Array.isArray(message.content)) {
|
|
774
|
-
return message;
|
|
775
|
-
}
|
|
776
|
-
return {
|
|
777
|
-
...message,
|
|
778
|
-
content: message.content.slice(summaryBoundary.contentIndex + 1),
|
|
779
|
-
};
|
|
498
|
+
if (!summaryBoundary) return message;
|
|
499
|
+
if (messageIndex < summaryBoundary.messageIndex) return null;
|
|
500
|
+
if (messageIndex !== summaryBoundary.messageIndex || !Array.isArray(message.content)) return message;
|
|
501
|
+
return {
|
|
502
|
+
...message,
|
|
503
|
+
content: message.content.slice(summaryBoundary.contentIndex + 1)
|
|
504
|
+
};
|
|
780
505
|
}
|
|
781
506
|
function contentPartCharLength(part) {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
const { input } = record;
|
|
791
|
-
if (typeof input === 'string') {
|
|
792
|
-
len += input.length;
|
|
793
|
-
}
|
|
794
|
-
else if (input != null && typeof input === 'object') {
|
|
795
|
-
len += JSON.stringify(input).length;
|
|
796
|
-
}
|
|
797
|
-
return len;
|
|
507
|
+
const record = part;
|
|
508
|
+
let len = 0;
|
|
509
|
+
if (typeof record.text === "string") len += record.text.length;
|
|
510
|
+
if (typeof record.thinking === "string") len += record.thinking.length;
|
|
511
|
+
const { input } = record;
|
|
512
|
+
if (typeof input === "string") len += input.length;
|
|
513
|
+
else if (input != null && typeof input === "object") len += JSON.stringify(input).length;
|
|
514
|
+
return len;
|
|
798
515
|
}
|
|
799
516
|
/** Extracts the skillName from a skill tool_call's args (string or object). */
|
|
800
517
|
function extractSkillName(args) {
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
else {
|
|
811
|
-
parsed = args;
|
|
812
|
-
}
|
|
813
|
-
const name = parsed?.skillName;
|
|
814
|
-
return typeof name === 'string' && name !== '' ? name : undefined;
|
|
518
|
+
let parsed;
|
|
519
|
+
if (typeof args === "string") try {
|
|
520
|
+
parsed = JSON.parse(args);
|
|
521
|
+
} catch {}
|
|
522
|
+
else parsed = args;
|
|
523
|
+
const name = parsed?.skillName;
|
|
524
|
+
return typeof name === "string" && name !== "" ? name : void 0;
|
|
815
525
|
}
|
|
816
526
|
/**
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
const formatAgentMessages = (payload, indexTokenCountMap, tools,
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
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
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
for (let p = 0; p < content.length; p++) {
|
|
1070
|
-
const charLen = contentPartCharLength(content[p]);
|
|
1071
|
-
totalCharLen += charLen;
|
|
1072
|
-
if (p > contentIndex) {
|
|
1073
|
-
remainingCharLen += charLen;
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
if (totalCharLen > 0) {
|
|
1077
|
-
const original = tokenCount;
|
|
1078
|
-
tokenCount = Math.max(1, Math.round(tokenCount * (remainingCharLen / totalCharLen)));
|
|
1079
|
-
boundaryTokenAdjustment = {
|
|
1080
|
-
original,
|
|
1081
|
-
adjusted: tokenCount,
|
|
1082
|
-
remainingChars: remainingCharLen,
|
|
1083
|
-
totalChars: totalCharLen,
|
|
1084
|
-
};
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
const msgCount = resultIndices.length;
|
|
1089
|
-
if (msgCount === 1) {
|
|
1090
|
-
updatedIndexTokenCountMap[resultIndices[0]] = tokenCount;
|
|
1091
|
-
continue;
|
|
1092
|
-
}
|
|
1093
|
-
if (msgCount < 2) {
|
|
1094
|
-
continue;
|
|
1095
|
-
}
|
|
1096
|
-
let totalLength = 0;
|
|
1097
|
-
const lastIdx = msgCount - 1;
|
|
1098
|
-
const lengths = new Array(msgCount);
|
|
1099
|
-
for (let k = 0; k < msgCount; k++) {
|
|
1100
|
-
const msg = messages[resultIndices[k]];
|
|
1101
|
-
const { content } = msg;
|
|
1102
|
-
let len = 0;
|
|
1103
|
-
if (typeof content === 'string') {
|
|
1104
|
-
len = content.length;
|
|
1105
|
-
}
|
|
1106
|
-
else if (Array.isArray(content)) {
|
|
1107
|
-
for (const part of content) {
|
|
1108
|
-
if (typeof part === 'string') {
|
|
1109
|
-
len += part.length;
|
|
1110
|
-
}
|
|
1111
|
-
else if (part != null && typeof part === 'object') {
|
|
1112
|
-
const val = part.text ?? part.content;
|
|
1113
|
-
if (typeof val === 'string') {
|
|
1114
|
-
len += val.length;
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
const toolCalls = msg.tool_calls;
|
|
1120
|
-
if (Array.isArray(toolCalls)) {
|
|
1121
|
-
for (const tc of toolCalls) {
|
|
1122
|
-
if (typeof tc.name === 'string') {
|
|
1123
|
-
len += tc.name.length;
|
|
1124
|
-
}
|
|
1125
|
-
const { args } = tc;
|
|
1126
|
-
if (typeof args === 'string') {
|
|
1127
|
-
len += args.length;
|
|
1128
|
-
}
|
|
1129
|
-
else if (args != null) {
|
|
1130
|
-
len += JSON.stringify(args).length;
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
lengths[k] = len;
|
|
1135
|
-
totalLength += len;
|
|
1136
|
-
}
|
|
1137
|
-
if (totalLength === 0) {
|
|
1138
|
-
const countPerMessage = Math.floor(tokenCount / msgCount);
|
|
1139
|
-
for (let k = 0; k < lastIdx; k++) {
|
|
1140
|
-
updatedIndexTokenCountMap[resultIndices[k]] = countPerMessage;
|
|
1141
|
-
}
|
|
1142
|
-
updatedIndexTokenCountMap[resultIndices[lastIdx]] =
|
|
1143
|
-
tokenCount - countPerMessage * lastIdx;
|
|
1144
|
-
}
|
|
1145
|
-
else {
|
|
1146
|
-
let distributed = 0;
|
|
1147
|
-
for (let k = 0; k < lastIdx; k++) {
|
|
1148
|
-
const share = Math.floor((lengths[k] / totalLength) * tokenCount);
|
|
1149
|
-
updatedIndexTokenCountMap[resultIndices[k]] = share;
|
|
1150
|
-
distributed += share;
|
|
1151
|
-
}
|
|
1152
|
-
updatedIndexTokenCountMap[resultIndices[lastIdx]] =
|
|
1153
|
-
tokenCount - distributed;
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
return {
|
|
1158
|
-
messages,
|
|
1159
|
-
indexTokenCountMap: indexTokenCountMap
|
|
1160
|
-
? updatedIndexTokenCountMap
|
|
1161
|
-
: undefined,
|
|
1162
|
-
summary: summaryBoundary
|
|
1163
|
-
? { text: summaryBoundary.text, tokenCount: summaryBoundary.tokenCount }
|
|
1164
|
-
: undefined,
|
|
1165
|
-
boundaryTokenAdjustment,
|
|
1166
|
-
};
|
|
527
|
+
* Formats an array of messages for LangChain, handling tool calls and creating ToolMessage instances.
|
|
528
|
+
*
|
|
529
|
+
* @param payload - The array of messages to format.
|
|
530
|
+
* @param indexTokenCountMap - Optional map of message indices to token counts.
|
|
531
|
+
* @param tools - Optional set of tool names that are allowed in the request.
|
|
532
|
+
* @param skills - Optional map of skill name to body for reconstructing skill HumanMessages.
|
|
533
|
+
* @param options - Optional formatting options (provider, skipSkillBodyNames).
|
|
534
|
+
* @returns - Object containing formatted messages and updated indexTokenCountMap if provided.
|
|
535
|
+
*/
|
|
536
|
+
const formatAgentMessages = (payload, indexTokenCountMap, tools, skills, options) => {
|
|
537
|
+
const messages = [];
|
|
538
|
+
const updatedIndexTokenCountMap = {};
|
|
539
|
+
let boundaryTokenAdjustment;
|
|
540
|
+
const indexMapping = {};
|
|
541
|
+
const summaryBoundary = getLatestSummaryBoundary(payload);
|
|
542
|
+
/**
|
|
543
|
+
* Create a mutable copy of the tools set that can be expanded dynamically.
|
|
544
|
+
* When we encounter tool_search results, we add discovered tools to this set,
|
|
545
|
+
* making their subsequent tool calls valid.
|
|
546
|
+
*/
|
|
547
|
+
const discoveredTools = tools ? new Set(tools) : void 0;
|
|
548
|
+
for (let i = 0; i < payload.length; i++) {
|
|
549
|
+
const rawMessage = payload[i];
|
|
550
|
+
const sourceMessageId = getSourceMessageId(rawMessage);
|
|
551
|
+
let message = applySummaryBoundary(rawMessage, i, summaryBoundary);
|
|
552
|
+
if (!message) {
|
|
553
|
+
indexMapping[i] = [];
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
if (typeof message.content === "string") message = {
|
|
557
|
+
...message,
|
|
558
|
+
content: [{
|
|
559
|
+
type: "text",
|
|
560
|
+
["text"]: message.content
|
|
561
|
+
}]
|
|
562
|
+
};
|
|
563
|
+
else if (Array.isArray(message.content) && message.content.length === 0) {
|
|
564
|
+
indexMapping[i] = [];
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
if (message.role !== "assistant") {
|
|
568
|
+
const formattedMessage = formatMessage({
|
|
569
|
+
message,
|
|
570
|
+
langChain: true
|
|
571
|
+
});
|
|
572
|
+
if (sourceMessageId != null && sourceMessageId !== "") formattedMessage.id = sourceMessageId;
|
|
573
|
+
messages.push(formattedMessage);
|
|
574
|
+
indexMapping[i] = [messages.length - 1];
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
const startMessageIndex = messages.length;
|
|
578
|
+
/**
|
|
579
|
+
* If tools set is provided, process tool_calls:
|
|
580
|
+
* - Keep valid tool_calls (tools in the set or dynamically discovered)
|
|
581
|
+
* - Convert invalid tool_calls to string representation for context preservation
|
|
582
|
+
* - Dynamically expand the set when tool_search results are encountered
|
|
583
|
+
*/
|
|
584
|
+
let processedMessage = message;
|
|
585
|
+
let pendingSkillNames;
|
|
586
|
+
if (discoveredTools) {
|
|
587
|
+
const content = message.content;
|
|
588
|
+
if (content != null && Array.isArray(content)) {
|
|
589
|
+
const filteredContent = [];
|
|
590
|
+
const invalidToolCallIds = /* @__PURE__ */ new Set();
|
|
591
|
+
const invalidToolStrings = [];
|
|
592
|
+
for (const part of content) {
|
|
593
|
+
if (part.type !== "tool_call") {
|
|
594
|
+
filteredContent.push(part);
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
/** Skip malformed tool_call entries */
|
|
598
|
+
if (part.tool_call == null || part.tool_call.name == null || part.tool_call.name === "") {
|
|
599
|
+
if (typeof part.tool_call?.id === "string" && part.tool_call.id !== "") invalidToolCallIds.add(part.tool_call.id);
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
const toolName = part.tool_call.name;
|
|
603
|
+
/**
|
|
604
|
+
* If this is a tool_search result with output, extract discovered tool names
|
|
605
|
+
* and add them to the discoveredTools set for subsequent validation.
|
|
606
|
+
*/
|
|
607
|
+
if (toolName === "tool_search" && typeof part.tool_call.output === "string" && part.tool_call.output !== "") {
|
|
608
|
+
const extracted = extractToolNamesFromSearchOutput(part.tool_call.output);
|
|
609
|
+
for (const name of extracted) discoveredTools.add(name);
|
|
610
|
+
}
|
|
611
|
+
if (discoveredTools.has(toolName)) {
|
|
612
|
+
filteredContent.push(part);
|
|
613
|
+
if (toolName === "skill" && skills?.size != null && skills.size > 0) {
|
|
614
|
+
const skillName = extractSkillName(part.tool_call.args) ?? "";
|
|
615
|
+
if (skillName) (pendingSkillNames ??= /* @__PURE__ */ new Set()).add(skillName);
|
|
616
|
+
}
|
|
617
|
+
} else {
|
|
618
|
+
/** Invalid tool - convert to string for context preservation */
|
|
619
|
+
if (typeof part.tool_call.id === "string" && part.tool_call.id !== "") invalidToolCallIds.add(part.tool_call.id);
|
|
620
|
+
const output = part.tool_call.output ?? "";
|
|
621
|
+
invalidToolStrings.push(`Tool: ${toolName}, ${output}`);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
/** Remove tool_call_ids references to invalid tools from text parts */
|
|
625
|
+
if (invalidToolCallIds.size > 0) {
|
|
626
|
+
for (const part of filteredContent) if (part.type === "text" && Array.isArray(part.tool_call_ids)) {
|
|
627
|
+
part.tool_call_ids = part.tool_call_ids.filter((id) => !invalidToolCallIds.has(id));
|
|
628
|
+
if (part.tool_call_ids.length === 0) delete part.tool_call_ids;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
/** Append invalid tool strings to the content for context preservation */
|
|
632
|
+
if (invalidToolStrings.length > 0) {
|
|
633
|
+
/** Find the last text part or create one */
|
|
634
|
+
let lastTextPartIndex = -1;
|
|
635
|
+
for (let j = filteredContent.length - 1; j >= 0; j--) if (filteredContent[j].type === "text") {
|
|
636
|
+
lastTextPartIndex = j;
|
|
637
|
+
break;
|
|
638
|
+
}
|
|
639
|
+
const invalidToolText = invalidToolStrings.join("\n");
|
|
640
|
+
if (lastTextPartIndex >= 0) {
|
|
641
|
+
const lastTextPart = filteredContent[lastTextPartIndex];
|
|
642
|
+
const existingText = lastTextPart["text"] ?? lastTextPart.text ?? "";
|
|
643
|
+
filteredContent[lastTextPartIndex] = {
|
|
644
|
+
...lastTextPart,
|
|
645
|
+
["text"]: existingText ? `${existingText}\n${invalidToolText}` : invalidToolText
|
|
646
|
+
};
|
|
647
|
+
} else
|
|
648
|
+
/** No text part exists, create one */
|
|
649
|
+
filteredContent.push({
|
|
650
|
+
type: "text",
|
|
651
|
+
["text"]: invalidToolText
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
/** Use filtered content if we made any changes */
|
|
655
|
+
if (filteredContent.length !== content.length || invalidToolStrings.length > 0) processedMessage = {
|
|
656
|
+
...message,
|
|
657
|
+
content: filteredContent
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
/** When tools filtering is off, still detect skill tool_calls for body reconstruction */
|
|
662
|
+
if (!discoveredTools && skills?.size != null && skills.size > 0) {
|
|
663
|
+
const content = processedMessage.content;
|
|
664
|
+
if (Array.isArray(content)) for (const part of content) {
|
|
665
|
+
if (part.type !== "tool_call" || part.tool_call?.name !== "skill") continue;
|
|
666
|
+
const skillName = extractSkillName(part.tool_call.args) ?? "";
|
|
667
|
+
if (skillName) (pendingSkillNames ??= /* @__PURE__ */ new Set()).add(skillName);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
const formattedMessages = formatAssistantMessage(processedMessage, {
|
|
671
|
+
preserveUnpairedServerToolUses: i === payload.length - 1,
|
|
672
|
+
preserveReasoningContent: options?.provider === "deepseek",
|
|
673
|
+
provider: options?.provider
|
|
674
|
+
});
|
|
675
|
+
if (sourceMessageId != null && sourceMessageId !== "") for (const formattedMessage of formattedMessages) formattedMessage.id = sourceMessageId;
|
|
676
|
+
messages.push(...formattedMessages);
|
|
677
|
+
const endMessageIndex = messages.length;
|
|
678
|
+
if (pendingSkillNames?.size != null && pendingSkillNames.size > 0) {
|
|
679
|
+
const skipSkillBodyNames = options?.skipSkillBodyNames;
|
|
680
|
+
for (const skillName of pendingSkillNames) {
|
|
681
|
+
if (skipSkillBodyNames != null && skipSkillBodyNames.has(skillName)) continue;
|
|
682
|
+
const body = skills?.get(skillName) ?? "";
|
|
683
|
+
if (body) messages.push(withMessageRole(new HumanMessage({
|
|
684
|
+
content: body,
|
|
685
|
+
additional_kwargs: {
|
|
686
|
+
role: "user",
|
|
687
|
+
isMeta: true,
|
|
688
|
+
source: "skill",
|
|
689
|
+
skillName
|
|
690
|
+
}
|
|
691
|
+
}), "user"));
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
const resultIndices = [];
|
|
695
|
+
for (let j = startMessageIndex; j < endMessageIndex; j++) resultIndices.push(j);
|
|
696
|
+
indexMapping[i] = resultIndices;
|
|
697
|
+
}
|
|
698
|
+
if (indexTokenCountMap) for (let originalIndex = 0; originalIndex < payload.length; originalIndex++) {
|
|
699
|
+
const resultIndices = indexMapping[originalIndex] || [];
|
|
700
|
+
let tokenCount = indexTokenCountMap[originalIndex];
|
|
701
|
+
if (tokenCount === void 0) continue;
|
|
702
|
+
if (summaryBoundary && originalIndex === summaryBoundary.messageIndex && Array.isArray(payload[originalIndex].content)) {
|
|
703
|
+
const content = payload[originalIndex].content;
|
|
704
|
+
const { contentIndex } = summaryBoundary;
|
|
705
|
+
if (contentIndex >= 0 && contentIndex < content.length - 1) {
|
|
706
|
+
let totalCharLen = 0;
|
|
707
|
+
let remainingCharLen = 0;
|
|
708
|
+
for (let p = 0; p < content.length; p++) {
|
|
709
|
+
const charLen = contentPartCharLength(content[p]);
|
|
710
|
+
totalCharLen += charLen;
|
|
711
|
+
if (p > contentIndex) remainingCharLen += charLen;
|
|
712
|
+
}
|
|
713
|
+
if (totalCharLen > 0) {
|
|
714
|
+
const original = tokenCount;
|
|
715
|
+
tokenCount = Math.max(1, Math.round(tokenCount * (remainingCharLen / totalCharLen)));
|
|
716
|
+
boundaryTokenAdjustment = {
|
|
717
|
+
original,
|
|
718
|
+
adjusted: tokenCount,
|
|
719
|
+
remainingChars: remainingCharLen,
|
|
720
|
+
totalChars: totalCharLen
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
const msgCount = resultIndices.length;
|
|
726
|
+
if (msgCount === 1) {
|
|
727
|
+
updatedIndexTokenCountMap[resultIndices[0]] = tokenCount;
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
if (msgCount < 2) continue;
|
|
731
|
+
let totalLength = 0;
|
|
732
|
+
const lastIdx = msgCount - 1;
|
|
733
|
+
const lengths = new Array(msgCount);
|
|
734
|
+
for (let k = 0; k < msgCount; k++) {
|
|
735
|
+
const msg = messages[resultIndices[k]];
|
|
736
|
+
const { content } = msg;
|
|
737
|
+
let len = 0;
|
|
738
|
+
if (typeof content === "string") len = content.length;
|
|
739
|
+
else if (Array.isArray(content)) {
|
|
740
|
+
for (const part of content) if (typeof part === "string") len += part.length;
|
|
741
|
+
else if (part != null && typeof part === "object") {
|
|
742
|
+
const val = part.text ?? part.content;
|
|
743
|
+
if (typeof val === "string") len += val.length;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
const toolCalls = msg.tool_calls;
|
|
747
|
+
if (Array.isArray(toolCalls)) for (const tc of toolCalls) {
|
|
748
|
+
if (typeof tc.name === "string") len += tc.name.length;
|
|
749
|
+
const { args } = tc;
|
|
750
|
+
if (typeof args === "string") len += args.length;
|
|
751
|
+
else if (args != null) len += JSON.stringify(args).length;
|
|
752
|
+
}
|
|
753
|
+
lengths[k] = len;
|
|
754
|
+
totalLength += len;
|
|
755
|
+
}
|
|
756
|
+
if (totalLength === 0) {
|
|
757
|
+
const countPerMessage = Math.floor(tokenCount / msgCount);
|
|
758
|
+
for (let k = 0; k < lastIdx; k++) updatedIndexTokenCountMap[resultIndices[k]] = countPerMessage;
|
|
759
|
+
updatedIndexTokenCountMap[resultIndices[lastIdx]] = tokenCount - countPerMessage * lastIdx;
|
|
760
|
+
} else {
|
|
761
|
+
let distributed = 0;
|
|
762
|
+
for (let k = 0; k < lastIdx; k++) {
|
|
763
|
+
const share = Math.floor(lengths[k] / totalLength * tokenCount);
|
|
764
|
+
updatedIndexTokenCountMap[resultIndices[k]] = share;
|
|
765
|
+
distributed += share;
|
|
766
|
+
}
|
|
767
|
+
updatedIndexTokenCountMap[resultIndices[lastIdx]] = tokenCount - distributed;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
return {
|
|
771
|
+
messages,
|
|
772
|
+
indexTokenCountMap: indexTokenCountMap ? updatedIndexTokenCountMap : void 0,
|
|
773
|
+
summary: summaryBoundary ? {
|
|
774
|
+
text: summaryBoundary.text,
|
|
775
|
+
tokenCount: summaryBoundary.tokenCount
|
|
776
|
+
} : void 0,
|
|
777
|
+
boundaryTokenAdjustment
|
|
778
|
+
};
|
|
1167
779
|
};
|
|
1168
780
|
/**
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
781
|
+
* Adds a value at key 0 for system messages and shifts all key indices by one in an indexTokenCountMap.
|
|
782
|
+
* This is useful when adding a system message at the beginning of a conversation.
|
|
783
|
+
*
|
|
784
|
+
* @param indexTokenCountMap - The original map of message indices to token counts
|
|
785
|
+
* @param instructionsTokenCount - The token count for the system message to add at index 0
|
|
786
|
+
* @returns A new map with the system message at index 0 and all other indices shifted by 1
|
|
787
|
+
*/
|
|
1176
788
|
function shiftIndexTokenCountMap(indexTokenCountMap, instructionsTokenCount) {
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
}
|
|
1185
|
-
return shiftedMap;
|
|
789
|
+
const shiftedMap = {};
|
|
790
|
+
shiftedMap[0] = instructionsTokenCount;
|
|
791
|
+
for (const [indexStr, tokenCount] of Object.entries(indexTokenCountMap)) {
|
|
792
|
+
const index = Number(indexStr);
|
|
793
|
+
shiftedMap[index + 1] = tokenCount;
|
|
794
|
+
}
|
|
795
|
+
return shiftedMap;
|
|
1186
796
|
}
|
|
1187
797
|
/** Block types that contain binary image data and must be preserved structurally. */
|
|
1188
|
-
const IMAGE_BLOCK_TYPES = new Set([
|
|
798
|
+
const IMAGE_BLOCK_TYPES = new Set(["image_url", "image"]);
|
|
1189
799
|
/** Checks whether a BaseMessage is a tool-role message. */
|
|
1190
|
-
const isToolMessage = (m) => m instanceof ToolMessage ||
|
|
800
|
+
const isToolMessage$1 = (m) => m instanceof ToolMessage || "role" in m && m.role === "tool";
|
|
1191
801
|
/** Flushes accumulated text chunks into `parts` as a single text block. */
|
|
1192
802
|
function flushTextChunks(textChunks, parts) {
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
});
|
|
1200
|
-
textChunks.length = 0;
|
|
803
|
+
if (textChunks.length === 0) return;
|
|
804
|
+
parts.push({
|
|
805
|
+
type: "text",
|
|
806
|
+
text: textChunks.join("\n")
|
|
807
|
+
});
|
|
808
|
+
textChunks.length = 0;
|
|
1201
809
|
}
|
|
1202
810
|
/**
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
811
|
+
* Appends a single message's content to the running `textChunks` / `parts`
|
|
812
|
+
* accumulators. Image blocks are shallow-copied into `parts` as-is so that
|
|
813
|
+
* binary data (base64 images) never becomes text tokens. All other block
|
|
814
|
+
* types are serialized to text — unrecognized types are JSON-serialized
|
|
815
|
+
* rather than silently dropped.
|
|
816
|
+
*
|
|
817
|
+
* When `content` is an array containing tool_use blocks, `tool_calls` is NOT
|
|
818
|
+
* additionally serialized (avoiding double output). `tool_calls` is used as
|
|
819
|
+
* a fallback when `content` is a plain string or an array with no tool_use.
|
|
820
|
+
*/
|
|
1213
821
|
function appendMessageContent(msg, role, textChunks, parts) {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
if (block.type != null && block.type !== '') {
|
|
1245
|
-
textChunks.push(`${role}: [${block.type}] ${JSON.stringify(block)}`);
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
// If content array had no tool_use blocks, fall back to tool_calls metadata
|
|
1249
|
-
// (handles edge case: empty content array with tool_calls populated)
|
|
1250
|
-
if (!hasToolUseBlock) {
|
|
1251
|
-
appendToolCalls(msg, role, textChunks);
|
|
1252
|
-
}
|
|
822
|
+
const { content } = msg;
|
|
823
|
+
if (typeof content === "string") {
|
|
824
|
+
if (content) textChunks.push(`${role}: ${content}`);
|
|
825
|
+
appendToolCalls(msg, role, textChunks);
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (!Array.isArray(content)) {
|
|
829
|
+
appendToolCalls(msg, role, textChunks);
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
let hasToolUseBlock = false;
|
|
833
|
+
for (const block of content) {
|
|
834
|
+
if (IMAGE_BLOCK_TYPES.has(block.type ?? "")) {
|
|
835
|
+
flushTextChunks(textChunks, parts);
|
|
836
|
+
parts.push({ ...block });
|
|
837
|
+
continue;
|
|
838
|
+
}
|
|
839
|
+
if (block.type === "tool_use") {
|
|
840
|
+
hasToolUseBlock = true;
|
|
841
|
+
textChunks.push(`${role}: [tool_use] ${String(block.name ?? "")} ${JSON.stringify(block.input ?? {})}`);
|
|
842
|
+
continue;
|
|
843
|
+
}
|
|
844
|
+
const text = block.text ?? block.input;
|
|
845
|
+
if (typeof text === "string" && text) {
|
|
846
|
+
textChunks.push(`${role}: ${text}`);
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
if (block.type != null && block.type !== "") textChunks.push(`${role}: [${block.type}] ${JSON.stringify(block)}`);
|
|
850
|
+
}
|
|
851
|
+
if (!hasToolUseBlock) appendToolCalls(msg, role, textChunks);
|
|
1253
852
|
}
|
|
1254
853
|
function appendToolCalls(msg, role, textChunks) {
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
if (!aiMsg.tool_calls || aiMsg.tool_calls.length === 0) {
|
|
1260
|
-
return;
|
|
1261
|
-
}
|
|
1262
|
-
for (const tc of aiMsg.tool_calls) {
|
|
1263
|
-
textChunks.push(`AI: [tool_call] ${tc.name}(${JSON.stringify(tc.args)})`);
|
|
1264
|
-
}
|
|
854
|
+
if (role !== "AI") return;
|
|
855
|
+
const aiMsg = msg;
|
|
856
|
+
if (!aiMsg.tool_calls || aiMsg.tool_calls.length === 0) return;
|
|
857
|
+
for (const tc of aiMsg.tool_calls) textChunks.push(`AI: [tool_call] ${tc.name}(${JSON.stringify(tc.args)})`);
|
|
1265
858
|
}
|
|
1266
859
|
/**
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
860
|
+
* Ensures compatibility when switching from a non-thinking agent to a thinking-enabled agent.
|
|
861
|
+
* Converts AI messages with tool calls (that lack thinking/reasoning blocks) into buffer strings,
|
|
862
|
+
* avoiding the thinking block signature requirement.
|
|
863
|
+
*
|
|
864
|
+
* Recognizes the following as valid thinking/reasoning blocks:
|
|
865
|
+
* - ContentTypes.THINKING (Anthropic)
|
|
866
|
+
* - ContentTypes.REASONING_CONTENT (Bedrock)
|
|
867
|
+
* - ContentTypes.REASONING (VertexAI / Google)
|
|
868
|
+
* - 'redacted_thinking'
|
|
869
|
+
*
|
|
870
|
+
* @param messages - Array of messages to process
|
|
871
|
+
* @param provider - The provider being used (unused but kept for future compatibility)
|
|
872
|
+
* @param config - Optional RunnableConfig for structured agent logging
|
|
873
|
+
* @param runStartIndex - Index in `messages` where the CURRENT run's own
|
|
874
|
+
* appended AI/Tool messages begin (i.e. anything at this index or later
|
|
875
|
+
* was just produced by this run's own iterations, not historical
|
|
876
|
+
* context). When provided, AI messages at or after this index are
|
|
877
|
+
* never converted to `[Previous agent context]` placeholders — Claude
|
|
878
|
+
* can validly skip a thinking block before a tool_use (cf. PR #116),
|
|
879
|
+
* so the agent's own in-run iterations must not be misclassified as
|
|
880
|
+
* foreign history. Without the signal the function falls back to its
|
|
881
|
+
* prior heuristic (`chainHasThinkingBlock`), preserving backward
|
|
882
|
+
* compatibility for callers that don't yet pass the boundary.
|
|
883
|
+
* @returns The messages array with tool sequences converted to buffer strings if necessary
|
|
884
|
+
*/
|
|
1292
885
|
function ensureThinkingBlockInMessages(messages, _provider, config, runStartIndex) {
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
}
|
|
1354
|
-
// If message has tool use but no thinking block, check whether this is a
|
|
1355
|
-
// continuation of a thinking-enabled agent's chain before converting.
|
|
1356
|
-
// Bedrock reasoning models can produce multiple AI→Tool rounds after an
|
|
1357
|
-
// initial reasoning response: the first AI message has reasoning_content,
|
|
1358
|
-
// but follow-ups have content: "" with only tool_calls. These are the
|
|
1359
|
-
// same agent's turn and must NOT be converted to HumanMessages.
|
|
1360
|
-
if (hasToolUse && !hasThinkingBlock) {
|
|
1361
|
-
// Current-run boundary check: anything at or after `runStartIndex`
|
|
1362
|
-
// is the current run's own work — preserve it. Claude is allowed
|
|
1363
|
-
// to skip a thinking block before a tool_use (cf. PR #116 in the
|
|
1364
|
-
// agents repo), so the agent's own first-iteration AI message can
|
|
1365
|
-
// legitimately have tool_calls without reasoning. Converting it to
|
|
1366
|
-
// a `[Previous agent context]` placeholder pollutes the next
|
|
1367
|
-
// iteration's prompt — the LLM sees the placeholder, treats it as
|
|
1368
|
-
// suspicious injected content, ignores its own real prior tool
|
|
1369
|
-
// result, and re-runs the tool to verify (which then often fails
|
|
1370
|
-
// because subsequent calls land in fresh sandboxes without the
|
|
1371
|
-
// file). Skip the conversion when we know this is in-run.
|
|
1372
|
-
if (runStartIndex !== undefined && i >= runStartIndex) {
|
|
1373
|
-
result.push(msg);
|
|
1374
|
-
i++;
|
|
1375
|
-
continue;
|
|
1376
|
-
}
|
|
1377
|
-
// Walk backwards — if an earlier AI message in the same chain (before
|
|
1378
|
-
// the nearest HumanMessage) has a thinking/reasoning block, this is a
|
|
1379
|
-
// continuation of a thinking-enabled turn, not a non-thinking handoff.
|
|
1380
|
-
if (chainHasThinkingBlock(messages, i)) {
|
|
1381
|
-
result.push(msg);
|
|
1382
|
-
i++;
|
|
1383
|
-
continue;
|
|
1384
|
-
}
|
|
1385
|
-
// Build structured content in a single pass over the AI + following
|
|
1386
|
-
// ToolMessages — preserves image blocks as-is to avoid serializing
|
|
1387
|
-
// binary data as text (which caused 174× token amplification).
|
|
1388
|
-
const parts = [];
|
|
1389
|
-
const textChunks = ['[Previous agent context]'];
|
|
1390
|
-
appendMessageContent(msg, 'AI', textChunks, parts);
|
|
1391
|
-
let j = i + 1;
|
|
1392
|
-
while (j < messages.length && isToolMessage(messages[j])) {
|
|
1393
|
-
appendMessageContent(messages[j], 'Tool', textChunks, parts);
|
|
1394
|
-
j++;
|
|
1395
|
-
}
|
|
1396
|
-
flushTextChunks(textChunks, parts);
|
|
1397
|
-
emitAgentLog(config, 'warn', 'format', 'ensureThinkingBlockInMessages: injecting [Previous agent context] HumanMessage' +
|
|
1398
|
-
` (${parts.length} msgs at index ${i}, no thinking block in chain)`);
|
|
1399
|
-
result.push(withMessageRole(new HumanMessage({ content: toLangChainContent(parts) }), 'user'));
|
|
1400
|
-
i = j;
|
|
1401
|
-
}
|
|
1402
|
-
else {
|
|
1403
|
-
// Keep the message as is
|
|
1404
|
-
result.push(msg);
|
|
1405
|
-
i++;
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
return result;
|
|
886
|
+
if (messages.length === 0) return messages;
|
|
887
|
+
let lastHumanIndex = -1;
|
|
888
|
+
for (let k = messages.length - 1; k >= 0; k--) {
|
|
889
|
+
const m = messages[k];
|
|
890
|
+
if (m instanceof HumanMessage || "role" in m && m.role === "user") {
|
|
891
|
+
lastHumanIndex = k;
|
|
892
|
+
break;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
if (lastHumanIndex === messages.length - 1) return messages;
|
|
896
|
+
const result = lastHumanIndex >= 0 ? messages.slice(0, lastHumanIndex + 1) : [];
|
|
897
|
+
let i = lastHumanIndex + 1;
|
|
898
|
+
while (i < messages.length) {
|
|
899
|
+
const msg = messages[i];
|
|
900
|
+
if (!(msg instanceof AIMessage || msg instanceof AIMessageChunk || "role" in msg && msg.role === "assistant")) {
|
|
901
|
+
result.push(msg);
|
|
902
|
+
i++;
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
const aiMsg = msg;
|
|
906
|
+
const hasToolCalls = aiMsg.tool_calls && aiMsg.tool_calls.length > 0;
|
|
907
|
+
const contentIsArray = Array.isArray(aiMsg.content);
|
|
908
|
+
let hasToolUse = hasToolCalls ?? false;
|
|
909
|
+
let hasThinkingBlock = false;
|
|
910
|
+
if (contentIsArray && aiMsg.content.length > 0) for (const c of aiMsg.content) {
|
|
911
|
+
if (typeof c !== "object") continue;
|
|
912
|
+
if (c.type === "tool_use") hasToolUse = true;
|
|
913
|
+
else if (c.type === "thinking" || c.type === "reasoning_content" || c.type === "reasoning" || c.type === "redacted_thinking") hasThinkingBlock = true;
|
|
914
|
+
if (hasToolUse && hasThinkingBlock) break;
|
|
915
|
+
}
|
|
916
|
+
if (!hasThinkingBlock && aiMsg.additional_kwargs.reasoning_content != null) hasThinkingBlock = true;
|
|
917
|
+
if (hasToolUse && !hasThinkingBlock) {
|
|
918
|
+
if (runStartIndex !== void 0 && i >= runStartIndex) {
|
|
919
|
+
result.push(msg);
|
|
920
|
+
i++;
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
if (chainHasThinkingBlock(messages, i)) {
|
|
924
|
+
result.push(msg);
|
|
925
|
+
i++;
|
|
926
|
+
continue;
|
|
927
|
+
}
|
|
928
|
+
const parts = [];
|
|
929
|
+
const textChunks = ["[Previous agent context]"];
|
|
930
|
+
appendMessageContent(msg, "AI", textChunks, parts);
|
|
931
|
+
let j = i + 1;
|
|
932
|
+
while (j < messages.length && isToolMessage$1(messages[j])) {
|
|
933
|
+
appendMessageContent(messages[j], "Tool", textChunks, parts);
|
|
934
|
+
j++;
|
|
935
|
+
}
|
|
936
|
+
flushTextChunks(textChunks, parts);
|
|
937
|
+
emitAgentLog(config, "warn", "format", `ensureThinkingBlockInMessages: injecting [Previous agent context] HumanMessage (${parts.length} msgs at index ${i}, no thinking block in chain)`);
|
|
938
|
+
result.push(withMessageRole(new HumanMessage({ content: toLangChainContent(parts) }), "user"));
|
|
939
|
+
i = j;
|
|
940
|
+
} else {
|
|
941
|
+
result.push(msg);
|
|
942
|
+
i++;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return result;
|
|
1409
946
|
}
|
|
1410
947
|
/**
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
948
|
+
* Walks backwards from `currentIndex` through the message array to check
|
|
949
|
+
* whether an earlier AI message in the same "chain" (no HumanMessage boundary)
|
|
950
|
+
* contains a thinking/reasoning block.
|
|
951
|
+
*
|
|
952
|
+
* A "chain" is a contiguous sequence of AI + Tool messages with no intervening
|
|
953
|
+
* HumanMessage. Bedrock reasoning models produce reasoning on the first AI
|
|
954
|
+
* response, then issue follow-up tool calls with `content: ""` and no
|
|
955
|
+
* reasoning block. These follow-ups are part of the same thinking-enabled
|
|
956
|
+
* turn and should not be converted.
|
|
957
|
+
*/
|
|
1421
958
|
function chainHasThinkingBlock(messages, currentIndex) {
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
const prevAiMsg = prev;
|
|
1435
|
-
if (Array.isArray(prevAiMsg.content) && prevAiMsg.content.length > 0) {
|
|
1436
|
-
const content = prevAiMsg.content;
|
|
1437
|
-
if (content.some((c) => typeof c === 'object' &&
|
|
1438
|
-
(c.type === ContentTypes.THINKING ||
|
|
1439
|
-
c.type === ContentTypes.REASONING_CONTENT ||
|
|
1440
|
-
c.type === ContentTypes.REASONING ||
|
|
1441
|
-
c.type === 'redacted_thinking'))) {
|
|
1442
|
-
return true;
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
// Bedrock also stores reasoning in additional_kwargs
|
|
1446
|
-
if (prevAiMsg.additional_kwargs.reasoning_content != null) {
|
|
1447
|
-
return true;
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
// ToolMessages are part of the chain — keep walking back
|
|
1451
|
-
}
|
|
1452
|
-
return false;
|
|
959
|
+
for (let k = currentIndex - 1; k >= 0; k--) {
|
|
960
|
+
const prev = messages[k];
|
|
961
|
+
if (prev instanceof HumanMessage || "role" in prev && prev.role === "user") return false;
|
|
962
|
+
if (prev instanceof AIMessage || prev instanceof AIMessageChunk || "role" in prev && prev.role === "assistant") {
|
|
963
|
+
const prevAiMsg = prev;
|
|
964
|
+
if (Array.isArray(prevAiMsg.content) && prevAiMsg.content.length > 0) {
|
|
965
|
+
if (prevAiMsg.content.some((c) => typeof c === "object" && (c.type === "thinking" || c.type === "reasoning_content" || c.type === "reasoning" || c.type === "redacted_thinking"))) return true;
|
|
966
|
+
}
|
|
967
|
+
if (prevAiMsg.additional_kwargs.reasoning_content != null) return true;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return false;
|
|
1453
971
|
}
|
|
1454
|
-
|
|
972
|
+
//#endregion
|
|
1455
973
|
export { ensureThinkingBlockInMessages, formatAgentMessages, formatFromLangChain, formatLangChainMessages, formatMediaMessage, formatMessage, labelContentByAgent, shiftIndexTokenCountMap, withMessageRole };
|
|
1456
|
-
|
|
974
|
+
|
|
975
|
+
//# sourceMappingURL=format.mjs.map
|