mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-07-15 12:58:04 +00:00
fix(agent): execute fenced tool calls with inline args and bare email tool names
Two bugs made local (Ollama) models unable to use email tools, leaving
raw fences like ```list_email_accounts {}``` in the chat:
1. _TOOL_BLOCK_RE required a newline right after the fence tag, so a
tool call with args on the same line ("```list_email_accounts {}")
never matched and was never executed. The fence now matches with
optional spaces/newline after the tag.
2. Even when parsed, bare email tool names had no dispatch branch in
tool_execution.py and fell through to "Unknown tool type". They now
route to the email MCP server as mcp__email__<name>, matching how
function_call_to_tool_block already maps them for native callers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -767,6 +767,23 @@ async def execute_tool_block(
|
|||||||
elif tool == "vault_unlock":
|
elif tool == "vault_unlock":
|
||||||
desc = "vault_unlock"
|
desc = "vault_unlock"
|
||||||
result = await do_vault_unlock(content, owner=owner)
|
result = await do_vault_unlock(content, owner=owner)
|
||||||
|
elif tool in {"list_email_accounts", "send_email", "list_emails", "read_email",
|
||||||
|
"reply_to_email", "bulk_email", "archive_email", "delete_email",
|
||||||
|
"mark_email_read", "search_emails", "draft_email", "draft_email_reply",
|
||||||
|
"ai_draft_email_reply", "download_attachment"}:
|
||||||
|
# Bare email tool name from fenced-block models (e.g. Ollama) — route to MCP email server
|
||||||
|
mcp = get_mcp_manager()
|
||||||
|
qualified = f"mcp__email__{tool}"
|
||||||
|
if mcp:
|
||||||
|
try:
|
||||||
|
args = json.loads(content) if content.strip().startswith("{") else {}
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
args = {}
|
||||||
|
desc = f"email: {tool}"
|
||||||
|
result = await mcp.call_tool(qualified, args)
|
||||||
|
else:
|
||||||
|
desc = f"email: {tool}"
|
||||||
|
result = {"error": "MCP manager not available", "exit_code": 1}
|
||||||
elif tool.startswith("mcp__"):
|
elif tool.startswith("mcp__"):
|
||||||
# MCP tool dispatch
|
# MCP tool dispatch
|
||||||
mcp = get_mcp_manager()
|
mcp = get_mcp_manager()
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# Pattern 1: ```bash ... ``` fenced code blocks
|
# Pattern 1: ```bash ... ``` fenced code blocks
|
||||||
_TOOL_BLOCK_RE = re.compile(
|
_TOOL_BLOCK_RE = re.compile(
|
||||||
r"```(" + "|".join(TOOL_TAGS) + r")\s*\n([\s\S]*?)```",
|
r"```(" + "|".join(TOOL_TAGS) + r")[ \t]*\n?([\s\S]*?)```",
|
||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user