zeph_common/config/memory.rs
1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Shared runtime configuration structs for memory subsystems.
5//!
6//! These are plain (no serde) structs used as runtime parameters. They are separate from the
7//! serde-annotated config types in `zeph-config` which own the deserialization concerns.
8
9/// Runtime config for Kumiho belief revision passed into resolver methods.
10#[derive(Debug, Clone)]
11pub struct BeliefRevisionConfig {
12 pub similarity_threshold: f32,
13}
14
15/// Runtime config for A-MEM dynamic note linking.
16#[derive(Debug, Clone)]
17pub struct NoteLinkingConfig {
18 pub enabled: bool,
19 pub similarity_threshold: f32,
20 pub top_k: usize,
21 pub timeout_secs: u64,
22}
23
24impl Default for NoteLinkingConfig {
25 fn default() -> Self {
26 Self {
27 enabled: false,
28 similarity_threshold: 0.85,
29 top_k: 10,
30 timeout_secs: 5,
31 }
32 }
33}
34
35/// Runtime config for Hebbian background consolidation (HL-F3/F4, #3345).
36///
37/// Passed to `spawn_consolidation_loop` after being constructed from `HebbianConfig` in the
38/// top-level runner.
39#[derive(Debug, Clone)]
40pub struct HebbianConsolidationConfig {
41 /// How often the consolidation sweep runs, in seconds. `0` disables the loop.
42 pub consolidation_interval_secs: u64,
43 /// Minimum `degree × avg_weight` score for a candidate to qualify.
44 pub consolidation_threshold: f64,
45 /// Maximum candidates processed per sweep.
46 pub max_candidates_per_sweep: usize,
47 /// Re-consolidation cooldown per entity, in seconds.
48 pub consolidation_cooldown_secs: u64,
49 /// LLM prompt timeout per distillation call, in seconds.
50 pub consolidation_prompt_timeout_secs: u64,
51 /// Maximum neighbour summaries passed to the LLM per candidate.
52 pub consolidation_max_neighbors: usize,
53}
54
55impl Default for HebbianConsolidationConfig {
56 fn default() -> Self {
57 Self {
58 consolidation_interval_secs: 3600,
59 consolidation_threshold: 5.0,
60 max_candidates_per_sweep: 10,
61 consolidation_cooldown_secs: 86_400,
62 consolidation_prompt_timeout_secs: 30,
63 consolidation_max_neighbors: 20,
64 }
65 }
66}
67
68/// Runtime config for the consolidation sweep loop.
69#[derive(Debug, Clone)]
70pub struct ConsolidationConfig {
71 pub enabled: bool,
72 pub confidence_threshold: f32,
73 pub sweep_interval_secs: u64,
74 pub sweep_batch_size: usize,
75 pub similarity_threshold: f32,
76 /// LLM call timeout per `propose_merge_op` invocation, in seconds.
77 pub llm_timeout_secs: u64,
78 /// Per-call timeout for every `embed()` invocation, in seconds. Default: `5`.
79 pub embed_timeout_secs: u64,
80}
81
82/// Runtime config for the forgetting sweep (#2397).
83#[derive(Debug, Clone)]
84pub struct ForgettingConfig {
85 /// Enable the forgetting sweep.
86 pub enabled: bool,
87 /// Per-sweep decay rate applied to importance scores. Range: (0.0, 1.0).
88 pub decay_rate: f32,
89 /// Importance floor below which memories are pruned. Range: [0.0, 1.0].
90 pub forgetting_floor: f32,
91 /// How often the forgetting sweep runs, in seconds.
92 pub sweep_interval_secs: u64,
93 /// Maximum messages to process per sweep.
94 pub sweep_batch_size: usize,
95 /// Hours: messages accessed within this window get replay protection.
96 pub replay_window_hours: u32,
97 /// Messages with `access_count` >= this get replay protection.
98 pub replay_min_access_count: u32,
99 /// Hours: never prune messages accessed within this window.
100 pub protect_recent_hours: u32,
101 /// Never prune messages with `access_count` >= this.
102 pub protect_min_access_count: u32,
103}
104
105impl Default for ForgettingConfig {
106 fn default() -> Self {
107 Self {
108 enabled: false,
109 decay_rate: 0.1,
110 forgetting_floor: 0.05,
111 sweep_interval_secs: 7200,
112 sweep_batch_size: 500,
113 replay_window_hours: 24,
114 replay_min_access_count: 3,
115 protect_recent_hours: 24,
116 protect_min_access_count: 3,
117 }
118 }
119}