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.
This commit is contained in:
2026-03-23 09:53:29 +00:00
parent 1ba4e016ba
commit 2a1d7a003d

View File

@@ -81,10 +81,10 @@ impl ConversationRegistry {
) -> Result<ConversationResponse, String> {
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();