extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum AgentState {
Spawned,
Running,
Suspended,
Terminal,
}
impl AgentState {
pub const fn as_str(self) -> &'static str {
match self {
Self::Spawned => "spawned",
Self::Running => "running",
Self::Suspended => "suspended",
Self::Terminal => "terminal",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum TerminalReason {
Completed,
Failed,
Killed,
Abandoned,
HostRestart,
}
impl TerminalReason {
pub const fn as_str(self) -> &'static str {
match self {
Self::Completed => "completed",
Self::Failed => "failed",
Self::Killed => "killed",
Self::Abandoned => "abandoned",
Self::HostRestart => "host_restart",
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct AgentRecord {
pub agent_id: String,
pub state: AgentState,
pub terminal_reason: Option<TerminalReason>,
pub provider: String,
pub provider_session_id: Option<String>,
pub checkpoint_session_id: Option<String>,
pub checkpoint_cursor: Option<i64>,
pub owner_actor: String,
pub owner_peer_class: String,
pub owner_write_namespace: String,
pub owner_visible_namespaces: Vec<String>,
pub spawn_fingerprint: String,
pub spawned_at: i64,
pub state_changed_at: i64,
pub idempotency_key: Option<String>,
}
#[cfg(all(test, feature = "serde"))]
mod tests {
use super::*;
#[test]
fn agent_state_as_str_matches_serde_wire_spelling() {
let cases = [
(AgentState::Spawned, "spawned"),
(AgentState::Running, "running"),
(AgentState::Suspended, "suspended"),
(AgentState::Terminal, "terminal"),
];
for (state, spelling) in cases {
let wire = serde_json::to_value(state).unwrap();
assert_eq!(wire.as_str(), Some(state.as_str()), "{state:?}");
assert_eq!(state.as_str(), spelling);
}
}
#[test]
fn terminal_reason_as_str_matches_serde_wire_spelling() {
let cases = [
(TerminalReason::Completed, "completed"),
(TerminalReason::Failed, "failed"),
(TerminalReason::Killed, "killed"),
(TerminalReason::Abandoned, "abandoned"),
(TerminalReason::HostRestart, "host_restart"),
];
for (reason, spelling) in cases {
let wire = serde_json::to_value(reason).unwrap();
assert_eq!(wire.as_str(), Some(reason.as_str()), "{reason:?}");
assert_eq!(reason.as_str(), spelling);
}
}
}