From 7adabea656c630a87e0447e093cf7b4fa748d0a0 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Mon, 14 Sep 2026 14:19:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B7=A5=E5=85=B7=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E5=8D=A1=E7=89=87=E6=8A=80=E6=9C=AF=E6=96=B9=E6=A1=88?= =?UTF-8?q?=EF=BC=88=E5=A5=91=E7=BA=A6=E5=86=BB=E7=BB=93=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/technical:【技术方案】GameAgent对话工具调用卡片-2026-09-14.md:工具调用条目形状、独立历史文件 tool-calls.jsonl、事件新增 toolCalls 字段、read_direct_tool_calls 回读命令、卡片 DOM 与无障碍要求、验收判据与不做项 - docs/README.md:把该方案登记进「AI 游戏创作与 Agent Runtime」索引 - 方案明确不改 project.jsonl 既有格式与 Codex 上下文注入路径,避免污染模型上下文 --- docs/README.md | 1 + ...方案】GameAgent对话工具调用卡片-2026-09-14.md | 108 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md diff --git a/docs/README.md b/docs/README.md index 531c0c706..44066f85b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -32,6 +32,7 @@ - [AI 游戏创作智能体 App 实施计划](./technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md):当前 DirectProject、受控语义工具、UI workflow、资源和运行时合同。 - [策划会话 Runtime V2 接入与旧链路退役方案](./technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md):新单 Agent 策划会话、GDD 策略、未来 MCP/Skill 兼容插槽、阶段任务与退役验收合同。 - [DirectProject Codex 原始历史与异常恢复](<./technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md>):原始 Responses item 持久化、线程注入与异常回合收尾。 +- [GameAgent 对话工具调用卡片](./technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md):把右侧对话里的执行命令 / 写文件投影成 Codex 风格可折叠卡片,含采集、独立历史文件、事件字段与回读契约。 - [DirectProject 客户端 Skill 与 MCP 扩展导入方案](./technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md):客户端扩展导入、按独立 Skill/MCP 拆分、命名、启用和启动时注入边界。 - [AGC 通用插件宿主与编辑器适配](./technical/【技术方案】AGC通用插件宿主与编辑器适配-2026-09-09.md):通用插件宿主、SDK、权限审计、UI 挂载和 Cocos 编辑器适配边界。 - [AGC Cocos Creator 编辑器桥接模块](<./technical/【技术方案】AGC Cocos Creator 编辑器桥接模块-2026-09-09.md>):独立 crate、feature 开关、目标校验与 Windows 注入边界。 diff --git a/docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md b/docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md new file mode 100644 index 000000000..7cf7c832e --- /dev/null +++ b/docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md @@ -0,0 +1,108 @@ +# 【技术方案】GameAgent 对话工具调用卡片(Codex 风格)-2026-09-14 + +## 一句话交付 + +把 GameAgent 右侧对话面板里的「执行命令 / 写文件 / 调工具」从一行中文进度文本,改成 Codex 桌面客户端那样的**可折叠卡片**(折叠态一行摘要,展开态看命令与文件明细),并且在**刷新页面、重开项目后仍然存在**。 + +## 背景与现状(已核实) + +- 数据来源: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`,**没有结构化工具调用**。 +- 历史持久化:`.agent/conversations/project.jsonl` 现在只写 message 条目(实测 61 条全是 message),工具调用不留痕。 +- 历史回读:`read_direct_project_chat_history_at()`(`direct_project_history.rs:575`)只把 `role ∈ {user, assistant}` 且有文本的条目投影成 `LocalConversationMessageRecord`,**形状上装不下工具调用**。 +- 结论:要做成卡片必须同时改「采集 → 传输 → 持久化 → 回读 → 渲染」五段,纯前端做不出来。 + +## 契约(实现必须照此,不得自行改形状) + +### 1. 工具调用条目(采集与持久化形状) + +新增独立历史文件:`/.agent/conversations/tool-calls.jsonl`,一行一条,行信封与既有历史一致: + +```json +{ "type": "tool_call_item", "payload": { "schemaVersion": "agc-tool-call.v1", "id": "...", "turnId": "...", "kind": "command|file_change|mcp_tool|web_search|context_compaction|other", "title": "执行命令", "summary": "npm run build", "status": "running|completed|failed", "detail": { "command": "...", "output": "...", "changes": [{ "path": "game/src/x.ts", "kind": "add|update|delete" }] }, "startedAt": 0, "updatedAt": 0 } } +``` + +- `id`:Codex item 的 id;同一 item 的 `started` 与 `completed` 必须落成**同一条**(按 id 幂等 upsert,不允许写两行)。 +- `title` 是折叠态的一行标题,按 kind 固定:`command` → `执行命令`、`file_change` → `编辑 N 个文件`(N = changes 去重后数量)、其余见 kind 枚举。 +- `summary` 是折叠态标题后面的短摘要:命令取命令首行(截断 120 字符),`file_change` 取首个变更路径。 +- `detail.command` / `detail.output` 各截断到 4000 字符;`detail.changes[].path` 用项目相对路径。 +- **必须脱敏**:沿用既有 `codex_app_server.rs` 里对 command/tool 参数的安全处理,不得把 API Key、Token、Cookie、绝对用户目录写进 `detail`。 + +### 2. 实时事件(新增字段,不改既有字段语义) + +`GameCreatorDirectTurnUpdateEvent` 增加**可选**字段: + +```ts +toolCalls?: DirectTurnToolCall[] | null; +``` + +- 只有在本回合工具调用集合发生变化时才带(不要每个 heartbeat 都重发全量)。 +- 字段**可选**:老版本事件解析路径必须保持兼容(前端拿到 `undefined` 时行为与现在一致)。 +- `DirectTurnToolCall` 与上面 payload 同形(去掉 `turnId`)。 + +### 3. 回读命令 + +新增 Tauri 命令 `read_direct_tool_calls(projectPath)`,返回按时间正序的 `DirectTurnToolCall[]`,最多最近 200 条(超出截断,保留最新)。 + +- 历史文件缺失 → 返回空数组,不报错。 +- 单行损坏 → 跳过该行继续,不整体失败(与 Codex item 流一样是"尽力而为"的展示数据,不是业务真相)。 + +### 4. 前端合并与渲染 + +- 加载对话时把回读结果按 `turnId` 归并进消息流:工具调用卡插在**同一回合最后一条 assistant 消息之后**,同一回合内按 `startedAt` 升序。 +- 实时回合(`directCodexProductRuntime` 且 `activeDirectCodexTurnRef` 命中)时,卡片跟着事件增量更新;回合结束后由持久化数据接管(不出现重复卡片,同一 `id` 只渲染一次)。 +- 卡片 DOM 与交互(对齐 Codex): + +```html +
+ + +
+``` + +- 必须用 `