Skip to main content

codetether_agent/agent/execution/
run.rs

1//! Prompt loop for agent execution.
2//!
3//! This module implements the outer completion loop that alternates between
4//! provider responses and tool execution until the model stops calling tools.
5//!
6//! # Examples
7//!
8//! ```ignore
9//! let response = agent.execute(&mut session, "inspect").await?;
10//! ```
11
12use super::messages::{collect_tool_calls, response_text};
13use crate::agent::{Agent, AgentResponse};
14use crate::provider::{ContentPart, Message, Role};
15use crate::session::Session;
16use anyhow::{Result, bail};
17
18impl Agent {
19    /// Executes a prompt against the agent until the run completes or max-steps is hit.
20    ///
21    /// The agent appends the prompt to the session, loops through tool calls,
22    /// and returns the final assistant text plus recorded usage data.
23    ///
24    /// # Examples
25    ///
26    /// ```ignore
27    /// let response = agent.execute(&mut session, "review this file").await?;
28    /// ```
29    pub async fn execute(&self, session: &mut Session, prompt: &str) -> Result<AgentResponse> {
30        session.add_message(Message {
31            role: Role::User,
32            content: vec![ContentPart::Text {
33                text: prompt.to_string(),
34            }],
35        });
36        let max_steps = self.info.max_steps.unwrap_or(100);
37        for _step in 1..=max_steps {
38            let response = self
39                .provider
40                .complete(self.build_completion_request(session))
41                .await?;
42            session.add_message(response.message.clone());
43            let tool_calls = collect_tool_calls(&response.message);
44            if tool_calls.is_empty() {
45                return Ok(AgentResponse {
46                    text: response_text(&response.message),
47                    tool_uses: session.tool_uses.clone(),
48                    usage: session.usage.clone(),
49                });
50            }
51            self.execute_tool_calls(session, tool_calls).await;
52        }
53        bail!("Exceeded maximum steps ({max_steps})");
54    }
55}