Skip to main content

scouter_types/genai/
traits.rs

1use crate::genai::{
2    utils::AssertionTasks, AgentAssertionTask, AssertionResult, AssertionTask, ComparisonOperator,
3    EvaluationTask, EvaluationTaskType, LLMJudgeTask, TraceAssertionTask,
4};
5use serde_json::Value;
6use std::fmt::Debug;
7
8pub trait TaskAccessor {
9    /// Returns optional context path - avoids `&Option<String>` pattern
10    fn context_path(&self) -> Option<&str>;
11
12    /// When `context_path` resolves to an array of objects, this path is applied to
13    /// each element to extract the value before the operator is evaluated.
14    fn item_context_path(&self) -> Option<&str>;
15
16    /// Returns assertion ID as string slice
17    fn id(&self) -> &str;
18
19    fn task_type(&self) -> &EvaluationTaskType;
20
21    /// Returns reference to comparison operator
22    fn operator(&self) -> &ComparisonOperator;
23
24    /// Returns reference to expected value
25    fn expected_value(&self) -> &Value;
26
27    /// Returns slice of dependency IDs - more efficient than `&Vec<String>`
28    fn depends_on(&self) -> &[String];
29
30    fn add_result(&mut self, result: AssertionResult);
31}
32
33pub fn separate_tasks(tasks: Vec<EvaluationTask>) -> AssertionTasks {
34    let mut llm_judges = Vec::new();
35    let mut assertions = Vec::new();
36    let mut trace_assertions = Vec::new();
37    let mut agent_assertions = Vec::new();
38
39    for task in tasks {
40        match task {
41            EvaluationTask::Assertion(a) => assertions.push(*a),
42            EvaluationTask::LLMJudge(j) => llm_judges.push(*j),
43            EvaluationTask::TraceAssertion(t) => trace_assertions.push(*t),
44            EvaluationTask::AgentAssertion(r) => agent_assertions.push(*r),
45        }
46    }
47
48    AssertionTasks {
49        assertion: assertions,
50        judge: llm_judges,
51        trace: trace_assertions,
52        agent: agent_assertions,
53    }
54}
55
56#[derive(Debug)]
57pub enum TaskRef<'a> {
58    Assertion(&'a mut AssertionTask),
59    LLMJudge(&'a mut LLMJudgeTask),
60    TraceAssertion(&'a mut TraceAssertionTask),
61    AgentAssertion(&'a mut AgentAssertionTask),
62}
63
64impl<'a> TaskRef<'a> {
65    pub fn depends_on(&self) -> &[String] {
66        match self {
67            TaskRef::Assertion(t) => t.depends_on(),
68            TaskRef::LLMJudge(t) => t.depends_on(),
69            TaskRef::TraceAssertion(t) => t.depends_on(),
70            TaskRef::AgentAssertion(t) => t.depends_on(),
71        }
72    }
73}
74
75/// Extension trait for evaluation profiles
76/// Provides unified access to assertions and LLM judge tasks
77pub trait ProfileExt {
78    fn id(&self) -> &str;
79    fn get_assertion_by_id(&self, id: &str) -> Option<&AssertionTask>;
80    fn get_llm_judge_by_id(&self, id: &str) -> Option<&LLMJudgeTask>;
81    fn get_trace_assertion_by_id(&self, id: &str) -> Option<&TraceAssertionTask>;
82    fn get_agent_assertion_by_id(&self, id: &str) -> Option<&AgentAssertionTask>;
83    fn get_task_by_id(&self, id: &str) -> Option<&dyn TaskAccessor>;
84    fn has_llm_tasks(&self) -> bool;
85    fn has_trace_assertions(&self) -> bool;
86    fn has_agent_assertions(&self) -> bool;
87}