Interactive REPL mode. Reads tasks from stdin. Special commands: /plan — run task in plan mode (decompose → generate YAML plans → execute) exit — quit the loop
(self)
| 175 | return result |
| 176 | |
| 177 | def run_interactive(self) -> None: |
| 178 | """Interactive REPL mode. Reads tasks from stdin. |
| 179 | |
| 180 | Special commands: |
| 181 | /plan <task> — run task in plan mode (decompose → generate YAML plans → execute) |
| 182 | exit — quit the loop |
| 183 | """ |
| 184 | self._setup() |
| 185 | print( |
| 186 | "AgentSPEX Agentic Loop (type '/exit' to quit, '/plan <task>' for plan mode)" |
| 187 | ) |
| 188 | |
| 189 | while True: |
| 190 | print() |
| 191 | self.logger.rule() |
| 192 | try: |
| 193 | user_input = pt_prompt( |
| 194 | "> ", lexer=_SlashCommandLexer(), style=_PROMPT_STYLE |
| 195 | ).strip() |
| 196 | except (EOFError, KeyboardInterrupt): |
| 197 | print("\nExiting.") |
| 198 | break |
| 199 | |
| 200 | if user_input.lower() in ("/exit", "/quit", "/q"): |
| 201 | break |
| 202 | if not user_input: |
| 203 | continue |
| 204 | |
| 205 | self.logger.rule() |
| 206 | print() |
| 207 | |
| 208 | if user_input.startswith("/plan "): |
| 209 | task = user_input[len("/plan ") :].strip() |
| 210 | if not task: |
| 211 | print("Usage: /plan <task description>") |
| 212 | continue |
| 213 | self.logger.event("user_message", {"content": user_input}) |
| 214 | result = self._run_plan_mode(task) |
| 215 | self.logger.event("loop_end", self.session.get_usage_summary()) |
| 216 | continue |
| 217 | |
| 218 | self.session.add_user_message(user_input) |
| 219 | self._inner_loop() |
| 220 | |
| 221 | self.logger.event("loop_end", self.session.get_usage_summary()) |
| 222 | |
| 223 | def _setup(self) -> None: |
| 224 | """Initialize MCP tools, orchestrator tools, plan generator, and system prompt.""" |
no test coverage detected