Skip to main content

vtcode_config/core/agent/
memory.rs

1//! Codex-compatible memories and persistent-memory configuration.
2
3use serde::{Deserialize, Serialize};
4
5/// Codex-compatible memories configuration.
6///
7/// Controls whether VT Code extracts durable context from completed threads
8/// and injects it into future sessions. Mirrors the Codex `[memories]` table.
9#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
10#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
11pub struct MemoriesConfig {
12    /// Controls whether newly completed threads can be stored as
13    /// memory-generation inputs.
14    #[serde(default = "default_memories_generate")]
15    pub(crate) generate_memories: bool,
16
17    /// Controls whether VT Code injects existing memories into future sessions.
18    #[serde(default = "default_memories_use")]
19    pub(crate) use_memories: bool,
20
21    /// Overrides the model used for per-thread memory extraction.
22    #[serde(default)]
23    pub extract_model: Option<String>,
24
25    /// Overrides the model used for global memory consolidation.
26    #[serde(default)]
27    pub consolidation_model: Option<String>,
28
29    /// Number of recent sessions scanned by batch memory extraction
30    /// (`run_batch_memory_extraction` / `/memory rebuild --batch`).
31    #[serde(default = "default_memories_batch_sessions")]
32    pub batch_sessions: usize,
33
34    /// Maximum concurrent per-session reads during batch extraction.
35    #[serde(default = "default_memories_batch_concurrency")]
36    pub batch_concurrency: usize,
37}
38
39impl Default for MemoriesConfig {
40    fn default() -> Self {
41        Self {
42            generate_memories: default_memories_generate(),
43            use_memories: default_memories_use(),
44            extract_model: None,
45            consolidation_model: None,
46            batch_sessions: default_memories_batch_sessions(),
47            batch_concurrency: default_memories_batch_concurrency(),
48        }
49    }
50}
51
52#[inline]
53const fn default_memories_generate() -> bool {
54    true
55}
56
57#[inline]
58const fn default_memories_use() -> bool {
59    true
60}
61
62#[inline]
63const fn default_memories_batch_sessions() -> usize {
64    50
65}
66
67#[inline]
68const fn default_memories_batch_concurrency() -> usize {
69    8
70}
71
72#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
73#[derive(Debug, Clone, Deserialize, Serialize)]
74pub struct PersistentMemoryConfig {
75    /// Toggle main-session persistent memory for this repository. Natural-language saves resolve
76    /// "it", "this", and "that" only against the immediately preceding assistant answer and
77    /// require confirmation; identity names and aliases are stored as preferences.
78    #[serde(default = "default_persistent_memory_enabled")]
79    pub enabled: bool,
80
81    /// Write durable memory after completed turns and session finalization
82    #[serde(default = "default_persistent_memory_auto_write")]
83    pub auto_write: bool,
84
85    /// Optional user-local directory override for persistent memory storage
86    #[serde(default)]
87    pub directory_override: Option<String>,
88
89    /// Startup line budget scanned from memory_summary.md before VT Code renders a compact startup summary
90    #[serde(default = "default_persistent_memory_startup_line_limit")]
91    pub startup_line_limit: usize,
92
93    /// Startup byte budget scanned from memory_summary.md before VT Code renders a compact startup summary
94    #[serde(default = "default_persistent_memory_startup_byte_limit")]
95    pub startup_byte_limit: usize,
96
97    /// Startup token budget for the injected memory excerpt. `0` disables the
98    /// token cap and keeps only the line/byte budgets.
99    #[serde(default = "default_persistent_memory_startup_token_budget")]
100    pub startup_token_budget: usize,
101
102    /// Codex-compatible memories sub-configuration
103    #[serde(default)]
104    pub memories: MemoriesConfig,
105}
106
107impl Default for PersistentMemoryConfig {
108    fn default() -> Self {
109        Self {
110            enabled: default_persistent_memory_enabled(),
111            auto_write: default_persistent_memory_auto_write(),
112            directory_override: None,
113            startup_line_limit: default_persistent_memory_startup_line_limit(),
114            startup_byte_limit: default_persistent_memory_startup_byte_limit(),
115            startup_token_budget: default_persistent_memory_startup_token_budget(),
116            memories: MemoriesConfig::default(),
117        }
118    }
119}
120
121impl PersistentMemoryConfig {
122    pub(crate) fn validate(&self) -> Result<(), String> {
123        if self.startup_line_limit == 0 {
124            return Err("persistent_memory.startup_line_limit must be greater than 0".to_string());
125        }
126
127        if self.startup_byte_limit == 0 {
128            return Err("persistent_memory.startup_byte_limit must be greater than 0".to_string());
129        }
130
131        Ok(())
132    }
133}
134
135#[inline]
136const fn default_persistent_memory_enabled() -> bool {
137    false
138}
139
140#[inline]
141const fn default_persistent_memory_auto_write() -> bool {
142    true
143}
144
145#[inline]
146const fn default_persistent_memory_startup_line_limit() -> usize {
147    200
148}
149
150#[inline]
151const fn default_persistent_memory_startup_byte_limit() -> usize {
152    25 * 1024
153}
154
155#[inline]
156const fn default_persistent_memory_startup_token_budget() -> usize {
157    5000
158}