| 177 | """ |
| 178 | |
| 179 | def handle_generate_plan(args: dict) -> str: |
| 180 | task_id = args["task_id"] |
| 181 | task = task_board.get_task(task_id) |
| 182 | if not task: |
| 183 | return f"Error: Task {task_id} not found on the task board." |
| 184 | |
| 185 | # 1. Generate — pass all orchestrator-provided context to the plan generator |
| 186 | try: |
| 187 | plan_path = plan_generator.generate( |
| 188 | task_id=task_id, |
| 189 | task_description=args["task_description"], |
| 190 | context_summary=args.get("context_summary"), |
| 191 | hints=args.get("hints"), |
| 192 | recommended_tools=args.get("recommended_tools"), |
| 193 | ) |
| 194 | except ValueError as e: |
| 195 | return f"Error generating plan: {e}" |
| 196 | |
| 197 | task_board.update_task(task_id, plan_file=str(plan_path)) |
| 198 | |
| 199 | # 2. Verify automatically |
| 200 | result = verifier.verify(plan_path) |
| 201 | task_board.update_task(task_id, plan_verified=result.is_valid) |
| 202 | |
| 203 | if not result.is_valid: |
| 204 | return ( |
| 205 | f"Plan generated at {plan_path} but verification FAILED: " |
| 206 | f"{result.summary()}" |
| 207 | ) |
| 208 | |
| 209 | # 3. Show full YAML to user and ask for approval |
| 210 | yaml_content = Path(plan_path).read_text(encoding="utf-8") |
| 211 | approval = user_input_fn( |
| 212 | f"Plan generated and verified for {task_id}. Approve?\n\n" |
| 213 | f"```yaml\n{yaml_content}\n```", |
| 214 | ["Yes, approve", "No, reject"], |
| 215 | ) |
| 216 | approved = approval.lower() in ("yes", "yes, approve", "y", "1") |
| 217 | if approved: |
| 218 | return ( |
| 219 | f"Plan generated, verified, and APPROVED.\n" |
| 220 | f"Path: {plan_path}\n\n```yaml\n{yaml_content}\n```" |
| 221 | ) |
| 222 | else: |
| 223 | task_board.update_task(task_id, plan_verified=False) |
| 224 | return f"Plan generated and verified, but REJECTED by user. Feedback: {approval}" |
| 225 | |
| 226 | return [ |
| 227 | OrchestratorTool( |