use crate::bridge_retrieval::BridgeRetrieval;
use crate::error::Result;
use crate::framework::ChaoticSemanticFramework;
use crate::metadata_filter::MetadataFilter;
use crate::semantic_bridge::{BridgeHit, MemoryPacket, SemanticReranker};
impl ChaoticSemanticFramework {
pub async fn probe_bridge_text(
&self,
query: &str,
top_k: usize,
bridge: &BridgeRetrieval,
) -> Result<Vec<BridgeHit>> {
self.validate_top_k(top_k)?;
let singularity = self.singularity.read().await;
bridge.query(&singularity, query, top_k, None)
}
pub async fn probe_bridge_text_with_reranker(
&self,
query: &str,
top_k: usize,
bridge: &BridgeRetrieval,
reranker: &dyn SemanticReranker,
) -> Result<Vec<BridgeHit>> {
self.validate_top_k(top_k)?;
let singularity = self.singularity.read().await;
bridge.query(&singularity, query, top_k, Some(reranker))
}
pub async fn probe_bridge_text_filtered(
&self,
query: &str,
top_k: usize,
bridge: &BridgeRetrieval,
filter: &MetadataFilter,
) -> Result<Vec<BridgeHit>> {
self.validate_top_k(top_k)?;
let singularity = self.singularity.read().await;
let query_hv = bridge.encoder().encode(query);
let filtered_results = singularity.find_similar_filtered(&query_hv, top_k, filter);
let filtered_ids: std::collections::HashSet<String> = filtered_results
.as_ref()
.iter()
.map(|(id, _)| id.clone())
.collect();
let hits = bridge.query(&singularity, query, top_k, None)?;
let filtered_hits: Vec<BridgeHit> = hits
.into_iter()
.filter(|hit| filtered_ids.contains(&hit.id))
.collect();
Ok(filtered_hits)
}
pub async fn memory_packet_text(
&self,
query: &str,
top_k: usize,
bridge: &BridgeRetrieval,
) -> Result<MemoryPacket> {
self.validate_top_k(top_k)?;
let singularity = self.singularity.read().await;
bridge.memory_packet(&singularity, query, top_k, None)
}
pub async fn memory_packet_text_with_reranker(
&self,
query: &str,
top_k: usize,
bridge: &BridgeRetrieval,
reranker: &dyn SemanticReranker,
) -> Result<MemoryPacket> {
self.validate_top_k(top_k)?;
let singularity = self.singularity.read().await;
bridge.memory_packet(&singularity, query, top_k, Some(reranker))
}
}
#[cfg(test)]
mod tests {
use crate::encoder::TextEncoder;
use crate::framework_builder::FrameworkBuilder;
use crate::semantic_bridge::{CanonicalConcept, ConceptGraph};
use crate::singularity::ConceptBuilder;
#[tokio::test]
async fn test_probe_bridge_text_empty() {
let framework = FrameworkBuilder::new().build().await.unwrap();
let encoder = TextEncoder::new();
let graph = ConceptGraph::new();
let bridge = crate::bridge_retrieval::BridgeRetrieval::with_defaults(encoder, graph);
let results = framework
.probe_bridge_text("test query", 10, &bridge)
.await
.unwrap();
assert!(results.is_empty());
}
#[tokio::test]
async fn test_memory_packet_text_empty() {
let framework = FrameworkBuilder::new().build().await.unwrap();
let encoder = TextEncoder::new();
let graph = ConceptGraph::new();
let bridge = crate::bridge_retrieval::BridgeRetrieval::with_defaults(encoder, graph);
let packet = framework
.memory_packet_text("test query", 10, &bridge)
.await
.unwrap();
assert!(packet.facts.is_empty());
assert_eq!(packet.confidence, 0.0);
}
#[tokio::test]
async fn test_probe_bridge_text_with_concepts() {
let framework = FrameworkBuilder::new().build().await.unwrap();
let encoder = TextEncoder::new();
let concept = ConceptBuilder::new("test-concept")
.with_vector(encoder.encode("agent memory system"))
.build()
.unwrap();
framework
.inject_concept(concept.id.clone(), concept.vector)
.await
.unwrap();
let mut graph = ConceptGraph::new();
graph.add_concept(
CanonicalConcept::new("c1")
.with_label("agent-memory")
.with_label("ai-memory"),
);
let bridge = crate::bridge_retrieval::BridgeRetrieval::with_defaults(encoder, graph);
let results = framework
.probe_bridge_text("agent memory", 10, &bridge)
.await
.unwrap();
assert!(!results.is_empty());
assert!(results.iter().any(|h| h.id == "test-concept"));
}
}