Browse Source
Phase 14 complete - Milestone v1.1 finished Tasks completed: - Normalize dynamic handle IDs to standard values - Update connection validation for normalized handles - Map normalized handles to schema names in execution - Add placeholder handles for unused input types SUMMARY: .planning/phases/14-fix-drag-connect-bugs/14-01-SUMMARY.md Co-Authored-By: Claude <noreply@anthropic.com>handoff-20260429-1057
4 changed files with 334 additions and 17 deletions
@ -0,0 +1,204 @@ |
|||
--- |
|||
phase: 14-fix-drag-connect-bugs |
|||
plan: 01 |
|||
type: execute |
|||
--- |
|||
|
|||
<objective> |
|||
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. |
|||
</objective> |
|||
|
|||
<execution_context> |
|||
@~/.claude/get-shit-done/workflows/execute-phase.md |
|||
@~/.claude/get-shit-done/templates/summary.md |
|||
</execution_context> |
|||
|
|||
<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 |
|||
</context> |
|||
|
|||
<tasks> |
|||
|
|||
<task type="auto"> |
|||
<name>Task 1: Normalize dynamic handle IDs to standard values</name> |
|||
<files>src/components/nodes/GenerateImageNode.tsx</files> |
|||
<action> |
|||
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 |
|||
... |
|||
/> |
|||
``` |
|||
</action> |
|||
<verify> |
|||
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 |
|||
</verify> |
|||
<done> |
|||
- Dynamic handles use standard IDs: "image", "text" (or indexed if multiple) |
|||
- Schema input names preserved for labels and tooltips |
|||
- Connections persist through model changes |
|||
</done> |
|||
</task> |
|||
|
|||
<task type="auto"> |
|||
<name>Task 2: Update connection validation for normalized handles</name> |
|||
<files>src/components/WorkflowCanvas.tsx</files> |
|||
<action> |
|||
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. |
|||
</action> |
|||
<verify> |
|||
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) |
|||
</verify> |
|||
<done> |
|||
- getHandleType handles indexed handle IDs |
|||
- findCompatibleHandle returns normalized IDs |
|||
- Multi-input models (multiple images) work correctly |
|||
</done> |
|||
</task> |
|||
|
|||
<task type="auto"> |
|||
<name>Task 3: Update execution to map normalized handles to schema names</name> |
|||
<files>src/store/workflowStore.ts, src/app/api/generate/route.ts</files> |
|||
<action> |
|||
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. |
|||
</action> |
|||
<verify> |
|||
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 |
|||
</verify> |
|||
<done> |
|||
- Execution maps normalized handle IDs to schema parameter names |
|||
- Provider APIs receive correct parameter names |
|||
- No regression in existing workflows |
|||
</done> |
|||
</task> |
|||
|
|||
</tasks> |
|||
|
|||
<verification> |
|||
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 |
|||
</verification> |
|||
|
|||
<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> |
|||
|
|||
<output> |
|||
After completion, create `.planning/phases/14-fix-drag-connect-bugs/14-01-SUMMARY.md` |
|||
</output> |
|||
@ -0,0 +1,109 @@ |
|||
--- |
|||
phase: 14-fix-drag-connect-bugs |
|||
plan: 01 |
|||
subsystem: ui |
|||
tags: [react-flow, handles, connections, node-editor] |
|||
|
|||
requires: |
|||
- phase: 03-generate-node-refactor |
|||
provides: Dynamic handle rendering from model schema |
|||
- phase: 04-model-search-dialog |
|||
provides: Model selection and schema loading |
|||
provides: |
|||
- Stable drag-connect node creation that persists through model selection |
|||
- Normalized handle ID system for multi-provider compatibility |
|||
- Handle-to-schema mapping for API parameter passing |
|||
affects: [future-node-types, connection-system-improvements] |
|||
|
|||
tech-stack: |
|||
added: [] |
|||
patterns: |
|||
- "Normalized handle IDs (image, text, image-0, text-0) for connection stability" |
|||
- "data-schema-name attribute for preserving API parameter names" |
|||
- "handleToSchemaName mapping in execution for API compatibility" |
|||
|
|||
key-files: |
|||
created: [] |
|||
modified: |
|||
- src/components/nodes/GenerateImageNode.tsx |
|||
- src/components/nodes/GenerateVideoNode.tsx |
|||
- src/components/WorkflowCanvas.tsx |
|||
- src/store/workflowStore.ts |
|||
|
|||
key-decisions: |
|||
- "Use normalized handle IDs instead of schema names for React Flow handles" |
|||
- "Store schema name in data-schema-name attribute for reference" |
|||
- "Build handleToSchemaName mapping at execution time from inputSchema" |
|||
|
|||
patterns-established: |
|||
- "Handle normalization: single input uses type name (image), multiple use indexed (image-0)" |
|||
- "Schema mapping: inputSchema drives normalized ID to schema name conversion" |
|||
|
|||
issues-created: [] |
|||
|
|||
duration: 7min |
|||
completed: 2026-01-12 |
|||
--- |
|||
|
|||
# Phase 14 Plan 01: Fix Drag-Connect Node Creation Bugs Summary |
|||
|
|||
**Placeholder handles ensure connections persist when selecting models that don't use all input types** |
|||
|
|||
## Performance |
|||
|
|||
- **Duration:** 12 min |
|||
- **Started:** 2026-01-12T10:11:43Z |
|||
- **Completed:** 2026-01-12T10:23:00Z |
|||
- **Tasks:** 3 |
|||
- **Files modified:** 4 |
|||
|
|||
## Accomplishments |
|||
- Always render "image" and "text" handles even when model schema doesn't include them |
|||
- Placeholder handles (dimmed at 30% opacity) preserve connections for models that don't use that input type |
|||
- Normalized dynamic handle IDs to use standard values ("image", "text") instead of schema-specific names |
|||
- Updated connection validation to return normalized handle IDs when finding compatible targets |
|||
- Added handle-to-schema mapping in execution to preserve API parameter compatibility |
|||
|
|||
## Task Commits |
|||
|
|||
Each task was committed atomically: |
|||
|
|||
1. **Task 1: Normalize handle IDs + placeholder handles** - `7548e5a` (fix) |
|||
2. **Task 2: Update connection validation** - `714b60b` (fix) |
|||
3. **Task 3: Map handles to schema names in execution** - `5643cb8` (feat) |
|||
|
|||
## Files Created/Modified |
|||
- `src/components/nodes/GenerateImageNode.tsx` - Placeholder handles for missing inputs, normalized IDs |
|||
- `src/components/nodes/GenerateVideoNode.tsx` - Same fix for video nodes |
|||
- `src/components/WorkflowCanvas.tsx` - findCompatibleHandle returns normalized IDs |
|||
- `src/store/workflowStore.ts` - getConnectedInputs builds handleToSchemaName mapping |
|||
|
|||
## Decisions Made |
|||
- **Placeholder handles**: Always render "image" and "text" handles, dimmed when model doesn't use them |
|||
- **Normalized handle naming**: Single input of type uses base name ("image"), multiple use indexed ("image-0", "image-1") |
|||
- **Schema name preservation**: Stored in data-schema-name attribute for debugging/reference |
|||
- **Execution mapping**: Build mapping at runtime from inputSchema rather than storing in edge data |
|||
|
|||
## Deviations from Plan |
|||
|
|||
### Auto-fixed Issues |
|||
|
|||
**1. [Rule 1 - Bug] Handle disappearance with text-to-image models** |
|||
- **Found during:** Testing after initial fix |
|||
- **Issue:** Text-to-image models (FLUX, etc.) have no image input in schema, causing image handle to disappear |
|||
- **Fix:** Always render placeholder handles for missing input types (dimmed at 30% opacity) |
|||
- **Files modified:** GenerateImageNode.tsx, GenerateVideoNode.tsx |
|||
- **Verification:** Build passes, handles persist through model selection |
|||
|
|||
## Issues Encountered |
|||
|
|||
None |
|||
|
|||
## Next Phase Readiness |
|||
- Phase 14 complete (single plan phase) |
|||
- Milestone v1.1 complete - all 8 phases finished |
|||
- Ready for `/gsd:complete-milestone` |
|||
|
|||
--- |
|||
*Phase: 14-fix-drag-connect-bugs* |
|||
*Completed: 2026-01-12* |
|||
Loading…
Reference in new issue