From 1c0967c4ec1d3df8914afe257b070ce521ab4b83 Mon Sep 17 00:00:00 2001 From: ProofOfConcept Date: Sat, 11 Apr 2026 19:43:24 -0400 Subject: [PATCH] Agent::new: tool definitions from caller's tool list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The system prompt was advertising all tools to every agent, but the runtime only dispatched the agent's actual subset. This caused unconscious agents to call tools that returned "Unknown tool." Agent::new now takes the tool list explicitly. Each caller passes its own tools — the prompt and runtime always match. MCP tool definitions are still appended for agents that use them. Co-Authored-By: Proof of Concept --- src/agent/mod.rs | 7 +++++-- src/agent/oneshot.rs | 1 + src/agent/tools/mod.rs | 4 ++++ src/mind/mod.rs | 1 + src/mind/unconscious.rs | 2 +- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/agent/mod.rs b/src/agent/mod.rs index e371a53..349fe91 100644 --- a/src/agent/mod.rs +++ b/src/agent/mod.rs @@ -192,12 +192,15 @@ impl Agent { prompt_file: String, conversation_log: Option, active_tools: tools::ActiveTools, + agent_tools: Vec, ) -> Arc { let mut context = ContextState::new(); context.conversation_log = conversation_log; context.push_no_log(Section::System, AstNode::system_msg(&system_prompt)); - let tool_defs = tools::all_tool_definitions().await; + let mut tool_defs: Vec = agent_tools.iter().map(|t| t.to_json()).collect(); + tool_defs.extend(tools::all_mcp_tool_definitions().await); + if !tool_defs.is_empty() { let tools_text = format!( "# Tools\n\nYou have access to the following functions:\n\n\n{}\n\n\n\ @@ -223,7 +226,7 @@ impl Agent { session_id, context: tokio::sync::Mutex::new(context), state: tokio::sync::Mutex::new(AgentState { - tools: tools::tools(), + tools: agent_tools, mcp_tools: McpToolAccess::All, last_prompt_tokens: 0, reasoning_effort: "none".to_string(), diff --git a/src/agent/oneshot.rs b/src/agent/oneshot.rs index cc590bb..9a2fed9 100644 --- a/src/agent/oneshot.rs +++ b/src/agent/oneshot.rs @@ -138,6 +138,7 @@ impl AutoAgent { app, String::new(), None, super::tools::ActiveTools::new(), + super::tools::tools(), ).await; { let mut st = agent.state.lock().await; diff --git a/src/agent/tools/mod.rs b/src/agent/tools/mod.rs index ce42c9e..b873a11 100644 --- a/src/agent/tools/mod.rs +++ b/src/agent/tools/mod.rs @@ -195,6 +195,10 @@ pub async fn all_tool_definitions() -> Vec { defs } +pub async fn all_mcp_tool_definitions() -> Vec { + mcp_client::tool_definitions_json().await +} + /// Memory + journal tools only — for subconscious agents. pub fn memory_and_journal_tools() -> Vec { let mut all = memory::memory_tools().to_vec(); diff --git a/src/mind/mod.rs b/src/mind/mod.rs index 010829f..38e8fdf 100644 --- a/src/mind/mod.rs +++ b/src/mind/mod.rs @@ -298,6 +298,7 @@ impl Mind { config.prompt_file.clone(), conversation_log, crate::agent::tools::ActiveTools::new(), + crate::agent::tools::tools(), ).await; let shared = Arc::new(std::sync::Mutex::new(MindState::new(config.app.dmn.max_turns))); diff --git a/src/mind/unconscious.rs b/src/mind/unconscious.rs index 0f87b17..8b4af40 100644 --- a/src/mind/unconscious.rs +++ b/src/mind/unconscious.rs @@ -282,11 +282,11 @@ impl Unconscious { client, system_prompt, personality, app, String::new(), None, crate::agent::tools::ActiveTools::new(), + auto.tools.clone(), ).await; { let mut st = agent.state.lock().await; st.provenance = format!("unconscious:{}", auto.name); - st.tools = auto.tools.clone(); st.priority = Some(10); }