Skip to main content

atomr_agents_eval/
scorer.rs

1use atomr_agents_core::Value;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ScorerOutcome {
6    pub passed: bool,
7    pub score: f32,
8    pub note: String,
9}
10
11pub trait Scorer: Send + Sync + 'static {
12    fn score(&self, expected: &Value, actual: &Value) -> ScorerOutcome;
13}
14
15/// Trivial substring-presence scorer.
16pub struct ContainsScorer;
17
18impl Scorer for ContainsScorer {
19    fn score(&self, expected: &Value, actual: &Value) -> ScorerOutcome {
20        let needle = expected
21            .get("must_contain")
22            .and_then(|v| v.as_str())
23            .unwrap_or("");
24        let hay = match actual {
25            Value::String(s) => s.clone(),
26            other => serde_json::to_string(other).unwrap_or_default(),
27        };
28        let passed = hay.contains(needle);
29        ScorerOutcome {
30            passed,
31            score: if passed { 1.0 } else { 0.0 },
32            note: if passed {
33                format!("found {needle:?}")
34            } else {
35                format!("missing {needle:?} in {hay:?}")
36            },
37        }
38    }
39}