Merge branch 'master' into feat/agc-use-ui-design
Project CI / Repository checks (pull_request) Successful in 4m32s
Project CI / Frontend tests (pull_request) Successful in 4m4s
Project CI / Backend tests (pull_request) Successful in 7m17s
Project CI / Native shell tests (pull_request) Failing after 17m10s

This commit is contained in:
2026-09-01 20:20:17 +08:00
32 changed files with 4047 additions and 55 deletions
@@ -1755,6 +1755,6 @@ V1.54 的公共编排层可以在运行前构造动态 DAG,但 LLM 在执行
## DirectProject 原生工具边界覆盖(2026-08-24)
本文中 V1.1/V1.52 关于 app-server 全局关闭 native shell、network、browser、plugin 和 multi-agent 的表述继续适用于 ToolHost/DirectHome 与 legacy Runtime;不再作为 DirectProject 的现行实现。DirectProject 恢复原生文件/搜索/命令、图片查看和 Skill,并通过隔离 `CODEX_HOME` 只注入审核后的 `agc_tools` MCP。平台美术、资源投影、浏览器试玩、受控搜索、付费副作用和 durable delegation 仍必须走 AGC 权威链路。
本文中 V1.1/V1.52 关于 app-server 全局关闭 native shell、network、browser、plugin 和 multi-agent 的表述继续适用于 ToolHost/DirectHome 与 legacy Runtime;不再作为 DirectProject 的现行实现。DirectProject 恢复原生文件/搜索/命令、图片查看和 Skill,始终注入审核后的 `agc_tools` MCP,并可在启动时从客户端扩展仓库接入用户已启用的独立第三方 MCP 配置;第三方配置不进入全局 Codex home,不开启完整 Plugin Runtime。平台美术、资源投影、浏览器试玩、受控搜索、付费副作用和 durable delegation 仍必须走 AGC 权威链路。
DirectProject 的写入根固定为真实 `game/`,审批策略为 `never`,原生命令网络保持关闭,联网资料继续走受控 `agc_web_search`;shell 使用 Codex `shell_environment_policy` 的 glob 排除 API key、proxy、loopback bridge 和受控开关。配置了 AGC LLM Key 或可解析的 `OPENAI_API_KEY` 登录态时,真实 provider 凭据只由 AGC 本地 provider proxy 持有,Codex 仅获得连接级随机代理令牌;无法安全代理的 OAuth `auth.json` 继续关闭 native shell/unified exec。Codex 原生子 Agent、Apps、插件、hooks、图片生成、Goals、Workspace Dependencies、Tool Suggestion 以及未接入 AGC 证据链的浏览器/电脑控制保持关闭。系统提示词只传入最小身份、工作区、Skill 索引和副作用边界,不再批量注入源码快照或 Skill 正文。sandbox writableRoots 不提供 deny-read;`.agent` 与 `../assets` 的不可读约束仍需通过 prompt/Skill 行为合同和真实 smoke 验证,不能误称为 OS 强制隔离。
@@ -1184,7 +1184,7 @@ game-project/
- 普通项目对话只由一个 project-bound Codex app-server thread 执行。客户端系统提示词只放最小工程合同、当前游戏源码有界快照、项目 prompts 和审核 Skill 索引;不再批量读取项目 `.codex/.agents` Skill 正文,也不恢复 Supervisor、专业 Agent 或 harness。
- 首页恢复“做游戏 / 做素材 / 做方案”三个创作类型,默认“做游戏”。该选择与设置页的 Agent Runtime 模式无关;每次首页提交仍只自动创建一个新项目并进入项目工作台。用户正文原样进入项目对话,`game|art|doc` 仅作为受限结构化首轮上下文传给同一 Codex thread,不拼接“初始意图”文案、不产生首页对话、不切换 Provider 或恢复旧 Runtime 编排。
- `agc-skill-pack.v1` 只包含项目结构、陶泥儿美术、Web 游戏实现、真实浏览器试玩、客户端资源投影五项 Skill。清单记录用途、触发条件、所需工具、版本和内容 SHA-256;审核文本按 UTF-8 读取并将 CRLF 规范为 LF 后计算指纹和安装,避免混合换行造成 Windows / Linux 构建结果漂移,语义内容变化时必须同步重算对应清单指纹并提升版本。同步统一运行 `npm run agc:skill-pack:sync`,只读校验由 AGC `typecheck` 和 release build 自动执行,发现漂移时直接列出 Skill 与实际摘要,不让失配内容进入构建产物。客户端把审核文件安装到隔离目录后通过 app-server `skills/extraRoots/set + skills/list` 注册并复核,完整正文由 Codex 原生 Skill 机制按意图加载,一层引用只能经 `agc_read_skill_resource` 读取清单内 Markdown。引用路径按平台无关规则拒绝反斜杠、盘符、UNC、绝对路径和 `..`,不能依赖当前宿主的 `std::path` 语义判断其它平台路径。
- DirectProject 只连接客户端内置的 `agc_tools` STDIO MCP,工具固定为审核引用读取、标准陶泥儿美术准备、已登记资源有界查询、视频 / 角色动画 / 音效 / BGM 的 create-or-derive 语义生成、已登记图片去背景和 desktop/mobile 浏览器试玩。MCP 进程只做协议;真实浏览器与付费 External v1 调用通过随机 loopback 地址回到客户端主进程,因此不复制 GUI 登录态、开发者 Key、项目路径、revision、operation 或幂等键到模型上下文。已登记工具固定自动批准,但付费资源工具仍由客户端绑定稳定回合身份、限制单回合请求数、串行执行并优先恢复匹配账本;通用 shell、Codex 原生 webSearch、任意网络、多 Agent、插件和外部 MCP 继续关闭。`codex_app_server` 模式要求 `llm.webSearchEnabled=false`。
- DirectProject 始终连接客户端内置的 `agc_tools` STDIO MCP;2026-08-31 起还会在启动时接入客户端扩展仓库中用户已启用的独立第三方 STDIO/HTTP MCP 配置,但不读取用户全局 Codex MCP、不开启完整 Plugin Runtime。`agc_tools` 工具固定为审核引用读取、标准陶泥儿美术准备、已登记资源有界查询、视频 / 角色动画 / 音效 / BGM 的 create-or-derive 语义生成、已登记图片去背景和 desktop/mobile 浏览器试玩。内置 MCP 进程只做协议;真实浏览器与付费 External v1 调用通过随机 loopback 地址回到客户端主进程,因此不复制 GUI 登录态、开发者 Key、项目路径、revision、operation 或幂等键到模型上下文。内置与用户启用的第三方 MCP 工具都沿用 DirectProject 自动批准方式,但付费资源工具仍由客户端绑定稳定回合身份、限制单回合请求数、串行执行并优先恢复匹配账本;Codex 原生 webSearch、任意原生命令网络、多 Agent 和完整插件能力继续关闭。
- 陶泥儿生成继续复用持久幂等账本、operation 恢复、来源/下载/PNG 解码和 manifest 登记;普通客户端优先使用当前 AGC 登录会话及账号路由,只有受控的 ExternalDeveloper 发布模式才在客户端内部使用按服务器 origin 隔离的私有 Key。用户和模型都不需要提供或配置 API Key;凭据失效、来源不明或结果未知时失败关闭,不能自动换 Key 或重新扣费。
- 自定义 LLM API Key 路由只在 DirectHome/DirectProject 经 loopback `/responses` 流式代理转发。代理不注入 Key,只要求请求自带 Bearer,并剥离开发网关错误携带的 `X-Codex-*` ChatGPT 账户额度头,防止隔离 app-server 把 API Provider 误判为余额 0;旧 ToolHost 保持原 Provider 行为。
@@ -1249,8 +1249,7 @@ game-project/
本文早期关于“DirectProject 关闭通用 shell、原生网络和主动工具”的描述属于迁移前基线,现由以下覆盖规则取代:DirectProject 仅在真实 `game/` cwd 与 `workspaceWrite(writableRoots=[game])` 内恢复 Codex 原生文件/搜索/命令、图片查看和 Skill;其余 ToolHost/DirectHome 合同不变。客户端审核的 `agc_tools` MCP 继续承担平台美术、资源登记、去背景、浏览器试玩和受控搜索,并保留项目锁、幂等账本、下载校验、恢复与投影权威。
DirectProject 使用 `approvalPolicy=never`,避免每次原生调用再经过泛化 ToolHost 包装;原生命令网络保持关闭,联网资料继续走受控 `agc_web_search`。多 Agent、Apps、插件、hooks、Goals、Workspace Dependencies、Tool Suggestion 和原生浏览器/电脑控制仍关闭,避免绕过 AGC durable delegation、浏览器证据和副作用审计;图片生成通过客户端审核的 `agc_tools.agc_generate_image` 暴露普通单图、角色图、视觉规范图和 UI 设计图,完整游戏美术包继续使用 `agc_tools.taonier_prepare_game_art`,两者都复用同一客户端登录态、幂等账本、下载校验和 manifest/revision 投影,不开放 Codex 原生 image tool。app-server 使用隔离 `CODEX_HOME`,明确清空外部 MCP 后只注入 `agc_tools`;配置了 AGC LLM Key 或可解析的 `OPENAI_API_KEY` 登录态时,真实 provider 凭据只由 AGC 本地 provider proxy 持有,Codex 仅使用连接级随机代理令牌;无法安全代理的 OAuth `auth.json` 继续关闭 native shell/unified exec。`agc_tools` 的平台授权由 AGC 客户端当前登录会话和受控后端完成,普通客户端不得把 DirectProject 请求改成外部 API Key 请求;401/403 只投影为客户端登录或权限异常,不向用户索要凭据或暴露内部 URL。shell 子进程采用 `shell_environment_policy` core 继承及 secret/proxy/bridge 排除,provider key 和桥接凭据不得进入命令环境。系统提示词不再预注入项目源码快照或 Skill 正文,Codex 按需读取当前 cwd 文件。
DirectProject 使用 `approvalPolicy=never`,避免每次原生调用再经过泛化 ToolHost 包装;原生命令网络保持关闭,联网资料继续走受控 `agc_web_search`。多 Agent、Apps、完整插件 Runtime、hooks、Goals、Workspace Dependencies、Tool Suggestion 和原生浏览器/电脑控制仍关闭,避免绕过 AGC durable delegation、浏览器证据和副作用审计;图片生成通过客户端审核的 `agc_tools.agc_generate_image` 暴露普通单图、角色图、视觉规范图和 UI 设计图,完整游戏美术包继续使用 `agc_tools.taonier_prepare_game_art`,两者都复用同一客户端登录态、幂等账本、下载校验和 manifest/revision 投影,不开放 Codex 原生 image tool。app-server 使用隔离 `CODEX_HOME`:内置 `agc_tools` 由客户端启动参数注入,用户在客户端扩展列表启用的独立第三方 MCP 以原生配置写入该次隔离 home;全局 Codex MCP、禁用项、Plugin hooks/apps 和其它插件能力不进入 DirectProject。第三方项固定非 required,配置或启动失败只记录该项,不替换 `agc_tools`;provider session token、工具桥地址和受控搜索标记不得通过第三方 MCP 的环境转发字段泄露。配置了 AGC LLM Key 或可解析的 `OPENAI_API_KEY` 登录态时,真实 provider 凭据只由 AGC 本地 provider proxy 持有,Codex 仅使用连接级随机代理令牌;无法安全代理的 OAuth `auth.json` 继续关闭 native shell/unified exec。`agc_tools` 的平台授权由 AGC 客户端当前登录会话和受控后端完成,普通客户端不得把 DirectProject 请求改成外部 API Key 请求;401/403 只投影为客户端登录或权限异常,不向用户索要凭据或暴露内部 URL。shell 子进程采用 `shell_environment_policy` core 继承及 secret/proxy/bridge 排除,provider key 和桥接凭据不得进入命令环境。系统提示词不再预注入项目源码快照或 Skill 正文,Codex 按需读取当前 cwd 文件。
## 2026-08-24 AGC UI 原型桥接与自主 UI workflow
- 2026-08-24 起,`ui-prototype` 与 UI 编辑器的 `UI` JSON 资源明确分离。设计图生成后必须由白名单 `ui.workflow.run` 按页面执行 `prepare → recognize → status → finalize`:为每个功能页面创建并关联 `UI` JSON,载入页面设计图和已登记图片/图标/字体,调用 UI Editor 的 provider-backed 结构识别、多树合并与分批组件绑定,持久化 State/revision,写入 `game/` 应用标记,并把 `reference-ready → structure-ready → merge-ready → binding-ready → application-ready → completed` 各阶段的 `generationKind` 和 manifest revision 投影给客户端。Provider 未配置、请求失败、工具调用缺失、结果不匹配、未知字体引用、未产出可渲染组件或仍有待审节点时保留最近真实阶段并返回 blocker,不得使用 deterministic seed 冒充完成。工作台点击 `ui-prototype` 时通过 `ensure_ui_design_resource_for_prototype` 幂等补齐关联资源;工作流完成后自动打开首个页面的 UI 编辑器 `visual-binding` 最终阶段,交给用户检查和手动调整。UI 编辑器独立的语义建议请求也必须复用统一 LLM 传输选择,`llm.stream=true` 时发送 `stream=true` 并聚合完整工具调用后再校验结果。只生成图片、登记空 JSON 或进入普通图片画布均不构成 UI 工作流完成,详见 [`【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md`](../【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md)。
@@ -0,0 +1,185 @@
# DirectProject 客户端 Skill 自然语言触发能力缺口
状态:待提 Issue,当前仅记录现状和候选方向,未修改代码。
## 1. 问题摘要
AGC 已经可以把用户导入的 Skill 安装到客户端,并在下一次 DirectProject 启动时注入真实 Codex app-server。使用 Codex 原生的 `$skill-name` 形式时,导入的 Skill 可以被读取并执行。
目前缺少的是:用户在普通自然语言中直接提到 Skill 名称时,AGC 没有把这次请求确定性地绑定为 Codex 的 Skill 输入项。结果是模型可能只看到用户提到了一个名称,并把“调用 Skill”误解成调用一个工具,返回“没有可调用接口”,而不是读取 `SKILL.md`。
这不是 Skill 导入失败,也不是需要把 Skill 改造成 MCP 工具;是 AGC 客户端没有复用 Codex 官方客户端的 Skill 输入适配层。
## 2. 当前 AGC 如何使用 Skill
### 2.1 客户端导入
用户在客户端设置的“扩展”页面导入文件、目录或 zip。目录或 zip 中发现的每个 `SKILL.md` 会成为独立的 Skill 扩展项,可以单独启用、禁用、重命名和删除。
已识别的 Skill 导入后默认启用。扩展内容保存于 AGC 客户端扩展仓库,不直接写入用户全局 `CODEX_HOME`。
### 2.2 DirectProject 启动时注入
创建或复用 DirectProject 的 Codex app-server 时,AGC 会:
1. 读取客户端扩展索引中 `enabled=true` 的 Skill;
2. 在本次隔离运行的临时 HOME 下创建客户端 Skill root;
3. 将每个 Skill 的运行时副本复制到该目录;
4. 对手动重命名的 Skill,只在运行时副本的 frontmatter 中使用当前名称;
5. 调用 Codex app-server 的 `skills/extraRoots/set`;
6. 调用 `skills/list` 重新发现 Skill。
AGC 侧的运行时目录准备位于 [`client_extensions.rs`](../../apps/ai-game-creator-shell/src-tauri/src/client_extensions.rs) 的 `prepare_enabled_client_skill_root`,app-server 的 Skill root 注册位于 [`codex_app_server.rs`](../../apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server.rs)。
Skill 配置从下一次 DirectProject 启动生效,当前已经运行的 Codex 会话不热更新。首页的 DirectHome 不作为客户端 Skill 的运行时入口。
### 2.3 当前可用的触发方式
Codex 原生显式触发方式是:
```text
$import-smoke-skill 请只回复一行结果。
```
这个方式已经在 AGC 中验证成功,测试 Skill 返回:
```text
SKILL_IMPORT_OK
```
这证明导入、启用、运行时 Skill root 注入、Codex 发现和 Skill 正文执行链路已经打通。
## 3. 当前缺少的能力
### 3.1 普通自然语言名称没有确定性绑定
以下输入目前不能稳定触发导入的 Skill:
```text
请调用 import-smoke-skill skill。
```
```text
请明确使用 import-smoke-skill。
```
实际结果是模型报告“当前没有可调用该 Skill 的工具接口”。这句话在“Skill 不是工具”这一点上没有错,但没有完成 Skill 指令的读取和应用。
### 3.2 AGC 没有发送结构化 Skill 输入项
Codex 官方 TUI 在识别 `$skill-name` 或用户从 Skill 提及菜单选择后,会向 `turn/start` 输入中追加类似内容:
```json
{
"type": "skill",
"name": "import-smoke-skill",
"path": ".../SKILL.md"
}
```
对应实现见 Codex 仓库中的 `codex-rs/tui/src/chatwidget/input_submission.rs`。随后 Codex core 会根据结构化输入加载 Skill 正文。
AGC 当前的 [`codex_app_server_turn_input`](../../apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server.rs) 只把用户消息整理成普通文本和图片输入,没有追加 `type: "skill"` 项。
### 3.3 “能发现”与“本轮已使用”没有明确的客户端绑定
AGC 启动时会设置 `skills/extraRoots` 并调用 `skills/list`,这只能证明 Skill 在当前 app-server 进程的发现范围内。它不等于本轮已经选中了某个 Skill,也不等于模型一定会读取该 Skill 的正文。
Codex 的 Skill 扩展会把可用 Skill 目录和使用规则放入模型上下文,但普通文本相关性判断主要交给模型;它不是 AGC 客户端已经完成的确定性绑定。
## 4. Codex 源码中的相关分层
### 4.1 模型侧使用规则
Codex 仓库中的 `codex-rs/ext/skills/src/catalog_prompt.rs` 会向模型说明:用户用 `$SkillName` 或普通文本点名 Skill,或者任务符合 Skill 描述时,应使用该 Skill。
这是一条模型行为指令,不是一个保证命中的 `if user_text.contains(...)` 路由器。普通自然语言是否命中,仍取决于模型能否看到对应目录、是否理解名称和描述,以及是否调用 `skills.read`。
### 4.2 显式 Skill 选择
Codex 仓库中的 `codex-rs/ext/skills/src/selection.rs` 会处理结构化 `UserInput::Skill`,也会解析文本中的 `$skill-name`。选中后,core 在回合开始阶段读取并注入 Skill 正文。
### 4.3 “隐式 Skill”不是普通自然语言路由
源码中的 `implicit invocation` 主要用于命令或脚本访问某个 Skill 的资源目录时记录/识别对应 Skill,入口在 Codex 仓库的 `codex-rs/ext/skills/src/invocation.rs`。它不是一个根据任意用户自然语言自动选择 Skill 的通用分类器。
### 4.4 相关性选择实验不是当前确定性注入
Codex 的 `shadow_selection` / `skill_search` 相关实现会对任务和 Skill 描述做词法/相关性排序,但当前是 shadow 观测路径,不直接替当前回合注入 Skill,不能作为 AGC 当前缺口的现成解决方案。
## 5. 复现步骤
准备一个普通的 Skill 导入目录,目录中放置一个 `SKILL.md`。例如:
```markdown
---
name: import-smoke-skill
description: 用于验证客户端导入和加载 Skill 的最小测试 Skill。
---
当用户明确要求使用 `import-smoke-skill` 时,先单独输出一行 `SKILL_IMPORT_OK`,再继续回答用户的问题。
```
该目录和文件可以由 Issue 提交者在自己的测试环境中临时创建,不依赖仓库外的固定目录或本机产物。
复现:
1. 在客户端“扩展”中导入包含上述 `SKILL.md` 的目录;
2. 确认列表显示 `import-smoke-skill`、类型为 Skill、状态为“已启用”;
3. 新开一个 DirectProject 会话;
4. 依次发送:
```text
请调用 import-smoke-skill skill,如果找不到这个skill,不要伪造结果。
```
```text
请明确使用 import-smoke-skill,只回复一行结果。
```
```text
$import-smoke-skill 请只回复一行结果。
```
预期现象:前两条不会稳定加载 Skill,第三条返回 `SKILL_IMPORT_OK`。
## 6. 可能的修复方向
以下只是供 Issue 讨论的候选方向,不在本文锁定具体实现。
### 方向 A:客户端显式绑定用户点名的 Skill
AGC 在发送回合前,根据当前已启用 Skill 列表识别用户明确提到的名称,并把匹配项转换成 Codex 原生的 `type: "skill"` 输入项,同时保留原始用户文本。
优点是行为确定、与官方 TUI 的协议一致;需要讨论名称边界、重名处理和用户文本中普通单词与 Skill 名称的冲突。
### 方向 B:增加 Skill 提及选择入口
在聊天输入框提供 Skill 名称补全或选择入口。用户选择后,客户端保存/发送结构化 Skill 绑定,而不是要求用户手写 `$`。
优点是用户不需要了解 Codex 协议标记;需要额外的前端交互设计,且要决定是否在 DirectProject 聊天区增加入口。
### 方向 C:仅支持 Codex 原生 `$skill-name`
保持当前实现,只把 `$skill-name` 作为 Skill 的正式调用方式,并在测试和使用说明中明确这一点。
优点是改动最小;缺点是用户需要知道 Codex 的 Skill 提及语法,普通中文“请使用某 Skill”仍不会得到确定性支持。
### 方向 D:依赖模型根据 Skill 目录自行判断
让 Skill 目录和描述保持模型可见,由模型在普通任务中自行判断是否需要调用 `skills.read`。
这种方式可以覆盖“任务适合某 Skill”而不仅是精确名称,但结果受模型判断和上下文影响,不适合作为“用户明确点名后必须使用”的唯一保证。
## 7. Issue 建议关注点
提 Issue 时建议先确认产品契约,而不是直接指定实现:
- “用户普通中文提到已启用 Skill 名称”是否必须确定性生效;
- 是否接受用户使用 Codex 原生 `$skill-name`;
- 是否需要聊天输入框提供 Skill 选择/补全;
- Skill 名称与 MCP Server 名称冲突时,客户端按哪类扩展解析;
- 没有找到匹配 Skill 时,是否只给出说明并继续普通对话;
- 是否需要在回合记录或状态 UI 中展示本轮实际注入了哪些 Skill。
本 Issue 不应扩大为:重新设计 Skill/MCP 导入格式、把 Skill 做成 MCP 工具、增加第三方内容安全扫描、增加脚本沙箱,或重做 Codex Plugin Runtime。