use async_trait::async_trait;
use super::super::RetrievalContext;
use super::super::types::{NavigationStep, SearchPath};
use crate::document::{DocumentTree, NodeId};
use crate::retrieval::pilot::Pilot;
#[derive(Debug, Clone)]
pub struct SearchResult {
pub paths: Vec<SearchPath>,
pub trace: Vec<NavigationStep>,
pub nodes_visited: usize,
pub iterations: usize,
pub pilot_interventions: usize,
}
impl Default for SearchResult {
fn default() -> Self {
Self {
paths: Vec::new(),
trace: Vec::new(),
nodes_visited: 0,
iterations: 0,
pilot_interventions: 0,
}
}
}
#[derive(Debug, Clone)]
pub struct SearchConfig {
pub top_k: usize,
pub beam_width: usize,
pub max_iterations: usize,
pub min_score: f32,
pub leaf_only: bool,
}
impl Default for SearchConfig {
fn default() -> Self {
Self {
top_k: 5,
beam_width: 3,
max_iterations: 10,
min_score: 0.1,
leaf_only: false,
}
}
}
#[async_trait]
pub trait SearchTree: Send + Sync {
async fn search(
&self,
tree: &DocumentTree,
context: &RetrievalContext,
config: &SearchConfig,
pilot: Option<&dyn Pilot>,
) -> SearchResult;
async fn search_without_pilot(
&self,
tree: &DocumentTree,
context: &RetrievalContext,
config: &SearchConfig,
) -> SearchResult {
self.search(tree, context, config, None).await
}
async fn search_from(
&self,
tree: &DocumentTree,
context: &RetrievalContext,
config: &SearchConfig,
pilot: Option<&dyn Pilot>,
start_node: NodeId,
) -> SearchResult {
let _ = start_node; self.search(tree, context, config, pilot).await
}
fn name(&self) -> &str;
}