1use oxibrain::Brain;
2use oxibrain::BrainConfig;
3use oxibrain_core::{DropReason, Query, QueryMode};
4use std::path::Path;
5
6pub async fn run_dropped(
10 dir: &Path,
11 query_text: &str,
12 space: &str,
13 min_confidence: f32,
14) -> anyhow::Result<()> {
15 let brain = Brain::open(BrainConfig::at(dir)).await?;
16 let space_id = brain.ensure_space(space).await?;
17 let q = Query {
18 text: query_text.to_string(),
19 mode: QueryMode::Hybrid,
20 space: space_id,
21 as_of: None,
22 limit: 20,
23 min_confidence,
24 };
25 let result = brain.query(q).await?;
26 if result.dropped.is_empty() {
27 println!(
28 "no candidates were dropped (limit {})",
29 result.total_candidates
30 );
31 return Ok(());
32 }
33 println!(
34 "dropped {} of {} candidates:",
35 result.dropped.len(),
36 result.total_candidates
37 );
38 for d in &result.dropped {
39 let reason = match &d.reason {
40 DropReason::BelowConfidenceFloor { actual, floor } => {
41 format!("below confidence floor: {actual:.2} < {floor:.2}")
42 }
43 DropReason::OutsideValidWindow { valid_at } => {
44 format!("outside valid window at {valid_at:?}")
45 }
46 DropReason::BeforeKnownAt {
47 known_at,
48 recorded_at,
49 } => {
50 format!("recorded {recorded_at:?} after known_at {known_at:?}")
51 }
52 DropReason::TrustExcluded { tier } => format!("trust tier excluded: {tier:?}"),
53 DropReason::PredicateDenied { predicate } => {
54 format!("predicate denied: {predicate}")
55 }
56 DropReason::EntityTypeMismatch { expected } => {
57 format!("entity type mismatch, expected {expected:?}")
58 }
59 DropReason::TruncatedByBudget { position } => {
60 format!("truncated by budget (position {position})")
61 }
62 };
63 println!(" {} — {reason}", d.target.rrf_key());
64 }
65 Ok(())
66}
67
68pub async fn run(dir: &Path, statement_id: &str, space: &str) -> anyhow::Result<()> {
69 let brain = Brain::open(BrainConfig::at(dir)).await?;
70 let space_id = brain.ensure_space(space).await?;
71 let block = brain.why(&space_id, statement_id).await?;
72 println!("statement: {}", block.statement.id);
73 println!(" subject: {}", block.statement.subject);
74 println!(" predicate: {}", block.statement.predicate);
75 println!(" object: {:?}", block.statement.object);
76 println!("status: {}", block.status);
77 println!(
78 "confidence: raw={:.3} support={} contradiction={}",
79 block.confidence_breakdown.raw_confidence,
80 block.confidence_breakdown.support_count,
81 block.confidence_breakdown.contradiction_count
82 );
83 println!("assertions: {}", block.assertions.len());
84 for a in &block.assertions {
85 println!(
86 " [{}] episode={} extractor={:?} conf={:.3} recorded={}",
87 a.polarity, a.episode_id, a.extractor, a.confidence, a.recorded_at
88 );
89 }
90 Ok(())
91}