(text: &str)
| 308 | // ======================================================================== |
| 309 | |
| 310 | fn parse_plan_response(text: &str) -> Result<ExecutionPlan> { |
| 311 | let parsed: PlanResponse = Self::parse_json_lenient(text) |
| 312 | .context("Failed to parse plan JSON from LLM response")?; |
| 313 | |
| 314 | let complexity = match parsed.complexity.as_str() { |
| 315 | "Simple" => Complexity::Simple, |
| 316 | "Medium" => Complexity::Medium, |
| 317 | "Complex" => Complexity::Complex, |
| 318 | "VeryComplex" => Complexity::VeryComplex, |
| 319 | _ => Complexity::Medium, |
| 320 | }; |
| 321 | |
| 322 | let mut plan = ExecutionPlan::new(parsed.goal, complexity); |
| 323 | |
| 324 | for step_resp in parsed.steps { |
| 325 | let mut task = Task::new(step_resp.id, step_resp.description); |
| 326 | if let Some(tool) = step_resp.tool { |
| 327 | task = task.with_tool(tool); |
| 328 | } |
| 329 | if !step_resp.dependencies.is_empty() { |
| 330 | task = task.with_dependencies(step_resp.dependencies); |
| 331 | } |
| 332 | if let Some(criteria) = step_resp.success_criteria { |
| 333 | task = task.with_success_criteria(criteria); |
| 334 | } |
| 335 | plan.add_step(task); |
| 336 | } |
| 337 | |
| 338 | for tool in parsed.required_tools { |
| 339 | plan.add_required_tool(tool); |
| 340 | } |
| 341 | |
| 342 | Ok(plan) |
| 343 | } |
| 344 | |
| 345 | fn parse_goal_response(text: &str) -> Result<AgentGoal> { |
| 346 | let parsed: GoalResponse = Self::parse_json_lenient(text) |
nothing calls this directly
no test coverage detected