From f0e41a8f514bc939401f4bc54cc18ec4fa7baad6 Mon Sep 17 00:00:00 2001 From: shrimbly Date: Wed, 18 Feb 2026 19:25:39 +1300 Subject: [PATCH] feat: rename Audio Input to Audio, add audio input handle for pass-through - Rename node title from "Audio Input" to "Audio" - Rename label in ConnectionDropMenu from "Audio Input" to "Audio" - Add target (input) handle to Audio node so it can receive audio from GenerateAudio and other upstream nodes - Add Audio node to AUDIO_TARGET_OPTIONS so it appears in the context menu when dragging from GenerateAudio's output connector - Add execution logic: connected audio populates audioFile (connection wins over uploaded file), enabling pass-through to downstream nodes Co-Authored-By: Claude Opus 4.6 --- src/components/ConnectionDropMenu.tsx | 11 ++++++++++- src/components/WorkflowCanvas.tsx | 3 ++- src/components/nodes/AudioInputNode.tsx | 9 ++++++++- src/store/execution/executeNode.ts | 11 +++++++++-- src/store/workflowStore.ts | 11 +++++++++-- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/components/ConnectionDropMenu.tsx b/src/components/ConnectionDropMenu.tsx index 09bebbc4..c751475c 100644 --- a/src/components/ConnectionDropMenu.tsx +++ b/src/components/ConnectionDropMenu.tsx @@ -290,6 +290,15 @@ const VIDEO_SOURCE_OPTIONS: MenuOption[] = [ // Audio target options (nodes that accept audio input) const AUDIO_TARGET_OPTIONS: MenuOption[] = [ + { + type: "audioInput", + label: "Audio", + icon: ( + + + + ), + }, { type: "output", label: "Output", @@ -314,7 +323,7 @@ const AUDIO_TARGET_OPTIONS: MenuOption[] = [ const AUDIO_SOURCE_OPTIONS: MenuOption[] = [ { type: "audioInput", - label: "Audio Input", + label: "Audio", icon: ( diff --git a/src/components/WorkflowCanvas.tsx b/src/components/WorkflowCanvas.tsx index f238e7b5..370ad48e 100644 --- a/src/components/WorkflowCanvas.tsx +++ b/src/components/WorkflowCanvas.tsx @@ -850,7 +850,8 @@ export function WorkflowCanvas() { } } else if (handleType === "audio") { if (nodeType === "audioInput") { - // AudioInput outputs audio + // Audio node: accepts audio input and outputs audio + targetHandleId = "audio"; sourceHandleIdForNewNode = "audio"; } else if (nodeType === "generateAudio") { // GenerateAudio outputs audio diff --git a/src/components/nodes/AudioInputNode.tsx b/src/components/nodes/AudioInputNode.tsx index 90882bb6..327efbf4 100644 --- a/src/components/nodes/AudioInputNode.tsx +++ b/src/components/nodes/AudioInputNode.tsx @@ -278,7 +278,7 @@ export function AudioInputNode({ id, data, selected }: NodeProps updateNodeData(id, { customTitle: title || undefined })} @@ -389,6 +389,13 @@ export function AudioInputNode({ id, data, selected }: NodeProps )} + 0 && audioInputs.audio[0]) { + ctx.updateNodeData(ctx.node.id, { audioFile: audioInputs.audio[0] }); + } + break; + } case "annotation": await executeAnnotation(ctx); break; diff --git a/src/store/workflowStore.ts b/src/store/workflowStore.ts index 435f9498..d255a9f7 100644 --- a/src/store/workflowStore.ts +++ b/src/store/workflowStore.ts @@ -870,9 +870,16 @@ export const useWorkflowStore = create((set, get) => ({ switch (node.type) { case "imageInput": - case "audioInput": - // Data source nodes - no execution needed + // Data source node - no execution needed break; + case "audioInput": { + // If audio is connected from upstream, use it (connection wins over upload) + const audioInputs = get().getConnectedInputs(node.id); + if (audioInputs.audio.length > 0 && audioInputs.audio[0]) { + get().updateNodeData(node.id, { audioFile: audioInputs.audio[0] }); + } + break; + } case "glbViewer": await executeGlbViewer(executionCtx); break;