From b39cd555ae1504616f7f510e7a420f0096ff0c93 Mon Sep 17 00:00:00 2001 From: Linghong Date: Wed, 23 Sep 2026 16:41:43 +0000 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86=E4=B9=9D=E6=9D=A1=E6=97=A7?= =?UTF-8?q?=E5=8C=85=E8=A3=85=E4=B8=8E=E5=A4=B1=E6=95=88=E9=97=A8=E7=A6=81?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除无调用的素材生成、Goal 与用户修订查询包装 清理恒假视觉门禁、专属提示词及不可达等待分支 移除 manifest 初始化未用参数并更新全部调用 以循环返回值替代 Direct 回合的冗余初始化,保持重试语义 同步现行行为文档、警告处理记录及未编译验证边界 --- .../prompts/runtime/texts/execution.json | 1 - .../src-tauri/src/agent/direct_runtime/mod.rs | 11 +- .../src-tauri/src/agent/generation.rs | 3 +- .../src/agent/generation/canvas_generation.rs | 27 --- .../agent/runtime_actions/project_gates.rs | 178 ------------------ .../src/agent/runtime_driver/main_loop.rs | 30 +-- .../src/agent/runtime_driver/task_start.rs | 65 +------ .../runtime_protocol/autonomous_completion.rs | 4 +- .../src/agent/runtime_tools/task_ops.rs | 29 +-- .../src-tauri/src/delegation.rs | 21 +-- .../src-tauri/src/project/manifest.rs | 28 +-- ...解决】主要构建入口编译警告清单-2026-09-23.md | 22 ++- ...案】AI游戏创作智能体App实施计划-2026-06-24.md | 6 + 13 files changed, 61 insertions(+), 364 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/prompts/runtime/texts/execution.json b/apps/ai-game-creator-shell/src-tauri/prompts/runtime/texts/execution.json index 261169b4d..bef5c46e7 100644 --- a/apps/ai-game-creator-shell/src-tauri/prompts/runtime/texts/execution.json +++ b/apps/ai-game-creator-shell/src-tauri/prompts/runtime/texts/execution.json @@ -15,7 +15,6 @@ "owner.task": "{base}\n\n这是 正式 owner 写入任务。必须实际生成并写入非空正式产物:{paths};JSON 文件必须是可解析 JSON,code-prototype 的 game/index.html 不能沿用初始化占位。{publish_package_requirement}{visual_usage_requirement}{visual_requirement}{verification_requirement}不要调用 task.update。", "background.previewReadiness": "{base}\n\n这是 只读静态验证任务,不要修改项目文件。固定核心动作是且只能是 command.run_limited(commandId=game.static_smoke);通过后直接交付验证结论,不要调用其它命令、项目 mutation 或 task.update。", "background.previewPlaytest": "{base}\n\n这是 只读试玩验收任务,不要修改项目文件。固定核心动作是且只能是 preview.validate;完成当前 revision 的桌面与移动试玩后直接交付验收结论,不要调用项目 mutation、其它预览动作或 task.update。", - "background.artDirection": "{base}\n\n这是 视觉方向任务。根据项目需求决定是否调用 canvas.asset_generate,并选择图片名称、数量、素材类别和布局;生成成功后直接交付结论。", "background.artDirectionWithoutCredentials": "{base}\n\n这是 无生图凭据只读协调任务。当前未配置 External Editor 生图凭据,上述 seed task 中 assets/art-spec.png 图片产物与生成验收条款在本轮不适用;只交付正式视觉方向结论,不要修改项目文件,不调用 canvas.asset_generate、game.static_smoke、project.verify、command.run_limited、preview 或 task.update。", "background.coordination": "{base}\n\n这是 只读协调任务,不要修改项目文件,也不要为了 manifest 内部回执路径写入 memory/、game/、assets/ 或 exports/。只读取当前项目事实,完成方向协调、审查或验收并直接交付结论;不要调用 task.update。", "background.relaxed": "处理 manifest ready 任务:{}\n\n任务 ID:{}\n专业组:{}\n角色:{}\n依赖(仅供参考):{}\n\n这是并行自主执行任务。请在当前项目根内按你的职责自行规划和调用可用工具,可以与其它任务同时进行。完成后直接回复实际完成情况。", diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs index a82a3d925..0b816ffee 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs @@ -5256,9 +5256,8 @@ async fn run_direct_game_creator_turn_inner( } else { let mut feedback_prompt = prompt.to_string(); let mut turn_kind = DirectCodexTurnKind::User; - let mut response = None; let mut attempt = 1; - loop { + let response = loop { let result = direct_game_creator_codex_chat_at_with_optional_observer( root, system_prompt.clone(), @@ -5273,15 +5272,15 @@ async fn run_direct_game_creator_turn_inner( match result { Ok(value) => { match super::direct_delivery::review_reply(root,&execution_session).await { - Ok(Some(report)) => { response = Some(report); break; } - Ok(None) => { response = Some(value); break; } + Ok(Some(report)) => break Some(report), + Ok(None) => break Some(value), Err(detail) if detail.starts_with("delivery-review-required:") => { feedback_prompt = format!(prompt_text!("direct.deliveryFeedback"),detail=detail); } Err(error) => return Err(DirectCodexTurnFailure::new(DirectCodexFailureStage::CodeGeneration,error)), } } - Err(_) if super::direct_delivery::terminal_report(&execution_session).is_some() => { response = super::direct_delivery::terminal_report(&execution_session); break; } + Err(_) if super::direct_delivery::terminal_report(&execution_session).is_some() => break super::direct_delivery::terminal_report(&execution_session), Err(error) if attempt < DIRECT_CODEX_ERROR_FEEDBACK_MAX_ATTEMPTS && direct_codex_error_should_feedback(&error) => @@ -5297,7 +5296,7 @@ async fn run_direct_game_creator_turn_inner( )); } } - } + }; response.ok_or_else(|| "陶泥儿错误反馈回合未返回结果".to_string()) } .map_err(|error| DirectCodexTurnFailure::new(DirectCodexFailureStage::CodeGeneration, error))?; diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/generation.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/generation.rs index c5642cca8..bad2f072a 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/generation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/generation.rs @@ -63,8 +63,7 @@ pub(crate) use canvas_generation::request_platform_art_asset_with_options_for_te #[allow(unused_imports)] pub(crate) use canvas_generation::{ build_platform_art_asset_prompt, editor_api_key_is_configured, generate_platform_art_asset_at, - generate_platform_art_asset_with_options_at, - generate_platform_art_asset_with_required_slices_at, maybe_generate_platform_art_asset_step, + generate_platform_art_asset_with_options_at, maybe_generate_platform_art_asset_step, needs_platform_art_asset_generation, normalize_platform_art_asset_generation_kind, normalize_platform_art_reference_asset_ids, normalize_platform_art_target_category, platform_art_asset_art_spec, platform_art_asset_output_extension_matches, diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs index 671986b72..30b035d8a 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs @@ -2579,33 +2579,6 @@ pub(crate) async fn generate_platform_art_asset_with_options_at( .await } -/// Generates the canonical game spritesheet together with the four durable -/// core slices. Callers that promise a playable game must use this instead -/// of the permissive asset path: a bare spritesheet is not enough evidence -/// that player, target, obstacle, and feedback visuals are available. -pub(crate) async fn generate_platform_art_asset_with_required_slices_at( - root: &Path, - prompt: &str, - briefs: &[AgentGroupBrief], - options: &PlatformArtAssetGenerationOptions, -) -> Result { - if options.asset_kind != GameCreationAppAssetKind::IconSpritesheet { - return Err("严格游戏切片生成只允许 icon-spritesheet 资产类型".to_string()); - } - let generation_prompt = build_platform_art_asset_prompt(prompt, options); - let runtime_context = - standalone_platform_art_generation_runtime_context(&generation_prompt, options, false)?; - generate_platform_art_asset_with_runtime_options_at( - root, - prompt, - briefs, - options, - false, - &runtime_context, - ) - .await -} - /// standalone 图片生成的**精确动作身份材料**。 /// /// 这份材料既是动作指纹(`actionFingerprint`)的来源,也是 durable 输出槽身份 diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/project_gates.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/project_gates.rs index b4b0c116b..4d4f72abe 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/project_gates.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/project_gates.rs @@ -1102,184 +1102,6 @@ pub(in crate::agent) fn agent_runtime_non_verification_completion_blocker_at_loc .or_else(|| process_session_completion_blocker_at_locked(root, agent_id, run_id)) .or_else(|| isolated_join_completion_blocker_at_locked(root, agent_id, run_id)) .or_else(|| static_delegate_completion_blocker_at_locked(root, agent_id, run_id)) - .or_else(|| visual_asset_completion_blocker_at_locked(root, agent_id, Some(run_id))) -} - -pub(in crate::agent) fn ui_prototype_visual_inspection_blocker_detail_at_locked( - root: &Path, - agent_id: &str, - required_run_id: Option<&str>, - expected_path: &str, -) -> Result, String> { - let inspection_run_id = required_run_id.unwrap_or("task_update_current_image"); - let mut images = load_agent_runtime_inspection_images( - root, - agent_id, - inspection_run_id, - &[expected_path.to_string()], - )?; - let image = images - .pop() - .ok_or_else(|| "UI 原型图片读取结果为空".to_string())?; - // 摘要缺失必须失败关闭:视觉检查审计按摘要证明「检查过的就是当前这张图」, - // 不能退化成空摘要比较,否则一条 sha256 为空的记录就能通过复核。 - let image_sha256 = image.sha256_digest()?.to_string(); - let (records, scan_truncated) = - read_agent_db_records_bounded(root, AGENT_RUNTIME_ACTION_HISTORY_MAX_DB_BYTES)?; - let matching = records.iter().rev().find(|record| { - record.get("recordType").and_then(serde_json::Value::as_str) - == Some("agent.runtime.image.inspect") - && record.get("agentId").and_then(serde_json::Value::as_str) == Some(agent_id) - && required_run_id.is_none_or(|run_id| { - record.get("runId").and_then(serde_json::Value::as_str) == Some(run_id) - }) - && record - .get("inspectionKind") - .and_then(serde_json::Value::as_str) - == Some(AGENT_RUNTIME_UI_DESIGN_INSPECTION_KIND) - && record - .get("validationProfile") - .and_then(serde_json::Value::as_str) - == Some(AGENT_RUNTIME_UI_PROTOTYPE_VALIDATION_PROFILE) - && record - .get("images") - .and_then(serde_json::Value::as_array) - .is_some_and(|items| { - items.len() == 1 - && items[0].get("path").and_then(serde_json::Value::as_str) - == Some(expected_path) - && items[0].get("sha256").and_then(serde_json::Value::as_str) - == Some(image_sha256.as_str()) - }) - }); - let Some(record) = matching else { - return Ok(Some(format!( - "expectedPath={expected_path} · currentSha256={} · requiredInspection=image.inspect · inspectionRunId={} · scanTruncated={scan_truncated}", - image_sha256, - required_run_id.unwrap_or("latest-current-image") - ))); - }; - let checks = serde_json::from_value::( - record - .get("checks") - .cloned() - .ok_or_else(|| "UI 原型视觉检查审计缺少 checks".to_string())?, - ) - .map_err(|error| format!("解析 UI 原型视觉检查 checks 失败:{error}"))?; - let issues = serde_json::from_value::>( - record - .get("issues") - .cloned() - .ok_or_else(|| "UI 原型视觉检查审计缺少 issues".to_string())?, - ) - .map_err(|error| format!("解析 UI 原型视觉检查 issues 失败:{error}"))?; - let assessment = AgentRuntimeUiPrototypeAssessment { - checks, - issues, - summary: "结构化 UI 视觉检查审计".to_string(), - } - .validate()?; - let recorded_passed = record - .get("passed") - .and_then(serde_json::Value::as_bool) - .ok_or_else(|| "UI 原型视觉检查审计缺少 passed".to_string())?; - if recorded_passed != assessment.passed() { - return Err("UI 原型视觉检查审计的 passed 与结构化字段冲突".to_string()); - } - if recorded_passed { - return Ok(None); - } - Ok(Some(format!( - "expectedPath={expected_path} · informationHud={} · gameplaySurface={} · objectiveEntities={} · primaryControls={} · failureRestartFlow={} · responsiveLayout={} · implementationClarity={} · originalTheme={} · issues={}", - assessment.checks.information_hud, - assessment.checks.gameplay_surface, - assessment.checks.objective_entities, - assessment.checks.primary_controls, - assessment.checks.failure_restart_flow, - assessment.checks.responsive_layout, - assessment.checks.implementation_clarity, - assessment.checks.original_theme, - assessment.issues.join(";"), - ))) -} - -pub(in crate::agent) fn visual_asset_completion_blocker_at_locked( - root: &Path, - agent_id: &str, - required_run_id: Option<&str>, -) -> Option { - // 图片产物由 Codex 按项目需求选择,不再存在固定视觉资产完成门禁。 - return None; - #[allow(unreachable_code)] - { - if !editor_api_key_is_configured() { - return None; - } - let (expected_path, expected_kind, label) = match agent_id { - "art-director" => ( - AGENT_RUNTIME_ART_SPEC_PATH, - GameCreationAppAssetKind::IconSpec, - "统一视觉规范图", - ), - "design-foundation" => ( - "assets/ui-prototype.png", - GameCreationAppAssetKind::UiDesign, - "策划界面原型图", - ), - "art-asset-plan" => ( - "assets/art-spritesheet.png", - GameCreationAppAssetKind::IconSpritesheet, - "首版美术素材图", - ), - _ => return None, - }; - let manifest = match read_manifest_for_project(root) { - Ok(manifest) => manifest, - Err(error) => { - return Some(AgentRuntimeToolObservation { - tool: "runtime.visual_asset".to_string(), - status: "blocked".to_string(), - summary: format!("无法核对{label},不能完成任务"), - detail: Some(redact_agent_runtime_project_paths(root, &error, 500)), - }); - } - }; - if let Err(error) = validate_manifest_required_visual_asset(root, &manifest, agent_id) { - return Some(AgentRuntimeToolObservation { - tool: "runtime.visual_asset".to_string(), - status: "blocked".to_string(), - summary: format!("{label}尚未按正式视觉流程生成并登记,不能完成任务"), - detail: Some(format!( - "expectedPath={expected_path} · expectedKind={expected_kind} · editorApiKeyConfigured={} · reason={}", - editor_api_key_is_configured(), - redact_agent_runtime_project_paths(root, &error, 300), - )), - }); - } - if agent_id != "design-foundation" { - return None; - } - match ui_prototype_visual_inspection_blocker_detail_at_locked( - root, - agent_id, - required_run_id, - expected_path, - ) { - Ok(None) => None, - Ok(Some(detail)) => Some(AgentRuntimeToolObservation { - tool: "runtime.visual_asset".to_string(), - status: "blocked".to_string(), - summary: "策划界面原型图尚未通过结构化 UI 视觉检查,不能完成任务".to_string(), - detail: Some(detail), - }), - Err(error) => Some(AgentRuntimeToolObservation { - tool: "runtime.visual_asset".to_string(), - status: "blocked".to_string(), - summary: "无法核对策划界面原型图的结构化 UI 视觉证据,不能完成任务".to_string(), - detail: Some(redact_agent_runtime_project_paths(root, &error, 500)), - }), - } - } } pub(in crate::agent) fn provider_retry_completion_blocker_at_locked( diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs index 2a85b26fe..0df942e3f 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs @@ -544,30 +544,30 @@ async fn run_game_creator_agent_background_task_pass_without_deadline( // impossible for a relaxed run to read the DAG and accidentally // re-enter `waiting-for-manifest-tasks`. if !relaxed_autonomous { - let autonomous_root_goal_contract_persisted = if agent_id + let autonomous_root_parent_identity_valid = if agent_id == GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID && runtime.run_profile == AGENT_RUNTIME_RUN_PROFILE_AUTONOMOUS_GAME_BUILD { - match autonomous_root_goal_contract_persisted_at( + match validate_autonomous_game_build_ready_task_parent_identity_at( &root, &agent_id, &runtime.run_id, ) { - Ok(value) => value, + Ok(_) => true, Err(error) => { return fail_game_creator_agent_background_context_at( &root, &agent_id, &session_id, runtime, - &format!("读取自主构建根 Goal Contract 门失败:{error}"), + &format!("校验自主构建根任务身份失败:{error}"), ); } } } else { false }; - let autonomous_manifest_parent_can_wait = autonomous_root_goal_contract_persisted + let autonomous_manifest_parent_can_wait = autonomous_root_parent_identity_valid && agent_id == GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID && runtime.run_profile == AGENT_RUNTIME_RUN_PROFILE_AUTONOMOUS_GAME_BUILD && !game_creator_agent_runtime_provider_action_batch_exists( @@ -1471,13 +1471,6 @@ async fn run_game_creator_agent_background_task_pass_without_deadline( .or_else(|| { static_delegate_completion_blocker_at(&root, &agent_id, &runtime.run_id) }) - .or_else(|| { - visual_asset_completion_blocker_at_locked( - &root, - &agent_id, - Some(&runtime.run_id), - ) - }) .or_else(|| { project_verification_completion_blocker_at( &root, @@ -1648,19 +1641,6 @@ async fn run_game_creator_agent_background_task_pass_without_deadline( runtime.next_step = "调用 agent.run_status 取得 readyDelegateReceipts".to_string(); } - } else if blocker.tool == "runtime.visual_asset" { - runtime.status = "running".to_string(); - runtime.phase = "waiting-for-visual-asset".to_string(); - if agent_id == "design-foundation" { - runtime.current_action = "等待可验收的 UI 原型图".to_string(); - runtime.waiting_on = - "图片生成、manifest 登记与 ui-prototype.v2 结构化视觉检查".to_string(); - runtime.next_step = "缺图时调用 canvas.asset_generate;已有候选时对 assets/ui-prototype.png 调用 image.inspect;未通过时如实返回 needs-repair,由 Supervisor 认领后发起唯一 repair 原位替换,禁止先删除正式图片".to_string(); - } else { - runtime.current_action = "等待实际图片产物".to_string(); - runtime.waiting_on = "图片生成确认、配置与本地 manifest 登记".to_string(); - runtime.next_step = "调用 canvas.asset_generate 生成确定路径图片,并用 asset.list 核对登记结果".to_string(); - } } else if blocker.tool == "runtime.autonomous_completion" { runtime.status = "running".to_string(); runtime.phase = "planning".to_string(); diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs index 2b6b56999..8fb4bb594 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs @@ -669,7 +669,7 @@ pub(crate) fn schedule_game_creator_agent_ready_tasks_at( Ok(results) } -fn validate_autonomous_game_build_ready_task_parent_identity_at( +pub(super) fn validate_autonomous_game_build_ready_task_parent_identity_at( root: &Path, parent_agent_id: &str, parent_run_id: &str, @@ -691,33 +691,6 @@ fn validate_autonomous_game_build_ready_task_parent_identity_at( Ok(binding) } -fn autonomous_root_goal_contract_persisted_for_binding_at( - root: &Path, - binding: &AgentRuntimeRunProfileBinding, -) -> Result { - Ok( - read_game_creator_agent_runtime_goal_contract_at(root, &binding.agent_id, &binding.run_id)? - .is_some(), - ) -} - -/// Return whether the trusted autonomous root has a valid, persisted Goal -/// Contract. The scheduler uses the `false` result as a safe no-op when the -/// sidecar has not landed yet; malformed or identity-conflicting sidecars are -/// deliberately propagated by `read_game_creator_agent_runtime_goal_contract_at`. -pub(crate) fn autonomous_root_goal_contract_persisted_at( - root: &Path, - parent_agent_id: &str, - parent_run_id: &str, -) -> Result { - validate_autonomous_game_build_ready_task_parent_identity_at( - root, - parent_agent_id, - parent_run_id, - )?; - Ok(true) -} - fn validate_autonomous_game_build_ready_task_parent_at( root: &Path, parent_agent_id: &str, @@ -1500,7 +1473,7 @@ pub(in crate::agent) fn project_autonomous_manifest_ready_task_terminal_at_locke else { return Ok(false); }; - let mut status = match state.phase.as_str() { + let status = match state.phase.as_str() { "completed" => GameCreationAppTaskStatus::Completed, "failed" | "cancelled" | "budget-exhausted" => GameCreationAppTaskStatus::Failed, _ => return Ok(false), @@ -1550,27 +1523,6 @@ pub(in crate::agent) fn project_autonomous_manifest_ready_task_terminal_at_locke manifest_task, &task_text, )?; - if status == GameCreationAppTaskStatus::Completed - && !autonomous_relaxed_run_profile(&state.run_profile) - && autonomous_manifest_ready_task_requires_visual_asset(&manifest_task.id) - && !manifest_has_required_visual_asset(root, &manifest, &manifest_task.id) - { - status = GameCreationAppTaskStatus::Failed; - append_agent_db_record( - root, - serde_json::json!({ - "recordType": "agent.runtime.autonomous_ready_task.missing_visual_failed", - "agentId": state.agent_id, - "taskId": state.agent_id, - "sessionId": state.session_id, - "runId": state.run_id, - "source": state.source, - "parentAgentId": parent_agent_id, - "parentRunId": parent_run_id, - "terminalPhase": state.phase, - }), - )?; - } if status == GameCreationAppTaskStatus::Completed && !autonomous_relaxed_run_profile(&state.run_profile) { @@ -1633,10 +1585,6 @@ pub(in crate::agent) fn project_autonomous_manifest_ready_task_terminal_at_locke Ok(true) } -pub(super) fn autonomous_manifest_ready_task_requires_visual_asset(task_id: &str) -> bool { - false -} - fn render_autonomous_manifest_ready_task_owner_prompt(task: &GameCreationAppTaskState) -> String { let base = render_manifest_ready_task_background_prompt(task); let paths = autonomous_manifest_owner_artifact_paths(&task.id).join(", "); @@ -1688,12 +1636,6 @@ pub(in crate::agent) fn render_autonomous_manifest_ready_task_background_prompt( ); } if task.id == "art-director" { - if autonomous_manifest_ready_task_requires_visual_asset(&task.id) { - return format!( - prompt_text!("execution.background.artDirection"), - base = base, - ); - } return format!( prompt_text!("execution.background.artDirectionWithoutCredentials"), base = base, @@ -1823,9 +1765,6 @@ mod tests { assert!(prompt.contains("无生图凭据只读协调任务")); assert!(prompt.contains("assets/art-spec.png 图片产物与生成验收条款在本轮不适用")); assert!(prompt.contains("不要修改项目文件")); - assert!(!autonomous_manifest_ready_task_requires_visual_asset( - "art-director" - )); assert!(agent_runtime_task_requires_read_only_delivery( "art-director", &prompt diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs index e289e81e0..3618ca475 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs @@ -7232,7 +7232,7 @@ fn reset_cancelled_reconciliation_manifest_tasks_for_continuation_at( "runtime.autonomous.manifest.reconciliation_cancel_retry", )?; let (manifest_path, mut manifest) = read_or_create_manifest(root)?; - ensure_manifest_seed_tasks(root, &mut manifest); + ensure_manifest_seed_tasks(&mut manifest); let failed_task_ids = manifest .tasks .iter() @@ -14626,7 +14626,7 @@ fn reset_autonomous_manifest_seed_tasks_at( "runtime.autonomous.manifest.reset", )?; let (manifest_path, mut manifest) = read_or_create_manifest(root)?; - ensure_manifest_seed_tasks(root, &mut manifest); + ensure_manifest_seed_tasks(&mut manifest); let seed_task_ids = new_game_creation_app_seed_tasks() .into_iter() .map(|task| task.id) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/task_ops.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/task_ops.rs index f5360e521..9ff8dede7 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/task_ops.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/task_ops.rs @@ -320,28 +320,13 @@ pub(in crate::agent) fn observe_agent_runtime_task_update( detail: None, }; } - let relaxed_autonomous = match task_ops_relaxed_autonomous_profile_at(root, agent_id, run_id) { - Ok(value) => value, - Err(error) => { - return AgentRuntimeToolObservation { - tool: "task.update".to_string(), - status: "failed".to_string(), - summary: redact_agent_runtime_project_paths(root, &error, 240), - detail: None, - }; - } - }; - if status == GameCreationAppTaskStatus::Completed && !relaxed_autonomous { - if let Some(blocker) = - visual_asset_completion_blocker_at_locked(root, task_id.as_str(), None) - { - return AgentRuntimeToolObservation { - tool: "task.update".to_string(), - status: "failed".to_string(), - summary: blocker.summary, - detail: blocker.detail, - }; - } + if let Err(error) = task_ops_relaxed_autonomous_profile_at(root, agent_id, run_id) { + return AgentRuntimeToolObservation { + tool: "task.update".to_string(), + status: "failed".to_string(), + summary: redact_agent_runtime_project_paths(root, &error, 240), + detail: None, + }; } let result = update_manifest_task_status_at(root, task_id.as_str(), status).and_then(|task| { append_agent_db_record( diff --git a/apps/ai-game-creator-shell/src-tauri/src/delegation.rs b/apps/ai-game-creator-shell/src-tauri/src/delegation.rs index e460e8f05..4b6a402e3 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/delegation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/delegation.rs @@ -1263,25 +1263,8 @@ fn static_delegate_original_is_awaiting_clarification( }) } -/// 唯一权威判据:某条 delivery 是否由用户审批的「修改」动作标记为待修订。 -/// -/// 该状态只由后续审批工作包写入;本包只让 lineage 重放认识它,不能自行生成或 -/// 把其它状态静默映射成它。 -/// 该原 delivery 是否正等着用户提出的修订(而不是质量返工)。 -/// -/// 用户修订和质量返工都带 `repairOfDelegationId`,但额度完全不同:`repair_depth` -/// 防的是 runaway agent,而用户修订每一轮都由人触发,人本身就是循环边界。委派 task -/// 末尾那句「你在这条链路上的位置」必须按这个判据分开渲染,否则用户第一次点修改就会 -/// 被告知「这是唯一返工轮」。 -pub(crate) fn static_delegate_original_awaits_user_revision_at( - root: &Path, - delegation_id: &str, -) -> Result { - Ok(read_static_delegate_delivery_at(root, delegation_id)? - .as_ref() - .is_some_and(static_delegate_original_is_user_revision_requested)) -} - +/// 识别持久交付记录中的用户修订状态,供 lineage 重放和修订请求校验共用。 +/// 用户修订不消耗质量返工深度;此判据不写入状态,也不把其它状态映射成用户修订。 fn static_delegate_original_is_user_revision_requested( delivery: &StaticDelegateDeliveryRecord, ) -> bool { diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs b/apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs index ae4ad0550..873305801 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs @@ -863,7 +863,7 @@ pub(crate) fn record_preview_state( port: Option, ) -> Result<(), String> { let (manifest_path, mut manifest) = read_or_create_manifest(root)?; - ensure_manifest_seed_tasks(root, &mut manifest); + ensure_manifest_seed_tasks(&mut manifest); let is_running = status == GameCreationAppPreviewStatus::Running; manifest.preview = Some(GameCreationAppPreviewState { status, url, port }); if is_running && !autonomous_game_build_root_run_active_at(root) { @@ -881,7 +881,7 @@ pub(crate) fn record_command_run( run: GameCreationAppCommandRunState, ) -> Result<(), String> { let (manifest_path, mut manifest) = read_or_create_manifest(root)?; - ensure_manifest_seed_tasks(root, &mut manifest); + ensure_manifest_seed_tasks(&mut manifest); if !autonomous_game_build_root_run_active_at(root) && run.command_id == "game.static_smoke" && run.status == GameCreationAppCommandRunStatus::Completed @@ -917,12 +917,12 @@ pub(crate) fn read_manifest_for_project(root: &Path) -> Result Result { let godot_project_root = discover_local_godot_project_root(root)?; let (manifest_path, mut manifest) = read_or_create_manifest(root)?; - ensure_manifest_seed_tasks(root, &mut manifest); + ensure_manifest_seed_tasks(&mut manifest); manifest.godot_project_root = godot_project_root; write_manifest(&manifest_path, &manifest)?; Ok(manifest) @@ -1071,7 +1071,7 @@ pub(crate) fn ensure_manifest_has_seed_tasks( goal: Option<&str>, ) -> Result { mutate_manifest_at(root, |manifest| { - ensure_manifest_seed_tasks(root, manifest); + ensure_manifest_seed_tasks(manifest); if let Some(goal) = goal.map(str::trim).filter(|goal| !goal.is_empty()) { manifest.goal = Some(goal.to_string()); } @@ -1086,7 +1086,7 @@ pub(crate) fn record_draft_task_progress( agent_log_path: &Path, ) -> Result { let (manifest_path, mut manifest) = read_or_create_manifest(root)?; - ensure_manifest_seed_tasks(root, &mut manifest); + ensure_manifest_seed_tasks(&mut manifest); manifest.goal = Some(goal.to_string()); for completed_task_id in [ "design-director", @@ -1122,7 +1122,7 @@ pub(crate) fn record_draft_task_progress( Ok(manifest) } -pub(crate) fn ensure_manifest_seed_tasks(root: &Path, manifest: &mut GameCreationAppManifest) { +pub(crate) fn ensure_manifest_seed_tasks(manifest: &mut GameCreationAppManifest) { let seed_tasks = new_game_creation_app_seed_tasks(); if manifest.tasks.is_empty() { manifest.tasks = seed_tasks; @@ -1148,14 +1148,6 @@ pub(crate) fn ensure_manifest_seed_tasks(root: &Path, manifest: &mut GameCreatio } } -pub(crate) fn manifest_has_required_visual_asset( - root: &Path, - manifest: &GameCreationAppManifest, - task_id: &str, -) -> bool { - validate_manifest_required_visual_asset(root, manifest, task_id).is_ok() -} - pub(crate) fn validate_manifest_required_visual_asset( root: &Path, manifest: &GameCreationAppManifest, @@ -1330,7 +1322,7 @@ pub(crate) fn update_manifest_task_status_at( return Err("任务 ID 不能为空".to_string()); } mutate_manifest_at(root, |manifest| { - ensure_manifest_seed_tasks(root, manifest); + ensure_manifest_seed_tasks(manifest); let Some(task) = manifest.tasks.iter_mut().find(|task| task.id == task_id) else { return Err(format!("项目任务不存在:{task_id}")); }; @@ -1691,7 +1683,7 @@ pub(crate) fn create_manifest_task_at( acceptance_criteria: Vec, ) -> Result { let (manifest_path, mut manifest) = read_or_create_manifest(root)?; - ensure_manifest_seed_tasks(root, &mut manifest); + ensure_manifest_seed_tasks(&mut manifest); let fallback_id = format!( "agent-task-{}-{}", unix_timestamp(), diff --git a/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md b/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md index c0cbc28a7..ea6fd62b7 100644 --- a/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md +++ b/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md @@ -7,7 +7,7 @@ ## 1. 基线与范围 -首次诊断的基线提交为 `016356e509f11a1a638ce45ed51b9e40ef3e36a2`,诊断时工作树干净。环境为 Windows x64、Rust `1.98.1`、Node `v24.15.0`、npm `12.0.2`。第 2~6 节和附录保留首次诊断快照;后续处理状态及契约核查见第 7~18 节,不能将附录的全部条目视为仍未解决。 +首次诊断的基线提交为 `016356e509f11a1a638ce45ed51b9e40ef3e36a2`,诊断时工作树干净。环境为 Windows x64、Rust `1.98.1`、Node `v24.15.0`、npm `12.0.2`。第 2~6 节和附录保留首次诊断快照;后续处理状态及契约核查见第 7~19 节,不能将附录的全部条目视为仍未解决。 AGC Rust 使用默认 features、dev profile;237 是本轮编译器诊断数,不代表 237 个独立根因,也不是所有平台、features 和 test targets 的总数。另有 5 条不带常规源码 span 的 ts-rs 宏提示,不计入 237。 @@ -615,6 +615,26 @@ W076 只将 Pending(String) 收窄为 Pending;三处生产返回前继续记 最近一次实测仍为第 14 节的 50 条;第 15~16 节预期减少 20 条,本批再处理 6 条,预期剩余 **24 条**,尚未重新编译确认。 +## 19. 剩余旧包装、失效门禁及冗余参数清理(2026-09-23) + +本批处理 W051、W071、W116、W210~W212、W216、W221、W234 共 9 条诊断。此前明确暂留的 W004~W006、W113 以及平台 / feature / 构建脚本项不在本批范围内。 + +| 编号 | 实施结论 | +| --- | --- | +| W051 | 删除没有调用方的 `generate_platform_art_asset_with_required_slices_at` 及 facade 导出;现役生成入口、内部切片提交和素材校验保留。 | +| W071 | 删除孤立的 Goal 读取 helper,以及只校验身份却以 Goal 持久化命名的转发包装。主循环直接复用父任务身份校验,修正局部变量和错误说明,不恢复已停用的 Goal 前置门。 | +| W116 | 删除无调用的用户修订查询包装;保留持久状态判据、lineage 重放及修订校验。注释改为实际职责,不再声称存在包装的提示词消费者。 | +| W210~W212 | 删除恒返回 `None` 的固定视觉素材门禁、不可达旧实现及其专属 UI 检查 helper,移除三个空调用和主循环中只消费旧门禁结果的等待分支。`task.update` 仍执行原有 Run Profile 读取及错误返回,现役图像检查、素材与完成合同校验保留。 | +| W216 | 删除恒为 `false` 的素材需求判断、不可达失败投影、永不选择的提示词分支及其专属文本;顺带删除失去唯一调用方的 `manifest_has_required_visual_asset` 布尔包装。保留实际使用的提示词和原有只读断言,仅移除对恒假 helper 的断言,不迁移或新增测试。 | +| W221 | `ensure_manifest_seed_tasks` 删除未用 `root`,更新全部 11 处调用;任务状态和元数据同步行为不变。 | +| W234 | Direct 无 observer 路径以循环返回值代替必被覆盖的 `response = None`。反馈、重试计数、错误传播和终态报告读取次数 / 顺序保持不变。 | + +边界:旧 `art-director` 提示词函数原先无论凭据是否配置都选择只读分支,本批保留该实际行为;现役 relaxed 调度提示词不变。调整提示词的凭据策略不属于 warning 清理,不能借删除恒假条件悄然恢复旧门禁。 + +验证:修改文件 rustfmt 检查、编码检查、文档索引及 `git diff --check`;静态核对删除符号、全部删参调用、身份校验与异常路径,并解析修改后的提示词 JSON。遵照用户不跑全量编译的要求,未执行 Cargo check/build/test、Rust 单元测试或跨平台构建;静态检查不替代类型检查与运行验证。 + +最近一次实测仍为第 14 节的 50 条;第 15~18 节已处理 26 条,本批再处理 9 条,预期剩余 **15 条**(11 条平台 / feature / 构建脚本项、4 条暂留契约项),尚未重新编译确认。另有 5 条 ts-rs 提示,不包含在本计数中。 + ## 附录:237 条编译器诊断位置 以下是诊断的人工可读整理,不保存原始构建日志、本机路径或 target 缓存路径。位置相对 `apps/ai-game-creator-shell/src-tauri/`;行号只对应本节基线,修改后以符号搜索及重新编译为准。每条保留一个主要 span,编号用于本清单内跟踪,不表示独立业务缺陷。生成产物项须回到 `build_support/runtime_prompt_bundle.rs` 处理。 diff --git a/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md b/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md index cdba75b97..25a2f9491 100644 --- a/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md +++ b/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md @@ -4,6 +4,12 @@ 策划 V1、策划会话 Runtime V2 均已删除,当前“做方案”只使用独立 Design Agent,现行合同见[策划 Agent 生产迁移与工作区浏览](./【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)。旧 V1/V2 Runtime、命令、会话、审批卡、身份白名单和专属测试不作为兼容或恢复目标;历史方案中的 lifecycle v3、planning binding 等要求不能作为孤立代码的保留依据。共享能力按现役调用判断,不因名称相似删除当前 Design Agent 或通用 Runtime。 +## 固定视觉门禁与任务身份的现行边界 + +图片产物按项目需求选择,不恢复按固定 Agent 身份要求视觉资源的旧完成门禁。已停用门禁的空调用、不可达检查和无消费者包装直接清理;现役 `validate_manifest_required_visual_asset`、图片检查、内部切片提交及各完成合同继续按各自调用场景执行,不因清理旧门禁而一并删除。 + +自主任务父身份校验只核对当前父任务及 Run Profile 绑定,不代表 Goal Contract 已持久化,也不新增等待 Goal 文件的前置条件。manifest seed 同步保留执行状态,不以素材检查结果重新推导任务状态。用户修订的持久状态判据继续供 lineage 重放与修订请求校验使用,不依赖已无消费者的查询包装。 + ## 2026-09-23 Direct 宿主继续请求输入修复 - 首次模型请求使用原始结构化用户输入,保留 Skill 提及及其它引用;未提供结构化输入时沿用请求正文与图片转换。