From 1765930dc33a5162149aaa70554e6bfd28c74f5a Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Sun, 11 Oct 2026 19:57:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E7=94=9F=E5=9B=BE=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E5=90=8E=E9=87=8D=E8=AF=95=E6=97=B6=EF=BC=8C=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E7=94=B1=E6=96=B0=E5=8D=A1=E7=89=87=E6=8E=A5?= =?UTF-8?q?=E6=9B=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同一轮里生图失败后又发起了生图,只保留最新的那张卡片,不再同时显示失败卡片和生成中卡片。 Co-Authored-By: Claude Opus 5.5 --- .../components/chat/GeneratedImages.test.tsx | 13 +++++ .../components/chat/generatedImageModel.ts | 53 ++++++++++--------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/chat/GeneratedImages.test.tsx b/frontend/src/components/chat/GeneratedImages.test.tsx index ef6d2e06b..f1a6f6499 100644 --- a/frontend/src/components/chat/GeneratedImages.test.tsx +++ b/frontend/src/components/chat/GeneratedImages.test.tsx @@ -179,4 +179,17 @@ describe('collectPendingImageGenerations', () => { ]); expect(collectPendingImageGenerations(null, [])).toEqual([]); }); + + it('drops a failed card once a later generation replaces it', () => { + const failed = { status: 'failed' as const, resultSummary: { kind: 'generated_image', truncated: false, error_code: 'no_image_returned' } as never }; + const retrying = runWith([call(failed), call({ toolCallId: 'call-2' })]); + expect(collectPendingImageGenerations(retrying, [])).toMatchObject([{ toolCallId: 'call-2', status: 'running' }]); + + const retried = runWith([call(failed), call({ + toolCallId: 'call-2', + status: 'success', + resultSummary: { kind: 'generated_image', truncated: false, file_id: 'file-1' } as never, + })]); + expect(collectPendingImageGenerations(retried, [block])).toEqual([]); + }); }); diff --git a/frontend/src/components/chat/generatedImageModel.ts b/frontend/src/components/chat/generatedImageModel.ts index bf72f06f8..04fbc791c 100644 --- a/frontend/src/components/chat/generatedImageModel.ts +++ b/frontend/src/components/chat/generatedImageModel.ts @@ -57,33 +57,34 @@ export function collectPendingImageGenerations( ): PendingImageGeneration[] { if (!run) return []; const renderedFileIds = new Set(blocks.map(block => block.file_id)); + const calls = run.steps.flatMap(step => step.toolCalls.filter(call => call.toolName === GENERATE_IMAGE_TOOL_NAME)); const pending: PendingImageGeneration[] = []; - for (const step of run.steps) { - for (const call of step.toolCalls) { - if (call.toolName !== GENERATE_IMAGE_TOOL_NAME) continue; - const summary = call.resultSummary as (Record | undefined); - const fileId = typeof summary?.file_id === 'string' ? summary.file_id : null; - let status: PendingImageStatus; - if (call.status === 'running') { - status = 'running'; - } else if (call.status === 'success') { - if (!fileId || renderedFileIds.has(fileId)) continue; - status = 'running'; - } else if (call.status === 'interrupted') { - status = 'interrupted'; - } else { - status = 'failed'; - } - const aspectRatio = typeof call.arguments?.aspect_ratio === 'string' ? call.arguments.aspect_ratio : '1:1'; - pending.push({ - toolCallId: call.toolCallId, - status, - aspectRatio, - startedAt: call.startedAt, - completedAt: call.completedAt, - errorCode: typeof summary?.error_code === 'string' ? summary.error_code : null, - }); + calls.forEach((call, index) => { + const summary = call.resultSummary as (Record | undefined); + const fileId = typeof summary?.file_id === 'string' ? summary.file_id : null; + let status: PendingImageStatus; + if (call.status === 'running') { + status = 'running'; + } else if (call.status === 'success') { + if (!fileId || renderedFileIds.has(fileId)) return; + status = 'running'; + } else if (index < calls.length - 1) { + // 失败或中断后又发起了生图(重试),由后一张卡片接替,不再保留失败卡片。 + return; + } else if (call.status === 'interrupted') { + status = 'interrupted'; + } else { + status = 'failed'; } - } + const aspectRatio = typeof call.arguments?.aspect_ratio === 'string' ? call.arguments.aspect_ratio : '1:1'; + pending.push({ + toolCallId: call.toolCallId, + status, + aspectRatio, + startedAt: call.startedAt, + completedAt: call.completedAt, + errorCode: typeof summary?.error_code === 'string' ? summary.error_code : null, + }); + }); return pending; } From 407746876a6f0ef76c6098b8d66fe84d6b4d590d Mon Sep 17 00:00:00 2001 From: HyxiaoGe <18889592303@163.com> Date: Sun, 11 Oct 2026 20:02:14 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E7=94=9F=E5=9B=BE=E7=82=B9=E9=98=B5?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E5=8E=BB=E6=8E=89=E5=B7=A6=E4=B8=8A=E8=A7=92?= =?UTF-8?q?=E3=80=8C=E6=AD=A3=E5=9C=A8=E7=94=9F=E6=88=90=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E3=80=8D=E6=96=87=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 文字和点阵混在一起不易分辨,只保留右下角秒数;文字改为仅读屏可见,状态播报不变。 Co-Authored-By: Claude Opus 5.5 --- frontend/src/components/chat/GeneratedImages.test.tsx | 1 + frontend/src/components/chat/GeneratedImages.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/chat/GeneratedImages.test.tsx b/frontend/src/components/chat/GeneratedImages.test.tsx index f1a6f6499..318f6ad54 100644 --- a/frontend/src/components/chat/GeneratedImages.test.tsx +++ b/frontend/src/components/chat/GeneratedImages.test.tsx @@ -132,6 +132,7 @@ describe('GeneratedImages', () => { const card = screen.getByTestId('generated-image-pending'); expect(card).toHaveStyle({ width: `${imageDisplayWidth(2, 3)}px` }); expect(screen.getByRole('status')).toHaveTextContent('正在生成图片'); + expect(screen.getByText('正在生成图片')).toHaveClass('sr-only'); expect(screen.getByText('12 秒')).toBeInTheDocument(); act(() => { diff --git a/frontend/src/components/chat/GeneratedImages.tsx b/frontend/src/components/chat/GeneratedImages.tsx index 92699df6a..34856d773 100644 --- a/frontend/src/components/chat/GeneratedImages.tsx +++ b/frontend/src/components/chat/GeneratedImages.tsx @@ -94,7 +94,7 @@ function PendingImageCard({ pending }: { pending: PendingImageGeneration }) { {label}