diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/ui_design_doc.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/ui_design_doc.rs index 2e7caf72f..646de29d8 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/ui_design_doc.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/ui_design_doc.rs @@ -4,7 +4,7 @@ //! Runtime 注入,模型只给设计图引用与目标文档 assetId。 use super::*; -use crate::ui_editor::design_doc::{ +use crate::ui_editor::agent_tools::{ create_ui_design_doc_from_images, run_ui_design_doc_workflow, CreateUiDesignDocFromImagesInput, RunUiDesignDocWorkflowInput, UiDesignImageReference, }; diff --git a/apps/ai-game-creator-shell/src-tauri/src/main.rs b/apps/ai-game-creator-shell/src-tauri/src/main.rs index e3b42b5cc..fea0af800 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/main.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/main.rs @@ -269,9 +269,9 @@ fn generate_ui_design_code( #[tauri::command] fn create_ui_design_doc_from_images( - input: ui_editor::design_doc::CreateUiDesignDocFromImagesInput, -) -> Result { - ui_editor::design_doc::create_ui_design_doc_from_images(input) + input: ui_editor::agent_tools::CreateUiDesignDocFromImagesInput, +) -> Result { + ui_editor::agent_tools::create_ui_design_doc_from_images(input) } #[derive(Debug, Eq, PartialEq, Serialize)] diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs index 647c22b93..59992eb36 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs @@ -2823,7 +2823,7 @@ fn register_local_asset_keeps_explicit_category_when_kind_is_unchanged() { /// 写侧 → 分类的端到端口径:现役写入侧直接写出的 canonical kind 必须落进明确栏目。 /// /// 这里的字面量与写入侧逐字一致:UI 设计资产是 -/// `ui_editor/design_doc/creation.rs` / `persistence.rs` 的 +/// `ui_editor/agent_tools/creation.rs` / `persistence.rs` 的 /// `register_local_asset_at` 使用 UI 文档 kind/media 常量, /// 字体是 `commands.rs` 字体上传的 `register_local_asset_entry(root, path, "font", ...)`。 #[test] @@ -2898,7 +2898,7 @@ fn register_local_asset_derives_category_from_real_write_side_kinds() { /// /// 编号按已登记的 UI 文档数推导,旧项目里 kind 已被收口为 `unknown` 的文档不再计入, /// 只按计数取名就会撞上仍然存在的同名文件并报「路径已存在」。文档创建入口必须用 -/// `ui_editor::design_doc::next_ui_design_path` 的「第一个空闲编号」规则, +/// `ui_editor::agent_tools::next_ui_design_path` 的「第一个空闲编号」规则, /// 既不改名既有文件也不覆盖。 #[test] fn create_ui_design_doc_from_images_skips_a_taken_ui_design_path() { @@ -2919,11 +2919,11 @@ fn create_ui_design_doc_from_images_skips_a_taken_ui_design_path() { fs::create_dir_all(root.join("assets")).expect("assets dir"); fs::write(root.join("assets/page.png"), bytes).expect("write design image"); - let created = crate::ui_editor::design_doc::create_ui_design_doc_from_images( - crate::ui_editor::design_doc::CreateUiDesignDocFromImagesInput { + let created = crate::ui_editor::agent_tools::create_ui_design_doc_from_images( + crate::ui_editor::agent_tools::CreateUiDesignDocFromImagesInput { project_path: root.to_string_lossy().to_string(), expected_project_id: "project-1".to_string(), - images: vec![crate::ui_editor::design_doc::UiDesignImageReference { + images: vec![crate::ui_editor::agent_tools::UiDesignImageReference { asset_id: None, path: Some("assets/page.png".to_string()), }], diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/checkpoint.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/checkpoint.rs similarity index 100% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/checkpoint.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/checkpoint.rs diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/creation.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/creation.rs similarity index 100% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/creation.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/creation.rs diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/mod.rs similarity index 100% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/mod.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/mod.rs diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/run_workflow.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/run_workflow.rs similarity index 100% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/run_workflow.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/run_workflow.rs diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/mod.rs similarity index 100% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/mod.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/mod.rs diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/recognize.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/recognize.rs similarity index 98% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/recognize.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/recognize.rs index 754a7d567..0b2925366 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/recognize.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/recognize.rs @@ -74,7 +74,7 @@ fn tree_size(state: &State, tree_id: &UIDesignImageId) -> Result<[f32; 2], Strin #[cfg(test)] mod tests { use super::*; - use crate::ui_editor::design_doc::test_support::{node, state_with}; + use crate::ui_editor::agent_tools::test_support::{node, state_with}; use crate::ui_editor::state::UITree; fn dto(trees: &[(&str, &str)]) -> RecognitionDTO { diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/cut_images.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/separate/cut_images.rs similarity index 100% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/cut_images.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/separate/cut_images.rs diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/separate/mod.rs similarity index 98% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/mod.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/separate/mod.rs index bde0c7631..002584a94 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/separate/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/separate/mod.rs @@ -224,8 +224,8 @@ fn format_pixel_size(size: nalgebra::Vector2) -> String { #[cfg(test)] mod tests { use super::*; + use crate::ui_editor::agent_tools::test_support::{image_node, sprite, state_with, tree}; use crate::ui_editor::commands::separation::BoundNode; - use crate::ui_editor::design_doc::test_support::{image_node, sprite, state_with, tree}; use crate::ui_editor::utils::SpriteAssetId; fn sprite_by_path(sprites: &[SpriteAsset]) -> HashMap { @@ -298,7 +298,7 @@ mod tests { let mut state = state_with(&[("page-a", 100.0, 50.0)]); state.ui_trees.push(tree( "page-a", - crate::ui_editor::design_doc::test_support::node("node-b"), + crate::ui_editor::agent_tools::test_support::node("node-b"), )); let errors = apply_separation( &mut state, diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/write_back.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/write_back.rs similarity index 100% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/steps/write_back.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/steps/write_back.rs diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/test_support.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/test_support.rs similarity index 97% rename from apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/test_support.rs rename to apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/test_support.rs index e8a529705..18801327f 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/design_doc/test_support.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/agent_tools/test_support.rs @@ -1,4 +1,4 @@ -//! design_doc 单测共用夹具:只提供最小可用的 State / 节点 / 素材构造。 +//! agent_tools 单测共用夹具:只提供最小可用的 State / 节点 / 素材构造。 use crate::ui_editor::component::image::ImageComponent; use crate::ui_editor::component::Component; diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/mod.rs index 8a76456a6..fa2ccf15a 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/mod.rs @@ -1,6 +1,6 @@ +pub(crate) mod agent_tools; pub mod commands; pub mod component; -pub(crate) mod design_doc; pub(crate) mod html_renderer; pub mod layout; pub mod persistence; diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 373fb830d..394c69845 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -9346,4 +9346,4 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在 - 决策(边界):文档内设计图身份直接采用该图在 manifest 里的 `assetId`,输入给相对路径时先登记再用它的 `assetId`;每次调用都新建文档,不做「原型 → 已存在文档」的幂等查找。切图资源失败不回滚,重放靠 by-path 复用接上;切分 op 内部更细粒度的恢复仍由 `SeparationState` sidecar 承担,日志不复制它的进度。前端 `useUiEditorPage.ts` 的人工链路保留同语义,Rust 只是第二份实现,不把编排搬进 Rust。 - 退役:`ui.workflow.run`、`ui_editor/commands/{merge.rs,binding.rs}`、`ui_editor/workflow.rs`、`ensure_ui_design_resource_for_prototype`、`ui/ui-workflow-.json` 命名与 `ui-workflow.*` manifest 阶段全部删除,不保留迁移、兼容与 fallback。 - 代价与取舍:不接受跨语言 fixture 比对(四个 seam 都是简单变换,靠同语义实现与各自单测覆盖);`run-workflow` 每次调用都推进一轮,调用方重复调用会重新识别而不是被幂等短路(除「保存成功但缺 `write-back` 行」这一种重放)。工具名 `ui-design-doc.*` 含连字符,Function Calling 的函数名归一同时处理 `.` 与 `-`。 -- 验证方式:`cargo test --bin genarrative-ai-game-creator-shell design_doc` 覆盖检查点、识别/切分镜像与切图登记;`ui_design_doc` 与 `native_ui_design_doc_tools` 用例覆盖工具入参和函数名;`npm run check:encoding`、`npm run check:doc-index`、`git diff --check` 通过。整套 Rust 用例在本容器仍有 9 条既有环境性失败(本地 HTTP 资源编辑器与 LLM 超时,改动前同样失败)。 +- 验证方式:`cargo test --bin genarrative-ai-game-creator-shell agent_tools` 覆盖检查点、识别/切分镜像与切图登记;`ui_design_doc` 与 `native_ui_design_doc_tools` 用例覆盖工具入参和函数名;`npm run check:encoding`、`npm run check:doc-index`、`git diff --check` 通过。整套 Rust 用例在本容器仍有 9 条既有环境性失败(本地 HTTP 资源编辑器与 LLM 超时,改动前同样失败)。 diff --git a/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md b/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md index f93394529..eecbc5aca 100644 --- a/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md +++ b/docs/technical/【技术方案】UI编辑器Agent工具化重写-2026-09-23.md @@ -65,7 +65,7 @@ ### Rust ```text -src/ui_editor/design_doc/ +src/ui_editor/agent_tools/ ├─ mod.rs 模块声明与三个工具的对外导出 ├─ creation.rs from-images:登记图片、建文档、manifest 注册、命名取号 ├─ checkpoint.rs JSONL 追加、读取、轮次判定 @@ -77,7 +77,7 @@ src/ui_editor/design_doc/ │ │ ├─ mod.rs 切分 DTO 落 State(回填、清状态、写 NeedReview) │ │ └─ cut_images.rs 切图图片登记与 SpriteAsset 构造 │ └─ write_back.rs 保存 State、记 write-back / outdated 行、漂移文案 -└─ test_support.rs design_doc 单测共用夹具 +└─ test_support.rs agent_tools 单测共用夹具 src/agent/runtime_tools/ui_design_doc.rs 工具参数解析与 Runtime 侧调用 ``` @@ -100,7 +100,7 @@ src/agent/runtime_tools/ui_design_doc.rs 工具参数解析与 Runtime 侧调 2. 术语与 ADR:`CONTEXT.md` 四个词条、检查点 ADR。 3. 本文档。 4. 提示词目录模块 + 两个无状态工具(`from-images`、`into-js`)。 -5. `run-workflow` 与 JSONL 检查点(`design_doc/{checkpoint,run_workflow}.rs` + `steps/separate/`)。 +5. `run-workflow` 与 JSONL 检查点(`agent_tools/{checkpoint,run_workflow}.rs` + `steps/separate/`)。 6. 前端收口:删 `uiDesignResourceBridge` 的 `ui-workflow.*` 优先级与 `project-development` 的自动打开分支。 7. 三个工具注册进 Runtime(`agent_native_tools`、`runtime_tools/ui_design_doc.rs`、可执行工具目录、并行账本映射、design-foundation 白名单)。 diff --git a/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md b/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md index 81e4399eb..03906c91d 100644 --- a/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md +++ b/docs/technical/【技术方案】UI编辑器代码地图与模块职责-2026-09-23.md @@ -27,7 +27,7 @@ view/ui-editor (页面/组件) | `component/` | 组件枚举 `Component::{Image, Text}`、`NodeComponent`(LLM 工具载荷的 `PureNode`/`WithComponent` 判别式) | | `resource/` | 界面图(`path` / `pixel_size` / `pixels_per_unit`)、sprite(含 `SpriteBorder` 九宫格)、字体(格式/媒体类型/CSS format)资源描述 | | `persistence.rs` | 文档读写、`revision` 乐观并发保存、领域校验(重复 ID、树/资源引用、组件状态)、代码生成写盘 | -| `design_doc/` | Agent 工具链路:`creation.rs` 用一至四张设计图新建文档(登记未登记图片、按 `ui/UI 设计 N.json` 取号、持项目写锁装 revision 0、失败回滚)、`checkpoint.rs` JSONL 检查点日志、`run_workflow.rs` 三步编排与崩溃恢复、`steps/` 逐步落 State(`mod.rs` 用已记录 DTO 重放目标 State、`recognize.rs` 识别、`separate/` 切分:`cut_images.rs` 登记切图与 `SpriteAsset` 构造、`mod.rs` 回填与问题状态、`write_back.rs` 保存与漂移文案) | +| `agent_tools/` | Agent 工具链路:`creation.rs` 用一至四张设计图新建文档(登记未登记图片、按 `ui/UI 设计 N.json` 取号、持项目写锁装 revision 0、失败回滚)、`checkpoint.rs` JSONL 检查点日志、`run_workflow.rs` 三步编排与崩溃恢复、`steps/` 逐步落 State(`mod.rs` 用已记录 DTO 重放目标 State、`recognize.rs` 识别、`separate/` 切分:`cut_images.rs` 登记切图与 `SpriteAsset` 构造、`mod.rs` 回填与问题状态、`write_back.rs` 保存与漂移文案) | | `html_renderer/` | 由 State 生成 HTML 片段与 JS(maud + 布局/组件 CSS 映射),供预览与 `ui/generated-*.js` | | `commands/` | LLM 工具链:`recognition`(结构识别)、`separation/`(自动切分素材)、`utils.rs`(LLM 请求、重试、`required_tool_arguments`) | | `commands/separation/` | 切分批处理、截图/预切、sidecar 恢复(inspect / finalize / discard)、patch 回写 |