|
16 | 16 | from ripperdoc import __version__ |
17 | 17 | from ripperdoc.core.agents import load_agent_definitions |
18 | 18 | from ripperdoc.cli.commands import list_custom_commands, list_slash_commands |
| 19 | +from ripperdoc.core import tool_defaults as tool_defaults_module |
19 | 20 | from ripperdoc.core.config import ( |
20 | 21 | ProtocolType, |
21 | 22 | get_effective_model_profile, |
|
31 | 32 | from ripperdoc.core.output_styles import load_all_output_styles, resolve_output_style |
32 | 33 | from ripperdoc.core.plugins import discover_plugins, set_runtime_plugin_dirs |
33 | 34 | from ripperdoc.core.system_prompt_overrides import select_base_system_prompt |
34 | | -from ripperdoc.core.tool_defaults import get_default_tools_async |
35 | 35 | from ripperdoc.core.hooks.llm_callback import build_hook_llm_callback |
36 | 36 | from ripperdoc.core.hooks.manager import hook_manager |
37 | 37 | from ripperdoc.core.hooks.state import bind_pending_message_queue, bind_hook_scopes |
|
67 | 67 |
|
68 | 68 | logger = logging.getLogger("ripperdoc.protocol.stdio.handler") |
69 | 69 |
|
| 70 | +# Keep these module-level aliases patchable for tests and other callers that |
| 71 | +# inject deterministic tool lists during stdio initialization. |
| 72 | +get_default_tools = tool_defaults_module.get_default_tools |
| 73 | +get_default_tools_async = tool_defaults_module.get_default_tools_async |
| 74 | +_DEFAULT_SYNC_TOOL_LOADER = tool_defaults_module.get_default_tools |
| 75 | + |
70 | 76 |
|
71 | 77 | class StdioSessionMixin: |
72 | 78 | _pre_plan_mode: str | None |
@@ -114,6 +120,12 @@ async def _load_dynamic_mcp_tools_for_initialize(self) -> list[Any]: |
114 | 120 | raise |
115 | 121 | return await load_dynamic_mcp_tools_async(self._project_path) |
116 | 122 |
|
| 123 | + async def _get_initialize_tools(self) -> list[Any]: |
| 124 | + """Resolve the initialize-time tool list with a patchable sync fallback.""" |
| 125 | + if get_default_tools is not _DEFAULT_SYNC_TOOL_LOADER: |
| 126 | + return list(get_default_tools()) |
| 127 | + return await get_default_tools_async(project_path=self._project_path) |
| 128 | + |
117 | 129 | async def _send_sdk_mcp_message(self, server_name: str, message: dict[str, Any]) -> dict[str, Any]: |
118 | 130 | """Bridge SDK-backed MCP traffic over stdio control requests.""" |
119 | 131 | response = await self._send_control_request( |
@@ -463,7 +475,7 @@ async def _handle_initialize(self, request: dict[str, Any], request_id: str) -> |
463 | 475 | self._tools_list = self._normalize_tool_list(options.get("tools")) |
464 | 476 |
|
465 | 477 | # Get the tool list (apply SDK filters) |
466 | | - tools = await get_default_tools_async(project_path=self._project_path) |
| 478 | + tools = await self._get_initialize_tools() |
467 | 479 | if self._disable_slash_commands: |
468 | 480 | tools = [tool for tool in tools if getattr(tool, "name", None) != "Skill"] |
469 | 481 | tools = self._apply_tool_filters( |
|
0 commit comments