Image editor: hide raw Prompt, use Resolution

Remove backend-assembled raw Prompt and copy action from image info; render a lightweight generationInputs snapshot (user panel inputs + reference thumbnails) stored on canvas layers and shown in the image info dialog. Unify canvas display and info to use originalWidth/originalHeight (Resolution) instead of saved Size and hydrate legacy layout width/height only as fallback. Add model/aspectRatio/imageSize options for character/icon generation (frontend state, tests, and client payloads). Increase Axum JSON body limit for character animation endpoint to 12MB for compatibility and prefer submitting persisted objectKey over large Data URLs. Update tests, docs, and related server/frontend code to reflect these behaviors and validations.
This commit is contained in:
2026-06-16 17:06:21 +08:00
parent 7eeff10c67
commit 3a3cc89280
14 changed files with 1041 additions and 135 deletions

View File

@@ -0,0 +1,146 @@
# Editor Image Model Options Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 让图片画布的“生成角色形象”和“生成图标素材”支持 `nanobanana2``gpt-image-2`,并按模型提供合法的尺寸比例与大小尺寸选项。
**Architecture:** 前端抽出编辑器图片模型配置,生成面板只保存模型、比例、大小三个轻量状态;后端集中归一模型和尺寸组合,角色图与图标 spritesheet 继续走现有 VectorEngine、去背、OSS 和拆分链路。用户模型偏好用 localStorage 记住,默认 `nanobanana2`
**Tech Stack:** React + TypeScript + VitestRust Axum api-serverplatform-image VectorEngine providerMarkdown 项目文档。
---
## File Structure
- Modify `C:\Genarrative\src\services\image-editor\editorProjectClient.ts`
- 扩展图片生成和图标 spritesheet 请求类型,加入 `aspectRatio``imageSize`
- 默认图标模型改为 `gemini-3.1-flash-image-preview` 对应的 `nanobanana2`
- Modify `C:\Genarrative\src\services\image-editor\editorProjectClient.test.ts`
- 先补失败测试:角色 / 图标请求会带模型、比例、大小。
- Modify `C:\Genarrative\src\components\image-editor\ImageCanvasEditorView.tsx`
- 增加模型配置、选项归一、localStorage 偏好、角色 / 图标面板字段和提交 payload。
- Modify `C:\Genarrative\src\components\image-editor\ImageCanvasEditorView.test.tsx`
- 先补失败测试:默认显示 nanobanana2切换模型后比例 / 大小选项变更,并在请求中传递。
- Modify `C:\Genarrative\server-rs\crates\platform-image\src\vector_engine\request.rs`
-`512` 不被 normalize 成非法尺寸,并保留 gpt-image-2 尺寸。
- Modify `C:\Genarrative\server-rs\crates\platform-image\tests\vector_engine.rs`
- 先补失败测试nanobanana2 0.5K 请求 body 保留 `512`
- Modify `C:\Genarrative\server-rs\crates\api-server\src\editor_project.rs`
- 扩展请求 DTO集中校验 `nanobanana2 / gpt-image-2` 与尺寸组合。
- 角色生成按模型走 with_model 调用;图标生成按模型和组合选择尺寸。
- Modify docs:
- `C:\Genarrative\docs\【编辑器】画板角色形象生成入口设计-2026-06-15.md`
- `C:\Genarrative\docs\【编辑器】画板图标素材生成入口设计-2026-06-15.md`
- `C:\Genarrative\docs\technical\【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`
---
### Task 1: Client request contract
**Files:**
- Modify: `C:\Genarrative\src\services\image-editor\editorProjectClient.ts`
- Test: `C:\Genarrative\src\services\image-editor\editorProjectClient.test.ts`
- [ ] **Step 1: Write failing tests**
Add tests asserting `generateEditorImage` and `generateEditorIconSpritesheet` serialize `model`, `aspectRatio`, and `imageSize` when supplied.
- [ ] **Step 2: Run test to verify failure**
Run: `npm run test -- src/services/image-editor/editorProjectClient.test.ts -t "image model options"`
Expected: FAIL because payloads do not include `aspectRatio` / `imageSize`.
- [ ] **Step 3: Minimal implementation**
Extend input types and JSON body builders to include optional `aspectRatio` and `imageSize`; change icon default model constant to `gemini-3.1-flash-image-preview` if not already.
- [ ] **Step 4: Verify green**
Run same test command. Expected: PASS.
### Task 2: Frontend panel state and local preference
**Files:**
- Modify: `C:\Genarrative\src\components\image-editor\ImageCanvasEditorView.tsx`
- Test: `C:\Genarrative\src\components\image-editor\ImageCanvasEditorView.test.tsx`
- [ ] **Step 1: Write failing tests**
Add tests for:
1. opening `生成角色形象` defaults to model `nanobanana2` and shows `尺寸比例` / `大小尺寸`;
2. switching to `gpt-image-2` limits visible combinations and submits model + mapped size metadata;
3. icon spritesheet defaults to `nanobanana2` and submits the chosen model.
- [ ] **Step 2: Run test to verify failure**
Run: `npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx -t "模型|尺寸比例|大小尺寸"`
Expected: FAIL because current UI has placeholder model button only.
- [ ] **Step 3: Minimal implementation**
Add model option config, dialog fields `imageModel/aspectRatio/imageSize`, localStorage helpers, option buttons/selects, and submit payload wiring.
- [ ] **Step 4: Verify green**
Run same test command. Expected: PASS.
### Task 3: Backend model and dimension normalization
**Files:**
- Modify: `C:\Genarrative\server-rs\crates\platform-image\src\vector_engine\request.rs`
- Modify: `C:\Genarrative\server-rs\crates\api-server\src\editor_project.rs`
- Test: `C:\Genarrative\server-rs\crates\platform-image\tests\vector_engine.rs`
- Test: existing unit tests inside `editor_project.rs`
- [ ] **Step 1: Write failing tests**
Add tests covering:
1. `build_vector_engine_image_request_body_with_model("gemini-3.1-flash-image-preview", ..., "512", ...)` keeps `size = "512"`.
2. editor character model normalization defaults to nanobanana2 and maps `gpt-image-2 + 2:3 + 1K` to `1024x1536`.
3. icon spritesheet model normalization accepts both models.
- [ ] **Step 2: Run backend tests to verify failure**
Run:
`cargo test -p platform-image --manifest-path server-rs/Cargo.toml vector_engine_request_body_can_use_nanobanana2_half_k -- --nocapture`
`cargo test -p api-server --manifest-path server-rs/Cargo.toml editor_project -- --nocapture`
Expected: FAIL until normalization functions exist.
- [ ] **Step 3: Minimal implementation**
Add constants and helpers:
- `EDITOR_IMAGE_MODEL_NANOBANANA2 = "gemini-3.1-flash-image-preview"`
- `EDITOR_IMAGE_MODEL_GPT_IMAGE_2 = "gpt-image-2"`
- `normalize_editor_image_model`
- `normalize_editor_generation_dimensions`
Use with_model calls for character and icon generation responses.
- [ ] **Step 4: Verify green**
Run the same backend tests. Expected: PASS.
### Task 4: Documentation and final checks
**Files:**
- Modify docs listed above.
- [ ] **Step 1: Update docs**
Document defaults, user preference, model-specific options, and Apifox source URLs.
- [ ] **Step 2: Run focused verification**
Run:
`npm run test -- src/services/image-editor/editorProjectClient.test.ts src/components/image-editor/ImageCanvasEditorView.test.tsx`
`cargo test -p platform-image --manifest-path server-rs/Cargo.toml vector_engine_request_body_can_use_nanobanana2_half_k -- --nocapture`
`cargo test -p api-server --manifest-path server-rs/Cargo.toml editor_project -- --nocapture`
`npm run typecheck -- --pretty false`
`npm run check:encoding`
---
## Self-Review
- Spec coverage: covers role generation, icon spritesheet generation, default model, user preference, model-specific dimensions, docs.
- Placeholder scan: no unresolved placeholders.
- Type consistency: frontend uses `model/aspectRatio/imageSize`; backend DTO mirrors camelCase fields.

