合并主分支
Project CI / Repository checks (pull_request) Successful in 50s
Project CI / Frontend tests (pull_request) Successful in 3m18s
Project CI / Backend tests (pull_request) Successful in 3m55s
Project CI / Native shell tests (pull_request) Successful in 14m36s

解决合并冲突
This commit is contained in:
2026-08-11 11:34:17 +08:00
6 changed files with 42 additions and 31 deletions
@@ -1,5 +1,18 @@
use super::*;
fn provider_retry_identity_for_response_stream_test(
snapshot: &AgentRuntimeProviderRequestSnapshot,
llm: &GameCreatorLlmConfig,
request: &LlmRunRequest,
) -> Result<AgentRuntimeProviderRetryIdentity, String> {
game_creator_agent_runtime_provider_retry_identity_for_mode(
snapshot,
llm,
request,
GAME_CREATOR_AGENT_MODE_PROVIDER,
)
}
fn response_stream_fixture(
run_id: &str,
) -> (
@@ -75,10 +88,10 @@ fn persist_tool_plan_handoff_repair_chain(
LlmMessage::user("修复格式"),
]);
let base_identity =
game_creator_agent_runtime_provider_retry_identity(&base_snapshot, llm, &base_request)
provider_retry_identity_for_response_stream_test(&base_snapshot, llm, &base_request)
.expect("build cleanup base identity");
let repair_identity =
game_creator_agent_runtime_provider_retry_identity(&repair_snapshot, llm, &repair_request)
provider_retry_identity_for_response_stream_test(&repair_snapshot, llm, &repair_request)
.expect("build cleanup repair identity");
let base_request_id = game_creator_agent_runtime_provider_request_id(&base_snapshot);
let repair_request_id = game_creator_agent_runtime_provider_request_id(&repair_snapshot);
@@ -972,7 +985,7 @@ async fn provider_handoff_identity_drift_closes_lifecycle_without_leaking_respon
let mut new_llm = old_llm.clone();
new_llm.model = "new-provider-model".to_string();
let old_identity =
game_creator_agent_runtime_provider_retry_identity(&snapshot, &old_llm, &request)
provider_retry_identity_for_response_stream_test(&snapshot, &old_llm, &request)
.expect("build old handoff identity");
let provider_request_id = game_creator_agent_runtime_provider_request_id(&snapshot);
append_game_creator_agent_runtime_provider_request_lifecycle(
@@ -1008,9 +1021,7 @@ async fn provider_handoff_identity_drift_closes_lifecycle_without_leaking_respon
"agentLlm.design-director",
"测试 Provider handoff 身份漂移",
&request,
load_game_creator_app_config()
.expect("load test agent mode")
.agent_mode,
GAME_CREATOR_AGENT_MODE_PROVIDER.to_string(),
|_request| async {
Err(platform_llm::LlmError::Transport(
"identity drift must not call Provider".to_string(),
@@ -1077,9 +1088,9 @@ async fn tool_plan_handoff_identity_drift_closes_entire_repair_chain_before_remo
let mut new_llm = old_llm.clone();
new_llm.model = "new-tool-plan-model".to_string();
let base_identity =
game_creator_agent_runtime_provider_retry_identity(&base_snapshot, &old_llm, &base_request)
provider_retry_identity_for_response_stream_test(&base_snapshot, &old_llm, &base_request)
.expect("build old base identity");
let repair_identity = game_creator_agent_runtime_provider_retry_identity(
let repair_identity = provider_retry_identity_for_response_stream_test(
&repair_snapshot,
&old_llm,
&repair_request,
@@ -1138,9 +1149,7 @@ async fn tool_plan_handoff_identity_drift_closes_entire_repair_chain_before_remo
"agentLlm.project-supervisor",
"测试 tool-plan handoff 身份漂移",
&base_request,
load_game_creator_app_config()
.expect("load test agent mode")
.agent_mode,
GAME_CREATOR_AGENT_MODE_PROVIDER.to_string(),
|_request| async {
Err(platform_llm::LlmError::Transport(
"identity drift must not call Provider".to_string(),
@@ -1197,7 +1206,7 @@ async fn generic_retry_identity_drift_closes_tool_plan_repair_chain_before_remov
persist_tool_plan_handoff_repair_chain(root, &snapshot, &old_llm);
let request = LlmRunRequest::new(vec![LlmMessage::user("验证通用 retry 身份漂移")]);
let old_identity =
game_creator_agent_runtime_provider_retry_identity(&snapshot, &old_llm, &request)
provider_retry_identity_for_response_stream_test(&snapshot, &old_llm, &request)
.expect("build old generic retry identity");
provider_retry::write_next_at(
root,
@@ -1220,9 +1229,7 @@ async fn generic_retry_identity_drift_closes_tool_plan_repair_chain_before_remov
"agentLlm.project-supervisor",
"测试通用 retry 身份漂移",
&request,
load_game_creator_app_config()
.expect("load test agent mode")
.agent_mode,
GAME_CREATOR_AGENT_MODE_PROVIDER.to_string(),
|_request| async {
Err(platform_llm::LlmError::Transport(
"generic retry drift must not call Provider".to_string(),
@@ -1289,7 +1296,7 @@ async fn tool_plan_capacity_gate_runs_before_provider_lifecycle_and_network() {
"capacity request {loop_iteration}"
))]);
let identity =
game_creator_agent_runtime_provider_retry_identity(&entry_snapshot, &llm, &request)
provider_retry_identity_for_response_stream_test(&entry_snapshot, &llm, &request)
.expect("build capacity entry identity");
let request_id = game_creator_agent_runtime_provider_request_id(&entry_snapshot);
let response = platform_llm::LlmRunResponse {
@@ -1335,9 +1342,7 @@ async fn tool_plan_capacity_gate_runs_before_provider_lifecycle_and_network() {
"agentLlm.project-supervisor",
"测试 tool-plan 请求前容量门禁",
&request,
load_game_creator_app_config()
.expect("load test agent mode")
.agent_mode,
GAME_CREATOR_AGENT_MODE_PROVIDER.to_string(),
move |_request| async move {
provider_called_for_request.store(true, Ordering::Release);
Err(platform_llm::LlmError::Transport(
@@ -1404,10 +1409,10 @@ async fn tool_plan_handoff_durable_control_closes_entire_repair_chain_before_rem
retry_backoff_ms: 1,
};
let base_identity =
game_creator_agent_runtime_provider_retry_identity(&base_snapshot, &llm, &base_request)
provider_retry_identity_for_response_stream_test(&base_snapshot, &llm, &base_request)
.expect("build durable control base identity");
let repair_identity =
game_creator_agent_runtime_provider_retry_identity(&repair_snapshot, &llm, &repair_request)
provider_retry_identity_for_response_stream_test(&repair_snapshot, &llm, &repair_request)
.expect("build durable control repair identity");
let base_request_id = game_creator_agent_runtime_provider_request_id(&base_snapshot);
let repair_request_id = game_creator_agent_runtime_provider_request_id(&repair_snapshot);
@@ -1470,9 +1475,7 @@ async fn tool_plan_handoff_durable_control_closes_entire_repair_chain_before_rem
"agentLlm.project-supervisor",
"测试 durable control 清理 tool-plan handoff",
&base_request,
load_game_creator_app_config()
.expect("load test agent mode")
.agent_mode,
GAME_CREATOR_AGENT_MODE_PROVIDER.to_string(),
|_request| async {
Err(platform_llm::LlmError::Transport(
"durable control must not call Provider".to_string(),
@@ -1528,7 +1531,7 @@ fn provider_recovery_cleanup_closes_tool_plan_lifecycle_before_removing_handoff(
max_retries: 0,
retry_backoff_ms: 1,
};
let identity = game_creator_agent_runtime_provider_retry_identity(&snapshot, &llm, &request)
let identity = provider_retry_identity_for_response_stream_test(&snapshot, &llm, &request)
.expect("build cleanup handoff identity");
let request_id = game_creator_agent_runtime_provider_request_id(&snapshot);
append_game_creator_agent_runtime_provider_request_lifecycle(
@@ -1598,7 +1601,7 @@ fn runtime_resume_scans_and_cleans_terminal_tool_plan_handoff() {
max_retries: 0,
retry_backoff_ms: 1,
};
let identity = game_creator_agent_runtime_provider_retry_identity(&snapshot, &llm, &request)
let identity = provider_retry_identity_for_response_stream_test(&snapshot, &llm, &request)
.expect("build terminal handoff identity");
let request_id = game_creator_agent_runtime_provider_request_id(&snapshot);
append_game_creator_agent_runtime_provider_request_lifecycle(
@@ -1692,7 +1695,7 @@ async fn provider_handoff_retry_conflict_preserves_both_sidecars_for_reconciliat
max_retries: 1,
retry_backoff_ms: 1,
};
let identity = game_creator_agent_runtime_provider_retry_identity(&snapshot, &llm, &request)
let identity = provider_retry_identity_for_response_stream_test(&snapshot, &llm, &request)
.expect("build Provider recovery identity");
let provider_request_id = game_creator_agent_runtime_provider_request_id(&snapshot);
append_game_creator_agent_runtime_provider_request_lifecycle(
@@ -1738,9 +1741,7 @@ async fn provider_handoff_retry_conflict_preserves_both_sidecars_for_reconciliat
"agentLlm.design-director",
"测试 Provider recovery 冲突",
&request,
load_game_creator_app_config()
.expect("load test agent mode")
.agent_mode,
GAME_CREATOR_AGENT_MODE_PROVIDER.to_string(),
|_request| async {
Err(platform_llm::LlmError::Transport(
"reconciliation must not call Provider".to_string(),
@@ -80,7 +80,7 @@ async fn agent_goal_edit_pause_resume_keeps_one_session_and_run_until_completion
.expect("edit active Goal");
assert_eq!(edited.goal.revision, 2);
assert_eq!(edited.goal.run_id, run_id);
assert!(edited.provider_interrupted);
assert!(!edited.provider_interrupted);
let stale_edit = edit_game_creator_agent_goal_at(
&root,
"code-prototype",
@@ -1127,6 +1127,7 @@ fn write_mcp_runtime_test_config(config_dir: &Path, llm_base_url: &str, marker_p
fs::create_dir_all(config_dir).expect("create MCP runtime test config dir");
let marker_arg = format!("--marker={}", marker_path.display());
let config = serde_json::json!({
"agentMode": "provider",
"agentLlm": {
"code-prototype": {
"apiKey": "mcp-runtime-test-key",
@@ -677,6 +677,7 @@ async fn background_agent_runtime_can_generate_platform_art_asset() {
fs::write(
config_dir.join(GAME_CREATOR_CONFIG_FILE_NAME),
serde_json::json!({
"agentMode": "provider",
"editorApi": {
"baseUrl": canvas_base_url,
"apiKey": "editor-runtime-key"
@@ -243,6 +243,7 @@ async fn background_agent_runtime_asset_generation_respects_project_policy() {
fs::write(
config_dir.join(GAME_CREATOR_CONFIG_FILE_NAME),
serde_json::json!({
"agentMode": "provider",
"agentLlm": {
"art-asset-plan": {
"apiKey": "art-key",
@@ -4499,6 +4499,13 @@
- 处理:Codex CLI 必须只作为新的节点推理适配器,继续经过原 Runtime 的 lifecycle、retry、handoff、receipt、revision、verification 和 reconciliation。只接受完整 JSONL `turn.completed` 与可验证的最终消息;`started``completed`、超时、异常退出或输出破损都继续走原失败/核对边界。`agentMode`、CLI 版本和影响输出的固定参数必须纳入配置指纹;CLI 不可用时显式报错,不得静默切回 Provider。
- 验证:确定性回归覆盖 stdin prompt、空临时 cwd、read-only/no-shell/ephemeral 参数、structured tool call 转换、缺失终态、超时进程组回收和 stderr 不泄漏;真实 smoke 必须显式 opt-in,并分开报告 CLI 协议成功与本机认证/网络结果。
## 模拟 Provider 的测试不能继承生产默认 Agent 模式(2026-08-11
- 现象:生产默认切到 `codex_app_server` 后,HTTP mock Provider 测试不再收到请求并超时;只验证 retry/handoff identity 的纯单测还会在未安装 Codex CLI 的 CI Runner 上直接失败。本机安装了 Codex 时,相关遗漏可能被掩盖。
- 原因:测试只构造 `agentLlm` 或直接调用读取全局配置的 identity helper,没有显式固定 `agentMode`;缺省配置按正式产品合同选择 `codex_app_server`,测试因此意外依赖本机 CLI 和认证环境。
- 处理:测试若验证 HTTP Provider 协议或 mock 请求,必须在测试配置中显式写入 `agentMode: provider`;只验证 Provider retry/handoff 数据结构的纯单测应调用显式接收模式的 identity helper。不得把生产默认模式改回 Provider,也不得仅为单测向通用 CI 镜像安装 Codex CLI。
- 验证:在 PATH 不含 Codex CLI 的环境运行 response-stream identity、MCP Runtime 和平台素材 mock 回归;同时保留独立的 Codex CLI/app-server 可用性与协议测试,防止 Provider 测试替代正式模式覆盖。
## 空 MCP 覆盖不会清除 Codex 用户配置中的 MCP2026-08-10
- 现象:以 `codex app-server -c 'mcp_servers={}'` 启动后,`thread/start` 仍发出用户配置中各 MCP server 的 startup 事件;若直接把这种进程当 AGC 节点 Agent,会出现 Codex 与 AGC 两套 ToolHost、副作用和审批边界。