use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use systemprompt_identifiers::{FactKindId, WorkflowId};
use crate::brain::source::SourceClass;
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, default)]
pub struct ImportanceConfig {
pub base: BaseImportance,
pub in_context: InContextImportance,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, default)]
pub struct BaseImportance {
pub kind_weight: BTreeMap<FactKindId, f64>,
pub source_weight: BTreeMap<SourceClass, f64>,
pub model_hint: Option<ModelHint>,
pub confirmed_by_owner: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ModelHint {
pub field: String,
pub weight: f64,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, default)]
pub struct InContextImportance {
pub workflow_weight: BTreeMap<WorkflowId, BTreeMap<FactKindId, f64>>,
pub subject_match: f64,
pub recency: Recency,
pub usage: UsageWeights,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, default)]
pub struct Recency {
pub half_life_days: u32,
}
impl Default for Recency {
fn default() -> Self {
Self { half_life_days: 90 }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, default)]
pub struct UsageWeights {
pub cited_rate_weight: f64,
pub ignored_penalty: f64,
}
impl Default for UsageWeights {
fn default() -> Self {
Self {
cited_rate_weight: 0.2,
ignored_penalty: 0.1,
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, default)]
pub struct RetrievalDoc {
pub tiers: TierWeights,
pub rrf_k: u32,
pub max_facts: u32,
pub quotas: BTreeMap<FactKindId, u32>,
pub links_weight: f64,
pub search_max_df: f64,
pub search_quorum: f64,
pub search_retry_quorum: f64,
pub search_quorum_over: QuorumUnit,
pub alias_min_sim: f64,
pub max_subjects: u32,
pub fill_order: FillOrder,
pub linked_share: f64,
pub min_fused_score: f64,
pub context_share: f64,
pub usage_weight: f64,
pub usage_min_recalls: u32,
pub extension_max_candidates: u32,
pub context_requires_signal: bool,
pub full_text_opens_context: bool,
pub search_stop_words: Vec<String>,
pub search_max_ndoc: u32,
pub search_rare_alone_share: f64,
pub subject_limit: u32,
pub alias_longest_wins: bool,
pub unknown_name_withholds_full_text: bool,
pub links_depth: u32,
pub links_decay: f64,
pub links_require_readable_anchor: bool,
pub reranker_timeout_ms: u32,
}
impl Default for RetrievalDoc {
fn default() -> Self {
Self {
tiers: TierWeights::default(),
rrf_k: 60,
max_facts: 12,
quotas: BTreeMap::new(),
links_weight: 0.6,
search_max_df: 0.2,
search_quorum: 0.5,
search_retry_quorum: 0.0,
search_quorum_over: QuorumUnit::default(),
alias_min_sim: 0.6,
max_subjects: 4,
fill_order: FillOrder::default(),
linked_share: 0.0,
min_fused_score: 0.0,
context_share: 1.0,
usage_weight: 0.0,
usage_min_recalls: 0,
extension_max_candidates: 24,
context_requires_signal: false,
full_text_opens_context: true,
search_stop_words: Vec::new(),
search_max_ndoc: 0,
search_rare_alone_share: 0.0,
subject_limit: 0,
alias_longest_wins: false,
unknown_name_withholds_full_text: false,
links_depth: 1,
links_decay: 0.5,
links_require_readable_anchor: false,
reranker_timeout_ms: 150,
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum QuorumUnit {
#[default]
Groups,
Words,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FillOrder {
#[default]
Rank,
Importance,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, default)]
pub struct TierWeights {
pub pinned: f64,
pub subject: f64,
pub linked: f64,
pub context: f64,
pub full_text: f64,
pub extension: f64,
}
impl Default for TierWeights {
fn default() -> Self {
Self {
pinned: 1.0,
subject: 1.0,
linked: 0.6,
context: 0.8,
full_text: 0.6,
extension: 0.0,
}
}
}