From 2a1d7a003d1f52d10d22678e803f1a9128822d38 Mon Sep 17 00:00:00 2001 From: Sienna Meridian Satterwhite Date: Mon, 23 Mar 2026 09:53:29 +0000 Subject: [PATCH] auto-recover corrupted conversations on API error when append_conversation fails (422, 404, etc.), the stale mapping is deleted and a fresh conversation is created automatically. prevents Sol from being permanently stuck after a hung research session or Mistral API error. --- src/conversations.rs | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/conversations.rs b/src/conversations.rs index be9611a..b478d37 100644 --- a/src/conversations.rs +++ b/src/conversations.rs @@ -81,10 +81,10 @@ impl ConversationRegistry { ) -> Result { let mut mapping = self.mapping.lock().await; + // Try to append to existing conversation; if it fails, drop and recreate if let Some(state) = mapping.get_mut(room_id) { - // Existing conversation — append let req = AppendConversationRequest { - inputs: message, + inputs: message.clone(), completion_args: None, handoff_execution: None, store: Some(true), @@ -92,24 +92,38 @@ impl ConversationRegistry { stream: false, }; - let response = mistral + match mistral .append_conversation_async(&state.conversation_id, &req) .await - .map_err(|e| format!("append_conversation failed: {}", e.message))?; + { + Ok(response) => { + state.estimated_tokens += response.usage.total_tokens; + self.store.update_tokens(room_id, state.estimated_tokens); - // Update token estimate - state.estimated_tokens += response.usage.total_tokens; - self.store.update_tokens(room_id, state.estimated_tokens); + debug!( + room = room_id, + conversation_id = state.conversation_id.as_str(), + tokens = state.estimated_tokens, + "Appended to conversation" + ); - debug!( - room = room_id, - conversation_id = state.conversation_id.as_str(), - tokens = state.estimated_tokens, - "Appended to conversation" - ); + return Ok(response); + } + Err(e) => { + warn!( + room = room_id, + conversation_id = state.conversation_id.as_str(), + error = e.message.as_str(), + "Conversation corrupted — dropping and creating fresh" + ); + self.store.delete_conversation(room_id); + mapping.remove(room_id); + // Fall through to create a new conversation below + } + } + } - Ok(response) - } else { + { // New conversation — create (with optional context hint for continuity) let agent_id = self.agent_id.lock().await.clone();