测试纯静态美术产物验证合同
新增无 package.json 的 art-asset-plan 回归场景 约束自主验证仅走静态 smoke 与浏览器验收链路 记录当前错误暴露 project.verify 的失败证据
This commit is contained in:
+131
@@ -2919,3 +2919,134 @@ async fn autonomous_game_build_verified_revision_forces_response_only_delivery()
|
||||
|
||||
fs::remove_dir_all(root).ok();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn autonomous_static_art_asset_verification_does_not_require_node_project() {
|
||||
let root = unique_project_path();
|
||||
init_local_game_project_at(
|
||||
&root,
|
||||
"project-autonomous-static-art-verification",
|
||||
"自主构建纯静态美术验证测试",
|
||||
)
|
||||
.expect("project init");
|
||||
assert!(
|
||||
!root.join("package.json").exists(),
|
||||
"static HTML fixture must not gain a Node project manifest"
|
||||
);
|
||||
fs::write(
|
||||
root.join("assets/manifest.art.json"),
|
||||
br#"{"assets":[{"path":"assets/art-spritesheet.png","kind":"art-spritesheet"}]}"#,
|
||||
)
|
||||
.expect("write static art manifest");
|
||||
register_canvas_visual_asset_fixture(&root, "assets/art-spritesheet.png", "art-spritesheet");
|
||||
|
||||
let child_run_id = "autonomous-static-art-verification-child";
|
||||
let task = "为纯静态 HTML 游戏生成并登记 assets/manifest.art.json 与 assets/art-spritesheet.png;项目不使用 Node 或 npm。";
|
||||
let response_arguments = serde_json::json!({
|
||||
"response": "美术清单和精灵图已经生成,可以交付。"
|
||||
})
|
||||
.to_string();
|
||||
let smoke_arguments = serde_json::json!({
|
||||
"reason": "使用静态 smoke 验证当前纯静态项目 revision",
|
||||
"input": {"commandId": "game.static_smoke"}
|
||||
})
|
||||
.to_string();
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
let base_url = spawn_mock_llm_raw_responses_with_capture(
|
||||
vec![
|
||||
native_agent_tool_plan_chat_response(
|
||||
"call-autonomous-static-art-response",
|
||||
AGENT_RUNTIME_RESPOND_FUNCTION_NAME,
|
||||
response_arguments,
|
||||
),
|
||||
native_agent_tool_plan_chat_response(
|
||||
"call-autonomous-static-art-smoke",
|
||||
&native_runtime_function_name("command.run_limited")
|
||||
.expect("limited command function"),
|
||||
smoke_arguments,
|
||||
),
|
||||
],
|
||||
Some(sender),
|
||||
);
|
||||
let _config_guard = write_test_local_config(format!(
|
||||
r#"{{
|
||||
"agentLlm": {{
|
||||
"art-asset-plan": {{
|
||||
"apiKey": "autonomous-static-art-verification-key",
|
||||
"baseUrl": {base_url:?},
|
||||
"model": "autonomous-static-art-verification-model",
|
||||
"apiKind": "openai_chat",
|
||||
"maxRetries": 0
|
||||
}}
|
||||
}}
|
||||
}}"#
|
||||
));
|
||||
let runtime = bind_autonomous_specialist_runtime_for_test(
|
||||
&root,
|
||||
"autonomous-static-art-verification-parent",
|
||||
"art-asset-plan",
|
||||
child_run_id,
|
||||
task,
|
||||
);
|
||||
prepare_agent_runtime_project_mutation_locked(
|
||||
&root,
|
||||
"art-asset-plan",
|
||||
child_run_id,
|
||||
"canvas.asset_generate",
|
||||
)
|
||||
.expect("record generated art mutation");
|
||||
let observations = vec![AgentRuntimeToolObservation {
|
||||
tool: "canvas.asset_generate".to_string(),
|
||||
status: "ok".to_string(),
|
||||
summary: "已生成 assets/manifest.art.json 与 assets/art-spritesheet.png".to_string(),
|
||||
detail: None,
|
||||
}];
|
||||
|
||||
let plan = request_game_creator_agent_background_tool_plan_for_test(
|
||||
&root,
|
||||
"art-asset-plan",
|
||||
&runtime.session_id,
|
||||
child_run_id,
|
||||
task,
|
||||
&observations,
|
||||
2,
|
||||
0,
|
||||
)
|
||||
.await
|
||||
.expect("repair static art delivery into static verification")
|
||||
.expect("static smoke verification plan");
|
||||
assert!(plan.response.is_empty());
|
||||
assert_eq!(plan.actions.len(), 1);
|
||||
assert_eq!(plan.actions[0].tool, "command.run_limited");
|
||||
assert_eq!(plan.actions[0].input["commandId"], "game.static_smoke");
|
||||
|
||||
receiver
|
||||
.recv_timeout(Duration::from_secs(2))
|
||||
.expect("initial static art response request");
|
||||
let repair_request = receiver
|
||||
.recv_timeout(Duration::from_secs(2))
|
||||
.expect("static art verification-only repair request");
|
||||
let repair_function_names = captured_native_function_names_for_test(&repair_request);
|
||||
assert_eq!(
|
||||
repair_function_names,
|
||||
BTreeSet::from([
|
||||
native_runtime_function_name("command.run_limited").expect("static smoke function")
|
||||
]),
|
||||
"pure static asset delivery must not expose package.json-backed project.verify"
|
||||
);
|
||||
let repair_request_json = mock_http_request_json(&repair_request);
|
||||
let repair_instruction = repair_request_json["messages"]
|
||||
.as_array()
|
||||
.and_then(|messages| messages.last())
|
||||
.and_then(|message| message.get("content"))
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.expect("static art repair instruction");
|
||||
assert!(repair_instruction.contains("game.static_smoke"));
|
||||
assert!(repair_instruction.contains("preview.validate"));
|
||||
assert!(!repair_instruction.contains("project.verify"));
|
||||
assert!(!repair_instruction.contains("package.json"));
|
||||
assert!(!repair_instruction.contains("Node"));
|
||||
assert!(receiver.recv_timeout(Duration::from_millis(200)).is_err());
|
||||
|
||||
fs::remove_dir_all(root).ok();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user