mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-16 09:45:24 -04:00
Merge pull request #2529 from NubsCarson/codex/2509-mcp-tool-input-params
fix(mcp): expose MCP tool input parameters to the agent
This commit is contained in:
@@ -38,6 +38,7 @@ try:
|
||||
_detect_admin_intent,
|
||||
_compute_final_metrics,
|
||||
_append_tool_results,
|
||||
_MCP_KEYWORDS,
|
||||
)
|
||||
_IMPORTED_AGENT_LOOP = sys.modules.get("src.agent_loop")
|
||||
finally:
|
||||
@@ -57,6 +58,10 @@ def test_import_stubs_do_not_leak_into_later_tests():
|
||||
assert sys.modules.get("src.agent_loop") is not _IMPORTED_AGENT_LOOP
|
||||
|
||||
|
||||
def test_mcp_keyword_gate_matches_literal_mcp_requests():
|
||||
assert "mcp" in _MCP_KEYWORDS
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _detect_admin_intent
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
"""Regression for issue #2509 — MCP tools must expose their input parameters.
|
||||
|
||||
``McpManager.get_tool_descriptions_for_prompt()`` previously emitted only
|
||||
``- name: description`` per MCP tool, so agents (notably on the fenced-block
|
||||
tool path used by Ollama models) never saw a tool's declared inputs and guessed
|
||||
argument names from the description alone. ``get_all_tools()`` also dropped the
|
||||
``input_schema`` entirely. These tests pin that the inputs now reach both
|
||||
surfaces.
|
||||
"""
|
||||
|
||||
from src.mcp_manager import McpManager
|
||||
|
||||
|
||||
def _mgr_with_tool() -> McpManager:
|
||||
mgr = McpManager()
|
||||
mgr._tools = {
|
||||
"srv1": [
|
||||
{
|
||||
"name": "fetch_doc",
|
||||
"description": "Fetch a document by path.",
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {"type": "string", "description": "file path"},
|
||||
"limit": {"type": "integer"},
|
||||
},
|
||||
"required": ["path"],
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
mgr._connections = {"srv1": {"status": "connected", "name": "Files", "identity": ""}}
|
||||
return mgr
|
||||
|
||||
|
||||
def test_get_all_tools_carries_input_schema():
|
||||
tools = _mgr_with_tool().get_all_tools()
|
||||
assert tools and tools[0]["input_schema"]["properties"]["path"]["type"] == "string"
|
||||
|
||||
|
||||
def test_prompt_descriptions_surface_param_names_and_required():
|
||||
text = _mgr_with_tool().get_tool_descriptions_for_prompt()
|
||||
assert "mcp__srv1__fetch_doc" in text
|
||||
assert "path" in text and "limit" in text # inputs are surfaced to the model
|
||||
assert "required" in text # required-ness is surfaced
|
||||
|
||||
|
||||
def test_format_mcp_params_handles_no_params():
|
||||
from src.mcp_manager import _format_mcp_params
|
||||
|
||||
assert _format_mcp_params({}) == ""
|
||||
assert _format_mcp_params(None) == ""
|
||||
assert _format_mcp_params({"type": "object", "properties": {}}) == ""
|
||||
|
||||
|
||||
def test_format_mcp_params_marks_required_and_types():
|
||||
from src.mcp_manager import _format_mcp_params
|
||||
|
||||
out = _format_mcp_params(
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {"q": {"type": "string"}, "n": {"type": "integer"}},
|
||||
"required": ["q"],
|
||||
}
|
||||
)
|
||||
assert '"q": string (required)' in out
|
||||
assert '"n": integer' in out
|
||||
assert '"n": integer (required)' not in out # optional param not marked required
|
||||
Reference in New Issue
Block a user