use async_trait::async_trait;
use std::path::PathBuf;
use crate::vlm_bench::scoring::{self, LevelScore, Rating};
use crate::vlm_bench::{BenchScenario, Difficulty, ExpectedAnswer, VlmBenchLevel};
const PASS_THRESHOLD: f64 = 0.70;
pub struct L2Diagnostics {
fixtures_dir: PathBuf,
}
impl Default for L2Diagnostics {
fn default() -> Self {
Self::new()
}
}
impl L2Diagnostics {
pub fn new() -> Self {
Self {
fixtures_dir: PathBuf::from("vlm_fixtures/l2_diagnostics"),
}
}
}
#[async_trait]
impl VlmBenchLevel for L2Diagnostics {
fn name(&self) -> &str {
"L2 Diagnostics"
}
fn difficulty(&self) -> Difficulty {
Difficulty::Medium
}
fn description(&self) -> &str {
"Compiler diagnostic reading: identify error types, extract error codes (E0xxx), \
locate file:line references, and suggest fix categories from terminal screenshots."
}
fn scenarios(&self) -> Vec<BenchScenario> {
vec![
BenchScenario {
id: "l2_lifetime_error".into(),
description: "Identify a lifetime/borrow checker error".into(),
image_path: self.fixtures_dir.join("lifetime_error.png"),
prompt: "This screenshot shows a Rust compiler error. Analyze it and respond with JSON: \
{\"error_code\": \"E0xxx\", \"error_type\": \"<lifetime|borrow|type|trait>\", \
\"file\": \"<file path>\", \"line\": <line number>, \
\"fix_category\": \"<add lifetime annotation|clone|reference|restructure>\"}".into(),
expected: ExpectedAnswer::JsonFields(serde_json::json!({
"error_type": "lifetime"
})),
},
BenchScenario {
id: "l2_type_mismatch".into(),
description: "Identify a type mismatch error".into(),
image_path: self.fixtures_dir.join("type_mismatch.png"),
prompt: "This screenshot shows a Rust compiler error about type mismatches. \
Analyze it and respond with JSON: \
{\"error_code\": \"E0xxx\", \"error_type\": \"type\", \
\"expected_type\": \"<type>\", \"found_type\": \"<type>\", \
\"file\": \"<file path>\", \"line\": <line number>}".into(),
expected: ExpectedAnswer::Keywords(vec![
"type".into(),
"mismatch".into(),
"expected".into(),
]),
},
BenchScenario {
id: "l2_trait_bound".into(),
description: "Identify a trait bound error".into(),
image_path: self.fixtures_dir.join("trait_bound.png"),
prompt: "This screenshot shows a Rust compiler error about trait bounds. \
What trait is missing? Respond with JSON: \
{\"error_code\": \"E0xxx\", \"error_type\": \"trait\", \
\"missing_trait\": \"<trait name>\", \"on_type\": \"<type>\", \
\"fix_category\": \"<derive|impl|bound|where clause>\"}".into(),
expected: ExpectedAnswer::Keywords(vec![
"trait".into(),
"bound".into(),
]),
},
]
}
fn evaluate(&self, scenario: &BenchScenario, response: &str) -> LevelScore {
crate::vlm_bench::score_response(scenario, response, PASS_THRESHOLD)
}
}
#[cfg(test)]
#[path = "../../../tests/unit/vlm_bench/levels/l2_diagnostics/l2_diagnostics_test.rs"]
mod tests;