use std::path::PathBuf;
use thiserror::Error;
use crate::EvalSetResult;
pub mod console;
#[cfg(feature = "html-report")]
pub mod html;
pub mod json;
#[cfg(feature = "langsmith")]
pub mod langsmith;
pub mod markdown;
pub use console::ConsoleReporter;
#[cfg(feature = "html-report")]
pub use html::HtmlReporter;
pub use json::{JsonReporter, SCHEMA_VERSION};
#[cfg(feature = "langsmith")]
pub use langsmith::{LangSmithExportError, LangSmithExporter};
pub use markdown::MarkdownReporter;
pub const JSON_SCHEMA_PATH: &str = "specs/043-evals-adv-features/contracts/eval-result.schema.json";
pub trait Reporter: Send + Sync {
fn render(&self, result: &EvalSetResult) -> Result<ReporterOutput, ReporterError>;
}
#[derive(Debug, Clone)]
pub enum ReporterOutput {
Stdout(String),
Artifact {
path: PathBuf,
bytes: Vec<u8>,
},
Remote {
backend: String,
identifier: String,
},
}
#[derive(Debug, Error)]
pub enum ReporterError {
#[error("reporter I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("reporter formatting error: {0}")]
Format(String),
#[error("reporter network error: {0}")]
Network(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reporter_error_from_io() {
let io_err = std::io::Error::other("boom");
let err: ReporterError = io_err.into();
assert!(err.to_string().contains("boom"));
assert!(matches!(err, ReporterError::Io(_)));
}
#[test]
fn reporter_output_variants_are_constructible() {
let _stdout = ReporterOutput::Stdout("hello".into());
let _artifact = ReporterOutput::Artifact {
path: PathBuf::from("/tmp/out.json"),
bytes: vec![0xDE, 0xAD, 0xBE, 0xEF],
};
let _remote = ReporterOutput::Remote {
backend: "langsmith".into(),
identifier: "run-1234".into(),
};
}
#[test]
fn schema_path_constant_points_at_repo_contract() {
assert!(JSON_SCHEMA_PATH.ends_with("eval-result.schema.json"));
}
}