You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

8.3 KiB

phase plan type
14-fix-drag-connect-bugs 1 execute
Fix two bugs with nodes created via drag-connect: 1. Connection vanishes after selecting model from browser 2. Node defaults to Gemini with correct Browse button but connection to default handles breaks when model schema loads

Root Cause Analysis:

Bug 1 (Connection Vanishes):

  • Node created via drag-connect gets default Gemini model (no inputSchema)
  • Connection made to default handle IDs: "image" and "text"
  • User clicks Browse → selects external model (Replicate/fal.ai)
  • handleBrowseModelSelect updates selectedModel
  • ModelParameters component loads schema → calls handleInputsLoaded → sets inputSchema
  • Node re-renders with dynamic handles that have different IDs from schema (e.g., "image_url" instead of "image")
  • React Flow invalidates edges connected to non-existent handles → connection vanishes

Bug 2 is a symptom of Bug 1 - the node works fine with Gemini defaults, but switching to an external provider with dynamic schema causes the connection loss.

Solution: When a user selects an external model on a node created via drag-connect, we need to either: A) Remap existing connections to the new dynamic handle IDs, OR B) Keep standard "image" and "text" handles for external models too (normalize schema handle IDs)

Option B is simpler and more robust - normalize all dynamic schema handles to use standard IDs. The schema already provides semantic type info ("image" vs "text"), so we don't need the provider-specific names as handle IDs.

Output: Connections persist when switching from default Gemini to external provider on drag-connect-created nodes.

<execution_context> @~/.claude/get-shit-done/workflows/execute-phase.md @~/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md

Key source files: @src/components/nodes/GenerateImageNode.tsx - Dynamic handle rendering (lines 464-550) @src/components/WorkflowCanvas.tsx - Connection handling, handleMenuSelect (lines 529-646) @src/components/nodes/ModelParameters.tsx - Schema fetching and input loading

Current behavior:

  1. handleMenuSelect creates node with addNode(nodeType, flowPosition) - no initial data
  2. Node gets default Gemini with handles id="image" and id="text"
  3. Connection made to default handle IDs
  4. User selects external model → handleInputsLoaded sets inputSchema
  5. Node renders dynamic handles with schema-specific IDs (e.g., "image_url", "prompt")
  6. Connection to "image" or "text" becomes invalid → edge removed

Target behavior:

  • Dynamic handles use standard IDs ("image", "text") regardless of schema
  • Schema still provides semantic info but doesn't change handle IDs
  • Connections persist through model changes
Task 1: Normalize dynamic handle IDs to standard values src/components/nodes/GenerateImageNode.tsx Modify the dynamic handle rendering logic (lines 464-510) to use standard handle IDs instead of schema-specific names:
1. In the dynamic handle rendering section, change `id={input.name}` to use standard IDs:
   - For image inputs: use `"image"` (or `"image-{index}"` if multiple)
   - For text inputs: use `"text"` (or `"text-{index}"` if multiple)

2. Update the handle key to use a combination of type and index for uniqueness

3. The schema `input.name` is still used for:
   - `title` attribute (tooltip)
   - Label display
   - Parameter mapping during execution (stored in nodeData, not handle ID)

This ensures connections made to `"image"` or `"text"` remain valid when schema loads.

Example change:
```typescript
// Before:
<Handle
  type="target"
  position={Position.Left}
  id={input.name}  // e.g., "image_url"
  ...
/>

// After:
<Handle
  type="target"
  position={Position.Left}
  id={imageInputs.length > 1 ? `image-${imageIndex}` : "image"}  // Standard ID
  ...
/>
```
1. Create node via drag-connect from image output 2. Connection appears with default Gemini handles 3. Click Browse → select Replicate model 4. Connection persists after schema loads - Dynamic handles use standard IDs: "image", "text" (or indexed if multiple) - Schema input names preserved for labels and tooltips - Connections persist through model changes Task 2: Update connection validation for normalized handles src/components/WorkflowCanvas.tsx Verify and update `getHandleType` and `findCompatibleHandle` functions to work with normalized handle IDs:
1. `getHandleType` (lines 63-73): May need updates if we use indexed handles like `"image-0"`
   - Add pattern matching for indexed handles: `if (handleId.startsWith("image")) return "image"`

2. `findCompatibleHandle` (lines 327-341): Update to return standard handle IDs
   - When finding compatible input handle, return `"image"` or `"text"` instead of schema name

3. `handleMenuSelect` (lines 544-646): Already uses `"image"` and `"text"` for targetHandleId, so should work as-is

The key insight: by normalizing handle IDs in the node, all existing connection logic that expects `"image"` and `"text"` will continue to work.
1. Drag connection from prompt node's text output 2. Drop on empty space → select "Generate Image" 3. Connection creates to text handle 4. Browse → select fal.ai model with text input 5. Connection persists (text handle still valid) - getHandleType handles indexed handle IDs - findCompatibleHandle returns normalized IDs - Multi-input models (multiple images) work correctly Task 3: Update execution to map normalized handles to schema names src/store/workflowStore.ts, src/app/api/generate/route.ts Ensure the execution pipeline correctly maps normalized handle IDs back to schema parameter names:
1. In `getConnectedInputs` (workflowStore.ts): Check if it needs to map handle IDs to schema names
   - Currently uses handle IDs directly for dynamicInputs
   - May need to look up schema to get the actual parameter name

2. In `/api/generate/route.ts`: Verify parameter mapping
   - Check how dynamicInputs are passed to provider APIs
   - Ensure the provider receives the correct parameter names (e.g., "image_url" not "image")

3. Store the schema input name mapping in nodeData for execution:
   - `inputSchema` already has `{ name, type, label }`
   - Execution can look up: "image" handle → first image input from schema → use schema name for API

If execution already uses nodeData.inputSchema for parameter names (not handle IDs), this task may be minimal.
1. Create node via drag-connect 2. Connect image and text inputs 3. Select external model (Replicate/fal.ai) 4. Run workflow 5. Verify API call uses correct parameter names from schema - Execution maps normalized handle IDs to schema parameter names - Provider APIs receive correct parameter names - No regression in existing workflows Before declaring phase complete: - [ ] `npm run build` succeeds without errors - [ ] Drag-connect from image output → Generate Image → connection persists - [ ] Browse → select external model → connection still persists - [ ] Drag-connect from text output → Generate Image → connection persists after model change - [ ] Execute workflow with drag-connect-created node → works correctly - [ ] Existing workflows (created via action bar) still work - [ ] Multiple input models (if any) handle correctly

<success_criteria>

  • All tasks completed
  • All verification checks pass
  • Connections persist when switching models on drag-connect nodes
  • No regression in existing functionality
  • External providers work correctly with normalized handles </success_criteria>
After completion, create `.planning/phases/14-fix-drag-connect-bugs/14-01-SUMMARY.md`