Skip to main content

a3s_code_core/config/
mod.rs

1//! Configuration module for A3S Code
2//!
3//! Provides configuration for:
4//! - LLM providers and models (defaultModel in "provider/model" format, providers)
5//! - Queue configuration (a3s-lane integration)
6//! - Search configuration (a3s-search integration)
7//! - Directories for dynamic skill and agent loading
8//!
9//! Configuration is loaded from ACL-compatible files or strings.
10//! Existing `.acl` config filenames are still accepted for compatibility.
11//! JSON support has been removed.
12
13mod acl_render;
14pub mod agent_dir;
15mod editor;
16mod loader;
17#[cfg(test)]
18mod loader_tests;
19mod provider;
20mod search;
21#[cfg(test)]
22mod tests;
23
24pub use agent_dir::{AgentDir, ScheduleSpec, ScriptToolLimits, ScriptToolSpec, ToolSpec};
25pub use editor::{rewrite_acl_sections, ConfigSection};
26pub use provider::{ModelConfig, ModelCost, ModelLimit, ModelModalities, ProviderConfig};
27pub use search::{
28    BrowserBackend, DocumentCacheConfig, DocumentParserConfig, HeadlessConfig, SearchConfig,
29    SearchEngineConfig, SearchHealthConfig,
30};
31
32use crate::memory::MemoryConfig;
33use serde::{Deserialize, Serialize};
34use std::path::PathBuf;
35
36// ============================================================================
37// Storage Configuration
38// ============================================================================
39
40/// Session storage backend type
41#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
42#[serde(rename_all = "lowercase")]
43pub enum StorageBackend {
44    /// In-memory storage (no persistence)
45    Memory,
46    /// File-based storage (JSON files)
47    #[default]
48    File,
49    /// Custom external storage (Redis, PostgreSQL, etc.)
50    ///
51    /// Requires a `SessionStore` implementation registered on `AgentSession` options.
52    /// Use `storage_url` in config to pass connection details.
53    Custom,
54}
55
56// ============================================================================
57// Main Configuration
58// ============================================================================
59
60/// Automatic subagent delegation controls.
61#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
62#[serde(default, rename_all = "camelCase")]
63pub struct AutoDelegationConfig {
64    /// Enable runtime-driven automatic child agent delegation.
65    pub enabled: bool,
66    /// Allow automatic delegation to launch multiple child agents in parallel.
67    ///
68    /// Manual `task` fan-out remains available when this is false.
69    #[serde(alias = "auto_parallel")]
70    pub auto_parallel: bool,
71    /// Allow the model-visible `task` tool (including multi-item fan-out).
72    ///
73    /// Set this to false for cost control or debugging when child-agent tools
74    /// should be absent from the session tool surface. This is not a security
75    /// sandbox: the parent agent may still have other tools such as `bash`,
76    /// MCP tools, or skills.
77    #[serde(alias = "allow_manual_delegation")]
78    pub allow_manual_delegation: bool,
79    /// Minimum local confidence required to auto-delegate a child task.
80    pub min_confidence: f32,
81    /// Maximum number of automatic child tasks per user request.
82    pub max_tasks: usize,
83}
84
85impl Default for AutoDelegationConfig {
86    fn default() -> Self {
87        Self {
88            enabled: false,
89            auto_parallel: true,
90            allow_manual_delegation: true,
91            min_confidence: 0.72,
92            max_tasks: 4,
93        }
94    }
95}
96
97/// Optional platform endpoint used by hosts for account login.
98#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
99#[serde(rename_all = "camelCase")]
100pub struct OsConfig {
101    /// Base address of the configured platform instance.
102    #[serde(alias = "url", alias = "baseUrl", alias = "base_url")]
103    pub address: String,
104}
105
106/// Configuration for A3S Code
107#[derive(Debug, Clone, Serialize, Deserialize, Default)]
108#[serde(rename_all = "camelCase")]
109pub struct CodeConfig {
110    /// Default model in "provider/model" format (e.g., "anthropic/claude-sonnet-4-20250514")
111    #[serde(default, alias = "default_model")]
112    pub default_model: Option<String>,
113
114    /// Provider configurations
115    #[serde(default)]
116    pub providers: Vec<ProviderConfig>,
117
118    /// Session storage backend
119    #[serde(default)]
120    pub storage_backend: StorageBackend,
121
122    /// Sessions directory (for file backend)
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub sessions_dir: Option<PathBuf>,
125
126    /// Memory directory for the default file-backed memory store.
127    ///
128    /// If unset, sessions use `<workspace>/.a3s/memory` unless the host passes
129    /// an explicit memory store or file memory directory.
130    #[serde(default, alias = "memoryDir", skip_serializing_if = "Option::is_none")]
131    pub memory_dir: Option<PathBuf>,
132
133    /// Connection URL for custom storage backend (e.g., "redis://localhost:6379", "postgres://user:pass@localhost/a3s")
134    #[serde(default, skip_serializing_if = "Option::is_none")]
135    pub storage_url: Option<String>,
136
137    /// Directories to scan for skill files (*.md with tool definitions)
138    #[serde(default, alias = "skill_dirs")]
139    pub skill_dirs: Vec<PathBuf>,
140
141    /// Directories to scan for agent files (*.yaml or *.md)
142    #[serde(default, alias = "agent_dirs")]
143    pub agent_dirs: Vec<PathBuf>,
144
145    /// Directory containing personal instructions loaded before project files.
146    ///
147    /// When unset, instruction discovery checks `~/.a3s/AGENTS.override.md`
148    /// and then `~/.a3s/AGENTS.md`, using the first non-empty regular file.
149    #[serde(
150        default,
151        alias = "user_instructions_dir",
152        alias = "globalInstructionsDir",
153        alias = "global_instructions_dir",
154        skip_serializing_if = "Option::is_none"
155    )]
156    pub user_instructions_dir: Option<PathBuf>,
157
158    /// Maximum combined bytes loaded from personal and project instruction files.
159    ///
160    /// When unset, instruction discovery uses the Codex-compatible 32 KiB
161    /// default. A value of zero disables all automatic instruction loading.
162    #[serde(default, alias = "project_doc_max_bytes")]
163    pub project_doc_max_bytes: Option<usize>,
164
165    /// Ordered fallback filenames checked after `AGENTS.override.md` and
166    /// `AGENTS.md` in every directory from the project root to the workspace.
167    #[serde(default, alias = "project_doc_fallback_filenames")]
168    pub project_doc_fallback_filenames: Vec<String>,
169
170    /// Maximum tool execution rounds per turn (default: 25)
171    #[serde(default, alias = "max_tool_rounds")]
172    pub max_tool_rounds: Option<usize>,
173
174    /// Maximum sibling branches/tools to run concurrently in bounded parallel fan-out paths.
175    #[serde(default, alias = "max_parallel_tasks")]
176    pub max_parallel_tasks: Option<usize>,
177
178    /// Agent-wide priority and concurrency admission shared by all sessions.
179    #[serde(default, alias = "task_scheduler")]
180    pub task_scheduler: crate::task_scheduler::TaskSchedulerConfig,
181
182    /// Global automatic child-agent delegation settings.
183    #[serde(default, alias = "auto_delegation")]
184    pub auto_delegation: AutoDelegationConfig,
185
186    /// Convenience global kill switch for automatic parallel child-agent fan-out.
187    ///
188    /// When set, overrides `auto_delegation.auto_parallel`.
189    #[serde(default, alias = "auto_parallel")]
190    pub auto_parallel: Option<bool>,
191
192    /// Thinking/reasoning budget in tokens
193    #[serde(default, alias = "thinking_budget")]
194    pub thinking_budget: Option<usize>,
195
196    /// Per-model API HTTP timeout in milliseconds. Separate from tool execution
197    /// timeouts so provider/network deadlines do not constrain local tools.
198    #[serde(
199        default,
200        alias = "llm_api_timeout_ms",
201        alias = "api_timeout_ms",
202        alias = "model_api_timeout_ms"
203    )]
204    pub llm_api_timeout_ms: Option<u64>,
205
206    /// Memory system configuration
207    #[serde(default, skip_serializing_if = "Option::is_none")]
208    pub memory: Option<MemoryConfig>,
209
210    /// Queue configuration (a3s-lane integration)
211    #[serde(default, skip_serializing_if = "Option::is_none")]
212    pub queue: Option<crate::queue::SessionQueueConfig>,
213
214    /// Search configuration (a3s-search integration)
215    #[serde(default, skip_serializing_if = "Option::is_none")]
216    pub search: Option<SearchConfig>,
217
218    /// Optional platform endpoint. When set, hosts may enable account login.
219    #[serde(default, skip_serializing_if = "Option::is_none")]
220    pub os: Option<OsConfig>,
221
222    /// Built-in document context extraction configuration.
223    #[serde(default, skip_serializing_if = "Option::is_none")]
224    pub document_parser: Option<DocumentParserConfig>,
225
226    /// MCP server configurations
227    #[serde(default, alias = "mcp_servers")]
228    pub mcp_servers: Vec<crate::mcp::McpServerConfig>,
229}