diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/entrypoints.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/entrypoints.rs index b3aefc508..282563633 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/entrypoints.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/entrypoints.rs @@ -93,6 +93,8 @@ impl DirectGameCreatorTurnUpdateEmitter { | "controlled-tool" | "web-search" | "context-compaction" + | "host-review" + | "error-feedback" | "response-finalization" | "none" ) @@ -102,11 +104,7 @@ impl DirectGameCreatorTurnUpdateEmitter { return; } let sequence = self.sequence.fetch_add(1, Ordering::AcqRel) + 1; - let updated_at = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_default() - .as_millis() - .min(u64::MAX as u128) as u64; + let updated_at = crate::agent::direct_now_ms(); update_active_turn( &self.thread_id, &self.turn_id, @@ -936,3 +934,33 @@ pub(crate) fn read_game_creator_agent_runtimes_at( .map(|agent_id| read_game_creator_agent_runtime_at(root, &agent_id)) .collect() } + +#[cfg(test)] +mod tests { + use super::*; + + /// DirectRuntime 实际传过的活动值必须都在 `emit` 白名单里:漏一个会在 debug 构建 panic、 + /// 在 release 构建静默丢掉整次进度回填(首页「运行中的项目」不再随这一轮更新)。 + #[test] + fn emit_accepts_every_activity_the_direct_runtime_passes() { + let root = std::env::temp_dir().join("agc-emit-activity-guard"); + let emitter = DirectGameCreatorTurnUpdateEmitter::new(&root, "turn-guard".to_string()); + for activity in [ + "request-accepted", + "preparing", + "file-read", + "file-write", + "game-verify", + "command-exec", + "controlled-tool", + "web-search", + "context-compaction", + "host-review", + "error-feedback", + "response-finalization", + "none", + ] { + emitter.emit("running", Some(activity)); + } + } +} diff --git a/docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md b/docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md index 0b8b2991f..b47f28b1f 100644 --- a/docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md +++ b/docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md @@ -46,9 +46,11 @@ ## 背景与现状(2026-09-14 立项时点) +> 以下记录立项时点的现状,用来解释这次改造的动机;其中「工具调用不留痕」「没有结构化工具调用」等结论都已被后续实现与 2026-09-16 修订取代,**当前状态以文首修订与 ADR 为准**。 + - 数据来源:Codex app-server 会推 `item/started` / `item/completed`,item 里带完整信息(`commandExecution.command`、`fileChange.changes[].path` 等)。 - 现状投影:`apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server.rs` 的 `direct_codex_item_intermediate_text()`(约 791 行)把 item **压成一行中文文本**(`正在执行命令:xxx` / `正在写入文件:xxx`),经 `DirectCodexTurnObservation::IntermediateText` 下发。 -- 前端事件:`GameCreatorDirectTurnUpdateEvent`(`src/app/types.ts:1090`)只有 `projectPath / turnId / sequence / status / activity / accumulatedText / updatedAt`,**没有结构化工具调用**。 +- 前端事件:`GameCreatorDirectTurnUpdateEvent`(该事件已随 issue #553 删除)只有 `projectPath / turnId / sequence / status / activity / accumulatedText / updatedAt`,**没有结构化工具调用**。 - 历史持久化:`.agent/conversations/project.jsonl` 现在只写 message 条目(实测 61 条全是 message),工具调用不留痕。 - 历史回读:`read_direct_project_chat_history_at()`(`direct_project_history.rs:575`)只把 `role ∈ {user, assistant}` 且有文本的条目投影成 `LocalConversationMessageRecord`,**形状上装不下工具调用**。 - 结论:要做成卡片必须同时改「采集 → 传输 → 持久化 → 回读 → 渲染」五段,纯前端做不出来。