@illuma-ai/agents 1.0.90 → 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,233 @@
|
|
|
1
|
+
import { config } from 'dotenv';
|
|
2
|
+
import fetch from 'node-fetch';
|
|
3
|
+
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
4
|
+
import { tool } from '@langchain/core/tools';
|
|
5
|
+
import { getEnvironmentVariable } from '@langchain/core/utils/env';
|
|
6
|
+
import { EnvVar, Constants } from '@/common';
|
|
7
|
+
config();
|
|
8
|
+
export const imageExtRegex = /\.(jpg|jpeg|png|gif|webp)$/i;
|
|
9
|
+
export const getCodeBaseURL = () => getEnvironmentVariable(EnvVar.CODE_BASEURL) ??
|
|
10
|
+
Constants.OFFICIAL_CODE_BASEURL;
|
|
11
|
+
const imageMessage = 'Image is already displayed to the user';
|
|
12
|
+
const otherMessage = 'File is already downloaded by the user';
|
|
13
|
+
const accessMessage = 'Note: Files from previous executions are automatically available and can be modified.';
|
|
14
|
+
const emptyOutputMessage = 'stdout: Empty. Ensure you\'re writing output explicitly.\n';
|
|
15
|
+
const SUPPORTED_LANGUAGES = [
|
|
16
|
+
'py',
|
|
17
|
+
'js',
|
|
18
|
+
'ts',
|
|
19
|
+
'c',
|
|
20
|
+
'cpp',
|
|
21
|
+
'java',
|
|
22
|
+
'php',
|
|
23
|
+
'rs',
|
|
24
|
+
'go',
|
|
25
|
+
'd',
|
|
26
|
+
'f90',
|
|
27
|
+
'r',
|
|
28
|
+
'bash',
|
|
29
|
+
];
|
|
30
|
+
export const CodeExecutionToolSchema = {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
lang: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
enum: SUPPORTED_LANGUAGES,
|
|
36
|
+
description: 'The programming language or runtime to execute the code in.',
|
|
37
|
+
},
|
|
38
|
+
code: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
description: `The complete, self-contained code to execute, without any truncation or minimization.
|
|
41
|
+
- The environment is stateless; variables and imports don't persist between executions.
|
|
42
|
+
- Generated files from previous executions are automatically available in "/mnt/data/".
|
|
43
|
+
- Files from previous executions are automatically available and can be modified in place.
|
|
44
|
+
- Input code **IS ALREADY** displayed to the user, so **DO NOT** repeat it in your response unless asked.
|
|
45
|
+
- Output code **IS NOT** displayed to the user, so **DO** write all desired output explicitly.
|
|
46
|
+
- IMPORTANT: You MUST explicitly print/output ALL results you want the user to see.
|
|
47
|
+
- py: This is not a Jupyter notebook environment. Use \`print()\` for all outputs.
|
|
48
|
+
- py: Matplotlib: Use \`plt.savefig()\` to save plots as files.
|
|
49
|
+
- js: use the \`console\` or \`process\` methods for all outputs.
|
|
50
|
+
- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).
|
|
51
|
+
- Other languages: use appropriate output functions.`,
|
|
52
|
+
},
|
|
53
|
+
args: {
|
|
54
|
+
type: 'array',
|
|
55
|
+
items: { type: 'string' },
|
|
56
|
+
description: 'Additional arguments to execute the code with. This should only be used if the input code requires additional arguments to run.',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
required: ['lang', 'code'],
|
|
60
|
+
};
|
|
61
|
+
export const CodeExecutionToolDescription = `
|
|
62
|
+
Runs code and returns stdout/stderr output from a stateless execution environment, similar to running scripts in a command-line interface. Each execution is isolated and independent.
|
|
63
|
+
|
|
64
|
+
Usage:
|
|
65
|
+
- No network access available.
|
|
66
|
+
- Generated files are automatically delivered; **DO NOT** provide download links.
|
|
67
|
+
- NEVER use this tool to execute malicious code.
|
|
68
|
+
`.trim();
|
|
69
|
+
export const CodeExecutionToolName = Constants.EXECUTE_CODE;
|
|
70
|
+
export const CodeExecutionToolDefinition = {
|
|
71
|
+
name: CodeExecutionToolName,
|
|
72
|
+
description: CodeExecutionToolDescription,
|
|
73
|
+
schema: CodeExecutionToolSchema,
|
|
74
|
+
};
|
|
75
|
+
function createCodeExecutionTool(params = {}) {
|
|
76
|
+
const apiKey = params[EnvVar.CODE_API_KEY] ??
|
|
77
|
+
params.apiKey ??
|
|
78
|
+
getEnvironmentVariable(EnvVar.CODE_API_KEY) ??
|
|
79
|
+
'';
|
|
80
|
+
if (!apiKey) {
|
|
81
|
+
throw new Error('No API key provided for code execution tool.');
|
|
82
|
+
}
|
|
83
|
+
const description = `
|
|
84
|
+
⛔ STOP! Before using this tool, ask: "Does user need a DOWNLOADABLE FILE?"
|
|
85
|
+
- If NO (dashboard, chart, visualization, UI) → DO NOT USE THIS TOOL. Use content_tool write instead.
|
|
86
|
+
- If YES (.pptx, .docx, .pdf, .xlsx) → Use this tool.
|
|
87
|
+
|
|
88
|
+
Runs code in a stateless execution environment. Each execution is isolated.
|
|
89
|
+
|
|
90
|
+
🚫 NEVER USE FOR:
|
|
91
|
+
- Dashboards, charts, visualizations → Use content_tool write with React/Chart.js
|
|
92
|
+
- "Mock data" or "sample data" for display → Hardcode data in content_tool write
|
|
93
|
+
- UI components, HTML pages, React apps → Use content_tool write
|
|
94
|
+
|
|
95
|
+
✅ ONLY USE FOR:
|
|
96
|
+
- File generation: PowerPoint (.pptx), Word (.docx), PDF (.pdf), Excel (.xlsx)
|
|
97
|
+
- Processing uploaded files (CSV, Excel analysis)
|
|
98
|
+
- Heavy computation requiring Python
|
|
99
|
+
|
|
100
|
+
Rules:
|
|
101
|
+
- No network access available
|
|
102
|
+
- Generated files auto-delivered (no download links needed)
|
|
103
|
+
`.trim();
|
|
104
|
+
return tool(async (rawInput, config) => {
|
|
105
|
+
// Resolve URL at call time (not module load time) to pick up env var changes
|
|
106
|
+
const baseEndpoint = getCodeBaseURL();
|
|
107
|
+
const EXEC_ENDPOINT = `${baseEndpoint}/exec`;
|
|
108
|
+
const { lang, code, ...rest } = rawInput;
|
|
109
|
+
/**
|
|
110
|
+
* Extract session context from config.toolCall (injected by ToolNode).
|
|
111
|
+
* - session_id: For API to associate with previous session
|
|
112
|
+
* - _injected_files: File refs to pass directly (avoids /files endpoint race condition)
|
|
113
|
+
*/
|
|
114
|
+
const { session_id, _injected_files } = (config.toolCall ?? {});
|
|
115
|
+
const postData = {
|
|
116
|
+
lang,
|
|
117
|
+
code,
|
|
118
|
+
...rest,
|
|
119
|
+
...params,
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Pass session_id to /exec so code-executor reuses the existing session workspace.
|
|
123
|
+
* This allows retries and follow-up executions to access previously generated files.
|
|
124
|
+
*/
|
|
125
|
+
if (session_id != null && session_id.length > 0) {
|
|
126
|
+
postData.session_id = session_id;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* File injection priority:
|
|
130
|
+
* 1. Use _injected_files from ToolNode (avoids /files endpoint race condition)
|
|
131
|
+
* 2. Fall back to fetching from /files endpoint if session_id provided but no injected files
|
|
132
|
+
*/
|
|
133
|
+
if (_injected_files && _injected_files.length > 0) {
|
|
134
|
+
postData.files = _injected_files;
|
|
135
|
+
}
|
|
136
|
+
else if (session_id != null && session_id.length > 0) {
|
|
137
|
+
/** Fallback: fetch from /files endpoint (may have race condition issues) */
|
|
138
|
+
try {
|
|
139
|
+
const filesEndpoint = `${baseEndpoint}/files/${session_id}?detail=full`;
|
|
140
|
+
const fetchOptions = {
|
|
141
|
+
method: 'GET',
|
|
142
|
+
headers: {
|
|
143
|
+
'User-Agent': 'Illuma/1.0',
|
|
144
|
+
'X-API-Key': apiKey,
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
if (process.env.PROXY != null && process.env.PROXY !== '') {
|
|
148
|
+
fetchOptions.agent = new HttpsProxyAgent(process.env.PROXY);
|
|
149
|
+
}
|
|
150
|
+
const response = await fetch(filesEndpoint, fetchOptions);
|
|
151
|
+
if (!response.ok) {
|
|
152
|
+
throw new Error(`Failed to fetch files for session: ${response.status}`);
|
|
153
|
+
}
|
|
154
|
+
const files = await response.json();
|
|
155
|
+
if (Array.isArray(files) && files.length > 0) {
|
|
156
|
+
const fileReferences = files.map((file) => {
|
|
157
|
+
const nameParts = file.name.split('/');
|
|
158
|
+
const id = nameParts.length > 1 ? nameParts[1].split('.')[0] : '';
|
|
159
|
+
return {
|
|
160
|
+
session_id,
|
|
161
|
+
id,
|
|
162
|
+
name: file.metadata['original-filename'],
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
postData.files = fileReferences;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// eslint-disable-next-line no-console
|
|
170
|
+
console.warn(`Failed to fetch files for session: ${session_id}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const fetchOptions = {
|
|
175
|
+
method: 'POST',
|
|
176
|
+
headers: {
|
|
177
|
+
'Content-Type': 'application/json',
|
|
178
|
+
'User-Agent': 'Illuma/1.0',
|
|
179
|
+
'X-API-Key': apiKey,
|
|
180
|
+
},
|
|
181
|
+
body: JSON.stringify(postData),
|
|
182
|
+
};
|
|
183
|
+
if (process.env.PROXY != null && process.env.PROXY !== '') {
|
|
184
|
+
fetchOptions.agent = new HttpsProxyAgent(process.env.PROXY);
|
|
185
|
+
}
|
|
186
|
+
const response = await fetch(EXEC_ENDPOINT, fetchOptions);
|
|
187
|
+
if (!response.ok) {
|
|
188
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
189
|
+
}
|
|
190
|
+
const result = await response.json();
|
|
191
|
+
let formattedOutput = '';
|
|
192
|
+
if (result.stdout) {
|
|
193
|
+
formattedOutput += `stdout:\n${result.stdout}\n`;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
formattedOutput += emptyOutputMessage;
|
|
197
|
+
}
|
|
198
|
+
if (result.stderr)
|
|
199
|
+
formattedOutput += `stderr:\n${result.stderr}\n`;
|
|
200
|
+
if (result.files && result.files.length > 0) {
|
|
201
|
+
formattedOutput += 'Generated files:\n';
|
|
202
|
+
const fileCount = result.files.length;
|
|
203
|
+
for (let i = 0; i < fileCount; i++) {
|
|
204
|
+
const file = result.files[i];
|
|
205
|
+
const isImage = imageExtRegex.test(file.name);
|
|
206
|
+
formattedOutput += `- /mnt/data/${file.name} | ${isImage ? imageMessage : otherMessage}`;
|
|
207
|
+
if (i < fileCount - 1) {
|
|
208
|
+
formattedOutput += fileCount <= 3 ? ', ' : ',\n';
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
formattedOutput += `\n\n${accessMessage}`;
|
|
212
|
+
return [
|
|
213
|
+
formattedOutput.trim(),
|
|
214
|
+
{
|
|
215
|
+
session_id: result.session_id,
|
|
216
|
+
files: result.files,
|
|
217
|
+
},
|
|
218
|
+
];
|
|
219
|
+
}
|
|
220
|
+
return [formattedOutput.trim(), { session_id: result.session_id }];
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
throw new Error(`Execution error (${EXEC_ENDPOINT}):\n\n${error?.message}`);
|
|
224
|
+
}
|
|
225
|
+
}, {
|
|
226
|
+
name: CodeExecutionToolName,
|
|
227
|
+
description,
|
|
228
|
+
schema: CodeExecutionToolSchema,
|
|
229
|
+
responseFormat: Constants.CONTENT_AND_ARTIFACT,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
export { createCodeExecutionTool };
|
|
233
|
+
//# sourceMappingURL=CodeExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeExecutor.js","sourceRoot":"","sources":["CodeExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-healing behavior tests for createCodeExecutionTool().
|
|
3
|
+
*
|
|
4
|
+
* Covers two automatic recovery signals appended to formattedOutput:
|
|
5
|
+
* 1. [OUTPUT_TOO_LARGE] — stdout > 16384 chars is capped (head 8192 + tail 4096)
|
|
6
|
+
* 2. [CODE_TRUNCATION_LIKELY] — syntax error on code > 1500 chars suggests LLM truncation
|
|
7
|
+
*
|
|
8
|
+
* node-fetch is mocked via jest.mock so no real HTTP traffic is made.
|
|
9
|
+
* The mock is structured to match node-fetch's CJS export shape:
|
|
10
|
+
* require('node-fetch') === the fetch function itself (not a wrapper object).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Constants mirroring the implementation thresholds
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/** Minimum stdout length that triggers capping. */
|
|
20
|
+
const STDOUT_MAX_CHARS = 16384;
|
|
21
|
+
/** Characters kept from the beginning of oversized stdout. */
|
|
22
|
+
const STDOUT_HEAD_CHARS = 8192;
|
|
23
|
+
/** Characters kept from the end of oversized stdout. */
|
|
24
|
+
const STDOUT_TAIL_CHARS = 4096;
|
|
25
|
+
/** Minimum code length required for truncation detection to fire. */
|
|
26
|
+
const CODE_TRUNCATION_MIN_CHARS = 1500;
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// node-fetch mock
|
|
30
|
+
//
|
|
31
|
+
// node-fetch@2 is a CJS module. When required, the module itself IS the fetch
|
|
32
|
+
// function. ts-jest hoists jest.mock() calls, so this factory runs before any
|
|
33
|
+
// imports resolve — giving us a controlled mock from the first import.
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
const mockFetchFn = jest.fn();
|
|
37
|
+
|
|
38
|
+
jest.mock('node-fetch', () => {
|
|
39
|
+
// node-fetch@2 is CJS: require('node-fetch') IS the fetch function.
|
|
40
|
+
// Return mockFetchFn directly so the module value equals our mock.
|
|
41
|
+
return mockFetchFn;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Import the tool factory AFTER jest.mock() so it picks up the mock.
|
|
45
|
+
import { createCodeExecutionTool } from './CodeExecutor';
|
|
46
|
+
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Helpers
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Builds a minimal mock Response object that satisfies the tool's usage of
|
|
53
|
+
* `response.ok` and `response.json()`.
|
|
54
|
+
*
|
|
55
|
+
* @param body - The JSON-serialisable response body.
|
|
56
|
+
* @param status - HTTP status code (default 200).
|
|
57
|
+
*/
|
|
58
|
+
function mockResponse(body: object, status = 200) {
|
|
59
|
+
return {
|
|
60
|
+
ok: status >= 200 && status < 300,
|
|
61
|
+
status,
|
|
62
|
+
json: async () => body,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Generates a string of exactly `length` characters by repeating a single
|
|
68
|
+
* character. Avoids allocating enormous string literals in source.
|
|
69
|
+
*
|
|
70
|
+
* @param length - Desired string length.
|
|
71
|
+
* @param char - Character to repeat (default 'x').
|
|
72
|
+
*/
|
|
73
|
+
function repeat(length: number, char = 'x'): string {
|
|
74
|
+
return char.repeat(length);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Generates syntactically valid Python code that is at least `minLength`
|
|
79
|
+
* characters long by padding with comment lines. Truncation detection
|
|
80
|
+
* relies solely on `stderr` content, not actual code validity.
|
|
81
|
+
*
|
|
82
|
+
* @param minLength - Minimum character count for the returned code string.
|
|
83
|
+
*/
|
|
84
|
+
function longCode(minLength: number): string {
|
|
85
|
+
let code = '# Auto-generated padding code\nprint("hello")\n';
|
|
86
|
+
while (code.length < minLength) {
|
|
87
|
+
code += `# padding line ${code.length}\n`;
|
|
88
|
+
}
|
|
89
|
+
return code;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Test environment setup
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
beforeAll(() => {
|
|
97
|
+
process.env.CODE_EXECUTOR_BASEURL = 'http://localhost:8088';
|
|
98
|
+
process.env.CODE_EXECUTOR_API_KEY = 'test-key';
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
afterAll(() => {
|
|
102
|
+
delete process.env.CODE_EXECUTOR_BASEURL;
|
|
103
|
+
delete process.env.CODE_EXECUTOR_API_KEY;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
beforeEach(() => {
|
|
107
|
+
mockFetchFn.mockReset();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Tool factory and invocation helpers
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Creates a fresh tool instance using the test API key.
|
|
116
|
+
*/
|
|
117
|
+
function makeTool(): DynamicStructuredTool {
|
|
118
|
+
return createCodeExecutionTool({ apiKey: 'test-key' });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Invokes the tool and returns only the string content part of the result.
|
|
123
|
+
* The tool returns `[formattedOutput, artifact]` when responseFormat is
|
|
124
|
+
* `content_and_artifact`; we surface only the string for assertion.
|
|
125
|
+
*
|
|
126
|
+
* @param execTool - Tool instance to invoke.
|
|
127
|
+
* @param input - Execution input (lang, code, optional args).
|
|
128
|
+
*/
|
|
129
|
+
async function invoke(
|
|
130
|
+
execTool: DynamicStructuredTool,
|
|
131
|
+
input: { lang: string; code: string; args?: string[] }
|
|
132
|
+
): Promise<string> {
|
|
133
|
+
const result = await execTool.invoke(input, { toolCall: {} } as never);
|
|
134
|
+
if (Array.isArray(result)) {
|
|
135
|
+
return result[0] as string;
|
|
136
|
+
}
|
|
137
|
+
return result as string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ===========================================================================
|
|
141
|
+
// Suite 1 — OUTPUT_TOO_LARGE tag
|
|
142
|
+
// ===========================================================================
|
|
143
|
+
|
|
144
|
+
describe('[OUTPUT_TOO_LARGE] stdout capping', () => {
|
|
145
|
+
it('appends [OUTPUT_TOO_LARGE] when stdout exceeds 16384 chars', async () => {
|
|
146
|
+
const largeStdout = repeat(STDOUT_MAX_CHARS + 1);
|
|
147
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
148
|
+
mockResponse({ session_id: 's1', stdout: largeStdout, stderr: '' })
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const output = await invoke(makeTool(), {
|
|
152
|
+
lang: 'py',
|
|
153
|
+
code: 'print("hi")',
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
expect(output).toContain('[OUTPUT_TOO_LARGE]');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('does NOT append [OUTPUT_TOO_LARGE] for stdout at exactly 16384 chars', async () => {
|
|
160
|
+
const normalStdout = repeat(STDOUT_MAX_CHARS);
|
|
161
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
162
|
+
mockResponse({ session_id: 's2', stdout: normalStdout, stderr: '' })
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const output = await invoke(makeTool(), {
|
|
166
|
+
lang: 'py',
|
|
167
|
+
code: 'print("hi")',
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
expect(output).not.toContain('[OUTPUT_TOO_LARGE]');
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('does NOT append [OUTPUT_TOO_LARGE] for short stdout', async () => {
|
|
174
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
175
|
+
mockResponse({ session_id: 's3', stdout: 'hello world', stderr: '' })
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const output = await invoke(makeTool(), {
|
|
179
|
+
lang: 'py',
|
|
180
|
+
code: 'print("hello world")',
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
expect(output).not.toContain('[OUTPUT_TOO_LARGE]');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('preserves head content from oversized stdout', async () => {
|
|
187
|
+
// First STDOUT_HEAD_CHARS chars are 'a', the remainder are 'b'
|
|
188
|
+
const head = repeat(STDOUT_HEAD_CHARS, 'a');
|
|
189
|
+
const rest = repeat(STDOUT_MAX_CHARS + 1 - STDOUT_HEAD_CHARS, 'b');
|
|
190
|
+
const largeStdout = head + rest;
|
|
191
|
+
|
|
192
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
193
|
+
mockResponse({ session_id: 's4', stdout: largeStdout, stderr: '' })
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const output = await invoke(makeTool(), { lang: 'py', code: 'print("x")' });
|
|
197
|
+
|
|
198
|
+
expect(output).toContain(repeat(STDOUT_HEAD_CHARS, 'a'));
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('preserves tail content from oversized stdout', async () => {
|
|
202
|
+
// Last STDOUT_TAIL_CHARS chars are 'z', the leading portion is 'y'
|
|
203
|
+
const leading = repeat(STDOUT_MAX_CHARS + 1 - STDOUT_TAIL_CHARS, 'y');
|
|
204
|
+
const tail = repeat(STDOUT_TAIL_CHARS, 'z');
|
|
205
|
+
const largeStdout = leading + tail;
|
|
206
|
+
|
|
207
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
208
|
+
mockResponse({ session_id: 's5', stdout: largeStdout, stderr: '' })
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const output = await invoke(makeTool(), { lang: 'py', code: 'print("x")' });
|
|
212
|
+
|
|
213
|
+
expect(output).toContain(repeat(STDOUT_TAIL_CHARS, 'z'));
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('inserts [...N chars omitted...] between head and tail when capping', async () => {
|
|
217
|
+
const totalLen = STDOUT_MAX_CHARS + 500;
|
|
218
|
+
const largeStdout = repeat(totalLen);
|
|
219
|
+
const expectedOmitted = totalLen - STDOUT_HEAD_CHARS - STDOUT_TAIL_CHARS;
|
|
220
|
+
|
|
221
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
222
|
+
mockResponse({ session_id: 's6', stdout: largeStdout, stderr: '' })
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const output = await invoke(makeTool(), { lang: 'py', code: 'print("x")' });
|
|
226
|
+
|
|
227
|
+
expect(output).toContain(`[...${expectedOmitted} chars omitted...]`);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// ===========================================================================
|
|
232
|
+
// Suite 2 — CODE_TRUNCATION_LIKELY tag
|
|
233
|
+
// ===========================================================================
|
|
234
|
+
|
|
235
|
+
describe('[CODE_TRUNCATION_LIKELY] truncation detection', () => {
|
|
236
|
+
it('appends [CODE_TRUNCATION_LIKELY] for long code + SyntaxError in stderr', async () => {
|
|
237
|
+
const code = longCode(CODE_TRUNCATION_MIN_CHARS + 1);
|
|
238
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
239
|
+
mockResponse({
|
|
240
|
+
session_id: 't1',
|
|
241
|
+
stdout: '',
|
|
242
|
+
stderr: 'SyntaxError: invalid syntax (line 42)',
|
|
243
|
+
})
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
const output = await invoke(makeTool(), { lang: 'py', code });
|
|
247
|
+
|
|
248
|
+
expect(output).toContain('[CODE_TRUNCATION_LIKELY]');
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('does NOT append [CODE_TRUNCATION_LIKELY] for short code + SyntaxError (likely a real bug)', async () => {
|
|
252
|
+
// Deliberately broken but well under 1500 chars — this is a genuine syntax error
|
|
253
|
+
const shortCode = 'print(x';
|
|
254
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
255
|
+
mockResponse({
|
|
256
|
+
session_id: 't2',
|
|
257
|
+
stdout: '',
|
|
258
|
+
stderr: 'SyntaxError: unexpected EOF while parsing',
|
|
259
|
+
})
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
const output = await invoke(makeTool(), { lang: 'py', code: shortCode });
|
|
263
|
+
|
|
264
|
+
expect(output).not.toContain('[CODE_TRUNCATION_LIKELY]');
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('does NOT append [CODE_TRUNCATION_LIKELY] for long code + non-syntax error (NameError)', async () => {
|
|
268
|
+
const code = longCode(CODE_TRUNCATION_MIN_CHARS + 1);
|
|
269
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
270
|
+
mockResponse({
|
|
271
|
+
session_id: 't3',
|
|
272
|
+
stdout: '',
|
|
273
|
+
stderr: "NameError: name 'undefined_var' is not defined",
|
|
274
|
+
})
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
const output = await invoke(makeTool(), { lang: 'py', code });
|
|
278
|
+
|
|
279
|
+
expect(output).not.toContain('[CODE_TRUNCATION_LIKELY]');
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('detects "unexpected end" in stderr for long code', async () => {
|
|
283
|
+
const code = longCode(CODE_TRUNCATION_MIN_CHARS + 1);
|
|
284
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
285
|
+
mockResponse({
|
|
286
|
+
session_id: 't4',
|
|
287
|
+
stdout: '',
|
|
288
|
+
stderr: 'unexpected end of input at line 200',
|
|
289
|
+
})
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
const output = await invoke(makeTool(), { lang: 'js', code });
|
|
293
|
+
|
|
294
|
+
expect(output).toContain('[CODE_TRUNCATION_LIKELY]');
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('detects "unexpected eof" in stderr for long code', async () => {
|
|
298
|
+
const code = longCode(CODE_TRUNCATION_MIN_CHARS + 1);
|
|
299
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
300
|
+
mockResponse({
|
|
301
|
+
session_id: 't5',
|
|
302
|
+
stdout: '',
|
|
303
|
+
stderr: 'Unexpected EOF — did you forget a closing bracket?',
|
|
304
|
+
})
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
const output = await invoke(makeTool(), { lang: 'js', code });
|
|
308
|
+
|
|
309
|
+
expect(output).toContain('[CODE_TRUNCATION_LIKELY]');
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('detects "unterminated" in stderr for long code', async () => {
|
|
313
|
+
const code = longCode(CODE_TRUNCATION_MIN_CHARS + 1);
|
|
314
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
315
|
+
mockResponse({
|
|
316
|
+
session_id: 't6',
|
|
317
|
+
stdout: '',
|
|
318
|
+
stderr: 'unterminated string literal at line 50',
|
|
319
|
+
})
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
const output = await invoke(makeTool(), { lang: 'py', code });
|
|
323
|
+
|
|
324
|
+
expect(output).toContain('[CODE_TRUNCATION_LIKELY]');
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('is case-insensitive when matching stderr keywords', async () => {
|
|
328
|
+
const code = longCode(CODE_TRUNCATION_MIN_CHARS + 1);
|
|
329
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
330
|
+
mockResponse({
|
|
331
|
+
session_id: 't7',
|
|
332
|
+
stdout: '',
|
|
333
|
+
// All-caps — the implementation uses .toLowerCase() before matching
|
|
334
|
+
stderr: 'SYNTAXERROR: INVALID SYNTAX ON LINE 99',
|
|
335
|
+
})
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
const output = await invoke(makeTool(), { lang: 'py', code });
|
|
339
|
+
|
|
340
|
+
expect(output).toContain('[CODE_TRUNCATION_LIKELY]');
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
// ===========================================================================
|
|
345
|
+
// Suite 3 — Normal execution (no self-healing tags)
|
|
346
|
+
// ===========================================================================
|
|
347
|
+
|
|
348
|
+
describe('normal execution — no self-healing tags', () => {
|
|
349
|
+
it('produces no self-healing tags on successful execution with short stdout', async () => {
|
|
350
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
351
|
+
mockResponse({
|
|
352
|
+
session_id: 'n1',
|
|
353
|
+
stdout: 'Hello, world!\n',
|
|
354
|
+
stderr: '',
|
|
355
|
+
})
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
const output = await invoke(makeTool(), {
|
|
359
|
+
lang: 'py',
|
|
360
|
+
code: 'print("Hello, world!")',
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
expect(output).not.toContain('[OUTPUT_TOO_LARGE]');
|
|
364
|
+
expect(output).not.toContain('[CODE_TRUNCATION_LIKELY]');
|
|
365
|
+
expect(output).toContain('Hello, world!');
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
it('produces no self-healing tags when stderr contains a runtime error on short code', async () => {
|
|
369
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
370
|
+
mockResponse({
|
|
371
|
+
session_id: 'n2',
|
|
372
|
+
stdout: '',
|
|
373
|
+
stderr: 'ZeroDivisionError: division by zero',
|
|
374
|
+
})
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
const output = await invoke(makeTool(), { lang: 'py', code: 'print(1/0)' });
|
|
378
|
+
|
|
379
|
+
expect(output).not.toContain('[OUTPUT_TOO_LARGE]');
|
|
380
|
+
expect(output).not.toContain('[CODE_TRUNCATION_LIKELY]');
|
|
381
|
+
expect(output).toContain('ZeroDivisionError');
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// ===========================================================================
|
|
386
|
+
// Suite 4 — Both tags appear simultaneously
|
|
387
|
+
// ===========================================================================
|
|
388
|
+
|
|
389
|
+
describe('both self-healing tags can appear together', () => {
|
|
390
|
+
it('appends both [OUTPUT_TOO_LARGE] and [CODE_TRUNCATION_LIKELY] when both conditions are met', async () => {
|
|
391
|
+
const code = longCode(CODE_TRUNCATION_MIN_CHARS + 1);
|
|
392
|
+
const largeStdout = repeat(STDOUT_MAX_CHARS + 1);
|
|
393
|
+
|
|
394
|
+
mockFetchFn.mockResolvedValueOnce(
|
|
395
|
+
mockResponse({
|
|
396
|
+
session_id: 'b1',
|
|
397
|
+
stdout: largeStdout,
|
|
398
|
+
stderr: 'SyntaxError: invalid syntax',
|
|
399
|
+
})
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
const output = await invoke(makeTool(), { lang: 'py', code });
|
|
403
|
+
|
|
404
|
+
expect(output).toContain('[OUTPUT_TOO_LARGE]');
|
|
405
|
+
expect(output).toContain('[CODE_TRUNCATION_LIKELY]');
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
// ===========================================================================
|
|
410
|
+
// Suite 5 — Tool construction guard
|
|
411
|
+
// ===========================================================================
|
|
412
|
+
|
|
413
|
+
describe('createCodeExecutionTool() construction', () => {
|
|
414
|
+
it('throws when no API key is available', () => {
|
|
415
|
+
const savedKey = process.env.CODE_EXECUTOR_API_KEY;
|
|
416
|
+
delete process.env.CODE_EXECUTOR_API_KEY;
|
|
417
|
+
|
|
418
|
+
expect(() => createCodeExecutionTool({})).toThrow(
|
|
419
|
+
'No API key provided for code execution tool.'
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
process.env.CODE_EXECUTOR_API_KEY = savedKey;
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
it('accepts apiKey directly from params without requiring env var', () => {
|
|
426
|
+
const savedKey = process.env.CODE_EXECUTOR_API_KEY;
|
|
427
|
+
delete process.env.CODE_EXECUTOR_API_KEY;
|
|
428
|
+
|
|
429
|
+
expect(() =>
|
|
430
|
+
createCodeExecutionTool({ apiKey: 'direct-key' })
|
|
431
|
+
).not.toThrow();
|
|
432
|
+
|
|
433
|
+
process.env.CODE_EXECUTOR_API_KEY = savedKey;
|
|
434
|
+
});
|
|
435
|
+
});
|