From 20a5934cfcf1a63a29c9afac433a5f65098e6523 Mon Sep 17 00:00:00 2001 From: 7418 <7418@openclaw.ai> Date: Fri, 27 Feb 2026 11:32:00 +0800 Subject: [PATCH] fix: persist image generation results to DB for reload survival, bump v0.17.2 Root cause: after image generation, the message content in DB stayed as `image-gen-request` (the options form). On app restart, MessageItem re-parsed this as a generation form instead of showing the completed result. The result only lived in React state and localStorage. Fix: - db.ts: add updateMessageContent() to update a message's content by ID - /api/chat/messages: add PUT handler for message content updates - ImageGenConfirmation: accept messageId prop; on successful generation, replace message content from image-gen-request to image-gen-result format (with localPath references) via PUT API call - MessageItem: pass message.id to ImageGenConfirmation Now on restart, parseImageGenResult() matches the persisted image-gen-result block and renders ImageGenCard directly with the saved image paths. Co-Authored-By: Claude Opus 4.6 --- package-lock.json | 4 +-- package.json | 2 +- src/app/api/chat/messages/route.ts | 30 +++++++++++++++++++- src/components/chat/ImageGenConfirmation.tsx | 24 ++++++++++++++++ src/components/chat/MessageItem.tsx | 1 + src/lib/db.ts | 5 ++++ 6 files changed, 62 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b522632..72f3c79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codepilot", - "version": "0.17.1", + "version": "0.17.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codepilot", - "version": "0.17.1", + "version": "0.17.2", "dependencies": { "@ai-sdk/anthropic": "^3.0.47", "@ai-sdk/google": "^3.0.31", diff --git a/package.json b/package.json index d49074b..8695091 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codepilot", - "version": "0.17.1", + "version": "0.17.2", "private": true, "author": { "name": "op7418", diff --git a/src/app/api/chat/messages/route.ts b/src/app/api/chat/messages/route.ts index 9f9c0ff..7057c77 100644 --- a/src/app/api/chat/messages/route.ts +++ b/src/app/api/chat/messages/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import { addMessage, getSession } from '@/lib/db'; +import { addMessage, updateMessageContent, getSession } from '@/lib/db'; export const runtime = 'nodejs'; @@ -37,3 +37,31 @@ export async function POST(request: NextRequest) { return NextResponse.json({ error: msg }, { status: 500 }); } } + +/** + * PUT /api/chat/messages + * Update the content of an existing message. + * Used to replace image-gen-request with image-gen-result after generation. + */ +export async function PUT(request: NextRequest) { + try { + const body = await request.json(); + const { message_id, content } = body as { + message_id: string; + content: string; + }; + + if (!message_id || !content) { + return NextResponse.json( + { error: 'message_id and content are required' }, + { status: 400 }, + ); + } + + updateMessageContent(message_id, content); + return NextResponse.json({ ok: true }); + } catch (error) { + const msg = error instanceof Error ? error.message : 'Failed to update message'; + return NextResponse.json({ error: msg }, { status: 500 }); + } +} diff --git a/src/components/chat/ImageGenConfirmation.tsx b/src/components/chat/ImageGenConfirmation.tsx index 20b1c9a..ebeb9e9 100644 --- a/src/components/chat/ImageGenConfirmation.tsx +++ b/src/components/chat/ImageGenConfirmation.tsx @@ -17,6 +17,7 @@ const ASPECT_RATIOS = [ const RESOLUTIONS = ['1K', '2K', '4K'] as const; interface ImageGenConfirmationProps { + messageId?: string; initialPrompt: string; initialAspectRatio: string; initialResolution: string; @@ -32,6 +33,7 @@ function storageKey(prompt: string, sessionId?: string): string { } export function ImageGenConfirmation({ + messageId, initialPrompt, initialAspectRatio, initialResolution, @@ -140,6 +142,28 @@ export function ImageGenConfirmation({ // storage full } + // Persist result to DB by replacing image-gen-request with image-gen-result + if (messageId) { + const resultBlock = JSON.stringify({ + status: 'completed', + prompt, + aspectRatio, + resolution, + images: genResult.images.map(img => ({ + mimeType: img.mimeType, + localPath: img.localPath, + })), + }); + fetch('/api/chat/messages', { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + message_id: messageId, + content: '```image-gen-result\n' + resultBlock + '\n```', + }), + }).catch(() => {}); + } + // Defer event dispatch so React commits setResult/setStatus before // ChatView's handler calls sendMessage and triggers a re-render setTimeout(() => { diff --git a/src/components/chat/MessageItem.tsx b/src/components/chat/MessageItem.tsx index 808bba4..11cc253 100644 --- a/src/components/chat/MessageItem.tsx +++ b/src/components/chat/MessageItem.tsx @@ -491,6 +491,7 @@ export function MessageItem({ message }: MessageItemProps) { <> {parsed.beforeText && {parsed.beforeText}}