From 71776b9464384bc8a692825b99e0074ce971f652 Mon Sep 17 00:00:00 2001 From: shrimbly Date: Sat, 14 Feb 2026 23:37:32 +1300 Subject: [PATCH] refactor: remove 3D code from GenerateImageNode and nanoBananaExecutor - Remove text-to-3d/image-to-3d from IMAGE_CAPABILITIES - Remove is3D memo and conditional handle/label styling - Remove 3D output preview block - Remove output3dUrl from model change handlers - Remove is3DModel detection and mediaType from nanoBanana executor - Remove 3D response handling from nanoBanana executor - Remove output3dUrl from NanoBananaNodeData and its defaults - Remove 3D fallback from nanoBanana in connectedInputs Co-Authored-By: Claude Opus 4.6 --- src/components/nodes/GenerateImageNode.tsx | 27 +++++---------- src/store/execution/nanoBananaExecutor.ts | 40 ---------------------- src/store/utils/connectedInputs.ts | 3 -- src/store/utils/nodeDefaults.ts | 1 - src/types/nodes.ts | 1 - 5 files changed, 9 insertions(+), 63 deletions(-) diff --git a/src/components/nodes/GenerateImageNode.tsx b/src/components/nodes/GenerateImageNode.tsx index 8c22cd35..686afe93 100644 --- a/src/components/nodes/GenerateImageNode.tsx +++ b/src/components/nodes/GenerateImageNode.tsx @@ -61,7 +61,7 @@ const GEMINI_IMAGE_MODELS: { value: ModelType; label: string }[] = [ ]; // Image generation capabilities -const IMAGE_CAPABILITIES: ModelCapability[] = ["text-to-image", "image-to-image", "text-to-3d", "image-to-3d"]; +const IMAGE_CAPABILITIES: ModelCapability[] = ["text-to-image", "image-to-image"]; type NanoBananaNodeType = Node; @@ -212,8 +212,8 @@ export function GenerateImageNode({ id, data, selected }: NodeProps nodeData.selectedModel?.capabilities?.some((c: string) => c.includes("3d")) ?? false, [nodeData.selectedModel]); // Dynamic title based on selected model - just the model name const displayTitle = useMemo(() => { @@ -533,13 +532,13 @@ export function GenerateImageNode({ id, data, selected }: NodeProps Prompt - {/* Output handle — always "image" ID for stable connections; visual style changes for 3D */} + {/* Output handle */} {/* Output label */}
- {is3D ? "3D" : "Image"} + Image
{/* Preview area */} - {nodeData.output3dUrl ? ( -
- - - - 3D Model Generated - Connect to 3D Viewer -
- ) : nodeData.outputImage ? ( + {nodeData.outputImage ? ( <>
c.includes("3d")); - const requestPayload = { images, prompt: promptText, @@ -93,7 +90,6 @@ export async function executeNanoBanana( selectedModel: nodeData.selectedModel, parameters: nodeData.parameters, dynamicInputs, - ...(is3DModel ? { mediaType: "3d" as const } : {}), }; try { @@ -123,41 +119,6 @@ export async function executeNanoBanana( const result = await response.json(); - // Handle 3D model response - if (result.success && result.model3dUrl) { - updateNodeData(node.id, { - output3dUrl: result.model3dUrl, - outputImage: null, - status: "complete", - error: null, - }); - - // Track cost if applicable - if (nodeData.selectedModel?.provider === "fal" && nodeData.selectedModel?.pricing) { - addIncurredCost(nodeData.selectedModel.pricing.amount); - } - - // Auto-save 3D model to generations folder if configured - if (generationsPath) { - const savePromise = fetch("/api/save-generation", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - directoryPath: generationsPath, - model3d: result.model3dUrl, - prompt: promptText, - }), - }) - .then((res) => res.json()) - .catch((err) => { - console.error("Failed to save 3D model:", err); - }); - - trackSaveGeneration(`3d-${Date.now()}`, savePromise); - } - return; - } - if (result.success && result.image) { const timestamp = Date.now(); const imageId = `${timestamp}`; @@ -183,7 +144,6 @@ export async function executeNanoBanana( updateNodeData(node.id, { outputImage: result.image, - output3dUrl: null, status: "complete", error: null, imageHistory: updatedHistory, diff --git a/src/store/utils/connectedInputs.ts b/src/store/utils/connectedInputs.ts index 5676fe30..0c79f05e 100644 --- a/src/store/utils/connectedInputs.ts +++ b/src/store/utils/connectedInputs.ts @@ -63,9 +63,6 @@ function getSourceOutput(sourceNode: WorkflowNode): { type: "image" | "text" | " return { type: "image", value: (sourceNode.data as AnnotationNodeData).outputImage }; } else if (sourceNode.type === "nanoBanana") { const nbData = sourceNode.data as NanoBananaNodeData; - if (nbData.output3dUrl) { - return { type: "3d", value: nbData.output3dUrl }; - } return { type: "image", value: nbData.outputImage }; } else if (sourceNode.type === "generate3d") { const g3dData = sourceNode.data as Generate3DNodeData; diff --git a/src/store/utils/nodeDefaults.ts b/src/store/utils/nodeDefaults.ts index 4f9a3e65..25fbc3d7 100644 --- a/src/store/utils/nodeDefaults.ts +++ b/src/store/utils/nodeDefaults.ts @@ -123,7 +123,6 @@ export const createDefaultNodeData = (type: NodeType): WorkflowNodeData => { inputImages: [], inputPrompt: null, outputImage: null, - output3dUrl: null, aspectRatio, resolution, model: legacyDefaults.model, // Keep legacy model field for backward compat diff --git a/src/types/nodes.ts b/src/types/nodes.ts index f319ac36..f712c371 100644 --- a/src/types/nodes.ts +++ b/src/types/nodes.ts @@ -151,7 +151,6 @@ export interface NanoBananaNodeData extends BaseNodeData { useGoogleSearch: boolean; // Only available for Nano Banana Pro parameters?: Record; // Model-specific parameters for external providers inputSchema?: ModelInputDef[]; // Model's input schema for dynamic handles - output3dUrl?: string | null; // URL to generated 3D GLB model status: NodeStatus; error: string | null; imageHistory: CarouselImageItem[]; // Carousel history (IDs only)