agentics_domain/models/challenge/
metrics.rs1use serde::{Deserialize, Serialize};
2
3use super::super::names::MetricName;
4use super::serde_helpers::{
5 required_nullable, required_nullable_non_empty_vec, required_nullable_non_empty_vec_schema,
6 required_nullable_schema, serialize_empty_vec_as_null,
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
11#[serde(rename_all = "snake_case")]
12pub enum MetricDirection {
13 Maximize,
14 Minimize,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)]
19#[serde(rename_all = "snake_case")]
20pub enum MetricVisibility {
21 Public,
23 Official,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
29#[serde(deny_unknown_fields)]
30pub struct MetricDefinitionSpec {
31 pub name: MetricName,
32 pub label: String,
33 #[serde(deserialize_with = "required_nullable")]
34 #[schemars(required, schema_with = "required_nullable_schema::<String>")]
35 pub unit: Option<String>,
36 pub direction: MetricDirection,
37 pub visibility: MetricVisibility,
38 #[serde(deserialize_with = "required_nullable")]
39 #[schemars(required, schema_with = "required_nullable_schema::<String>")]
40 pub metric_description: Option<String>,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
45#[serde(deny_unknown_fields)]
46pub struct RankingSpec {
47 pub primary_metric_name: MetricName,
48 #[serde(
49 deserialize_with = "required_nullable_non_empty_vec",
50 serialize_with = "serialize_empty_vec_as_null"
51 )]
52 #[schemars(
53 required,
54 schema_with = "required_nullable_non_empty_vec_schema::<MetricName>"
55 )]
56 pub tie_breaker_metric_names: Vec<MetricName>,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
61#[serde(deny_unknown_fields)]
62pub struct MetricSchemaSpec {
63 pub metrics: Vec<MetricDefinitionSpec>,
64 pub ranking: RankingSpec,
65}
66
67impl MetricSchemaSpec {
68 pub fn metric(&self, metric_name: &MetricName) -> Option<&MetricDefinitionSpec> {
70 self.metrics
71 .iter()
72 .find(|metric| &metric.name == metric_name)
73 }
74
75 pub fn primary_metric(&self) -> Option<&MetricDefinitionSpec> {
77 self.metric(&self.ranking.primary_metric_name)
78 }
79}
80
81impl Default for MetricSchemaSpec {
82 fn default() -> Self {
84 Self {
85 metrics: vec![MetricDefinitionSpec {
86 name: MetricName::score(),
87 label: "Score".to_string(),
88 unit: None,
89 direction: MetricDirection::Maximize,
90 visibility: MetricVisibility::Public,
91 metric_description: Some("Challenge-defined compatibility score.".to_string()),
92 }],
93 ranking: RankingSpec {
94 primary_metric_name: MetricName::score(),
95 tie_breaker_metric_names: vec![],
96 },
97 }
98 }
99}