From 999ecf644f58af7de0b0a36b22a69897d8056a1c Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 1 Feb 2026 00:47:02 +0000 Subject: [WIP] Heartbeat checkpoint - 2026-02-01 00:47:02 UTC --- makima/src/daemon/ws/protocol.rs | 103 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'makima/src/daemon') diff --git a/makima/src/daemon/ws/protocol.rs b/makima/src/daemon/ws/protocol.rs index bfe6326..8c2994a 100644 --- a/makima/src/daemon/ws/protocol.rs +++ b/makima/src/daemon/ws/protocol.rs @@ -397,6 +397,63 @@ pub enum DaemonMessage { #[serde(rename = "baseSha")] base_sha: String, }, + + // ========================================================================= + // Supervisor State Update Messages (Phase 3: Crash Recovery) + // ========================================================================= + + /// Supervisor state update for crash recovery. + /// Sent periodically or at key save points to persist state. + SupervisorStateUpdate { + /// Task ID of the supervisor. + #[serde(rename = "taskId")] + task_id: Uuid, + /// Contract ID. + #[serde(rename = "contractId")] + contract_id: Uuid, + /// Save point type that triggered this update. + #[serde(rename = "savePoint")] + save_point: String, + /// Current supervisor activity state. + state: Option, + /// Human-readable current activity. + #[serde(rename = "currentActivity")] + current_activity: Option, + /// Progress percentage (0-100). + progress: Option, + /// Last LLM response for context restoration. + #[serde(rename = "lastLlmResponse")] + last_llm_response: Option, + /// Task that was just spawned (if save_point is "task_spawn"). + #[serde(rename = "spawnedTaskId")] + spawned_task_id: Option, + /// Question ID (if save_point is "question_asked"). + #[serde(rename = "questionId")] + question_id: Option, + /// Error message (if state is "error"). + #[serde(rename = "errorMessage")] + error_message: Option, + /// Updated conversation history (sent on llm_response save points). + #[serde(rename = "conversationHistory")] + conversation_history: Option, + }, + + /// Supervisor heartbeat for lightweight state updates. + SupervisorHeartbeat { + /// Task ID of the supervisor. + #[serde(rename = "taskId")] + task_id: Uuid, + /// Contract ID. + #[serde(rename = "contractId")] + contract_id: Uuid, + /// Current state (optional). + state: Option, + /// Current activity description (optional). + #[serde(rename = "currentActivity")] + current_activity: Option, + /// Progress percentage (optional). + progress: Option, + }, } /// Information about a branch (used in BranchList message). @@ -857,6 +914,52 @@ impl DaemonMessage { pub fn revoke_tool_key(task_id: Uuid) -> Self { Self::RevokeToolKey { task_id } } + + /// Create a supervisor state update message. + pub fn supervisor_state_update( + task_id: Uuid, + contract_id: Uuid, + save_point: &str, + state: Option<&str>, + current_activity: Option<&str>, + progress: Option, + last_llm_response: Option<&str>, + spawned_task_id: Option, + question_id: Option, + error_message: Option<&str>, + conversation_history: Option, + ) -> Self { + Self::SupervisorStateUpdate { + task_id, + contract_id, + save_point: save_point.to_string(), + state: state.map(|s| s.to_string()), + current_activity: current_activity.map(|s| s.to_string()), + progress, + last_llm_response: last_llm_response.map(|s| s.to_string()), + spawned_task_id, + question_id, + error_message: error_message.map(|s| s.to_string()), + conversation_history, + } + } + + /// Create a supervisor heartbeat message. + pub fn supervisor_heartbeat( + task_id: Uuid, + contract_id: Uuid, + state: Option<&str>, + current_activity: Option<&str>, + progress: Option, + ) -> Self { + Self::SupervisorHeartbeat { + task_id, + contract_id, + state: state.map(|s| s.to_string()), + current_activity: current_activity.map(|s| s.to_string()), + progress, + } + } } #[cfg(test)] -- cgit v1.2.3