Orchestrates LLM-driven plan execution with mcp-cli integration. Each step is executed by the LLM: given the step description and tool schemas, the LLM generates the actual tool call (with correct parameter names and values). If a tool fails, the error is fed back to the LLM which c
| 95 | |
| 96 | |
| 97 | class PlanRunner: |
| 98 | """Orchestrates LLM-driven plan execution with mcp-cli integration. |
| 99 | |
| 100 | Each step is executed by the LLM: given the step description and tool |
| 101 | schemas, the LLM generates the actual tool call (with correct parameter |
| 102 | names and values). If a tool fails, the error is fed back to the LLM |
| 103 | which can retry with corrected arguments. |
| 104 | |
| 105 | Features: |
| 106 | - LLM-driven tool call generation with tool schemas |
| 107 | - Automatic retry on failure with LLM error correction |
| 108 | - Parallel batch execution for independent steps (topological batching) |
| 109 | - Progress callbacks for terminal/dashboard display |
| 110 | - Dry-run mode (trace without executing) |
| 111 | - Execution checkpointing and resume |
| 112 | - DAG visualization |
| 113 | """ |
| 114 | |
| 115 | def __init__( |
| 116 | self, |
| 117 | context: PlanningContext, |
| 118 | *, |
| 119 | model_manager: ModelManagerProtocol | None = None, |
| 120 | on_step_start: Callable[[str, str, str], None] | None = None, |
| 121 | on_step_complete: Callable[[StepResult], None] | None = None, |
| 122 | on_tool_start: ToolStartCallback | None = None, |
| 123 | on_tool_complete: ToolCompleteCallback | None = None, |
| 124 | enable_guards: bool = False, |
| 125 | max_concurrency: int = DEFAULT_PLAN_MAX_CONCURRENCY, |
| 126 | max_step_retries: int = DEFAULT_PLAN_MAX_STEP_RETRIES, |
| 127 | ) -> None: |
| 128 | """Initialize the plan runner. |
| 129 | |
| 130 | Args: |
| 131 | context: PlanningContext with tool_manager and graph_store. |
| 132 | model_manager: ModelManager for LLM-driven step execution. |
| 133 | When provided, the LLM generates tool calls from step |
| 134 | descriptions and can retry on failure with error feedback. |
| 135 | on_step_start: Callback(step_index, step_title, tool_name) before each step. |
| 136 | on_step_complete: Callback(StepResult) after each step. |
| 137 | on_tool_start: Async callback(tool_name, arguments) before each tool call |
| 138 | within a step. Called for each agentic loop tool invocation. |
| 139 | on_tool_complete: Async callback(tool_name, result_str, success, elapsed) |
| 140 | after each tool call. Called for each agentic loop tool invocation. |
| 141 | enable_guards: If True, enforce guard checks during execution. |
| 142 | max_concurrency: Maximum concurrent steps within a batch. |
| 143 | max_step_retries: Maximum LLM retry attempts per step on failure. |
| 144 | """ |
| 145 | self.context = context |
| 146 | self._model_manager = model_manager |
| 147 | self._on_step_start = on_step_start |
| 148 | self._on_step_complete = on_step_complete |
| 149 | self._on_tool_start = on_tool_start |
| 150 | self._on_tool_complete = on_tool_complete |
| 151 | self._max_concurrency = max_concurrency |
| 152 | self._max_step_retries = max_step_retries |
| 153 | |
| 154 | # Create the MCP tool backend with guard integration |
no outgoing calls