Skip to main content

opi_agent/
loop_types.rs

1//! Types for the agent loop (S6.1, S8.2).
2
3use std::collections::VecDeque;
4use std::sync::{Arc, Mutex};
5
6use crate::message::AgentMessage;
7use crate::tool::Tool;
8use opi_ai::provider::{Provider, ThinkingConfig};
9
10/// Errors that can occur during the agent loop.
11#[derive(Debug, thiserror::Error)]
12pub enum AgentError {
13    #[error("provider error: {0}")]
14    Provider(String),
15    #[error("authentication failed: {0}")]
16    AuthFailed(String),
17    #[error("tool error: {0}")]
18    Tool(String),
19    #[error("hook error: {0}")]
20    Hook(String),
21    #[error("cancelled")]
22    Cancelled,
23    #[error("max turns exceeded ({0})")]
24    MaxTurnsExceeded(u32),
25}
26
27/// Input context for the agent loop.
28pub struct AgentLoopContext {
29    /// The LLM provider.
30    pub provider: Box<dyn Provider>,
31    /// Available tools.
32    pub tools: Vec<Box<dyn Tool>>,
33    /// Initial conversation messages.
34    pub messages: Vec<AgentMessage>,
35    /// Model identifier to use.
36    pub model: String,
37    /// Optional system prompt.
38    pub system: Option<String>,
39    /// Steering queue (high-priority user messages injected before next turn).
40    pub steering_queue: Option<Arc<Mutex<VecDeque<String>>>>,
41    /// Follow-up queue (messages injected when agent would otherwise stop).
42    pub follow_up_queue: Option<Arc<Mutex<VecDeque<String>>>>,
43}
44
45/// Configuration for the agent loop.
46#[derive(Debug, Clone)]
47pub struct AgentLoopConfig {
48    /// Maximum number of turns before stopping.
49    pub max_turns: u32,
50    /// Maximum output tokens per request.
51    pub max_tokens: Option<u64>,
52    /// Sampling temperature.
53    pub temperature: Option<f64>,
54    /// Retry configuration for retryable provider errors.
55    pub retry: Option<opi_ai::retry::RetryConfig>,
56    /// Thinking/reasoning configuration for extended thinking models.
57    pub thinking: Option<ThinkingConfig>,
58}
59
60impl Default for AgentLoopConfig {
61    fn default() -> Self {
62        Self {
63            max_turns: 50,
64            max_tokens: None,
65            temperature: None,
66            retry: None,
67            thinking: None,
68        }
69    }
70}
71
72/// Update returned by `prepare_next_turn` to modify the next turn.
73pub struct AgentLoopTurnUpdate {
74    pub extra_messages: Vec<AgentMessage>,
75}