Skip to main content

thndrs_lib/server/
mod.rs

1//! ACP agent server entrypoint and protocol handlers.
2//!
3//! This module exposes `thndrs` as an ACP agent over stdio. The initial server
4//! boundary is deliberately small: stdout is reserved for JSON-RPC transport
5//! and all diagnostics belong on stderr or tracing sinks configured by the
6//! binary.
7
8pub mod config_options;
9pub mod events;
10pub mod handlers;
11pub mod session;
12
13#[cfg(test)]
14mod tests;
15
16use std::path::PathBuf;
17
18use crate::cli::{ReasoningEffort, ReasoningSummary};
19use agent_client_protocol::Result;
20
21/// Runtime configuration accepted by the ACP agent binary.
22#[derive(Clone, Debug, Eq, PartialEq)]
23pub struct ServerConfig {
24    /// Workspace directory used for ACP sessions when the client does not
25    /// provide a more specific root.
26    pub cwd: PathBuf,
27    /// Provider model selected for future harness turns.
28    pub model: String,
29    /// Web search policy label selected for future harness turns.
30    pub websearch: String,
31    /// Optional base URL for the SearXNG backend.
32    pub websearch_url: Option<String>,
33    /// Default reasoning effort for ChatGPT Codex GPT-5.6 sessions.
34    pub reasoning_effort: ReasoningEffort,
35    /// Default reasoning-summary policy for ChatGPT Codex GPT-5.6 sessions.
36    pub reasoning_summary: ReasoningSummary,
37    /// Optional append-only session directory.
38    pub session_dir: Option<PathBuf>,
39}
40
41impl ServerConfig {
42    /// Build a server config from parsed binary flags.
43    pub fn new(cwd: PathBuf, model: String, websearch: String, session_dir: Option<PathBuf>) -> Self {
44        Self {
45            cwd,
46            model,
47            websearch,
48            websearch_url: None,
49            reasoning_effort: ReasoningEffort::default(),
50            reasoning_summary: ReasoningSummary::default(),
51            session_dir,
52        }
53    }
54
55    /// Apply resolved reasoning defaults from local configuration.
56    pub fn with_reasoning(mut self, effort: ReasoningEffort, summary: ReasoningSummary) -> Self {
57        self.reasoning_effort = effort;
58        self.reasoning_summary = summary;
59        self
60    }
61
62    /// Apply the configured SearXNG base URL.
63    pub fn with_search_url(mut self, url: Option<String>) -> Self {
64        self.websearch_url = url;
65        self
66    }
67}
68
69/// Run `thndrs acp serve` over stdio until the ACP connection closes.
70pub async fn run_stdio(config: ServerConfig) -> Result<()> {
71    handlers::run_stdio(config).await
72}