use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use super::context::FeatureConfigDto;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum EvidenceSourceDto {
Explicit {
#[serde(default, skip_serializing_if = "Option::is_none")]
relation_term_id: Option<String>,
},
Emergent {
unified_degree: f64,
},
Both {
#[serde(default, skip_serializing_if = "Option::is_none")]
relation_term_id: Option<String>,
unified_degree: f64,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum RelationTypeDto {
Explicit,
Emergent { unified_features: Vec<String> },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConceptMatchDto {
pub canonical_name: String,
pub concept_id: String,
#[serde(default)]
pub features: BTreeMap<String, serde_json::Value>,
pub match_degree: f64,
pub match_reason: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name_variants: Option<serde_json::Value>,
#[serde(default)]
pub source_ids: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PrerequisiteInfoDto {
pub below_threshold: bool,
pub canonical_name: String,
pub concept_id: String,
pub depth: u32,
pub evidence: EvidenceSourceDto,
pub path: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub value: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DependentInfoDto {
pub canonical_name: String,
pub concept_id: String,
pub depends_on: String,
pub evidence: EvidenceSourceDto,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RelatedInfoDto {
pub canonical_name: String,
pub concept_id: String,
pub degree: f64,
pub evidence: EvidenceSourceDto,
pub relation_type: RelationTypeDto,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct OntologyRagStatsDto {
pub embedding_search_ms: u64,
pub emergent_discovered: u64,
pub emergent_discovery_ms: u64,
pub feature_unification_ms: u64,
pub terms_searched: u64,
pub terms_unified: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OntologyRagRequest {
pub concept_sort_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub concept_values: Option<BTreeMap<String, f64>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub feature_config: Option<FeatureConfigDto>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub include_dependents: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub include_prerequisites: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub include_related: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_concepts: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min_degree: Option<f64>,
pub query_text: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub value_threshold: Option<f64>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct OntologyRagResponse {
#[serde(default)]
pub dependents: Vec<DependentInfoDto>,
#[serde(default)]
pub prerequisites: Vec<PrerequisiteInfoDto>,
#[serde(default)]
pub primary_concepts: Vec<ConceptMatchDto>,
#[serde(default)]
pub related: Vec<RelatedInfoDto>,
#[serde(default)]
pub stats: OntologyRagStatsDto,
}