Fix provider proposals after task switches

This commit is contained in:
2026-08-15 18:08:47 -05:00
parent 4b20952cec
commit d10deb80a2
2 changed files with 158 additions and 13 deletions
+59 -9
View File
@@ -2349,15 +2349,12 @@ impl AIConversation {
if self.contains_action(&action.id) {
return Ok(());
}
let added_exchanges = self
.added_exchanges_by_response
.get(stream_id)
.ok_or(UpdateConversationError::NoPendingRequest)?;
let exchange_id = added_exchanges
.iter()
.find(|added| added.task_id == action.task_id)
.map(|added| added.exchange_id)
.ok_or(UpdateConversationError::TaskNotFound)?;
let exchange_id = self.ensure_response_exchange_for_task(
stream_id,
&action.task_id,
terminal_surface_id,
ctx,
)?;
let message_id = MessageId::new(action.id.to_string());
let exchange = self.get_exchange_to_update(exchange_id)?;
match &exchange.output_status {
@@ -2383,6 +2380,59 @@ impl AIConversation {
Ok(())
}
fn ensure_response_exchange_for_task(
&mut self,
stream_id: &ResponseStreamId,
task_id: &TaskId,
terminal_surface_id: EntityId,
ctx: &mut ModelContext<BlocklistAIHistoryModel>,
) -> Result<AIAgentExchangeId, UpdateConversationError> {
let added_exchanges = self
.added_exchanges_by_response
.get(stream_id)
.ok_or(UpdateConversationError::NoPendingRequest)?;
if let Some(exchange_id) = added_exchanges
.iter()
.find_map(|added| (added.task_id == *task_id).then_some(added.exchange_id))
{
return Ok(exchange_id);
}
// Direct-provider command monitoring can switch tasks within one response stream. A
// tool-first monitor turn needs an exchange before any message event can create it.
let source_exchange = added_exchanges.last().clone();
let existing_exchange = self
.task_store
.get(&source_exchange.task_id)
.ok_or(UpdateConversationError::TaskNotFound)?
.exchange(source_exchange.exchange_id)
.cloned()
.ok_or(UpdateConversationError::ExchangeNotFound)?;
let mut task = self
.task_store
.remove(task_id)
.ok_or(UpdateConversationError::TaskNotFound)?;
let exchange_id = task.append_new_exchange(&existing_exchange);
self.task_store.insert(task);
self.added_exchanges_by_response
.get_mut(stream_id)
.ok_or(UpdateConversationError::NoPendingRequest)?
.push(AddedExchange {
task_id: task_id.clone(),
exchange_id,
});
let is_hidden = self.hidden_exchanges.contains(&exchange_id);
ctx.emit(BlocklistAIHistoryEvent::AppendedExchange {
response_stream_id: Some(stream_id.clone()),
exchange_id,
task_id: task_id.clone(),
terminal_surface_id,
conversation_id: self.id,
is_hidden,
});
Ok(exchange_id)
}
pub fn update_cost_and_usage_for_request(
&mut self,
request_cost: Option<RequestCost>,