use crate::output::RecallItem;
#[derive(serde::Serialize)]
pub struct HybridSearchItem {
pub memory_id: i64,
pub name: String,
pub namespace: String,
#[serde(rename = "type")]
pub memory_type: String,
pub description: String,
pub body: String,
pub snippet: String,
pub combined_score: f64,
pub score: f64,
pub source: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub vec_rank: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fts_rank: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rrf_score: Option<f64>,
pub normalized_score: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub vec_distance: Option<f64>,
}
#[derive(serde::Serialize)]
pub struct Weights {
pub vec: f32,
pub fts: f32,
}
#[derive(serde::Serialize)]
pub struct HybridSearchResponse {
pub query: String,
pub k: usize,
pub rrf_k: u32,
pub weights: Weights,
pub results: Vec<HybridSearchItem>,
pub graph_matches: Vec<RecallItem>,
pub max_graph_results: Option<usize>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub fts_degraded: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub fts_error: Option<String>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub fts_auto_rebuilt: bool,
#[serde(skip_serializing_if = "std::ops::Not::not", default)]
pub vec_degraded: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub vec_error: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub warning: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub backend_invoked: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vec_degraded_reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vec_degraded_code: Option<&'static str>,
pub elapsed_ms: u64,
}