feat(mcp-client): Integrate new Python structural tools
This commit is contained in:
@@ -7,10 +7,10 @@
|
|||||||
- [x] Task: Implement `py_add_def` core logic. [d044ccb]
|
- [x] Task: Implement `py_add_def` core logic. [d044ccb]
|
||||||
- [x] Task: Implement `py_move_def` core logic. [d044ccb]
|
- [x] Task: Implement `py_move_def` core logic. [d044ccb]
|
||||||
- [x] Task: Implement `py_region_wrap` core logic. [d044ccb]
|
- [x] Task: Implement `py_region_wrap` core logic. [d044ccb]
|
||||||
- [~] Task: Conductor - User Manual Verification 'Phase 1: Core Logic Implementation' (Protocol in workflow.md)
|
- [x] Task: Conductor - User Manual Verification 'Phase 1: Core Logic Implementation' (Protocol in workflow.md) [578d9a2]
|
||||||
|
|
||||||
## Phase 2: MCP Client Integration
|
## Phase 2: MCP Client Integration
|
||||||
- [ ] Task: Register JSON schemas for `py_remove_def`, `py_add_def`, `py_move_def`, and `py_region_wrap` in `src/mcp_client.py`.
|
- [~] Task: Register JSON schemas for `py_remove_def`, `py_add_def`, `py_move_def`, and `py_region_wrap` in `src/mcp_client.py`.
|
||||||
- [ ] Task: Implement dispatch handlers in `src/mcp_client.py` to bridge the native tool calls to the `./scripts/py_struct_tools.py` logic.
|
- [ ] Task: Implement dispatch handlers in `src/mcp_client.py` to bridge the native tool calls to the `./scripts/py_struct_tools.py` logic.
|
||||||
- [ ] Task: Update the `TOOL_NAMES` and `MUTATING_TOOLS` constants to include the new capabilities.
|
- [ ] Task: Update the `TOOL_NAMES` and `MUTATING_TOOLS` constants to include the new capabilities.
|
||||||
- [ ] Task: Conductor - User Manual Verification 'Phase 2: MCP Client Integration' (Protocol in workflow.md)
|
- [ ] Task: Conductor - User Manual Verification 'Phase 2: MCP Client Integration' (Protocol in workflow.md)
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ from src import beads_client
|
|||||||
from src import models
|
from src import models
|
||||||
from src import outline_tool
|
from src import outline_tool
|
||||||
from src import summarize
|
from src import summarize
|
||||||
|
from scripts import py_struct_tools
|
||||||
|
|
||||||
# ------------------------------------------------------------------ mutating tools sentinel
|
# ------------------------------------------------------------------ mutating tools sentinel
|
||||||
|
|
||||||
@@ -80,6 +81,10 @@ MUTATING_TOOLS: frozenset[str] = frozenset({
|
|||||||
"edit_file",
|
"edit_file",
|
||||||
"ts_c_update_definition",
|
"ts_c_update_definition",
|
||||||
"ts_cpp_update_definition",
|
"ts_cpp_update_definition",
|
||||||
|
"py_remove_def",
|
||||||
|
"py_add_def",
|
||||||
|
"py_move_def",
|
||||||
|
"py_region_wrap",
|
||||||
})
|
})
|
||||||
|
|
||||||
# ------------------------------------------------------------------ state
|
# ------------------------------------------------------------------ state
|
||||||
@@ -1351,6 +1356,32 @@ def dispatch(tool_name: str, tool_input: dict[str, Any]) -> str:
|
|||||||
return ts_c_update_definition(path, str(tool_input.get("name", "")), str(tool_input.get("new_content", "")))
|
return ts_c_update_definition(path, str(tool_input.get("name", "")), str(tool_input.get("new_content", "")))
|
||||||
if tool_name == "ts_cpp_update_definition":
|
if tool_name == "ts_cpp_update_definition":
|
||||||
return ts_cpp_update_definition(path, str(tool_input.get("name", "")), str(tool_input.get("new_content", "")))
|
return ts_cpp_update_definition(path, str(tool_input.get("name", "")), str(tool_input.get("new_content", "")))
|
||||||
|
if tool_name == "py_remove_def":
|
||||||
|
return py_struct_tools.py_remove_def(path, str(tool_input.get("name", "")))
|
||||||
|
if tool_name == "py_add_def":
|
||||||
|
return py_struct_tools.py_add_def(
|
||||||
|
path,
|
||||||
|
str(tool_input.get("name", "")),
|
||||||
|
str(tool_input.get("new_content", "")),
|
||||||
|
str(tool_input.get("anchor_type", "")),
|
||||||
|
tool_input.get("anchor_symbol")
|
||||||
|
)
|
||||||
|
if tool_name == "py_move_def":
|
||||||
|
return py_struct_tools.py_move_def(
|
||||||
|
str(tool_input.get("src_path", "")),
|
||||||
|
str(tool_input.get("dest_path", "")),
|
||||||
|
str(tool_input.get("name", "")),
|
||||||
|
str(tool_input.get("dest_name", "")),
|
||||||
|
str(tool_input.get("anchor_type", "")),
|
||||||
|
tool_input.get("anchor_symbol")
|
||||||
|
)
|
||||||
|
if tool_name == "py_region_wrap":
|
||||||
|
return py_struct_tools.py_region_wrap(
|
||||||
|
path,
|
||||||
|
int(tool_input.get("start_line", 1)),
|
||||||
|
int(tool_input.get("end_line", 1)),
|
||||||
|
str(tool_input.get("region_name", ""))
|
||||||
|
)
|
||||||
if tool_name == "py_get_definition":
|
if tool_name == "py_get_definition":
|
||||||
return py_get_definition(path, str(tool_input.get("name", "")))
|
return py_get_definition(path, str(tool_input.get("name", "")))
|
||||||
if tool_name == "py_update_definition":
|
if tool_name == "py_update_definition":
|
||||||
@@ -1468,6 +1499,63 @@ def get_tool_schemas() -> list[dict[str, Any]]:
|
|||||||
# These are imported by ai_client.py to build provider-specific declarations.
|
# These are imported by ai_client.py to build provider-specific declarations.
|
||||||
|
|
||||||
MCP_TOOL_SPECS: list[dict[str, Any]] = [
|
MCP_TOOL_SPECS: list[dict[str, Any]] = [
|
||||||
|
{
|
||||||
|
"name": "py_remove_def",
|
||||||
|
"description": "Excises a specific class or function definition from a Python file using AST-derived line ranges, preserving surrounding formatting and comments.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": { "type": "string", "description": "Path to the .py file." },
|
||||||
|
"name": { "type": "string", "description": "The name of the class or function to remove. Use 'ClassName.method_name' for methods." }
|
||||||
|
},
|
||||||
|
"required": ["path", "name"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "py_add_def",
|
||||||
|
"description": "Inserts a new definition into a specific context (module level or within a specific class).",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": { "type": "string", "description": "Path to the .py file." },
|
||||||
|
"name": { "type": "string", "description": "Context path (e.g. 'ClassName' or empty for module level)." },
|
||||||
|
"new_content": { "type": "string", "description": "The code to insert." },
|
||||||
|
"anchor_type": { "type": "string", "enum": ["before", "after", "top", "bottom"], "description": "Where to insert relative to the anchor." },
|
||||||
|
"anchor_symbol": { "type": "string", "description": "Symbol name to anchor to if anchor_type is 'before' or 'after'." }
|
||||||
|
},
|
||||||
|
"required": ["path", "name", "new_content", "anchor_type"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "py_move_def",
|
||||||
|
"description": "Relocates a definition within a file or across different Python files.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"src_path": { "type": "string", "description": "Path to the source .py file." },
|
||||||
|
"dest_path": { "type": "string", "description": "Path to the destination .py file." },
|
||||||
|
"name": { "type": "string", "description": "The name of the class or function to move." },
|
||||||
|
"dest_name": { "type": "string", "description": "Context path in destination file (e.g. 'ClassName' or empty)." },
|
||||||
|
"anchor_type": { "type": "string", "enum": ["before", "after", "top", "bottom"], "description": "Where to insert in destination." },
|
||||||
|
"anchor_symbol": { "type": "string", "description": "Anchor symbol in destination." }
|
||||||
|
},
|
||||||
|
"required": ["src_path", "dest_path", "name", "dest_name", "anchor_type"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "py_region_wrap",
|
||||||
|
"description": "Wraps a specified block of code (e.g., a set of methods) in #region: Name and #endregion: Name tags.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": { "type": "string", "description": "Path to the .py file." },
|
||||||
|
"start_line": { "type": "integer", "description": "1-based start line number." },
|
||||||
|
"end_line": { "type": "integer", "description": "1-based end line number (inclusive)." },
|
||||||
|
"region_name": { "type": "string", "description": "The name of the region." }
|
||||||
|
},
|
||||||
|
"required": ["path", "start_line", "end_line", "region_name"]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "read_file",
|
"name": "read_file",
|
||||||
"description": (
|
"description": (
|
||||||
|
|||||||
Reference in New Issue
Block a user