接入 DotCraft Unity 编辑器插件
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 6m41s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m8s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 7m16s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 7m38s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m11s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m11s
Project CI / Repository checks (pull_request) Successful in 4m22s
Project CI / Frontend tests (pull_request) Successful in 5m52s
Project CI / Native shell tests (pull_request) Successful in 9m52s
Project CI / Backend tests (pull_request) Successful in 11m3s
Project CI / AI game creator shell web tests (pull_request) Successful in 6m41s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 6m41s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m8s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 7m16s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 7m38s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m11s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m11s
Project CI / Repository checks (pull_request) Successful in 4m22s
Project CI / Frontend tests (pull_request) Successful in 5m52s
Project CI / Native shell tests (pull_request) Successful in 9m52s
Project CI / Backend tests (pull_request) Successful in 11m3s
Project CI / AI game creator shell web tests (pull_request) Successful in 6m41s
新增内置 Unity 插件与自包含 Attach helper,固定上游版本并保留许可证 统一 Runner 执行归属、项目身份校验、回执确认和不确定结果阻断 接入 Unity 工程导入、Agent 工具目录及 Windows 构建分发 补齐插件测试、CI 执行入口和 Windows .NET 10 工具链检查 记录真实 Unity 连接、执行、重载恢复及 Runner 边界验证
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# AGC Unity 编辑器插件接入
|
||||
|
||||
> 文档状态:`current`
|
||||
> 规范关系:承接 AGC 通用插件宿主与编辑器适配主规范
|
||||
|
||||
更新时间:`2026-09-18`
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
将 DotCraft.Unity 0.4.3 对应的 Attach 执行核心接入 AGC 现有插件系统,使当前 Unity 项目能够探测编辑器、建立连接、执行 C# 并获得真实结果。复用既有扩展列表、内置插件开关、权限、审计、EditorAdapter 和 Agent 工具通路。
|
||||
|
||||
首期只支持 Windows x64 的 Unity Mono Editor。连接不修改项目文件、不安装 UPM 包、不启动或关闭用户编辑器。不引入 DotCraft.Harness、另一套 Agent Runtime、MCP 服务或聊天界面;截图、热重载专用工具、macOS、Linux 和 Unity CoreCLR 不属于本次交付。
|
||||
|
||||
## 来源与分发
|
||||
|
||||
源码固定为 `DotHarness/dotcraft-unity` 的 `a65f091c162ebcfde5ec9b399d188fcc57261947`(发布插件 0.4.3 的 provenance)。只吸收 Attach 与必要 Shared 源码,保留 Apache-2.0 许可、第三方声明、来源及本地修改记录;构建产物不提交。Roslyn 版本固定为 5.3.0。Windows helper 自包含分发,用户不需要预装 .NET;构建端需要 .NET 10 SDK 和 x64 C++ 工具链。
|
||||
|
||||
## 入口与行为合同
|
||||
|
||||
- Unity 项目以当前受控根目录中的普通 `ProjectSettings/ProjectVersion.txt`、`Assets/` 和 `Packages/` 识别;复用现有打开项目入口,不创建平行工作台。
|
||||
- 只有当前项目为 Unity、内置插件启用且平台适配器可用时才显示插件并向 Agent 暴露 Unity 工具。禁用或离开 Unity 项目后停止插件实例,执行入口再次检查开关和项目身份。
|
||||
- 探测只读取进程和项目身份。连接必须匹配规范化项目路径、PID、进程启动身份与实际握手;多个候选时失败,不选择任意实例。助手只接受受控项目、操作和代码,不接受任意可执行文件或 payload 路径。
|
||||
- 执行接收 UTF-8 C# 代码,最多 128 KiB,拒绝空值和 NUL。连接及执行有总期限,消息最多 2 MiB,并发执行直接拒绝,不积压写请求。
|
||||
- 成功仅由 Unity 真实执行回执决定;编译或运行错误返回结构化失败与脱敏诊断。主线程同步代码不承诺可硬中止。
|
||||
- 执行发送后超时、连接丢失、回执损坏或上游 unknown/lost 一律返回 `needs-reconciliation`、`retryAllowed=false`,阻断后续执行。停止/重启 JS 插件、断开连接和切换项目不能清除该阻断;用户核对后重启宿主才恢复。发送前参数、项目、平台或缺少 helper 的失败不进入执行不确定状态。
|
||||
- 探测不等于连接;连接不等于执行成功。Domain Reload 后重新验证身份与 generation,不能重放上一条写操作。
|
||||
- 宿主禁止 RPC 覆盖 manifest 声明的 adapter,并校验显式项目路径等于当前受控项目;缺省路径由宿主填充。编辑器路由不允许在全局锁后无界等待。切换项目使旧连接失效,旧请求回执只能归属原请求,不更新新项目连接状态。连接尝试先撤销旧连接,失败保持 disconnected。
|
||||
- GUI 项目切换采用线性化处理:已有插件执行先在受控期限内结束,再切换宿主项目和失效旧连接;切换在后台线程等待,不阻塞 UI 线程。前端项目设置与 cleanup 按顺序送达宿主,旧 cleanup 不能覆盖新项目。
|
||||
- 插件不继承 Provider 凭据。helper 使用受控可执行路径、最小环境、受限消息和超时;任意 C# 在 Unity 权限下执行,宿主 RPC 权限不构成 OS 沙箱。
|
||||
|
||||
## 模块与契约
|
||||
|
||||
插件包放在 `plugins/agc-unity-editor`,使用现有 Agent Plugins manifest 和 `agc.plugin.v1`。JS 入口通过 `host.rpc` 使用编译期注册的 `unity-editor` 适配器。AGC Runner 是 Unity 执行服务的唯一 owner:GUI 适配器复用现有经过鉴权的 Runner RPC 转发,Runtime 和 DirectProject 在同一个长寿命 Runner 中调用原生服务;不创建另一条跨进程 IPC。执行服务调用独立 Attach helper,再由上游本地协议连接 Unity。GUI 项目切换通过同一路径使连接失效;JS 或连接池重建不得重置 owner 内的不确定门闩,恢复要求核对后重启该执行 owner。
|
||||
|
||||
插件命令 `unity.editor.execute`,连接能力 `unity.editor.connection`;Agent Runtime 同名工具与 DirectProject `agc_unity_execute` 共享同一原生服务、项目检查与不确定结果阻断。面向模型的执行参数只有 `code`,项目路径由宿主注入。
|
||||
|
||||
Runner 在执行前保存请求身份,不保存代码或用户路径;GUI 完整验证确定性终态回执后才确认交付。回执丢失、损坏及插件最后一跳失败均保留持久阻断;正常并发或等待确定回执确认返回未派发失败,不误判执行不确定。Runner 自动重启和新增窗口都不清除阻断;用户核对后退出全部 AGC/Runner,再次启动客户端时,只有同时独占既有 GUI 参与锁和 Runner 实例锁才能恢复。启动、派发、读取和确认共享 80 秒客户端总期限,传给 helper 的预算扣除已用启动时间,过期请求不得派发。
|
||||
|
||||
helper 使用一行一条 JSON 请求/响应,请求包含 `id`、`method`、`params`,响应回显 `id` 与 `result` 或结构化 `error`。方法为 `detect`、`connect`、`status`、`execute`、`disconnect`;`projectPath` 始终来自受控宿主,`processId` 为可选探测约束,`timeoutMs` 不超过 60000。执行响应至少有 `ok`、`status`、`retryAllowed`、`result`/`error`,状态为 `completed`、`failed` 或 `needs-reconciliation`。detect/connect/status 结果包含 `adapter`、`connected`、`pid`、`projectPath`、`version`。
|
||||
|
||||
协议名为 `agc.unity.attach.v1`,每条请求均带 `jsonrpc: "2.0"` 和 `protocol`,id 为正整数。helper 是由原生服务持有的单个常驻子进程;Rust 服务在插件与 Runtime 之间共享,执行不确定门闩独立于 helper 生命周期。请求的 `params` 每次包含当前 `projectPath`,无单独 initialize/wait 公开方法;execute 内部完成连接、执行与有界 wait,总 deadline 包含发现、连接与等待,内部不重发 execute。detect 不进行注入。非执行方法的协议错误为 `{code, message}`;execute 的已知未发送失败同样放在结构化 result,只有带完整 `status: failed, ok: false, retryAllowed: false, dispatched: false` 的回执可判为未执行,未知错误不得据此解锁。执行成功含 `dispatched: true`;不确定结果含 `dispatched: true`。连接成功另含 `startedUtc` 与 `generation`,以实际目标身份/握手为准。
|
||||
|
||||
明确收到可信 `failed, ok: false, dispatched: true` 回执表示 Unity 已确定执行失败,不进入不确定门闩;可以由 LLM 修复代码后再执行。`retryAllowed: false` 禁止自动原样重放,不阻止确定性编译或运行错误后的修复。只有完整且匹配请求的终态回执可以支持这一判断。
|
||||
|
||||
首次通过现有打开项目入口导入 Unity 时允许沿用 AGC 的 `.agent` 元数据初始化;不修改 `Assets`、`Packages`、`ProjectSettings` 或 Unity 工程文件。此动作与只读 detect、不改文件 connect 分开。
|
||||
|
||||
不修改服务端 API、SpacetimeDB schema 或现有持久项目数据。新增插件开关沿用既有内置开关存储;不兼容或模拟 DotCraft.Harness 插件 ABI。
|
||||
|
||||
## 验收标准
|
||||
|
||||
| 条款 | 必须取得的证据 |
|
||||
| --- | --- |
|
||||
| 来源与构建 | 固定源码版本、许可、helper 构建和自包含发布检查 |
|
||||
| 插件接入 | manifest/协议测试,发现、启停、开关和项目级工具过滤测试 |
|
||||
| 执行闭环 | helper 与原生适配器定向测试,Agent 参数及结果映射测试 |
|
||||
| 失败边界 | 跨项目、并发、超时、损坏回执、不确定阻断、重启插件不解除阻断测试 |
|
||||
| 分发 | Windows 构建脚本准备 helper,staging 仅包含目标平台运行文件及许可 |
|
||||
| 运行时 | 若有可用 Unity,使用临时测试项目验证连接和无副作用 C# 回执;没有可用编辑器时明确标为未验证,不以 mock 代替实机 |
|
||||
| 仓库门禁 | 定向测试、类型检查、文档索引、编码检查及 git diff --check |
|
||||
|
||||
真实 Unity、安装包及全版本兼容验收与单元测试分别报告。
|
||||
|
||||
## 当前验证范围与复验入口
|
||||
|
||||
- .NET helper 的 27 项定向测试与 Windows x64 自包含发布通过;发布程序在最小环境中完成协议 smoke。
|
||||
- 插件 JS 的参数/消息/并发/项目切换测试通过;Unity/Cocos 打开入口、插件启停投影及开发构建参数的前端定向验证通过。
|
||||
- 原生 helper 进程测试覆盖写入阻塞、EOF、错误 id、超长帧、期限、环境隔离及不确定结果阻断。
|
||||
- 宿主 Unity 定向 8 项、PluginHost 13 项、原生工具目录 16 项和引擎识别 5 项通过;Cocos 10 项、MCP 25 项通过,两组中同一个默认忽略的 Cocos 实机用例未在本任务运行。双 feature 编译检查和调试构建通过。
|
||||
- Unity `6000.3.7f1` 的独立临时工程已完成真实连接、C# 执行、编译错误回传及修复、确定运行错误、临时对象创建/销毁、断开重连验证。项目没有安装 DotCraft UPM 包。
|
||||
- `tests/live_unity.rs` 已显式执行通过,覆盖共享原生服务、编译修复以及 Domain Reload 后重新握手和 generation 更新;它默认 ignored,避免普通测试连接开发者项目。
|
||||
- 新构建的 AGC Runner 使用独立临时配置,完成真实 Unity 执行、ACK、错误 ACK 拒绝、未确认回执的并发拒绝,以及不确定状态跨 Runner 重启保留的验证。
|
||||
- 安装包 UI smoke、其它 Unity 版本及 CoreCLR 不属于上述已验证范围;不能从单一版本实机通过推断全版本兼容。
|
||||
- Gitea 的现有 AGC web 与 Rust crates 门禁分别执行 Cocos/Unity 插件 JS 和原生 crate 测试;Linux CI 不执行 Windows Attach helper 或真实 Unity。Windows Jenkins 构建要求 PATH 可解析 .NET 10 SDK,并由 helper 构建脚本执行 .NET 测试及自包含发布;实机与安装包验收仍单独报告。
|
||||
|
||||
复验命令:
|
||||
|
||||
```powershell
|
||||
powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File plugins/agc-unity-editor/dotnet/build.ps1
|
||||
node --test plugins/agc-unity-editor/src/entry.test.mjs
|
||||
cargo test --locked --manifest-path plugins/agc-unity-editor/native/unity-editor-bridge/Cargo.toml
|
||||
```
|
||||
|
||||
实机复验先自行创建、打开隔离测试工程,核对其 Unity PID,并设置
|
||||
`AGC_UNITY_SMOKE_HELPER`、`AGC_UNITY_SMOKE_PROJECT`、`AGC_UNITY_SMOKE_PID` 后执行:
|
||||
|
||||
```powershell
|
||||
cargo test --locked --manifest-path plugins/agc-unity-editor/native/unity-editor-bridge/Cargo.toml --test live_unity -- --ignored --nocapture
|
||||
```
|
||||
|
||||
该实机用例会触发 Domain Reload,不能指向有未保存工作的用户工程。
|
||||
|
||||
独立评审已核对项目归属、并发拒绝、总期限、ACK 原子归属、最后一跳回执丢失、
|
||||
进程重启阻断及发布许可边界;定向证据与上述真实运行时验证共同覆盖本次接入合同。
|
||||
@@ -4,7 +4,7 @@
|
||||
> 规范关系:AGC 插件与编辑器适配主规范
|
||||
> 验收范围:插件 manifest、宿主生命周期、RPC、Capability/权限审计、UI 挂载和编辑器适配器边界
|
||||
|
||||
更新时间:`2026-09-09`
|
||||
更新时间:`2026-09-18`
|
||||
|
||||
## 目标与边界
|
||||
|
||||
@@ -19,6 +19,7 @@ apps/ai-game-creator-shell/src-tauri/src/editor_adapters.rs
|
||||
packages/agc-plugin-sdk/src/index.ts
|
||||
server-rs/crates/editor-adapter-api/src/lib.rs
|
||||
plugins/agc-cocos-editor/ (第一个编辑器插件包)
|
||||
plugins/agc-unity-editor/ (Unity Mono 编辑器插件包)
|
||||
```
|
||||
|
||||
现有 DirectProject 的 Skill/MCP 导入仍保留。它们是 Codex 扩展注入链路,不等同于本宿主管理的可运行 AGC Plugin。
|
||||
@@ -115,6 +116,13 @@ host.rpc(method, params)
|
||||
|
||||
当前 native 适配器仍由宿主在编译期链接(Cargo path 依赖);动态加载插件 native 模块不在本次范围,插件包格式与宿主协议不受此限制。
|
||||
|
||||
Unity 插件复用此扩展点,GUI 适配器通过已有 Runner RPC 转发到唯一的 Unity 执行
|
||||
服务,避免 GUI、DirectProject 与 Runtime 分别持有连接或执行不确定门闩。
|
||||
宿主 RPC 将目标 adapter 绑定到 manifest,并校验显式项目路径等于当前项目;切换
|
||||
项目使旧连接失效,禁止互斥锁后积压的请求在调用方超时后继续派发。
|
||||
Windows x64 的 Attach helper 来源、构建工具链和执行回执合同见
|
||||
[Unity 插件接入](./【技术方案】AGC Unity编辑器插件接入-2026-09-18.md)。
|
||||
|
||||
## Tauri 命令
|
||||
|
||||
`list_agc_extensions` 返回统一的 Plugin/Skill/MCP catalog;`list_agc_plugins`、`refresh_agc_plugins`、`start_agc_plugin`、`stop_agc_plugin`、`reload_agc_plugin`、`call_agc_plugin` 和 `read_agc_plugin_panel` 提供 Runtime Plugin 管理入口;`set_agc_plugin_project_path` 设置当前项目的受控上下文。编辑器适配器通过宿主 registry 和 Plugin RPC 使用,不增加编辑器专属 Tauri 命令。
|
||||
|
||||
Reference in New Issue
Block a user