@librechat/agents 3.2.2 → 3.2.31
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 +3 -2
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/events.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +200 -54
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +13 -7
- package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
- package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
- package/dist/cjs/hooks/types.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +33 -0
- package/dist/cjs/instrumentation.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +17 -1
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +2 -2
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/index.cjs +1 -1
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +2 -2
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/toolCache.cjs +8 -5
- package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
- package/dist/cjs/llm/fake.cjs +16 -14
- package/dist/cjs/llm/fake.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs +22 -0
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +88 -27
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +2 -2
- package/dist/cjs/llm/invoke.cjs +108 -11
- package/dist/cjs/llm/invoke.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 +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +1 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +8 -7
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/content.cjs.map +1 -1
- package/dist/cjs/messages/contextPruning.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +124 -17
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/reducer.cjs +1 -1
- package/dist/cjs/messages/reducer.cjs.map +1 -1
- package/dist/cjs/messages/tools.cjs +1 -1
- package/dist/cjs/messages/tools.cjs.map +1 -1
- package/dist/cjs/openai/index.cjs.map +1 -1
- package/dist/cjs/responses/index.cjs.map +1 -1
- package/dist/cjs/run.cjs +47 -21
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/AgentSession.cjs +4 -4
- package/dist/cjs/session/AgentSession.cjs.map +1 -1
- package/dist/cjs/session/JsonlSessionStore.cjs +2 -2
- package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
- package/dist/cjs/session/handlers.cjs +2 -2
- package/dist/cjs/session/handlers.cjs.map +1 -1
- package/dist/cjs/stream.cjs +248 -25
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/Calculator.cjs +1 -1
- package/dist/cjs/tools/Calculator.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +37 -18
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/ToolSearch.cjs +1 -1
- package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +7 -4
- package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +4 -4
- package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +2 -1
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
- package/dist/cjs/tools/local/FileCheckpointer.cjs +2 -1
- package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalCodingTools.cjs +45 -19
- package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs +3 -3
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalExecutionTools.cjs +2 -2
- package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +4 -3
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/attachments.cjs +0 -5
- package/dist/cjs/tools/local/attachments.cjs.map +1 -1
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +4 -4
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs +7 -3
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/tavily-search.cjs +1 -1
- package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +76 -8
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/utils/handlers.cjs +1 -1
- package/dist/cjs/utils/handlers.cjs.map +1 -1
- package/dist/cjs/utils/run.cjs +1 -1
- package/dist/cjs/utils/run.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +3 -2
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/events.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +200 -54
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/hooks/createWorkspacePolicyHook.mjs +13 -7
- package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
- package/dist/esm/hooks/executeHooks.mjs.map +1 -1
- package/dist/esm/hooks/types.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +33 -1
- package/dist/esm/instrumentation.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +17 -2
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +2 -2
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
- package/dist/esm/llm/anthropic/index.mjs +1 -1
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +2 -2
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/toolCache.mjs +8 -5
- package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
- package/dist/esm/llm/fake.mjs +16 -14
- package/dist/esm/llm/fake.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +23 -1
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +88 -27
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +2 -2
- package/dist/esm/llm/invoke.mjs +104 -7
- package/dist/esm/llm/invoke.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 +1 -1
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +1 -1
- package/dist/esm/messages/cache.mjs +8 -7
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/content.mjs.map +1 -1
- package/dist/esm/messages/contextPruning.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +124 -18
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/reducer.mjs +1 -1
- package/dist/esm/messages/reducer.mjs.map +1 -1
- package/dist/esm/messages/tools.mjs +1 -1
- package/dist/esm/messages/tools.mjs.map +1 -1
- package/dist/esm/openai/index.mjs.map +1 -1
- package/dist/esm/responses/index.mjs.map +1 -1
- package/dist/esm/run.mjs +47 -21
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/AgentSession.mjs +4 -4
- package/dist/esm/session/AgentSession.mjs.map +1 -1
- package/dist/esm/session/JsonlSessionStore.mjs +2 -2
- package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
- package/dist/esm/session/handlers.mjs +2 -2
- package/dist/esm/session/handlers.mjs.map +1 -1
- package/dist/esm/stream.mjs +248 -25
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/Calculator.mjs +1 -1
- package/dist/esm/tools/Calculator.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +1 -1
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/SubagentTool.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +37 -18
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/ToolSearch.mjs +1 -1
- package/dist/esm/tools/ToolSearch.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +7 -4
- package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +4 -4
- package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +2 -1
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
- package/dist/esm/tools/local/FileCheckpointer.mjs +2 -1
- package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
- package/dist/esm/tools/local/LocalCodingTools.mjs +45 -19
- package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
- package/dist/esm/tools/local/LocalExecutionEngine.mjs +3 -3
- package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
- package/dist/esm/tools/local/LocalExecutionTools.mjs +2 -2
- package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +4 -3
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/attachments.mjs +0 -5
- package/dist/esm/tools/local/attachments.mjs.map +1 -1
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +4 -4
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs +1 -1
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs +8 -4
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/tavily-search.mjs +1 -1
- package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +76 -9
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/utils/handlers.mjs +1 -1
- package/dist/esm/utils/handlers.mjs.map +1 -1
- package/dist/esm/utils/run.mjs +1 -1
- package/dist/esm/utils/run.mjs.map +1 -1
- package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +1 -1
- package/dist/types/events.d.ts +1 -1
- package/dist/types/graphs/Graph.d.ts +7 -1
- package/dist/types/hooks/executeHooks.d.ts +1 -1
- package/dist/types/hooks/types.d.ts +5 -0
- package/dist/types/instrumentation.d.ts +1 -0
- package/dist/types/langfuse.d.ts +4 -0
- package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
- package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -1
- package/dist/types/llm/anthropic/utils/output_parsers.d.ts +2 -2
- package/dist/types/llm/bedrock/index.d.ts +2 -2
- package/dist/types/llm/fake.d.ts +3 -3
- package/dist/types/llm/google/index.d.ts +1 -0
- package/dist/types/llm/google/types.d.ts +1 -1
- package/dist/types/llm/google/utils/common.d.ts +2 -2
- package/dist/types/llm/google/utils/tools.d.ts +1 -1
- package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +1 -1
- package/dist/types/llm/openai/index.d.ts +2 -2
- package/dist/types/llm/openai/utils/index.d.ts +1 -1
- package/dist/types/llm/openrouter/index.d.ts +4 -4
- package/dist/types/messages/contextPruning.d.ts +1 -1
- package/dist/types/messages/format.d.ts +9 -4
- package/dist/types/messages/prune.d.ts +1 -1
- package/dist/types/session/JsonlSessionStore.d.ts +1 -1
- package/dist/types/session/handlers.d.ts +1 -1
- package/dist/types/session/types.d.ts +1 -1
- package/dist/types/summarization/node.d.ts +1 -1
- package/dist/types/tools/SubagentTool.d.ts +2 -2
- package/dist/types/tools/ToolNode.d.ts +9 -2
- package/dist/types/tools/cloudflare/CloudflareSandboxExecutionEngine.d.ts +1 -1
- package/dist/types/tools/search/types.d.ts +1 -1
- package/dist/types/tools/search/utils.d.ts +11 -0
- package/dist/types/types/graph.d.ts +12 -4
- package/dist/types/types/llm.d.ts +4 -3
- package/dist/types/types/messages.d.ts +1 -1
- package/dist/types/types/run.d.ts +6 -6
- package/dist/types/types/stream.d.ts +2 -2
- package/dist/types/types/tools.d.ts +5 -1
- package/dist/types/utils/handlers.d.ts +2 -2
- package/dist/types/utils/run.d.ts +1 -1
- package/package.json +6 -3
- package/src/__tests__/stream.eagerEventExecution.test.ts +543 -6
- package/src/agents/AgentContext.ts +2 -2
- package/src/agents/__tests__/AgentContext.test.ts +3 -3
- package/src/agents/__tests__/promptCacheLiveHelpers.ts +1 -1
- package/src/events.ts +1 -1
- package/src/graphs/Graph.ts +329 -72
- package/src/graphs/MultiAgentGraph.ts +1 -1
- package/src/graphs/__tests__/Graph.reasoning.test.ts +919 -6
- package/src/graphs/__tests__/MultiAgentGraph.test.ts +1 -1
- package/src/graphs/__tests__/composition.smoke.test.ts +1 -1
- package/src/hooks/__tests__/HookRegistry.test.ts +1 -1
- package/src/hooks/__tests__/compactHooks.test.ts +8 -8
- package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +34 -22
- package/src/hooks/__tests__/executeHooks.test.ts +3 -3
- package/src/hooks/__tests__/integration.test.ts +3 -3
- package/src/hooks/__tests__/toolHooks.test.ts +10 -10
- package/src/hooks/createWorkspacePolicyHook.ts +17 -14
- package/src/hooks/executeHooks.ts +1 -1
- package/src/hooks/types.ts +5 -0
- package/src/instrumentation.ts +49 -8
- package/src/langfuse.ts +35 -1
- package/src/langfuseToolOutputTracing.ts +2 -2
- package/src/llm/anthropic/index.ts +1 -1
- package/src/llm/anthropic/utils/message_inputs.ts +1 -1
- package/src/llm/anthropic/utils/message_outputs.ts +3 -5
- package/src/llm/anthropic/utils/output_parsers.ts +5 -5
- package/src/llm/bedrock/index.ts +4 -4
- package/src/llm/bedrock/toolCache.test.ts +48 -9
- package/src/llm/bedrock/toolCache.ts +11 -6
- package/src/llm/custom-chat-models.smoke.test.ts +114 -0
- package/src/llm/fake.ts +30 -25
- package/src/llm/google/index.ts +43 -1
- package/src/llm/google/llm.spec.ts +173 -1
- package/src/llm/google/types.ts +1 -1
- package/src/llm/google/utils/common.ts +154 -45
- package/src/llm/google/utils/tools.ts +8 -8
- package/src/llm/google/utils/zod_to_genai_parameters.ts +4 -4
- package/src/llm/invoke.test.ts +3 -3
- package/src/llm/invoke.ts +170 -10
- package/src/llm/openai/index.ts +4 -4
- package/src/llm/openai/utils/index.ts +14 -14
- package/src/llm/openrouter/index.ts +4 -4
- package/src/llm/openrouter/reasoning.test.ts +2 -2
- package/src/llm/vertexai/fixThoughtSignatures.test.ts +1 -1
- package/src/llm/vertexai/index.ts +1 -1
- package/src/messages/cache.test.ts +22 -0
- package/src/messages/cache.ts +25 -12
- package/src/messages/content.ts +1 -1
- package/src/messages/contextPruning.ts +1 -1
- package/src/messages/format.ts +227 -43
- package/src/messages/formatAgentMessages.skills.test.ts +105 -26
- package/src/messages/formatAgentMessages.test.ts +841 -10
- package/src/messages/labelContentByAgent.test.ts +2 -2
- package/src/messages/prune.ts +1 -1
- package/src/messages/reducer.ts +1 -1
- package/src/messages/tools.ts +1 -1
- package/src/openai/__tests__/openai.test.ts +2 -2
- package/src/openai/index.ts +1 -1
- package/src/responses/__tests__/responses.test.ts +2 -2
- package/src/responses/index.ts +1 -1
- package/src/run.ts +82 -47
- package/src/session/AgentSession.ts +6 -6
- package/src/session/JsonlSessionStore.ts +3 -3
- package/src/session/__tests__/JsonlSessionStore.test.ts +5 -5
- package/src/session/__tests__/handlers.test.ts +2 -2
- package/src/session/handlers.ts +5 -5
- package/src/session/types.ts +1 -1
- package/src/specs/agent-handoffs.test.ts +1 -1
- package/src/specs/deterministic-trace-id.test.ts +50 -0
- package/src/specs/langfuse-callbacks.test.ts +2 -2
- package/src/specs/langfuse-metadata.test.ts +39 -0
- package/src/specs/langfuse-tool-output-tracing.test.ts +1 -1
- package/src/specs/multi-agent-summarization.test.ts +4 -4
- package/src/specs/subagent.test.ts +3 -3
- package/src/specs/summarization-unit.test.ts +1 -1
- package/src/specs/thinking-handoff.test.ts +1 -1
- package/src/splitStream.test.ts +48 -0
- package/src/stream.test.ts +53 -3
- package/src/stream.ts +450 -39
- package/src/summarization/__tests__/aggregator.test.ts +2 -2
- package/src/summarization/__tests__/node.test.ts +2 -2
- package/src/summarization/node.ts +1 -1
- package/src/tools/BashProgrammaticToolCalling.ts +5 -5
- package/src/tools/Calculator.ts +1 -1
- package/src/tools/CodeExecutor.ts +2 -4
- package/src/tools/SubagentTool.ts +2 -2
- package/src/tools/ToolNode.ts +37 -16
- package/src/tools/ToolSearch.ts +1 -1
- package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +4 -4
- package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +12 -12
- package/src/tools/__tests__/LocalExecutionTools.test.ts +125 -93
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +29 -5
- package/src/tools/__tests__/ReadFile.test.ts +1 -1
- package/src/tools/__tests__/SkillTool.test.ts +4 -4
- package/src/tools/__tests__/SubagentExecutor.test.ts +17 -13
- package/src/tools/__tests__/SubagentTool.test.ts +2 -2
- package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +1 -1
- package/src/tools/__tests__/ToolNode.outputReferences.test.ts +2 -5
- package/src/tools/__tests__/ToolNode.session.test.ts +1 -1
- package/src/tools/__tests__/ToolSearch.test.ts +1 -1
- package/src/tools/__tests__/annotateMessagesForLLM.test.ts +1 -1
- package/src/tools/__tests__/directToolHITLResumeScope.test.ts +35 -32
- package/src/tools/__tests__/directToolHooks.test.ts +41 -0
- package/src/tools/__tests__/handlers.test.ts +2 -2
- package/src/tools/__tests__/hitl.test.ts +11 -11
- package/src/tools/__tests__/localToolNames.test.ts +8 -6
- package/src/tools/__tests__/skillCatalog.test.ts +1 -1
- package/src/tools/__tests__/subagentHooks.test.ts +20 -10
- package/src/tools/__tests__/workspaceSeam.test.ts +20 -7
- package/src/tools/cloudflare/CloudflareSandboxExecutionEngine.ts +9 -6
- package/src/tools/cloudflare/CloudflareSandboxTools.ts +19 -19
- package/src/tools/handlers.ts +5 -5
- package/src/tools/local/CompileCheckTool.ts +4 -7
- package/src/tools/local/FileCheckpointer.ts +6 -5
- package/src/tools/local/LocalCodingTools.ts +100 -45
- package/src/tools/local/LocalExecutionEngine.ts +5 -5
- package/src/tools/local/LocalExecutionTools.ts +9 -9
- package/src/tools/local/LocalProgrammaticToolCalling.ts +5 -4
- package/src/tools/local/attachments.ts +0 -6
- package/src/tools/local/resolveLocalExecutionTools.ts +15 -15
- package/src/tools/search/firecrawl.ts +1 -1
- package/src/tools/search/jina-reranker.test.ts +148 -37
- package/src/tools/search/rerankers.ts +14 -4
- package/src/tools/search/tavily-search.ts +2 -2
- package/src/tools/search/types.ts +1 -1
- package/src/tools/search/utils.ts +99 -9
- package/src/tools/subagent/SubagentExecutor.ts +12 -6
- package/src/types/graph.ts +20 -12
- package/src/types/llm.ts +7 -6
- package/src/types/messages.ts +1 -1
- package/src/types/run.ts +7 -7
- package/src/types/stream.ts +2 -2
- package/src/types/tools.ts +5 -1
- package/src/utils/handlers.ts +2 -2
- package/src/utils/llmConfig.ts +1 -1
- package/src/utils/logging.ts +20 -10
- package/src/utils/run.ts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudflareSandboxTools.mjs","sources":["../../../../src/tools/cloudflare/CloudflareSandboxTools.ts"],"sourcesContent":["import { tool } from '@langchain/core/tools';\nimport type { DynamicStructuredTool } from '@langchain/core/tools';\nimport type * as t from '@/types';\nimport {\n CodeExecutionToolName,\n CodeExecutionToolSchema,\n} from '@/tools/CodeExecutor';\nimport {\n BashExecutionToolName,\n BashExecutionToolSchema,\n BashToolOutputReferencesGuide,\n} from '@/tools/BashExecutor';\nimport {\n createLocalReadFileTool,\n createLocalWriteFileTool,\n createLocalEditFileTool,\n createLocalGrepSearchTool,\n createLocalGlobSearchTool,\n createLocalListDirectoryTool,\n} from '@/tools/local/LocalCodingTools';\nimport { createLocalFileCheckpointer } from '@/tools/local/FileCheckpointer';\nimport { createCompileCheckTool } from '@/tools/local/CompileCheckTool';\nimport { Constants } from '@/common';\nimport {\n createCloudflareLocalExecutionConfig,\n createCloudflareWorkspaceFS,\n executeCloudflareBash,\n executeCloudflareCode,\n formatCloudflareOutput,\n getCloudflareWorkspaceRoot,\n} from './CloudflareSandboxExecutionEngine';\nimport {\n createCloudflareBashProgrammaticToolCallingTool,\n createCloudflareProgrammaticToolCallingTool,\n} from './CloudflareProgrammaticToolCalling';\n\nexport const CLOUDFLARE_CODING_TOOL_NAMES: readonly string[] = [\n Constants.READ_FILE,\n Constants.WRITE_FILE,\n Constants.EDIT_FILE,\n Constants.GREP_SEARCH,\n Constants.GLOB_SEARCH,\n Constants.LIST_DIRECTORY,\n Constants.COMPILE_CHECK,\n Constants.BASH_TOOL,\n Constants.EXECUTE_CODE,\n Constants.PROGRAMMATIC_TOOL_CALLING,\n Constants.BASH_PROGRAMMATIC_TOOL_CALLING,\n];\n\nexport const CLOUDFLARE_BASH_CODING_TOOL_NAMES: readonly string[] = [\n Constants.READ_FILE,\n Constants.WRITE_FILE,\n Constants.EDIT_FILE,\n Constants.GREP_SEARCH,\n Constants.GLOB_SEARCH,\n Constants.LIST_DIRECTORY,\n Constants.COMPILE_CHECK,\n Constants.BASH_TOOL,\n Constants.BASH_PROGRAMMATIC_TOOL_CALLING,\n];\n\nexport const CloudflareCodeExecutionToolDescription = `\nRuns code inside the configured Cloudflare Sandbox workspace. The sandbox can see files and installed runtimes available inside the Cloudflare Sandbox container.\n\nUsage:\n- Commands execute in the Cloudflare Sandbox workspace and may modify sandbox files.\n- Input code is already displayed to the user, so do not repeat it unless asked.\n- Output is not displayed unless you print it explicitly.\n`.trim();\n\nexport const CloudflareBashExecutionToolDescription = `\nRuns bash commands inside the configured Cloudflare Sandbox workspace.\n\nUsage:\n- Commands execute in the Cloudflare Sandbox workspace and may modify sandbox files.\n- Output is not displayed unless you print it explicitly.\n- Prefer project-native commands and inspect files before changing them.\n`.trim();\n\nexport function createCloudflareCodeExecutionTool(\n config: t.CloudflareSandboxExecutionConfig\n): DynamicStructuredTool {\n return tool(\n async (rawInput) => {\n const input = rawInput as {\n lang: string;\n code: string;\n args?: string[];\n };\n const cwd = getCloudflareWorkspaceRoot(config);\n const result = await executeCloudflareCode(input, config);\n return [\n formatCloudflareOutput(result, cwd),\n {\n session_id: 'cloudflare-sandbox',\n files: [],\n } satisfies t.CodeExecutionArtifact,\n ];\n },\n {\n name: CodeExecutionToolName,\n description: CloudflareCodeExecutionToolDescription,\n schema: CodeExecutionToolSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport function createCloudflareBashExecutionTool(options: {\n config: t.CloudflareSandboxExecutionConfig;\n enableToolOutputReferences?: boolean;\n}): DynamicStructuredTool {\n const { config } = options;\n return tool(\n async (rawInput) => {\n const input = rawInput as { command: string; args?: string[] };\n const cwd = getCloudflareWorkspaceRoot(config);\n const result = await executeCloudflareBash(\n input.command,\n config,\n input.args ?? []\n );\n return [\n formatCloudflareOutput(result, cwd),\n {\n session_id: 'cloudflare-sandbox',\n files: [],\n } satisfies t.CodeExecutionArtifact,\n ];\n },\n {\n name: BashExecutionToolName,\n description:\n options.enableToolOutputReferences === true\n ? `${CloudflareBashExecutionToolDescription}\\n\\n${BashToolOutputReferencesGuide}`\n : CloudflareBashExecutionToolDescription,\n schema: BashExecutionToolSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport type CloudflareCodingToolBundle = {\n tools: DynamicStructuredTool[];\n checkpointer?: t.LocalFileCheckpointer;\n};\n\nfunction getSelectedCodingToolNames(\n config: t.CloudflareSandboxExecutionConfig\n): Set<string> {\n return new Set(config.codingToolNames ?? CLOUDFLARE_CODING_TOOL_NAMES);\n}\n\nexport function createCloudflareCodingTools(\n config: t.CloudflareSandboxExecutionConfig,\n options: { checkpointer?: t.LocalFileCheckpointer } = {}\n): DynamicStructuredTool[] {\n const localConfig = createCloudflareLocalExecutionConfig(config);\n const checkpointer =\n options.checkpointer ??\n (config.fileCheckpointing === true\n ? createLocalFileCheckpointer({\n fs: createCloudflareWorkspaceFS(config),\n })\n : undefined);\n const tools = [\n [Constants.READ_FILE, createLocalReadFileTool(localConfig)],\n [Constants.WRITE_FILE, createLocalWriteFileTool(localConfig, checkpointer)],\n [Constants.EDIT_FILE, createLocalEditFileTool(localConfig, checkpointer)],\n [Constants.GREP_SEARCH, createLocalGrepSearchTool(localConfig)],\n [Constants.GLOB_SEARCH, createLocalGlobSearchTool(localConfig)],\n [Constants.LIST_DIRECTORY, createLocalListDirectoryTool(localConfig)],\n [Constants.COMPILE_CHECK, createCompileCheckTool(localConfig)],\n [Constants.BASH_TOOL, createCloudflareBashExecutionTool({ config })],\n [Constants.EXECUTE_CODE, createCloudflareCodeExecutionTool(config)],\n [\n Constants.PROGRAMMATIC_TOOL_CALLING,\n createCloudflareProgrammaticToolCallingTool(config),\n ],\n [\n Constants.BASH_PROGRAMMATIC_TOOL_CALLING,\n createCloudflareBashProgrammaticToolCallingTool(config),\n ],\n ] satisfies Array<[string, DynamicStructuredTool]>;\n const selectedNames = getSelectedCodingToolNames(config);\n return tools\n .filter(([name]) => selectedNames.has(name))\n .map(([, selectedTool]) => selectedTool);\n}\n\nexport function createCloudflareCodingToolBundle(\n config: t.CloudflareSandboxExecutionConfig,\n options: { checkpointer?: t.LocalFileCheckpointer } = {}\n): CloudflareCodingToolBundle {\n const checkpointer =\n options.checkpointer ??\n (config.fileCheckpointing === true\n ? createLocalFileCheckpointer({\n fs: createCloudflareWorkspaceFS(config),\n })\n : undefined);\n return {\n tools: createCloudflareCodingTools(config, { checkpointer }),\n checkpointer,\n };\n}\n\nexport function createCloudflareExecutionTool(\n name: string,\n config: t.CloudflareSandboxExecutionConfig\n): t.GenericTool | undefined {\n switch (name) {\n case Constants.EXECUTE_CODE:\n return createCloudflareCodeExecutionTool(config);\n case Constants.BASH_TOOL:\n return createCloudflareBashExecutionTool({ config });\n case Constants.PROGRAMMATIC_TOOL_CALLING:\n return createCloudflareProgrammaticToolCallingTool(config);\n case Constants.BASH_PROGRAMMATIC_TOOL_CALLING:\n return createCloudflareBashProgrammaticToolCallingTool(config);\n default:\n return undefined;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CloudflareSandboxTools.mjs","sources":["../../../../src/tools/cloudflare/CloudflareSandboxTools.ts"],"sourcesContent":["import { tool } from '@langchain/core/tools';\nimport type { DynamicStructuredTool } from '@langchain/core/tools';\nimport type * as t from '@/types';\nimport {\n createCloudflareLocalExecutionConfig,\n createCloudflareWorkspaceFS,\n executeCloudflareBash,\n executeCloudflareCode,\n formatCloudflareOutput,\n getCloudflareWorkspaceRoot,\n} from './CloudflareSandboxExecutionEngine';\nimport {\n createLocalReadFileTool,\n createLocalWriteFileTool,\n createLocalEditFileTool,\n createLocalGrepSearchTool,\n createLocalGlobSearchTool,\n createLocalListDirectoryTool,\n} from '@/tools/local/LocalCodingTools';\nimport {\n createCloudflareBashProgrammaticToolCallingTool,\n createCloudflareProgrammaticToolCallingTool,\n} from './CloudflareProgrammaticToolCalling';\nimport {\n BashExecutionToolName,\n BashExecutionToolSchema,\n BashToolOutputReferencesGuide,\n} from '@/tools/BashExecutor';\nimport {\n CodeExecutionToolName,\n CodeExecutionToolSchema,\n} from '@/tools/CodeExecutor';\nimport { createLocalFileCheckpointer } from '@/tools/local/FileCheckpointer';\nimport { createCompileCheckTool } from '@/tools/local/CompileCheckTool';\nimport { Constants } from '@/common';\n\nexport const CLOUDFLARE_CODING_TOOL_NAMES: readonly string[] = [\n Constants.READ_FILE,\n Constants.WRITE_FILE,\n Constants.EDIT_FILE,\n Constants.GREP_SEARCH,\n Constants.GLOB_SEARCH,\n Constants.LIST_DIRECTORY,\n Constants.COMPILE_CHECK,\n Constants.BASH_TOOL,\n Constants.EXECUTE_CODE,\n Constants.PROGRAMMATIC_TOOL_CALLING,\n Constants.BASH_PROGRAMMATIC_TOOL_CALLING,\n];\n\nexport const CLOUDFLARE_BASH_CODING_TOOL_NAMES: readonly string[] = [\n Constants.READ_FILE,\n Constants.WRITE_FILE,\n Constants.EDIT_FILE,\n Constants.GREP_SEARCH,\n Constants.GLOB_SEARCH,\n Constants.LIST_DIRECTORY,\n Constants.COMPILE_CHECK,\n Constants.BASH_TOOL,\n Constants.BASH_PROGRAMMATIC_TOOL_CALLING,\n];\n\nexport const CloudflareCodeExecutionToolDescription = `\nRuns code inside the configured Cloudflare Sandbox workspace. The sandbox can see files and installed runtimes available inside the Cloudflare Sandbox container.\n\nUsage:\n- Commands execute in the Cloudflare Sandbox workspace and may modify sandbox files.\n- Input code is already displayed to the user, so do not repeat it unless asked.\n- Output is not displayed unless you print it explicitly.\n`.trim();\n\nexport const CloudflareBashExecutionToolDescription = `\nRuns bash commands inside the configured Cloudflare Sandbox workspace.\n\nUsage:\n- Commands execute in the Cloudflare Sandbox workspace and may modify sandbox files.\n- Output is not displayed unless you print it explicitly.\n- Prefer project-native commands and inspect files before changing them.\n`.trim();\n\nexport function createCloudflareCodeExecutionTool(\n config: t.CloudflareSandboxExecutionConfig\n): DynamicStructuredTool {\n return tool(\n async (rawInput) => {\n const input = rawInput as {\n lang: string;\n code: string;\n args?: string[];\n };\n const cwd = getCloudflareWorkspaceRoot(config);\n const result = await executeCloudflareCode(input, config);\n return [\n formatCloudflareOutput(result, cwd),\n {\n session_id: 'cloudflare-sandbox',\n files: [],\n } satisfies t.CodeExecutionArtifact,\n ];\n },\n {\n name: CodeExecutionToolName,\n description: CloudflareCodeExecutionToolDescription,\n schema: CodeExecutionToolSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport function createCloudflareBashExecutionTool(options: {\n config: t.CloudflareSandboxExecutionConfig;\n enableToolOutputReferences?: boolean;\n}): DynamicStructuredTool {\n const { config } = options;\n return tool(\n async (rawInput) => {\n const input = rawInput as { command: string; args?: string[] };\n const cwd = getCloudflareWorkspaceRoot(config);\n const result = await executeCloudflareBash(\n input.command,\n config,\n input.args ?? []\n );\n return [\n formatCloudflareOutput(result, cwd),\n {\n session_id: 'cloudflare-sandbox',\n files: [],\n } satisfies t.CodeExecutionArtifact,\n ];\n },\n {\n name: BashExecutionToolName,\n description:\n options.enableToolOutputReferences === true\n ? `${CloudflareBashExecutionToolDescription}\\n\\n${BashToolOutputReferencesGuide}`\n : CloudflareBashExecutionToolDescription,\n schema: BashExecutionToolSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport type CloudflareCodingToolBundle = {\n tools: DynamicStructuredTool[];\n checkpointer?: t.LocalFileCheckpointer;\n};\n\nfunction getSelectedCodingToolNames(\n config: t.CloudflareSandboxExecutionConfig\n): Set<string> {\n return new Set(config.codingToolNames ?? CLOUDFLARE_CODING_TOOL_NAMES);\n}\n\nexport function createCloudflareCodingTools(\n config: t.CloudflareSandboxExecutionConfig,\n options: { checkpointer?: t.LocalFileCheckpointer } = {}\n): DynamicStructuredTool[] {\n const localConfig = createCloudflareLocalExecutionConfig(config);\n const checkpointer =\n options.checkpointer ??\n (config.fileCheckpointing === true\n ? createLocalFileCheckpointer({\n fs: createCloudflareWorkspaceFS(config),\n })\n : undefined);\n const tools = [\n [Constants.READ_FILE, createLocalReadFileTool(localConfig)],\n [Constants.WRITE_FILE, createLocalWriteFileTool(localConfig, checkpointer)],\n [Constants.EDIT_FILE, createLocalEditFileTool(localConfig, checkpointer)],\n [Constants.GREP_SEARCH, createLocalGrepSearchTool(localConfig)],\n [Constants.GLOB_SEARCH, createLocalGlobSearchTool(localConfig)],\n [Constants.LIST_DIRECTORY, createLocalListDirectoryTool(localConfig)],\n [Constants.COMPILE_CHECK, createCompileCheckTool(localConfig)],\n [Constants.BASH_TOOL, createCloudflareBashExecutionTool({ config })],\n [Constants.EXECUTE_CODE, createCloudflareCodeExecutionTool(config)],\n [\n Constants.PROGRAMMATIC_TOOL_CALLING,\n createCloudflareProgrammaticToolCallingTool(config),\n ],\n [\n Constants.BASH_PROGRAMMATIC_TOOL_CALLING,\n createCloudflareBashProgrammaticToolCallingTool(config),\n ],\n ] satisfies Array<[string, DynamicStructuredTool]>;\n const selectedNames = getSelectedCodingToolNames(config);\n return tools\n .filter(([name]) => selectedNames.has(name))\n .map(([, selectedTool]) => selectedTool);\n}\n\nexport function createCloudflareCodingToolBundle(\n config: t.CloudflareSandboxExecutionConfig,\n options: { checkpointer?: t.LocalFileCheckpointer } = {}\n): CloudflareCodingToolBundle {\n const checkpointer =\n options.checkpointer ??\n (config.fileCheckpointing === true\n ? createLocalFileCheckpointer({\n fs: createCloudflareWorkspaceFS(config),\n })\n : undefined);\n return {\n tools: createCloudflareCodingTools(config, { checkpointer }),\n checkpointer,\n };\n}\n\nexport function createCloudflareExecutionTool(\n name: string,\n config: t.CloudflareSandboxExecutionConfig\n): t.GenericTool | undefined {\n switch (name) {\n case Constants.EXECUTE_CODE:\n return createCloudflareCodeExecutionTool(config);\n case Constants.BASH_TOOL:\n return createCloudflareBashExecutionTool({ config });\n case Constants.PROGRAMMATIC_TOOL_CALLING:\n return createCloudflareProgrammaticToolCallingTool(config);\n case Constants.BASH_PROGRAMMATIC_TOOL_CALLING:\n return createCloudflareBashProgrammaticToolCallingTool(config);\n default:\n return undefined;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { nanoid } from 'nanoid';
|
|
2
2
|
import { ToolMessage } from '@langchain/core/messages';
|
|
3
|
-
import { Providers, StepTypes, ToolCallTypes, Constants, GraphEvents } from '../common/enum.mjs';
|
|
4
3
|
import { isAnthropicWebSearchResult, coerceAnthropicSearchResults } from './search/anthropic.mjs';
|
|
4
|
+
import { Providers, StepTypes, ToolCallTypes, Constants, GraphEvents } from '../common/enum.mjs';
|
|
5
5
|
import { formatResultsForLLM } from './search/format.mjs';
|
|
6
6
|
import '../messages/core.mjs';
|
|
7
7
|
import { getMessageId } from '../messages/ids.mjs';
|
|
8
|
+
import 'node:crypto';
|
|
8
9
|
import '@langchain/core/callbacks/dispatch';
|
|
9
10
|
import 'uuid';
|
|
10
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.mjs","sources":["../../../src/tools/handlers.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/tools/handlers.ts\nimport { nanoid } from 'nanoid';\nimport { ToolMessage } from '@langchain/core/messages';\nimport type { AnthropicWebSearchResultBlockParam } from '@/llm/anthropic/types';\nimport type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';\nimport type { Graph, MultiAgentGraph, StandardGraph } from '@/graphs';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type * as t from '@/types';\nimport {\n ToolCallTypes,\n GraphEvents,\n StepTypes,\n Providers,\n Constants,\n} from '@/common';\nimport {\n coerceAnthropicSearchResults,\n isAnthropicWebSearchResult,\n} from '@/tools/search/anthropic';\nimport { formatResultsForLLM } from '@/tools/search/format';\nimport { getMessageId } from '@/messages';\n\nexport async function handleToolCallChunks({\n graph,\n stepKey,\n toolCallChunks,\n metadata,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n stepKey: string;\n toolCallChunks: ToolCallChunk[];\n metadata?: Record<string, unknown>;\n}): Promise<void> {\n let prevStepId: string;\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n /** Edge Case: If no previous step exists, create a new message creation step */\n const message_id = getMessageId(stepKey, graph, true) ?? '';\n prevStepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id,\n },\n },\n metadata\n );\n prevRunStep = graph.getRunStep(prevStepId);\n }\n\n const _stepId = graph.getStepIdByKey(stepKey);\n\n /** Edge Case: Tool Call Run Step or `tool_call_ids` never dispatched */\n const tool_calls: ToolCall[] | undefined =\n prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION\n ? []\n : undefined;\n\n /** Edge Case: `id` and `name` fields cannot be empty strings */\n for (const toolCallChunk of toolCallChunks) {\n if (toolCallChunk.name === '') {\n toolCallChunk.name = undefined;\n }\n if (toolCallChunk.id === '') {\n toolCallChunk.id = undefined;\n } else if (\n tool_calls != null &&\n toolCallChunk.id != null &&\n toolCallChunk.name != null\n ) {\n tool_calls.push({\n args: {},\n id: toolCallChunk.id,\n name: toolCallChunk.name,\n type: ToolCallTypes.TOOL_CALL,\n });\n }\n }\n\n let stepId: string = _stepId;\n const alreadyDispatched =\n prevRunStep?.type === StepTypes.MESSAGE_CREATION &&\n graph.messageStepHasToolCalls.has(prevStepId);\n\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n /**\n * If previous step is already a tool_calls step, use that step ID\n * This ensures tool call deltas are dispatched to the correct step\n */\n stepId = prevStepId;\n } else if (\n !alreadyDispatched &&\n prevRunStep?.type === StepTypes.MESSAGE_CREATION\n ) {\n /**\n * Create tool_calls step as soon as we receive the first tool call chunk\n * This ensures deltas are always associated with the correct step\n *\n * NOTE: We do NOT dispatch an empty text block here because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - The tool_calls themselves are sufficient for the step\n * - Empty content with tool_call_ids gets stored in conversation history\n * and causes \"messages must have non-empty content\" errors on replay\n */\n graph.messageStepHasToolCalls.set(prevStepId, true);\n stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: tool_calls ?? [],\n },\n metadata\n );\n }\n\n await graph.dispatchRunStepDelta(\n stepId,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: toolCallChunks,\n },\n metadata\n );\n}\n\nexport const handleToolCalls = async (\n toolCalls?: ToolCall[],\n metadata?: Record<string, unknown>,\n graph?: Graph | StandardGraph | MultiAgentGraph\n): Promise<void> => {\n if (!graph || !metadata) {\n console.warn('Graph or metadata not found in `handleToolCalls`');\n return;\n }\n\n if (!toolCalls) {\n return;\n }\n\n if (toolCalls.length === 0) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n /**\n * Track whether we've already reused an empty TOOL_CALLS step created by\n * handleToolCallChunks during streaming. Only reuse it once (for the first\n * tool call); subsequent parallel tool calls must create their own steps.\n */\n let reusedChunkStepId: string | undefined;\n\n for (const tool_call of toolCalls) {\n const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;\n tool_call.id = toolCallId;\n if (!toolCallId || graph.toolCallStepIds.has(toolCallId)) {\n continue;\n }\n\n let prevStepId = '';\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n // no previous step\n }\n\n /**\n * If the previous step is TOOL_CALLS (from handleToolCallChunks or a prior\n * iteration), either reuse it (if empty) or dispatch a new TOOL_CALLS step\n * directly — skip the intermediate MESSAGE_CREATION to avoid orphaned gaps.\n */\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n const details = prevRunStep.stepDetails as t.ToolCallsDetails;\n const isEmpty = !details.tool_calls || details.tool_calls.length === 0;\n if (isEmpty && prevStepId !== reusedChunkStepId) {\n graph.toolCallStepIds.set(toolCallId, prevStepId);\n reusedChunkStepId = prevStepId;\n continue;\n }\n await graph.dispatchRunStep(\n stepKey,\n { type: StepTypes.TOOL_CALLS, tool_calls: [tool_call] },\n metadata\n );\n continue;\n }\n\n /**\n * NOTE: We do NOT dispatch empty text blocks with tool_call_ids because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - They get stored in conversation history and cause errors on replay:\n * \"messages must have non-empty content\" (Anthropic)\n * \"The content field in the Message object is empty\" (Bedrock)\n * - The tool_calls themselves are sufficient\n */\n if (prevStepId && prevRunStep) {\n graph.messageStepHasToolCalls.set(prevStepId, true);\n } else if (!prevRunStep) {\n const messageId = getMessageId(stepKey, graph, true) ?? '';\n const stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id: messageId,\n },\n },\n metadata\n );\n graph.messageStepHasToolCalls.set(stepId, true);\n }\n\n await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: [tool_call],\n },\n metadata\n );\n }\n};\n\nexport const toolResultTypes = new Set([\n // 'tool_use',\n // 'server_tool_use',\n // 'input_json_delta',\n 'tool_result',\n 'web_search_result',\n 'web_search_tool_result',\n]);\n\n/**\n * Handles the result of a server tool call; in other words, a provider's built-in tool.\n * As of 2025-07-06, only Anthropic handles server tool calls with this pattern.\n */\nexport async function handleServerToolResult({\n graph,\n content,\n metadata,\n agentContext,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n content?: string | t.MessageContentComplex[];\n metadata?: Record<string, unknown>;\n agentContext?: AgentContext;\n}): Promise<boolean> {\n let skipHandling = false;\n if (agentContext?.provider !== Providers.ANTHROPIC) {\n return skipHandling;\n }\n if (\n typeof content === 'string' ||\n content == null ||\n content.length === 0 ||\n (content.length === 1 &&\n (content[0] as t.ToolResultContent).tool_use_id == null)\n ) {\n return skipHandling;\n }\n\n for (const contentPart of content) {\n const toolUseId = (contentPart as t.ToolResultContent).tool_use_id;\n if (toolUseId == null || toolUseId === '') {\n continue;\n }\n const stepId = graph.toolCallStepIds.get(toolUseId);\n if (stepId == null || stepId === '') {\n console.warn(\n `Tool use ID ${toolUseId} not found in graph, cannot dispatch tool result.`\n );\n continue;\n }\n const runStep = graph.getRunStep(stepId);\n if (!runStep) {\n console.warn(\n `Run step for ${stepId} does not exist, cannot dispatch tool result.`\n );\n continue;\n } else if (runStep.type !== StepTypes.TOOL_CALLS) {\n console.warn(\n `Run step for ${stepId} is not a tool call step, cannot dispatch tool result.`\n );\n continue;\n }\n\n const toolCall =\n runStep.stepDetails.type === StepTypes.TOOL_CALLS\n ? (runStep.stepDetails.tool_calls?.find(\n (toolCall) => toolCall.id === toolUseId\n ) as ToolCall)\n : undefined;\n\n if (!toolCall) {\n continue;\n }\n\n if (\n contentPart.type === 'web_search_result' ||\n contentPart.type === 'web_search_tool_result'\n ) {\n await handleAnthropicSearchResults({\n contentPart: contentPart as t.ToolResultContent,\n toolCall,\n metadata,\n graph,\n });\n }\n\n if (!skipHandling) {\n skipHandling = true;\n }\n }\n\n return skipHandling;\n}\n\nasync function handleAnthropicSearchResults({\n contentPart,\n toolCall,\n metadata,\n graph,\n}: {\n contentPart: t.ToolResultContent;\n toolCall: Partial<ToolCall>;\n metadata?: Record<string, unknown>;\n graph: StandardGraph | MultiAgentGraph;\n}): Promise<void> {\n if (!Array.isArray(contentPart.content)) {\n console.warn(\n `Expected content to be an array, got ${typeof contentPart.content}`\n );\n return;\n }\n\n if (!isAnthropicWebSearchResult(contentPart.content[0])) {\n console.warn(\n `Expected content to be an Anthropic web search result, got ${JSON.stringify(\n contentPart.content\n )}`\n );\n return;\n }\n\n const turn = graph.invokedToolIds?.size ?? 0;\n const searchResultData = coerceAnthropicSearchResults({\n turn,\n results: contentPart.content as AnthropicWebSearchResultBlockParam[],\n });\n\n const name = toolCall.name;\n const input = toolCall.args ?? {};\n const artifact = {\n [Constants.WEB_SEARCH]: searchResultData,\n };\n const { output: formattedOutput } = formatResultsForLLM(\n turn,\n searchResultData\n );\n const output = new ToolMessage({\n name,\n artifact,\n content: formattedOutput,\n tool_call_id: toolCall.id!,\n });\n const toolEndData: t.ToolEndData = {\n input,\n output,\n };\n await graph.handlerRegistry\n ?.getHandler(GraphEvents.TOOL_END)\n ?.handle(GraphEvents.TOOL_END, toolEndData, metadata, graph);\n\n if (graph.invokedToolIds == null) {\n graph.invokedToolIds = new Set<string>();\n }\n\n graph.invokedToolIds.add(toolCall.id!);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"handlers.mjs","sources":["../../../src/tools/handlers.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/tools/handlers.ts\nimport { nanoid } from 'nanoid';\nimport { ToolMessage } from '@langchain/core/messages';\nimport type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';\nimport type { AnthropicWebSearchResultBlockParam } from '@/llm/anthropic/types';\nimport type { Graph, MultiAgentGraph, StandardGraph } from '@/graphs';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type * as t from '@/types';\nimport {\n coerceAnthropicSearchResults,\n isAnthropicWebSearchResult,\n} from '@/tools/search/anthropic';\nimport {\n ToolCallTypes,\n GraphEvents,\n StepTypes,\n Providers,\n Constants,\n} from '@/common';\nimport { formatResultsForLLM } from '@/tools/search/format';\nimport { getMessageId } from '@/messages';\n\nexport async function handleToolCallChunks({\n graph,\n stepKey,\n toolCallChunks,\n metadata,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n stepKey: string;\n toolCallChunks: ToolCallChunk[];\n metadata?: Record<string, unknown>;\n}): Promise<void> {\n let prevStepId: string;\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n /** Edge Case: If no previous step exists, create a new message creation step */\n const message_id = getMessageId(stepKey, graph, true) ?? '';\n prevStepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id,\n },\n },\n metadata\n );\n prevRunStep = graph.getRunStep(prevStepId);\n }\n\n const _stepId = graph.getStepIdByKey(stepKey);\n\n /** Edge Case: Tool Call Run Step or `tool_call_ids` never dispatched */\n const tool_calls: ToolCall[] | undefined =\n prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION\n ? []\n : undefined;\n\n /** Edge Case: `id` and `name` fields cannot be empty strings */\n for (const toolCallChunk of toolCallChunks) {\n if (toolCallChunk.name === '') {\n toolCallChunk.name = undefined;\n }\n if (toolCallChunk.id === '') {\n toolCallChunk.id = undefined;\n } else if (\n tool_calls != null &&\n toolCallChunk.id != null &&\n toolCallChunk.name != null\n ) {\n tool_calls.push({\n args: {},\n id: toolCallChunk.id,\n name: toolCallChunk.name,\n type: ToolCallTypes.TOOL_CALL,\n });\n }\n }\n\n let stepId: string = _stepId;\n const alreadyDispatched =\n prevRunStep?.type === StepTypes.MESSAGE_CREATION &&\n graph.messageStepHasToolCalls.has(prevStepId);\n\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n /**\n * If previous step is already a tool_calls step, use that step ID\n * This ensures tool call deltas are dispatched to the correct step\n */\n stepId = prevStepId;\n } else if (\n !alreadyDispatched &&\n prevRunStep?.type === StepTypes.MESSAGE_CREATION\n ) {\n /**\n * Create tool_calls step as soon as we receive the first tool call chunk\n * This ensures deltas are always associated with the correct step\n *\n * NOTE: We do NOT dispatch an empty text block here because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - The tool_calls themselves are sufficient for the step\n * - Empty content with tool_call_ids gets stored in conversation history\n * and causes \"messages must have non-empty content\" errors on replay\n */\n graph.messageStepHasToolCalls.set(prevStepId, true);\n stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: tool_calls ?? [],\n },\n metadata\n );\n }\n\n await graph.dispatchRunStepDelta(\n stepId,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: toolCallChunks,\n },\n metadata\n );\n}\n\nexport const handleToolCalls = async (\n toolCalls?: ToolCall[],\n metadata?: Record<string, unknown>,\n graph?: Graph | StandardGraph | MultiAgentGraph\n): Promise<void> => {\n if (!graph || !metadata) {\n console.warn('Graph or metadata not found in `handleToolCalls`');\n return;\n }\n\n if (!toolCalls) {\n return;\n }\n\n if (toolCalls.length === 0) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n /**\n * Track whether we've already reused an empty TOOL_CALLS step created by\n * handleToolCallChunks during streaming. Only reuse it once (for the first\n * tool call); subsequent parallel tool calls must create their own steps.\n */\n let reusedChunkStepId: string | undefined;\n\n for (const tool_call of toolCalls) {\n const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;\n tool_call.id = toolCallId;\n if (!toolCallId || graph.toolCallStepIds.has(toolCallId)) {\n continue;\n }\n\n let prevStepId = '';\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch {\n // no previous step\n }\n\n /**\n * If the previous step is TOOL_CALLS (from handleToolCallChunks or a prior\n * iteration), either reuse it (if empty) or dispatch a new TOOL_CALLS step\n * directly — skip the intermediate MESSAGE_CREATION to avoid orphaned gaps.\n */\n if (prevRunStep?.type === StepTypes.TOOL_CALLS) {\n const details = prevRunStep.stepDetails as t.ToolCallsDetails;\n const isEmpty = !details.tool_calls || details.tool_calls.length === 0;\n if (isEmpty && prevStepId !== reusedChunkStepId) {\n graph.toolCallStepIds.set(toolCallId, prevStepId);\n reusedChunkStepId = prevStepId;\n continue;\n }\n await graph.dispatchRunStep(\n stepKey,\n { type: StepTypes.TOOL_CALLS, tool_calls: [tool_call] },\n metadata\n );\n continue;\n }\n\n /**\n * NOTE: We do NOT dispatch empty text blocks with tool_call_ids because:\n * - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages\n * - They get stored in conversation history and cause errors on replay:\n * \"messages must have non-empty content\" (Anthropic)\n * \"The content field in the Message object is empty\" (Bedrock)\n * - The tool_calls themselves are sufficient\n */\n if (prevStepId && prevRunStep) {\n graph.messageStepHasToolCalls.set(prevStepId, true);\n } else if (!prevRunStep) {\n const messageId = getMessageId(stepKey, graph, true) ?? '';\n const stepId = await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id: messageId,\n },\n },\n metadata\n );\n graph.messageStepHasToolCalls.set(stepId, true);\n }\n\n await graph.dispatchRunStep(\n stepKey,\n {\n type: StepTypes.TOOL_CALLS,\n tool_calls: [tool_call],\n },\n metadata\n );\n }\n};\n\nexport const toolResultTypes = new Set([\n // 'tool_use',\n // 'server_tool_use',\n // 'input_json_delta',\n 'tool_result',\n 'web_search_result',\n 'web_search_tool_result',\n]);\n\n/**\n * Handles the result of a server tool call; in other words, a provider's built-in tool.\n * As of 2025-07-06, only Anthropic handles server tool calls with this pattern.\n */\nexport async function handleServerToolResult({\n graph,\n content,\n metadata,\n agentContext,\n}: {\n graph: StandardGraph | MultiAgentGraph;\n content?: string | t.MessageContentComplex[];\n metadata?: Record<string, unknown>;\n agentContext?: AgentContext;\n}): Promise<boolean> {\n let skipHandling = false;\n if (agentContext?.provider !== Providers.ANTHROPIC) {\n return skipHandling;\n }\n if (\n typeof content === 'string' ||\n content == null ||\n content.length === 0 ||\n (content.length === 1 &&\n (content[0] as t.ToolResultContent).tool_use_id == null)\n ) {\n return skipHandling;\n }\n\n for (const contentPart of content) {\n const toolUseId = (contentPart as t.ToolResultContent).tool_use_id;\n if (toolUseId == null || toolUseId === '') {\n continue;\n }\n const stepId = graph.toolCallStepIds.get(toolUseId);\n if (stepId == null || stepId === '') {\n console.warn(\n `Tool use ID ${toolUseId} not found in graph, cannot dispatch tool result.`\n );\n continue;\n }\n const runStep = graph.getRunStep(stepId);\n if (!runStep) {\n console.warn(\n `Run step for ${stepId} does not exist, cannot dispatch tool result.`\n );\n continue;\n } else if (runStep.type !== StepTypes.TOOL_CALLS) {\n console.warn(\n `Run step for ${stepId} is not a tool call step, cannot dispatch tool result.`\n );\n continue;\n }\n\n const toolCall =\n runStep.stepDetails.type === StepTypes.TOOL_CALLS\n ? (runStep.stepDetails.tool_calls?.find(\n (toolCall) => toolCall.id === toolUseId\n ) as ToolCall)\n : undefined;\n\n if (!toolCall) {\n continue;\n }\n\n if (\n contentPart.type === 'web_search_result' ||\n contentPart.type === 'web_search_tool_result'\n ) {\n await handleAnthropicSearchResults({\n contentPart: contentPart as t.ToolResultContent,\n toolCall,\n metadata,\n graph,\n });\n }\n\n if (!skipHandling) {\n skipHandling = true;\n }\n }\n\n return skipHandling;\n}\n\nasync function handleAnthropicSearchResults({\n contentPart,\n toolCall,\n metadata,\n graph,\n}: {\n contentPart: t.ToolResultContent;\n toolCall: Partial<ToolCall>;\n metadata?: Record<string, unknown>;\n graph: StandardGraph | MultiAgentGraph;\n}): Promise<void> {\n if (!Array.isArray(contentPart.content)) {\n console.warn(\n `Expected content to be an array, got ${typeof contentPart.content}`\n );\n return;\n }\n\n if (!isAnthropicWebSearchResult(contentPart.content[0])) {\n console.warn(\n `Expected content to be an Anthropic web search result, got ${JSON.stringify(\n contentPart.content\n )}`\n );\n return;\n }\n\n const turn = graph.invokedToolIds?.size ?? 0;\n const searchResultData = coerceAnthropicSearchResults({\n turn,\n results: contentPart.content as AnthropicWebSearchResultBlockParam[],\n });\n\n const name = toolCall.name;\n const input = toolCall.args ?? {};\n const artifact = {\n [Constants.WEB_SEARCH]: searchResultData,\n };\n const { output: formattedOutput } = formatResultsForLLM(\n turn,\n searchResultData\n );\n const output = new ToolMessage({\n name,\n artifact,\n content: formattedOutput,\n tool_call_id: toolCall.id!,\n });\n const toolEndData: t.ToolEndData = {\n input,\n output,\n };\n await graph.handlerRegistry\n ?.getHandler(GraphEvents.TOOL_END)\n ?.handle(GraphEvents.TOOL_END, toolEndData, metadata, graph);\n\n if (graph.invokedToolIds == null) {\n graph.invokedToolIds = new Set<string>();\n }\n\n graph.invokedToolIds.add(toolCall.id!);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompileCheckTool.mjs","sources":["../../../../src/tools/local/CompileCheckTool.ts"],"sourcesContent":["/**\n * `compile_check` — a thin LLM-callable wrapper around the project's\n * standard typecheck/lint command. Lets the agent answer \"did my\n * change break anything?\" without us shipping a real LSP client.\n *\n * Auto-detection priority (first hit wins):\n *\n * 1. `local.compileCheck.command` — explicit override\n * 2. `tsconfig.json` → `npx --no-install tsc --noEmit`\n * 3. `package.json` with a typescript dep → same as 2\n * 4. `pyproject.toml` or `setup.py` / `setup.cfg`\n * with a dev dep on mypy → `python3 -m mypy .`\n * else → `python3 -m py_compile <every .py>`\n * (bounded by find-walk so node_modules\n * and `.venv` don't blow up)\n * 5. `Cargo.toml` → `cargo check --message-format=short`\n * 6. `go.mod` → `go vet ./...`\n * 7. otherwise → tells the agent there's\n * no detected toolchain.\n *\n * Output is the spawn process's stdout/stderr passed through\n * `truncateLocalOutput` so a 10MB tsc dump can't blow context. The\n * exit code is reported.\n */\n\nimport { resolve } from 'path';\nimport { tool } from '@langchain/core/tools';\nimport type { DynamicStructuredTool } from '@langchain/core/tools';\nimport type * as t from '@/types';\nimport {\n getLocalCwd,\n getWorkspaceFS,\n spawnLocalProcess,\n truncateLocalOutput,\n validateBashCommand,\n} from './LocalExecutionEngine';\nimport type { WorkspaceFS } from './workspaceFS';\nimport { Constants } from '@/common';\n\n/** Back-compat alias; canonical name lives on `Constants.COMPILE_CHECK`. */\nexport const CompileCheckToolName = Constants.COMPILE_CHECK;\n\nconst CompileCheckSchema: t.JsonSchemaType = {\n type: 'object',\n properties: {\n command: {\n type: 'string',\n description:\n 'Optional explicit command to run instead of the auto-detected one. Runs verbatim from the local engine cwd; honours the standard sandbox/AST gate.',\n },\n timeout_ms: {\n type: 'integer',\n description:\n 'Optional timeout in milliseconds. Defaults to 120000 (2 min).',\n },\n },\n};\n\ntype DetectedKind =\n | 'typescript'\n | 'python-mypy'\n | 'python-compile'\n | 'rust'\n | 'go'\n | 'unknown';\n\ntype Detection = {\n kind: DetectedKind;\n command: string;\n reason: string;\n};\n\nasync function pathExists(fs: WorkspaceFS, p: string): Promise<boolean> {\n try {\n await fs.stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\n// Probes for project markers via the configured WorkspaceFS so a Run\n// with `local.exec.fs` (in-memory or remote engine) detects the right\n// toolchain against the actual workspace — not the host filesystem.\n// Codex P1 #25.\nasync function detect(cwd: string, fs: WorkspaceFS): Promise<Detection> {\n if (await pathExists(fs, resolve(cwd, 'tsconfig.json'))) {\n return {\n kind: 'typescript',\n command: 'npx --no-install tsc --noEmit',\n reason: 'tsconfig.json present',\n };\n }\n if (await pathExists(fs, resolve(cwd, 'package.json'))) {\n const pkgRaw = await fs\n .readFile(resolve(cwd, 'package.json'), 'utf8')\n .catch(() => '');\n if (pkgRaw.includes('\"typescript\"')) {\n return {\n kind: 'typescript',\n command: 'npx --no-install tsc --noEmit',\n reason: 'package.json declares typescript',\n };\n }\n }\n if (await pathExists(fs, resolve(cwd, 'Cargo.toml'))) {\n return {\n kind: 'rust',\n command: 'cargo check --message-format=short',\n reason: 'Cargo.toml present',\n };\n }\n if (await pathExists(fs, resolve(cwd, 'go.mod'))) {\n return {\n kind: 'go',\n command: 'go vet ./...',\n reason: 'go.mod present',\n };\n }\n if (\n (await pathExists(fs, resolve(cwd, 'pyproject.toml'))) ||\n (await pathExists(fs, resolve(cwd, 'setup.py'))) ||\n (await pathExists(fs, resolve(cwd, 'setup.cfg')))\n ) {\n const pyToml = await fs\n .readFile(resolve(cwd, 'pyproject.toml'), 'utf8')\n .catch(() => '');\n if (pyToml.includes('mypy')) {\n return {\n kind: 'python-mypy',\n command: 'python3 -m mypy .',\n reason: 'pyproject.toml declares mypy',\n };\n }\n return {\n kind: 'python-compile',\n command:\n 'python3 -c \"import compileall, sys; sys.exit(0 if compileall.compile_dir(\\'.\\', quiet=1, rx=__import__(\\'re\\').compile(r\\'(node_modules|\\\\.venv|\\\\.git|build|dist)\\')) else 1)\"',\n reason: 'Python project (no mypy detected)',\n };\n }\n return {\n kind: 'unknown',\n command: '',\n reason:\n 'no recognised project marker (tsconfig.json, package.json[typescript], Cargo.toml, go.mod, pyproject.toml, setup.py)',\n };\n}\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\n\nexport function createCompileCheckTool(\n config: t.LocalExecutionConfig = {}\n): DynamicStructuredTool {\n return tool(\n async (rawInput) => {\n const input = rawInput as {\n command?: string;\n timeout_ms?: number;\n };\n const cwd = getLocalCwd(config);\n const fs = getWorkspaceFS(config);\n const overrideCommand = input.command ?? config.compileCheck?.command;\n let detection: Detection;\n if (overrideCommand != null && overrideCommand.trim() !== '') {\n detection = {\n kind: 'unknown',\n command: overrideCommand,\n reason: 'explicit override',\n };\n } else {\n detection = await detect(cwd, fs);\n }\n\n if (detection.command === '') {\n const explainer =\n `compile_check: ${detection.reason}. Pass an explicit \\`command\\` (e.g. \\`npm run typecheck\\`) to override.`;\n return [\n explainer,\n {\n kind: detection.kind,\n ran: false,\n reason: detection.reason,\n cwd,\n },\n ];\n }\n\n // Codex P1 #21: route the resolved command through the same\n // safety gates the rest of the local engine uses. Without this\n // a host with `readOnly: true` (or relying on the destructive-\n // command guard) could be bypassed by passing a `command`\n // override to compile_check that performs writes/deletes.\n // Auto-detected commands (tsc/cargo/etc.) pass these gates\n // unchanged — the validation is only blocking for genuinely\n // mutating overrides.\n const validation = await validateBashCommand(detection.command, config);\n if (!validation.valid) {\n const explainer =\n `compile_check refused to run \\`${detection.command}\\`: ${validation.errors.join('; ')}`;\n return [\n explainer,\n {\n kind: detection.kind,\n ran: false,\n reason: validation.errors.join('; '),\n cwd,\n },\n ];\n }\n\n const timeoutMs =\n input.timeout_ms ??\n config.compileCheck?.timeoutMs ??\n DEFAULT_TIMEOUT_MS;\n const result = await spawnLocalProcess(\n config.shell ?? (process.platform === 'win32' ? 'bash.exe' : 'bash'),\n ['-lc', detection.command],\n {\n ...config,\n timeoutMs,\n maxOutputChars: config.maxOutputChars ?? 8000,\n }\n );\n\n const passed =\n result.exitCode === 0 && !result.timedOut;\n const headline = passed\n ? `compile_check (${detection.kind}) PASSED via \\`${detection.command}\\``\n : `compile_check (${detection.kind}) FAILED via \\`${detection.command}\\` ` +\n `(exit=${result.exitCode ?? 'unknown'}${result.timedOut ? ', timed_out=true' : ''})`;\n\n let body = '';\n if (result.stdout !== '') {\n body += `\\n\\nstdout:\\n${truncateLocalOutput(result.stdout, 4000)}`;\n }\n if (result.stderr !== '') {\n body += `\\n\\nstderr:\\n${truncateLocalOutput(result.stderr, 4000)}`;\n }\n if (result.fullOutputPath != null) {\n body += `\\n\\nfull_output_path: ${result.fullOutputPath}`;\n }\n const summary = `${headline}${body}\\n\\nworking_directory: ${cwd}\\nreason: ${detection.reason}`;\n\n return [\n summary,\n {\n kind: detection.kind,\n ran: true,\n passed,\n exit_code: result.exitCode,\n timed_out: result.timedOut,\n command: detection.command,\n cwd,\n },\n ];\n },\n {\n name: CompileCheckToolName,\n description:\n 'Run the project\\'s standard typecheck or lint pass and return its output. Auto-detects from project markers (tsconfig.json/package.json -> tsc; Cargo.toml -> cargo check; go.mod -> go vet; pyproject.toml -> mypy or py_compile). Pass `command` to override.',\n schema: CompileCheckSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport function createCompileCheckToolDefinition(): t.LCTool {\n return {\n name: CompileCheckToolName,\n description:\n 'Run the project\\'s standard typecheck or lint pass and return its output.',\n parameters: CompileCheckSchema,\n allowed_callers: ['direct', 'code_execution'],\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n toolType: 'builtin',\n };\n}\n"],"names":[],"mappings":";;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AAgBH;AACO,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAE9C,MAAM,kBAAkB,GAAqB;AAC3C,IAAA,IAAI,EAAE,QAAQ;AACd,IAAA,UAAU,EAAE;AACV,QAAA,OAAO,EAAE;AACP,YAAA,IAAI,EAAE,QAAQ;AACd,YAAA,WAAW,EACT,oJAAoJ;AACvJ,SAAA;AACD,QAAA,UAAU,EAAE;AACV,YAAA,IAAI,EAAE,SAAS;AACf,YAAA,WAAW,EACT,+DAA+D;AAClE,SAAA;AACF,KAAA;CACF;AAgBD,eAAe,UAAU,CAAC,EAAe,EAAE,CAAS,EAAA;AAClD,IAAA,IAAI;AACF,QAAA,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAChB,QAAA,OAAO,IAAI;IACb;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACF;AAEA;AACA;AACA;AACA;AACA,eAAe,MAAM,CAAC,GAAW,EAAE,EAAe,EAAA;AAChD,IAAA,IAAI,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE;QACvD,OAAO;AACL,YAAA,IAAI,EAAE,YAAY;AAClB,YAAA,OAAO,EAAE,+BAA+B;AACxC,YAAA,MAAM,EAAE,uBAAuB;SAChC;IACH;AACA,IAAA,IAAI,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE;QACtD,MAAM,MAAM,GAAG,MAAM;aAClB,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM;AAC7C,aAAA,KAAK,CAAC,MAAM,EAAE,CAAC;AAClB,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;YACnC,OAAO;AACL,gBAAA,IAAI,EAAE,YAAY;AAClB,gBAAA,OAAO,EAAE,+BAA+B;AACxC,gBAAA,MAAM,EAAE,kCAAkC;aAC3C;QACH;IACF;AACA,IAAA,IAAI,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE;QACpD,OAAO;AACL,YAAA,IAAI,EAAE,MAAM;AACZ,YAAA,OAAO,EAAE,oCAAoC;AAC7C,YAAA,MAAM,EAAE,oBAAoB;SAC7B;IACH;AACA,IAAA,IAAI,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE;QAChD,OAAO;AACL,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,OAAO,EAAE,cAAc;AACvB,YAAA,MAAM,EAAE,gBAAgB;SACzB;IACH;AACA,IAAA,IACE,CAAC,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;AACrD,SAAC,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;AAChD,SAAC,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,EACjD;QACA,MAAM,MAAM,GAAG,MAAM;aAClB,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,MAAM;AAC/C,aAAA,KAAK,CAAC,MAAM,EAAE,CAAC;AAClB,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;YAC3B,OAAO;AACL,gBAAA,IAAI,EAAE,aAAa;AACnB,gBAAA,OAAO,EAAE,mBAAmB;AAC5B,gBAAA,MAAM,EAAE,8BAA8B;aACvC;QACH;QACA,OAAO;AACL,YAAA,IAAI,EAAE,gBAAgB;AACtB,YAAA,OAAO,EACL,iLAAiL;AACnL,YAAA,MAAM,EAAE,mCAAmC;SAC5C;IACH;IACA,OAAO;AACL,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,OAAO,EAAE,EAAE;AACX,QAAA,MAAM,EACJ,sHAAsH;KACzH;AACH;AAEA,MAAM,kBAAkB,GAAG,OAAO;AAE5B,SAAU,sBAAsB,CACpC,MAAA,GAAiC,EAAE,EAAA;AAEnC,IAAA,OAAO,IAAI,CACT,OAAO,QAAQ,KAAI;QACjB,MAAM,KAAK,GAAG,QAGb;AACD,QAAA,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC;AAC/B,QAAA,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC;QACjC,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,YAAY,EAAE,OAAO;AACrE,QAAA,IAAI,SAAoB;QACxB,IAAI,eAAe,IAAI,IAAI,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AAC5D,YAAA,SAAS,GAAG;AACV,gBAAA,IAAI,EAAE,SAAS;AACf,gBAAA,OAAO,EAAE,eAAe;AACxB,gBAAA,MAAM,EAAE,mBAAmB;aAC5B;QACH;aAAO;YACL,SAAS,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC;QACnC;AAEA,QAAA,IAAI,SAAS,CAAC,OAAO,KAAK,EAAE,EAAE;AAC5B,YAAA,MAAM,SAAS,GACb,CAAA,eAAA,EAAkB,SAAS,CAAC,MAAM,0EAA0E;YAC9G,OAAO;gBACL,SAAS;AACT,gBAAA;oBACE,IAAI,EAAE,SAAS,CAAC,IAAI;AACpB,oBAAA,GAAG,EAAE,KAAK;oBACV,MAAM,EAAE,SAAS,CAAC,MAAM;oBACxB,GAAG;AACJ,iBAAA;aACF;QACH;;;;;;;;;QAUA,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;AACvE,QAAA,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;AACrB,YAAA,MAAM,SAAS,GACb,CAAA,+BAAA,EAAkC,SAAS,CAAC,OAAO,CAAA,IAAA,EAAO,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC1F,OAAO;gBACL,SAAS;AACT,gBAAA;oBACE,IAAI,EAAE,SAAS,CAAC,IAAI;AACpB,oBAAA,GAAG,EAAE,KAAK;oBACV,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;oBACpC,GAAG;AACJ,iBAAA;aACF;QACH;AAEA,QAAA,MAAM,SAAS,GACb,KAAK,CAAC,UAAU;YAChB,MAAM,CAAC,YAAY,EAAE,SAAS;AAC9B,YAAA,kBAAkB;AACpB,QAAA,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,MAAM,CAAC,KAAK,KAAK,OAAO,CAAC,QAAQ,KAAK,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC,EACpE,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EAC1B;AACE,YAAA,GAAG,MAAM;YACT,SAAS;AACT,YAAA,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,IAAI;AAC9C,SAAA,CACF;AAED,QAAA,MAAM,MAAM,GACV,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ;QAC3C,MAAM,QAAQ,GAAG;cACb,kBAAkB,SAAS,CAAC,IAAI,CAAA,eAAA,EAAkB,SAAS,CAAC,OAAO,CAAA,EAAA;cACnE,kBAAkB,SAAS,CAAC,IAAI,CAAA,eAAA,EAAkB,SAAS,CAAC,OAAO,CAAA,GAAA,CAAK;AACxE,gBAAA,CAAA,MAAA,EAAS,MAAM,CAAC,QAAQ,IAAI,SAAS,CAAA,EAAG,MAAM,CAAC,QAAQ,GAAG,kBAAkB,GAAG,EAAE,GAAG;QAExF,IAAI,IAAI,GAAG,EAAE;AACb,QAAA,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE;YACxB,IAAI,IAAI,CAAA,aAAA,EAAgB,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA,CAAE;QACpE;AACA,QAAA,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE;YACxB,IAAI,IAAI,CAAA,aAAA,EAAgB,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA,CAAE;QACpE;AACA,QAAA,IAAI,MAAM,CAAC,cAAc,IAAI,IAAI,EAAE;AACjC,YAAA,IAAI,IAAI,CAAA,sBAAA,EAAyB,MAAM,CAAC,cAAc,EAAE;QAC1D;AACA,QAAA,MAAM,OAAO,GAAG,CAAA,EAAG,QAAQ,CAAA,EAAG,IAAI,CAAA,uBAAA,EAA0B,GAAG,CAAA,UAAA,EAAa,SAAS,CAAC,MAAM,EAAE;QAE9F,OAAO;YACL,OAAO;AACP,YAAA;gBACE,IAAI,EAAE,SAAS,CAAC,IAAI;AACpB,gBAAA,GAAG,EAAE,IAAI;gBACT,MAAM;gBACN,SAAS,EAAE,MAAM,CAAC,QAAQ;gBAC1B,SAAS,EAAE,MAAM,CAAC,QAAQ;gBAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;gBAC1B,GAAG;AACJ,aAAA;SACF;AACH,IAAA,CAAC,EACD;AACE,QAAA,IAAI,EAAE,oBAAoB;AAC1B,QAAA,WAAW,EACT,iQAAiQ;AACnQ,QAAA,MAAM,EAAE,kBAAkB;QAC1B,cAAc,EAAE,SAAS,CAAC,oBAAoB;AAC/C,KAAA,CACF;AACH;SAEgB,gCAAgC,GAAA;IAC9C,OAAO;AACL,QAAA,IAAI,EAAE,oBAAoB;AAC1B,QAAA,WAAW,EACT,2EAA2E;AAC7E,QAAA,UAAU,EAAE,kBAAkB;AAC9B,QAAA,eAAe,EAAE,CAAC,QAAQ,EAAE,gBAAgB,CAAC;QAC7C,cAAc,EAAE,SAAS,CAAC,oBAAoB;AAC9C,QAAA,QAAQ,EAAE,SAAS;KACpB;AACH;;;;"}
|
|
1
|
+
{"version":3,"file":"CompileCheckTool.mjs","sources":["../../../../src/tools/local/CompileCheckTool.ts"],"sourcesContent":["/**\n * `compile_check` — a thin LLM-callable wrapper around the project's\n * standard typecheck/lint command. Lets the agent answer \"did my\n * change break anything?\" without us shipping a real LSP client.\n *\n * Auto-detection priority (first hit wins):\n *\n * 1. `local.compileCheck.command` — explicit override\n * 2. `tsconfig.json` → `npx --no-install tsc --noEmit`\n * 3. `package.json` with a typescript dep → same as 2\n * 4. `pyproject.toml` or `setup.py` / `setup.cfg`\n * with a dev dep on mypy → `python3 -m mypy .`\n * else → `python3 -m py_compile <every .py>`\n * (bounded by find-walk so node_modules\n * and `.venv` don't blow up)\n * 5. `Cargo.toml` → `cargo check --message-format=short`\n * 6. `go.mod` → `go vet ./...`\n * 7. otherwise → tells the agent there's\n * no detected toolchain.\n *\n * Output is the spawn process's stdout/stderr passed through\n * `truncateLocalOutput` so a 10MB tsc dump can't blow context. The\n * exit code is reported.\n */\n\nimport { resolve } from 'path';\nimport { tool } from '@langchain/core/tools';\nimport type { DynamicStructuredTool } from '@langchain/core/tools';\nimport type { WorkspaceFS } from './workspaceFS';\nimport type * as t from '@/types';\nimport {\n getLocalCwd,\n getWorkspaceFS,\n spawnLocalProcess,\n truncateLocalOutput,\n validateBashCommand,\n} from './LocalExecutionEngine';\nimport { Constants } from '@/common';\n\n/** Back-compat alias; canonical name lives on `Constants.COMPILE_CHECK`. */\nexport const CompileCheckToolName = Constants.COMPILE_CHECK;\n\nconst CompileCheckSchema: t.JsonSchemaType = {\n type: 'object',\n properties: {\n command: {\n type: 'string',\n description:\n 'Optional explicit command to run instead of the auto-detected one. Runs verbatim from the local engine cwd; honours the standard sandbox/AST gate.',\n },\n timeout_ms: {\n type: 'integer',\n description:\n 'Optional timeout in milliseconds. Defaults to 120000 (2 min).',\n },\n },\n};\n\ntype DetectedKind =\n | 'typescript'\n | 'python-mypy'\n | 'python-compile'\n | 'rust'\n | 'go'\n | 'unknown';\n\ntype Detection = {\n kind: DetectedKind;\n command: string;\n reason: string;\n};\n\nasync function pathExists(fs: WorkspaceFS, p: string): Promise<boolean> {\n try {\n await fs.stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\n// Probes for project markers via the configured WorkspaceFS so a Run\n// with `local.exec.fs` (in-memory or remote engine) detects the right\n// toolchain against the actual workspace — not the host filesystem.\n// Codex P1 #25.\nasync function detect(cwd: string, fs: WorkspaceFS): Promise<Detection> {\n if (await pathExists(fs, resolve(cwd, 'tsconfig.json'))) {\n return {\n kind: 'typescript',\n command: 'npx --no-install tsc --noEmit',\n reason: 'tsconfig.json present',\n };\n }\n if (await pathExists(fs, resolve(cwd, 'package.json'))) {\n const pkgRaw = await fs\n .readFile(resolve(cwd, 'package.json'), 'utf8')\n .catch(() => '');\n if (pkgRaw.includes('\"typescript\"')) {\n return {\n kind: 'typescript',\n command: 'npx --no-install tsc --noEmit',\n reason: 'package.json declares typescript',\n };\n }\n }\n if (await pathExists(fs, resolve(cwd, 'Cargo.toml'))) {\n return {\n kind: 'rust',\n command: 'cargo check --message-format=short',\n reason: 'Cargo.toml present',\n };\n }\n if (await pathExists(fs, resolve(cwd, 'go.mod'))) {\n return {\n kind: 'go',\n command: 'go vet ./...',\n reason: 'go.mod present',\n };\n }\n if (\n (await pathExists(fs, resolve(cwd, 'pyproject.toml'))) ||\n (await pathExists(fs, resolve(cwd, 'setup.py'))) ||\n (await pathExists(fs, resolve(cwd, 'setup.cfg')))\n ) {\n const pyToml = await fs\n .readFile(resolve(cwd, 'pyproject.toml'), 'utf8')\n .catch(() => '');\n if (pyToml.includes('mypy')) {\n return {\n kind: 'python-mypy',\n command: 'python3 -m mypy .',\n reason: 'pyproject.toml declares mypy',\n };\n }\n return {\n kind: 'python-compile',\n command:\n 'python3 -c \"import compileall, sys; sys.exit(0 if compileall.compile_dir(\\'.\\', quiet=1, rx=__import__(\\'re\\').compile(r\\'(node_modules|\\\\.venv|\\\\.git|build|dist)\\')) else 1)\"',\n reason: 'Python project (no mypy detected)',\n };\n }\n return {\n kind: 'unknown',\n command: '',\n reason:\n 'no recognised project marker (tsconfig.json, package.json[typescript], Cargo.toml, go.mod, pyproject.toml, setup.py)',\n };\n}\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\n\nexport function createCompileCheckTool(\n config: t.LocalExecutionConfig = {}\n): DynamicStructuredTool {\n return tool(\n async (rawInput) => {\n const input = rawInput as {\n command?: string;\n timeout_ms?: number;\n };\n const cwd = getLocalCwd(config);\n const fs = getWorkspaceFS(config);\n const overrideCommand = input.command ?? config.compileCheck?.command;\n let detection: Detection;\n if (overrideCommand != null && overrideCommand.trim() !== '') {\n detection = {\n kind: 'unknown',\n command: overrideCommand,\n reason: 'explicit override',\n };\n } else {\n detection = await detect(cwd, fs);\n }\n\n if (detection.command === '') {\n const explainer = `compile_check: ${detection.reason}. Pass an explicit \\`command\\` (e.g. \\`npm run typecheck\\`) to override.`;\n return [\n explainer,\n {\n kind: detection.kind,\n ran: false,\n reason: detection.reason,\n cwd,\n },\n ];\n }\n\n // Codex P1 #21: route the resolved command through the same\n // safety gates the rest of the local engine uses. Without this\n // a host with `readOnly: true` (or relying on the destructive-\n // command guard) could be bypassed by passing a `command`\n // override to compile_check that performs writes/deletes.\n // Auto-detected commands (tsc/cargo/etc.) pass these gates\n // unchanged — the validation is only blocking for genuinely\n // mutating overrides.\n const validation = await validateBashCommand(detection.command, config);\n if (!validation.valid) {\n const explainer = `compile_check refused to run \\`${detection.command}\\`: ${validation.errors.join('; ')}`;\n return [\n explainer,\n {\n kind: detection.kind,\n ran: false,\n reason: validation.errors.join('; '),\n cwd,\n },\n ];\n }\n\n const timeoutMs =\n input.timeout_ms ??\n config.compileCheck?.timeoutMs ??\n DEFAULT_TIMEOUT_MS;\n const result = await spawnLocalProcess(\n config.shell ?? (process.platform === 'win32' ? 'bash.exe' : 'bash'),\n ['-lc', detection.command],\n {\n ...config,\n timeoutMs,\n maxOutputChars: config.maxOutputChars ?? 8000,\n }\n );\n\n const passed = result.exitCode === 0 && !result.timedOut;\n const headline = passed\n ? `compile_check (${detection.kind}) PASSED via \\`${detection.command}\\``\n : `compile_check (${detection.kind}) FAILED via \\`${detection.command}\\` ` +\n `(exit=${result.exitCode ?? 'unknown'}${result.timedOut ? ', timed_out=true' : ''})`;\n\n let body = '';\n if (result.stdout !== '') {\n body += `\\n\\nstdout:\\n${truncateLocalOutput(result.stdout, 4000)}`;\n }\n if (result.stderr !== '') {\n body += `\\n\\nstderr:\\n${truncateLocalOutput(result.stderr, 4000)}`;\n }\n if (result.fullOutputPath != null) {\n body += `\\n\\nfull_output_path: ${result.fullOutputPath}`;\n }\n const summary = `${headline}${body}\\n\\nworking_directory: ${cwd}\\nreason: ${detection.reason}`;\n\n return [\n summary,\n {\n kind: detection.kind,\n ran: true,\n passed,\n exit_code: result.exitCode,\n timed_out: result.timedOut,\n command: detection.command,\n cwd,\n },\n ];\n },\n {\n name: CompileCheckToolName,\n description:\n 'Run the project\\'s standard typecheck or lint pass and return its output. Auto-detects from project markers (tsconfig.json/package.json -> tsc; Cargo.toml -> cargo check; go.mod -> go vet; pyproject.toml -> mypy or py_compile). Pass `command` to override.',\n schema: CompileCheckSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport function createCompileCheckToolDefinition(): t.LCTool {\n return {\n name: CompileCheckToolName,\n description:\n 'Run the project\\'s standard typecheck or lint pass and return its output.',\n parameters: CompileCheckSchema,\n allowed_callers: ['direct', 'code_execution'],\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n toolType: 'builtin',\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -28,7 +28,8 @@ class LocalFileCheckpointerImpl {
|
|
|
28
28
|
this.fs = fs;
|
|
29
29
|
}
|
|
30
30
|
async captureBeforeWrite(absolutePath) {
|
|
31
|
-
if (this.snapshots.has(absolutePath) ||
|
|
31
|
+
if (this.snapshots.has(absolutePath) ||
|
|
32
|
+
this.oversizePaths.has(absolutePath)) {
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
34
35
|
let info;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileCheckpointer.mjs","sources":["../../../../src/tools/local/FileCheckpointer.ts"],"sourcesContent":["import { dirname } from 'path';\nimport {
|
|
1
|
+
{"version":3,"file":"FileCheckpointer.mjs","sources":["../../../../src/tools/local/FileCheckpointer.ts"],"sourcesContent":["import { dirname } from 'path';\nimport type { WorkspaceFS } from './workspaceFS';\nimport type * as t from '@/types';\nimport { nodeWorkspaceFS } from './workspaceFS';\n\ntype Snapshot = { kind: 'absent' } | { kind: 'present'; content: Buffer };\n\n/**\n * Per-Run snapshot store for write_file / edit_file. Captures the\n * pre-write byte content of every path the local engine is about to\n * mutate so a later `rewind()` can restore the working tree to its\n * original state. Notes:\n *\n * - Idempotent per path: subsequent captures preserve the first\n * snapshot (so rewind always restores the *original* content).\n * - Captures missing files as `{ kind: 'absent' }`; rewind deletes\n * those paths so created files are removed.\n * - In-memory: snapshots live for the lifetime of this instance and\n * are not persisted across processes. Tie the lifetime to a Run.\n * - Bounded by `maxBytesPerFile` (default 32 MiB) to bound memory.\n * A file larger than the cap is recorded but not snapshotted; the\n * rewind of that path is best-effort and the caller is told via\n * the result count not to trust it.\n */\nexport class LocalFileCheckpointerImpl implements t.LocalFileCheckpointer {\n private snapshots = new Map<string, Snapshot>();\n private oversizePaths = new Set<string>();\n\n constructor(\n private readonly maxBytesPerFile: number = 32 * 1024 * 1024,\n private readonly fs: WorkspaceFS = nodeWorkspaceFS\n ) {}\n\n async captureBeforeWrite(absolutePath: string): Promise<void> {\n if (\n this.snapshots.has(absolutePath) ||\n this.oversizePaths.has(absolutePath)\n ) {\n return;\n }\n let info;\n try {\n info = await this.fs.stat(absolutePath);\n } catch {\n this.snapshots.set(absolutePath, { kind: 'absent' });\n return;\n }\n if (!info.isFile()) {\n return;\n }\n if (info.size > this.maxBytesPerFile) {\n this.oversizePaths.add(absolutePath);\n return;\n }\n const content = (await this.fs.readFile(absolutePath)) as Buffer;\n this.snapshots.set(absolutePath, { kind: 'present', content });\n }\n\n async rewind(): Promise<number> {\n let restored = 0;\n for (const [path, snapshot] of this.snapshots.entries()) {\n if (snapshot.kind === 'absent') {\n await this.fs.unlink(path).catch(() => undefined);\n restored++;\n continue;\n }\n try {\n await this.fs.mkdir(dirname(path), { recursive: true });\n await this.fs.writeFile(path, snapshot.content);\n restored++;\n } catch {\n // Best-effort: ignore individual restore failures so the rest\n // of the rewind continues.\n }\n }\n return restored;\n }\n\n capturedPaths(): string[] {\n return [...this.snapshots.keys(), ...this.oversizePaths];\n }\n}\n\n/**\n * Convenience factory so callers don't have to reach for the impl\n * class directly. Accepts an optional `WorkspaceFS` so a host using a\n * non-default engine (remote sandbox, in-memory test FS, etc.) can\n * route the checkpointer through the same I/O.\n */\nexport function createLocalFileCheckpointer(\n options: { maxBytesPerFile?: number; fs?: WorkspaceFS } = {}\n): t.LocalFileCheckpointer {\n return new LocalFileCheckpointerImpl(options.maxBytesPerFile, options.fs);\n}\n"],"names":[],"mappings":";;;AAOA;;;;;;;;;;;;;;;;AAgBG;MACU,yBAAyB,CAAA;AAKjB,IAAA,eAAA;AACA,IAAA,EAAA;AALX,IAAA,SAAS,GAAG,IAAI,GAAG,EAAoB;AACvC,IAAA,aAAa,GAAG,IAAI,GAAG,EAAU;IAEzC,WAAA,CACmB,eAAA,GAA0B,EAAE,GAAG,IAAI,GAAG,IAAI,EAC1C,KAAkB,eAAe,EAAA;QADjC,IAAA,CAAA,eAAe,GAAf,eAAe;QACf,IAAA,CAAA,EAAE,GAAF,EAAE;IAClB;IAEH,MAAM,kBAAkB,CAAC,YAAoB,EAAA;AAC3C,QAAA,IACE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC;YAChC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EACpC;YACA;QACF;AACA,QAAA,IAAI,IAAI;AACR,QAAA,IAAI;YACF,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC;QACzC;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YACpD;QACF;AACA,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE;YAClB;QACF;QACA,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE;AACpC,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC;YACpC;QACF;AACA,QAAA,MAAM,OAAO,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAW;AAChE,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IAChE;AAEA,IAAA,MAAM,MAAM,GAAA;QACV,IAAI,QAAQ,GAAG,CAAC;AAChB,QAAA,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE;AACvD,YAAA,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;AAC9B,gBAAA,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC;AACjD,gBAAA,QAAQ,EAAE;gBACV;YACF;AACA,YAAA,IAAI;AACF,gBAAA,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACvD,gBAAA,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC;AAC/C,gBAAA,QAAQ,EAAE;YACZ;AAAE,YAAA,MAAM;;;YAGR;QACF;AACA,QAAA,OAAO,QAAQ;IACjB;IAEA,aAAa,GAAA;AACX,QAAA,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;IAC1D;AACD;AAED;;;;;AAKG;AACG,SAAU,2BAA2B,CACzC,OAAA,GAA0D,EAAE,EAAA;IAE5D,OAAO,IAAI,yBAAyB,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,EAAE,CAAC;AAC3E;;;;"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { dirname, basename } from 'path';
|
|
2
|
-
import { tool } from '@langchain/core/tools';
|
|
3
2
|
import { createTwoFilesPatch } from 'diff';
|
|
4
|
-
import {
|
|
3
|
+
import { tool } from '@langchain/core/tools';
|
|
5
4
|
import { createLocalProgrammaticToolCallingTool, createLocalBashProgrammaticToolCallingTool } from './LocalProgrammaticToolCalling.mjs';
|
|
6
5
|
import { getWorkspaceFS, resolveWorkspacePathSafe, spawnLocalProcess, getSpawn, truncateLocalOutput } from './LocalExecutionEngine.mjs';
|
|
6
|
+
import { createLocalBashExecutionTool, createLocalCodeExecutionTool } from './LocalExecutionTools.mjs';
|
|
7
|
+
import { createCompileCheckToolDefinition, createCompileCheckTool } from './CompileCheckTool.mjs';
|
|
8
|
+
import { classifyAttachment, imageAttachmentContent } from './attachments.mjs';
|
|
7
9
|
import { createLocalFileCheckpointer } from './FileCheckpointer.mjs';
|
|
8
10
|
import { locateEdit, applyEdit } from './editStrategies.mjs';
|
|
9
11
|
import { decodeFile, encodeFile } from './textEncoding.mjs';
|
|
10
|
-
import { classifyAttachment, imageAttachmentContent } from './attachments.mjs';
|
|
11
12
|
import { runPostEditSyntaxCheck } from './syntaxCheck.mjs';
|
|
12
|
-
import { createCompileCheckToolDefinition, createCompileCheckTool } from './CompileCheckTool.mjs';
|
|
13
13
|
import { Constants } from '../../common/enum.mjs';
|
|
14
14
|
|
|
15
15
|
const MAX_READ_CHARS = 256000;
|
|
@@ -576,7 +576,7 @@ async function isRipgrepAvailable(config) {
|
|
|
576
576
|
let probePromise = envMap.get(envKey);
|
|
577
577
|
if (probePromise == null) {
|
|
578
578
|
probePromise = spawnLocalProcess('rg', ['--version'], { ...config, timeoutMs: 5000, sandbox: { enabled: false } }, { internal: true })
|
|
579
|
-
.then((probe) => probe
|
|
579
|
+
.then((probe) => probe.exitCode === 0)
|
|
580
580
|
.catch(() => false);
|
|
581
581
|
envMap.set(envKey, probePromise);
|
|
582
582
|
}
|
|
@@ -778,10 +778,22 @@ function compileFallbackRegex(pattern) {
|
|
|
778
778
|
throw new FallbackGrepError('invalid-pattern', `Invalid regex: ${e.message}`);
|
|
779
779
|
}
|
|
780
780
|
}
|
|
781
|
+
/** Renders fallback-grep output: real matches first, skip diagnostics appended. */
|
|
782
|
+
function formatFallbackGrepDisplay(result) {
|
|
783
|
+
if (result.matches.length > 0) {
|
|
784
|
+
return [...result.matches, ...result.skipped].join('\n');
|
|
785
|
+
}
|
|
786
|
+
if (result.skipped.length > 0) {
|
|
787
|
+
return result.skipped.join('\n');
|
|
788
|
+
}
|
|
789
|
+
return 'No matches found.';
|
|
790
|
+
}
|
|
781
791
|
async function fallbackGrep(root, pattern, globFilter, maxResults, fs) {
|
|
782
792
|
const rx = compileFallbackRegex(pattern);
|
|
783
793
|
const deadline = Date.now() + FALLBACK_GREP_BUDGET_MS;
|
|
784
|
-
const globRx = globFilter != null && globFilter !== ''
|
|
794
|
+
const globRx = globFilter != null && globFilter !== ''
|
|
795
|
+
? globToRegExp(globFilter)
|
|
796
|
+
: undefined;
|
|
785
797
|
const matches = [];
|
|
786
798
|
// Track skipped (oversize) files separately so they don't consume
|
|
787
799
|
// the maxResults budget. Codex P2 [43]: round 14's fix pushed skip
|
|
@@ -798,7 +810,9 @@ async function fallbackGrep(root, pattern, globFilter, maxResults, fs) {
|
|
|
798
810
|
return { matches, skipped: skippedDiagnostics };
|
|
799
811
|
}
|
|
800
812
|
if (globRx != null) {
|
|
801
|
-
const rel = file.startsWith(root + '/')
|
|
813
|
+
const rel = file.startsWith(root + '/')
|
|
814
|
+
? file.slice(root.length + 1)
|
|
815
|
+
: file;
|
|
802
816
|
if (!globRx.test(rel)) {
|
|
803
817
|
continue;
|
|
804
818
|
}
|
|
@@ -850,7 +864,9 @@ async function fallbackGlob(root, pattern, maxResults, fs) {
|
|
|
850
864
|
const rx = globToRegExp(pattern);
|
|
851
865
|
const out = [];
|
|
852
866
|
for await (const file of walkFiles(root, fs)) {
|
|
853
|
-
const rel = file.startsWith(root + '/')
|
|
867
|
+
const rel = file.startsWith(root + '/')
|
|
868
|
+
? file.slice(root.length + 1)
|
|
869
|
+
: file;
|
|
854
870
|
if (rx.test(rel)) {
|
|
855
871
|
out.push(file);
|
|
856
872
|
if (out.length >= maxResults) {
|
|
@@ -879,7 +895,9 @@ function createLocalGrepSearchTool(config = {}) {
|
|
|
879
895
|
'--hidden',
|
|
880
896
|
'--glob',
|
|
881
897
|
'!.git/**',
|
|
882
|
-
...(input.glob != null && input.glob !== ''
|
|
898
|
+
...(input.glob != null && input.glob !== ''
|
|
899
|
+
? ['--glob', input.glob]
|
|
900
|
+
: []),
|
|
883
901
|
'-e',
|
|
884
902
|
input.pattern,
|
|
885
903
|
target,
|
|
@@ -896,7 +914,8 @@ function createLocalGrepSearchTool(config = {}) {
|
|
|
896
914
|
// got from P2 #13), exit-2 errors silently mapped to
|
|
897
915
|
// `matches: 0`, so the agent treated tooling failures as a
|
|
898
916
|
// genuine absence of matches.
|
|
899
|
-
if (result.timedOut ||
|
|
917
|
+
if (result.timedOut ||
|
|
918
|
+
(result.exitCode != null && result.exitCode > 1)) {
|
|
900
919
|
const detail = result.stderr.trim() || `rg exited ${result.exitCode}`;
|
|
901
920
|
return [
|
|
902
921
|
`grep_search failed: ${detail}`,
|
|
@@ -908,7 +927,10 @@ function createLocalGrepSearchTool(config = {}) {
|
|
|
908
927
|
},
|
|
909
928
|
];
|
|
910
929
|
}
|
|
911
|
-
const lines = result.stdout
|
|
930
|
+
const lines = result.stdout
|
|
931
|
+
.split('\n')
|
|
932
|
+
.filter(Boolean)
|
|
933
|
+
.slice(0, maxResults);
|
|
912
934
|
const output = lines.length > 0
|
|
913
935
|
? lines.join('\n')
|
|
914
936
|
: result.stderr.trim() || 'No matches found.';
|
|
@@ -916,14 +938,9 @@ function createLocalGrepSearchTool(config = {}) {
|
|
|
916
938
|
}
|
|
917
939
|
try {
|
|
918
940
|
const { matches, skipped } = await fallbackGrep(target, input.pattern, input.glob, maxResults, fs);
|
|
919
|
-
// Display: real matches first, skip diagnostics appended.
|
|
920
941
|
// Artifact count: ONLY real matches (Codex P2 [43] —
|
|
921
942
|
// skip sentinels used to inflate the count and the budget).
|
|
922
|
-
const display = matches
|
|
923
|
-
? [...matches, ...skipped].join('\n')
|
|
924
|
-
: skipped.length > 0
|
|
925
|
-
? skipped.join('\n')
|
|
926
|
-
: 'No matches found.';
|
|
943
|
+
const display = formatFallbackGrepDisplay({ matches, skipped });
|
|
927
944
|
return [
|
|
928
945
|
display,
|
|
929
946
|
{
|
|
@@ -961,7 +978,15 @@ function createLocalGlobSearchTool(config = {}) {
|
|
|
961
978
|
const target = await resolveWorkspacePathSafe(input.path ?? '.', config, 'read');
|
|
962
979
|
const maxResults = Math.max(input.max_results ?? DEFAULT_MAX_RESULTS, 1);
|
|
963
980
|
if (await isRipgrepAvailable(config)) {
|
|
964
|
-
const result = await spawnLocalProcess('rg', [
|
|
981
|
+
const result = await spawnLocalProcess('rg', [
|
|
982
|
+
'--files',
|
|
983
|
+
'--hidden',
|
|
984
|
+
'--glob',
|
|
985
|
+
'!.git/**',
|
|
986
|
+
'--glob',
|
|
987
|
+
input.pattern,
|
|
988
|
+
target,
|
|
989
|
+
], { ...config, timeoutMs: config.timeoutMs ?? 30000 });
|
|
965
990
|
// rg --files exit codes:
|
|
966
991
|
// 0 → at least one file matched
|
|
967
992
|
// 1 → no files matched (clean — "No files found.")
|
|
@@ -969,7 +994,8 @@ function createLocalGlobSearchTool(config = {}) {
|
|
|
969
994
|
// Without this branch, exit-2 errors used to silently map to
|
|
970
995
|
// "No files found." — the agent then treats a tooling failure
|
|
971
996
|
// as a real absence of matches.
|
|
972
|
-
if (result.timedOut ||
|
|
997
|
+
if (result.timedOut ||
|
|
998
|
+
(result.exitCode != null && result.exitCode > 1)) {
|
|
973
999
|
const detail = result.stderr.trim() || `rg exited ${result.exitCode}`;
|
|
974
1000
|
return [
|
|
975
1001
|
`glob_search failed: ${detail}`,
|