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}