use serde_json::{Map, Value};
use super::convs::AgentState;
use super::fields;
pub(crate) const KIND: &str = "attention";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct QueueRow {
pub workspace: String,
pub agent: String,
pub display: String,
pub state: AgentState,
pub uncertain: bool,
pub preview: String,
pub age_secs: i64,
pub pending: u64,
pub signals: Vec<String>,
pub failure: Option<String>,
pub flag: Option<Flag>,
pub held: Option<Held>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Flag {
pub at: String,
pub reason: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Held {
pub tool: String,
pub tool_use: String,
pub reason: String,
}
pub(crate) fn row(value: &Value) -> Result<QueueRow, String> {
let obj: &Map<String, Value> = value.as_object().ok_or("attention row: not an object")?;
Ok(QueueRow {
workspace: fields::text(obj, "workspace")?,
agent: fields::text(obj, "agent")?,
display: fields::text(obj, "display")?,
state: AgentState::of(&fields::text(obj, "state")?),
uncertain: fields::flag(obj, "uncertain")?,
preview: fields::text(obj, "preview")?,
age_secs: fields::secs(obj, "age_secs")?,
pending: fields::count(obj, "pending")?,
signals: fields::list(obj, "signals", word)?,
failure: fields::opt_text(obj, "failure")?,
flag: fields::nested(obj, "flag", flag)?,
held: fields::nested(obj, "held", held)?,
})
}
fn word(value: &Value) -> Result<String, String> {
value
.as_str()
.map(str::to_owned)
.ok_or_else(|| "signal: not a string".to_owned())
}
fn flag(obj: &Map<String, Value>) -> Result<Flag, String> {
Ok(Flag {
at: fields::text(obj, "at")?,
reason: fields::text(obj, "reason")?,
})
}
fn held(obj: &Map<String, Value>) -> Result<Held, String> {
Ok(Held {
tool: fields::text(obj, "tool")?,
tool_use: fields::text(obj, "tool_use")?,
reason: fields::text(obj, "reason")?,
})
}
#[cfg(test)]
mod tests;