扩展客户端 MCP 能力与 Skill 资源
保留客户端对话链并扩展 AGC 工具 MCP 白名单 增加审核 Skill 索引与正文资源读取 补充 Codex 返回旁路记录及幂等安全校验 同步更新 AGC、DirectProject 与审计边界文档
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -242,6 +242,27 @@ pub(crate) fn render_agc_skill_pack_index() -> Result<String, String> {
|
||||
Ok(lines.join("\n"))
|
||||
}
|
||||
|
||||
pub(crate) fn read_agc_skill_resource(resource: &str) -> Result<String, String> {
|
||||
let manifest = validated_skill_pack_manifest()?;
|
||||
let normalized = resource.trim().trim_start_matches('/').replace('\\', "/");
|
||||
let (skill_name, relative) = normalized
|
||||
.split_once('/')
|
||||
.ok_or_else(|| "Skill 资源路径必须是 skill/file".to_string())?;
|
||||
let entry = manifest
|
||||
.skills
|
||||
.iter()
|
||||
.find(|entry| entry.name == skill_name)
|
||||
.ok_or_else(|| "未登记的 AGC Skill 资源".to_string())?;
|
||||
if !entry.files.iter().any(|file| file == relative) || !is_safe_skill_relative_path(relative) {
|
||||
return Err("未登记或不安全的 AGC Skill 资源".to_string());
|
||||
}
|
||||
let bundled_path = format!("{skill_name}/{relative}");
|
||||
let bytes =
|
||||
bundled_skill_file(&bundled_path).ok_or_else(|| "AGC Skill 资源不存在".to_string())?;
|
||||
let canonical = canonical_skill_text_bytes(&bundled_path, bytes)?;
|
||||
String::from_utf8(canonical.into_owned()).map_err(|_| "AGC Skill 资源不是 UTF-8".to_string())
|
||||
}
|
||||
|
||||
pub(crate) fn install_agc_skill_pack(isolated_os_home: &Path) -> Result<String, String> {
|
||||
let manifest = validated_skill_pack_manifest()?;
|
||||
let skills_root = isolated_os_home.join(".agents").join("skills");
|
||||
|
||||
@@ -7959,3 +7959,12 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- UI 编辑器导出的 `ui/generated-*.js` 是派生本地产物。代码生成只写文件,绝不推进项目 revision、UI State revision、manifest 阶段或 Runtime 验证门;写入失败只返回生成错误,不能把生成文件写入冒充项目 mutation。
|
||||
- 生成文件名保留可读清洗前缀,并追加 asset ID 的 SHA-256 摘要前缀以避免不同 ID 碰撞;不迁移既有旧路径,调用方需在采用新命名后使用新返回路径。
|
||||
- Radial90 的前端预览与 Rust 导出统一使用角点映射和顺时针起始角规则,顺时针填充从角点前一条边开始,避免两端渲染偏移。
|
||||
|
||||
## 2026-09-03 AGC 客户端能力以 MCP 暴露
|
||||
|
||||
- 背景:客户端仍启动并驱动自己的 Codex 对话;同时需要把客户端自身的受控业务能力以 MCP 暴露给 Codex。客户端不应替 Codex 做业务语义门禁、意图判断或完成判定。
|
||||
- 决策:MCP 作为客户端能力层外挂,GUI 主进程提供 loopback MCP,stdio broker 只做协议转发;会话绑定 `accountId + projectId + clientInstanceId + sessionId`,项目切换、登出、重启、断开或令牌轮换失效。客户端保留现有对话/UI 和 `codex_app_server` 链路,仅暴露稳定业务工具白名单,不透传全部 Tauri command、任意路径、凭据、内部 URL、shell、数据库或管理能力。
|
||||
- 返回记录:客户端对话继续走现有 conversation projection;外部 Host 如需旁路归档,才调用 `conversation.record_codex_response` 写入有界、脱敏 journal。该记录不是客户端对话前置条件,UI 不从文本推断完成、规划、同步或其它副作用。
|
||||
- 迁移与兼容:`codex_app_server`、`codex_cli`、`provider`、既有 Agent Runtime 和客户端对话均保留;MCP 仅新增能力暴露,不替换现有 Codex 控制链。公网 `/api/external/v1/mcp` 与桌面 MCP facade 保持独立。
|
||||
- 影响范围:AGC 客户端 MCP facade、loopback/stdio 传输、DirectProject 会话绑定、Codex 返回 journal、前端对话数据源、运行模式与恢复/幂等测试;不新增 SpacetimeDB 表,不改变公网 External MCP 合同。
|
||||
- 验证方式:覆盖客户端对话驱动的 MCP 初始化/绑定/失效、跨项目与路径安全、工具大小和幂等、异步 operation 恢复、Skill resource 白名单以及旧 Provider/Codex 模式回归;执行对应 Rust/前端定向测试、MCP contract smoke、typecheck、`npm run check:encoding` 与 `git diff --check`。
|
||||
|
||||
@@ -233,6 +233,13 @@ Supervisor 认领该回执后,由父 run 自己为每个原 delivery 逐一创
|
||||
- 旧配置迁移:既有 AppData 若没有 `agentMode`,只有全局和逐 Agent 路由均为 `openai_responses` 时迁移到 `codex_app_server`;存在 `openai_chat / anthropic` 时显式保留 `provider`,避免打开项目自动恢复时把所有节点批量写成 `invalid-config`。用户确认端点支持 Responses 后,可在设置中显式切换并保留原 model/base URL/API Key。
|
||||
- 验收:fake JSON-RPC fixture、三态 UI/config、配置指纹、unknown-terminal 零重放、旧两种模式回归和显式 ignored 真实 smoke 全部通过后,才可视为模式切换完成。
|
||||
|
||||
### 2026-09-03 AGC 客户端能力以 MCP 暴露
|
||||
|
||||
- MCP 暴露是客户端能力层,不替换 `codex_app_server / codex_cli / provider` 或客户端对话。Codex 仍可由客户端对话入口驱动,同时其它 Codex Host 也可连接 loopback MCP facade/stdio broker;客户端不再替 Codex 做业务语义门禁、意图判断和完成判定。
|
||||
- MCP 会话在客户端握手时绑定当前账号、项目和实例,工具参数不得携带 `projectPath`、Token、Cookie、objectKey 或内部 URL。仅暴露稳定业务白名单与 `resources/list/read`,所有文件、资源、画布、预览和 operation 副作用继续复用客户端权限、锁、计费、幂等账本、manifest/revision 与恢复机制。
|
||||
- 客户端对话继续写入现有 conversation projection;外部 Host 如需旁路保存返回文本,可显式调用 `conversation.record_codex_response`。客户端将有界、脱敏正文、SHA-256、安全摘要和状态追加到项目级 journal,UI 只展示记录,不从文本推断业务状态或触发副作用。
|
||||
- loopback MCP 在账号登出、会话代际变化、项目切换、客户端退出或令牌轮换后立即失效;未知副作用保持 `needs-reconciliation`,只能通过 operation 查询恢复。稳定验收覆盖客户端对话驱动的 MCP 工具调用、Skill 指导资源、跨项目/账号拒绝以及旧 Provider/Codex 回归。
|
||||
|
||||
### 2026-08-10 Supervisor 边做边聊与条件中断
|
||||
|
||||
- 根 Project Supervisor 的运行中消息继续进入当前 `taskId / sessionId / runId`,先持久显示“正在判断、当前任务继续”,再由独立 LLM 生成非终态语义回复并给出 `interruptCurrentProvider`。过程回复不能调用终态 `respond_to_user`,不能把制作 Run、Goal 或 task 提前完成。
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
## 3. 已确定的产品边界
|
||||
|
||||
### 3.0 客户端能力 MCP 暴露边界(2026-09-03)
|
||||
|
||||
客户端仍由现有对话入口启动并驱动 Codex;MCP 只是把客户端已审核的项目、文件、资源、画布、生成和预览能力暴露给该 Codex 或其它 Host。客户端只负责账号、项目路径、权限、计费、幂等、锁和恢复等自身安全,不替 Codex 做高层意图/完成门禁。审核 Skill 的索引和正文可作为只读 MCP resource 提供,第三方扩展不得获得客户端会话凭据、内部路径或 bridge token;该能力与公网 `/api/external/v1/mcp` 保持独立。
|
||||
|
||||
### 3.1 客户端安装、运行时注入
|
||||
|
||||
- 扩展内容保存在 AGC 客户端的扩展仓库。
|
||||
|
||||
@@ -89,6 +89,10 @@ Codex app-server 协议里,`commandExecution.commandActions` 已分类为 `Rea
|
||||
|
||||
不升级 `GAME_CREATOR_AGENT_DB_SCHEMA_VERSION`;新 `recordType` 走 Ordinary 追加。`updatedAt` / `schemaVersion` 仍由 `serialize_agent_db_record` 写入。
|
||||
|
||||
### 2026-09-03 客户端对话与 MCP 能力边界
|
||||
|
||||
客户端对话仍由现有 Codex app-server 链路完成;MCP 只暴露客户端自身业务能力和审核 Skill 指导。客户端安全门禁限于账号、项目路径、权限、计费、幂等、锁、revision 与恢复,不根据 Codex 自然语言替代 Codex 决定业务动作。外部 Host 返回如需旁路归档,可使用显式记录工具,但不替代现有 conversation projection,也不触发资源、状态或完成判定。
|
||||
|
||||
jsonl 每条自带 `recordedAtMs`(`unix_millis`)。同一 `clientTurnId` 若再次进入(当前 GUI 运行中互斥,结束后理论上可再来):只追加,不截断;后一次 `turn_start` 视为新 attempt。读摘要时按文件内最后一次 `turn_start` 到对应 `turn_end` 计算 `offeredRead`。`agent.db` 每次 `turn_end` 再追加一条摘要,分析取该 `clientTurnId` 最后一条。
|
||||
|
||||
## 5. 记录合同
|
||||
@@ -291,7 +295,7 @@ chat_with_game_creator_direct_codex
|
||||
|
||||
`direct_game_creator_codex_chat_at_with_optional_observer` 增加可选 `audit: Option<&mut DirectCodexTurnAudit>`,再传到 `run_turn_with_direct_observer`。仅 `workspace_mode == DirectProject` 且 `audit` 为 Some 时抽取。
|
||||
|
||||
`run_direct_game_creator_turn_inner` 的 UI observer 保持只处理 `AccumulatedText` / `Activity`。
|
||||
`run_direct_game_creator_turn_inner` 的 UI observer 把 `AccumulatedText`(仅开启流式时)映射为 `streaming`,`IntermediateText` 与 `Activity` 一律映射为 `running`,只向前端暴露安全活动词与可见正文,不携带原始 item JSON。
|
||||
|
||||
回合失败(生成失败、浏览器试玩失败、回复落盘失败):只要 `start` 过就 `finish(false)`,保留已观察到的 item。Codex 尚未启动则 `itemCount=0`。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user