Merge remote-tracking branch 'origin/master' into codex/infinite-canvas
This commit is contained in:
+31
-30
@@ -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",
|
||||
|
||||
@@ -4604,6 +4604,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 用户配置中的 MCP(2026-08-10)
|
||||
|
||||
- 现象:以 `codex app-server -c 'mcp_servers={}'` 启动后,`thread/start` 仍发出用户配置中各 MCP server 的 startup 事件;若直接把这种进程当 AGC 节点 Agent,会出现 Codex 与 AGC 两套 ToolHost、副作用和审批边界。
|
||||
|
||||
Reference in New Issue
Block a user