@illuma-ai/agents 1.0.89 → 1.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/agents/AgentContext.cjs +98 -49
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/constants.cjs +25 -0
- package/dist/cjs/common/constants.cjs.map +1 -0
- package/dist/cjs/common/enum.cjs +30 -0
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/events.cjs +9 -4
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +397 -92
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +223 -92
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +30 -14
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/index.cjs +43 -11
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +10 -7
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +32 -0
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +129 -101
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +489 -0
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -0
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +176 -0
- package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -0
- package/dist/cjs/llm/fake.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +1 -1
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +59 -5
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs.map +1 -1
- package/dist/cjs/llm/text.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +80 -2
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +60 -27
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +131 -108
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/content.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +3 -0
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +265 -47
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/ids.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +55 -2
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/summarize.cjs +170 -0
- package/dist/cjs/messages/summarize.cjs.map +1 -0
- package/dist/cjs/messages/tools.cjs.map +1 -1
- package/dist/cjs/run.cjs +87 -30
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/schemas/validate.cjs.map +1 -1
- package/dist/cjs/splitStream.cjs.map +1 -1
- package/dist/cjs/stream.cjs +59 -25
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/AskUser.cjs +131 -0
- package/dist/cjs/tools/AskUser.cjs.map +1 -0
- package/dist/cjs/tools/BrowserTools.cjs +11 -7
- package/dist/cjs/tools/BrowserTools.cjs.map +1 -1
- package/dist/cjs/tools/Calculator.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +46 -4
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +36 -53
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/StreamingToolCallBuffer.cjs +208 -0
- package/dist/cjs/tools/StreamingToolCallBuffer.cjs.map +1 -0
- package/dist/cjs/tools/ToolNode.cjs +333 -30
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/ToolSearch.cjs +66 -30
- package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +94 -8
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/tools/schema.cjs.map +1 -1
- package/dist/cjs/tools/search/content.cjs.map +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/highlights.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/schema.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +1 -0
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/types/graph.cjs +1 -1
- package/dist/cjs/types/graph.cjs.map +1 -1
- package/dist/cjs/utils/contextAnalytics.cjs +23 -6
- package/dist/cjs/utils/contextAnalytics.cjs.map +1 -1
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/cjs/utils/graph.cjs.map +1 -1
- package/dist/cjs/utils/handlers.cjs.map +1 -1
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/misc.cjs.map +1 -1
- package/dist/cjs/utils/run.cjs +3 -1
- package/dist/cjs/utils/run.cjs.map +1 -1
- package/dist/cjs/utils/schema.cjs.map +1 -1
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +33 -58
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/cjs/utils/toolCallContinuation.cjs +55 -0
- package/dist/cjs/utils/toolCallContinuation.cjs.map +1 -0
- package/dist/cjs/utils/toonFormat.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +98 -49
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/constants.mjs +22 -0
- package/dist/esm/common/constants.mjs.map +1 -0
- package/dist/esm/common/enum.mjs +31 -1
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/events.mjs +9 -4
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +393 -88
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +224 -93
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +30 -14
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/llm/anthropic/index.mjs +43 -11
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +10 -7
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +32 -0
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +128 -101
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +484 -0
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -0
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs +171 -0
- package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -0
- package/dist/esm/llm/fake.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +1 -1
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +59 -5
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs.map +1 -1
- package/dist/esm/llm/text.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +80 -2
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +8 -3
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +131 -108
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/content.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +4 -1
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +267 -49
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/ids.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +56 -4
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/summarize.mjs +161 -0
- package/dist/esm/messages/summarize.mjs.map +1 -0
- package/dist/esm/messages/tools.mjs.map +1 -1
- package/dist/esm/run.mjs +88 -31
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/schemas/validate.mjs.map +1 -1
- package/dist/esm/splitStream.mjs.map +1 -1
- package/dist/esm/stream.mjs +60 -26
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/AskUser.mjs +125 -0
- package/dist/esm/tools/AskUser.mjs.map +1 -0
- package/dist/esm/tools/BrowserTools.mjs +11 -7
- package/dist/esm/tools/BrowserTools.mjs.map +1 -1
- package/dist/esm/tools/Calculator.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +46 -4
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +37 -54
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/StreamingToolCallBuffer.mjs +206 -0
- package/dist/esm/tools/StreamingToolCallBuffer.mjs.map +1 -0
- package/dist/esm/tools/ToolNode.mjs +333 -30
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/ToolSearch.mjs +66 -30
- package/dist/esm/tools/ToolSearch.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +95 -9
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/tools/schema.mjs.map +1 -1
- package/dist/esm/tools/search/content.mjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/highlights.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/schema.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +1 -0
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/types/graph.mjs +1 -1
- package/dist/esm/types/graph.mjs.map +1 -1
- package/dist/esm/utils/contextAnalytics.mjs +23 -6
- package/dist/esm/utils/contextAnalytics.mjs.map +1 -1
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/esm/utils/graph.mjs.map +1 -1
- package/dist/esm/utils/handlers.mjs.map +1 -1
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/misc.mjs.map +1 -1
- package/dist/esm/utils/run.mjs +3 -1
- package/dist/esm/utils/run.mjs.map +1 -1
- package/dist/esm/utils/schema.mjs.map +1 -1
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +33 -59
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/esm/utils/toolCallContinuation.mjs +52 -0
- package/dist/esm/utils/toolCallContinuation.mjs.map +1 -0
- package/dist/esm/utils/toonFormat.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +14 -7
- package/dist/types/common/constants.d.ts +18 -0
- package/dist/types/common/enum.d.ts +28 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/events.d.ts +10 -3
- package/dist/types/graphs/Graph.d.ts +37 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/llm/anthropic/index.d.ts +7 -1
- package/dist/types/llm/anthropic/types.d.ts +5 -2
- package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -1
- package/dist/types/llm/bedrock/index.d.ts +40 -33
- package/dist/types/llm/bedrock/utils/message_outputs.d.ts +1 -1
- package/dist/types/llm/google/index.d.ts +2 -3
- package/dist/types/llm/openrouter/index.d.ts +21 -1
- package/dist/types/llm/vertexai/index.d.ts +3 -2
- package/dist/types/messages/cache.d.ts +1 -1
- package/dist/types/messages/index.d.ts +1 -0
- package/dist/types/messages/prune.d.ts +2 -7
- package/dist/types/messages/summarize.d.ts +33 -0
- package/dist/types/run.d.ts +6 -0
- package/dist/types/tools/AskUser.d.ts +408 -0
- package/dist/types/tools/BrowserTools.d.ts +2 -2
- package/dist/types/tools/CodeExecutor.d.ts +2 -2
- package/dist/types/tools/StreamingToolCallBuffer.d.ts +106 -0
- package/dist/types/tools/ToolNode.d.ts +55 -3
- package/dist/types/tools/ToolSearch.d.ts +9 -5
- package/dist/types/tools/handlers.d.ts +2 -2
- package/dist/types/types/graph.d.ts +9 -2
- package/dist/types/types/llm.d.ts +8 -3
- package/dist/types/types/run.d.ts +2 -0
- package/dist/types/types/tools.d.ts +20 -2
- package/dist/types/utils/contextAnalytics.d.ts +5 -4
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/tokens.d.ts +6 -19
- package/dist/types/utils/toolCallContinuation.d.ts +30 -0
- package/package.json +15 -8
- package/src/agents/AgentContext.js +782 -0
- package/src/agents/AgentContext.js.map +1 -0
- package/src/agents/AgentContext.test.js +421 -0
- package/src/agents/AgentContext.test.js.map +1 -0
- package/src/agents/AgentContext.ts +132 -64
- package/src/agents/__tests__/AgentContext.test.js +678 -0
- package/src/agents/__tests__/AgentContext.test.js.map +1 -0
- package/src/agents/__tests__/AgentContext.test.ts +25 -4
- package/src/agents/__tests__/resolveStructuredOutputMode.test.js +117 -0
- package/src/agents/__tests__/resolveStructuredOutputMode.test.js.map +1 -0
- package/src/common/__tests__/enum.test.ts +135 -0
- package/src/common/constants.ts +21 -0
- package/src/common/enum.js +192 -0
- package/src/common/enum.js.map +1 -0
- package/src/common/enum.ts +30 -0
- package/src/common/index.js +3 -0
- package/src/common/index.js.map +1 -0
- package/src/common/index.ts +2 -1
- package/src/events.js +166 -0
- package/src/events.js.map +1 -0
- package/src/events.ts +11 -14
- package/src/graphs/Graph.js +1857 -0
- package/src/graphs/Graph.js.map +1 -0
- package/src/graphs/Graph.ts +580 -162
- package/src/graphs/MultiAgentGraph.js +1092 -0
- package/src/graphs/MultiAgentGraph.js.map +1 -0
- package/src/graphs/MultiAgentGraph.ts +331 -112
- package/src/graphs/__tests__/adaptive-thinking.test.ts +369 -0
- package/src/graphs/__tests__/graph-direct-tool-names.test.ts +210 -0
- package/src/graphs/__tests__/multi-agent-edges.test.ts +237 -0
- package/src/graphs/__tests__/structured-output.integration.test.js +624 -0
- package/src/graphs/__tests__/structured-output.integration.test.js.map +1 -0
- package/src/graphs/__tests__/structured-output.test.js +144 -0
- package/src/graphs/__tests__/structured-output.test.js.map +1 -0
- package/src/graphs/contextManagement.e2e.test.js +718 -0
- package/src/graphs/contextManagement.e2e.test.js.map +1 -0
- package/src/graphs/contextManagement.e2e.test.ts +990 -0
- package/src/graphs/contextManagement.test.js +485 -0
- package/src/graphs/contextManagement.test.js.map +1 -0
- package/src/graphs/contextManagement.test.ts +625 -0
- package/src/graphs/handoffValidation.test.js +276 -0
- package/src/graphs/handoffValidation.test.js.map +1 -0
- package/src/graphs/handoffValidation.test.ts +353 -0
- package/src/graphs/index.js +3 -0
- package/src/graphs/index.js.map +1 -0
- package/src/index.js +28 -0
- package/src/index.js.map +1 -0
- package/src/index.ts +13 -0
- package/src/instrumentation.js +21 -0
- package/src/instrumentation.js.map +1 -0
- package/src/instrumentation.ts +38 -17
- package/src/llm/anthropic/index.js +319 -0
- package/src/llm/anthropic/index.js.map +1 -0
- package/src/llm/anthropic/index.ts +68 -15
- package/src/llm/anthropic/llm.spec.ts +402 -0
- package/src/llm/anthropic/types.js +46 -0
- package/src/llm/anthropic/types.js.map +1 -0
- package/src/llm/anthropic/types.ts +8 -2
- package/src/llm/anthropic/utils/message_inputs.js +627 -0
- package/src/llm/anthropic/utils/message_inputs.js.map +1 -0
- package/src/llm/anthropic/utils/message_inputs.ts +16 -33
- package/src/llm/anthropic/utils/message_outputs.js +290 -0
- package/src/llm/anthropic/utils/message_outputs.js.map +1 -0
- package/src/llm/anthropic/utils/message_outputs.ts +40 -1
- package/src/llm/anthropic/utils/output_parsers.js +89 -0
- package/src/llm/anthropic/utils/output_parsers.js.map +1 -0
- package/src/llm/anthropic/utils/tools.js +25 -0
- package/src/llm/anthropic/utils/tools.js.map +1 -0
- package/src/llm/bedrock/__tests__/bedrock-caching.test.js +392 -0
- package/src/llm/bedrock/__tests__/bedrock-caching.test.js.map +1 -0
- package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +24 -40
- package/src/llm/bedrock/index.js +303 -0
- package/src/llm/bedrock/index.js.map +1 -0
- package/src/llm/bedrock/index.ts +171 -134
- package/src/llm/bedrock/llm.spec.ts +395 -52
- package/src/llm/bedrock/types.js +2 -0
- package/src/llm/bedrock/types.js.map +1 -0
- package/src/llm/bedrock/utils/index.js +6 -0
- package/src/llm/bedrock/utils/index.js.map +1 -0
- package/src/llm/bedrock/utils/message_inputs.js +463 -0
- package/src/llm/bedrock/utils/message_inputs.js.map +1 -0
- package/src/llm/bedrock/utils/message_inputs.ts +30 -5
- package/src/llm/bedrock/utils/message_outputs.js +269 -0
- package/src/llm/bedrock/utils/message_outputs.js.map +1 -0
- package/src/llm/bedrock/utils/message_outputs.ts +70 -22
- package/src/llm/fake.js +92 -0
- package/src/llm/fake.js.map +1 -0
- package/src/llm/google/index.js +215 -0
- package/src/llm/google/index.js.map +1 -0
- package/src/llm/google/index.ts +2 -3
- package/src/llm/google/types.js +12 -0
- package/src/llm/google/types.js.map +1 -0
- package/src/llm/google/utils/common.js +670 -0
- package/src/llm/google/utils/common.js.map +1 -0
- package/src/llm/google/utils/tools.js +111 -0
- package/src/llm/google/utils/tools.js.map +1 -0
- package/src/llm/google/utils/zod_to_genai_parameters.js +47 -0
- package/src/llm/google/utils/zod_to_genai_parameters.js.map +1 -0
- package/src/llm/openai/index.js +1033 -0
- package/src/llm/openai/index.js.map +1 -0
- package/src/llm/openai/types.js +2 -0
- package/src/llm/openai/types.js.map +1 -0
- package/src/llm/openai/utils/index.js +756 -0
- package/src/llm/openai/utils/index.js.map +1 -0
- package/src/llm/openai/utils/isReasoningModel.test.js +79 -0
- package/src/llm/openai/utils/isReasoningModel.test.js.map +1 -0
- package/src/llm/openrouter/index.js +261 -0
- package/src/llm/openrouter/index.js.map +1 -0
- package/src/llm/openrouter/index.ts +117 -6
- package/src/llm/openrouter/reasoning.test.js +181 -0
- package/src/llm/openrouter/reasoning.test.js.map +1 -0
- package/src/llm/openrouter/reasoning.test.ts +207 -0
- package/src/llm/providers.js +36 -0
- package/src/llm/providers.js.map +1 -0
- package/src/llm/text.js +65 -0
- package/src/llm/text.js.map +1 -0
- package/src/llm/vertexai/index.js +402 -0
- package/src/llm/vertexai/index.js.map +1 -0
- package/src/llm/vertexai/index.ts +115 -5
- package/src/llm/vertexai/llm.spec.ts +114 -0
- package/src/messages/__tests__/tools.test.js +392 -0
- package/src/messages/__tests__/tools.test.js.map +1 -0
- package/src/messages/cache.js +404 -0
- package/src/messages/cache.js.map +1 -0
- package/src/messages/cache.test.js +1167 -0
- package/src/messages/cache.test.js.map +1 -0
- package/src/messages/cache.test.ts +178 -16
- package/src/messages/cache.ts +152 -147
- package/src/messages/content.js +48 -0
- package/src/messages/content.js.map +1 -0
- package/src/messages/content.test.js +314 -0
- package/src/messages/content.test.js.map +1 -0
- package/src/messages/core.js +359 -0
- package/src/messages/core.js.map +1 -0
- package/src/messages/core.ts +5 -0
- package/src/messages/ensureThinkingBlock.test.js +997 -0
- package/src/messages/ensureThinkingBlock.test.js.map +1 -0
- package/src/messages/ensureThinkingBlock.test.ts +751 -10
- package/src/messages/format.js +973 -0
- package/src/messages/format.js.map +1 -0
- package/src/messages/format.ts +334 -57
- package/src/messages/formatAgentMessages.test.js +2278 -0
- package/src/messages/formatAgentMessages.test.js.map +1 -0
- package/src/messages/formatAgentMessages.test.ts +1175 -1
- package/src/messages/formatAgentMessages.tools.test.js +362 -0
- package/src/messages/formatAgentMessages.tools.test.js.map +1 -0
- package/src/messages/formatMessage.test.js +608 -0
- package/src/messages/formatMessage.test.js.map +1 -0
- package/src/messages/ids.js +18 -0
- package/src/messages/ids.js.map +1 -0
- package/src/messages/index.js +9 -0
- package/src/messages/index.js.map +1 -0
- package/src/messages/index.ts +1 -0
- package/src/messages/labelContentByAgent.test.js +725 -0
- package/src/messages/labelContentByAgent.test.js.map +1 -0
- package/src/messages/prune.js +438 -0
- package/src/messages/prune.js.map +1 -0
- package/src/messages/prune.ts +87 -25
- package/src/messages/reducer.js +60 -0
- package/src/messages/reducer.js.map +1 -0
- package/src/messages/shiftIndexTokenCountMap.test.js +63 -0
- package/src/messages/shiftIndexTokenCountMap.test.js.map +1 -0
- package/src/messages/summarize.js +146 -0
- package/src/messages/summarize.js.map +1 -0
- package/src/messages/summarize.test.js +332 -0
- package/src/messages/summarize.test.js.map +1 -0
- package/src/messages/summarize.test.ts +466 -0
- package/src/messages/summarize.ts +222 -0
- package/src/messages/tools.js +90 -0
- package/src/messages/tools.js.map +1 -0
- package/src/mockStream.js +81 -0
- package/src/mockStream.js.map +1 -0
- package/src/prompts/collab.js +7 -0
- package/src/prompts/collab.js.map +1 -0
- package/src/prompts/index.js +3 -0
- package/src/prompts/index.js.map +1 -0
- package/src/prompts/taskmanager.js +58 -0
- package/src/prompts/taskmanager.js.map +1 -0
- package/src/run.js +427 -0
- package/src/run.js.map +1 -0
- package/src/run.ts +101 -33
- package/src/schemas/index.js +3 -0
- package/src/schemas/index.js.map +1 -0
- package/src/schemas/schema-preparation.test.js +370 -0
- package/src/schemas/schema-preparation.test.js.map +1 -0
- package/src/schemas/validate.js +314 -0
- package/src/schemas/validate.js.map +1 -0
- package/src/schemas/validate.test.js +264 -0
- package/src/schemas/validate.test.js.map +1 -0
- package/src/scripts/abort.js +127 -0
- package/src/scripts/abort.js.map +1 -0
- package/src/scripts/ant_web_search.js +130 -0
- package/src/scripts/ant_web_search.js.map +1 -0
- package/src/scripts/ant_web_search.ts +1 -0
- package/src/scripts/ant_web_search_edge_case.js +133 -0
- package/src/scripts/ant_web_search_edge_case.js.map +1 -0
- package/src/scripts/ant_web_search_edge_case.ts +1 -0
- package/src/scripts/ant_web_search_error_edge_case.js +119 -0
- package/src/scripts/ant_web_search_error_edge_case.js.map +1 -0
- package/src/scripts/ant_web_search_error_edge_case.ts +1 -0
- package/src/scripts/args.js +41 -0
- package/src/scripts/args.js.map +1 -0
- package/src/scripts/bedrock-cache-debug.js +186 -0
- package/src/scripts/bedrock-cache-debug.js.map +1 -0
- package/src/scripts/bedrock-cache-debug.ts +250 -0
- package/src/scripts/bedrock-content-aggregation-test.js +195 -0
- package/src/scripts/bedrock-content-aggregation-test.js.map +1 -0
- package/src/scripts/bedrock-content-aggregation-test.ts +266 -0
- package/src/scripts/bedrock-merge-test.js +80 -0
- package/src/scripts/bedrock-merge-test.js.map +1 -0
- package/src/scripts/bedrock-merge-test.ts +107 -0
- package/src/scripts/bedrock-parallel-tools-test.js +150 -0
- package/src/scripts/bedrock-parallel-tools-test.js.map +1 -0
- package/src/scripts/bedrock-parallel-tools-test.ts +204 -0
- package/src/scripts/caching.js +106 -0
- package/src/scripts/caching.js.map +1 -0
- package/src/scripts/caching.ts +1 -0
- package/src/scripts/cli.js +152 -0
- package/src/scripts/cli.js.map +1 -0
- package/src/scripts/cli2.js +119 -0
- package/src/scripts/cli2.js.map +1 -0
- package/src/scripts/cli3.js +163 -0
- package/src/scripts/cli3.js.map +1 -0
- package/src/scripts/cli4.js +165 -0
- package/src/scripts/cli4.js.map +1 -0
- package/src/scripts/cli5.js +165 -0
- package/src/scripts/cli5.js.map +1 -0
- package/src/scripts/code_exec.js +171 -0
- package/src/scripts/code_exec.js.map +1 -0
- package/src/scripts/code_exec.ts +1 -0
- package/src/scripts/code_exec_files.js +180 -0
- package/src/scripts/code_exec_files.js.map +1 -0
- package/src/scripts/code_exec_files.ts +1 -0
- package/src/scripts/code_exec_multi_session.js +185 -0
- package/src/scripts/code_exec_multi_session.js.map +1 -0
- package/src/scripts/code_exec_multi_session.ts +9 -13
- package/src/scripts/code_exec_ptc.js +265 -0
- package/src/scripts/code_exec_ptc.js.map +1 -0
- package/src/scripts/code_exec_ptc.ts +1 -0
- package/src/scripts/code_exec_session.js +217 -0
- package/src/scripts/code_exec_session.js.map +1 -0
- package/src/scripts/code_exec_session.ts +1 -0
- package/src/scripts/code_exec_simple.js +120 -0
- package/src/scripts/code_exec_simple.js.map +1 -0
- package/src/scripts/code_exec_simple.ts +1 -0
- package/src/scripts/content.js +111 -0
- package/src/scripts/content.js.map +1 -0
- package/src/scripts/content.ts +1 -0
- package/src/scripts/empty_input.js +125 -0
- package/src/scripts/empty_input.js.map +1 -0
- package/src/scripts/handoff-test.js +96 -0
- package/src/scripts/handoff-test.js.map +1 -0
- package/src/scripts/image.js +138 -0
- package/src/scripts/image.js.map +1 -0
- package/src/scripts/image.ts +3 -1
- package/src/scripts/memory.js +83 -0
- package/src/scripts/memory.js.map +1 -0
- package/src/scripts/memory.ts +16 -6
- package/src/scripts/multi-agent-chain.js +271 -0
- package/src/scripts/multi-agent-chain.js.map +1 -0
- package/src/scripts/multi-agent-chain.ts +1 -0
- package/src/scripts/multi-agent-conditional.js +185 -0
- package/src/scripts/multi-agent-conditional.js.map +1 -0
- package/src/scripts/multi-agent-conditional.ts +1 -0
- package/src/scripts/multi-agent-document-review-chain.js +171 -0
- package/src/scripts/multi-agent-document-review-chain.js.map +1 -0
- package/src/scripts/multi-agent-document-review-chain.ts +1 -0
- package/src/scripts/multi-agent-hybrid-flow.js +264 -0
- package/src/scripts/multi-agent-hybrid-flow.js.map +1 -0
- package/src/scripts/multi-agent-hybrid-flow.ts +1 -0
- package/src/scripts/multi-agent-parallel-start.js +214 -0
- package/src/scripts/multi-agent-parallel-start.js.map +1 -0
- package/src/scripts/multi-agent-parallel-start.ts +4 -4
- package/src/scripts/multi-agent-parallel.js +346 -0
- package/src/scripts/multi-agent-parallel.js.map +1 -0
- package/src/scripts/multi-agent-parallel.ts +1 -0
- package/src/scripts/multi-agent-sequence.js +184 -0
- package/src/scripts/multi-agent-sequence.js.map +1 -0
- package/src/scripts/multi-agent-sequence.ts +4 -4
- package/src/scripts/multi-agent-supervisor.js +324 -0
- package/src/scripts/multi-agent-supervisor.js.map +1 -0
- package/src/scripts/multi-agent-supervisor.ts +1 -0
- package/src/scripts/multi-agent-test.js +147 -0
- package/src/scripts/multi-agent-test.js.map +1 -0
- package/src/scripts/multi-agent-test.ts +1 -0
- package/src/scripts/parallel-asymmetric-tools-test.js +202 -0
- package/src/scripts/parallel-asymmetric-tools-test.js.map +1 -0
- package/src/scripts/parallel-asymmetric-tools-test.ts +1 -0
- package/src/scripts/parallel-full-metadata-test.js +176 -0
- package/src/scripts/parallel-full-metadata-test.js.map +1 -0
- package/src/scripts/parallel-full-metadata-test.ts +1 -0
- package/src/scripts/parallel-tools-test.js +256 -0
- package/src/scripts/parallel-tools-test.js.map +1 -0
- package/src/scripts/parallel-tools-test.ts +1 -0
- package/src/scripts/poc-multi-agent-comprehensive.ts +1222 -0
- package/src/scripts/programmatic_exec.js +277 -0
- package/src/scripts/programmatic_exec.js.map +1 -0
- package/src/scripts/programmatic_exec_agent.js +168 -0
- package/src/scripts/programmatic_exec_agent.js.map +1 -0
- package/src/scripts/programmatic_exec_agent.ts +1 -0
- package/src/scripts/search.js +118 -0
- package/src/scripts/search.js.map +1 -0
- package/src/scripts/search.ts +1 -0
- package/src/scripts/sequential-full-metadata-test.js +143 -0
- package/src/scripts/sequential-full-metadata-test.js.map +1 -0
- package/src/scripts/sequential-full-metadata-test.ts +1 -0
- package/src/scripts/simple.js +174 -0
- package/src/scripts/simple.js.map +1 -0
- package/src/scripts/simple.ts +2 -1
- package/src/scripts/single-agent-metadata-test.js +152 -0
- package/src/scripts/single-agent-metadata-test.js.map +1 -0
- package/src/scripts/single-agent-metadata-test.ts +4 -6
- package/src/scripts/stream.js +113 -0
- package/src/scripts/stream.js.map +1 -0
- package/src/scripts/stream.ts +1 -0
- package/src/scripts/test-custom-prompt-key.js +132 -0
- package/src/scripts/test-custom-prompt-key.js.map +1 -0
- package/src/scripts/test-handoff-input.js +143 -0
- package/src/scripts/test-handoff-input.js.map +1 -0
- package/src/scripts/test-handoff-preamble.js +227 -0
- package/src/scripts/test-handoff-preamble.js.map +1 -0
- package/src/scripts/test-handoff-preamble.ts +1 -0
- package/src/scripts/test-handoff-steering.js +353 -0
- package/src/scripts/test-handoff-steering.js.map +1 -0
- package/src/scripts/test-handoff-steering.ts +430 -0
- package/src/scripts/test-multi-agent-list-handoff.js +318 -0
- package/src/scripts/test-multi-agent-list-handoff.js.map +1 -0
- package/src/scripts/test-multi-agent-list-handoff.ts +1 -0
- package/src/scripts/test-parallel-agent-labeling.js +253 -0
- package/src/scripts/test-parallel-agent-labeling.js.map +1 -0
- package/src/scripts/test-parallel-agent-labeling.ts +2 -0
- package/src/scripts/test-parallel-handoffs.js +229 -0
- package/src/scripts/test-parallel-handoffs.js.map +1 -0
- package/src/scripts/test-parallel-handoffs.ts +1 -0
- package/src/scripts/test-thinking-handoff-bedrock.js +132 -0
- package/src/scripts/test-thinking-handoff-bedrock.js.map +1 -0
- package/src/scripts/test-thinking-handoff-bedrock.ts +1 -0
- package/src/scripts/test-thinking-handoff.js +132 -0
- package/src/scripts/test-thinking-handoff.js.map +1 -0
- package/src/scripts/test-thinking-handoff.ts +1 -0
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js +140 -0
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js.map +1 -0
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.ts +166 -0
- package/src/scripts/test-tool-before-handoff-role-order.js +223 -0
- package/src/scripts/test-tool-before-handoff-role-order.js.map +1 -0
- package/src/scripts/test-tool-before-handoff-role-order.ts +276 -0
- package/src/scripts/test-tools-before-handoff.js +187 -0
- package/src/scripts/test-tools-before-handoff.js.map +1 -0
- package/src/scripts/test-tools-before-handoff.ts +4 -8
- package/src/scripts/test_code_api.js +263 -0
- package/src/scripts/test_code_api.js.map +1 -0
- package/src/scripts/thinking-bedrock.js +128 -0
- package/src/scripts/thinking-bedrock.js.map +1 -0
- package/src/scripts/thinking-bedrock.ts +1 -0
- package/src/scripts/thinking-vertexai.js +130 -0
- package/src/scripts/thinking-vertexai.js.map +1 -0
- package/src/scripts/thinking-vertexai.ts +168 -0
- package/src/scripts/thinking.js +134 -0
- package/src/scripts/thinking.js.map +1 -0
- package/src/scripts/thinking.ts +1 -0
- package/src/scripts/tool_search.js +114 -0
- package/src/scripts/tool_search.js.map +1 -0
- package/src/scripts/tools.js +125 -0
- package/src/scripts/tools.js.map +1 -0
- package/src/scripts/tools.ts +5 -19
- package/src/specs/agent-handoffs-bedrock.integration.test.js +280 -0
- package/src/specs/agent-handoffs-bedrock.integration.test.js.map +1 -0
- package/src/specs/agent-handoffs-bedrock.integration.test.ts +412 -375
- package/src/specs/agent-handoffs.test.js +924 -0
- package/src/specs/agent-handoffs.test.js.map +1 -0
- package/src/specs/agent-handoffs.test.ts +152 -39
- package/src/specs/anthropic.simple.test.js +287 -0
- package/src/specs/anthropic.simple.test.js.map +1 -0
- package/src/specs/anthropic.simple.test.ts +7 -4
- package/src/specs/azure.simple.test.js +381 -0
- package/src/specs/azure.simple.test.js.map +1 -0
- package/src/specs/azure.simple.test.ts +143 -5
- package/src/specs/cache.simple.test.js +282 -0
- package/src/specs/cache.simple.test.js.map +1 -0
- package/src/specs/cache.simple.test.ts +9 -2
- package/src/specs/custom-event-await.test.js +148 -0
- package/src/specs/custom-event-await.test.js.map +1 -0
- package/src/specs/custom-event-await.test.ts +215 -0
- package/src/specs/deepseek.simple.test.js +189 -0
- package/src/specs/deepseek.simple.test.js.map +1 -0
- package/src/specs/deepseek.simple.test.ts +4 -2
- package/src/specs/emergency-prune.test.js +308 -0
- package/src/specs/emergency-prune.test.js.map +1 -0
- package/src/specs/moonshot.simple.test.js +237 -0
- package/src/specs/moonshot.simple.test.js.map +1 -0
- package/src/specs/moonshot.simple.test.ts +6 -2
- package/src/specs/observability.integration.test.js +1337 -0
- package/src/specs/observability.integration.test.js.map +1 -0
- package/src/specs/observability.integration.test.ts +2223 -0
- package/src/specs/openai.simple.test.js +233 -0
- package/src/specs/openai.simple.test.js.map +1 -0
- package/src/specs/openai.simple.test.ts +4 -2
- package/src/specs/openrouter.simple.test.js +202 -0
- package/src/specs/openrouter.simple.test.js.map +1 -0
- package/src/specs/openrouter.simple.test.ts +165 -4
- package/src/specs/prune.test.js +733 -0
- package/src/specs/prune.test.js.map +1 -0
- package/src/specs/prune.test.ts +1 -0
- package/src/specs/reasoning.test.js +144 -0
- package/src/specs/reasoning.test.js.map +1 -0
- package/src/specs/reasoning.test.ts +2 -2
- package/src/specs/spec.utils.js +4 -0
- package/src/specs/spec.utils.js.map +1 -0
- package/src/specs/thinking-handoff.test.js +486 -0
- package/src/specs/thinking-handoff.test.js.map +1 -0
- package/src/specs/thinking-handoff.test.ts +3 -2
- package/src/specs/thinking-prune.test.js +600 -0
- package/src/specs/thinking-prune.test.js.map +1 -0
- package/src/specs/token-distribution-edge-case.test.js +246 -0
- package/src/specs/token-distribution-edge-case.test.js.map +1 -0
- package/src/specs/token-memoization.test.js +32 -0
- package/src/specs/token-memoization.test.js.map +1 -0
- package/src/specs/token-memoization.test.ts +14 -5
- package/src/specs/tokens.test.js +49 -0
- package/src/specs/tokens.test.js.map +1 -0
- package/src/specs/tokens.test.ts +64 -0
- package/src/specs/tool-error.test.js +139 -0
- package/src/specs/tool-error.test.js.map +1 -0
- package/src/specs/tool-error.test.ts +2 -2
- package/src/splitStream.js +204 -0
- package/src/splitStream.js.map +1 -0
- package/src/splitStream.test.js +504 -0
- package/src/splitStream.test.js.map +1 -0
- package/src/stream.js +650 -0
- package/src/stream.js.map +1 -0
- package/src/stream.test.js +225 -0
- package/src/stream.test.js.map +1 -0
- package/src/stream.test.ts +25 -15
- package/src/stream.ts +82 -32
- package/src/test/mockTools.js +340 -0
- package/src/test/mockTools.js.map +1 -0
- package/src/tools/AskUser.ts +159 -0
- package/src/tools/BrowserTools.js +245 -0
- package/src/tools/BrowserTools.js.map +1 -0
- package/src/tools/BrowserTools.ts +12 -8
- package/src/tools/Calculator.js +38 -0
- package/src/tools/Calculator.js.map +1 -0
- package/src/tools/Calculator.test.js +225 -0
- package/src/tools/Calculator.test.js.map +1 -0
- package/src/tools/CodeExecutor.js +233 -0
- package/src/tools/CodeExecutor.js.map +1 -0
- package/src/tools/CodeExecutor.selfhealing.test.ts +435 -0
- package/src/tools/CodeExecutor.ts +62 -4
- package/src/tools/ProgrammaticToolCalling.js +602 -0
- package/src/tools/ProgrammaticToolCalling.js.map +1 -0
- package/src/tools/ProgrammaticToolCalling.ts +40 -52
- package/src/tools/StreamingToolCallBuffer.js +179 -0
- package/src/tools/StreamingToolCallBuffer.js.map +1 -0
- package/src/tools/StreamingToolCallBuffer.ts +218 -0
- package/src/tools/ToolNode.js +930 -0
- package/src/tools/ToolNode.js.map +1 -0
- package/src/tools/ToolNode.ts +454 -41
- package/src/tools/ToolSearch.js +904 -0
- package/src/tools/ToolSearch.js.map +1 -0
- package/src/tools/ToolSearch.ts +84 -33
- package/src/tools/__tests__/AskUser.test.ts +537 -0
- package/src/tools/__tests__/BrowserTools.test.js +306 -0
- package/src/tools/__tests__/BrowserTools.test.js.map +1 -0
- package/src/tools/__tests__/BrowserTools.test.ts +131 -6
- package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js +276 -0
- package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js.map +1 -0
- package/src/tools/__tests__/ProgrammaticToolCalling.test.js +807 -0
- package/src/tools/__tests__/ProgrammaticToolCalling.test.js.map +1 -0
- package/src/tools/__tests__/StreamingToolCallBuffer.test.js +175 -0
- package/src/tools/__tests__/StreamingToolCallBuffer.test.js.map +1 -0
- package/src/tools/__tests__/StreamingToolCallBuffer.test.ts +263 -0
- package/src/tools/__tests__/ToolApproval.test.js +675 -0
- package/src/tools/__tests__/ToolApproval.test.js.map +1 -0
- package/src/tools/__tests__/ToolApproval.test.ts +194 -20
- package/src/tools/__tests__/ToolNode.hitl.test.ts +267 -0
- package/src/tools/__tests__/ToolNode.recovery.test.js +200 -0
- package/src/tools/__tests__/ToolNode.recovery.test.js.map +1 -0
- package/src/tools/__tests__/ToolNode.recovery.test.ts +276 -0
- package/src/tools/__tests__/ToolNode.session.test.js +319 -0
- package/src/tools/__tests__/ToolNode.session.test.js.map +1 -0
- package/src/tools/__tests__/ToolNode.session.test.ts +465 -0
- package/src/tools/__tests__/ToolSearch.integration.test.js +125 -0
- package/src/tools/__tests__/ToolSearch.integration.test.js.map +1 -0
- package/src/tools/__tests__/ToolSearch.test.js +812 -0
- package/src/tools/__tests__/ToolSearch.test.js.map +1 -0
- package/src/tools/__tests__/ToolSearch.test.ts +78 -5
- package/src/tools/__tests__/handlers.test.js +799 -0
- package/src/tools/__tests__/handlers.test.js.map +1 -0
- package/src/tools/__tests__/handlers.test.ts +1100 -0
- package/src/tools/__tests__/truncation-recovery.integration.test.js +362 -0
- package/src/tools/__tests__/truncation-recovery.integration.test.js.map +1 -0
- package/src/tools/__tests__/truncation-recovery.integration.test.ts +560 -0
- package/src/tools/handlers.js +306 -0
- package/src/tools/handlers.js.map +1 -0
- package/src/tools/handlers.ts +119 -16
- package/src/tools/schema.js +25 -0
- package/src/tools/schema.js.map +1 -0
- package/src/tools/search/anthropic.js +34 -0
- package/src/tools/search/anthropic.js.map +1 -0
- package/src/tools/search/content.js +116 -0
- package/src/tools/search/content.js.map +1 -0
- package/src/tools/search/content.test.js +133 -0
- package/src/tools/search/content.test.js.map +1 -0
- package/src/tools/search/firecrawl.js +173 -0
- package/src/tools/search/firecrawl.js.map +1 -0
- package/src/tools/search/format.js +198 -0
- package/src/tools/search/format.js.map +1 -0
- package/src/tools/search/highlights.js +241 -0
- package/src/tools/search/highlights.js.map +1 -0
- package/src/tools/search/index.js +3 -0
- package/src/tools/search/index.js.map +1 -0
- package/src/tools/search/jina-reranker.test.js +106 -0
- package/src/tools/search/jina-reranker.test.js.map +1 -0
- package/src/tools/search/rerankers.js +165 -0
- package/src/tools/search/rerankers.js.map +1 -0
- package/src/tools/search/schema.js +102 -0
- package/src/tools/search/schema.js.map +1 -0
- package/src/tools/search/search.js +561 -0
- package/src/tools/search/search.js.map +1 -0
- package/src/tools/search/serper-scraper.js +126 -0
- package/src/tools/search/serper-scraper.js.map +1 -0
- package/src/tools/search/test.js +129 -0
- package/src/tools/search/test.js.map +1 -0
- package/src/tools/search/tool.js +453 -0
- package/src/tools/search/tool.js.map +1 -0
- package/src/tools/search/types.js +2 -0
- package/src/tools/search/types.js.map +1 -0
- package/src/tools/search/utils.js +59 -0
- package/src/tools/search/utils.js.map +1 -0
- package/src/types/graph.js +24 -0
- package/src/types/graph.js.map +1 -0
- package/src/types/graph.test.js +192 -0
- package/src/types/graph.test.js.map +1 -0
- package/src/types/graph.ts +26 -6
- package/src/types/index.js +7 -0
- package/src/types/index.js.map +1 -0
- package/src/types/llm.js +2 -0
- package/src/types/llm.js.map +1 -0
- package/src/types/llm.ts +8 -3
- package/src/types/messages.js +2 -0
- package/src/types/messages.js.map +1 -0
- package/src/types/run.js +2 -0
- package/src/types/run.js.map +1 -0
- package/src/types/run.ts +2 -0
- package/src/types/stream.js +2 -0
- package/src/types/stream.js.map +1 -0
- package/src/types/tools.js +2 -0
- package/src/types/tools.js.map +1 -0
- package/src/types/tools.ts +21 -2
- package/src/utils/contextAnalytics.js +79 -0
- package/src/utils/contextAnalytics.js.map +1 -0
- package/src/utils/contextAnalytics.test.js +166 -0
- package/src/utils/contextAnalytics.test.js.map +1 -0
- package/src/utils/contextAnalytics.test.ts +222 -0
- package/src/utils/contextAnalytics.ts +27 -9
- package/src/utils/events.js +26 -0
- package/src/utils/events.js.map +1 -0
- package/src/utils/graph.js +11 -0
- package/src/utils/graph.js.map +1 -0
- package/src/utils/handlers.js +65 -0
- package/src/utils/handlers.js.map +1 -0
- package/src/utils/index.js +10 -0
- package/src/utils/index.js.map +1 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/llm.js +21 -0
- package/src/utils/llm.js.map +1 -0
- package/src/utils/llmConfig.js +205 -0
- package/src/utils/llmConfig.js.map +1 -0
- package/src/utils/llmConfig.ts +5 -5
- package/src/utils/logging.js +37 -0
- package/src/utils/logging.js.map +1 -0
- package/src/utils/misc.js +51 -0
- package/src/utils/misc.js.map +1 -0
- package/src/utils/run.js +69 -0
- package/src/utils/run.js.map +1 -0
- package/src/utils/run.ts +108 -106
- package/src/utils/schema.js +21 -0
- package/src/utils/schema.js.map +1 -0
- package/src/utils/title.js +119 -0
- package/src/utils/title.js.map +1 -0
- package/src/utils/tokens.js +92 -0
- package/src/utils/tokens.js.map +1 -0
- package/src/utils/tokens.ts +118 -142
- package/src/utils/toolCallContinuation.ts +55 -0
- package/src/utils/toonFormat.js +379 -0
- package/src/utils/toonFormat.js.map +1 -0
|
@@ -0,0 +1,1222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive Multi-Agent POC — All Combinations
|
|
3
|
+
*
|
|
4
|
+
* Tests every combination of edge type (handoff vs direct/sequential) and
|
|
5
|
+
* tool usage (none, single, multiple) end-to-end with Bedrock.
|
|
6
|
+
*
|
|
7
|
+
* S1: Handoff — No tools
|
|
8
|
+
* S2: Handoff — Single tool call
|
|
9
|
+
* S3: Handoff — Multiple tool calls (3 tools)
|
|
10
|
+
* S4: Sequential (direct edges) — No tools
|
|
11
|
+
* S5: Sequential — Single tool per agent
|
|
12
|
+
* S6: Sequential — Multiple tools per agent
|
|
13
|
+
* S7: Hybrid (direct + handoff) — Mixed tools
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* npx tsx --tsconfig tsconfig.json -r tsconfig-paths/register src/scripts/poc-multi-agent-comprehensive.ts
|
|
17
|
+
*/
|
|
18
|
+
import { config } from 'dotenv';
|
|
19
|
+
config();
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
HumanMessage,
|
|
23
|
+
BaseMessage,
|
|
24
|
+
getBufferString,
|
|
25
|
+
} from '@langchain/core/messages';
|
|
26
|
+
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
import { Run } from '@/run';
|
|
29
|
+
import { Providers, GraphEvents } from '@/common';
|
|
30
|
+
import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
|
|
31
|
+
import { ToolEndHandler, ModelEndHandler } from '@/events';
|
|
32
|
+
import type * as t from '@/types';
|
|
33
|
+
|
|
34
|
+
/* ------------------------------------------------------------------ */
|
|
35
|
+
/* Shared helpers */
|
|
36
|
+
/* ------------------------------------------------------------------ */
|
|
37
|
+
|
|
38
|
+
/** Bedrock client options reused across all agents */
|
|
39
|
+
const bedrockOptions: t.ClientOptions = {
|
|
40
|
+
region: process.env.BEDROCK_AWS_DEFAULT_REGION ?? 'us-east-1',
|
|
41
|
+
credentials: {
|
|
42
|
+
accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!,
|
|
43
|
+
secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!,
|
|
44
|
+
},
|
|
45
|
+
model: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** Create standard event handlers for observability */
|
|
49
|
+
function createHandlers(label: string) {
|
|
50
|
+
const { contentParts, aggregateContent, stepMap } = createContentAggregator();
|
|
51
|
+
|
|
52
|
+
let currentAgent = '';
|
|
53
|
+
|
|
54
|
+
const handlers: Record<string, t.EventHandler> = {
|
|
55
|
+
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
56
|
+
[GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
|
|
57
|
+
[GraphEvents.CHAT_MODEL_STREAM]: {
|
|
58
|
+
handle: (
|
|
59
|
+
event: string,
|
|
60
|
+
data: t.StreamEventData,
|
|
61
|
+
metadata?: Record<string, unknown>,
|
|
62
|
+
graph?: unknown
|
|
63
|
+
): void => {
|
|
64
|
+
const chunk = data.chunk as Record<string, unknown> | undefined;
|
|
65
|
+
if (!chunk) return;
|
|
66
|
+
const content = chunk.content;
|
|
67
|
+
if (typeof content === 'string' && content) {
|
|
68
|
+
process.stdout.write(content);
|
|
69
|
+
} else if (Array.isArray(content)) {
|
|
70
|
+
for (const block of content) {
|
|
71
|
+
if (
|
|
72
|
+
typeof block === 'object' &&
|
|
73
|
+
block !== null &&
|
|
74
|
+
'type' in block &&
|
|
75
|
+
block.type === 'text' &&
|
|
76
|
+
'text' in block &&
|
|
77
|
+
typeof block.text === 'string'
|
|
78
|
+
) {
|
|
79
|
+
process.stdout.write(block.text);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
[GraphEvents.ON_RUN_STEP]: {
|
|
86
|
+
handle: (
|
|
87
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
88
|
+
data: t.StreamEventData
|
|
89
|
+
): void => {
|
|
90
|
+
const runStepData = data as Record<string, unknown>;
|
|
91
|
+
const name =
|
|
92
|
+
typeof runStepData?.name === 'string' ? runStepData.name : undefined;
|
|
93
|
+
if (name && name !== currentAgent) {
|
|
94
|
+
currentAgent = name;
|
|
95
|
+
console.log(`\n\n>>> [${label}] Agent "${currentAgent}" starting...`);
|
|
96
|
+
}
|
|
97
|
+
aggregateContent({ event, data: data as t.RunStep });
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
101
|
+
handle: (
|
|
102
|
+
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
103
|
+
data: t.StreamEventData
|
|
104
|
+
): void => {
|
|
105
|
+
const runStepData = data as Record<string, unknown>;
|
|
106
|
+
const name =
|
|
107
|
+
typeof runStepData?.name === 'string' ? runStepData.name : undefined;
|
|
108
|
+
if (name) {
|
|
109
|
+
console.log(`\n<<< [${label}] Agent "${name}" completed`);
|
|
110
|
+
}
|
|
111
|
+
aggregateContent({
|
|
112
|
+
event,
|
|
113
|
+
data: data as unknown as { result: t.ToolEndEvent },
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
118
|
+
handle: (
|
|
119
|
+
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
120
|
+
data: t.StreamEventData
|
|
121
|
+
): void => {
|
|
122
|
+
aggregateContent({ event, data: data as t.RunStepDeltaEvent });
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
126
|
+
handle: (
|
|
127
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
128
|
+
data: t.StreamEventData
|
|
129
|
+
): void => {
|
|
130
|
+
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
return { handlers, contentParts, stepMap };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function printHeader(title: string) {
|
|
139
|
+
console.log('\n' + '='.repeat(80));
|
|
140
|
+
console.log(` ${title}`);
|
|
141
|
+
console.log('='.repeat(80));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function printResult(label: string, success: boolean, details?: string) {
|
|
145
|
+
const icon = success ? '[PASS]' : '[FAIL]';
|
|
146
|
+
console.log(`\n${icon} ${label}`);
|
|
147
|
+
if (details) console.log(` ${details}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Helper to build a default agent config */
|
|
151
|
+
function agent(
|
|
152
|
+
agentId: string,
|
|
153
|
+
name: string,
|
|
154
|
+
instructions: string,
|
|
155
|
+
extras?: Partial<t.AgentInputs>
|
|
156
|
+
): t.AgentInputs {
|
|
157
|
+
return {
|
|
158
|
+
agentId,
|
|
159
|
+
name,
|
|
160
|
+
provider: Providers.BEDROCK,
|
|
161
|
+
clientOptions: bedrockOptions,
|
|
162
|
+
instructions,
|
|
163
|
+
maxContextTokens: 8000,
|
|
164
|
+
...extras,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* ------------------------------------------------------------------ */
|
|
169
|
+
/* Mock Tools */
|
|
170
|
+
/* ------------------------------------------------------------------ */
|
|
171
|
+
|
|
172
|
+
const getWeatherTool = new DynamicStructuredTool({
|
|
173
|
+
name: 'get_weather',
|
|
174
|
+
description:
|
|
175
|
+
'Get the current weather for a city. Returns temperature in Fahrenheit and conditions.',
|
|
176
|
+
schema: z.object({
|
|
177
|
+
city: z.string().describe('The city name'),
|
|
178
|
+
}),
|
|
179
|
+
func: async ({ city }) => {
|
|
180
|
+
const temps: Record<string, number> = {
|
|
181
|
+
boston: 45,
|
|
182
|
+
miami: 82,
|
|
183
|
+
'new york': 55,
|
|
184
|
+
'los angeles': 72,
|
|
185
|
+
chicago: 40,
|
|
186
|
+
london: 50,
|
|
187
|
+
tokyo: 60,
|
|
188
|
+
paris: 55,
|
|
189
|
+
sydney: 75,
|
|
190
|
+
};
|
|
191
|
+
const temp = temps[city.toLowerCase()] ?? 65;
|
|
192
|
+
return JSON.stringify({
|
|
193
|
+
city,
|
|
194
|
+
temperature: temp,
|
|
195
|
+
unit: 'F',
|
|
196
|
+
condition: temp > 70 ? 'Sunny' : temp > 50 ? 'Partly Cloudy' : 'Cold',
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const getStockPriceTool = new DynamicStructuredTool({
|
|
202
|
+
name: 'get_stock_price',
|
|
203
|
+
description: 'Get the current stock price for a ticker symbol.',
|
|
204
|
+
schema: z.object({
|
|
205
|
+
ticker: z.string().describe('Stock ticker symbol (e.g. AAPL, GOOGL)'),
|
|
206
|
+
}),
|
|
207
|
+
func: async ({ ticker }) => {
|
|
208
|
+
const prices: Record<string, number> = {
|
|
209
|
+
AAPL: 178.5,
|
|
210
|
+
GOOGL: 141.2,
|
|
211
|
+
MSFT: 378.9,
|
|
212
|
+
AMZN: 185.6,
|
|
213
|
+
TSLA: 245.3,
|
|
214
|
+
META: 505.75,
|
|
215
|
+
NVDA: 875.4,
|
|
216
|
+
};
|
|
217
|
+
const price = prices[ticker.toUpperCase()] ?? 100.0;
|
|
218
|
+
const change = (Math.random() * 6 - 3).toFixed(2);
|
|
219
|
+
return JSON.stringify({
|
|
220
|
+
ticker: ticker.toUpperCase(),
|
|
221
|
+
price,
|
|
222
|
+
change: parseFloat(change),
|
|
223
|
+
currency: 'USD',
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const searchDatabaseTool = new DynamicStructuredTool({
|
|
229
|
+
name: 'search_database',
|
|
230
|
+
description:
|
|
231
|
+
'Search the company database for employee or project information.',
|
|
232
|
+
schema: z.object({
|
|
233
|
+
query: z.string().describe('Search query'),
|
|
234
|
+
category: z
|
|
235
|
+
.enum(['employees', 'projects', 'departments'])
|
|
236
|
+
.describe('Category to search'),
|
|
237
|
+
}),
|
|
238
|
+
func: async ({ query, category }) => {
|
|
239
|
+
const results: Record<string, Record<string, string[]>> = {
|
|
240
|
+
employees: {
|
|
241
|
+
engineering: [
|
|
242
|
+
'Alice Chen (Senior Engineer)',
|
|
243
|
+
'Bob Kumar (Tech Lead)',
|
|
244
|
+
'Carol Smith (Staff Engineer)',
|
|
245
|
+
],
|
|
246
|
+
marketing: ['Dan Lee (VP Marketing)', 'Eva Brown (Content Manager)'],
|
|
247
|
+
},
|
|
248
|
+
projects: {
|
|
249
|
+
active: [
|
|
250
|
+
'Project Phoenix (AI Platform)',
|
|
251
|
+
'Project Atlas (Data Migration)',
|
|
252
|
+
'Project Nexus (API Gateway)',
|
|
253
|
+
],
|
|
254
|
+
completed: ['Project Omega (Auth System)', 'Project Delta (Dashboard)'],
|
|
255
|
+
},
|
|
256
|
+
departments: {
|
|
257
|
+
all: [
|
|
258
|
+
'Engineering (45 people)',
|
|
259
|
+
'Marketing (12 people)',
|
|
260
|
+
'Sales (20 people)',
|
|
261
|
+
'Operations (8 people)',
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
const catResults = results[category] ?? {};
|
|
266
|
+
const matchingValues = Object.values(catResults)
|
|
267
|
+
.flat()
|
|
268
|
+
.filter((v) => v.toLowerCase().includes(query.toLowerCase()));
|
|
269
|
+
return JSON.stringify({
|
|
270
|
+
category,
|
|
271
|
+
query,
|
|
272
|
+
results:
|
|
273
|
+
matchingValues.length > 0
|
|
274
|
+
? matchingValues
|
|
275
|
+
: Object.values(catResults).flat().slice(0, 3),
|
|
276
|
+
totalMatches: matchingValues.length || 3,
|
|
277
|
+
});
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
const translateTextTool = new DynamicStructuredTool({
|
|
282
|
+
name: 'translate_text',
|
|
283
|
+
description: 'Translate text from one language to another.',
|
|
284
|
+
schema: z.object({
|
|
285
|
+
text: z.string().describe('Text to translate'),
|
|
286
|
+
targetLanguage: z
|
|
287
|
+
.string()
|
|
288
|
+
.describe('Target language (e.g. Spanish, French, Japanese)'),
|
|
289
|
+
}),
|
|
290
|
+
func: async ({ text, targetLanguage }) => {
|
|
291
|
+
const translations: Record<string, string> = {
|
|
292
|
+
spanish: `[ES] ${text} (traducción simulada)`,
|
|
293
|
+
french: `[FR] ${text} (traduction simulée)`,
|
|
294
|
+
japanese: `[JA] ${text} (模擬翻訳)`,
|
|
295
|
+
german: `[DE] ${text} (simulierte Übersetzung)`,
|
|
296
|
+
};
|
|
297
|
+
return JSON.stringify({
|
|
298
|
+
original: text,
|
|
299
|
+
translated:
|
|
300
|
+
translations[targetLanguage.toLowerCase()] ??
|
|
301
|
+
`[${targetLanguage}] ${text} (simulated)`,
|
|
302
|
+
targetLanguage,
|
|
303
|
+
});
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const getTimeTool = new DynamicStructuredTool({
|
|
308
|
+
name: 'get_time',
|
|
309
|
+
description: 'Get the current time in a specific timezone.',
|
|
310
|
+
schema: z.object({
|
|
311
|
+
timezone: z.string().describe('Timezone (e.g. EST, PST, UTC, JST)'),
|
|
312
|
+
}),
|
|
313
|
+
func: async ({ timezone }) => {
|
|
314
|
+
const offsets: Record<string, number> = {
|
|
315
|
+
EST: -5,
|
|
316
|
+
PST: -8,
|
|
317
|
+
CST: -6,
|
|
318
|
+
MST: -7,
|
|
319
|
+
UTC: 0,
|
|
320
|
+
GMT: 0,
|
|
321
|
+
JST: 9,
|
|
322
|
+
CET: 1,
|
|
323
|
+
IST: 5.5,
|
|
324
|
+
AEST: 11,
|
|
325
|
+
};
|
|
326
|
+
const offset = offsets[timezone.toUpperCase()] ?? 0;
|
|
327
|
+
const now = new Date();
|
|
328
|
+
const utcHour = now.getUTCHours();
|
|
329
|
+
const localHour = (utcHour + offset + 24) % 24;
|
|
330
|
+
const mins = now.getUTCMinutes().toString().padStart(2, '0');
|
|
331
|
+
return JSON.stringify({
|
|
332
|
+
timezone: timezone.toUpperCase(),
|
|
333
|
+
time: `${Math.floor(localHour)}:${mins}`,
|
|
334
|
+
date: now.toISOString().split('T')[0],
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
const sentimentAnalysisTool = new DynamicStructuredTool({
|
|
340
|
+
name: 'analyze_sentiment',
|
|
341
|
+
description:
|
|
342
|
+
'Analyze the sentiment of a piece of text. Returns positive, negative, or neutral with a confidence score.',
|
|
343
|
+
schema: z.object({
|
|
344
|
+
text: z.string().describe('Text to analyze for sentiment'),
|
|
345
|
+
}),
|
|
346
|
+
func: async ({ text }) => {
|
|
347
|
+
const words = text.toLowerCase().split(/\s+/);
|
|
348
|
+
const positive = [
|
|
349
|
+
'good',
|
|
350
|
+
'great',
|
|
351
|
+
'excellent',
|
|
352
|
+
'amazing',
|
|
353
|
+
'love',
|
|
354
|
+
'best',
|
|
355
|
+
'happy',
|
|
356
|
+
'wonderful',
|
|
357
|
+
'fantastic',
|
|
358
|
+
];
|
|
359
|
+
const negative = [
|
|
360
|
+
'bad',
|
|
361
|
+
'terrible',
|
|
362
|
+
'awful',
|
|
363
|
+
'hate',
|
|
364
|
+
'worst',
|
|
365
|
+
'poor',
|
|
366
|
+
'disappointed',
|
|
367
|
+
'horrible',
|
|
368
|
+
];
|
|
369
|
+
const posCount = words.filter((w) => positive.includes(w)).length;
|
|
370
|
+
const negCount = words.filter((w) => negative.includes(w)).length;
|
|
371
|
+
const sentiment =
|
|
372
|
+
posCount > negCount
|
|
373
|
+
? 'positive'
|
|
374
|
+
: negCount > posCount
|
|
375
|
+
? 'negative'
|
|
376
|
+
: 'neutral';
|
|
377
|
+
const confidence = Math.min(
|
|
378
|
+
0.95,
|
|
379
|
+
0.6 + Math.abs(posCount - negCount) * 0.1
|
|
380
|
+
);
|
|
381
|
+
return JSON.stringify({ sentiment, confidence, wordCount: words.length });
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
/* ================================================================== */
|
|
386
|
+
/* S1: Handoff — No Tools */
|
|
387
|
+
/* flight_assistant -> hotel_assistant (pure conversation handoff) */
|
|
388
|
+
/* ================================================================== */
|
|
389
|
+
async function s1_handoff_noTools(): Promise<boolean> {
|
|
390
|
+
printHeader('S1: HANDOFF — NO TOOLS');
|
|
391
|
+
console.log(' flight_assistant -> hotel_assistant');
|
|
392
|
+
console.log(' Pure conversation handoff, no tools involved\n');
|
|
393
|
+
|
|
394
|
+
const agents: t.AgentInputs[] = [
|
|
395
|
+
agent(
|
|
396
|
+
'flight_assistant',
|
|
397
|
+
'Flight Assistant',
|
|
398
|
+
`You are a flight booking assistant. Help users with flight-related queries.
|
|
399
|
+
When the user also needs hotel assistance, first briefly address the flight part (2-3 sentences),
|
|
400
|
+
then use the handoff tool to transfer to the hotel assistant.
|
|
401
|
+
Do NOT try to answer hotel questions yourself.`
|
|
402
|
+
),
|
|
403
|
+
agent(
|
|
404
|
+
'hotel_assistant',
|
|
405
|
+
'Hotel Assistant',
|
|
406
|
+
`You are a hotel booking assistant. Help users with hotel-related queries.
|
|
407
|
+
Provide your hotel recommendations (2-3 sentences) and complete the conversation.
|
|
408
|
+
Do NOT transfer back to the flight assistant.`
|
|
409
|
+
),
|
|
410
|
+
];
|
|
411
|
+
|
|
412
|
+
const edges: t.GraphEdge[] = [
|
|
413
|
+
{
|
|
414
|
+
from: 'flight_assistant',
|
|
415
|
+
to: 'hotel_assistant',
|
|
416
|
+
description:
|
|
417
|
+
'Transfer to hotel assistant when user needs hotel booking help',
|
|
418
|
+
},
|
|
419
|
+
];
|
|
420
|
+
|
|
421
|
+
const { handlers, contentParts } = createHandlers('S1');
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
const run = await Run.create({
|
|
425
|
+
runId: `s1-${Date.now()}`,
|
|
426
|
+
graphConfig: { type: 'multi-agent', agents, edges },
|
|
427
|
+
customHandlers: handlers,
|
|
428
|
+
returnContent: true,
|
|
429
|
+
skipCleanup: true,
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
await run.processStream(
|
|
433
|
+
{
|
|
434
|
+
messages: [
|
|
435
|
+
new HumanMessage(
|
|
436
|
+
'I need a flight from Boston to Miami, and also need a hotel near South Beach for 3 nights.'
|
|
437
|
+
),
|
|
438
|
+
],
|
|
439
|
+
},
|
|
440
|
+
{ configurable: { thread_id: 's1' }, version: 'v2' as const }
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
const runMessages = run.getRunMessages();
|
|
444
|
+
const aiCount =
|
|
445
|
+
runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
|
|
446
|
+
const lastAgent = run.getLastActiveAgentId?.();
|
|
447
|
+
|
|
448
|
+
console.log(`\n\n--- S1 Results ---`);
|
|
449
|
+
console.log(` AI messages: ${aiCount}, Last agent: ${lastAgent}`);
|
|
450
|
+
|
|
451
|
+
const success = aiCount >= 2 && lastAgent === 'hotel_assistant';
|
|
452
|
+
printResult(
|
|
453
|
+
'S1: Handoff — No Tools',
|
|
454
|
+
success,
|
|
455
|
+
success
|
|
456
|
+
? `Both agents participated (${aiCount} AI msgs), handoff to hotel confirmed`
|
|
457
|
+
: `Expected 2+ AI msgs & hotel_assistant last, got ${aiCount} msgs & ${lastAgent}`
|
|
458
|
+
);
|
|
459
|
+
return success;
|
|
460
|
+
} catch (error) {
|
|
461
|
+
console.error('S1 error:', error);
|
|
462
|
+
printResult('S1: Handoff — No Tools', false, String(error));
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/* ================================================================== */
|
|
468
|
+
/* S2: Handoff — Single Tool */
|
|
469
|
+
/* weather_agent (get_weather) -> activity_advisor */
|
|
470
|
+
/* ================================================================== */
|
|
471
|
+
async function s2_handoff_singleTool(): Promise<boolean> {
|
|
472
|
+
printHeader('S2: HANDOFF — SINGLE TOOL');
|
|
473
|
+
console.log(' weather_agent [get_weather] -> activity_advisor');
|
|
474
|
+
console.log(' Agent calls one tool, then hands off\n');
|
|
475
|
+
|
|
476
|
+
const agents: t.AgentInputs[] = [
|
|
477
|
+
agent(
|
|
478
|
+
'weather_agent',
|
|
479
|
+
'Weather Agent',
|
|
480
|
+
`You are a Weather Agent. When the user asks about weather:
|
|
481
|
+
1. Use the get_weather tool to get the data for the requested city
|
|
482
|
+
2. Briefly report the temperature and condition (1 sentence)
|
|
483
|
+
3. Then IMMEDIATELY hand off to the activity advisor
|
|
484
|
+
You MUST hand off after reporting the weather. Do NOT suggest activities yourself.`,
|
|
485
|
+
{ tools: [getWeatherTool], description: 'Gets weather data using tools' }
|
|
486
|
+
),
|
|
487
|
+
agent(
|
|
488
|
+
'activity_advisor',
|
|
489
|
+
'Activity Advisor',
|
|
490
|
+
`You are an Activity Advisor. Based on the weather information from the previous agent:
|
|
491
|
+
1. Suggest 2-3 activities suited for the conditions
|
|
492
|
+
2. Recommend what to wear or pack
|
|
493
|
+
Keep it brief (2-3 sentences).`,
|
|
494
|
+
{ description: 'Recommends activities based on weather' }
|
|
495
|
+
),
|
|
496
|
+
];
|
|
497
|
+
|
|
498
|
+
const edges: t.GraphEdge[] = [
|
|
499
|
+
{
|
|
500
|
+
from: 'weather_agent',
|
|
501
|
+
to: 'activity_advisor',
|
|
502
|
+
description: 'Transfer to activity advisor after getting weather data',
|
|
503
|
+
},
|
|
504
|
+
];
|
|
505
|
+
|
|
506
|
+
const { handlers, contentParts } = createHandlers('S2');
|
|
507
|
+
|
|
508
|
+
try {
|
|
509
|
+
const run = await Run.create({
|
|
510
|
+
runId: `s2-${Date.now()}`,
|
|
511
|
+
graphConfig: { type: 'multi-agent', agents, edges },
|
|
512
|
+
customHandlers: handlers,
|
|
513
|
+
returnContent: true,
|
|
514
|
+
skipCleanup: true,
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
await run.processStream(
|
|
518
|
+
{
|
|
519
|
+
messages: [
|
|
520
|
+
new HumanMessage(
|
|
521
|
+
'What is the weather like in Miami? What activities should I plan?'
|
|
522
|
+
),
|
|
523
|
+
],
|
|
524
|
+
},
|
|
525
|
+
{ configurable: { thread_id: 's2' }, version: 'v2' as const }
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
const runMessages = run.getRunMessages();
|
|
529
|
+
const aiCount =
|
|
530
|
+
runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
|
|
531
|
+
const toolCount =
|
|
532
|
+
runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
|
|
533
|
+
const lastAgent = run.getLastActiveAgentId?.();
|
|
534
|
+
|
|
535
|
+
console.log(`\n\n--- S2 Results ---`);
|
|
536
|
+
console.log(
|
|
537
|
+
` AI messages: ${aiCount}, Tool messages: ${toolCount}, Last agent: ${lastAgent}`
|
|
538
|
+
);
|
|
539
|
+
|
|
540
|
+
const success = aiCount >= 2 && toolCount >= 1;
|
|
541
|
+
printResult(
|
|
542
|
+
'S2: Handoff — Single Tool',
|
|
543
|
+
success,
|
|
544
|
+
`Tool used: ${toolCount >= 1}, Handoff: ${lastAgent === 'activity_advisor'}, AI msgs: ${aiCount}`
|
|
545
|
+
);
|
|
546
|
+
return success;
|
|
547
|
+
} catch (error) {
|
|
548
|
+
console.error('S2 error:', error);
|
|
549
|
+
printResult('S2: Handoff — Single Tool', false, String(error));
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/* ================================================================== */
|
|
555
|
+
/* S3: Handoff — Multiple Tools */
|
|
556
|
+
/* research_agent [weather + stock + time] -> report_agent */
|
|
557
|
+
/* ================================================================== */
|
|
558
|
+
async function s3_handoff_multipleTools(): Promise<boolean> {
|
|
559
|
+
printHeader('S3: HANDOFF — MULTIPLE TOOLS (3 tools)');
|
|
560
|
+
console.log(
|
|
561
|
+
' research_agent [get_weather, get_stock_price, get_time] -> report_agent'
|
|
562
|
+
);
|
|
563
|
+
console.log(' Agent calls multiple tools, then hands off\n');
|
|
564
|
+
|
|
565
|
+
const agents: t.AgentInputs[] = [
|
|
566
|
+
agent(
|
|
567
|
+
'research_agent',
|
|
568
|
+
'Research Agent',
|
|
569
|
+
`You are a Research Agent with three tools: get_weather, get_stock_price, and get_time.
|
|
570
|
+
When the user asks for a briefing:
|
|
571
|
+
1. Use get_weather to check weather in the requested city
|
|
572
|
+
2. Use get_stock_price to check the requested stock
|
|
573
|
+
3. Use get_time to check the time in the requested timezone
|
|
574
|
+
After gathering ALL data from all three tools, briefly summarize your findings (2-3 sentences).
|
|
575
|
+
Then IMMEDIATELY hand off to the report agent. Do NOT write the full report yourself.`,
|
|
576
|
+
{
|
|
577
|
+
tools: [getWeatherTool, getStockPriceTool, getTimeTool],
|
|
578
|
+
description: 'Gathers data from multiple tools',
|
|
579
|
+
}
|
|
580
|
+
),
|
|
581
|
+
agent(
|
|
582
|
+
'report_agent',
|
|
583
|
+
'Report Agent',
|
|
584
|
+
`You are a Report Agent. Based on the research data provided:
|
|
585
|
+
1. Create a formatted executive morning briefing
|
|
586
|
+
2. Include weather, market, and time sections
|
|
587
|
+
3. End with a brief recommendation for the day
|
|
588
|
+
Keep it to 4-6 sentences total.`,
|
|
589
|
+
{ description: 'Creates formatted reports from gathered data' }
|
|
590
|
+
),
|
|
591
|
+
];
|
|
592
|
+
|
|
593
|
+
const edges: t.GraphEdge[] = [
|
|
594
|
+
{
|
|
595
|
+
from: 'research_agent',
|
|
596
|
+
to: 'report_agent',
|
|
597
|
+
description:
|
|
598
|
+
'Transfer to report agent after gathering all research data to create a formatted report',
|
|
599
|
+
},
|
|
600
|
+
];
|
|
601
|
+
|
|
602
|
+
const { handlers, contentParts } = createHandlers('S3');
|
|
603
|
+
|
|
604
|
+
try {
|
|
605
|
+
const run = await Run.create({
|
|
606
|
+
runId: `s3-${Date.now()}`,
|
|
607
|
+
graphConfig: { type: 'multi-agent', agents, edges },
|
|
608
|
+
customHandlers: handlers,
|
|
609
|
+
returnContent: true,
|
|
610
|
+
skipCleanup: true,
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
await run.processStream(
|
|
614
|
+
{
|
|
615
|
+
messages: [
|
|
616
|
+
new HumanMessage(
|
|
617
|
+
'Give me a morning briefing: weather in New York, AAPL stock price, and current time in EST.'
|
|
618
|
+
),
|
|
619
|
+
],
|
|
620
|
+
},
|
|
621
|
+
{ configurable: { thread_id: 's3' }, version: 'v2' as const }
|
|
622
|
+
);
|
|
623
|
+
|
|
624
|
+
const runMessages = run.getRunMessages();
|
|
625
|
+
const aiCount =
|
|
626
|
+
runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
|
|
627
|
+
const toolCount =
|
|
628
|
+
runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
|
|
629
|
+
const lastAgent = run.getLastActiveAgentId?.();
|
|
630
|
+
|
|
631
|
+
console.log(`\n\n--- S3 Results ---`);
|
|
632
|
+
console.log(
|
|
633
|
+
` AI messages: ${aiCount}, Tool messages: ${toolCount}, Last agent: ${lastAgent}`
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
/** Expect at least 3 tool calls (weather + stock + time) */
|
|
637
|
+
const success = aiCount >= 2 && toolCount >= 3;
|
|
638
|
+
printResult(
|
|
639
|
+
'S3: Handoff — Multiple Tools',
|
|
640
|
+
success,
|
|
641
|
+
`Tools called: ${toolCount} (expected ≥3), Handoff: ${lastAgent === 'report_agent'}, AI msgs: ${aiCount}`
|
|
642
|
+
);
|
|
643
|
+
return success;
|
|
644
|
+
} catch (error) {
|
|
645
|
+
console.error('S3 error:', error);
|
|
646
|
+
printResult('S3: Handoff — Multiple Tools', false, String(error));
|
|
647
|
+
return false;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/* ================================================================== */
|
|
652
|
+
/* S4: Sequential (Direct Edges) — No Tools */
|
|
653
|
+
/* researcher -> analyst -> summarizer (sim-style DAG) */
|
|
654
|
+
/* ================================================================== */
|
|
655
|
+
async function s4_sequential_noTools(): Promise<boolean> {
|
|
656
|
+
printHeader('S4: SEQUENTIAL (DIRECT) — NO TOOLS');
|
|
657
|
+
console.log(' researcher -> analyst -> summarizer');
|
|
658
|
+
console.log(' Each agent receives previous outputs as context, no tools\n');
|
|
659
|
+
|
|
660
|
+
const agents: t.AgentInputs[] = [
|
|
661
|
+
agent(
|
|
662
|
+
'researcher',
|
|
663
|
+
'Researcher',
|
|
664
|
+
`You are a Research Agent. Your task:
|
|
665
|
+
1. Analyze the user's question
|
|
666
|
+
2. List 3-4 key facts or considerations
|
|
667
|
+
Keep it to 3-4 bullet points. Start with "RESEARCH:"`
|
|
668
|
+
),
|
|
669
|
+
agent(
|
|
670
|
+
'analyst',
|
|
671
|
+
'Analyst',
|
|
672
|
+
`You are an Analysis Agent. Your task:
|
|
673
|
+
1. Read the research findings from the previous agent
|
|
674
|
+
2. Identify patterns, risks, and opportunities
|
|
675
|
+
3. Add deeper analytical insights
|
|
676
|
+
Keep it to 3-4 bullet points. Start with "ANALYSIS:"`
|
|
677
|
+
),
|
|
678
|
+
agent(
|
|
679
|
+
'summarizer',
|
|
680
|
+
'Summarizer',
|
|
681
|
+
`You are a Summary Agent. Your task:
|
|
682
|
+
1. Synthesize the research AND analysis from previous agents
|
|
683
|
+
2. Create a cohesive 2-3 sentence executive summary
|
|
684
|
+
3. End with one key recommendation
|
|
685
|
+
Start with "SUMMARY:" and end with "RECOMMENDATION:"`
|
|
686
|
+
),
|
|
687
|
+
];
|
|
688
|
+
|
|
689
|
+
const edges: t.GraphEdge[] = [
|
|
690
|
+
{
|
|
691
|
+
from: 'researcher',
|
|
692
|
+
to: 'analyst',
|
|
693
|
+
edgeType: 'direct',
|
|
694
|
+
prompt: (messages: BaseMessage[], startIndex: number) => {
|
|
695
|
+
const buffer = getBufferString(messages.slice(startIndex));
|
|
696
|
+
return `Here are the research findings. Analyze them and provide insights:\n\n${buffer}`;
|
|
697
|
+
},
|
|
698
|
+
excludeResults: true,
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
from: 'analyst',
|
|
702
|
+
to: 'summarizer',
|
|
703
|
+
edgeType: 'direct',
|
|
704
|
+
prompt: (messages: BaseMessage[], startIndex: number) => {
|
|
705
|
+
const buffer = getBufferString(messages.slice(startIndex));
|
|
706
|
+
return `Here are the combined research and analysis. Synthesize into a final summary:\n\n${buffer}`;
|
|
707
|
+
},
|
|
708
|
+
excludeResults: true,
|
|
709
|
+
},
|
|
710
|
+
];
|
|
711
|
+
|
|
712
|
+
const { handlers, contentParts } = createHandlers('S4');
|
|
713
|
+
|
|
714
|
+
try {
|
|
715
|
+
const run = await Run.create({
|
|
716
|
+
runId: `s4-${Date.now()}`,
|
|
717
|
+
graphConfig: { type: 'multi-agent', agents, edges },
|
|
718
|
+
customHandlers: handlers,
|
|
719
|
+
returnContent: true,
|
|
720
|
+
skipCleanup: true,
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
await run.processStream(
|
|
724
|
+
{
|
|
725
|
+
messages: [
|
|
726
|
+
new HumanMessage(
|
|
727
|
+
'What are the key considerations for migrating a monolithic application to microservices?'
|
|
728
|
+
),
|
|
729
|
+
],
|
|
730
|
+
},
|
|
731
|
+
{ configurable: { thread_id: 's4' }, version: 'v2' as const }
|
|
732
|
+
);
|
|
733
|
+
|
|
734
|
+
const runMessages = run.getRunMessages();
|
|
735
|
+
const aiMessages = runMessages?.filter((m) => m._getType() === 'ai') ?? [];
|
|
736
|
+
|
|
737
|
+
console.log(`\n\n--- S4 Results ---`);
|
|
738
|
+
console.log(` AI messages: ${aiMessages.length}`);
|
|
739
|
+
for (let i = 0; i < aiMessages.length; i++) {
|
|
740
|
+
const name = ['researcher', 'analyst', 'summarizer'][i] ?? `agent_${i}`;
|
|
741
|
+
const content =
|
|
742
|
+
typeof aiMessages[i].content === 'string'
|
|
743
|
+
? aiMessages[i].content
|
|
744
|
+
: JSON.stringify(aiMessages[i].content);
|
|
745
|
+
console.log(` ${name}: ${(content as string).slice(0, 80)}...`);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const success = aiMessages.length === 3;
|
|
749
|
+
printResult(
|
|
750
|
+
'S4: Sequential — No Tools',
|
|
751
|
+
success,
|
|
752
|
+
success
|
|
753
|
+
? `All 3 agents produced output sequentially`
|
|
754
|
+
: `Expected 3 AI messages, got ${aiMessages.length}`
|
|
755
|
+
);
|
|
756
|
+
return success;
|
|
757
|
+
} catch (error) {
|
|
758
|
+
console.error('S4 error:', error);
|
|
759
|
+
printResult('S4: Sequential — No Tools', false, String(error));
|
|
760
|
+
return false;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/* ================================================================== */
|
|
765
|
+
/* S5: Sequential (Direct Edges) — Single Tool Per Agent */
|
|
766
|
+
/* data_collector [search_database] -> translator [translate_text] */
|
|
767
|
+
/* -> reviewer (no tool) */
|
|
768
|
+
/* ================================================================== */
|
|
769
|
+
async function s5_sequential_singleTool(): Promise<boolean> {
|
|
770
|
+
printHeader('S5: SEQUENTIAL (DIRECT) — SINGLE TOOL PER AGENT');
|
|
771
|
+
console.log(
|
|
772
|
+
' data_collector [search_database] -> translator [translate_text] -> reviewer'
|
|
773
|
+
);
|
|
774
|
+
console.log(' Each agent has one tool, output flows sequentially\n');
|
|
775
|
+
|
|
776
|
+
const agents: t.AgentInputs[] = [
|
|
777
|
+
agent(
|
|
778
|
+
'data_collector',
|
|
779
|
+
'Data Collector',
|
|
780
|
+
`You are a Data Collector Agent. When given a query:
|
|
781
|
+
1. Use the search_database tool to find relevant information
|
|
782
|
+
2. Present the search results in a clear, organized format (3-4 bullet points)
|
|
783
|
+
Start with "DATA COLLECTED:"`,
|
|
784
|
+
{
|
|
785
|
+
tools: [searchDatabaseTool],
|
|
786
|
+
description: 'Searches database for information',
|
|
787
|
+
}
|
|
788
|
+
),
|
|
789
|
+
agent(
|
|
790
|
+
'translator',
|
|
791
|
+
'Translator',
|
|
792
|
+
`You are a Translator Agent. When you receive data from the previous agent:
|
|
793
|
+
1. Use the translate_text tool to translate the KEY findings to the requested language
|
|
794
|
+
2. Present both original and translated versions
|
|
795
|
+
Keep it brief. Start with "TRANSLATED:"`,
|
|
796
|
+
{
|
|
797
|
+
tools: [translateTextTool],
|
|
798
|
+
description: 'Translates text between languages',
|
|
799
|
+
}
|
|
800
|
+
),
|
|
801
|
+
agent(
|
|
802
|
+
'reviewer',
|
|
803
|
+
'Quality Reviewer',
|
|
804
|
+
`You are a Quality Reviewer. Review the collected and translated data:
|
|
805
|
+
1. Confirm data accuracy and translation quality
|
|
806
|
+
2. Note any issues
|
|
807
|
+
3. Give a quality score (1-10)
|
|
808
|
+
Start with "REVIEW:" and keep it to 3-4 lines.`
|
|
809
|
+
),
|
|
810
|
+
];
|
|
811
|
+
|
|
812
|
+
const edges: t.GraphEdge[] = [
|
|
813
|
+
{
|
|
814
|
+
from: 'data_collector',
|
|
815
|
+
to: 'translator',
|
|
816
|
+
edgeType: 'direct',
|
|
817
|
+
prompt: (messages: BaseMessage[], startIndex: number) => {
|
|
818
|
+
const buffer = getBufferString(messages.slice(startIndex));
|
|
819
|
+
return `Here is the collected data. Translate the key findings to Spanish:\n\n${buffer}`;
|
|
820
|
+
},
|
|
821
|
+
excludeResults: true,
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
from: 'translator',
|
|
825
|
+
to: 'reviewer',
|
|
826
|
+
edgeType: 'direct',
|
|
827
|
+
prompt: (messages: BaseMessage[], startIndex: number) => {
|
|
828
|
+
const buffer = getBufferString(messages.slice(startIndex));
|
|
829
|
+
return `Here is the collected and translated data. Review it for quality:\n\n${buffer}`;
|
|
830
|
+
},
|
|
831
|
+
excludeResults: true,
|
|
832
|
+
},
|
|
833
|
+
];
|
|
834
|
+
|
|
835
|
+
const { handlers, contentParts } = createHandlers('S5');
|
|
836
|
+
|
|
837
|
+
try {
|
|
838
|
+
const run = await Run.create({
|
|
839
|
+
runId: `s5-${Date.now()}`,
|
|
840
|
+
graphConfig: { type: 'multi-agent', agents, edges },
|
|
841
|
+
customHandlers: handlers,
|
|
842
|
+
returnContent: true,
|
|
843
|
+
skipCleanup: true,
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
await run.processStream(
|
|
847
|
+
{
|
|
848
|
+
messages: [
|
|
849
|
+
new HumanMessage(
|
|
850
|
+
'Search for engineering employees and translate the key findings to Spanish.'
|
|
851
|
+
),
|
|
852
|
+
],
|
|
853
|
+
},
|
|
854
|
+
{ configurable: { thread_id: 's5' }, version: 'v2' as const }
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
const runMessages = run.getRunMessages();
|
|
858
|
+
const aiCount =
|
|
859
|
+
runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
|
|
860
|
+
const toolCount =
|
|
861
|
+
runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
|
|
862
|
+
|
|
863
|
+
console.log(`\n\n--- S5 Results ---`);
|
|
864
|
+
console.log(` AI messages: ${aiCount}, Tool messages: ${toolCount}`);
|
|
865
|
+
|
|
866
|
+
/** Expect at least 2 tool calls (search + translate) across the chain */
|
|
867
|
+
const success = aiCount >= 3 && toolCount >= 2;
|
|
868
|
+
printResult(
|
|
869
|
+
'S5: Sequential — Single Tool',
|
|
870
|
+
success,
|
|
871
|
+
`AI msgs: ${aiCount} (expected 3), Tool calls: ${toolCount} (expected ≥2)`
|
|
872
|
+
);
|
|
873
|
+
return success;
|
|
874
|
+
} catch (error) {
|
|
875
|
+
console.error('S5 error:', error);
|
|
876
|
+
printResult('S5: Sequential — Single Tool', false, String(error));
|
|
877
|
+
return false;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/* ================================================================== */
|
|
882
|
+
/* S6: Sequential (Direct Edges) — Multiple Tools Per Agent */
|
|
883
|
+
/* intel_gatherer [weather+stock+time] -> analyst [sentiment+search] */
|
|
884
|
+
/* -> presenter (no tools) */
|
|
885
|
+
/* ================================================================== */
|
|
886
|
+
async function s6_sequential_multipleTools(): Promise<boolean> {
|
|
887
|
+
printHeader('S6: SEQUENTIAL (DIRECT) — MULTIPLE TOOLS PER AGENT');
|
|
888
|
+
console.log(
|
|
889
|
+
' intel_gatherer [weather, stock, time] -> analyst [sentiment, search_db] -> presenter'
|
|
890
|
+
);
|
|
891
|
+
console.log(' Agents have 2-3 tools each, output flows sequentially\n');
|
|
892
|
+
|
|
893
|
+
const agents: t.AgentInputs[] = [
|
|
894
|
+
agent(
|
|
895
|
+
'intel_gatherer',
|
|
896
|
+
'Intelligence Gatherer',
|
|
897
|
+
`You are an Intelligence Gatherer Agent with three tools: get_weather, get_stock_price, and get_time.
|
|
898
|
+
For the morning intelligence report:
|
|
899
|
+
1. Use get_weather to check weather in Tokyo
|
|
900
|
+
2. Use get_stock_price to check NVDA stock
|
|
901
|
+
3. Use get_time to check current time in JST
|
|
902
|
+
Present all gathered data clearly. Start with "INTEL GATHERED:"`,
|
|
903
|
+
{
|
|
904
|
+
tools: [getWeatherTool, getStockPriceTool, getTimeTool],
|
|
905
|
+
description: 'Gathers intelligence from multiple data sources',
|
|
906
|
+
}
|
|
907
|
+
),
|
|
908
|
+
agent(
|
|
909
|
+
'market_analyst',
|
|
910
|
+
'Market Analyst',
|
|
911
|
+
`You are a Market Analyst Agent with two tools: analyze_sentiment and search_database.
|
|
912
|
+
Based on the intelligence gathered:
|
|
913
|
+
1. Use analyze_sentiment on a summary of the market conditions described by the previous agent
|
|
914
|
+
2. Use search_database to find relevant projects in the "projects" category related to "AI"
|
|
915
|
+
3. Combine insights into a brief market analysis
|
|
916
|
+
Start with "MARKET ANALYSIS:"`,
|
|
917
|
+
{
|
|
918
|
+
tools: [sentimentAnalysisTool, searchDatabaseTool],
|
|
919
|
+
description: 'Analyzes market sentiment and cross-references data',
|
|
920
|
+
}
|
|
921
|
+
),
|
|
922
|
+
agent(
|
|
923
|
+
'presenter',
|
|
924
|
+
'Executive Presenter',
|
|
925
|
+
`You are an Executive Presenter Agent. Create a polished executive summary from the intelligence and analysis:
|
|
926
|
+
1. Lead with the most important insight
|
|
927
|
+
2. Include key metrics (weather, market, time)
|
|
928
|
+
3. End with an actionable recommendation
|
|
929
|
+
Format as a brief executive memo (4-5 sentences). Start with "EXECUTIVE SUMMARY:"`
|
|
930
|
+
),
|
|
931
|
+
];
|
|
932
|
+
|
|
933
|
+
const edges: t.GraphEdge[] = [
|
|
934
|
+
{
|
|
935
|
+
from: 'intel_gatherer',
|
|
936
|
+
to: 'market_analyst',
|
|
937
|
+
edgeType: 'direct',
|
|
938
|
+
prompt: (messages: BaseMessage[], startIndex: number) => {
|
|
939
|
+
const buffer = getBufferString(messages.slice(startIndex));
|
|
940
|
+
return `Here is the gathered intelligence. Analyze the market sentiment and cross-reference with our database:\n\n${buffer}`;
|
|
941
|
+
},
|
|
942
|
+
excludeResults: true,
|
|
943
|
+
},
|
|
944
|
+
{
|
|
945
|
+
from: 'market_analyst',
|
|
946
|
+
to: 'presenter',
|
|
947
|
+
edgeType: 'direct',
|
|
948
|
+
prompt: (messages: BaseMessage[], startIndex: number) => {
|
|
949
|
+
const buffer = getBufferString(messages.slice(startIndex));
|
|
950
|
+
return `Here is the intelligence and market analysis. Create a polished executive summary:\n\n${buffer}`;
|
|
951
|
+
},
|
|
952
|
+
excludeResults: true,
|
|
953
|
+
},
|
|
954
|
+
];
|
|
955
|
+
|
|
956
|
+
const { handlers, contentParts } = createHandlers('S6');
|
|
957
|
+
|
|
958
|
+
try {
|
|
959
|
+
const run = await Run.create({
|
|
960
|
+
runId: `s6-${Date.now()}`,
|
|
961
|
+
graphConfig: { type: 'multi-agent', agents, edges },
|
|
962
|
+
customHandlers: handlers,
|
|
963
|
+
returnContent: true,
|
|
964
|
+
skipCleanup: true,
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
await run.processStream(
|
|
968
|
+
{
|
|
969
|
+
messages: [
|
|
970
|
+
new HumanMessage(
|
|
971
|
+
'Create a morning intelligence briefing: check Tokyo weather, NVDA stock, and JST time. Then analyze market sentiment and find relevant AI projects.'
|
|
972
|
+
),
|
|
973
|
+
],
|
|
974
|
+
},
|
|
975
|
+
{ configurable: { thread_id: 's6' }, version: 'v2' as const }
|
|
976
|
+
);
|
|
977
|
+
|
|
978
|
+
const runMessages = run.getRunMessages();
|
|
979
|
+
const aiCount =
|
|
980
|
+
runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
|
|
981
|
+
const toolCount =
|
|
982
|
+
runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
|
|
983
|
+
|
|
984
|
+
console.log(`\n\n--- S6 Results ---`);
|
|
985
|
+
console.log(` AI messages: ${aiCount}, Tool messages: ${toolCount}`);
|
|
986
|
+
|
|
987
|
+
/** Expect at least 5 tool calls (3 from gatherer + 2 from analyst) */
|
|
988
|
+
const success = aiCount >= 3 && toolCount >= 5;
|
|
989
|
+
printResult(
|
|
990
|
+
'S6: Sequential — Multiple Tools',
|
|
991
|
+
success,
|
|
992
|
+
`AI msgs: ${aiCount} (expected 3+), Tool calls: ${toolCount} (expected ≥5)`
|
|
993
|
+
);
|
|
994
|
+
return success;
|
|
995
|
+
} catch (error) {
|
|
996
|
+
console.error('S6 error:', error);
|
|
997
|
+
printResult('S6: Sequential — Multiple Tools', false, String(error));
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/* ================================================================== */
|
|
1003
|
+
/* S7: Hybrid (Direct + Handoff) — Mixed Tools */
|
|
1004
|
+
/* planner --(direct)--> researcher [weather+stock] --(handoff)--> */
|
|
1005
|
+
/* writer OR analyst [sentiment] */
|
|
1006
|
+
/* Direct sequential flow + dynamic handoff with tools */
|
|
1007
|
+
/* ================================================================== */
|
|
1008
|
+
async function s7_hybrid_mixedTools(): Promise<boolean> {
|
|
1009
|
+
printHeader('S7: HYBRID (DIRECT + HANDOFF) — MIXED TOOLS');
|
|
1010
|
+
console.log(' planner --(direct)--> researcher [weather, stock]');
|
|
1011
|
+
console.log(' --(handoff)--> writer (no tools) OR analyst [sentiment]');
|
|
1012
|
+
console.log(' Combines direct sequential + dynamic handoff + tools\n');
|
|
1013
|
+
|
|
1014
|
+
const agents: t.AgentInputs[] = [
|
|
1015
|
+
agent(
|
|
1016
|
+
'planner',
|
|
1017
|
+
'Content Planner',
|
|
1018
|
+
`You are a Content Planner. Given a topic:
|
|
1019
|
+
1. Create a brief 3-point outline for a market report
|
|
1020
|
+
2. Specify what data needs to be gathered (weather and stock)
|
|
1021
|
+
3. Note the target audience
|
|
1022
|
+
Keep it to 3-4 lines. Start with "PLAN:"`,
|
|
1023
|
+
{ description: 'Plans content structure and outlines' }
|
|
1024
|
+
),
|
|
1025
|
+
agent(
|
|
1026
|
+
'researcher',
|
|
1027
|
+
'Data Researcher',
|
|
1028
|
+
`You are a Data Researcher with get_weather and get_stock_price tools.
|
|
1029
|
+
Based on the content plan:
|
|
1030
|
+
1. Use get_weather to get weather for the city mentioned in the plan (default: Los Angeles)
|
|
1031
|
+
2. Use get_stock_price to get the stock price mentioned in the plan (default: GOOGL)
|
|
1032
|
+
3. Briefly summarize your data findings (2-3 sentences)
|
|
1033
|
+
Then transfer to the writer to create the full report.
|
|
1034
|
+
IMPORTANT: After gathering data, you MUST use the transfer tool to send to the writer.
|
|
1035
|
+
Start with "RESEARCH DATA:"`,
|
|
1036
|
+
{
|
|
1037
|
+
tools: [getWeatherTool, getStockPriceTool],
|
|
1038
|
+
description:
|
|
1039
|
+
'Gathers data using research tools, can route to writer or analyst',
|
|
1040
|
+
}
|
|
1041
|
+
),
|
|
1042
|
+
agent(
|
|
1043
|
+
'writer',
|
|
1044
|
+
'Report Writer',
|
|
1045
|
+
`You are a Report Writer. Based on the plan and research data:
|
|
1046
|
+
1. Write a brief market report (3-4 sentences)
|
|
1047
|
+
2. Include specific data points from the research
|
|
1048
|
+
3. Add a conclusion
|
|
1049
|
+
Start with "REPORT:" and keep it professional.`,
|
|
1050
|
+
{ description: 'Writes formatted reports from research data' }
|
|
1051
|
+
),
|
|
1052
|
+
agent(
|
|
1053
|
+
'analyst',
|
|
1054
|
+
'Sentiment Analyst',
|
|
1055
|
+
`You are a Sentiment Analyst with the analyze_sentiment tool.
|
|
1056
|
+
If you receive research data:
|
|
1057
|
+
1. Use analyze_sentiment on a summary of the market conditions
|
|
1058
|
+
2. Provide your sentiment assessment
|
|
1059
|
+
3. Give a market outlook (bullish/bearish/neutral)
|
|
1060
|
+
Start with "SENTIMENT ANALYSIS:"`,
|
|
1061
|
+
{
|
|
1062
|
+
tools: [sentimentAnalysisTool],
|
|
1063
|
+
description: 'Analyzes sentiment of market data',
|
|
1064
|
+
}
|
|
1065
|
+
),
|
|
1066
|
+
];
|
|
1067
|
+
|
|
1068
|
+
const edges: t.GraphEdge[] = [
|
|
1069
|
+
/** Direct: planner always flows to researcher */
|
|
1070
|
+
{
|
|
1071
|
+
from: 'planner',
|
|
1072
|
+
to: 'researcher',
|
|
1073
|
+
edgeType: 'direct',
|
|
1074
|
+
prompt: (messages: BaseMessage[], startIndex: number) => {
|
|
1075
|
+
const buffer = getBufferString(messages.slice(startIndex));
|
|
1076
|
+
return `Here is the content plan. Gather the required data:\n\n${buffer}`;
|
|
1077
|
+
},
|
|
1078
|
+
excludeResults: true,
|
|
1079
|
+
},
|
|
1080
|
+
/** Handoff: researcher dynamically chooses writer or analyst */
|
|
1081
|
+
{
|
|
1082
|
+
from: 'researcher',
|
|
1083
|
+
to: 'writer',
|
|
1084
|
+
description:
|
|
1085
|
+
'Transfer to the report writer to create a formatted market report from the gathered data',
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
from: 'researcher',
|
|
1089
|
+
to: 'analyst',
|
|
1090
|
+
description:
|
|
1091
|
+
'Transfer to the sentiment analyst for deeper market sentiment analysis',
|
|
1092
|
+
},
|
|
1093
|
+
];
|
|
1094
|
+
|
|
1095
|
+
const { handlers, contentParts } = createHandlers('S7');
|
|
1096
|
+
|
|
1097
|
+
try {
|
|
1098
|
+
const run = await Run.create({
|
|
1099
|
+
runId: `s7-${Date.now()}`,
|
|
1100
|
+
graphConfig: { type: 'multi-agent', agents, edges },
|
|
1101
|
+
customHandlers: handlers,
|
|
1102
|
+
returnContent: true,
|
|
1103
|
+
skipCleanup: true,
|
|
1104
|
+
});
|
|
1105
|
+
|
|
1106
|
+
await run.processStream(
|
|
1107
|
+
{
|
|
1108
|
+
messages: [
|
|
1109
|
+
new HumanMessage(
|
|
1110
|
+
'Create a market report: plan the structure, gather weather for Los Angeles and GOOGL stock data, then write the full report.'
|
|
1111
|
+
),
|
|
1112
|
+
],
|
|
1113
|
+
},
|
|
1114
|
+
{ configurable: { thread_id: 's7' }, version: 'v2' as const }
|
|
1115
|
+
);
|
|
1116
|
+
|
|
1117
|
+
const runMessages = run.getRunMessages();
|
|
1118
|
+
const aiCount =
|
|
1119
|
+
runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
|
|
1120
|
+
const toolCount =
|
|
1121
|
+
runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
|
|
1122
|
+
const lastAgent = run.getLastActiveAgentId?.();
|
|
1123
|
+
|
|
1124
|
+
console.log(`\n\n--- S7 Results ---`);
|
|
1125
|
+
console.log(
|
|
1126
|
+
` AI messages: ${aiCount}, Tool messages: ${toolCount}, Last agent: ${lastAgent}`
|
|
1127
|
+
);
|
|
1128
|
+
|
|
1129
|
+
/** Expect: planner (1 AI) + researcher (1+ AI with 2+ tools) + writer or analyst (1 AI) = 3+ AI, 2+ tools */
|
|
1130
|
+
const success = aiCount >= 3 && toolCount >= 2;
|
|
1131
|
+
printResult(
|
|
1132
|
+
'S7: Hybrid — Mixed Tools',
|
|
1133
|
+
success,
|
|
1134
|
+
`AI msgs: ${aiCount} (expected 3+), Tools: ${toolCount} (expected ≥2), ` +
|
|
1135
|
+
`Last: ${lastAgent}, Direct (planner→researcher) + handoff (researcher→${lastAgent}) verified`
|
|
1136
|
+
);
|
|
1137
|
+
return success;
|
|
1138
|
+
} catch (error) {
|
|
1139
|
+
console.error('S7 error:', error);
|
|
1140
|
+
printResult('S7: Hybrid — Mixed Tools', false, String(error));
|
|
1141
|
+
return false;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
/* ================================================================== */
|
|
1146
|
+
/* Main Runner */
|
|
1147
|
+
/* ================================================================== */
|
|
1148
|
+
async function main() {
|
|
1149
|
+
console.log('\n');
|
|
1150
|
+
console.log('*'.repeat(80));
|
|
1151
|
+
console.log('* ILLUMA AGENTS — COMPREHENSIVE MULTI-AGENT POC');
|
|
1152
|
+
console.log('* Provider: AWS Bedrock (Claude 3.5 Haiku)');
|
|
1153
|
+
console.log('*');
|
|
1154
|
+
console.log('* HANDOFF scenarios:');
|
|
1155
|
+
console.log(
|
|
1156
|
+
'* S1: No tools S2: Single tool S3: Multiple tools'
|
|
1157
|
+
);
|
|
1158
|
+
console.log('* SEQUENTIAL scenarios:');
|
|
1159
|
+
console.log(
|
|
1160
|
+
'* S4: No tools S5: Single tool S6: Multiple tools'
|
|
1161
|
+
);
|
|
1162
|
+
console.log('* HYBRID:');
|
|
1163
|
+
console.log('* S7: Direct + Handoff + Mixed tools');
|
|
1164
|
+
console.log('*'.repeat(80));
|
|
1165
|
+
|
|
1166
|
+
const results: Record<string, boolean> = {};
|
|
1167
|
+
|
|
1168
|
+
/** Run all scenarios sequentially for clear output */
|
|
1169
|
+
results['S1: Handoff — No Tools'] = await s1_handoff_noTools();
|
|
1170
|
+
results['S2: Handoff — Single Tool'] = await s2_handoff_singleTool();
|
|
1171
|
+
results['S3: Handoff — Multiple Tools (3)'] =
|
|
1172
|
+
await s3_handoff_multipleTools();
|
|
1173
|
+
results['S4: Sequential — No Tools'] = await s4_sequential_noTools();
|
|
1174
|
+
results['S5: Sequential — Single Tool'] = await s5_sequential_singleTool();
|
|
1175
|
+
results['S6: Sequential — Multiple Tools (2-3)'] =
|
|
1176
|
+
await s6_sequential_multipleTools();
|
|
1177
|
+
results['S7: Hybrid — Direct + Handoff + Tools'] =
|
|
1178
|
+
await s7_hybrid_mixedTools();
|
|
1179
|
+
|
|
1180
|
+
/** Final summary */
|
|
1181
|
+
printHeader('POC RESULTS SUMMARY');
|
|
1182
|
+
|
|
1183
|
+
const entries = Object.entries(results);
|
|
1184
|
+
let passCount = 0;
|
|
1185
|
+
|
|
1186
|
+
console.log('\n HANDOFF:');
|
|
1187
|
+
for (const [name, passed] of entries.filter(
|
|
1188
|
+
([n]) => n.startsWith('S1') || n.startsWith('S2') || n.startsWith('S3')
|
|
1189
|
+
)) {
|
|
1190
|
+
console.log(` ${passed ? '[PASS]' : '[FAIL]'} ${name}`);
|
|
1191
|
+
if (passed) passCount++;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
console.log('\n SEQUENTIAL:');
|
|
1195
|
+
for (const [name, passed] of entries.filter(
|
|
1196
|
+
([n]) => n.startsWith('S4') || n.startsWith('S5') || n.startsWith('S6')
|
|
1197
|
+
)) {
|
|
1198
|
+
console.log(` ${passed ? '[PASS]' : '[FAIL]'} ${name}`);
|
|
1199
|
+
if (passed) passCount++;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
console.log('\n HYBRID:');
|
|
1203
|
+
for (const [name, passed] of entries.filter(([n]) => n.startsWith('S7'))) {
|
|
1204
|
+
console.log(` ${passed ? '[PASS]' : '[FAIL]'} ${name}`);
|
|
1205
|
+
if (passed) passCount++;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
console.log(`\n ${passCount}/${entries.length} scenarios passed`);
|
|
1209
|
+
|
|
1210
|
+
if (passCount === entries.length) {
|
|
1211
|
+
console.log('\n All scenarios passed! Multi-agent system fully verified.');
|
|
1212
|
+
} else {
|
|
1213
|
+
console.log('\n Some scenarios failed. Check output above for details.');
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
console.log('\n' + '='.repeat(80));
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
main().catch((err) => {
|
|
1220
|
+
console.error('Fatal error:', err);
|
|
1221
|
+
process.exit(1);
|
|
1222
|
+
});
|