lc_agents/plan_execute/
agent.rs1use std::sync::Arc;
4
5use crate::{AgentError, AgentExecutor, BaseAgent, FunctionCallingAgent};
6use lc_core::language_models::BaseChatModel;
7use lc_core::tools::BaseTool;
8use lc_providers::ProviderError;
9
10use super::plan::StepStatus;
11use super::planner::Planner;
12
13#[derive(Debug, thiserror::Error)]
15pub enum PlanExecuteError {
16 #[error("Planning failed: {0}")]
18 PlanningError(String),
19 #[error("Step execution failed: {0}")]
21 StepExecutionError(String),
22 #[error("Max replans reached: step [{step}] failed: {reason}")]
24 MaxReplansReached { step: String, reason: String },
25 #[error("Plan incomplete after all replans")]
27 PlanIncomplete,
28}
29
30impl From<AgentError> for PlanExecuteError {
31 fn from(e: AgentError) -> Self {
32 PlanExecuteError::StepExecutionError(e.to_string())
33 }
34}
35
36pub struct PlanExecuteAgent {
40 llm: Arc<dyn BaseChatModel<Error = ProviderError> + Send + Sync>,
41 tools: Vec<Arc<dyn BaseTool>>,
42 max_replans: usize,
43}
44
45impl PlanExecuteAgent {
46 pub fn new<L>(llm: L, tools: Vec<Arc<dyn BaseTool>>) -> Self
55 where
56 L: BaseChatModel + Send + Sync + 'static,
57 L::Error: Into<ProviderError>,
58 {
59 Self {
60 llm: lc_providers::wrap_chat_model(llm),
61 tools,
62 max_replans: 2,
63 }
64 }
65
66 pub fn from_arc(
68 llm: Arc<dyn BaseChatModel<Error = ProviderError> + Send + Sync>,
69 tools: Vec<Arc<dyn BaseTool>>,
70 ) -> Self {
71 Self {
72 llm,
73 tools,
74 max_replans: 2,
75 }
76 }
77
78 pub fn with_max_replans(mut self, n: usize) -> Self {
79 self.max_replans = n;
80 self
81 }
82
83 pub async fn run(&self, objective: &str) -> Result<String, PlanExecuteError> {
85 let planner = Planner::new(self.llm.clone());
86 let mut plan = planner
87 .plan(objective)
88 .await
89 .map_err(PlanExecuteError::PlanningError)?;
90
91 for replan_count in 0..=self.max_replans {
92 let pending_ids: Vec<usize> = plan
93 .steps
94 .iter()
95 .filter(|s| s.status == StepStatus::Pending)
96 .map(|s| s.id)
97 .collect();
98
99 let mut failed = false;
100 for step_id in pending_ids {
101 let step = plan.steps.iter_mut().find(|s| s.id == step_id);
102 let step_desc = match step {
103 Some(s) => {
104 s.status = StepStatus::Running;
105 s.description.clone()
106 }
107 None => {
108 continue;
110 }
111 };
112
113 match self.execute_step(&step_desc).await {
114 Ok(result) => plan.mark_completed(step_id, result),
115 Err(e) => {
116 let error_msg = e.to_string();
117 plan.mark_failed(step_id, error_msg.clone());
118 if replan_count < self.max_replans {
119 plan = planner
120 .replan(objective, &step_desc, &error_msg)
121 .await
122 .map_err(PlanExecuteError::PlanningError)?;
123 failed = true;
124 break;
125 } else {
126 return Err(PlanExecuteError::MaxReplansReached {
127 step: step_desc,
128 reason: error_msg,
129 });
130 }
131 }
132 }
133 }
134
135 if !failed && plan.is_complete() {
136 let summary: Vec<String> = plan
137 .steps
138 .iter()
139 .map(|s| {
140 format!(
141 "{}. {}: {}",
142 s.id + 1,
143 s.description,
144 s.result.as_deref().unwrap_or("无结果")
145 )
146 })
147 .collect();
148 return Ok(summary.join("\n"));
149 }
150 }
151 Err(PlanExecuteError::PlanIncomplete)
152 }
153
154 async fn execute_step(&self, step: &str) -> Result<String, PlanExecuteError> {
156 let agent = FunctionCallingAgent::from_arc(self.llm.clone(), self.tools.clone(), None);
157 let executor =
158 AgentExecutor::new(Arc::new(agent) as Arc<dyn BaseAgent>, self.tools.clone())
159 .with_max_iterations(5);
160 executor
161 .invoke(step.to_string())
162 .await
163 .map_err(|e| PlanExecuteError::StepExecutionError(e.to_string()))
164 }
165}