Skip to main content

oxibrain_cli/cmd/
ask.rs

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}