use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ChoiceQuestion {
pub instructions: String,
pub criteria: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ScoreQuestion {
pub instructions: String,
pub criteria: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct NoulQuestion {
pub instructions: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type")]
pub enum Question {
#[serde(rename = "choice")]
Choice(ChoiceQuestion),
#[serde(rename = "score")]
Score(ScoreQuestion),
#[serde(rename = "noul")]
Noul(NoulQuestion),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ChoiceAnswer {
pub choice: String,
pub confidence: f64,
#[serde(default)]
pub probabilities: Option<HashMap<String, f64>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ScoreAnswer {
pub score: i32,
pub confidence: f64,
#[serde(default)]
pub legend: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct NoulAnswer {
pub noul: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type")]
pub enum Answer {
#[serde(rename = "choice")]
Choice(ChoiceAnswer),
#[serde(rename = "score")]
Score(ScoreAnswer),
#[serde(rename = "noul")]
Noul(NoulAnswer),
}
impl Answer {
pub fn as_choice(&self) -> Option<&ChoiceAnswer> {
match self {
Answer::Choice(a) => Some(a),
_ => None,
}
}
pub fn as_score(&self) -> Option<&ScoreAnswer> {
match self {
Answer::Score(a) => Some(a),
_ => None,
}
}
pub fn as_noul(&self) -> Option<&NoulAnswer> {
match self {
Answer::Noul(a) => Some(a),
_ => None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct JevUsage {
#[serde(default)]
pub input_tokens: u32,
#[serde(default)]
pub output_tokens: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct JevResponse {
pub model: String,
pub answers: HashMap<String, Answer>,
#[serde(default)]
pub usage: JevUsage,
#[serde(default)]
pub is_mock: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TestTriageResult {
pub category: String,
pub confidence: f64,
pub skip_llm: bool,
pub skip_llm_prob: f64,
pub severity_score: f64,
pub action_recommendation: String,
pub is_mock: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AbortGateResult {
pub should_abort: bool,
pub abort_probability: f64,
pub action: String,
pub viability_score: f64,
pub reasoning_summary: String,
pub is_mock: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ModelRouteResult {
pub selected_tier: String,
pub confidence: f64,
pub complexity_score: f64,
pub recommended_model: String,
pub rationale: String,
pub is_mock: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VerificationResult {
pub is_verified: bool,
pub satisfaction_probability: f64,
pub rigor_score: f64,
pub confidence: f64,
pub needs_rework: bool,
pub is_mock: bool,
}
#[derive(Debug)]
pub enum JevError {
Http(reqwest::Error),
Json(serde_json::Error),
Config(String),
Api { status: u16, message: String },
}
impl std::fmt::Display for JevError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
JevError::Http(e) => write!(f, "HTTP error: {}", e),
JevError::Json(e) => write!(f, "JSON serialization error: {}", e),
JevError::Config(m) => write!(f, "Configuration error: {}", m),
JevError::Api { status, message } => {
write!(f, "API error (HTTP {}): {}", status, message)
}
}
}
}
impl std::error::Error for JevError {}
impl From<reqwest::Error> for JevError {
fn from(e: reqwest::Error) -> Self {
JevError::Http(e)
}
}
impl From<serde_json::Error> for JevError {
fn from(e: serde_json::Error) -> Self {
JevError::Json(e)
}
}