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.
This commit is contained in:
Zer4tul 2026-05-11 14:57:23 +08:00
parent e983955036
commit 4e01728a67
15 changed files with 5220 additions and 3 deletions

76
src/config.rs Normal file
View file

@ -0,0 +1,76 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub server: ServerConfig,
pub forgejo: ForgejoConfig,
pub matrix: MatrixConfig,
pub orchestrator: OrchestratorConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerConfig {
pub bind: String,
pub port: u16,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForgejoConfig {
pub url: String,
pub token: String,
pub webhook_secret: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MatrixConfig {
pub homeserver_url: String,
pub user_id: String,
pub access_token: String,
pub room_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrchestratorConfig {
pub db_path: String,
pub heartbeat_interval_secs: u64,
pub heartbeat_timeout_threshold: u32,
pub task_timeout_secs: u64,
pub default_max_retries: u32,
}
impl Default for Config {
fn default() -> Self {
Self {
server: ServerConfig {
bind: "0.0.0.0".into(),
port: 9090,
},
forgejo: ForgejoConfig {
url: "https://git.0x08.org".into(),
token: String::new(),
webhook_secret: String::new(),
},
matrix: MatrixConfig {
homeserver_url: "https://matrix.0x08.org".into(),
user_id: "@jeeves:0x08.org".into(),
access_token: String::new(),
room_id: String::new(),
},
orchestrator: OrchestratorConfig {
db_path: "data/agent-fleet.db".into(),
heartbeat_interval_secs: 60,
heartbeat_timeout_threshold: 3,
task_timeout_secs: 1800,
default_max_retries: 2,
},
}
}
}
impl Config {
pub fn load(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
let content = std::fs::read_to_string(path)?;
let config: Config = toml::from_str(&content)?;
Ok(config)
}
}