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