pub mod access_frequency;
pub mod causal_distance;
pub mod consolidation;
pub mod metrics;
pub mod novelty;
pub mod scoring;
pub mod weights;
use std::sync::Arc;
use zeph_common::SessionId;
use zeph_config::memory::FiveSignalConfig;
use zeph_db::DbPool;
use crate::embedding_store::EmbeddingStore;
use crate::five_signal::{
access_frequency::AccessFrequencyCache, causal_distance::CausalDistanceComputer,
metrics::FiveSignalMetrics, novelty::NoveltyComputer, weights::FiveSignalWeights,
};
pub struct FiveSignalRuntime {
pub weights: FiveSignalWeights,
pub access_cache: AccessFrequencyCache,
pub causal_computer: tokio::sync::Mutex<CausalDistanceComputer>,
pub novelty_computer: NoveltyComputer,
pub metrics: Arc<FiveSignalMetrics>,
pub pool: DbPool,
pub qdrant: Option<Arc<EmbeddingStore>>,
pub session_start: i64,
pub session_id: SessionId,
pub config: FiveSignalConfig,
}
impl FiveSignalRuntime {
#[must_use]
pub fn new(
config: FiveSignalConfig,
pool: DbPool,
graph_store: Arc<crate::graph::GraphStore>,
qdrant: Option<Arc<EmbeddingStore>>,
session_start: i64,
session_id: impl Into<SessionId>,
) -> Self {
let weights = FiveSignalWeights::normalized(&config);
let daemon = &config.consolidation_daemon;
if daemon.enabled && daemon.top_k_per_run < daemon.batch_size {
tracing::warn!(
top_k_per_run = daemon.top_k_per_run,
batch_size = daemon.batch_size,
"five_signal: top_k_per_run < batch_size; daemon will only process top_k_per_run facts"
);
}
Self {
weights,
access_cache: AccessFrequencyCache::new(pool.clone()),
causal_computer: tokio::sync::Mutex::new(CausalDistanceComputer::new(
graph_store,
config.causal_bfs_max_depth,
config.neutral_causal_distance,
)),
novelty_computer: NoveltyComputer::new(session_start, config.novelty_decay_rate),
metrics: Arc::new(FiveSignalMetrics::default()),
pool,
qdrant,
session_start,
session_id: session_id.into(),
config,
}
}
}