Bridge between the agentic loop and the AgentSPEX workflow engine. Given a verified YAML plan file, loads it, creates a fresh Interpreter, and executes all workflow steps. Returns the final output string to the orchestrator for synthesis. The Interpreter handles all step types (tas
| 63 | |
| 64 | |
| 65 | class PlanExecutor: |
| 66 | """Bridge between the agentic loop and the AgentSPEX workflow engine. |
| 67 | |
| 68 | Given a verified YAML plan file, loads it, creates a fresh Interpreter, |
| 69 | and executes all workflow steps. Returns the final output string to the |
| 70 | orchestrator for synthesis. |
| 71 | |
| 72 | The Interpreter handles all step types (task, step, for_each, if, while, |
| 73 | switch, call, parallel, gather, set_variable, increment, input, return) |
| 74 | and manages its own conversation history and tool calling within each step. |
| 75 | |
| 76 | Shares the same MCPClient and LLMClient as the agentic loop to avoid |
| 77 | duplicate connections and ensure sandbox state is consistent. |
| 78 | A fresh Interpreter is created per execution to avoid state leakage |
| 79 | between plan runs. |
| 80 | """ |
| 81 | |
| 82 | def __init__( |
| 83 | self, |
| 84 | mcp_client: MCPClient, |
| 85 | llm_client: LLMClient, |
| 86 | logger: Logger, |
| 87 | output_dir: str, |
| 88 | ): |
| 89 | """Initialize the plan executor. |
| 90 | |
| 91 | Args: |
| 92 | mcp_client: Shared MCP client (same instance as the agentic loop |
| 93 | uses for its own tool calls). |
| 94 | llm_client: Shared LLM client (same instance as the agentic loop). |
| 95 | logger: Logger for execution events (plan_execution_start/end/error). |
| 96 | output_dir: Base output directory. Plan outputs go to |
| 97 | {output_dir}/plan_outputs/{task_name}/. |
| 98 | """ |
| 99 | self.mcp_client = mcp_client |
| 100 | self.llm_client = llm_client |
| 101 | self.logger = logger |
| 102 | self.output_dir = output_dir |
| 103 | self._parser = YAMLTaskParser() |
| 104 | |
| 105 | def execute( |
| 106 | self, |
| 107 | plan_path: Path, |
| 108 | model: Optional[str] = None, |
| 109 | ) -> ExecutionResult: |
| 110 | """Load and execute a YAML plan through the Interpreter. |
| 111 | |
| 112 | Args: |
| 113 | plan_path: Path to the verified YAML plan file. |
| 114 | model: Optional model override for execution. If provided, |
| 115 | takes precedence over the plan's config.model. If not |
| 116 | provided, the plan's config.model is used (or the |
| 117 | EffectiveArgs default of gpt-4.1-mini). |
| 118 | |
| 119 | Returns: |
| 120 | ExecutionResult with the output text, success flag, step |
| 121 | counts, any errors, the parsed plan data (for health |
| 122 | assessment), and token/cost usage. |