summaryrefslogtreecommitdiff
path: root/makima/src/daemon
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-01 00:47:02 +0000
committersoryu <soryu@soryu.co>2026-02-01 00:47:02 +0000
commit999ecf644f58af7de0b0a36b22a69897d8056a1c (patch)
treecd294c110c753034b5f9137b80a4aa493dd1a969 /makima/src/daemon
parent10d9b4ce345ac74161108818ad5532a74336cc3d (diff)
downloadsoryu-999ecf644f58af7de0b0a36b22a69897d8056a1c.tar.gz
soryu-999ecf644f58af7de0b0a36b22a69897d8056a1c.zip
[WIP] Heartbeat checkpoint - 2026-02-01 00:47:02 UTC
Diffstat (limited to 'makima/src/daemon')
-rw-r--r--makima/src/daemon/ws/protocol.rs103
1 files changed, 103 insertions, 0 deletions
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<String>,
+ /// Human-readable current activity.
+ #[serde(rename = "currentActivity")]
+ current_activity: Option<String>,
+ /// Progress percentage (0-100).
+ progress: Option<i32>,
+ /// Last LLM response for context restoration.
+ #[serde(rename = "lastLlmResponse")]
+ last_llm_response: Option<String>,
+ /// Task that was just spawned (if save_point is "task_spawn").
+ #[serde(rename = "spawnedTaskId")]
+ spawned_task_id: Option<Uuid>,
+ /// Question ID (if save_point is "question_asked").
+ #[serde(rename = "questionId")]
+ question_id: Option<Uuid>,
+ /// Error message (if state is "error").
+ #[serde(rename = "errorMessage")]
+ error_message: Option<String>,
+ /// Updated conversation history (sent on llm_response save points).
+ #[serde(rename = "conversationHistory")]
+ conversation_history: Option<serde_json::Value>,
+ },
+
+ /// 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<String>,
+ /// Current activity description (optional).
+ #[serde(rename = "currentActivity")]
+ current_activity: Option<String>,
+ /// Progress percentage (optional).
+ progress: Option<i32>,
+ },
}
/// 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<i32>,
+ last_llm_response: Option<&str>,
+ spawned_task_id: Option<Uuid>,
+ question_id: Option<Uuid>,
+ error_message: Option<&str>,
+ conversation_history: Option<serde_json::Value>,
+ ) -> 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<i32>,
+ ) -> 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)]