修正Agent失败关闭回归语义
Project CI / Repository checks (push) Successful in 1m0s
Project CI / Frontend tests (push) Successful in 3m4s
Project CI / Backend tests (push) Successful in 3m44s
Project CI / Native shell tests (push) Failing after 10m20s

将流式连接中断断言为 Runtime 失败
禁止 transport 错误提交 planning fallback 冒充成功
保留安全失败消息与 final-reply-failed 审计验证
This commit is contained in:
2026-08-12 22:24:17 +08:00
parent fd423770d8
commit da7c4dc71c
@@ -617,7 +617,8 @@ async fn response_stream_private_process_output_is_never_published_or_committed_
}
#[tokio::test]
async fn response_stream_final_failure_with_retry_disabled_commits_planning_fallback() {
async fn response_stream_final_disconnect_with_retry_disabled_fails_without_committing_planning_fallback(
) {
let root = unique_project_path();
init_local_game_project_at(
&root,
@@ -686,32 +687,28 @@ async fn response_stream_final_failure_with_retry_disabled_commits_planning_fall
);
drop(finalization_lock);
let completed = wait_for_agent_runtime_idle(&root, "design-director");
assert_eq!(completed.phase, "completed");
assert_eq!(completed.last_response.as_deref(), Some(planning_fallback));
let committed = wait_for_response_stream_status(
&root,
"design-director",
run_id,
"committed",
ready.sequence.saturating_add(1),
);
assert_eq!(committed.accumulated_text, planning_fallback);
let failed = wait_for_agent_runtime_phase(&root, "design-director", "failed");
assert_eq!(failed.status, "failed");
assert!(failed
.error
.as_deref()
.is_some_and(|error| error.contains("kind=transport")));
assert_eq!(failed.last_response, None);
let conversation = read_local_conversation_for_session_at(
&root,
Some("design-director"),
Some(&started.state.session_id),
)
.expect("read committed fallback conversation");
assert_eq!(
conversation
.messages
.iter()
.filter(|message| message.role == "assistant")
.map(|message| message.content.as_str())
.collect::<Vec<_>>(),
vec![planning_fallback]
);
.expect("read failed final stream conversation");
let assistant_messages = conversation
.messages
.iter()
.filter(|message| message.role == "assistant")
.map(|message| message.content.as_str())
.collect::<Vec<_>>();
assert_eq!(assistant_messages.len(), 1);
assert_ne!(assistant_messages[0], planning_fallback);
assert!(assistant_messages[0].contains("失败"));
let requests = mock.stop_and_collect();
assert_eq!(
@@ -760,12 +757,11 @@ async fn response_stream_final_failure_with_retry_disabled_commits_planning_fall
final_lifecycle[0]["requestSlot"],
final_lifecycle[1]["requestSlot"]
);
assert_response_stream_completion_event_details(
&root,
"design-director",
run_id,
planning_fallback,
);
assert!(read_agent_db_records_for_test(&root).iter().any(|record| {
record["recordType"] == "agent.runtime.background_task.failed"
&& record["runId"] == run_id
&& record["failureKind"] == "final-reply-failed"
}));
assert_response_stream_public_surfaces_exclude(&root, "design-director", &[planning_fallback]);
fs::remove_dir_all(root).ok();