重构调试落盘模块:统一 debug 命名空间并优化代码组织

This commit is contained in:
AIGameCreator App
2026-06-26 22:00:48 +08:00
parent 43cf689f78
commit c7c29dadb5
3 changed files with 16 additions and 11 deletions
@@ -0,0 +1,3 @@
pub(crate) mod debug_drafts;
pub(crate) use debug_drafts::*;
@@ -1,10 +1,12 @@
//! 调试落盘:保存 LLM 原始输出 / 失败输入,便于排查截断、空返回等问题。
//!
//! 本模块在 main.rs 用 `#[cfg(all(debug_assertions, not(test)))]` 声明——仅在开发(debug
//! 本模块用 `#[cfg(all(debug_assertions, not(test)))]` 声明——仅在开发(debug
//! 且非测试构建中编入二进制;生产 release 与 cargo test 下整个模块与其调用处一并被剔除,
//! 不会往仓库写任何文件。
use super::*;
use std::fs;
use std::path::PathBuf;
use crate::unix_millis;
// 找到仓库根(包含 apps/ai-game-creator-shell/src-tauri/Cargo.toml 的目录),
// 以便把草案落到仓库内而非 tmp 项目目录。
@@ -35,7 +37,7 @@ fn repo_root() -> Option<PathBuf> {
// 把生成器原始返回(含被截断、解析失败的内容)保存到仓库 .llm-drafts/
// 便于排查 “EOF while parsing a string” 这类输出截断问题。尽力而为,不阻断主流程。
pub(super) fn persist_snapshot(raw_content: &str) {
pub(crate) fn persist_snapshot(raw_content: &str) {
let Some(repo_root) = repo_root() else {
eprintln!("llm.draft.snapshot.skip: 未能定位仓库根目录");
return;
@@ -64,7 +66,7 @@ pub(super) fn persist_snapshot(raw_content: &str) {
// LLM 调用失败(例如返回内容为空)时,把本次发送给模型的输入(system + 完整 user prompt
// 连同错误信息一起落盘到 .llm-drafts/,便于按同样输入复现与定位。尽力而为,不阻断主流程。
pub(super) fn persist_error_input(system_prompt: &str, user_prompt: &str, error: &str) {
pub(crate) fn persist_error_input(system_prompt: &str, user_prompt: &str, error: &str) {
let Some(repo_root) = repo_root() else {
eprintln!("llm.draft.error-input.skip: 未能定位仓库根目录");
return;
@@ -34,6 +34,11 @@ use shared_contracts::game_creation_app::{
use tauri::Emitter;
use tauri_plugin_opener::OpenerExt;
// 调试落盘模块(保存 LLM 原始输出 / 失败输入,排查截断、空返回等)放在 debug_drafts.rs。
// 用 #[cfg] 编译期门控:仅开发(debug)且非测试构建编入;生产 release 与 cargo test 下整体剔除。
#[cfg(all(debug_assertions, not(test)))]
mod debug;
#[derive(Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
struct InitLocalProjectResult {
@@ -1833,7 +1838,7 @@ async fn request_generator_game_draft_with_client(
Err(error) => {
// 调用失败(含空返回重试耗尽)时,把本次输入连同错误一并落盘,便于复现定位(仅 debug 构建)。
#[cfg(all(debug_assertions, not(test)))]
debug_drafts::persist_error_input(
debug::persist_error_input(
system_prompt,
user_prompt.as_str(),
&error.to_string(),
@@ -1844,7 +1849,7 @@ async fn request_generator_game_draft_with_client(
};
// 先把原始返回落盘,再解析;解析失败(如输出截断)时仍能从仓库里拿到完整原文(仅 debug 构建)。
#[cfg(all(debug_assertions, not(test)))]
debug_drafts::persist_snapshot(response.content.as_str());
debug::persist_snapshot(response.content.as_str());
let content = strip_llm_thinking_blocks(response.content.as_str());
parse_llm_game_draft_response(content.as_str())
}
@@ -3749,11 +3754,6 @@ fn parse_llm_game_draft_response(content: &str) -> Result<LlmGameDraft, String>
.map_err(|error| format!("解析 LLM 游戏草案失败:{error}"))
}
// 调试落盘模块(保存 LLM 原始输出 / 失败输入,排查截断、空返回等)放在 debug_drafts.rs。
// 用 #[cfg] 编译期门控:仅开发(debug)且非测试构建编入;生产 release 与 cargo test 下整体剔除。
#[cfg(all(debug_assertions, not(test)))]
mod debug_drafts;
fn strip_llm_thinking_blocks(content: &str) -> String {
let mut output = String::new();
let mut rest = content;