From bd0928c135eef5c4154c92561847fec790ce391e Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 24 Mar 2026 15:21:22 +0800 Subject: [PATCH] chore: add agent scene generation diagnostics --- app/(chat)/api/chat/route.ts | 64 +++++++++++++++++++++ lib/canvas/generate-image.ts | 106 ++++++++++++++++++++++++++++------- 2 files changed, 150 insertions(+), 20 deletions(-) diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index 676a301fc..3801635a8 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -6974,6 +6974,7 @@ export async function POST(request: Request) { slotTitle: selectedAgentPreset.name, userSupplementPrompt: sanitizedUserSupplementPrompt || null, }); + const sceneGenerationStartedAt = Date.now(); try { const mergedImageParams = { @@ -6987,6 +6988,27 @@ export async function POST(request: Request) { ? String(selectedChatModel || "").trim() : presetModelId; const resolvedImageCount = Math.max(1, effectiveImageParams?.imageCount || 1); + console.info("[Chat API] Agent scene generation started:", { + chatId: id, + agentPresetId: selectedAgentPreset.id, + agentPresetName: selectedAgentPreset.name, + agentExecutionSnapshotId: presetSnapshot.id, + projectId: contextPayload?.projectId || null, + selectedChatModel: String(selectedChatModel || "").trim() || "auto", + resolvedModelRef, + resolvedImageCount, + sourceImageCount: sourceImageUrls.length, + sourceAssetCount: sourceAssetIds.length, + promptLength: String(scenePrompt || `生成${selectedAgentPreset.name}`).length, + aspectRatio: + typeof mergedImageParams.aspectRatio === "string" + ? mergedImageParams.aspectRatio + : effectiveImageParams?.aspectRatio || defaultImageQualityParams.aspectRatio, + imageSize: + typeof mergedImageParams.imageSize === "string" + ? mergedImageParams.imageSize + : effectiveImageParams?.imageSize || defaultImageQualityParams.imageSize, + }); const result = await generateCanvasImage({ prompt: scenePrompt || `生成${selectedAgentPreset.name}`, negativePrompt: @@ -7004,6 +7026,24 @@ export async function POST(request: Request) { : effectiveImageParams?.imageSize || defaultImageQualityParams.imageSize, imageCount: resolvedImageCount, referenceImages: sourceImageUrls, + debugLabel: "agent-scene-generation", + debugMeta: { + chatId: id, + agentPresetId: selectedAgentPreset.id, + agentPresetName: selectedAgentPreset.name, + agentExecutionSnapshotId: presetSnapshot.id, + projectId: contextPayload?.projectId || null, + }, + }); + console.info("[Chat API] Agent scene generation model completed:", { + chatId: id, + agentPresetId: selectedAgentPreset.id, + agentPresetName: selectedAgentPreset.name, + agentExecutionSnapshotId: presetSnapshot.id, + resultImageCount: result.images.length, + resultModelName: result.model, + resultModelRef: result.modelRef, + elapsedMs: Date.now() - sceneGenerationStartedAt, }); const imageMarkdown = buildAgentToolImagesMarkdown( @@ -7058,6 +7098,14 @@ export async function POST(request: Request) { requestedImageCount: resolvedImageCount, }, ); + console.info("[Chat API] Agent scene generation persisted:", { + chatId: id, + agentPresetId: selectedAgentPreset.id, + agentPresetName: selectedAgentPreset.name, + agentExecutionSnapshotId: presetSnapshot.id, + savedImageCount: result.images.length, + elapsedMs: Date.now() - sceneGenerationStartedAt, + }); writeAssistantTextChunk( writer, @@ -7085,10 +7133,26 @@ export async function POST(request: Request) { "agent-preset:image:scene-generation:canvas-media", ); } + console.info("[Chat API] Agent scene generation response streamed:", { + chatId: id, + agentPresetId: selectedAgentPreset.id, + agentPresetName: selectedAgentPreset.name, + agentExecutionSnapshotId: presetSnapshot.id, + resultImageCount: result.images.length, + elapsedMs: Date.now() - sceneGenerationStartedAt, + }); successCount = result.images.length; } catch (sceneError) { console.error("[Chat API] Agent preset scene generation failed:", sceneError); + console.error("[Chat API] Agent scene generation failed detail:", { + chatId: id, + agentPresetId: selectedAgentPreset.id, + agentPresetName: selectedAgentPreset.name, + agentExecutionSnapshotId: presetSnapshot.id, + elapsedMs: Date.now() - sceneGenerationStartedAt, + error: sceneError instanceof Error ? sceneError.message : String(sceneError), + }); const errorMessage = `### ${selectedAgentPreset.name}\n\n执行失败:${ sceneError instanceof Error ? sceneError.message : "请稍后重试" }`; diff --git a/lib/canvas/generate-image.ts b/lib/canvas/generate-image.ts index 87cfddd22..af281eccc 100644 --- a/lib/canvas/generate-image.ts +++ b/lib/canvas/generate-image.ts @@ -19,6 +19,8 @@ export interface CanvasGenerateImageRequest { imageCount?: number; referenceImage?: string; referenceImages?: string[]; + debugLabel?: string; + debugMeta?: Record; } export interface ParsedImage { @@ -93,6 +95,7 @@ function getProviderBatchLimit(providerType: string) { export async function generateCanvasImage( request: CanvasGenerateImageRequest ): Promise { + const startedAt = Date.now(); const prompt = String(request.prompt || "").trim(); if (!prompt) { throw new Error("请输入提示词"); @@ -118,6 +121,11 @@ export async function generateCanvasImage( const referenceImages = Array.isArray(request.referenceImages) ? request.referenceImages : []; + const debugLabel = String(request.debugLabel || "").trim() || "canvas-image"; + const debugMeta = + request.debugMeta && typeof request.debugMeta === "object" + ? request.debugMeta + : undefined; const allModels = await getEnabledAiModelsWithProvider(); const imageModels = allModels.filter((m) => m.model.supportsImageGen); @@ -191,6 +199,20 @@ export async function generateCanvasImage( throw new Error("参考图片链接不可访问,请重新上传后再试"); } + console.info("[Canvas Generate Image] Started:", { + debugLabel, + promptLength: prompt.length, + aspectRatio, + imageSize, + imageCount, + requestedReferenceImageCount: normalizedReferenceImages.length, + reachableReferenceImageCount: reachableReferenceImages.length, + selectedModelRef: selectedModel.model.id, + selectedModelId: selectedModel.model.modelId, + providerType: provider.type, + ...debugMeta, + }); + const messages = [ { role: "user" as const, @@ -338,29 +360,73 @@ export async function generateCanvasImage( const collectedImages: ParsedImage[] = []; const maxBatches = Math.max(1, Math.ceil(targetImageCount / providerBatchLimit)); - for (let batchIndex = 0; batchIndex < maxBatches; batchIndex += 1) { - const remaining = targetImageCount - collectedImages.length; - if (remaining <= 0) break; - const batchImageCount = Math.min(providerBatchLimit, remaining); - const imageMarkdown = await executeGenerateBatch(batchImageCount); - const parsedImages = parseImagesFromMarkdown(imageMarkdown); - if (parsedImages.length === 0) { - if (collectedImages.length > 0) { - break; + try { + for (let batchIndex = 0; batchIndex < maxBatches; batchIndex += 1) { + const remaining = targetImageCount - collectedImages.length; + if (remaining <= 0) break; + const batchImageCount = Math.min(providerBatchLimit, remaining); + const batchStartedAt = Date.now(); + console.info("[Canvas Generate Image] Batch started:", { + debugLabel, + batchIndex: batchIndex + 1, + totalBatches: maxBatches, + batchImageCount, + currentCollectedCount: collectedImages.length, + providerType: provider.type, + selectedModelId: selectedModel.model.modelId, + ...debugMeta, + }); + const imageMarkdown = await executeGenerateBatch(batchImageCount); + const parsedImages = parseImagesFromMarkdown(imageMarkdown); + console.info("[Canvas Generate Image] Batch completed:", { + debugLabel, + batchIndex: batchIndex + 1, + totalBatches: maxBatches, + batchImageCount, + parsedImageCount: parsedImages.length, + elapsedMs: Date.now() - batchStartedAt, + ...debugMeta, + }); + if (parsedImages.length === 0) { + if (collectedImages.length > 0) { + break; + } + throw new Error("图片生成失败"); } + collectedImages.push(...parsedImages.slice(0, batchImageCount)); + } + + if (collectedImages.length === 0) { throw new Error("图片生成失败"); } - collectedImages.push(...parsedImages.slice(0, batchImageCount)); - } - if (collectedImages.length === 0) { - throw new Error("图片生成失败"); - } + const finalImages = collectedImages.slice(0, targetImageCount); + console.info("[Canvas Generate Image] Completed:", { + debugLabel, + elapsedMs: Date.now() - startedAt, + finalImageCount: finalImages.length, + providerType: provider.type, + selectedModelRef: selectedModel.model.id, + selectedModelId: selectedModel.model.modelId, + ...debugMeta, + }); - return { - images: collectedImages.slice(0, targetImageCount), - model: selectedModel.model.displayName, - modelRef: selectedModel.model.id, - prompt, - }; + return { + images: finalImages, + model: selectedModel.model.displayName, + modelRef: selectedModel.model.id, + prompt, + }; + } catch (error) { + console.error("[Canvas Generate Image] Failed:", { + debugLabel, + elapsedMs: Date.now() - startedAt, + providerType: provider.type, + selectedModelRef: selectedModel.model.id, + selectedModelId: selectedModel.model.modelId, + error: error instanceof Error ? error.message : String(error), + ...debugMeta, + }); + throw error; + } }