@illuma-ai/agents 1.4.0-alpha.6 → 1.5.1
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/README.md +62 -0
- package/dist/cjs/agents/AgentContext.cjs +274 -67
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +44 -13
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +182 -5
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +152 -1167
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs +1 -1
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs.map +1 -1
- package/dist/cjs/hooks/HookRegistry.cjs +162 -0
- package/dist/cjs/hooks/HookRegistry.cjs.map +1 -0
- package/dist/cjs/hooks/executeHooks.cjs +276 -0
- package/dist/cjs/hooks/executeHooks.cjs.map +1 -0
- package/dist/cjs/hooks/matchers.cjs +256 -0
- package/dist/cjs/hooks/matchers.cjs.map +1 -0
- package/dist/cjs/hooks/types.cjs +27 -0
- package/dist/cjs/hooks/types.cjs.map +1 -0
- package/dist/cjs/langchain/google-common.cjs +3 -0
- package/dist/cjs/langchain/google-common.cjs.map +1 -0
- package/dist/cjs/langchain/index.cjs +86 -0
- package/dist/cjs/langchain/index.cjs.map +1 -0
- package/dist/cjs/langchain/language_models/chat_models.cjs +3 -0
- package/dist/cjs/langchain/language_models/chat_models.cjs.map +1 -0
- package/dist/cjs/langchain/messages/tool.cjs +3 -0
- package/dist/cjs/langchain/messages/tool.cjs.map +1 -0
- package/dist/cjs/langchain/messages.cjs +51 -0
- package/dist/cjs/langchain/messages.cjs.map +1 -0
- package/dist/cjs/langchain/openai.cjs +3 -0
- package/dist/cjs/langchain/openai.cjs.map +1 -0
- package/dist/cjs/langchain/prompts.cjs +11 -0
- package/dist/cjs/langchain/prompts.cjs.map +1 -0
- package/dist/cjs/langchain/runnables.cjs +19 -0
- package/dist/cjs/langchain/runnables.cjs.map +1 -0
- package/dist/cjs/langchain/tools.cjs +23 -0
- package/dist/cjs/langchain/tools.cjs.map +1 -0
- package/dist/cjs/langchain/utils/env.cjs +11 -0
- package/dist/cjs/langchain/utils/env.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +5 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/cacheSupport.cjs +55 -0
- package/dist/cjs/llm/bedrock/cacheSupport.cjs.map +1 -0
- package/dist/cjs/llm/bedrock/index.cjs +61 -33
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +1 -4
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +27 -10
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +178 -127
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/memory/citations.cjs +4 -4
- package/dist/cjs/memory/citations.cjs.map +1 -1
- package/dist/cjs/memory/constants.cjs +17 -17
- package/dist/cjs/memory/constants.cjs.map +1 -1
- package/dist/cjs/memory/mmr.cjs +1 -1
- package/dist/cjs/memory/mmr.cjs.map +1 -1
- package/dist/cjs/memory/paths.cjs +1 -1
- package/dist/cjs/memory/paths.cjs.map +1 -1
- package/dist/cjs/memory/recallTracking.cjs +3 -3
- package/dist/cjs/memory/recallTracking.cjs.map +1 -1
- package/dist/cjs/memory/temporalDecay.cjs +2 -2
- package/dist/cjs/memory/temporalDecay.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +89 -0
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/contextPruning.cjs +156 -0
- package/dist/cjs/messages/contextPruning.cjs.map +1 -0
- package/dist/cjs/messages/contextPruningSettings.cjs +53 -0
- package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -0
- package/dist/cjs/messages/format.cjs +144 -20
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +505 -4
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +141 -1
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/BashExecutor.cjs +235 -0
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -0
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +297 -0
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -0
- package/dist/cjs/tools/CodeExecutor.cjs +45 -47
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +16 -11
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ReadFile.cjs +44 -0
- package/dist/cjs/tools/ReadFile.cjs.map +1 -0
- package/dist/cjs/tools/SkillTool.cjs +51 -0
- package/dist/cjs/tools/SkillTool.cjs.map +1 -0
- package/dist/cjs/tools/SubagentTool.cjs +93 -0
- package/dist/cjs/tools/SubagentTool.cjs.map +1 -0
- package/dist/cjs/tools/ToolNode.cjs +450 -24
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/memory/memoryAppendTool.cjs +1 -1
- package/dist/cjs/tools/memory/memoryAppendTool.cjs.map +1 -1
- package/dist/cjs/tools/memory/memoryGetTool.cjs +2 -2
- package/dist/cjs/tools/memory/memoryGetTool.cjs.map +1 -1
- package/dist/cjs/tools/memory/memorySearchTool.cjs +3 -3
- package/dist/cjs/tools/memory/memorySearchTool.cjs.map +1 -1
- package/dist/cjs/tools/memory/shared.cjs +1 -1
- package/dist/cjs/tools/memory/shared.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +11 -3
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tavily-scraper.cjs +189 -0
- package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/tavily-search.cjs +372 -0
- package/dist/cjs/tools/search/tavily-search.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +28 -4
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +10 -3
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/tools/skillCatalog.cjs +84 -0
- package/dist/cjs/tools/skillCatalog.cjs.map +1 -0
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +512 -0
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -0
- package/dist/cjs/tools/toolOutputReferences.cjs +670 -0
- package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -0
- package/dist/cjs/types/agent-cache.cjs +54 -0
- package/dist/cjs/types/agent-cache.cjs.map +1 -0
- package/dist/cjs/types/graph.cjs.map +1 -1
- package/dist/cjs/utils/truncation.cjs +135 -0
- package/dist/cjs/utils/truncation.cjs.map +1 -0
- package/dist/esm/agents/AgentContext.mjs +274 -67
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +44 -12
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +182 -5
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +155 -1170
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs +1 -1
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs.map +1 -1
- package/dist/esm/hooks/HookRegistry.mjs +160 -0
- package/dist/esm/hooks/HookRegistry.mjs.map +1 -0
- package/dist/esm/hooks/executeHooks.mjs +273 -0
- package/dist/esm/hooks/executeHooks.mjs.map +1 -0
- package/dist/esm/hooks/matchers.mjs +251 -0
- package/dist/esm/hooks/matchers.mjs.map +1 -0
- package/dist/esm/hooks/types.mjs +25 -0
- package/dist/esm/hooks/types.mjs.map +1 -0
- package/dist/esm/langchain/google-common.mjs +2 -0
- package/dist/esm/langchain/google-common.mjs.map +1 -0
- package/dist/esm/langchain/index.mjs +5 -0
- package/dist/esm/langchain/language_models/chat_models.mjs +2 -0
- package/dist/esm/langchain/language_models/chat_models.mjs.map +1 -0
- package/dist/esm/langchain/messages/tool.mjs +2 -0
- package/dist/esm/langchain/messages/tool.mjs.map +1 -0
- package/dist/esm/langchain/messages.mjs +2 -0
- package/dist/esm/langchain/messages.mjs.map +1 -0
- package/dist/esm/langchain/openai.mjs +2 -0
- package/dist/esm/langchain/openai.mjs.map +1 -0
- package/dist/esm/langchain/prompts.mjs +2 -0
- package/dist/esm/langchain/prompts.mjs.map +1 -0
- package/dist/esm/langchain/runnables.mjs +2 -0
- package/dist/esm/langchain/runnables.mjs.map +1 -0
- package/dist/esm/langchain/tools.mjs +2 -0
- package/dist/esm/langchain/tools.mjs.map +1 -0
- package/dist/esm/langchain/utils/env.mjs +2 -0
- package/dist/esm/langchain/utils/env.mjs.map +1 -0
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +5 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/cacheSupport.mjs +52 -0
- package/dist/esm/llm/bedrock/cacheSupport.mjs.map +1 -0
- package/dist/esm/llm/bedrock/index.mjs +61 -34
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +1 -4
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +27 -10
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/main.mjs +21 -27
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/memory/citations.mjs +4 -4
- package/dist/esm/memory/citations.mjs.map +1 -1
- package/dist/esm/memory/constants.mjs +17 -17
- package/dist/esm/memory/constants.mjs.map +1 -1
- package/dist/esm/memory/mmr.mjs +1 -1
- package/dist/esm/memory/mmr.mjs.map +1 -1
- package/dist/esm/memory/paths.mjs +1 -1
- package/dist/esm/memory/paths.mjs.map +1 -1
- package/dist/esm/memory/recallTracking.mjs +3 -3
- package/dist/esm/memory/recallTracking.mjs.map +1 -1
- package/dist/esm/memory/temporalDecay.mjs +2 -2
- package/dist/esm/memory/temporalDecay.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +89 -0
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/contextPruning.mjs +154 -0
- package/dist/esm/messages/contextPruning.mjs.map +1 -0
- package/dist/esm/messages/contextPruningSettings.mjs +50 -0
- package/dist/esm/messages/contextPruningSettings.mjs.map +1 -0
- package/dist/esm/messages/format.mjs +136 -12
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +504 -7
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +141 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/BashExecutor.mjs +227 -0
- package/dist/esm/tools/BashExecutor.mjs.map +1 -0
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +288 -0
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -0
- package/dist/esm/tools/CodeExecutor.mjs +45 -48
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +17 -12
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ReadFile.mjs +39 -0
- package/dist/esm/tools/ReadFile.mjs.map +1 -0
- package/dist/esm/tools/SkillTool.mjs +46 -0
- package/dist/esm/tools/SkillTool.mjs.map +1 -0
- package/dist/esm/tools/SubagentTool.mjs +86 -0
- package/dist/esm/tools/SubagentTool.mjs.map +1 -0
- package/dist/esm/tools/ToolNode.mjs +452 -26
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/memory/memoryAppendTool.mjs +1 -1
- package/dist/esm/tools/memory/memoryAppendTool.mjs.map +1 -1
- package/dist/esm/tools/memory/memoryGetTool.mjs +2 -2
- package/dist/esm/tools/memory/memoryGetTool.mjs.map +1 -1
- package/dist/esm/tools/memory/memorySearchTool.mjs +3 -3
- package/dist/esm/tools/memory/memorySearchTool.mjs.map +1 -1
- package/dist/esm/tools/memory/shared.mjs +1 -1
- package/dist/esm/tools/memory/shared.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +11 -3
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tavily-scraper.mjs +186 -0
- package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/tavily-search.mjs +370 -0
- package/dist/esm/tools/search/tavily-search.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +28 -4
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +10 -3
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/tools/skillCatalog.mjs +82 -0
- package/dist/esm/tools/skillCatalog.mjs.map +1 -0
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +506 -0
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -0
- package/dist/esm/tools/toolOutputReferences.mjs +662 -0
- package/dist/esm/tools/toolOutputReferences.mjs.map +1 -0
- package/dist/esm/types/agent-cache.mjs +52 -0
- package/dist/esm/types/agent-cache.mjs.map +1 -0
- package/dist/esm/types/graph.mjs.map +1 -1
- package/dist/esm/utils/truncation.mjs +128 -0
- package/dist/esm/utils/truncation.mjs.map +1 -0
- package/dist/types/agents/AgentContext.d.ts +101 -8
- package/dist/types/common/enum.d.ts +39 -12
- package/dist/types/common/index.d.ts +0 -1
- package/dist/types/graphs/Graph.d.ts +43 -0
- package/dist/types/graphs/MultiAgentGraph.d.ts +26 -150
- package/dist/types/graphs/index.d.ts +0 -1
- package/dist/types/graphs/phases/memoryFlushPhase.d.ts +2 -2
- package/dist/types/hooks/HookRegistry.d.ts +56 -0
- package/dist/types/hooks/executeHooks.d.ts +79 -0
- package/dist/types/hooks/index.d.ts +6 -0
- package/dist/types/hooks/matchers.d.ts +95 -0
- package/dist/types/hooks/types.d.ts +320 -0
- package/dist/types/index.d.ts +9 -9
- package/dist/types/langchain/google-common.d.ts +1 -0
- package/dist/types/langchain/index.d.ts +8 -0
- package/dist/types/langchain/language_models/chat_models.d.ts +1 -0
- package/dist/types/langchain/messages/tool.d.ts +1 -0
- package/dist/types/langchain/messages.d.ts +2 -0
- package/dist/types/langchain/openai.d.ts +1 -0
- package/dist/types/langchain/prompts.d.ts +1 -0
- package/dist/types/langchain/runnables.d.ts +2 -0
- package/dist/types/langchain/tools.d.ts +2 -0
- package/dist/types/langchain/utils/env.d.ts +1 -0
- package/dist/types/llm/bedrock/cacheSupport.d.ts +35 -0
- package/dist/types/llm/bedrock/index.d.ts +54 -1
- package/dist/types/llm/openai/index.d.ts +1 -1
- package/dist/types/memory/citations.d.ts +4 -4
- package/dist/types/memory/constants.d.ts +17 -17
- package/dist/types/memory/mmr.d.ts +3 -3
- package/dist/types/memory/paths.d.ts +1 -1
- package/dist/types/memory/temporalDecay.d.ts +2 -2
- package/dist/types/memory/types.d.ts +3 -3
- package/dist/types/messages/contextPruning.d.ts +42 -0
- package/dist/types/messages/contextPruningSettings.d.ts +44 -0
- package/dist/types/messages/format.d.ts +9 -1
- package/dist/types/messages/index.d.ts +2 -0
- package/dist/types/messages/prune.d.ts +91 -1
- package/dist/types/run.d.ts +2 -0
- package/dist/types/tools/BashExecutor.d.ts +76 -0
- package/dist/types/tools/BashProgrammaticToolCalling.d.ts +72 -0
- package/dist/types/tools/CodeExecutor.d.ts +8 -26
- package/dist/types/tools/ReadFile.d.ts +28 -0
- package/dist/types/tools/SkillTool.d.ts +40 -0
- package/dist/types/tools/SubagentTool.d.ts +36 -0
- package/dist/types/tools/ToolNode.d.ts +77 -5
- package/dist/types/tools/memory/shared.d.ts +1 -1
- package/dist/types/tools/search/tavily-scraper.d.ts +19 -0
- package/dist/types/tools/search/tavily-search.d.ts +4 -0
- package/dist/types/tools/search/types.d.ts +99 -5
- package/dist/types/tools/search/utils.d.ts +2 -2
- package/dist/types/tools/skillCatalog.d.ts +19 -0
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +137 -0
- package/dist/types/tools/subagent/index.d.ts +2 -0
- package/dist/types/tools/subagent/types.d.ts +84 -0
- package/dist/types/tools/toolOutputReferences.d.ts +236 -0
- package/dist/types/types/agent-cache.d.ts +71 -0
- package/dist/types/types/graph.d.ts +163 -22
- package/dist/types/types/index.d.ts +3 -0
- package/dist/types/types/messages.d.ts +26 -0
- package/dist/types/types/run.d.ts +22 -0
- package/dist/types/types/skill.d.ts +9 -0
- package/dist/types/types/tools.d.ts +111 -0
- package/dist/types/utils/index.d.ts +1 -3
- package/dist/types/utils/truncation.d.ts +70 -0
- package/package.json +57 -17
- package/src/agents/AgentContext.ts +321 -78
- package/src/agents/__tests__/AgentContext.cacheTtl.live.test.ts +259 -0
- package/src/agents/__tests__/AgentContext.crossAgentTier1.live.test.ts +266 -0
- package/src/agents/__tests__/AgentContext.crossUserCache.live.test.ts +342 -0
- package/src/agents/__tests__/AgentContext.test.ts +632 -0
- package/src/common/__tests__/enum.test.ts +7 -17
- package/src/common/enum.ts +43 -12
- package/src/common/index.ts +0 -1
- package/src/graphs/Graph.ts +222 -2
- package/src/graphs/MultiAgentGraph.ts +154 -1466
- package/src/graphs/__tests__/MultiAgentGraph.test.ts +91 -0
- package/src/graphs/gapFeatures.test.ts +1 -1
- package/src/graphs/index.ts +0 -1
- package/src/graphs/phases/__tests__/memoryFlushPhase.test.ts +1 -1
- package/src/graphs/phases/memoryFlushPhase.ts +2 -2
- package/src/hooks/HookRegistry.ts +208 -0
- package/src/hooks/__tests__/HookRegistry.test.ts +190 -0
- package/src/hooks/__tests__/compactHooks.test.ts +214 -0
- package/src/hooks/__tests__/executeHooks.test.ts +1013 -0
- package/src/hooks/__tests__/integration.test.ts +337 -0
- package/src/hooks/__tests__/matchers.test.ts +238 -0
- package/src/hooks/__tests__/toolHooks.test.ts +665 -0
- package/src/hooks/executeHooks.ts +375 -0
- package/src/hooks/index.ts +57 -0
- package/src/hooks/matchers.ts +280 -0
- package/src/hooks/types.ts +404 -0
- package/src/index.ts +15 -24
- package/src/langchain/google-common.ts +1 -0
- package/src/langchain/index.ts +8 -0
- package/src/langchain/language_models/chat_models.ts +1 -0
- package/src/langchain/messages/tool.ts +5 -0
- package/src/langchain/messages.ts +21 -0
- package/src/langchain/openai.ts +1 -0
- package/src/langchain/prompts.ts +1 -0
- package/src/langchain/runnables.ts +7 -0
- package/src/langchain/tools.ts +8 -0
- package/src/langchain/utils/env.ts +1 -0
- package/src/llm/anthropic/utils/message_inputs.ts +10 -1
- package/src/llm/anthropic/utils/server-tool-inputs.test.ts +436 -0
- package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +166 -18
- package/src/llm/bedrock/cacheSupport.test.ts +99 -0
- package/src/llm/bedrock/cacheSupport.ts +53 -0
- package/src/llm/bedrock/index.ts +116 -41
- package/src/llm/openai/index.ts +2 -2
- package/src/llm/openai/utils/index.ts +31 -14
- package/src/memory/citations.ts +4 -4
- package/src/memory/constants.ts +17 -17
- package/src/memory/mmr.ts +3 -3
- package/src/memory/paths.ts +1 -1
- package/src/memory/recallTracking.ts +3 -3
- package/src/memory/temporalDecay.ts +2 -2
- package/src/memory/types.ts +3 -3
- package/src/messages/__tests__/contextPruning.test.ts +228 -0
- package/src/messages/cache.test.ts +62 -24
- package/src/messages/cache.ts +112 -0
- package/src/messages/contextPruning.ts +191 -0
- package/src/messages/contextPruningSettings.ts +90 -0
- package/src/messages/ensureThinkingBlock.test.ts +1 -1
- package/src/messages/format.ts +164 -12
- package/src/messages/formatAgentMessages.skills.test.ts +413 -0
- package/src/messages/formatAgentMessages.test.ts +1 -1
- package/src/messages/index.ts +2 -0
- package/src/messages/prune.ts +661 -4
- package/src/run.ts +155 -1
- package/src/scripts/multi-agent-chain.ts +2 -2
- package/src/scripts/multi-agent-document-review-chain.ts +2 -2
- package/src/scripts/multi-agent-hybrid-flow.ts +4 -4
- package/src/scripts/multi-agent-parallel.ts +3 -3
- package/src/scripts/multi-agent-sequence.ts +3 -3
- package/src/scripts/multi-agent-subagent.ts +246 -0
- package/src/scripts/multi-agent-supervisor.ts +5 -5
- package/src/scripts/poc-multi-agent-comprehensive.ts +8 -8
- package/src/scripts/sequential-full-metadata-test.ts +2 -2
- package/src/scripts/subagent-event-driven-debug.ts +190 -0
- package/src/scripts/subagent-tools-debug.ts +160 -0
- package/src/scripts/test-custom-prompt-key.ts +3 -3
- package/src/scripts/test-handoff-input.ts +1 -1
- package/src/scripts/test-handoff-steering.ts +3 -3
- package/src/scripts/test-multi-agent-list-handoff.ts +1 -1
- package/src/scripts/test-parallel-agent-labeling.ts +3 -3
- package/src/scripts/test-parallel-handoffs.ts +2 -2
- package/src/scripts/test-thinking-handoff-bedrock.ts +1 -1
- package/src/scripts/test-thinking-handoff.ts +1 -1
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.ts +1 -1
- package/src/scripts/test-tool-before-handoff-role-order.ts +1 -1
- package/src/scripts/test-tools-before-handoff.ts +1 -1
- package/src/specs/agent-handoffs.test.ts +26 -483
- package/src/specs/anthropic.simple.test.ts +61 -0
- package/src/specs/multi-agent-summarization.test.ts +396 -0
- package/src/specs/prune.orphans.test.ts +248 -0
- package/src/specs/prune.test.ts +104 -16
- package/src/specs/thinking-handoff.test.ts +19 -19
- package/src/tools/BashExecutor.ts +281 -0
- package/src/tools/BashProgrammaticToolCalling.ts +397 -0
- package/src/tools/CodeExecutor.ts +63 -54
- package/src/tools/ProgrammaticToolCalling.ts +29 -14
- package/src/tools/ReadFile.ts +39 -0
- package/src/tools/SkillTool.ts +46 -0
- package/src/tools/SubagentTool.ts +100 -0
- package/src/tools/ToolNode.ts +548 -26
- package/src/tools/__tests__/BashExecutor.test.ts +49 -0
- package/src/tools/__tests__/CodeExecutor.test.ts +37 -36
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +60 -0
- package/src/tools/__tests__/ReadFile.test.ts +44 -0
- package/src/tools/__tests__/SkillTool.test.ts +442 -0
- package/src/tools/__tests__/SubagentExecutor.test.ts +1148 -0
- package/src/tools/__tests__/SubagentTool.test.ts +149 -0
- package/src/tools/__tests__/ToolNode.outputReferences.test.ts +1438 -0
- package/src/tools/__tests__/annotateMessagesForLLM.test.ts +479 -0
- package/src/tools/__tests__/skillCatalog.test.ts +161 -0
- package/src/tools/__tests__/subagentHooks.test.ts +210 -0
- package/src/tools/__tests__/toolOutputReferences.test.ts +415 -0
- package/src/tools/memory/memoryAppendTool.ts +1 -1
- package/src/tools/memory/memoryGetTool.ts +2 -2
- package/src/tools/memory/memorySearchTool.ts +3 -3
- package/src/tools/memory/shared.ts +1 -1
- package/src/tools/search/search.ts +12 -2
- package/src/tools/search/tavily-scraper.ts +235 -0
- package/src/tools/search/tavily-search.ts +424 -0
- package/src/tools/search/tavily.test.ts +965 -0
- package/src/tools/search/tool.ts +36 -2
- package/src/tools/search/types.ts +133 -8
- package/src/tools/search/utils.ts +13 -5
- package/src/tools/skillCatalog.ts +126 -0
- package/src/tools/subagent/SubagentExecutor.ts +676 -0
- package/src/tools/subagent/index.ts +13 -0
- package/src/tools/subagent/types.test.ts +70 -0
- package/src/tools/subagent/types.ts +115 -0
- package/src/tools/toolOutputReferences.ts +825 -0
- package/src/types/agent-cache.ts +74 -0
- package/src/types/graph.ts +172 -20
- package/src/types/index.ts +3 -0
- package/src/types/messages.ts +27 -0
- package/src/types/run.ts +22 -0
- package/src/types/skill.ts +11 -0
- package/src/types/tools.ts +118 -0
- package/src/utils/__tests__/truncation.test.ts +66 -0
- package/src/utils/index.ts +1 -3
- package/src/utils/truncation.ts +154 -0
- package/dist/cjs/common/spawnPath.cjs +0 -104
- package/dist/cjs/common/spawnPath.cjs.map +0 -1
- package/dist/cjs/content/ArtifactStore.cjs +0 -579
- package/dist/cjs/content/ArtifactStore.cjs.map +0 -1
- package/dist/cjs/content/ContentStore.cjs +0 -638
- package/dist/cjs/content/ContentStore.cjs.map +0 -1
- package/dist/cjs/content/contentAnalyzer.cjs +0 -91
- package/dist/cjs/content/contentAnalyzer.cjs.map +0 -1
- package/dist/cjs/content/index.cjs +0 -20
- package/dist/cjs/content/index.cjs.map +0 -1
- package/dist/cjs/content/mcpAutoCache.cjs +0 -115
- package/dist/cjs/content/mcpAutoCache.cjs.map +0 -1
- package/dist/cjs/graphs/HandoffRegistry.cjs +0 -143
- package/dist/cjs/graphs/HandoffRegistry.cjs.map +0 -1
- package/dist/cjs/providers/a2a/A2ACapabilityProvider.cjs +0 -288
- package/dist/cjs/providers/a2a/A2ACapabilityProvider.cjs.map +0 -1
- package/dist/cjs/providers/a2a/client.cjs +0 -92
- package/dist/cjs/providers/a2a/client.cjs.map +0 -1
- package/dist/cjs/providers/a2a/config.cjs +0 -38
- package/dist/cjs/providers/a2a/config.cjs.map +0 -1
- package/dist/cjs/providers/capabilityNaming.cjs +0 -43
- package/dist/cjs/providers/capabilityNaming.cjs.map +0 -1
- package/dist/cjs/providers/mcp/MCPCapabilityProvider.cjs +0 -244
- package/dist/cjs/providers/mcp/MCPCapabilityProvider.cjs.map +0 -1
- package/dist/cjs/providers/mcp/config.cjs +0 -42
- package/dist/cjs/providers/mcp/config.cjs.map +0 -1
- package/dist/cjs/providers/mcp/transport.cjs +0 -65
- package/dist/cjs/providers/mcp/transport.cjs.map +0 -1
- package/dist/cjs/providers/tools-server/ToolsServerCapabilityProvider.cjs +0 -128
- package/dist/cjs/providers/tools-server/ToolsServerCapabilityProvider.cjs.map +0 -1
- package/dist/cjs/providers/types.cjs +0 -51
- package/dist/cjs/providers/types.cjs.map +0 -1
- package/dist/cjs/tools/artifacts/schema.cjs +0 -86
- package/dist/cjs/tools/artifacts/schema.cjs.map +0 -1
- package/dist/cjs/tools/artifacts/tool.cjs +0 -219
- package/dist/cjs/tools/artifacts/tool.cjs.map +0 -1
- package/dist/cjs/tools/fileSearch/formatter.cjs +0 -93
- package/dist/cjs/tools/fileSearch/formatter.cjs.map +0 -1
- package/dist/cjs/tools/fileSearch/ragClient.cjs +0 -102
- package/dist/cjs/tools/fileSearch/ragClient.cjs.map +0 -1
- package/dist/cjs/tools/fileSearch/schema.cjs +0 -18
- package/dist/cjs/tools/fileSearch/schema.cjs.map +0 -1
- package/dist/cjs/tools/fileSearch/tool.cjs +0 -155
- package/dist/cjs/tools/fileSearch/tool.cjs.map +0 -1
- package/dist/cjs/tools/proxyTool.cjs +0 -102
- package/dist/cjs/tools/proxyTool.cjs.map +0 -1
- package/dist/cjs/utils/childAgentContext.cjs +0 -242
- package/dist/cjs/utils/childAgentContext.cjs.map +0 -1
- package/dist/cjs/utils/credentials.cjs +0 -142
- package/dist/cjs/utils/credentials.cjs.map +0 -1
- package/dist/cjs/utils/httpClient.cjs +0 -74
- package/dist/cjs/utils/httpClient.cjs.map +0 -1
- package/dist/cjs/utils/toolManifest.cjs +0 -100
- package/dist/cjs/utils/toolManifest.cjs.map +0 -1
- package/dist/esm/common/spawnPath.mjs +0 -95
- package/dist/esm/common/spawnPath.mjs.map +0 -1
- package/dist/esm/content/ArtifactStore.mjs +0 -576
- package/dist/esm/content/ArtifactStore.mjs.map +0 -1
- package/dist/esm/content/ContentStore.mjs +0 -635
- package/dist/esm/content/ContentStore.mjs.map +0 -1
- package/dist/esm/content/contentAnalyzer.mjs +0 -87
- package/dist/esm/content/contentAnalyzer.mjs.map +0 -1
- package/dist/esm/content/index.mjs +0 -5
- package/dist/esm/content/mcpAutoCache.mjs +0 -111
- package/dist/esm/content/mcpAutoCache.mjs.map +0 -1
- package/dist/esm/graphs/HandoffRegistry.mjs +0 -141
- package/dist/esm/graphs/HandoffRegistry.mjs.map +0 -1
- package/dist/esm/providers/a2a/A2ACapabilityProvider.mjs +0 -281
- package/dist/esm/providers/a2a/A2ACapabilityProvider.mjs.map +0 -1
- package/dist/esm/providers/a2a/client.mjs +0 -88
- package/dist/esm/providers/a2a/client.mjs.map +0 -1
- package/dist/esm/providers/a2a/config.mjs +0 -35
- package/dist/esm/providers/a2a/config.mjs.map +0 -1
- package/dist/esm/providers/capabilityNaming.mjs +0 -39
- package/dist/esm/providers/capabilityNaming.mjs.map +0 -1
- package/dist/esm/providers/mcp/MCPCapabilityProvider.mjs +0 -240
- package/dist/esm/providers/mcp/MCPCapabilityProvider.mjs.map +0 -1
- package/dist/esm/providers/mcp/config.mjs +0 -39
- package/dist/esm/providers/mcp/config.mjs.map +0 -1
- package/dist/esm/providers/mcp/transport.mjs +0 -63
- package/dist/esm/providers/mcp/transport.mjs.map +0 -1
- package/dist/esm/providers/tools-server/ToolsServerCapabilityProvider.mjs +0 -126
- package/dist/esm/providers/tools-server/ToolsServerCapabilityProvider.mjs.map +0 -1
- package/dist/esm/providers/types.mjs +0 -51
- package/dist/esm/providers/types.mjs.map +0 -1
- package/dist/esm/tools/artifacts/schema.mjs +0 -79
- package/dist/esm/tools/artifacts/schema.mjs.map +0 -1
- package/dist/esm/tools/artifacts/tool.mjs +0 -213
- package/dist/esm/tools/artifacts/tool.mjs.map +0 -1
- package/dist/esm/tools/fileSearch/formatter.mjs +0 -90
- package/dist/esm/tools/fileSearch/formatter.mjs.map +0 -1
- package/dist/esm/tools/fileSearch/ragClient.mjs +0 -98
- package/dist/esm/tools/fileSearch/ragClient.mjs.map +0 -1
- package/dist/esm/tools/fileSearch/schema.mjs +0 -15
- package/dist/esm/tools/fileSearch/schema.mjs.map +0 -1
- package/dist/esm/tools/fileSearch/tool.mjs +0 -152
- package/dist/esm/tools/fileSearch/tool.mjs.map +0 -1
- package/dist/esm/tools/proxyTool.mjs +0 -100
- package/dist/esm/tools/proxyTool.mjs.map +0 -1
- package/dist/esm/utils/childAgentContext.mjs +0 -237
- package/dist/esm/utils/childAgentContext.mjs.map +0 -1
- package/dist/esm/utils/credentials.mjs +0 -135
- package/dist/esm/utils/credentials.mjs.map +0 -1
- package/dist/esm/utils/httpClient.mjs +0 -70
- package/dist/esm/utils/httpClient.mjs.map +0 -1
- package/dist/esm/utils/toolManifest.mjs +0 -96
- package/dist/esm/utils/toolManifest.mjs.map +0 -1
- package/dist/types/common/spawnPath.d.ts +0 -59
- package/dist/types/content/ArtifactStore.d.ts +0 -223
- package/dist/types/content/ContentStore.d.ts +0 -140
- package/dist/types/content/contentAnalyzer.d.ts +0 -38
- package/dist/types/content/index.d.ts +0 -24
- package/dist/types/content/mcpAutoCache.d.ts +0 -89
- package/dist/types/content/types.d.ts +0 -75
- package/dist/types/graphs/HandoffRegistry.d.ts +0 -97
- package/dist/types/providers/a2a/A2ACapabilityProvider.d.ts +0 -89
- package/dist/types/providers/a2a/client.d.ts +0 -47
- package/dist/types/providers/a2a/config.d.ts +0 -18
- package/dist/types/providers/a2a/index.d.ts +0 -6
- package/dist/types/providers/a2a/types.d.ts +0 -173
- package/dist/types/providers/capabilityNaming.d.ts +0 -25
- package/dist/types/providers/index.d.ts +0 -12
- package/dist/types/providers/mcp/MCPCapabilityProvider.d.ts +0 -54
- package/dist/types/providers/mcp/config.d.ts +0 -20
- package/dist/types/providers/mcp/index.d.ts +0 -5
- package/dist/types/providers/mcp/transport.d.ts +0 -18
- package/dist/types/providers/mcp/types.d.ts +0 -112
- package/dist/types/providers/tools-server/ToolsServerCapabilityProvider.d.ts +0 -59
- package/dist/types/providers/tools-server/index.d.ts +0 -1
- package/dist/types/providers/types.d.ts +0 -184
- package/dist/types/tools/artifacts/index.d.ts +0 -3
- package/dist/types/tools/artifacts/schema.d.ts +0 -63
- package/dist/types/tools/artifacts/tool.d.ts +0 -16
- package/dist/types/tools/artifacts/types.d.ts +0 -127
- package/dist/types/tools/fileSearch/formatter.d.ts +0 -25
- package/dist/types/tools/fileSearch/index.d.ts +0 -5
- package/dist/types/tools/fileSearch/ragClient.d.ts +0 -32
- package/dist/types/tools/fileSearch/schema.d.ts +0 -13
- package/dist/types/tools/fileSearch/tool.d.ts +0 -18
- package/dist/types/tools/fileSearch/types.d.ts +0 -139
- package/dist/types/tools/proxyTool.d.ts +0 -62
- package/dist/types/tools/search/test.d.ts +0 -1
- package/dist/types/utils/childAgentContext.d.ts +0 -99
- package/dist/types/utils/credentials.d.ts +0 -77
- package/dist/types/utils/httpClient.d.ts +0 -46
- package/dist/types/utils/toolManifest.d.ts +0 -49
- package/src/common/__tests__/spawnPath.test.ts +0 -110
- package/src/common/spawnPath.ts +0 -101
- package/src/content/ArtifactStore.ts +0 -782
- package/src/content/ContentStore.ts +0 -753
- package/src/content/contentAnalyzer.ts +0 -105
- package/src/content/index.ts +0 -51
- package/src/content/mcpAutoCache.ts +0 -185
- package/src/content/types.ts +0 -82
- package/src/graphs/HandoffRegistry.ts +0 -199
- package/src/graphs/__tests__/HandoffRegistry.test.ts +0 -410
- package/src/graphs/__tests__/multi-agent-delegate.test.ts +0 -458
- package/src/graphs/__tests__/multi-agent-edges.test.ts +0 -276
- package/src/graphs/__tests__/multi-agent-nested-subgraph.test.ts +0 -221
- package/src/graphs/handoffValidation.test.ts +0 -353
- package/src/providers/__tests__/ToolsServerCapabilityProvider.integration.spec.ts +0 -79
- package/src/providers/__tests__/ToolsServerCapabilityProvider.test.ts +0 -271
- package/src/providers/__tests__/types.test.ts +0 -64
- package/src/providers/a2a/A2ACapabilityProvider.ts +0 -384
- package/src/providers/a2a/__tests__/A2ACapabilityProvider.integration.spec.ts +0 -345
- package/src/providers/a2a/__tests__/A2ACapabilityProvider.test.ts +0 -460
- package/src/providers/a2a/client.ts +0 -115
- package/src/providers/a2a/config.ts +0 -40
- package/src/providers/a2a/index.ts +0 -29
- package/src/providers/a2a/types.ts +0 -191
- package/src/providers/capabilityNaming.ts +0 -42
- package/src/providers/index.ts +0 -68
- package/src/providers/mcp/MCPCapabilityProvider.ts +0 -345
- package/src/providers/mcp/__tests__/MCPCapabilityProvider.integration.spec.ts +0 -386
- package/src/providers/mcp/__tests__/MCPCapabilityProvider.test.ts +0 -371
- package/src/providers/mcp/config.ts +0 -45
- package/src/providers/mcp/index.ts +0 -21
- package/src/providers/mcp/transport.ts +0 -76
- package/src/providers/mcp/types.ts +0 -139
- package/src/providers/tools-server/ToolsServerCapabilityProvider.ts +0 -249
- package/src/providers/tools-server/index.ts +0 -1
- package/src/providers/types.ts +0 -204
- package/src/scripts/test-bedrock-handoff-autonomous.ts +0 -267
- package/src/scripts/test-handoff-preamble.ts +0 -278
- package/src/specs/agent-handoffs-bedrock.integration.test.ts +0 -415
- package/src/tools/artifacts/__tests__/tool.test.ts +0 -259
- package/src/tools/artifacts/index.ts +0 -33
- package/src/tools/artifacts/schema.ts +0 -99
- package/src/tools/artifacts/tool.ts +0 -289
- package/src/tools/artifacts/types.ts +0 -162
- package/src/tools/fileSearch/__tests__/tool.test.ts +0 -261
- package/src/tools/fileSearch/formatter.ts +0 -129
- package/src/tools/fileSearch/index.ts +0 -23
- package/src/tools/fileSearch/ragClient.ts +0 -137
- package/src/tools/fileSearch/schema.ts +0 -19
- package/src/tools/fileSearch/tool.ts +0 -207
- package/src/tools/fileSearch/types.ts +0 -149
- package/src/tools/proxyTool.ts +0 -166
- package/src/tools/search/output.md +0 -2775
- package/src/tools/search/test.html +0 -884
- package/src/tools/search/test.md +0 -643
- package/src/tools/search/test.ts +0 -159
- package/src/utils/__tests__/childAgentContext.test.ts +0 -217
- package/src/utils/__tests__/credentials.test.ts +0 -130
- package/src/utils/__tests__/httpClient.test.ts +0 -75
- package/src/utils/__tests__/toolManifest.test.ts +0 -116
- package/src/utils/childAgentContext.ts +0 -259
- package/src/utils/credentials.ts +0 -157
- package/src/utils/httpClient.ts +0 -92
- package/src/utils/toolManifest.ts +0 -109
- /package/dist/esm/{content → langchain}/index.mjs.map +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { HumanMessage } from '@langchain/core/messages';
|
|
2
|
+
import { FakeListChatModel } from '@langchain/core/utils/testing';
|
|
3
|
+
import type { ToolCall } from '@langchain/core/messages/tool';
|
|
4
|
+
import type * as t from '@/types';
|
|
5
|
+
import type {
|
|
6
|
+
HookCallback,
|
|
7
|
+
SubagentStartHookInput,
|
|
8
|
+
SubagentStartHookOutput,
|
|
9
|
+
SubagentStopHookInput,
|
|
10
|
+
SubagentStopHookOutput,
|
|
11
|
+
} from '@/hooks/types';
|
|
12
|
+
import { HookRegistry } from '@/hooks/HookRegistry';
|
|
13
|
+
import { Run } from '@/run';
|
|
14
|
+
import { Constants, GraphEvents, Providers } from '@/common';
|
|
15
|
+
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
16
|
+
import * as providers from '@/llm/providers';
|
|
17
|
+
|
|
18
|
+
const CHILD_RESPONSE = 'Hook test child response.';
|
|
19
|
+
|
|
20
|
+
const callerConfig = {
|
|
21
|
+
configurable: { thread_id: 'hook-test-thread' },
|
|
22
|
+
streamMode: 'values' as const,
|
|
23
|
+
version: 'v2' as const,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const originalGetChatModelClass = providers.getChatModelClass;
|
|
27
|
+
|
|
28
|
+
function makeSubagentToolCall(): ToolCall {
|
|
29
|
+
return {
|
|
30
|
+
name: Constants.SUBAGENT,
|
|
31
|
+
args: {
|
|
32
|
+
description: 'Test task for hook verification',
|
|
33
|
+
subagent_type: 'researcher',
|
|
34
|
+
},
|
|
35
|
+
id: `call_sub_${Date.now()}`,
|
|
36
|
+
type: 'tool_call',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function createParentAgent(): t.AgentInputs {
|
|
41
|
+
return {
|
|
42
|
+
agentId: 'hook-parent',
|
|
43
|
+
provider: Providers.OPENAI,
|
|
44
|
+
clientOptions: { modelName: 'gpt-4o-mini', apiKey: 'test-key' },
|
|
45
|
+
instructions: 'Delegate research tasks to subagents.',
|
|
46
|
+
maxContextTokens: 8000,
|
|
47
|
+
subagentConfigs: [
|
|
48
|
+
{
|
|
49
|
+
type: 'researcher',
|
|
50
|
+
name: 'Researcher',
|
|
51
|
+
description: 'Researches topics',
|
|
52
|
+
agentInputs: {
|
|
53
|
+
agentId: 'researcher-child',
|
|
54
|
+
provider: Providers.OPENAI,
|
|
55
|
+
clientOptions: { modelName: 'gpt-4o-mini', apiKey: 'test-key' },
|
|
56
|
+
instructions: 'Answer concisely.',
|
|
57
|
+
maxContextTokens: 8000,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function createSubagentRun(
|
|
65
|
+
hooks: HookRegistry,
|
|
66
|
+
runId = `subagent-hook-${Date.now()}`
|
|
67
|
+
): Promise<Run<t.IState>> {
|
|
68
|
+
return Run.create<t.IState>({
|
|
69
|
+
runId,
|
|
70
|
+
graphConfig: {
|
|
71
|
+
type: 'standard',
|
|
72
|
+
agents: [createParentAgent()],
|
|
73
|
+
},
|
|
74
|
+
returnContent: true,
|
|
75
|
+
skipCleanup: true,
|
|
76
|
+
customHandlers: {
|
|
77
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
78
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
79
|
+
},
|
|
80
|
+
hooks,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
describe('Subagent hook integration (end-to-end via Run)', () => {
|
|
85
|
+
jest.setTimeout(15000);
|
|
86
|
+
|
|
87
|
+
let getChatModelClassSpy: jest.SpyInstance;
|
|
88
|
+
|
|
89
|
+
beforeEach(() => {
|
|
90
|
+
getChatModelClassSpy = jest
|
|
91
|
+
.spyOn(providers, 'getChatModelClass')
|
|
92
|
+
.mockImplementation(((provider: Providers) => {
|
|
93
|
+
if (provider === Providers.OPENAI) {
|
|
94
|
+
return class extends FakeListChatModel {
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
96
|
+
constructor(_options: any) {
|
|
97
|
+
super({ responses: [CHILD_RESPONSE] });
|
|
98
|
+
}
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
+
} as any;
|
|
101
|
+
}
|
|
102
|
+
return originalGetChatModelClass(provider);
|
|
103
|
+
}) as typeof providers.getChatModelClass);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
afterEach(() => {
|
|
107
|
+
getChatModelClassSpy.mockRestore();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('SubagentStart fires with correct payload through real Run pipeline', async () => {
|
|
111
|
+
const registry = new HookRegistry();
|
|
112
|
+
let captured: SubagentStartHookInput | undefined;
|
|
113
|
+
|
|
114
|
+
const hook: HookCallback<'SubagentStart'> = async (
|
|
115
|
+
input
|
|
116
|
+
): Promise<SubagentStartHookOutput> => {
|
|
117
|
+
captured = input;
|
|
118
|
+
return {};
|
|
119
|
+
};
|
|
120
|
+
registry.register('SubagentStart', { hooks: [hook] });
|
|
121
|
+
|
|
122
|
+
const tc = makeSubagentToolCall();
|
|
123
|
+
const run = await createSubagentRun(registry);
|
|
124
|
+
run.Graph!.overrideTestModel(['Delegating...', 'Final answer.'], 5, [tc]);
|
|
125
|
+
|
|
126
|
+
await run.processStream(
|
|
127
|
+
{ messages: [new HumanMessage('research something')] },
|
|
128
|
+
callerConfig
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
expect(captured).toBeDefined();
|
|
132
|
+
expect(captured!.hook_event_name).toBe('SubagentStart');
|
|
133
|
+
expect(captured!.agentType).toBe('researcher');
|
|
134
|
+
expect(captured!.parentAgentId).toBe('hook-parent');
|
|
135
|
+
expect(captured!.threadId).toBe('hook-test-thread');
|
|
136
|
+
expect(captured!.inputs).toHaveLength(1);
|
|
137
|
+
expect(captured!.inputs[0].content).toContain(
|
|
138
|
+
'Test task for hook verification'
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('SubagentStop fires with messages from child execution', async () => {
|
|
143
|
+
const registry = new HookRegistry();
|
|
144
|
+
let captured: SubagentStopHookInput | undefined;
|
|
145
|
+
|
|
146
|
+
const hook: HookCallback<'SubagentStop'> = async (
|
|
147
|
+
input
|
|
148
|
+
): Promise<SubagentStopHookOutput> => {
|
|
149
|
+
captured = input;
|
|
150
|
+
return {};
|
|
151
|
+
};
|
|
152
|
+
registry.register('SubagentStop', { hooks: [hook] });
|
|
153
|
+
|
|
154
|
+
const tc = makeSubagentToolCall();
|
|
155
|
+
const run = await createSubagentRun(registry);
|
|
156
|
+
run.Graph!.overrideTestModel(['Delegating...', 'Final answer.'], 5, [tc]);
|
|
157
|
+
|
|
158
|
+
await run.processStream(
|
|
159
|
+
{ messages: [new HumanMessage('research something')] },
|
|
160
|
+
callerConfig
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
expect(captured).toBeDefined();
|
|
164
|
+
expect(captured!.hook_event_name).toBe('SubagentStop');
|
|
165
|
+
expect(captured!.agentType).toBe('researcher');
|
|
166
|
+
expect(captured!.threadId).toBe('hook-test-thread');
|
|
167
|
+
expect(captured!.messages.length).toBeGreaterThan(0);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('SubagentStart deny blocks subagent execution and returns blocked message', async () => {
|
|
171
|
+
const registry = new HookRegistry();
|
|
172
|
+
const denyHook: HookCallback<
|
|
173
|
+
'SubagentStart'
|
|
174
|
+
> = async (): Promise<SubagentStartHookOutput> => ({
|
|
175
|
+
decision: 'deny',
|
|
176
|
+
reason: 'policy violation',
|
|
177
|
+
});
|
|
178
|
+
registry.register('SubagentStart', {
|
|
179
|
+
pattern: '^researcher$',
|
|
180
|
+
hooks: [denyHook],
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const tc = makeSubagentToolCall();
|
|
184
|
+
const run = await createSubagentRun(registry);
|
|
185
|
+
run.Graph!.overrideTestModel(
|
|
186
|
+
['Delegating...', 'The subagent was blocked.'],
|
|
187
|
+
5,
|
|
188
|
+
[tc]
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
await run.processStream(
|
|
192
|
+
{ messages: [new HumanMessage('research something')] },
|
|
193
|
+
callerConfig
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const runMessages = run.getRunMessages();
|
|
197
|
+
expect(runMessages).toBeDefined();
|
|
198
|
+
|
|
199
|
+
const toolMessages = runMessages!.filter(
|
|
200
|
+
(msg) =>
|
|
201
|
+
msg._getType() === 'tool' &&
|
|
202
|
+
'name' in msg &&
|
|
203
|
+
msg.name === Constants.SUBAGENT
|
|
204
|
+
);
|
|
205
|
+
expect(toolMessages.length).toBe(1);
|
|
206
|
+
expect(String(toolMessages[0].content)).toContain(
|
|
207
|
+
'Blocked: policy violation'
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { describe, it, expect } from '@jest/globals';
|
|
2
|
+
import {
|
|
3
|
+
ToolOutputReferenceRegistry,
|
|
4
|
+
annotateToolOutputWithReference,
|
|
5
|
+
buildReferenceKey,
|
|
6
|
+
buildReferencePrefix,
|
|
7
|
+
TOOL_OUTPUT_REF_KEY,
|
|
8
|
+
TOOL_OUTPUT_REF_PATTERN,
|
|
9
|
+
} from '../toolOutputReferences';
|
|
10
|
+
|
|
11
|
+
describe('ToolOutputReferenceRegistry', () => {
|
|
12
|
+
describe('buildReferenceKey', () => {
|
|
13
|
+
it('formats keys as tool<idx>turn<turn>', () => {
|
|
14
|
+
expect(buildReferenceKey(0, 0)).toBe('tool0turn0');
|
|
15
|
+
expect(buildReferenceKey(3, 7)).toBe('tool3turn7');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe('set / get', () => {
|
|
20
|
+
it('stores and retrieves outputs by key', () => {
|
|
21
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
22
|
+
reg.set('r', 'tool0turn0', 'hello world');
|
|
23
|
+
expect(reg.get('r', 'tool0turn0')).toBe('hello world');
|
|
24
|
+
expect(reg.size).toBe(1);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('clips stored values to the per-output limit', () => {
|
|
28
|
+
const reg = new ToolOutputReferenceRegistry({ maxOutputSize: 5 });
|
|
29
|
+
reg.set('r', 'tool0turn0', 'abcdefghij');
|
|
30
|
+
expect(reg.get('r', 'tool0turn0')).toBe('abcde');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('replaces existing entries under the same key without double-counting size', () => {
|
|
34
|
+
const reg = new ToolOutputReferenceRegistry({
|
|
35
|
+
maxOutputSize: 100,
|
|
36
|
+
maxTotalSize: 20,
|
|
37
|
+
});
|
|
38
|
+
reg.set('r', 'tool0turn0', 'hello');
|
|
39
|
+
reg.set('r', 'tool0turn0', 'world-longer');
|
|
40
|
+
expect(reg.get('r', 'tool0turn0')).toBe('world-longer');
|
|
41
|
+
expect(reg.size).toBe(1);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('clear / releaseRun', () => {
|
|
46
|
+
it('clear() drops every run bucket', () => {
|
|
47
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
48
|
+
reg.set('run-A', 'tool0turn0', 'A');
|
|
49
|
+
reg.set('run-B', 'tool0turn0', 'B');
|
|
50
|
+
expect(reg.size).toBe(2);
|
|
51
|
+
reg.clear();
|
|
52
|
+
expect(reg.size).toBe(0);
|
|
53
|
+
expect(reg.get('run-A', 'tool0turn0')).toBeUndefined();
|
|
54
|
+
expect(reg.get('run-B', 'tool0turn0')).toBeUndefined();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('releaseRun() drops only the named run', () => {
|
|
58
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
59
|
+
reg.set('run-A', 'tool0turn0', 'A');
|
|
60
|
+
reg.set('run-B', 'tool0turn0', 'B');
|
|
61
|
+
reg.releaseRun('run-A');
|
|
62
|
+
expect(reg.get('run-A', 'tool0turn0')).toBeUndefined();
|
|
63
|
+
expect(reg.get('run-B', 'tool0turn0')).toBe('B');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('FIFO eviction', () => {
|
|
68
|
+
it('evicts oldest entries when the aggregate cap is exceeded', () => {
|
|
69
|
+
const reg = new ToolOutputReferenceRegistry({
|
|
70
|
+
maxOutputSize: 10,
|
|
71
|
+
maxTotalSize: 12,
|
|
72
|
+
});
|
|
73
|
+
reg.set('r', 'tool0turn0', '1234567'); // 7 chars
|
|
74
|
+
reg.set('r', 'tool1turn0', '89'); // 9 total
|
|
75
|
+
reg.set('r', 'tool2turn0', 'abc'); // 12 total — at limit
|
|
76
|
+
reg.set('r', 'tool3turn0', 'XY'); // 14 → must evict oldest
|
|
77
|
+
expect(reg.get('r', 'tool0turn0')).toBeUndefined();
|
|
78
|
+
expect(reg.get('r', 'tool1turn0')).toBe('89');
|
|
79
|
+
expect(reg.get('r', 'tool2turn0')).toBe('abc');
|
|
80
|
+
expect(reg.get('r', 'tool3turn0')).toBe('XY');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('keeps evicting oldest entries until the aggregate fits', () => {
|
|
84
|
+
const reg = new ToolOutputReferenceRegistry({
|
|
85
|
+
maxOutputSize: 10,
|
|
86
|
+
maxTotalSize: 8,
|
|
87
|
+
});
|
|
88
|
+
reg.set('r', 'tool0turn0', 'aaa');
|
|
89
|
+
reg.set('r', 'tool1turn0', 'bbb');
|
|
90
|
+
reg.set('r', 'tool2turn0', 'ccccccc'); // total 3+3+7=13 > 8, evict aaa then bbb
|
|
91
|
+
expect(reg.get('r', 'tool0turn0')).toBeUndefined();
|
|
92
|
+
expect(reg.get('r', 'tool1turn0')).toBeUndefined();
|
|
93
|
+
expect(reg.get('r', 'tool2turn0')).toBe('ccccccc');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('clamps the per-output cap to maxTotalSize so no entry exceeds the aggregate', () => {
|
|
97
|
+
const reg = new ToolOutputReferenceRegistry({
|
|
98
|
+
maxOutputSize: 1000,
|
|
99
|
+
maxTotalSize: 10,
|
|
100
|
+
});
|
|
101
|
+
reg.set('r', 'tool0turn0', 'x'.repeat(500));
|
|
102
|
+
const stored = reg.get('r', 'tool0turn0');
|
|
103
|
+
expect(stored).toBeDefined();
|
|
104
|
+
expect(stored!.length).toBeLessThanOrEqual(10);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('clamps a caller-supplied maxTotalSize to the documented hard cap', () => {
|
|
108
|
+
// 50 MB requested; should be clamped to the 5 MB hard cap.
|
|
109
|
+
const reg = new ToolOutputReferenceRegistry({
|
|
110
|
+
maxTotalSize: 50_000_000,
|
|
111
|
+
});
|
|
112
|
+
// `totalLimit` getter exposes the effective post-clamp value.
|
|
113
|
+
expect(reg.totalLimit).toBeLessThanOrEqual(5_000_000);
|
|
114
|
+
// Per-output is also bound by the same effective total.
|
|
115
|
+
expect(reg.perOutputLimit).toBeLessThanOrEqual(5_000_000);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('evicts the oldest run bucket when maxActiveRuns is exceeded', () => {
|
|
119
|
+
const reg = new ToolOutputReferenceRegistry({ maxActiveRuns: 2 });
|
|
120
|
+
reg.set('run-A', 'tool0turn0', 'A');
|
|
121
|
+
reg.set('run-B', 'tool0turn0', 'B');
|
|
122
|
+
reg.set('run-C', 'tool0turn0', 'C');
|
|
123
|
+
// run-A was the oldest insertion; LRU evicted it when run-C
|
|
124
|
+
// pushed the bucket count above the cap.
|
|
125
|
+
expect(reg.get('run-A', 'tool0turn0')).toBeUndefined();
|
|
126
|
+
expect(reg.get('run-B', 'tool0turn0')).toBe('B');
|
|
127
|
+
expect(reg.get('run-C', 'tool0turn0')).toBe('C');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe('resolve', () => {
|
|
132
|
+
it('replaces placeholders in string args', () => {
|
|
133
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
134
|
+
reg.set('r', 'tool0turn0', 'HELLO');
|
|
135
|
+
const { resolved, unresolved } = reg.resolve('r', 'echo {{tool0turn0}}');
|
|
136
|
+
expect(resolved).toBe('echo HELLO');
|
|
137
|
+
expect(unresolved).toEqual([]);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('replaces placeholders in nested object args', () => {
|
|
141
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
142
|
+
reg.set('r', 'tool0turn0', 'DATA');
|
|
143
|
+
const input = {
|
|
144
|
+
command: 'cat {{tool0turn0}}',
|
|
145
|
+
meta: { note: 'uses {{tool0turn0}} twice' },
|
|
146
|
+
};
|
|
147
|
+
const { resolved } = reg.resolve('r', input);
|
|
148
|
+
expect(resolved).toEqual({
|
|
149
|
+
command: 'cat DATA',
|
|
150
|
+
meta: { note: 'uses DATA twice' },
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('replaces placeholders inside array values', () => {
|
|
155
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
156
|
+
reg.set('r', 'tool1turn2', '42');
|
|
157
|
+
const { resolved } = reg.resolve('r', {
|
|
158
|
+
args: ['--id', '{{tool1turn2}}', 'plain'],
|
|
159
|
+
});
|
|
160
|
+
expect(resolved).toEqual({ args: ['--id', '42', 'plain'] });
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('reports unresolved references and leaves the placeholder in place', () => {
|
|
164
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
165
|
+
reg.set('r', 'tool0turn0', 'known');
|
|
166
|
+
const { resolved, unresolved } = reg.resolve(
|
|
167
|
+
'r',
|
|
168
|
+
'use {{tool0turn0}} and {{tool5turn9}}'
|
|
169
|
+
);
|
|
170
|
+
expect(resolved).toBe('use known and {{tool5turn9}}');
|
|
171
|
+
expect(unresolved).toEqual(['tool5turn9']);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('deduplicates repeated unresolved keys', () => {
|
|
175
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
176
|
+
const { unresolved } = reg.resolve(
|
|
177
|
+
'r',
|
|
178
|
+
'{{tool7turn0}} and {{tool7turn0}} again'
|
|
179
|
+
);
|
|
180
|
+
expect(unresolved).toEqual(['tool7turn0']);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('does not touch non-placeholder strings', () => {
|
|
184
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
185
|
+
reg.set('r', 'tool0turn0', 'X');
|
|
186
|
+
const { resolved } = reg.resolve('r', 'nothing to see here');
|
|
187
|
+
expect(resolved).toBe('nothing to see here');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('passes through primitive values untouched', () => {
|
|
191
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
192
|
+
const { resolved } = reg.resolve('r', {
|
|
193
|
+
count: 3,
|
|
194
|
+
enabled: true,
|
|
195
|
+
note: null,
|
|
196
|
+
});
|
|
197
|
+
expect(resolved).toEqual({ count: 3, enabled: true, note: null });
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe('snapshot', () => {
|
|
202
|
+
it('resolves against the captured state and ignores later mutations', () => {
|
|
203
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
204
|
+
reg.set('r', 'tool0turn0', 'OLD');
|
|
205
|
+
const view = reg.snapshot('r');
|
|
206
|
+
// Mutate after taking the snapshot.
|
|
207
|
+
reg.set('r', 'tool0turn0', 'NEW');
|
|
208
|
+
reg.set('r', 'tool1turn0', 'LATER');
|
|
209
|
+
// Snapshot still resolves to the captured value and treats
|
|
210
|
+
// post-snapshot additions as unresolved.
|
|
211
|
+
expect(view.resolve('echo {{tool0turn0}}').resolved).toBe('echo OLD');
|
|
212
|
+
const { resolved, unresolved } = view.resolve('see {{tool1turn0}}');
|
|
213
|
+
expect(resolved).toBe('see {{tool1turn0}}');
|
|
214
|
+
expect(unresolved).toEqual(['tool1turn0']);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('returns an empty view for a runId with no bucket', () => {
|
|
218
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
219
|
+
const view = reg.snapshot('never-touched');
|
|
220
|
+
const { resolved, unresolved } = view.resolve('see {{tool0turn0}}');
|
|
221
|
+
expect(resolved).toBe('see {{tool0turn0}}');
|
|
222
|
+
expect(unresolved).toEqual(['tool0turn0']);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('returns an isolated view per snapshot call', () => {
|
|
226
|
+
const reg = new ToolOutputReferenceRegistry();
|
|
227
|
+
reg.set('r', 'tool0turn0', 'A');
|
|
228
|
+
const view1 = reg.snapshot('r');
|
|
229
|
+
reg.set('r', 'tool0turn0', 'B');
|
|
230
|
+
const view2 = reg.snapshot('r');
|
|
231
|
+
expect(view1.resolve('{{tool0turn0}}').resolved).toBe('A');
|
|
232
|
+
expect(view2.resolve('{{tool0turn0}}').resolved).toBe('B');
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
describe('annotateToolOutputWithReference', () => {
|
|
237
|
+
it('injects _ref into plain JSON objects', () => {
|
|
238
|
+
const content = '{"a":1,"b":"x"}';
|
|
239
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
240
|
+
const parsed = JSON.parse(annotated);
|
|
241
|
+
expect(parsed[TOOL_OUTPUT_REF_KEY]).toBe('tool0turn0');
|
|
242
|
+
expect(parsed.a).toBe(1);
|
|
243
|
+
expect(parsed.b).toBe('x');
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('preserves pretty-printed formatting when the original was pretty', () => {
|
|
247
|
+
const content = '{\n "a": 1\n}';
|
|
248
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
249
|
+
expect(annotated).toContain('\n "');
|
|
250
|
+
const parsed = JSON.parse(annotated);
|
|
251
|
+
expect(parsed[TOOL_OUTPUT_REF_KEY]).toBe('tool0turn0');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('uses the [ref: …] prefix for JSON arrays', () => {
|
|
255
|
+
const content = '[1,2,3]';
|
|
256
|
+
const annotated = annotateToolOutputWithReference(content, 'tool1turn0');
|
|
257
|
+
expect(annotated).toBe(`${buildReferencePrefix('tool1turn0')}\n[1,2,3]`);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('uses the [ref: …] prefix for JSON primitives', () => {
|
|
261
|
+
expect(annotateToolOutputWithReference('42', 'tool0turn0')).toBe(
|
|
262
|
+
'[ref: tool0turn0]\n42'
|
|
263
|
+
);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it('uses the [ref: …] prefix for plain strings', () => {
|
|
267
|
+
expect(annotateToolOutputWithReference('hello', 'tool0turn0')).toBe(
|
|
268
|
+
'[ref: tool0turn0]\nhello'
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('falls back to the prefix on JSON _ref collision', () => {
|
|
273
|
+
const content = '{"_ref":"other-value","data":1}';
|
|
274
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
275
|
+
expect(annotated.startsWith('[ref: tool0turn0]\n')).toBe(true);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('injects when the existing _ref matches the target key', () => {
|
|
279
|
+
const content = '{"_ref":"tool0turn0","data":1}';
|
|
280
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
281
|
+
const parsed = JSON.parse(annotated);
|
|
282
|
+
expect(parsed._ref).toBe('tool0turn0');
|
|
283
|
+
expect(parsed.data).toBe(1);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('overwrites an existing _ref:null with the injected key', () => {
|
|
287
|
+
const content = '{"_ref":null,"data":1}';
|
|
288
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
289
|
+
const parsed = JSON.parse(annotated);
|
|
290
|
+
expect(parsed._ref).toBe('tool0turn0');
|
|
291
|
+
expect(parsed.data).toBe(1);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it('places the injected _ref as the first key in the serialized JSON', () => {
|
|
295
|
+
const content = '{"a":1,"b":"x"}';
|
|
296
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
297
|
+
expect(annotated.indexOf('"_ref"')).toBe(1);
|
|
298
|
+
const annotatedFromNull = annotateToolOutputWithReference(
|
|
299
|
+
'{"_ref":null,"a":1}',
|
|
300
|
+
'tool0turn0'
|
|
301
|
+
);
|
|
302
|
+
expect(annotatedFromNull.indexOf('"_ref"')).toBe(1);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('falls back to the prefix when parsing fails', () => {
|
|
306
|
+
const content = '{ not actually json';
|
|
307
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
308
|
+
expect(annotated).toBe(`[ref: tool0turn0]\n${content}`);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('carries unresolved refs as a JSON field on parseable objects', () => {
|
|
312
|
+
const content = '{"a":1}';
|
|
313
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0', [
|
|
314
|
+
'tool9turn9',
|
|
315
|
+
'tool7turn0',
|
|
316
|
+
]);
|
|
317
|
+
const parsed = JSON.parse(annotated);
|
|
318
|
+
expect(parsed._ref).toBe('tool0turn0');
|
|
319
|
+
expect(parsed._unresolved_refs).toEqual(['tool9turn9', 'tool7turn0']);
|
|
320
|
+
expect(parsed.a).toBe(1);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it('appends unresolved refs as a trailer line on non-object content', () => {
|
|
324
|
+
const annotated = annotateToolOutputWithReference(
|
|
325
|
+
'plain text',
|
|
326
|
+
'tool0turn0',
|
|
327
|
+
['tool9turn9']
|
|
328
|
+
);
|
|
329
|
+
expect(annotated).toBe(
|
|
330
|
+
'[ref: tool0turn0]\nplain text\n[unresolved refs: tool9turn9]'
|
|
331
|
+
);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it('supports unresolved-only annotation (no ref key)', () => {
|
|
335
|
+
const annotated = annotateToolOutputWithReference(
|
|
336
|
+
'error text',
|
|
337
|
+
undefined,
|
|
338
|
+
['tool9turn9']
|
|
339
|
+
);
|
|
340
|
+
expect(annotated).toBe('error text\n[unresolved refs: tool9turn9]');
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('keeps JSON parseable for unresolved-only annotation on object content', () => {
|
|
344
|
+
const annotated = annotateToolOutputWithReference(
|
|
345
|
+
'{"error":"bad"}',
|
|
346
|
+
undefined,
|
|
347
|
+
['tool9turn9']
|
|
348
|
+
);
|
|
349
|
+
const parsed = JSON.parse(annotated);
|
|
350
|
+
expect(parsed._unresolved_refs).toEqual(['tool9turn9']);
|
|
351
|
+
expect(parsed.error).toBe('bad');
|
|
352
|
+
expect(parsed._ref).toBeUndefined();
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('returns content unchanged when there is nothing to annotate', () => {
|
|
356
|
+
expect(annotateToolOutputWithReference('plain', undefined, [])).toBe(
|
|
357
|
+
'plain'
|
|
358
|
+
);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('preserves an existing _unresolved_refs payload when only injecting a ref key', () => {
|
|
362
|
+
const content = '{"data":1,"_unresolved_refs":["user-supplied"]}';
|
|
363
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0');
|
|
364
|
+
const parsed = JSON.parse(annotated);
|
|
365
|
+
expect(parsed._ref).toBe('tool0turn0');
|
|
366
|
+
expect(parsed._unresolved_refs).toEqual(['user-supplied']);
|
|
367
|
+
expect(parsed.data).toBe(1);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it('preserves an existing _ref payload on the unresolved-only path', () => {
|
|
371
|
+
const content = '{"data":1,"_ref":"preserved-value"}';
|
|
372
|
+
const annotated = annotateToolOutputWithReference(content, undefined, [
|
|
373
|
+
'tool9turn9',
|
|
374
|
+
]);
|
|
375
|
+
const parsed = JSON.parse(annotated);
|
|
376
|
+
expect(parsed._ref).toBe('preserved-value');
|
|
377
|
+
expect(parsed._unresolved_refs).toEqual(['tool9turn9']);
|
|
378
|
+
expect(parsed.data).toBe(1);
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it('falls back to the prefix when _unresolved_refs conflicts with a non-matching array', () => {
|
|
382
|
+
const content = '{"data":1,"_unresolved_refs":["legacy"]}';
|
|
383
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0', [
|
|
384
|
+
'tool9turn9',
|
|
385
|
+
]);
|
|
386
|
+
expect(annotated.startsWith('[ref: tool0turn0]\n')).toBe(true);
|
|
387
|
+
expect(annotated).toContain('[unresolved refs: tool9turn9]');
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it('accepts a deep-equal existing _unresolved_refs array', () => {
|
|
391
|
+
const content = '{"data":1,"_unresolved_refs":["tool9turn9"]}';
|
|
392
|
+
const annotated = annotateToolOutputWithReference(content, 'tool0turn0', [
|
|
393
|
+
'tool9turn9',
|
|
394
|
+
]);
|
|
395
|
+
const parsed = JSON.parse(annotated);
|
|
396
|
+
expect(parsed._unresolved_refs).toEqual(['tool9turn9']);
|
|
397
|
+
expect(parsed._ref).toBe('tool0turn0');
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
describe('TOOL_OUTPUT_REF_PATTERN', () => {
|
|
402
|
+
it('matches braced tool<N>turn<M> tokens and captures the key', () => {
|
|
403
|
+
const match = '{{tool0turn0}}'.match(TOOL_OUTPUT_REF_PATTERN);
|
|
404
|
+
expect(match?.[1]).toBe('tool0turn0');
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it('rejects bare tool<N>turn<M> tokens without braces', () => {
|
|
408
|
+
expect(TOOL_OUTPUT_REF_PATTERN.test('tool0turn0')).toBe(false);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('is non-global so callers cannot trip on stale lastIndex', () => {
|
|
412
|
+
expect(TOOL_OUTPUT_REF_PATTERN.flags).not.toContain('g');
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `memory_append` — the reflection-phase-only write tool.
|
|
3
3
|
*
|
|
4
|
-
* New (not present in
|
|
4
|
+
* New (not present in verbatim). Reference implementations enforce append-only via
|
|
5
5
|
* `wrapToolMemoryFlushAppendOnlyWrite`; we combine the tool and the phase
|
|
6
6
|
* gate in one place because the agents library has a simpler graph state.
|
|
7
7
|
*
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `memory_search` — the mandatory-recall tool.
|
|
3
3
|
*
|
|
4
|
-
* Port of
|
|
5
|
-
* `
|
|
6
|
-
* is verbatim "Mandatory recall step..." from
|
|
4
|
+
* Port of `createMemorySearchTool` at
|
|
5
|
+
* `reference`. The tool description
|
|
6
|
+
* is verbatim "Mandatory recall step..." from a reference implementation — this is the load-
|
|
7
7
|
* bearing line that turns "the agent may recall" into "the agent will recall".
|
|
8
8
|
*/
|
|
9
9
|
import { tool } from '@langchain/core/tools';
|
|
@@ -117,7 +117,7 @@ export function buildMemorySearchUnavailableResult(
|
|
|
117
117
|
|
|
118
118
|
/**
|
|
119
119
|
* Clamp a ranked result list to a total character budget.
|
|
120
|
-
* Ported from
|
|
120
|
+
* Ported from a reference implementation `tools.citations.ts::clampResultsByInjectedChars`.
|
|
121
121
|
*/
|
|
122
122
|
export function clampResultsByInjectedChars<T extends { content: string }>(
|
|
123
123
|
results: T[],
|