feat: 更新取消结果构建逻辑,确保已生成消息包含在取消响应中

This commit is contained in:
oudecheng 2026-07-02 18:27:22 +08:00
parent 32d49601a2
commit 4071dcc6ee

View File

@ -915,7 +915,7 @@ impl AgentLoop {
if let Some(ref mutex) = self.cancel_token { if let Some(ref mutex) = self.cancel_token {
if mutex.lock().await.has_changed().unwrap_or(true) { if mutex.lock().await.has_changed().unwrap_or(true) {
tracing::info!(iteration, "Agent execution cancelled by user"); tracing::info!(iteration, "Agent execution cancelled by user");
let cancel = Self::build_cancel_result(iteration, emitted_messages.len()); let cancel = Self::build_cancel_result(iteration, emitted_messages);
self.emit_live_tool_call_message(cancel.final_response.clone()).await; self.emit_live_tool_call_message(cancel.final_response.clone()).await;
return Ok(cancel); return Ok(cancel);
} }
@ -1027,7 +1027,7 @@ impl AgentLoop {
// 显式 drop 外部 stream_callback → delta_tx 释放 → channel 关闭。 // 显式 drop 外部 stream_callback → delta_tx 释放 → channel 关闭。
drop(stream_callback); drop(stream_callback);
let _ = consumer_task.await; let _ = consumer_task.await;
let cancel = Self::build_cancel_result(iteration, emitted_messages.len()); let cancel = Self::build_cancel_result(iteration, emitted_messages);
self.emit_live_tool_call_message(cancel.final_response.clone()).await; self.emit_live_tool_call_message(cancel.final_response.clone()).await;
return Ok(cancel); return Ok(cancel);
} }
@ -1035,7 +1035,12 @@ impl AgentLoop {
llm_result = result; llm_result = result;
} }
} }
// LLM 调用正常完成clone 的 Arc 已被 select! drop
// 但外部 stream_callback 仍存活。显式 drop 以关闭 mpsc channel
// 让 consumer_task 能自然退出。
drop(stream_callback);
} else { } else {
// 无取消令牌stream_callback 被 move 进 chat_with_streaming调用完成即释放。
llm_result = self.provider.chat_with_streaming(request, stream_callback).await; llm_result = self.provider.chat_with_streaming(request, stream_callback).await;
} }
@ -1147,7 +1152,7 @@ impl AgentLoop {
let tool_results = if self.cancel_token.is_some() { let tool_results = if self.cancel_token.is_some() {
tokio::select! { tokio::select! {
_ = self.cancel_signal() => { _ = self.cancel_signal() => {
let cancel = Self::build_cancel_result(iteration, emitted_messages.len()); let cancel = Self::build_cancel_result(iteration, emitted_messages);
self.emit_live_tool_call_message(cancel.final_response.clone()).await; self.emit_live_tool_call_message(cancel.final_response.clone()).await;
return Ok(cancel); return Ok(cancel);
} }
@ -1282,7 +1287,7 @@ impl AgentLoop {
if self.cancel_token.is_some() { if self.cancel_token.is_some() {
tokio::select! { tokio::select! {
_ = self.cancel_signal() => { _ = self.cancel_signal() => {
let cancel = Self::build_cancel_result(self.max_iterations, emitted_messages.len()); let cancel = Self::build_cancel_result(self.max_iterations, emitted_messages);
self.emit_live_tool_call_message(cancel.final_response.clone()).await; self.emit_live_tool_call_message(cancel.final_response.clone()).await;
return Ok(cancel); return Ok(cancel);
} }
@ -1342,15 +1347,22 @@ impl AgentLoop {
} }
/// 构建取消响应,包含已完成的迭代次数和已生成的消息数量。 /// 构建取消响应,包含已完成的迭代次数和已生成的消息数量。
fn build_cancel_result(iteration: usize, emitted_count: usize) -> AgentProcessResult { /// 构建取消响应,将取消通知追加到 `emitted_messages` 末尾后一并返回。
/// 这样 finalize_result 会把中间消息加入内存历史,确保下一个 LLM 调用有完整上下文。
fn build_cancel_result(
iteration: usize,
mut emitted_messages: Vec<ChatMessage>,
) -> AgentProcessResult {
let emitted_count = emitted_messages.len();
let cancel_message = format!( let cancel_message = format!(
"\n\n[用户已取消执行。已迭代 {} 次,取消前共生成了 {} 条消息。]", "\n\n[用户已取消执行。已迭代 {} 次,取消前共生成了 {} 条消息。]",
iteration, emitted_count iteration, emitted_count
); );
let assistant_message = ChatMessage::assistant(cancel_message); let assistant_message = ChatMessage::assistant(cancel_message);
emitted_messages.push(assistant_message.clone());
AgentProcessResult { AgentProcessResult {
final_response: assistant_message.clone(), final_response: assistant_message,
emitted_messages: vec![assistant_message], emitted_messages,
} }
} }