use super::{
ContextBundle, ContextCompiler, ContextRequest, FusedRetrievalHit, RetrievalProvider,
RetrievalQuery, TokenEstimator, fuse_retrieval,
};
use crate::{MemoryError, MemoryProjection, Result};
#[derive(Debug, Clone)]
pub struct RetrievedContextBundle {
pub context: ContextBundle,
pub retrieval: Vec<FusedRetrievalHit>,
}
impl<T> ContextCompiler<T>
where
T: TokenEstimator,
{
pub fn compile_with_retrieval(
&self,
projection: &MemoryProjection,
request: &ContextRequest,
query: &RetrievalQuery,
providers: &[&dyn RetrievalProvider],
) -> Result<RetrievedContextBundle> {
let retrieval = fuse_retrieval(providers, query).map_err(MemoryError::from)?;
let seeds = retrieval
.iter()
.filter(|hit| {
projection
.visible_node(&hit.entity, request.known_at)
.is_some()
})
.map(|hit| hit.entity.clone())
.collect::<Vec<_>>();
if seeds.is_empty() {
return Err(MemoryError::Retrieval {
provider: "fusion".to_owned(),
message: "no retrieved entity exists in this projection".to_owned(),
});
}
let mut exact = request.clone();
exact.seeds = seeds;
Ok(RetrievedContextBundle {
context: self.compile(projection, &exact)?,
retrieval,
})
}
}