1use oxibrain::Brain;
2use oxibrain::BrainConfig;
3use oxibrain_core::TargetId;
4use std::path::Path;
5
6pub async fn run(dir: &Path, question: &str, space: &str) -> anyhow::Result<()> {
7 let brain = Brain::open(BrainConfig::at(dir)).await?;
8 let space_id = brain.ensure_space(space).await?;
9 let q = oxibrain_core::Query {
10 text: question.to_string(),
11 mode: oxibrain_core::QueryMode::Hybrid,
12 space: space_id,
13 as_of: None,
14 limit: 20,
15 min_confidence: 0.0,
16 };
17 let result = brain.query(q).await?;
18 println!(
19 "hits: {} (total candidates: {})",
20 result.items.len(),
21 result.total_candidates
22 );
23 for item in &result.items {
24 let target = match &item.target {
25 TargetId::Episode { id } => format!("episode:{id}"),
26 TargetId::Statement { id } => format!("statement:{id}"),
27 TargetId::Entity { id } => format!("entity:{id}"),
28 TargetId::Chunk { id } => format!("chunk:{id}"),
29 TargetId::Community { id } => format!("community:{id}"),
30 };
31 println!(
32 " rank={} score={:.4} salience={:.4} -> {target}",
33 item.rank, item.fused_score, item.salience
34 );
35 if let TargetId::Episode { id } = &item.target {
36 if let Ok(Some(ep)) = brain.get_episode(id).await {
37 let flat: String = ep.content.chars().filter(|c| *c != '\n').collect();
38 let excerpt: String = flat.chars().take(160).collect();
39 println!(" {excerpt}");
40 }
41 }
42 }
43 Ok(())
44}