新增: Phase3阶段2 emit双写全接入(D2全19变体)

chat.rs 19 + audit/mod.rs 12 + guard.rs 3 + stream_recv.rs 2 + agentic/mod.rs 7(emit-only 补全,原11已落地)。每处 app.emit 前端 + publish_event tunnel 双路独立(emit 不删)。D2 全 19 变体透传 EventBus 供 tunnel subscriber 透传 miniapp。cargo EXIT=0。
This commit is contained in:
lxy
2026-06-22 03:31:58 +08:00
parent 60b73377f6
commit 612de4cd7c
5 changed files with 225 additions and 97 deletions
+11 -5
View File
@@ -4,7 +4,7 @@ use std::collections::HashMap;
use std::sync::atomic::AtomicBool;
use std::time::Duration;
use tauri::{AppHandle, Emitter};
use tauri::{AppHandle, Emitter, Manager};
use futures::StreamExt;
use tracing::warn;
@@ -226,10 +226,13 @@ pub(crate) async fn stream_llm(
Ok(chunk) => {
if !chunk.delta.is_empty() {
full_text.push_str(&chunk.delta);
let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiTextDelta {
// L3 emit 双写:提变量避免构造两次,publish 到事件总线(EVENT_BUS_ENABLED 门控在 publish 内)。
let ev = AiChatEvent::AiTextDelta {
delta: chunk.delta,
conversation_id: Some(conv_id.to_string()),
});
};
let _ = app_handle.emit("ai-chat-event", ev.clone());
let _ = app_handle.state::<crate::state::AppState>().ai_event_bus.publish_event(ev);
}
if let Some(tc_deltas) = &chunk.tool_calls {
for tc_delta in tc_deltas {
@@ -326,9 +329,12 @@ pub(crate) async fn stream_llm(
// 2) 心跳:静默期 30s 发 AiHeartbeat,前端 watchdog reset(B-260615-02)
_ = heartbeat.tick() => {
// 心跳只在「仍在等下一 chunk」时有意义——若 stop_flag 已置,顶部快检会 break,无需发心跳
let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiHeartbeat {
// L3 emit 双写:提变量避免构造两次,publish 到事件总线(EVENT_BUS_ENABLED 门控在 publish 内)。
let ev = AiChatEvent::AiHeartbeat {
conversation_id: Some(conv_id.to_string()),
});
};
let _ = app_handle.emit("ai-chat-event", ev.clone());
let _ = app_handle.state::<crate::state::AppState>().ai_event_bus.publish_event(ev);
}
// 3) 即时停止唤醒(B-260615-14):用户点 stop → ai_chat_stop 置 stop_flag 后 notify_one()。
// stream.next() 正阻塞等 chunk 时立即被唤醒,不再等 30s 心跳 tick 或 120s idle timeout。