Skip to main content

context_forge/lexicon/
defaults.rs

1use crate::entry::ContextEntry;
2
3use super::config::ConfigLexiconScorer;
4use super::LexiconScorer;
5
6const DEFAULT_ENGLISH_TOML: &str = include_str!("english_defaults.toml");
7
8/// Always-on baseline scorer for plain-English importance signals.
9///
10/// Recognizes common English affirmations (`"confirmed"`, `"that's correct"`,
11/// `"remember this"`) and negations (`"incorrect"`, `"never mind"`,
12/// `"disregard"`). Applied by the builder automatically alongside any persona
13/// scorer — no configuration required.
14///
15/// Domain-specific terms and persona vocabulary belong in
16/// [`ConfigLexiconScorer`]; this scorer handles the English layer that exists
17/// regardless of persona. A user speaking plain English to a Warhammer 40k
18/// bot still uses phrases like "confirmed" and "that's wrong" — those signals
19/// should not be invisible to the importance scorer just because no persona
20/// config is loaded.
21#[derive(Debug, Clone)]
22pub struct DefaultEnglishScorer(ConfigLexiconScorer);
23
24impl Default for DefaultEnglishScorer {
25    fn default() -> Self {
26        Self(
27            DEFAULT_ENGLISH_TOML
28                .parse()
29                .expect("built-in English config is valid TOML"),
30        )
31    }
32}
33
34impl LexiconScorer for DefaultEnglishScorer {
35    fn score(&self, entry: &ContextEntry, query: &str) -> f32 {
36        self.0.score(entry, query)
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43    use crate::entry::kind;
44
45    fn entry(content: &str) -> ContextEntry {
46        ContextEntry {
47            id: "test".into(),
48            content: content.into(),
49            timestamp: 0,
50            kind: kind::MANUAL.to_owned(),
51            scope: None,
52            session_id: None,
53            token_count: None,
54            metadata: None,
55        }
56    }
57
58    #[test]
59    fn affirmation_boosts_english_confirmation() {
60        let scorer = DefaultEnglishScorer::default();
61        let boost = scorer.score(&entry("confirmed, that will work"), "");
62        assert!(boost > 0.0, "expected affirmation boost, got {boost}");
63    }
64
65    #[test]
66    fn negation_reduces_english_denial() {
67        let scorer = DefaultEnglishScorer::default();
68        let boost = scorer.score(&entry("never mind, ignore that approach"), "");
69        assert!(boost < 0.0, "expected negation reduction, got {boost}");
70    }
71
72    #[test]
73    fn neutral_content_scores_zero() {
74        let scorer = DefaultEnglishScorer::default();
75        let boost = scorer.score(&entry("the quick brown fox jumps over the lazy dog"), "");
76        assert!(boost.abs() < f32::EPSILON);
77    }
78}