Files
zesdex/src/app/harness.rs
T

67 lines
1.8 KiB
Rust
Raw Normal View History

#[derive(Debug, Clone, PartialEq)]
pub enum Verdict {
Allow,
Block(String),
Escalate,
}
impl Verdict {
pub fn is_allowed(&self) -> bool {
matches!(self, Verdict::Allow)
}
}
pub struct Harness;
impl Harness {
pub fn classify(_cmd: &str, mode: &super::state::types::AgentMode) -> Verdict {
if mode.auto_approve() {
return Verdict::Allow;
}
Verdict::Allow
}
}
pub fn parse_verdict(text: &str) -> Option<Verdict> {
let trimmed = text.trim();
if let Ok(v) = serde_json::from_str::<serde_json::Value>(trimmed) {
if let Some(verdict) = v.get("verdict").and_then(|v| v.as_str()) {
return match verdict.to_lowercase().as_str() {
"allow" => Some(Verdict::Allow),
"block" => Some(Verdict::Block(
v.get("reason").and_then(|r| r.as_str()).unwrap_or("blocked").to_string()
)),
"escalate" => Some(Verdict::Escalate),
_ => None,
};
}
}
for line in trimmed.lines() {
let l = line.trim().to_lowercase();
if l.starts_with("verdict: allow") {
return Some(Verdict::Allow);
}
if l.starts_with("verdict: block") {
let reason = line.split_once(':').map(|x| x.1).unwrap_or("blocked").trim().to_string();
return Some(Verdict::Block(reason));
}
}
if trimmed.to_lowercase().contains("allow") {
return Some(Verdict::Allow);
}
if trimmed.to_lowercase().contains("block") {
return Some(Verdict::Block("blocked by classifier".to_string()));
}
None
}
pub fn classify(_cmd: &str, mode: &super::state::types::AgentMode) -> Verdict {
Harness::classify(_cmd, mode)
}
impl Default for Harness {
fn default() -> Self {
Harness
}
}