From 365af554dacc9f5414dbb69ce2bed80129f39b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=9D=E5=B0=98?= <237809796@qq.com> Date: Tue, 21 Jul 2026 00:31:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20max=5Fiterations=20?= =?UTF-8?q?=E4=B8=8D=E6=94=B6=E6=95=9B=E5=8D=A1=E6=AD=BB=20+=20stopBtnStat?= =?UTF-8?q?e=20=E6=AE=8B=E7=95=99=E7=BA=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/ai/agentic/mod.rs | 21 ++++++++++----------- src-tauri/src/commands/ai/stream_recv.rs | 1 + src/components/ai/ChatInput.vue | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src-tauri/src/commands/ai/agentic/mod.rs b/src-tauri/src/commands/ai/agentic/mod.rs index 5b555a2..948699d 100644 --- a/src-tauri/src/commands/ai/agentic/mod.rs +++ b/src-tauri/src/commands/ai/agentic/mod.rs @@ -1829,25 +1829,24 @@ pub(crate) async fn run_agentic_loop( tracing::warn!( conv_id = %conv_id, max_iter = max_iterations, - "[ai] agentic 循环达最大轮次(max_iterations={})仍未收敛,转暂停态询问用户(F-260616-03)", - max_iterations, + "[ai] agentic 循环达最大轮次仍未收敛,自动完成(incomplete=true)", ); - // 轮 token 落库(保留末轮已生成内容,续跑/停止都据此累加) let usage = df_ai::provider::TokenUsage { prompt_tokens: tokens.prompt(), completion_tokens: tokens.completion(), total_tokens: tokens.total(), }; save_conversation(&session_arc, &db, &conv_id, Some(&usage), Some(&resolved_model), true).await; - // 暂停态保持 generating=true(防其他 send 抢占,仿审批),disarm guard 跳过 Drop 兜底复位 - guard.disarm(); - let ev = AiChatEvent::AiMaxRoundsReached { + guard.reset().await; + let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiCompleted { + total_tokens: usage.total_tokens, + prompt_tokens: tokens.prompt(), + completion_tokens: tokens.completion(), + incomplete: Some(true), conversation_id: Some(conv_id.clone()), - }; - let _ = app_handle.emit("ai-chat-event", ev.clone()); - // L3 emit 双写:tunnel subscriber(阶段2)透传 miniapp - let _ = app_handle.state::().ai_event_bus.publish_event(ev); - return; // generating 保持 true,等 ai_continue_loop / ai_stop_loop + pinned_goals: pinned_goals_snapshot.clone(), + }); + return; } // 正常完成 diff --git a/src-tauri/src/commands/ai/stream_recv.rs b/src-tauri/src/commands/ai/stream_recv.rs index bb89804..d40d111 100644 --- a/src-tauri/src/commands/ai/stream_recv.rs +++ b/src-tauri/src/commands/ai/stream_recv.rs @@ -527,6 +527,7 @@ fn classify_status_or_class(status_or_class: &str) -> bool { // ============================================================ // 单测:诊断提取/格式化(纯函数,不发 HTTP、不依赖 app_handle) // ============================================================ + #[cfg(test)] mod tests { use super::*; diff --git a/src/components/ai/ChatInput.vue b/src/components/ai/ChatInput.vue index 4567d58..d1e14d7 100644 --- a/src/components/ai/ChatInput.vue +++ b/src/components/ai/ChatInput.vue @@ -244,8 +244,8 @@ const stopBtnState = computed<'idle' | 'stop' | 'stopping' | 'retry'>(() => { if (cs === 'stopping') return 'stopping' if (cs === 'error') return 'retry' if (cs === 'generating' || cs === 'compressed') return 'stop' - // conv_state 未收到(idle 或 null)→ 回退旧 streaming bool - return store.state.streaming ? 'stop' : 'idle' + // cs === null (conv_state 已 idle 收敛删项) 或 cs === 'idle' → 发送态 + return 'idle' }) // ── 技能 `/` 联想 ──