From 46c8573b0e4ca5ccbb0efa34ee74ab3d5f765f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 22 Sep 2026 11:47:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=89=8D=E7=AB=AF=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E6=A8=A1=E5=9E=8B=E6=B5=8B=E8=AF=95=E5=88=B0=20GPT=20?= =?UTF-8?q?Image=202.5=20=E9=87=8D=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 6 个 image-editor 测试文件的旧 gpt-image-2 断言改为 gpt-image-2.5 / GPT Image 2.5,覆盖图集导出、元数据弹窗、UI 素材提取模型菜单与生成/快速编辑 dialog 参数快照 - 工作流测试夹具与提取模型按钮改用 IMAGE_MODEL_GPT_IMAGE_2_5 常量,legacy 夹具保留并断言提交边界归一为当前业务模型 - decision-log 2026-09-21 条目补 platform-image 与前端全量测试验证结论 --- .../shared-memory/decision-log.md | 2 +- ...CanvasEditorGenerationIntegration.test.tsx | 8 +++--- .../ImageCanvasEditorView.test.tsx | 2 +- .../ImageCanvasExportModel.test.ts | 4 +-- .../ImageCanvasMetadataModalView.test.tsx | 4 +-- ...anvasUiAssetExtractionOverlayView.test.tsx | 10 ++++---- .../useImageCanvasGenerationWorkflow.test.tsx | 25 ++++++++++--------- 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 3be5f125f..1b4d7b8a9 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -7,7 +7,7 @@ - 边界:nanobanana 生成与编辑共用一个 concrete model,参考图不改变档位;不引入跨模型 fallback;历史持久化值与审计字符串不改写。 - 同批修复:`raw_image_edit` 发送前复用共享 `ensure_provider_matches_model` 白名单校验;`platform-image` 兜底 task id 前缀改为跟随实际 provider(`tiantoken-edit` / `tiantoken-nanobanana` 不再带 `vector-engine` 前缀);`resolve_image_provider` 增加 `gpt-image-2 → Tiantoken` 断言把历史值意图钉死;删除 `openai_image_generation.rs` 中仅测试使用的 `create_openai_image_edit` / `create_openai_image_edit_with_references`(测试改用 `..._and_model` 变体,保留空参考图本地校验覆盖);`normalize_editor_generation_options` 的具体 provider key 改用常量;External v1 OpenAPI 的 `model` 描述改为与实现一致(`kind=ui-design` / `publication-material` 固定 `gpt-image-2.5`,UI 素材提取未传默认 nanobanana)。 - 影响范围:`api-server`(`editor_generation_config`、`editor_project`、`editor_project_icon`、`character_visual_assets`、`editor_agent/tool`、`openai_image_generation`)、`platform-image`(`raw_image_edit`、`runtime/executor`、集成测试)、ADR、里程碑文档、External v1 OpenAPI 描述、`.codex/skills/gpt-image-2-apimart` 脚本与 SKILL.md(改用 `TIANTOKEN_*` 凭据 + concrete model)。 -- 验证:`cargo test -p api-server editor_generation_config`、`cargo test -p api-server editor_agent::tool`、`cargo test -p api-server`(1123 passed / 1 failed,失败项为 mock LLM 连接超时,单测隔离重跑通过)。 +- 验证:`cargo test -p api-server editor_generation_config`、`cargo test -p api-server editor_agent::tool`、`cargo test -p api-server`(1123 passed / 1 failed,失败项为 mock LLM 连接超时,单测隔离重跑通过);`cargo test -p platform-image`(22 + 64 + 14 passed);`npx vitest run` 全量 382 files / 4619 passed(6 个测试文件的旧 `gpt-image-2` 断言与 mock 请求体读取竞态同步修正);`npm run typecheck`、`npm run check:encoding`、`git diff --check` 通过。 - 关联文档:[`docs/adr/【ADR】GPT Image 2.5模型路由与历史值兼容-2026-09-18.md`](../../adr/【ADR】GPT%20Image%202.5模型路由与历史值兼容-2026-09-18.md)、[`docs/project-memory/plans/【里程碑】GPT Image 2.5 provider边界重构-2026-09-18.md`](../plans/【里程碑】GPT%20Image%202.5%20provider边界重构-2026-09-18.md)。 ## 2026-09-21 图片 provider 白名单收紧,并整体删除 gpt-image-2-c diff --git a/src/components/image-editor/ImageCanvasEditorGenerationIntegration.test.tsx b/src/components/image-editor/ImageCanvasEditorGenerationIntegration.test.tsx index 8f5033b45..7f9aee873 100644 --- a/src/components/image-editor/ImageCanvasEditorGenerationIntegration.test.tsx +++ b/src/components/image-editor/ImageCanvasEditorGenerationIntegration.test.tsx @@ -1527,7 +1527,7 @@ describe('ImageCanvasEditorView generation integration', () => { expect(generateEditorImageMock).toHaveBeenCalledWith( expect.objectContaining({ kind: 'spec', - model: 'gpt-image-2', + model: 'gpt-image-2.5', size: '2048x1152', aspectRatio: '16:9', imageSize: '2K', @@ -1872,7 +1872,7 @@ describe('ImageCanvasEditorView generation integration', () => { await waitFor(() => { expect(generateEditorIconSpritesheetMock).toHaveBeenCalledWith( expect.objectContaining({ - model: 'gpt-image-2', + model: 'gpt-image-2.5', aspectRatio: '2:3', imageSize: '2K', }), @@ -2315,7 +2315,7 @@ describe('ImageCanvasEditorView generation integration', () => { expect(generateEditorImageMock).toHaveBeenCalledWith( expect.objectContaining({ kind: 'spec', - model: 'gpt-image-2', + model: 'gpt-image-2.5', size: '2048x1152', aspectRatio: '16:9', imageSize: '2K', @@ -3894,7 +3894,7 @@ describe('ImageCanvasEditorView generation integration', () => { expect(within(metadataDialog).getByText('生成提示词')).toBeTruthy(); expect(within(metadataDialog).getByText('一张可修改的生成图')).toBeTruthy(); expect(within(metadataDialog).getByText('Model')).toBeTruthy(); - expect(within(metadataDialog).getByText('gpt-image-2')).toBeTruthy(); + expect(within(metadataDialog).getByText('GPT Image 2.5')).toBeTruthy(); expect(within(metadataDialog).queryByText('Size')).toBeNull(); expect(within(metadataDialog).getByText('Resolution')).toBeTruthy(); expect(within(metadataDialog).getByText('1024 x 1024 px')).toBeTruthy(); diff --git a/src/components/image-editor/ImageCanvasEditorView.test.tsx b/src/components/image-editor/ImageCanvasEditorView.test.tsx index 92b947c88..8665e391d 100644 --- a/src/components/image-editor/ImageCanvasEditorView.test.tsx +++ b/src/components/image-editor/ImageCanvasEditorView.test.tsx @@ -1274,7 +1274,7 @@ describe('ImageCanvasEditorView', () => { fields: [{ title: '生成提示词', value: '明亮主视觉' }], references: [], }, - model: 'gpt-image-2', + model: 'GPT Image 2.5', task: '1', object: 'asset-object-visible', resolution: '1024 x 1024 px', diff --git a/src/components/image-editor/ImageCanvasExportModel.test.ts b/src/components/image-editor/ImageCanvasExportModel.test.ts index 9a1e95e04..6c77f038a 100644 --- a/src/components/image-editor/ImageCanvasExportModel.test.ts +++ b/src/components/image-editor/ImageCanvasExportModel.test.ts @@ -187,7 +187,7 @@ describe('ImageCanvasExportModel', () => { }, ], }, - model: 'gpt-image-2', + model: 'GPT Image 2.5', task: '1', object: 'generated/layer.png', resolution: '1024 x 1024 px', @@ -268,7 +268,7 @@ describe('ImageCanvasExportModel', () => { ], references: [], }); - expect(metadata.visible.model).toBe('gpt-image-2'); + expect(metadata.visible.model).toBe('GPT Image 2.5'); }); it('builds a Spine JSON attachment timeline from image sequence frames', () => { diff --git a/src/components/image-editor/ImageCanvasMetadataModalView.test.tsx b/src/components/image-editor/ImageCanvasMetadataModalView.test.tsx index c108b87d8..95cba2b9d 100644 --- a/src/components/image-editor/ImageCanvasMetadataModalView.test.tsx +++ b/src/components/image-editor/ImageCanvasMetadataModalView.test.tsx @@ -81,7 +81,7 @@ describe('ImageCanvasMetadataModalView', () => { within(dialog).getByText('项目资源 · resource-reference'), ).toBeTruthy(); expect(within(dialog).getByText('Model')).toBeTruthy(); - expect(within(dialog).getByText('gpt-image-2')).toBeTruthy(); + expect(within(dialog).getByText('GPT Image 2.5')).toBeTruthy(); expect(within(dialog).getByText('1024 x 768 px')).toBeTruthy(); expect(within(dialog).queryByText('Provider')).toBeNull(); expect(within(dialog).queryByText(/VectorEngine/u)).toBeNull(); @@ -129,7 +129,7 @@ describe('ImageCanvasMetadataModalView', () => { expect(within(dialog).getByText('角色抠图')).toBeTruthy(); expect(within(dialog).queryByText('处理模型')).toBeNull(); expect(within(dialog).getByText('Model')).toBeTruthy(); - expect(within(dialog).getByText('gpt-image-2')).toBeTruthy(); + expect(within(dialog).getByText('GPT Image 2.5')).toBeTruthy(); expect(within(dialog).queryByText('birefnet')).toBeNull(); expect(within(dialog).queryByText('Aliyun Matting')).toBeNull(); expect(within(dialog).queryByText('segment-common-image')).toBeNull(); diff --git a/src/components/image-editor/ImageCanvasUiAssetExtractionOverlayView.test.tsx b/src/components/image-editor/ImageCanvasUiAssetExtractionOverlayView.test.tsx index 6220aacaa..bdc8f89f4 100644 --- a/src/components/image-editor/ImageCanvasUiAssetExtractionOverlayView.test.tsx +++ b/src/components/image-editor/ImageCanvasUiAssetExtractionOverlayView.test.tsx @@ -6,7 +6,7 @@ import { describe, expect, it, vi } from 'vitest'; import type { CanvasLayer } from './ImageCanvasEditorTypes'; import { - IMAGE_MODEL_GPT_IMAGE_2, + IMAGE_MODEL_GPT_IMAGE_2_5, IMAGE_MODEL_NANOBANANA2, } from './ImageCanvasGenerationModel'; import type { UiAssetExtractionState } from './ImageCanvasUiAssetExtractionModel'; @@ -229,11 +229,11 @@ describe('ImageCanvasUiAssetExtractionOverlayView', () => { fireEvent.click( within(screen.getByRole('menu', { name: '提取素材模型选项' })).getByRole( 'button', - { name: 'gpt-image-2' }, + { name: 'GPT Image 2.5' }, ), ); - expect(onModelChange).toHaveBeenCalledWith(IMAGE_MODEL_GPT_IMAGE_2); + expect(onModelChange).toHaveBeenCalledWith(IMAGE_MODEL_GPT_IMAGE_2_5); }); it('disables extraction submission while reference uploads are pending', () => { @@ -298,12 +298,12 @@ describe('ImageCanvasUiAssetExtractionOverlayView', () => { fireEvent.click( within(screen.getByRole('menu', { name: '提取素材模型选项' })).getByRole( 'button', - { name: 'gpt-image-2' }, + { name: 'GPT Image 2.5' }, ), ); expect(alertMock).toHaveBeenCalledWith( - '当前已有 5 张参考图,gpt-image-2 最多允许 4 张,请先删除多余参考图后再切换', + '当前已有 5 张参考图,GPT Image 2.5 最多允许 4 张,请先删除多余参考图后再切换', ); expect(onModelChange).not.toHaveBeenCalled(); expect(screen.getByRole('menu', { name: '提取素材模型选项' })).toBeTruthy(); diff --git a/src/components/image-editor/useImageCanvasGenerationWorkflow.test.tsx b/src/components/image-editor/useImageCanvasGenerationWorkflow.test.tsx index 0bbdb6dcb..798c96edc 100644 --- a/src/components/image-editor/useImageCanvasGenerationWorkflow.test.tsx +++ b/src/components/image-editor/useImageCanvasGenerationWorkflow.test.tsx @@ -31,6 +31,7 @@ import { CANVAS_GENERATION_PARAMETER_FALLBACK_WARNING, DEFAULT_IMAGE_MODEL, IMAGE_MODEL_GPT_IMAGE_2, + IMAGE_MODEL_GPT_IMAGE_2_5, } from './ImageCanvasGenerationModel'; import { readPerfectPixelOperations, @@ -622,7 +623,7 @@ function GenerationWorkflowHarness({ status: 'idle', composerOpen: true, sourceLayerId: 'layer-source', - imageModel: 'gpt-image-2', + imageModel: IMAGE_MODEL_GPT_IMAGE_2_5, aspectRatio: '2:3', imageSize: '2K', }) @@ -780,7 +781,7 @@ function GenerationWorkflowHarness({ status: 'idle', composerOpen: true, generatedLayerId: 'layer-source', - imageModel: 'gpt-image-2', + imageModel: IMAGE_MODEL_GPT_IMAGE_2_5, aspectRatio: '2:3', imageSize: '2K', }) @@ -797,7 +798,7 @@ function GenerationWorkflowHarness({ status: 'generating', composerOpen: false, sourceLayerId: 'layer-source', - imageModel: 'gpt-image-2', + imageModel: IMAGE_MODEL_GPT_IMAGE_2_5, aspectRatio: '1:1', imageSize: '1K', }) @@ -1241,7 +1242,7 @@ function GenerationWorkflowHarness({