zagens_core/engine/config.rs
1//! Engine configuration — **lean** subset that depends only on core types
2//! (M2 strangler step of the `Engine` struct → `zagens-core` migration).
3//!
4//! See [`PR_M0_ENGINE_STRUCT_TO_CORE_SPIKE`](../../../../docs/tech/adr/PR_M0_ENGINE_STRUCT_TO_CORE_SPIKE.md)
5//! §3 row #1 and §5 R2 for the design rationale. The tui crate keeps a fat
6//! facade `EngineConfig` whose accessor `lean()` / `into_parts()` produce
7//! a value of **this** struct plus an `EngineConfigExt` carrying the
8//! tui-only fields. When the Engine struct itself moves into core (M7),
9//! `Engine::with_hosts(lean, ext_via_host)` will replace the current
10//! `Engine::new(tui::EngineConfig)` entry point.
11
12use std::collections::HashMap;
13use std::path::PathBuf;
14use std::time::Duration;
15
16use crate::capacity::CapacityControllerConfig;
17use crate::compaction::CompactionConfig;
18use crate::cycle::CycleConfig;
19use crate::features::Features;
20use crate::long_horizon::LongHorizonConfig;
21use crate::scratchpad::ScratchpadConfig;
22use crate::task_type::TaskType;
23
24/// Plain-types / core-types subset of the live engine configuration.
25///
26/// Fields are intentionally `pub` so the tui facade can build it field by
27/// field; future core-only callers will go through builder methods.
28#[derive(Clone)]
29pub struct EngineConfig {
30 /// Model identifier to use for responses.
31 pub model: String,
32 /// Workspace root for tool execution and file operations.
33 pub workspace: PathBuf,
34 /// Allow shell tool execution when true.
35 pub allow_shell: bool,
36 /// User-configured sandbox mode (`"read-only"`, `"workspace-write"`, etc.).
37 /// When set, the tool context uses the stricter of this and the AppMode
38 /// default.
39 pub sandbox_mode: Option<String>,
40 /// Enable trust mode (skip approvals) when true.
41 pub trust_mode: bool,
42 /// Path to the notes file used by the notes tool.
43 pub notes_path: PathBuf,
44 /// Path to the MCP configuration file.
45 pub mcp_config_path: PathBuf,
46 /// Directory containing discoverable skills.
47 pub skills_dir: PathBuf,
48 /// Additional instruction files concatenated into the system prompt.
49 /// Loaded in declared order from the user's
50 /// `instructions = [...]` config (or the per-project override). The
51 /// caller is responsible for `expand_path`-style `~` substitution
52 /// before constructing this list — `zagens-core` does no disk I/O
53 /// on these paths.
54 pub instructions: Vec<PathBuf>,
55 /// Maximum number of assistant steps before stopping.
56 pub max_steps: u32,
57 /// Maximum number of concurrently active subagents.
58 pub max_subagents: usize,
59 /// Per-step sub-agent LLM API timeout.
60 pub subagent_step_timeout: Duration,
61 /// Feature flags controlling tool availability.
62 pub features: Features,
63 /// Auto-compaction settings for long conversations.
64 pub compaction: CompactionConfig,
65 /// Checkpoint-restart cycle settings (#124).
66 pub cycle: CycleConfig,
67 /// Capacity-controller settings.
68 pub capacity: CapacityControllerConfig,
69 /// Maximum sub-agent recursion depth.
70 pub max_spawn_depth: u32,
71 /// Whether to take side-git workspace snapshots before/after each turn.
72 pub snapshots_enabled: bool,
73 /// Skip side-git when workspace tree exceeds this size (GB).
74 pub snapshots_max_workspace_gb: f64,
75 /// Per-role/type sub-agent model overrides already resolved from config.
76 pub subagent_model_overrides: HashMap<String, String>,
77 /// Whether the user-memory feature is enabled (#489).
78 pub memory_enabled: bool,
79 /// Path to the user memory file (#489).
80 pub memory_path: PathBuf,
81 /// Long-horizon goal seed (#CRAFT) injected into the system prompt.
82 pub goal_objective: Option<String>,
83 /// Resolved BCP-47 locale tag (e.g. `"en"`, `"zh-Hans"`, `"ja"`).
84 pub locale_tag: String,
85 /// When true, force `tool_choice: "required"`.
86 pub strict_tool_mode: bool,
87 /// Office vs Code task surface (session-fixed).
88 pub task_type: TaskType,
89 /// Audit scratchpad engine hooks (Phase B).
90 pub scratchpad: ScratchpadConfig,
91 /// Long-horizon code task harness (LHT Phase 1).
92 pub long_horizon: LongHorizonConfig,
93}
94
95impl Default for EngineConfig {
96 fn default() -> Self {
97 Self {
98 model: String::new(),
99 workspace: PathBuf::from("."),
100 allow_shell: true,
101 sandbox_mode: None,
102 trust_mode: false,
103 notes_path: PathBuf::from("notes.txt"),
104 mcp_config_path: PathBuf::from("mcp.json"),
105 // Disk-dependent paths get a placeholder; the tui facade fills
106 // them in via `default_skills_dir()`. core-only callers must
107 // override before use.
108 skills_dir: PathBuf::new(),
109 instructions: Vec::new(),
110 max_steps: 100,
111 max_subagents: 0,
112 subagent_step_timeout: Duration::from_secs(0),
113 features: Features::with_defaults(),
114 compaction: CompactionConfig::default(),
115 cycle: CycleConfig::default(),
116 capacity: CapacityControllerConfig::default(),
117 max_spawn_depth: 0,
118 snapshots_enabled: true,
119 snapshots_max_workspace_gb: 2.0,
120 subagent_model_overrides: HashMap::new(),
121 memory_enabled: false,
122 memory_path: PathBuf::from("./memory.md"),
123 goal_objective: None,
124 locale_tag: "en".to_string(),
125 strict_tool_mode: false,
126 task_type: TaskType::default(),
127 scratchpad: ScratchpadConfig::default(),
128 long_horizon: LongHorizonConfig::default(),
129 }
130 }
131}