From d287061c61ea808b121d99b612a8a26ec1813967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 24 Sep 2026 13:08:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=BF=E4=B8=BB=EF=BC=9A=E4=BA=A4=E4=BB=98?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E5=85=9C=E5=BA=95=E5=8F=AA=E8=AF=BB=E4=B8=80?= =?UTF-8?q?=E6=AC=A1=20terminal=5Freport?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit direct_runtime/mod.rs:两处 `Err(_) if terminal_report(...).is_some()` 的 guard 与取值各调了一次 terminal_report,两次之间状态变化就会拿到不一致的结果——流式分支第二次拿到 None 时会把空串当回复返回(界面显示"未返回可展示的回复"),非流式分支则绕过"未返回结果"的兜底错误。改成一次读取后落变量,判据与取值同源;两个分支的优先级(有报告 > 可反馈修复 > 原样抛出)不变。direct_ 过滤 474 passed。 --- .../src-tauri/src/agent/direct_runtime/mod.rs | 65 +++++++++++-------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs index eef74fc72..8faae1c00 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs @@ -5027,23 +5027,27 @@ async fn run_direct_game_creator_turn_inner( } Err(error) => break Err(error), }, - Err(_) if super::direct_delivery::terminal_report(&execution_session).is_some() => break Ok(super::direct_delivery::terminal_report(&execution_session).unwrap_or_default()), - Err(error) - if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS - && error.is_model_repairable() => - { - let detail = redact_agent_runtime_error(root, &error.to_string(), 1800); - emitter.emit( - "running", - Some("error-feedback"), - Some(format!("检测到执行错误,正在反馈给陶泥儿继续修复({attempt}/{DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS})")), - None, - ); - attempt += 1; - feedback_prompt = direct_codex_error_feedback_prompt(&detail, attempt); - } - // 失败也先走统一收尾,确保已提交的回合流快照全部落盘。 - Err(error) => break Err(error), + // 交付报告的兜底只读一次:guard 与取值各调一次会在两次之间换出不同结果, + // 第二次拿到 `None` 时还会把空串当成回复返回。 + Err(error) => match super::direct_delivery::terminal_report(&execution_session) { + Some(report) => break Ok(report), + None + if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS + && error.is_model_repairable() => + { + let detail = redact_agent_runtime_error(root, &error.to_string(), 1800); + emitter.emit( + "running", + Some("error-feedback"), + Some(format!("检测到执行错误,正在反馈给陶泥儿继续修复({attempt}/{DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS})")), + None, + ); + attempt += 1; + feedback_prompt = direct_codex_error_feedback_prompt(&detail, attempt); + } + // 失败也先走统一收尾,确保已提交的回合流快照全部落盘。 + None => break Err(error), + }, } }; drop(observer); @@ -5087,16 +5091,23 @@ async fn run_direct_game_creator_turn_inner( Err(error) => return Err(error), } } - Err(_) if super::direct_delivery::terminal_report(&execution_session).is_some() => { response = super::direct_delivery::terminal_report(&execution_session); break; } - Err(error) - if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS - && error.is_model_repairable() => - { - let detail = redact_agent_runtime_error(root, &error.to_string(), 1800); - attempt += 1; - feedback_prompt = direct_codex_error_feedback_prompt(&detail, attempt); - } - Err(error) => return Err(error), + // 同上:交付报告只读一次,避免两次调用之间换出不同结果(第二次拿到 `None` + // 时还会绕过下面那条"未返回结果"的兜底错误)。 + Err(error) => match super::direct_delivery::terminal_report(&execution_session) { + Some(report) => { + response = Some(report); + break; + } + None + if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS + && error.is_model_repairable() => + { + let detail = redact_agent_runtime_error(root, &error.to_string(), 1800); + attempt += 1; + feedback_prompt = direct_codex_error_feedback_prompt(&detail, attempt); + } + None => return Err(error), + }, } } response.ok_or_else(|| {