agent-fleet/src/core/models.rs
Zer4tul 4e01728a67 feat: implement orchestrator core (Rust)
Task 1.1:  Cargo.toml with axum, rusqlite, matrix-sdk, serde, etc.
Task 1.2:  Directory structure: src/core, src/adapters, src/integrations, src/api
Task 1.5:  config.example.toml with full schema
Task 2.1:  Data models: Agent, Task, Receipt, Artifact, TaskEvent
Task 2.2:  Event Store: SQLite append-only with task/agent tables
Task 2.3:  Task state machine: created→assigned→running→completed/failed
Task 2.4:  Global task queue with priority ordering
Task 2.5:  Background timeout checker
Task 2.6:  Retry policy with configurable max_retries

Compiles clean (warnings only, no errors).
API handler stubs in place for Phase 2.
2026-05-11 14:57:23 +08:00

145 lines
4 KiB
Rust

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
// ─── Agent ───────────────────────────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "kebab-case")]
pub enum AgentType {
OpenClaw,
ClaudeCode,
CodexCli,
Hermes,
Acp,
Shell,
Other(String),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum AgentStatus {
Online,
Offline,
Draining,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Agent {
pub agent_id: String,
pub agent_type: AgentType,
pub hostname: String,
pub capabilities: Vec<String>,
pub max_concurrency: u32,
pub current_tasks: u32,
pub status: AgentStatus,
pub last_heartbeat_at: DateTime<Utc>,
pub registered_at: DateTime<Utc>,
pub metadata: std::collections::HashMap<String, String>,
}
// ─── Task ────────────────────────────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum TaskStatus {
Created,
Assigned,
Running,
Completed,
Failed,
AgentLost,
Cancelled,
}
impl TaskStatus {
pub fn as_str(&self) -> &'static str {
match self {
Self::Created => "created",
Self::Assigned => "assigned",
Self::Running => "running",
Self::Completed => "completed",
Self::Failed => "failed",
Self::AgentLost => "agent_lost",
Self::Cancelled => "cancelled",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
pub enum Priority {
Low,
Normal,
High,
Urgent,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Task {
pub task_id: String,
pub source: String, // "forgejo:<repo>#<issue>"
pub task_type: String, // "code", "review", "test", "deploy", "research"
pub priority: Priority,
pub status: TaskStatus,
pub assigned_agent_id: Option<String>,
pub requirements: String, // Issue body
pub labels: Vec<String>,
pub created_at: DateTime<Utc>,
pub assigned_at: Option<DateTime<Utc>>,
pub started_at: Option<DateTime<Utc>>,
pub completed_at: Option<DateTime<Utc>>,
pub retry_count: u32,
pub max_retries: u32,
pub timeout_seconds: u64,
}
// ─── Receipt ─────────────────────────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ReceiptStatus {
Completed,
Failed,
Partial,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ArtifactType {
Pr,
Commit,
File,
Comment,
Url,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Artifact {
pub artifact_type: ArtifactType,
pub url: Option<String>,
pub path: Option<String>,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Receipt {
pub task_id: String,
pub agent_id: String,
pub status: ReceiptStatus,
pub duration_seconds: u64,
pub summary: String,
pub artifacts: Vec<Artifact>,
pub error: Option<String>,
}
// ─── TaskEvent (event sourcing) ──────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskEvent {
pub event_id: String,
pub task_id: String,
pub event_type: String,
pub agent_id: Option<String>,
pub timestamp: DateTime<Utc>,
pub payload: serde_json::Value,
}