use crate::embeddings::EmbeddingConfig;
use crate::extraction::PatternExtractor;
use crate::learning::queue::{PatternExtractionQueue, QueueConfig};
use crate::monitoring::{AgentMonitor, MonitoringConfig, storage::SimpleMonitoringStorage};
use crate::pre_storage::{QualityAssessor, QualityConfig, SalientExtractor};
use crate::reflection::ReflectionGenerator;
use crate::reward::RewardCalculator;
use crate::security::audit::AuditLogger;
use crate::types::{DEFAULT_EVENT_CHANNEL_CAPACITY, MemoryConfig};
use std::collections::HashMap;
#[allow(unused_imports)]
use std::sync::Arc;
use tokio::sync::{RwLock, Semaphore, broadcast};
#[must_use]
pub fn with_config(config: MemoryConfig) -> super::SelfLearningMemory {
let pattern_extractor =
PatternExtractor::with_thresholds(config.pattern_extraction_threshold, 2, 5);
let quality_config = QualityConfig::new(config.quality_threshold);
let quality_assessor = QualityAssessor::new(quality_config);
let salient_extractor = SalientExtractor::new();
let capacity_manager = if let Some(max_episodes) = config.max_episodes {
let eviction_policy = config
.eviction_policy
.unwrap_or(crate::episodic::EvictionPolicy::RelevanceWeighted);
Some(crate::episodic::CapacityManager::new(
max_episodes,
eviction_policy,
))
} else {
None
};
let semantic_summarizer = if config.enable_summarization {
Some(crate::semantic::SemanticSummarizer::with_config(
config.summary_min_length,
config.summary_max_length,
5, ))
} else {
None
};
let spatiotemporal_index = if config.enable_spatiotemporal_indexing {
Some(Arc::new(RwLock::new(
crate::spatiotemporal::SpatiotemporalIndex::new(),
)))
} else {
None
};
let hierarchical_retriever = if config.enable_spatiotemporal_indexing {
Some(crate::spatiotemporal::HierarchicalRetriever::with_config(
config.temporal_bias_weight,
config.max_clusters_to_search,
))
} else {
None
};
let diversity_maximizer = if config.enable_diversity_maximization {
Some(crate::spatiotemporal::DiversityMaximizer::new(
config.diversity_lambda,
))
} else {
None
};
let semantic_config = EmbeddingConfig::default();
let semantic_service: Option<Arc<crate::embeddings::SemanticService>> = None;
let query_cache = Arc::new(crate::retrieval::QueryCache::new());
let dbscan_detector = crate::patterns::DBSCANAnomalyDetector::new();
let (event_sender, _) = broadcast::channel(DEFAULT_EVENT_CHANNEL_CAPACITY);
super::SelfLearningMemory {
config: config.clone(),
quality_assessor,
salient_extractor,
reward_calculator: RewardCalculator::new(),
reflection_generator: ReflectionGenerator::new(),
pattern_extractor,
heuristic_extractor: crate::patterns::extractors::HeuristicExtractor::new(),
agent_monitor: AgentMonitor::new(),
turso_storage: None,
cache_storage: None,
episodes_fallback: Arc::new(RwLock::new(HashMap::new())),
patterns_fallback: Arc::new(RwLock::new(HashMap::new())),
heuristics_fallback: Arc::new(RwLock::new(HashMap::new())),
relationships_fallback: Arc::new(RwLock::new(HashMap::new())),
pattern_queue: None,
step_buffers: Arc::new(RwLock::new(HashMap::new())),
cache_semaphore: Arc::new(Semaphore::new(config.concurrency.max_concurrent_cache_ops)),
capacity_manager,
semantic_summarizer,
spatiotemporal_index,
hierarchical_retriever,
diversity_maximizer,
context_aware_embeddings: None,
semantic_service,
semantic_config,
query_cache,
dbscan_detector,
audit_logger: AuditLogger::new(config.audit_config.clone()),
playbook_generator: super::playbook::PlaybookGenerator::new(),
summaries_fallback: Arc::new(RwLock::new(HashMap::new())),
recommendation_tracker: super::attribution::RecommendationTracker::new(),
event_sender,
}
}
pub fn with_storage(
config: MemoryConfig,
turso: Arc<dyn crate::StorageBackend>,
cache: Arc<dyn crate::StorageBackend>,
) -> super::SelfLearningMemory {
let pattern_extractor =
PatternExtractor::with_thresholds(config.pattern_extraction_threshold, 2, 5);
let quality_config = QualityConfig::new(config.quality_threshold);
let quality_assessor = QualityAssessor::new(quality_config);
let salient_extractor = SalientExtractor::new();
let monitoring_config = MonitoringConfig {
enabled: true,
enable_persistence: true,
max_records: 1000,
};
let monitoring_storage = SimpleMonitoringStorage::new(Arc::clone(&turso));
let agent_monitor = AgentMonitor::with_storage(monitoring_config, Arc::new(monitoring_storage));
let capacity_manager = if let Some(max_episodes) = config.max_episodes {
let eviction_policy = config
.eviction_policy
.unwrap_or(crate::episodic::EvictionPolicy::RelevanceWeighted);
Some(crate::episodic::CapacityManager::new(
max_episodes,
eviction_policy,
))
} else {
None
};
let semantic_summarizer = if config.enable_summarization {
Some(crate::semantic::SemanticSummarizer::with_config(
config.summary_min_length,
config.summary_max_length,
5,
))
} else {
None
};
let spatiotemporal_index = if config.enable_spatiotemporal_indexing {
Some(Arc::new(RwLock::new(
crate::spatiotemporal::SpatiotemporalIndex::new(),
)))
} else {
None
};
let hierarchical_retriever = if config.enable_spatiotemporal_indexing {
Some(crate::spatiotemporal::HierarchicalRetriever::with_config(
config.temporal_bias_weight,
config.max_clusters_to_search,
))
} else {
None
};
let diversity_maximizer = if config.enable_diversity_maximization {
Some(crate::spatiotemporal::DiversityMaximizer::new(
config.diversity_lambda,
))
} else {
None
};
let semantic_config = EmbeddingConfig::default();
let semantic_service: Option<Arc<crate::embeddings::SemanticService>> = None;
let query_cache = Arc::new(crate::retrieval::QueryCache::new());
let dbscan_detector = crate::patterns::DBSCANAnomalyDetector::new();
let audit_logger = AuditLogger::new(config.audit_config.clone());
let (event_sender, _) = broadcast::channel(DEFAULT_EVENT_CHANNEL_CAPACITY);
super::SelfLearningMemory {
config: config.clone(),
quality_assessor,
salient_extractor,
reward_calculator: RewardCalculator::new(),
reflection_generator: ReflectionGenerator::new(),
pattern_extractor,
heuristic_extractor: crate::patterns::extractors::HeuristicExtractor::new(),
agent_monitor,
turso_storage: Some(turso),
cache_storage: Some(cache),
episodes_fallback: Arc::new(RwLock::new(HashMap::new())),
patterns_fallback: Arc::new(RwLock::new(HashMap::new())),
heuristics_fallback: Arc::new(RwLock::new(HashMap::new())),
relationships_fallback: Arc::new(RwLock::new(HashMap::new())),
pattern_queue: None,
step_buffers: Arc::new(RwLock::new(HashMap::new())),
cache_semaphore: Arc::new(Semaphore::new(config.concurrency.max_concurrent_cache_ops)),
capacity_manager,
semantic_summarizer,
spatiotemporal_index,
hierarchical_retriever,
diversity_maximizer,
context_aware_embeddings: None,
semantic_service,
semantic_config,
query_cache,
dbscan_detector,
audit_logger,
playbook_generator: super::playbook::PlaybookGenerator::new(),
summaries_fallback: Arc::new(RwLock::new(HashMap::new())),
recommendation_tracker: super::attribution::RecommendationTracker::new(),
event_sender,
}
}
#[must_use]
pub fn with_semantic_config(
config: MemoryConfig,
semantic_config: EmbeddingConfig,
) -> super::SelfLearningMemory {
let mut memory = with_config(config);
memory.semantic_config = semantic_config;
memory
}
#[must_use]
pub fn enable_async_extraction(
memory: super::SelfLearningMemory,
queue_config: QueueConfig,
) -> super::SelfLearningMemory {
let memory_arc = Arc::new(memory.clone());
let queue = Arc::new(PatternExtractionQueue::new(queue_config, memory_arc));
let mut memory = memory;
memory.pattern_queue = Some(queue);
memory
}
pub async fn start_workers(memory: &super::SelfLearningMemory) {
if let Some(queue) = &memory.pattern_queue {
queue.start_workers().await;
}
}