feat(core): Wire tool toggles to AI provider tool declaration payload

This commit is contained in:
2026-02-23 11:30:36 -05:00
parent 1677d25298
commit 92aa33c6d3
3 changed files with 89 additions and 46 deletions

View File

@@ -286,15 +286,26 @@ def _list_anthropic_models() -> list[str]:
TOOL_NAME = "run_powershell" TOOL_NAME = "run_powershell"
_agent_tools: dict = {}
def set_agent_tools(tools: dict):
global _agent_tools, _CACHED_ANTHROPIC_TOOLS
_agent_tools = tools
_CACHED_ANTHROPIC_TOOLS = None
def _build_anthropic_tools() -> list[dict]: def _build_anthropic_tools() -> list[dict]:
"""Build the full Anthropic tools list: run_powershell + MCP file tools.""" """Build the full Anthropic tools list: run_powershell + MCP file tools."""
mcp_tools = [] mcp_tools = []
for spec in mcp_client.MCP_TOOL_SPECS: for spec in mcp_client.MCP_TOOL_SPECS:
if _agent_tools.get(spec["name"], True):
mcp_tools.append({ mcp_tools.append({
"name": spec["name"], "name": spec["name"],
"description": spec["description"], "description": spec["description"],
"input_schema": spec["parameters"], "input_schema": spec["parameters"],
}) })
tools_list = mcp_tools
if _agent_tools.get(TOOL_NAME, True):
powershell_tool = { powershell_tool = {
"name": TOOL_NAME, "name": TOOL_NAME,
"description": ( "description": (
@@ -316,7 +327,12 @@ def _build_anthropic_tools() -> list[dict]:
}, },
"cache_control": {"type": "ephemeral"}, "cache_control": {"type": "ephemeral"},
} }
return mcp_tools + [powershell_tool] tools_list.append(powershell_tool)
elif tools_list:
# Anthropic requires the LAST tool to have cache_control for the prefix caching to work optimally on tools
tools_list[-1]["cache_control"] = {"type": "ephemeral"}
return tools_list
_ANTHROPIC_TOOLS = _build_anthropic_tools() _ANTHROPIC_TOOLS = _build_anthropic_tools()
@@ -338,6 +354,8 @@ def _gemini_tool_declaration():
# MCP file tools # MCP file tools
for spec in mcp_client.MCP_TOOL_SPECS: for spec in mcp_client.MCP_TOOL_SPECS:
if not _agent_tools.get(spec["name"], True):
continue
props = {} props = {}
for pname, pdef in spec["parameters"].get("properties", {}).items(): for pname, pdef in spec["parameters"].get("properties", {}).items():
props[pname] = types.Schema( props[pname] = types.Schema(
@@ -355,6 +373,7 @@ def _gemini_tool_declaration():
)) ))
# PowerShell tool # PowerShell tool
if _agent_tools.get(TOOL_NAME, True):
declarations.append(types.FunctionDeclaration( declarations.append(types.FunctionDeclaration(
name=TOOL_NAME, name=TOOL_NAME,
description=( description=(
@@ -375,7 +394,7 @@ def _gemini_tool_declaration():
), ),
)) ))
return types.Tool(function_declarations=declarations) return types.Tool(function_declarations=declarations) if declarations else None
def _run_script(script: str, base_dir: str) -> str: def _run_script(script: str, base_dir: str) -> str:

1
gui.py
View File

@@ -1203,6 +1203,7 @@ class App:
if global_sp: combined_sp.append(global_sp.strip()) if global_sp: combined_sp.append(global_sp.strip())
if project_sp: combined_sp.append(project_sp.strip()) if project_sp: combined_sp.append(project_sp.strip())
ai_client.set_custom_system_prompt("\n\n".join(combined_sp)) ai_client.set_custom_system_prompt("\n\n".join(combined_sp))
ai_client.set_agent_tools(self.project.get("agent", {}).get("tools", {}))
temp = dpg.get_value("ai_temperature") if dpg.does_item_exist("ai_temperature") else 0.0 temp = dpg.get_value("ai_temperature") if dpg.does_item_exist("ai_temperature") else 0.0
max_tok = dpg.get_value("ai_max_tokens") if dpg.does_item_exist("ai_max_tokens") else 8192 max_tok = dpg.get_value("ai_max_tokens") if dpg.does_item_exist("ai_max_tokens") else 8192
trunc = dpg.get_value("ai_history_trunc") if dpg.does_item_exist("ai_history_trunc") else 8000 trunc = dpg.get_value("ai_history_trunc") if dpg.does_item_exist("ai_history_trunc") else 8000

View File

@@ -0,0 +1,23 @@
import pytest
from ai_client import set_agent_tools, _build_anthropic_tools
def test_agent_tools_wiring():
# Only enable read_file and run_powershell
agent_tools = {
"run_powershell": True,
"read_file": True,
"list_directory": False,
"search_files": False,
"get_file_summary": False,
"web_search": False,
"fetch_url": False
}
set_agent_tools(agent_tools)
anth_tools = _build_anthropic_tools()
tool_names = [t["name"] for t in anth_tools]
assert "read_file" in tool_names
assert "run_powershell" in tool_names
assert "list_directory" not in tool_names
assert "web_search" not in tool_names