继续收敛 Direct 交付终态读取错误
保留交付状态快照读取与锁失败的具体正文 合并原始回合错误与终态读取错误 补充交付复核回归验证记录
This commit is contained in:
@@ -1056,9 +1056,13 @@ impl ExecutionAdapter {
|
||||
}
|
||||
|
||||
fn report(&self) -> String {
|
||||
direct_delivery::terminal_report(&self.session).unwrap_or_else(|| {
|
||||
"本轮执行已停止,宿主尚未确认交付完成;请核对保留的证据与未完成项。".into()
|
||||
})
|
||||
match direct_delivery::terminal_report(&self.session) {
|
||||
Ok(Some(report)) => report,
|
||||
Ok(None) => "本轮执行已停止,宿主尚未确认交付完成;请核对保留的证据与未完成项。".into(),
|
||||
Err(error) => format!(
|
||||
"本轮执行已停止,读取宿主交付状态失败:{error};请核对保留的证据与未完成项。"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn drain(&self) {
|
||||
|
||||
@@ -644,8 +644,8 @@ fn assess(root: &Path, ledger: &ExecutionLedger) -> Result<Assessment, String> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn terminal_report(session: &Arc<ExecutionSession>) -> Option<String> {
|
||||
session.snapshot().ok()?.terminal_report
|
||||
pub(super) fn terminal_report(session: &Arc<ExecutionSession>) -> Result<Option<String>, String> {
|
||||
session.snapshot().map(|snapshot| snapshot.terminal_report)
|
||||
}
|
||||
|
||||
pub(super) async fn status(root: &Path, session: &Arc<ExecutionSession>) -> Result<Value, String> {
|
||||
@@ -710,7 +710,13 @@ pub(super) async fn review_reply(
|
||||
root: &Path,
|
||||
session: &Arc<ExecutionSession>,
|
||||
) -> Result<Option<String>, TurnError> {
|
||||
if let Some(report) = terminal_report(session) {
|
||||
let existing_report = terminal_report(session).map_err(|error| {
|
||||
TurnError::turn_failed(
|
||||
FailureStage::CodeGeneration,
|
||||
format!("读取交付终态失败:{error}"),
|
||||
)
|
||||
})?;
|
||||
if let Some(report) = existing_report {
|
||||
return Ok(Some(report));
|
||||
}
|
||||
let ledger = session.snapshot()?;
|
||||
@@ -721,7 +727,13 @@ pub(super) async fn review_reply(
|
||||
if let Some(report) = finish_sealing(root, session).await? {
|
||||
return Ok(Some(report));
|
||||
}
|
||||
if let Some(report) = terminal_report(session) {
|
||||
let terminal_report = terminal_report(session).map_err(|error| {
|
||||
TurnError::turn_failed(
|
||||
FailureStage::CodeGeneration,
|
||||
format!("读取交付终态失败:{error}"),
|
||||
)
|
||||
})?;
|
||||
if let Some(report) = terminal_report {
|
||||
return Ok(Some(report));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4528,7 +4528,9 @@ async fn run_direct_game_creator_turn_inner(
|
||||
direct_turn_trace("run-analytics-accepted");
|
||||
// 在 guard 仍存活时冻结整体结果,避免 Drop 的中断收尾覆盖真实失败原因。
|
||||
let result: Result<String, TurnError> = async {
|
||||
if let Some(report) = super::direct_delivery::terminal_report(&execution_session) {
|
||||
let terminal_report = super::direct_delivery::terminal_report(&execution_session)
|
||||
.map_err(|error| TurnError::turn_failed(FailureStage::CodeGeneration, format!("读取交付终态失败:{error}")))?;
|
||||
if let Some(report) = terminal_report {
|
||||
return Ok(report);
|
||||
}
|
||||
// CLI 没有结构化条目;在进入反馈循环前固定原始消息,避免后续反馈以同一 ID
|
||||
@@ -4670,20 +4672,28 @@ async fn run_direct_game_creator_turn_inner(
|
||||
}
|
||||
// 交付报告的兜底只读一次: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 =
|
||||
truncate_agent_runtime_text(&error.diagnostic_detail(), 1800);
|
||||
emitter.emit("running", Some("error-feedback"));
|
||||
attempt += 1;
|
||||
feedback_prompt = direct_codex_error_feedback_prompt(&detail);
|
||||
Err(error) => {
|
||||
let original_detail = error.diagnostic_detail();
|
||||
match super::direct_delivery::terminal_report(&execution_session) {
|
||||
Ok(Some(report)) => break Ok(report),
|
||||
Ok(None) if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS
|
||||
&& error.is_model_repairable() =>
|
||||
{
|
||||
let detail =
|
||||
truncate_agent_runtime_text(&original_detail, 1800);
|
||||
emitter.emit("running", Some("error-feedback"));
|
||||
attempt += 1;
|
||||
feedback_prompt = direct_codex_error_feedback_prompt(&detail);
|
||||
}
|
||||
Ok(None) => break Err(error),
|
||||
Err(report_error) => break Err(TurnError::turn_failed(
|
||||
FailureStage::CodeGeneration,
|
||||
format!(
|
||||
"读取交付终态失败:{report_error};原始回合失败:{original_detail}"
|
||||
),
|
||||
)),
|
||||
}
|
||||
None => break Err(error),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
drop(observer);
|
||||
@@ -4732,19 +4742,29 @@ async fn run_direct_game_creator_turn_inner(
|
||||
}
|
||||
// 同上:交付报告只读一次,避免两次调用之间换出不同结果(第二次拿到 `None`
|
||||
// 时还会绕过下面那条"未返回结果"的兜底错误)。
|
||||
Err(error) => match super::direct_delivery::terminal_report(&execution_session)
|
||||
{
|
||||
Some(report) => break Some(report),
|
||||
None if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS
|
||||
&& error.is_model_repairable() =>
|
||||
{
|
||||
let detail =
|
||||
truncate_agent_runtime_text(&error.diagnostic_detail(), 1800);
|
||||
attempt += 1;
|
||||
feedback_prompt = direct_codex_error_feedback_prompt(&detail);
|
||||
Err(error) => {
|
||||
let original_detail = error.diagnostic_detail();
|
||||
match super::direct_delivery::terminal_report(&execution_session) {
|
||||
Ok(Some(report)) => break Some(report),
|
||||
Ok(None) if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS
|
||||
&& error.is_model_repairable() =>
|
||||
{
|
||||
let detail =
|
||||
truncate_agent_runtime_text(&original_detail, 1800);
|
||||
attempt += 1;
|
||||
feedback_prompt = direct_codex_error_feedback_prompt(&detail);
|
||||
}
|
||||
Ok(None) => return Err(error),
|
||||
Err(report_error) => {
|
||||
return Err(TurnError::turn_failed(
|
||||
FailureStage::CodeGeneration,
|
||||
format!(
|
||||
"读取交付终态失败:{report_error};原始回合失败:{original_detail}"
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
None => return Err(error),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
response.ok_or_else(|| {
|
||||
|
||||
@@ -88,3 +88,4 @@ DirectProject 回合失败在确认不是客户端内部不可归类故障时,
|
||||
- Direct 补丁事务的目标指纹读取原先把元数据、打开、正文读取和文件超限都折叠为 `None`,可能误判文件缺失或继续比较;现只对确实 `NotFound` 保留 `missing`,其余失败返回目标相对路径、阶段和底层正文,避免补丁结果被错误归因。
|
||||
- CC/Direct 工具桥的执行前后成果指纹、回执结算 JoinError/落盘失败,以及外部 MCP journal 的读取/JSON 行解析原先仍会被 `.ok()`、固定回执句或“无记录”吞掉;现分别保留指纹阶段、回执任务/落盘原因、journal 行号和底层正文,只有真实 `NotFound` 才视为空记录。
|
||||
- 外部 MCP `resources/read` 仍把已能返回具体原因的 Codex journal 读取错误 `unwrap_or_default()` 成空资源;现把读取失败按 MCP 错误响应返回,Direct 执行会话当前项目 canonicalize 也保留底层 I/O 正文。
|
||||
- Direct 交付终态读取原先把 `session.snapshot()` 锁/状态错误折叠成 `None`,上层继续显示“尚未确认交付完成”;现沿 `code-generation` 失败出口保留终态读取正文,并在已有回合失败时同时保留原始失败与终态读取失败。
|
||||
|
||||
Reference in New Issue
Block a user