View File

@@ -0,0 +1,84 @@
# 图片信息生成输入快照 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 图片画布编辑器的图片信息页删除生图 Prompt 字段,改为展示图片生成时的面板输入快照,包括文本字段和参考图。
**Architecture:**`CanvasLayer` 上新增轻量 `generationInputs` 前端快照,只保存用户可见输入和参考图摘要;生成成功时从对应面板状态构建快照,随画布 layout JSON 持久化。图片信息弹窗只读取该快照渲染,不回退显示后端组装 Prompt。
**Tech Stack:** React + TypeScript + Vitest + Testing Library现有 `UnifiedModal`、平台按钮和图片画布 layout snapshot。
---
### Task 1: 信息弹窗行为测试
**Files:**
- Test: `C:/Genarrative/src/components/image-editor/ImageCanvasEditorView.test.tsx`
- [ ] **Step 1: Write the failing tests**
- 修改已有图片信息测试,断言弹窗不出现 `Prompt``复制Prompt`
- 新增普通生成图片测试:生成后打开信息页,应显示 `生成输入``生成提示词` 和用户输入值。
- 新增角色生成图片测试:绑定角色规范参考图后生成,信息页应显示 `角色设定``角色形象规范` 与参考图名称。
- 新增图标素材生成测试:绑定图标素材规范后生成,信息页应显示 `素材描述`、具体描述和 `图标素材规范` 参考图。
- [ ] **Step 2: Run test to verify it fails**
- Run: `npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx`
- Expected: FAIL because `generationInputs` is not yet implemented and old `Prompt` field still exists.
### Task 2: 生成输入快照模型与持久化
**Files:**
- Modify: `C:/Genarrative/src/components/image-editor/ImageCanvasEditorView.tsx`
- [ ] **Step 1: Add minimal types**
- Add `CanvasGenerationInputField`, `CanvasGenerationInputReference`, `CanvasGenerationInputs`.
- Add optional `generationInputs` to `CanvasLayer`.
- [ ] **Step 2: Serialize and hydrate**
- Include `generationInputs` in `serializeLayer`.
- Hydrate only trusted shapes: string `title`, string `value`, string `label`, string `src`.
### Task 3: Build snapshots when creating generated layers
**Files:**
- Modify: `C:/Genarrative/src/components/image-editor/ImageCanvasEditorView.tsx`
- [ ] **Step 1: Add builders**
- `buildGenerationInputsForImagePrompt(prompt)`.
- `buildGenerationInputsForSpec(specType, specValues)`.
- `buildGenerationInputsForCharacter(prompt, specRef, references)`.
- `buildGenerationInputsForIcon(iconDescriptions, iconSpecRef)`.
- `buildGenerationInputsForEdit(prompt, sourceLayer)`.
- [ ] **Step 2: Attach snapshots**
- Pass `generationInputs` into `addGeneratedResultLayer`, `addQuickEditResultLayer`, and `addIconSpritesheetResultLayers`.
- Keep old `prompt/actualPrompt` for backend metadata and backward compatibility, but do not render them in UI.
### Task 4: Render image info without生图 Prompt
**Files:**
- Modify: `C:/Genarrative/src/components/image-editor/ImageCanvasEditorView.tsx`
- Modify: `C:/Genarrative/src/index.css` if existing metadata styles need a reference grid helper.
- [ ] **Step 1: Replace Prompt row**
- Remove `Prompt` dt/dd and `复制Prompt` button.
- Render `生成输入` row.
- [ ] **Step 2: Render fields and references**
- If `generationInputs` has fields, render each field title/value.
- If it has references, render thumbnail cards with title and image.
- If both empty or absent, render `-`.
### Task 5: Documentation and verification
**Files:**
- Modify: `C:/Genarrative/docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`
- [ ] **Step 1: Update documentation**
- Add note: image info displays panel input snapshot and references, never assembled generation Prompt.
- [ ] **Step 2: Run verification**
- Run: `npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx`
- Run: `npm run typecheck`
- Run: `npm run check:encoding`
- Run: `git diff --check`