mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-27 21:05:34 +00:00
feat(executor): pull SystemBuilder MCP tools into agent's tool list
The AgentExecutor builds agents from a template's `tools` whitelist by resolving each name against the static `ToolRegistry`. External MCP tools (discovered at SystemBuilder.build() time via _discover_external_mcp) were never picked up — they exist on system.tool_executor._tools but the per-agent build path never read from there. Result: any agent whose template declared MCP tool names by name got 0 of them at runtime, falling back to natives only. The agent's system prompt could still mention the tools, but the model could not call them (only shell_exec or other native fallbacks were available). This adds a fallback after the ToolRegistry loop: for any tool name not resolved from the registry, look it up in system.tool_executor._tools and append the already-instantiated MCP adapter. Native tools still take precedence (same name, the registry hit wins). Verified by configuring a CyberStrikeAI stdio MCP server (78 tools). Before this patch: agent built with 4 tools. After: 4 native + 78 MCP.
This commit is contained in:
committed by
krypticmouse
parent
c8f1b3c54a
commit
4c37aa83df
@@ -317,6 +317,21 @@ class AgentExecutor:
|
||||
tool_instances.append(tool)
|
||||
except Exception:
|
||||
logger.warning("Failed to instantiate tool %s", tname)
|
||||
|
||||
# Pull tools already discovered by SystemBuilder (e.g. external MCP
|
||||
# adapters) that aren't in the static ToolRegistry. Without this,
|
||||
# agents declaring MCP-discovered tools in their template would
|
||||
# silently fall back to natives only.
|
||||
if self._system is not None and getattr(self._system, "tool_executor", None) is not None:
|
||||
mcp_pool = getattr(self._system.tool_executor, "_tools", {}) or {}
|
||||
existing = {t.spec.name for t in tool_instances}
|
||||
for tname in tool_names:
|
||||
if tname in existing:
|
||||
continue
|
||||
pooled = mcp_pool.get(tname)
|
||||
if pooled is not None:
|
||||
tool_instances.append(pooled)
|
||||
|
||||
if tool_instances:
|
||||
logger.info(
|
||||
"Agent %s: resolved %d/%d tools",
|
||||
@@ -332,6 +347,12 @@ class AgentExecutor:
|
||||
agent_kwargs["system_prompt"] = sys_prompt
|
||||
if getattr(agent_cls, "accepts_tools", False) and tool_instances:
|
||||
agent_kwargs["tools"] = tool_instances
|
||||
# Propagate confirmation policy from the AgentExecutor down to the
|
||||
# agent's own ToolExecutor. Set by CLI paths like `jarvis agents ask`
|
||||
# so non-interactive runs can auto-approve tool execution.
|
||||
if getattr(self, "_confirm_callback", None) is not None:
|
||||
agent_kwargs["interactive"] = True
|
||||
agent_kwargs["confirm_callback"] = self._confirm_callback
|
||||
try:
|
||||
agent_instance = agent_cls(engine, model, **agent_kwargs)
|
||||
except TypeError:
|
||||
|
||||
Reference in New Issue
Block a user