Skip to main content

vv_agent/
output_validation.rs

1use std::sync::Arc;
2
3use crate::model::ModelRef;
4use crate::model_settings::ModelSettings;
5
6pub const OUTPUT_VALIDATION_FAILED: &str = "output_validation_failed";
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct OutputValidationContext {
10    pub run_id: String,
11    pub agent_name: String,
12    pub output_type_name: Option<&'static str>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct OutputValidationResult {
17    pub valid: bool,
18    pub code: Option<String>,
19    pub message: Option<String>,
20}
21
22impl OutputValidationResult {
23    pub fn accept() -> Self {
24        Self {
25            valid: true,
26            code: None,
27            message: None,
28        }
29    }
30
31    pub fn reject(code: impl Into<String>, message: Option<impl Into<String>>) -> Self {
32        Self {
33            valid: false,
34            code: Some(code.into()),
35            message: message.map(Into::into),
36        }
37    }
38
39    pub fn reject_code(code: impl Into<String>) -> Self {
40        Self::reject(code, None::<String>)
41    }
42
43    pub(crate) fn normalized(self) -> Self {
44        if self.valid {
45            if self.code.is_none() && self.message.is_none() {
46                return self;
47            }
48            return Self::reject(
49                "output_validator_contract_invalid",
50                Some("a valid output result cannot contain an error"),
51            );
52        }
53        if self.code.as_deref().is_none_or(str::is_empty)
54            || self
55                .code
56                .as_deref()
57                .is_some_and(|code| code.trim().is_empty())
58        {
59            return Self::reject(
60                "output_validator_contract_invalid",
61                Some("an invalid output result requires a non-empty code"),
62            );
63        }
64        self
65    }
66}
67
68#[derive(Debug, Clone, PartialEq)]
69pub struct OutputRepairRequest {
70    pub invalid_output: String,
71    pub validation_code: String,
72    pub validation_message: Option<String>,
73    pub model: Option<ModelRef>,
74    pub model_settings: Option<ModelSettings>,
75    pub tools: Vec<serde_json::Value>,
76}
77
78pub type HostOutputValidator =
79    Arc<dyn Fn(&str, &OutputValidationContext) -> OutputValidationResult + Send + Sync>;
80pub type OutputRepair = Arc<dyn Fn(&OutputRepairRequest) -> Result<String, String> + Send + Sync>;