#![allow(dead_code, unused_imports, unused_variables)]
pub mod config;
pub mod fixtures;
pub mod levels;
pub mod report;
pub mod runner;
pub mod scoring;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum Difficulty {
Easy,
Medium,
Hard,
VeryHard,
Extreme,
Mega,
}
impl std::fmt::Display for Difficulty {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Easy => write!(f, "Easy"),
Self::Medium => write!(f, "Medium"),
Self::Hard => write!(f, "Hard"),
Self::VeryHard => write!(f, "Very Hard"),
Self::Extreme => write!(f, "Extreme"),
Self::Mega => write!(f, "Mega"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BenchScenario {
pub id: String,
pub description: String,
pub image_path: PathBuf,
pub prompt: String,
pub expected: ExpectedAnswer,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExpectedAnswer {
Keywords(Vec<String>),
JsonFields(serde_json::Value),
KeyValuePairs(Vec<(String, String)>),
VisualScores(Vec<f64>),
}
#[async_trait]
pub trait VlmBenchLevel: Send + Sync {
fn name(&self) -> &str;
fn difficulty(&self) -> Difficulty;
fn description(&self) -> &str;
fn scenarios(&self) -> Vec<BenchScenario>;
fn evaluate(&self, scenario: &BenchScenario, response: &str) -> scoring::LevelScore;
}
pub(crate) fn score_response(
scenario: &BenchScenario,
response: &str,
pass_threshold: f64,
) -> scoring::LevelScore {
let (accuracy, details) = match &scenario.expected {
ExpectedAnswer::Keywords(keywords) => {
let acc = scoring::keyword_accuracy(response, keywords);
let details = keywords
.iter()
.map(|kw| {
let found = response.to_lowercase().contains(&kw.to_lowercase());
(kw.clone(), if found { 1.0 } else { 0.0 })
})
.collect();
(acc, details)
}
ExpectedAnswer::JsonFields(expected) => scoring::json_field_accuracy(response, expected),
_ => (0.0, vec![]),
};
let rating = scoring::Rating::from_accuracy(accuracy, pass_threshold);
scoring::LevelScore {
accuracy,
detail_scores: details,
response_tokens: 0,
latency_ms: 0,
rating,
}
}
#[cfg(test)]
#[path = "../../tests/unit/vlm_bench/mod_test.rs"]
mod tests;