新增: 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
+35 -14
View File
@@ -354,11 +354,14 @@ async fn stream_one_provider(
candidate.name, delay.as_millis(), total_retry, max_retries + 1,
);
let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiStreamRetry {
let ev = AiChatEvent::AiStreamRetry {
attempt: total_retry as u32,
max_attempts: (max_retries + 1) as u32,
conversation_id: Some(conv_id.to_string()),
});
};
let _ = app_handle.emit("ai-chat-event", ev.clone());
// L3 emit 双写:tunnel subscriber(阶段2)透传 miniapp
let _ = app_handle.state::<AppState>().ai_event_bus.publish_event(ev);
tokio::time::sleep(delay).await;
continue;
@@ -861,9 +864,12 @@ pub(crate) async fn run_agentic_loop(
if should_compress {
// emit 压缩开始 + 置位防重入 + 读 active 克隆(不改 status)。
let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiCompressing {
let ev = AiChatEvent::AiCompressing {
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::<AppState>().ai_event_bus.publish_event(ev);
let (active_msgs, lang) = {
let mut session = session_arc.lock().await;
let conv = session.conv(&conv_id);
@@ -923,10 +929,13 @@ pub(crate) async fn run_agentic_loop(
pre_tokens = pre_compress_tokens,
"[ai] 自动压缩成功,摘要已插首位"
);
let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiCompressed {
let ev = AiChatEvent::AiCompressed {
conversation_id: Some(conv_id.clone()),
summary,
});
};
let _ = app_handle.emit("ai-chat-event", ev.clone());
// L3 emit 双写:tunnel subscriber(阶段2)透传 miniapp
let _ = app_handle.state::<AppState>().ai_event_bus.publish_event(ev);
}
Ok(None) => {
// 保护区外无 active 可压缩(已全 compressed/archived)→ noop,仅复位 is_compressing。
@@ -973,11 +982,14 @@ pub(crate) async fn run_agentic_loop(
);
}
}
let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiError {
let ev = AiChatEvent::AiError {
error: format!("自动上下文压缩失败,已降级为普通裁剪: {}", e),
error_type: Some(ErrorType::Unknown),
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::<AppState>().ai_event_bus.publish_event(ev);
}
}
}
@@ -1488,9 +1500,12 @@ pub(crate) async fn run_agentic_loop(
save_conversation(&session_arc, &db, &conv_id, Some(&usage), Some(&resolved_model), true).await;
// 暂停态保持 generating=true(防其他 send 抢占,仿审批),disarm guard 跳过 Drop 兜底复位
guard.disarm();
let _ = app_handle.emit("ai-chat-event", AiChatEvent::AiMaxRoundsReached {
let ev = AiChatEvent::AiMaxRoundsReached {
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::<AppState>().ai_event_bus.publish_event(ev);
return; // generating 保持 true,等 ai_continue_loop / ai_stop_loop
}
@@ -1629,13 +1644,16 @@ pub(crate) async fn try_continue_agent_loop(
Some(cid) => cid,
None => conv_id.to_string(),
};
let _ = app.emit("ai-chat-event", AiChatEvent::AiCompleted {
let ev = AiChatEvent::AiCompleted {
total_tokens: 0,
prompt_tokens: 0,
completion_tokens: 0,
incomplete: None,
conversation_id: Some(emit_conv_id),
});
};
let _ = app.emit("ai-chat-event", ev.clone());
// L3 emit 双写:tunnel subscriber(阶段2)透传 miniapp
let _ = app.state::<AppState>().ai_event_bus.publish_event(ev);
}
return;
}
@@ -1713,13 +1731,16 @@ pub(crate) async fn try_continue_agent_loop(
};
if !still_generating {
tracing::info!(conv_id = %conv_id, "[ai] try_continue 终止:spawn 前重检 generating 已被 stop 复位,补发 AiCompleted");
let _ = app.emit("ai-chat-event", AiChatEvent::AiCompleted {
let ev = AiChatEvent::AiCompleted {
total_tokens: 0,
prompt_tokens: 0,
completion_tokens: 0,
incomplete: None,
conversation_id: Some(conv_id_owned.clone()),
});
};
let _ = app.emit("ai-chat-event", ev.clone());
// L3 emit 双写:tunnel subscriber(阶段2)透传 miniapp
let _ = app.state::<AppState>().ai_event_bus.publish_event(ev);
return;
}