use crate::otel::conventions as c;
use tracing::field::Empty;
#[derive(Debug, Clone)]
pub struct EvalResult {
name: String,
score_value: Option<f64>,
score_label: Option<String>,
explanation: Option<String>,
response_id: Option<String>,
error_type: Option<String>,
}
impl EvalResult {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
score_value: None,
score_label: None,
explanation: None,
response_id: None,
error_type: None,
}
}
pub fn with_score_value(mut self, value: f64) -> Self {
self.score_value = Some(value);
self
}
pub fn with_score_label(mut self, label: impl Into<String>) -> Self {
self.score_label = Some(label.into());
self
}
pub fn with_explanation(mut self, explanation: impl Into<String>) -> Self {
self.explanation = Some(explanation.into());
self
}
pub fn with_response_id(mut self, response_id: impl Into<String>) -> Self {
self.response_id = Some(response_id.into());
self
}
pub fn with_error_type(mut self, error_type: impl Into<String>) -> Self {
self.error_type = Some(error_type.into());
self
}
pub fn emit(&self) {
let span = tracing::info_span!(
"genai.evaluation.result",
"otel.name" = "gen_ai.evaluation.result",
"otel.kind" = c::KIND_INTERNAL,
"otel.status_code" = Empty,
"gen_ai.evaluation.name" = self.name.as_str(),
"gen_ai.evaluation.score.value" = Empty,
"gen_ai.evaluation.score.label" = Empty,
"gen_ai.evaluation.explanation" = Empty,
"gen_ai.response.id" = Empty,
"error.type" = Empty,
);
if let Some(score_value) = self.score_value {
span.record(c::EVALUATION_SCORE_VALUE, score_value);
}
if let Some(score_label) = &self.score_label {
span.record(c::EVALUATION_SCORE_LABEL, score_label.as_str());
}
if let Some(explanation) = &self.explanation {
span.record(c::EVALUATION_EXPLANATION, explanation.as_str());
}
if let Some(response_id) = &self.response_id {
span.record(c::RESPONSE_ID, response_id.as_str());
}
if let Some(error_type) = &self.error_type {
span.record(c::OTEL_STATUS_CODE, c::STATUS_ERROR);
span.record(c::ERROR_TYPE, error_type.as_str());
}
}
}