实现: 在ui编辑器保存旁增加一个保存并生成代码(js) 生成的是js字符串形式的html, 在整个js前有文档说明 code agent使用js直接注入已经生成的 export的html片段, 每次保存会直接覆盖这些html片段, 依靠动态注入实现编辑器的微调反映到游戏中. 每个节点提供了稳定的id用于code agent在生成html的基础上进行功能实现, 节点增删 目前是作为一个自说明的文件直接让code agent阅读使用, 都是用户调整保存顺便生成, 不提供工具调用. 希望以skill的形式使用 --------- Co-authored-by: 段舒康 <kdletters@qq.com> Co-authored-by: 孔令弘 <ink29535@proton.me> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/237 Co-authored-by: 王德宇 <kvtodev@outlook.com> Co-committed-by: 王德宇 <kvtodev@outlook.com>
6.5 KiB
UI 工作流资源桥接与 Runtime 执行
目标
ui-prototype 与 UI 是两种不同资源,不能通过修改投影 subtype 混为一种资源:
ui-prototype:Agent 生成并登记到画布的界面设计图片。UI:UI 编辑器使用的 JSON 资源,保存界面图、UI 树、组件绑定和 State revision。
自然语言生成链路必须把前者桥接为后者,并持续让 manifest 成为客户端资源投影的权威来源。游戏场景的页面清单由 Runtime 自动发现,Agent 不得凭空猜测页面。
Runtime 工作流
Agent 通过白名单工具 ui.workflow.run 发起工作流。项目路径由 Runtime 注入,模型只能提交资源身份和页面描述,不能传入宿主路径。输入至少包含:
{
"operation": "discover|prepare|recognize|status|finalize",
"sourceAssetId": "ui-prototype manifest asset id",
"pages": [
{
"pageId": "home",
"title": "首页",
"description": "页面用途和交互说明",
"designAssetId": "页面设计图 manifest asset id",
"spriteAssetIds": ["已登记的按钮、图片或图标 manifest asset id"],
"fontAssetIds": ["已登记且可验证的项目字体 manifest asset id"],
"applicationPath": "game/ui_home.gd"
}
]
}
discover 只需要 sourceAssetId,不推进 revision,也不创建资源。Runtime 先读取可选的 game/ui-pages.json 页面注册表;同时扫描设计阶段已生成的 game/game_design.md,以及实现阶段的 game/index.html、game/game.js 和 game/style.css 中的 @genarrative-ui-page {JSON} 声明。声明必须包含稳定的 pageId、标题、描述和 game/ 下的 applicationPath,重复或越界输入直接拒绝。回执会按 pageId 排序返回 requiredDesignAssetPath(约定为 assets/ui-pages/{pageId}.png)和发现来源;design-foundation Agent 为每个页面生成并登记独立 ui-prototype 设计图后,才能继续 prepare。扫描器不会把一张 ui-prototype 图片冒充成多个页面,也不会凭空创建 UI JSON。
处理规则:
prepare为每个页面创建确定性的kind=UIJSON 资源,引用源ui-prototype和页面设计图,载入设计图尺寸与相对路径到ui_design_images,并保存 State。recognize依次执行 Provider 多模态结构识别、现有多树合并器、最多每批 5 项的图片/图标组件绑定,并把已登记字体的安全元数据提供给绑定器;阶段分别持久化为structure-ready、merge-ready、binding-ready,重复执行从最近真实阶段恢复。status只回读 State、页面阶段和 blockers,不推进项目 revision。finalize只接受game/下的真实 UTF-8 文件,写入与 UI State revision 绑定的应用标记;所有页面通过应用门禁后才返回visual-binding最终阶段路由。缺少页面、资源、组件或应用标记时拒绝伪造完成。
每次 State 或 manifest 阶段变化都推进项目 revision。Runtime 回执带有 revisionAdvanceCount,用于并发项目 revision 门禁;manifest 资产的 source.generationKind 依次记录:
UI 编辑器“生成代码”只把导出的 ui/generated-*.js 写入用户项目目录,绝不推进项目 revision,也不改变 UI State revision、manifest 阶段或 Runtime 验证门。生成文件属于派生本地产物;若写入失败,仅返回生成错误,不得通过 revision 变化制造 mutation 证据。
ui-workflow.reference-ready
ui-workflow.structure-ready
ui-workflow.merge-ready
ui-workflow.binding-ready
ui-workflow.application-ready
ui-workflow.completed
最终回执写入 .agent/ui-workflows/<source-hash>.json,客户端可据此恢复页面清单和最终编辑器路由。
recognize 现在直接复用 UI Editor 的 provider-backed recognize_ui_impl、merge_ui_impl 与 bind_components_impl:先对页面设计图执行多模态结构识别,再落盘合并后的唯一页面树,最后按 5 项一批绑定已登记图片/图标,并向模型提供 State 内已验证字体的 ID、family、face、weight 与 style。由 Agent Runtime 调用时,这三个阶段携带当前 agent_id/run_id,统一走活动 Provider 的 mode、请求快照、重试和恢复链路,不再从工作流偷偷创建另一套传统 HTTP client。Codex app-server 会把输入图片暂存到该连接的隔离工作区 input-images/,通过原生 localImage 输入发送;文本提示只保留图片占位符,避免把 base64 复制进提示词或 JSON-RPC。所有 LLM 工具参数仍沿用 UI Editor 的严格 schema、节点/深度/素材和字体白名单及有界输入校验。Provider 未配置、请求失败、工具调用缺失、结果不匹配、未知字体引用、绑定没有可渲染组件或仍有 NeedReview/Blocked 时,完成阶段不会推进;已落盘的中间阶段仍通过 manifest invalidation 更新客户端,不再使用 deterministic seed 冒充语义处理通过。
真实 Provider 鉴权失败时,Codex app-server 可能只返回 codexErrorInfo=other,而把上游 401/403 放在错误正文中。Runtime 必须从受控错误字段识别为 codex-app-server-error:unauthorized(公共摘要为 codex-app-server-unauthorized),只向公共运行记录暴露错误类别和指纹,不记录 Token 或上游原文。此错误不能伪造为 UI 工作流阶段完成;修复凭据后应从原有 run 的恢复边界重新执行。
画布跳转与客户端更新
点击画布中的 ui-prototype 时,工作台调用 ensure_ui_design_resource_for_prototype:
- 按 manifest asset id、
source.resourceId、source.assetObjectId识别已有关联,避免重复创建。 - 没有关联时原子创建
ui/UI 设计 N.json,登记kind=UI、application/json,并把原型图作为首张页面设计图载入 State。 - 成功后通过
onManifestChange更新客户端资源投影,再打开 UI 编辑器;普通桥接从reference-analysis开始。
点击已有 UI 资源直接打开 UI 编辑器。若 manifest 阶段为 ui-workflow.completed,工作台自动打开该资源的 visual-binding 阶段(最远步骤为 2),交给用户做最终检查和手动调整。
诚实完成门禁
ui-prototype 图片登记、UI JSON 创建、页面 State 保存、结构树生成、游戏应用标记和最终路由是不同证据。Agent 只有拿到所有页面的 completed 状态与 finalStageRoute 才能报告完成;只生成图片、只创建空 JSON、只写计划或只打开普通图片画布均不算完成。