Skip to main content

systemprompt_agent/services/agent_orchestration/
mod.rs

1//! Supervision of agent worker processes: lifecycle, monitoring, and
2//! reconciliation.
3//!
4//! This module groups the services that keep the database's view of running
5//! agents consistent with the OS process table. [`AgentOrchestrator`] is the
6//! top-level facade; the submodules cover process lifecycle, health
7//! monitoring, drift reconciliation, port allocation, the event bus, and the
8//! low-level process primitives. [`AgentStatus`] is the shared status model and
9//! [`OrchestrationError`] the unified error type.
10
11pub mod database;
12pub mod event_bus;
13pub mod events;
14pub mod lifecycle;
15pub mod monitor;
16pub mod orchestrator;
17pub mod port_service;
18pub mod process;
19pub mod reconciler;
20
21use systemprompt_identifiers::AgentId;
22
23pub use event_bus::AgentEventBus;
24pub use events::AgentEvent;
25pub use orchestrator::{AgentInfo, AgentOrchestrator};
26pub use port_service::PortService;
27
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub enum AgentStatus {
30    Running {
31        pid: u32,
32        port: u16,
33    },
34    Failed {
35        reason: String,
36        last_attempt: Option<String>,
37        retry_count: u32,
38    },
39}
40
41#[derive(Debug, Clone)]
42pub struct AgentRuntimeConfig {
43    pub id: AgentId,
44    pub name: String,
45    pub port: u16,
46}
47
48#[derive(Debug, Clone)]
49pub struct ValidationReport {
50    pub valid: bool,
51    pub issues: Vec<String>,
52}
53
54impl Default for ValidationReport {
55    fn default() -> Self {
56        Self::new()
57    }
58}
59
60impl ValidationReport {
61    pub const fn new() -> Self {
62        Self {
63            valid: true,
64            issues: Vec::new(),
65        }
66    }
67
68    pub fn with_issue(issue: String) -> Self {
69        Self {
70            valid: false,
71            issues: vec![issue],
72        }
73    }
74
75    pub fn add_issue(&mut self, issue: String) {
76        self.valid = false;
77        self.issues.push(issue);
78    }
79}
80
81use crate::services::shared::AgentServiceError;
82use thiserror::Error;
83
84#[derive(Error, Debug)]
85pub enum OrchestrationError {
86    #[error("Agent {0} not found")]
87    AgentNotFound(String),
88
89    #[error("Agent {0} already running")]
90    AgentAlreadyRunning(String),
91
92    #[error("Process spawn failed: {0}")]
93    ProcessSpawnFailed(String),
94
95    #[error("Database error: {0}")]
96    DatabaseError(#[from] sqlx::Error),
97
98    #[error("Database error: {0}")]
99    Database(String),
100
101    #[error("IO error: {0}")]
102    IoError(#[from] std::io::Error),
103
104    #[error("Health check timeout for agent {0}")]
105    HealthCheckTimeout(String),
106
107    #[error("Generic error: {0}")]
108    Generic(String),
109
110    #[error("agent: {0}")]
111    Agent(#[from] crate::error::AgentError),
112
113    #[error("Service error: {0}")]
114    AgentService(#[from] AgentServiceError),
115}
116
117pub type OrchestrationResult<T> = Result<T, OrchestrationError>;