Skip to main content

rhema_coding_agent/
config.rs

1//! The agent's configuration: model, prompt, workspace, turn budget.
2
3use std::path::PathBuf;
4
5use rhema_core::request::ThinkingEffort;
6
7/// Everything a [`CodingAgent`](crate::CodingAgent) needs besides the
8/// provider.
9#[derive(Debug, Clone)]
10pub struct CodingAgentConfig {
11    /// Model identifier, passed through to
12    /// [`ChatParams`](rhema_core::ChatParams).
13    pub model: String,
14    /// System prompt stamped into every request. `None` uses the base
15    /// prompt — [`base_system`](Self::base_system) when set, the
16    /// built-in default otherwise; setting it *replaces* everything, it
17    /// does not append.
18    pub system: Option<String>,
19    /// The base prompt from the user's `SYSTEM.md`, a Jinja template
20    /// rendered by [`render_system`](crate::render_system) — a template
21    /// error fails the agent's construction. `None` uses the built-in
22    /// [`default_system`](crate::default_system).
23    pub base_system: Option<String>,
24    /// Root all tools are scoped to; paths that escape it are rejected
25    /// in-band to the model.
26    pub workspace: PathBuf,
27    /// Cap on steps per turn; a turn still requesting tools past it fails
28    /// with `AgentError::MaxIterations`.
29    pub max_turn_steps: u32,
30    /// How much reasoning the model should do; providers without a knob
31    /// ignore it, and [`ThinkingEffort::Default`] sends nothing.
32    pub thinking: ThinkingEffort,
33}
34
35impl CodingAgentConfig {
36    /// Default for `max_turn_steps`. Long autonomous sessions — builds,
37    /// rebases, multi-package sweeps — routinely run hundreds of steps on
38    /// cheap models under a watching eye; the cap exists to end a runaway
39    /// loop, not to ration the model. `--max-steps` is the tighter leash
40    /// for unattended turns on expensive models.
41    pub const DEFAULT_MAX_TURN_STEPS: u32 = 2048;
42
43    /// Config naming `model`, rooted at `workspace`, defaults elsewhere.
44    pub fn new(model: impl Into<String>, workspace: impl Into<PathBuf>) -> Self {
45        Self {
46            model: model.into(),
47            system: None,
48            base_system: None,
49            workspace: workspace.into(),
50            max_turn_steps: Self::DEFAULT_MAX_TURN_STEPS,
51            thinking: ThinkingEffort::Default,
52        }
53    }
54}