use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum AgentState {
Working,
Blocked,
WaitingReview,
Idle,
}
impl AgentState {
pub fn as_str(&self) -> &'static str {
match self {
Self::Working => "working",
Self::Blocked => "blocked",
Self::WaitingReview => "waiting_review",
Self::Idle => "idle",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentStatusSnapshot {
pub state: AgentState,
pub task_id: Option<String>,
pub blocked_reason: Option<String>,
pub waiting_on_agent: Option<String>,
pub checkpoint: Option<String>,
pub working_on: String,
}
impl Default for AgentStatusSnapshot {
fn default() -> Self {
Self {
state: AgentState::Working,
task_id: None,
blocked_reason: None,
waiting_on_agent: None,
checkpoint: None,
working_on: "heartbeat via WS".into(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeartbeatRequest {
pub agent_id: String,
pub status: AgentStatusSnapshot,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeartbeatResponse {
pub accepted: bool,
pub nudges: Vec<NudgeMessage>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NudgeMessage {
pub reason: String,
pub severity: NudgeSeverity,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum NudgeSeverity {
Info,
Warning,
Blocking,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NudgeConfig {
pub stale_threshold_minutes: i64,
pub check_interval_seconds: u64,
}
impl Default for NudgeConfig {
fn default() -> Self {
Self {
stale_threshold_minutes: 5,
check_interval_seconds: 30,
}
}
}