(args: dict)
| 322 | """ |
| 323 | |
| 324 | def handle_execute_plan(args: dict) -> str: |
| 325 | task_id = args["task_id"] |
| 326 | task = task_board.get_task(task_id) |
| 327 | if not task: |
| 328 | return f"Error: Task {task_id} not found on the task board." |
| 329 | |
| 330 | # Guard: must have a generated and approved plan |
| 331 | if not task.plan_file: |
| 332 | return ( |
| 333 | f"Error: Task {task_id} has no plan file. " |
| 334 | "Generate a plan with generate_plan first." |
| 335 | ) |
| 336 | if not task.plan_verified: |
| 337 | return ( |
| 338 | f"Error: Task {task_id} plan is not verified/approved. " |
| 339 | "The plan must be generated and approved before execution." |
| 340 | ) |
| 341 | |
| 342 | plan_path = Path(task.plan_file) |
| 343 | if not plan_path.exists(): |
| 344 | return f"Error: Plan file {task.plan_file} not found on disk." |
| 345 | |
| 346 | # Mark task as in_progress before execution |
| 347 | task_board.update_task(task_id, status="in_progress") |
| 348 | |
| 349 | try: |
| 350 | # Execute the plan in isolation (fresh Interpreter, no orchestrator context) |
| 351 | execution_result = plan_executor.execute( |
| 352 | plan_path=plan_path, |
| 353 | model=args.get("model"), |
| 354 | ) |
| 355 | |
| 356 | # Summarize the raw result using a cheap LLM call — |
| 357 | # only the compact summary enters the orchestrator's context, |
| 358 | # not the full execution output (context isolation pattern) |
| 359 | result_summary = summarize_fn(execution_result.output, task.description) |
| 360 | |
| 361 | status = "completed" if execution_result.success else "failed" |
| 362 | task_board.update_task( |
| 363 | task_id, |
| 364 | status=status, |
| 365 | result_summary=result_summary, |
| 366 | error=( |
| 367 | "; ".join(execution_result.errors[:3]) |
| 368 | if execution_result.errors |
| 369 | else None |
| 370 | ), |
| 371 | ) |
| 372 | |
| 373 | status_line = "successfully" if execution_result.success else "with errors" |
| 374 | error_line = ( |
| 375 | f"Errors: {'; '.join(execution_result.errors[:3])}\n" |
| 376 | if execution_result.errors |
| 377 | else "" |
| 378 | ) |
| 379 | return ( |
| 380 | f"Plan executed {status_line} for {task_id}.\n" |
| 381 | f"Steps: {execution_result.steps_completed}/{execution_result.steps_total}\n" |
nothing calls this directly
no test coverage detected