use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
fn default_true() -> bool {
true
}
fn default_worker_count() -> u32 {
1
}
fn default_version() -> u32 {
1
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct SuccessCriterion {
#[serde(alias = "id")]
pub id: String,
#[serde(alias = "description")]
pub description: String,
#[serde(rename = "type", alias = "criterion_type")]
pub criterion_type: CriterionType,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "verification_method"
)]
pub verification_method: Option<VerificationMethod>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "verification_config"
)]
pub verification_config: Option<serde_json::Value>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "evaluation_prompt"
)]
pub evaluation_prompt: Option<String>,
#[serde(default = "default_true", alias = "required")]
pub required: bool,
#[serde(default = "default_true", alias = "is_critical")]
pub is_critical: bool,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "weight")]
pub weight: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "domain")]
pub domain: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum CriterionType {
Deterministic,
AiEvaluated,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum VerificationMethod {
BuildSuccess,
UnitTest,
IntegrationTest,
Playwright,
LogPattern,
GuiAutomation,
TypeCheck,
LintCheck,
CustomCommand,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct VerificationPlan {
#[serde(alias = "goal_summary")]
pub goal_summary: String,
#[serde(alias = "success_criteria")]
pub success_criteria: Vec<SuccessCriterion>,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "execution_steps"
)]
pub execution_steps: Vec<serde_json::Value>,
#[serde(default = "default_worker_count", alias = "suggested_worker_count")]
pub suggested_worker_count: u32,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "worker_domains"
)]
pub worker_domains: Option<Vec<WorkerDomain>>,
#[serde(default = "default_version", alias = "version")]
pub version: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct WorkerDomain {
#[serde(alias = "worker_id")]
pub worker_id: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "specialization"
)]
pub specialization: Option<String>,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "file_patterns"
)]
pub file_patterns: Vec<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "system_prompt_additions"
)]
pub system_prompt_additions: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct DomainAssignment {
#[serde(alias = "domain_id")]
pub domain_id: String,
#[serde(alias = "name")]
pub name: String,
#[serde(alias = "description")]
pub description: String,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "file_patterns"
)]
pub file_patterns: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty", alias = "keywords")]
pub keywords: Vec<String>,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "assigned_workers"
)]
pub assigned_workers: Vec<String>,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "domain_criteria"
)]
pub domain_criteria: Vec<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "system_prompt_context"
)]
pub system_prompt_context: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum WorkerStatus {
Idle,
Active,
AwaitingVerification,
Paused,
Completed,
Error,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct WorkerInstance {
#[serde(alias = "worker_id")]
pub worker_id: String,
#[serde(alias = "name")]
pub name: String,
#[serde(alias = "status")]
pub status: WorkerStatus,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "domain")]
pub domain: Option<String>,
#[serde(alias = "iteration")]
pub iteration: u32,
#[serde(alias = "max_iterations")]
pub max_iterations: u32,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "last_signal"
)]
pub last_signal: Option<WorkerSignal>,
#[serde(default, skip_serializing_if = "Vec::is_empty", alias = "findings")]
pub findings: Vec<Finding>,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "touched_files"
)]
pub touched_files: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "started_at")]
pub started_at: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "completed_at"
)]
pub completed_at: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "error_message"
)]
pub error_message: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", content = "data")]
pub enum WorkerCoordinationMessage {
#[serde(rename = "files_modified")]
FilesModified {
worker_id: String,
files: Vec<String>,
},
#[serde(rename = "shared_finding")]
SharedFinding {
worker_id: String,
finding: Finding,
},
#[serde(rename = "blocked")]
Blocked {
worker_id: String,
waiting_for: String,
reason: String,
},
#[serde(rename = "ready_for_verification")]
ReadyForVerification {
worker_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
domain: Option<String>,
},
#[serde(rename = "sync_point")]
SyncPoint {
worker_ids: Vec<String>,
reason: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct DomainVerificationResult {
#[serde(alias = "domain_id")]
pub domain_id: String,
#[serde(alias = "worker_ids")]
pub worker_ids: Vec<String>,
#[serde(alias = "results")]
pub results: Vec<VerificationResult>,
#[serde(alias = "all_passed")]
pub all_passed: bool,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "failure_summary"
)]
pub failure_summary: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "signal", content = "data")]
pub enum WorkerSignal {
#[serde(rename = "work_complete")]
WorkComplete {
#[serde(default, skip_serializing_if = "Option::is_none")]
reason: Option<String>,
},
#[serde(rename = "need_replan")]
NeedReplan {
reason: String,
},
#[serde(rename = "continue")]
Continue,
#[serde(rename = "finding")]
Finding(Finding),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct Finding {
#[serde(alias = "id")]
pub id: String,
#[serde(alias = "finding_type")]
pub finding_type: String,
#[serde(alias = "description")]
pub description: String,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "evidence")]
pub evidence: Option<String>,
#[serde(alias = "confidence")]
pub confidence: Confidence,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "related_files"
)]
pub related_files: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum Confidence {
High,
Medium,
Low,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct VerificationResult {
#[serde(alias = "criterion_id")]
pub criterion_id: String,
#[serde(alias = "passed")]
pub passed: bool,
#[serde(alias = "criterion_type")]
pub criterion_type: CriterionType,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "confidence")]
pub confidence: Option<Confidence>,
#[serde(default, skip_serializing_if = "Vec::is_empty", alias = "observations")]
pub observations: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty", alias = "issues")]
pub issues: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty", alias = "suggestions")]
pub suggestions: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "raw_output")]
pub raw_output: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct IterationVerificationResults {
#[serde(alias = "iteration")]
pub iteration: u32,
#[serde(alias = "deterministic_results")]
pub deterministic_results: Vec<VerificationResult>,
#[serde(alias = "ai_results")]
pub ai_results: Vec<VerificationResult>,
#[serde(alias = "deterministic_passed")]
pub deterministic_passed: bool,
#[serde(alias = "ai_passed")]
pub ai_passed: bool,
#[serde(alias = "all_passed")]
pub all_passed: bool,
#[serde(
default,
skip_serializing_if = "Option::is_none",
alias = "failure_summary"
)]
pub failure_summary: Option<String>,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "applied_overrides"
)]
pub applied_overrides: Vec<CriterionOverride>,
#[serde(
default,
skip_serializing_if = "Vec::is_empty",
alias = "overridden_criteria"
)]
pub overridden_criteria: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct VerificationAgentContext {
#[serde(alias = "screenshot_base64")]
pub screenshot_base64: String,
#[serde(alias = "evaluation_prompt")]
pub evaluation_prompt: String,
#[serde(alias = "goal_context")]
pub goal_context: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ExtendIterationsRequest {
#[serde(alias = "additional_iterations")]
pub additional_iterations: u32,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "guidance")]
pub guidance: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct CriterionOverride {
#[serde(alias = "criterion_id")]
pub criterion_id: String,
#[serde(alias = "item")]
pub item: String,
#[serde(alias = "justification")]
pub justification: String,
#[serde(alias = "iteration")]
pub iteration: u32,
#[serde(default, skip_serializing_if = "Option::is_none", alias = "worker_id")]
pub worker_id: Option<String>,
#[serde(alias = "recorded_at")]
pub recorded_at: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct OverrideCollection {
#[serde(default, skip_serializing_if = "Vec::is_empty", alias = "overrides")]
pub overrides: Vec<CriterionOverride>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "status")]
pub enum TaskCompletionResult {
#[serde(rename = "success")]
Success {
iterations: u32,
findings: Vec<Finding>,
verification_results: IterationVerificationResults,
},
#[serde(rename = "failed")]
Failed {
reason: String,
iterations: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
last_results: Option<IterationVerificationResults>,
findings: Vec<Finding>,
},
#[serde(rename = "stopped")]
Stopped {
at_iteration: u32,
findings: Vec<Finding>,
can_resume: bool,
},
#[serde(rename = "paused")]
Paused {
at_iteration: u32,
max_iterations: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
last_results: Option<IterationVerificationResults>,
findings: Vec<Finding>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct StageTransition {
#[serde(alias = "from")]
pub from: String,
#[serde(alias = "to")]
pub to: String,
#[serde(alias = "timestamp")]
pub timestamp: String,
#[serde(alias = "iteration")]
pub iteration: u32,
}