pub mod coreference;
#[cfg(feature = "seal-feedback")]
pub mod feedback_bridge;
#[cfg(feature = "seal-knowledge")]
pub mod knowledge_integration;
pub mod learning;
pub mod query_core;
pub mod reflection;
pub use coreference::{
CoreferenceResolver, DialogState, ReferenceType, ResolvedReference, SalienceScore,
UnresolvedReference,
};
#[cfg(feature = "seal-feedback")]
pub use feedback_bridge::{FeedbackBridge, FeedbackProcessingStats};
#[cfg(feature = "seal-knowledge")]
pub use knowledge_integration::{
EntityResolutionStrategy, IntegrationConfig, SealKnowledgeCoordinator,
};
pub use learning::{
GlobalMemory, LearningCoordinator, LocalMemory, PatternHint, QueryPattern, TrackedEntity,
};
pub use query_core::{
FilterPredicate, QueryCore, QueryCoreExtractor, QueryExpr, QueryOp, QueryResult, QuestionType,
RelationType, SuperlativeDir,
};
pub use reflection::{
CorrectionRecord, ErrorType, Issue, ReflectionConfig, ReflectionModule, ReflectionReport,
Severity, SuggestedFix,
};
use anyhow::Result;
use brainwires_core::graph::{EntityStoreT, RelationshipGraphT};
#[derive(Debug, Clone)]
pub struct SealConfig {
pub enable_coreference: bool,
pub enable_query_cores: bool,
pub enable_learning: bool,
pub enable_reflection: bool,
pub max_reflection_retries: u32,
pub min_coreference_confidence: f32,
pub min_pattern_reliability: f32,
}
impl Default for SealConfig {
fn default() -> Self {
Self {
enable_coreference: true,
enable_query_cores: true,
enable_learning: true,
enable_reflection: true,
max_reflection_retries: 2,
min_coreference_confidence: 0.5,
min_pattern_reliability: 0.7,
}
}
}
#[derive(Debug, Clone)]
pub struct SealProcessingResult {
pub original_query: String,
pub resolved_query: String,
pub query_core: Option<QueryCore>,
pub matched_pattern: Option<String>,
pub resolutions: Vec<ResolvedReference>,
pub quality_score: f32,
pub issues: Vec<Issue>,
}
impl SealProcessingResult {
pub fn new(quality_score: f32, resolved_query: String) -> Self {
Self {
original_query: resolved_query.clone(),
resolved_query,
query_core: None,
matched_pattern: None,
resolutions: Vec::new(),
quality_score,
issues: Vec::new(),
}
}
}
pub struct SealProcessor {
config: SealConfig,
coreference_resolver: CoreferenceResolver,
query_extractor: QueryCoreExtractor,
learning_coordinator: LearningCoordinator,
reflection_module: ReflectionModule,
}
impl SealProcessor {
pub fn new(config: SealConfig) -> Self {
Self {
coreference_resolver: CoreferenceResolver::new(),
query_extractor: QueryCoreExtractor::new(),
learning_coordinator: LearningCoordinator::new(String::new()),
reflection_module: ReflectionModule::new(ReflectionConfig::default()),
config,
}
}
pub fn with_defaults() -> Self {
Self::new(SealConfig::default())
}
pub fn init_conversation(&mut self, conversation_id: &str) {
self.learning_coordinator = LearningCoordinator::new(conversation_id.to_string());
}
pub fn process(
&mut self,
query: &str,
dialog_state: &DialogState,
entity_store: &dyn EntityStoreT,
graph: Option<&dyn RelationshipGraphT>,
) -> Result<SealProcessingResult> {
let mut result = SealProcessingResult {
original_query: query.to_string(),
resolved_query: query.to_string(),
query_core: None,
matched_pattern: None,
resolutions: Vec::new(),
quality_score: 1.0,
issues: Vec::new(),
};
if self.config.enable_coreference {
let references = self.coreference_resolver.detect_references(query);
if !references.is_empty() {
let resolutions = self.coreference_resolver.resolve(
&references,
dialog_state,
entity_store,
graph,
);
let confident_resolutions: Vec<_> = resolutions
.into_iter()
.filter(|r| r.confidence >= self.config.min_coreference_confidence)
.collect();
if !confident_resolutions.is_empty() {
result.resolved_query = self
.coreference_resolver
.rewrite_with_resolutions(query, &confident_resolutions);
result.resolutions = confident_resolutions;
}
}
}
if self.config.enable_query_cores {
let entities: Vec<_> = entity_store.top_entity_info(50);
result.query_core = self
.query_extractor
.extract(&result.resolved_query, &entities);
if let Some(ref mut core) = result.query_core
&& result.resolved_query != query
{
core.resolved = Some(result.resolved_query.clone());
}
}
if self.config.enable_learning
&& let Some(pattern) = self.learning_coordinator.process_query(
query,
&result.resolved_query,
result.query_core.clone(),
dialog_state.current_turn,
)
{
result.matched_pattern = Some(pattern.id.clone());
}
if self.config.enable_reflection && result.query_core.is_some() {
if let Some(ref core) = result.query_core {
result.issues = self.reflection_module.validate_query_core(core);
result.quality_score = if result.issues.is_empty() {
1.0
} else {
0.8 - (result.issues.len() as f32 * 0.1).min(0.5)
};
}
}
Ok(result)
}
pub fn record_outcome(
&mut self,
pattern_id: Option<&str>,
success: bool,
result_count: usize,
query_core: Option<&QueryCore>,
execution_time_ms: u64,
) {
if self.config.enable_learning {
self.learning_coordinator.record_outcome(
pattern_id,
success,
result_count,
query_core,
execution_time_ms,
);
}
}
pub fn reflect(
&mut self,
query_core: &QueryCore,
result: &QueryResult,
graph: &dyn RelationshipGraphT,
) -> ReflectionReport {
self.reflection_module.analyze(query_core, result, graph)
}
pub fn get_learning_context(&self) -> String {
self.learning_coordinator.get_context_for_prompt()
}
pub fn coreference(&self) -> &CoreferenceResolver {
&self.coreference_resolver
}
pub fn query_extractor(&self) -> &QueryCoreExtractor {
&self.query_extractor
}
pub fn learning_mut(&mut self) -> &mut LearningCoordinator {
&mut self.learning_coordinator
}
pub fn reflection(&self) -> &ReflectionModule {
&self.reflection_module
}
pub fn config(&self) -> &SealConfig {
&self.config
}
#[cfg(feature = "seal-mdap")]
pub fn record_mdap_metrics(&mut self, metrics: &crate::mdap::MdapMetrics) {
if !self.config.enable_learning {
return;
}
self.learning_coordinator.record_outcome(
None,
metrics.final_success,
metrics.completed_steps as usize,
None,
0, );
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_seal_processor_creation() {
let processor = SealProcessor::with_defaults();
assert!(processor.config.enable_coreference);
assert!(processor.config.enable_query_cores);
assert!(processor.config.enable_learning);
assert!(processor.config.enable_reflection);
}
#[test]
fn test_seal_config_default() {
let config = SealConfig::default();
assert!(config.enable_coreference);
assert_eq!(config.max_reflection_retries, 2);
assert!(config.min_coreference_confidence > 0.0);
}
#[test]
fn test_init_conversation() {
let mut processor = SealProcessor::with_defaults();
processor.init_conversation("test-conv-123");
assert_eq!(
processor.learning_coordinator.local.conversation_id,
"test-conv-123"
);
}
}