From a31afaba800705d0c1f7032b54ac4befcbb4efea Mon Sep 17 00:00:00 2001 From: wunianxiao Date: Mon, 1 Jun 2026 18:07:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=A1=E6=89=B9=E6=AD=BB=E9=94=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E2=80=94=20LLM=20=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit listen_loop 核心改动: 新消息到达 → tokio::spawn(generate_reply) → 主循环立即继续 LLM 调用 High 工具 → approval_flow 阻塞 spawn 的 task → 主循环不受影响 → receive_messages() 继续接收 → 用户回复确认码 → handle_reply 触发 oneshot → spawned task 从 approval_flow 恢复 → LLM 生成最终回复 Conversation 用 Arc 包裹以支持跨 task 共享 send_text + 入库移到 spawned task 内部完成 --- src/main.rs | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index d120b60..78a253d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -335,7 +335,7 @@ async fn cmd_listen( conv.set_tool_executor(executor); - Some(conv) + Some(Arc::new(conv)) } else { None }; @@ -387,7 +387,7 @@ async fn listen_loop( account_id: &str, database: &Option>, file_state: &state::StateManager, - conversation: Option, + conversation: Option>, approval_manager: Option>, current_user_id: Arc>, ) { @@ -465,32 +465,37 @@ async fn listen_loop( // 更新当前用户(审批流程需要) *current_user_id.lock().await = from.to_string(); - // LLM 回复 + // LLM 回复(异步执行,避免审批阻塞主循环) if enable_llm { if let Some(conv) = &conversation { - let reply_result = if conv.spec().tools.is_some() { - generate_reply_with_tools(conv, text.to_string(), database).await - } else { - generate_reply(conv, text.to_string(), database).await - }; + let conv = conv.clone(); + let client = client.clone(); + let database = database.clone(); + let from_owned = from.to_string(); + let text_owned = text.to_string(); + let ctx_owned = ctx_token.map(String::from); + let aid = account_id.to_string(); - match reply_result { - Ok(reply) => { - match client.send_text(from, &reply, ctx_token).await { - Ok(sent_id) => { - info!("LLM 回复成功 msg_id={}", sent_id); - if let Some(db) = database { - let _ = db::models::insert_chat_record( - db.pool(), "outbound", from, account_id, - &reply, "llm", ctx_token, &sent_id, - ).await; - } + tokio::spawn(async move { + let reply_result = if conv.spec().tools.is_some() { + generate_reply_with_tools(&conv, text_owned, &database).await + } else { + generate_reply(&conv, text_owned, &database).await + }; + let reply = reply_result.ok().unwrap_or_default(); + match client.send_text(&from_owned, &reply, ctx_owned.as_deref()).await { + Ok(sent_id) => { + info!("LLM 回复成功 msg_id={}", sent_id); + if let Some(db) = database { + let _ = db::models::insert_chat_record( + db.pool(), "outbound", &from_owned, &aid, + &reply, "llm", ctx_owned.as_deref(), &sent_id, + ).await; } - Err(e) => error!("发送 LLM 回复失败: {}", e), } + Err(e) => error!("发送 LLM 回复失败: {}", e), } - Err(e) => error!("生成 LLM 回复失败: {}", e), - } + }); } } }