diff --git a/src/components/composer/GenerationComposer.tsx b/src/components/composer/GenerationComposer.tsx index c62f9e4d..13c60dd4 100644 --- a/src/components/composer/GenerationComposer.tsx +++ b/src/components/composer/GenerationComposer.tsx @@ -989,12 +989,13 @@ export function GenerationComposer() { return current; } + const currentCapabilities = current.selectedModel?.capabilities ?? []; const next = { ...current, selectedModel: { ...resolvedModel, - capabilities: current.selectedModel.capabilities.length > 0 - ? current.selectedModel.capabilities + capabilities: currentCapabilities.length > 0 + ? currentCapabilities : resolvedModel.capabilities, }, }; @@ -1013,10 +1014,11 @@ export function GenerationComposer() { nodeModel && selectedModelNeedsPopiserverMetadataLookup(nodeModel) ) { + const nodeModelCapabilities = nodeModel.capabilities ?? []; updateNodeData(activeContext.node.id, { selectedModel: { ...resolvedModel, - capabilities: nodeModel.capabilities.length > 0 ? nodeModel.capabilities : resolvedModel.capabilities, + capabilities: nodeModelCapabilities.length > 0 ? nodeModelCapabilities : resolvedModel.capabilities, }, }); } diff --git a/src/store/execution/nanoBananaExecutor.ts b/src/store/execution/nanoBananaExecutor.ts index 1a1664f0..44144eca 100644 --- a/src/store/execution/nanoBananaExecutor.ts +++ b/src/store/execution/nanoBananaExecutor.ts @@ -7,6 +7,7 @@ import type { NanoBananaNodeData, + Resolution, SelectedModel, } from "@/types"; import { calculateGenerationCost } from "@/utils/costCalculator"; @@ -46,6 +47,12 @@ export interface NanoBananaOptions { useStoredFallback?: boolean; } +const GEMINI_RESOLUTIONS: Resolution[] = ["512", "1K", "2K", "4K"]; + +function normalizeGeminiResolution(value: string): Resolution { + return GEMINI_RESOLUTIONS.includes(value as Resolution) ? (value as Resolution) : "2K"; +} + function isProviderOverloadError(error: unknown): boolean { const message = error instanceof Error ? error.message : String(error); return /provider is temporarily overloaded|system\s+disk\s+overloaded/i.test(message); @@ -376,7 +383,7 @@ export async function executeNanoBanana( if (modelToUse.provider === "fal" && modelToUse.pricing) { addIncurredCost(modelToUse.pricing.amount); } else if (modelToUse.provider === "gemini") { - const generationCost = calculateGenerationCost(nodeData.model, nodeConfig.resolution); + const generationCost = calculateGenerationCost(nodeData.model, normalizeGeminiResolution(nodeConfig.resolution)); addIncurredCost(generationCost); } diff --git a/src/utils/modelSchemaDefaults.ts b/src/utils/modelSchemaDefaults.ts index 17b53f7b..b62ab861 100644 --- a/src/utils/modelSchemaDefaults.ts +++ b/src/utils/modelSchemaDefaults.ts @@ -57,7 +57,7 @@ export function buildImageDefaultsFromSchema(schema: ModelParameter[]): { return { ...(hasValue(ratioValue) ? { aspectRatio: String(ratioValue) as AspectRatio } : {}), ...(hasValue(resolutionValue) ? { resolution: String(resolutionValue) } : {}), - ...(Number.isInteger(imageCountValue) && imageCountValue > 0 + ...(typeof imageCountValue === "number" && Number.isInteger(imageCountValue) && imageCountValue > 0 ? { imageCount: imageCountValue as ImageGenerationCount } : {}), parameters,