Browse Source

docs(21): create phase plan

Phase 21: Fix Image Input & Deduplication Issues
- 1 plan created
- 2 tasks + 1 checkpoint defined
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 6 months ago
parent
commit
0161a823dc
  1. 26
      .planning/ROADMAP.md
  2. 13
      .planning/STATE.md
  3. 153
      .planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md

26
.planning/ROADMAP.md

@ -12,7 +12,7 @@ None
- ✅ **v1.0 Multi-Provider Support** - Phases 1-6 (shipped 2026-01-11) - ✅ **v1.0 Multi-Provider Support** - Phases 1-6 (shipped 2026-01-11)
- ✅ **v1.1 Improvements** - Phases 7-14 (shipped 2026-01-12) - ✅ **v1.1 Improvements** - Phases 7-14 (shipped 2026-01-12)
- 🚧 **v1.2 Improvements** - Phases 15-22 (in progress) - 🚧 **v1.2 Improvements** - Phases 15-23 (in progress)
## Phases ## Phases
@ -268,7 +268,7 @@ Plans:
**Depends on**: Phase 20 **Depends on**: Phase 20
**Research**: Likely (Gemini API image input handling, current hashing implementation) **Research**: Likely (Gemini API image input handling, current hashing implementation)
**Research topics**: Gemini 3 Pro image generation API requirements, why image inputs are ignored, current save logic for inputs vs generations **Research topics**: Gemini 3 Pro image generation API requirements, why image inputs are ignored, current save logic for inputs vs generations
**Plans**: TBD **Plans**: 1 plan
**Issues:** **Issues:**
1. nano-banana-pro model generates without considering image inputs (image data sent but not used) 1. nano-banana-pro model generates without considering image inputs (image data sent but not used)
@ -276,7 +276,7 @@ Plans:
3. Generated images should be prepended with prompt details like generated videos 3. Generated images should be prepended with prompt details like generated videos
Plans: Plans:
- [ ] 21-01: TBD (run /gsd:plan-phase 21 to break down) - [ ] 21-01: Fix Gemini image-to-image part ordering and unify MD5 hashing
#### Phase 22: Generate Node Dynamic Input Tests #### Phase 22: Generate Node Dynamic Input Tests
@ -295,10 +295,25 @@ Plans:
Plans: Plans:
- [ ] 22-01: ModelParameters tests, GenerateImageNode/GenerateVideoNode dynamic handle tests - [ ] 22-01: ModelParameters tests, GenerateImageNode/GenerateVideoNode dynamic handle tests
#### Phase 23: Model Browser Improvements
**Goal**: Improve model browser UX with recently used models section, icon-based provider dropdown with Gemini, and include Gemini models in browse list
**Depends on**: Phase 22
**Research**: Unlikely (existing UI patterns)
**Plans**: TBD
**Features:**
1. Recently used models section at top of browse dialog showing last 4 models used
2. Provider dropdown uses icons instead of text, add Gemini to the provider list
3. Include Gemini models (nano-banana, nano-banana-pro) in the browsable model list alongside Replicate/fal.ai models
Plans:
- [ ] 23-01: TBD (run /gsd:plan-phase 23 to break down)
## Progress ## Progress
**Execution Order:** **Execution Order:**
Phases execute in numeric order: 1 → 2 → ... → 14 → 15 → 16 → 17 → 18 → 19 → 20 → 21 → 22 Phases execute in numeric order: 1 → 2 → ... → 14 → 15 → 16 → 17 → 18 → 19 → 20 → 21 → 22 → 23
| Phase | Milestone | Plans Complete | Status | Completed | | Phase | Milestone | Plans Complete | Status | Completed |
|-------|-----------|----------------|--------|-----------| |-------|-----------|----------------|--------|-----------|
@ -322,5 +337,6 @@ Phases execute in numeric order: 1 → 2 → ... → 14 → 15 → 16 → 17 →
| 18. API Route Tests | v1.2 | 5/5 | Complete | 2026-01-13 | | 18. API Route Tests | v1.2 | 5/5 | Complete | 2026-01-13 |
| 19. Type Refactoring | v1.2 | 0/? | Not started | - | | 19. Type Refactoring | v1.2 | 0/? | Not started | - |
| 20. Integration Tests | v1.2 | 0/? | Not started | - | | 20. Integration Tests | v1.2 | 0/? | Not started | - |
| 21. Fix Image Input & Deduplication | v1.2 | 0/? | Not started | - | | 21. Fix Image Input & Deduplication | v1.2 | 0/1 | Planned | - |
| 22. Generate Node Dynamic Input Tests | v1.2 | 0/1 | Planned | - | | 22. Generate Node Dynamic Input Tests | v1.2 | 0/1 | Planned | - |
| 23. Model Browser Improvements | v1.2 | 0/? | Not started | - |

13
.planning/STATE.md

@ -9,10 +9,10 @@ See: .planning/PROJECT.md (updated 2026-01-09)
## Current Position ## Current Position
Phase: 18 of 22 (API Route Tests) Phase: 21 of 23 (Fix Image Input & Deduplication)
Plan: 5 of 5 in current phase Plan: 1 of 1 in current phase
Status: Phase complete Status: Planned
Last activity: 2026-01-13 - Completed 18-05-PLAN.md Last activity: 2026-01-13 - Created 21-01-PLAN.md
Progress: █████████░ 93% Progress: █████████░ 93%
@ -124,10 +124,11 @@ Recent decisions affecting current work:
- Milestone v1.2 Improvements created: 6 phases (Phase 15-20), testing and modularization - Milestone v1.2 Improvements created: 6 phases (Phase 15-20), testing and modularization
- Phase 21 added: Fix Gemini Pro image input handling and image deduplication issues - Phase 21 added: Fix Gemini Pro image input handling and image deduplication issues
- Phase 22 added: Generate node dynamic input validation and API call tests - Phase 22 added: Generate node dynamic input validation and API call tests
- Phase 23 added: Model browser improvements (recently used, icon dropdown, Gemini models in list)
## Session Continuity ## Session Continuity
Last session: 2026-01-13 Last session: 2026-01-13
Stopped at: Phase 22 planned (1 plan created) Stopped at: Phase 21 planned (1 plan created)
Resume file: None Resume file: None
Next action: Execute Phase 22 (run /gsd:execute-plan .planning/phases/22-generate-node-dynamic-input-tests/22-01-PLAN.md) Next action: Execute Phase 21 (run /gsd:execute-plan .planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md)

153
.planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md

@ -0,0 +1,153 @@
---
phase: 21-fix-image-input-deduplication
plan: 01
type: execute
---
<objective>
Fix Gemini nano-banana-pro model ignoring image inputs and resolve duplicate image saving across input/generated images.
Purpose: Ensure image-to-image generation works correctly with Gemini and that the deduplication system consistently prevents duplicate files in the generations folder.
Output: Working image-to-image generation with Gemini Pro, consistent hashing across all image saving operations.
</objective>
<execution_context>
~/.claude/get-shit-done/workflows/execute-phase.md
~/.claude/get-shit-done/templates/summary.md
~/.claude/get-shit-done/references/checkpoints.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
# Key source files:
@src/app/api/generate/route.ts
@src/app/api/save-generation/route.ts
@src/utils/imageStorage.ts
# Prior phase with related hashing decision:
@.planning/phases/13-fix-duplicate-generations/13-01-SUMMARY.md
**Tech stack available:** Next.js 16, Zustand, @google/genai SDK
**Established patterns:** MD5 content hashing for deduplication (Phase 13)
**Issues being addressed:**
1. nano-banana-pro model generates without considering image inputs (image data sent but not used)
2. Input and generated images have duplicate files despite different hashes - need consistent hashing approach
3. Generated images should be prepended with prompt details like generated videos
**Research findings:**
- Gemini SDK docs show that for image editing, the order matters: image should come BEFORE text in the parts array
- Current implementation sends [text, ...images] but should send [...images, text] for image-to-image
- imageStorage.ts uses position-based sampling hash while save-generation uses MD5 - these are incompatible
</context>
<tasks>
<task type="auto">
<name>Task 1: Fix Gemini image-to-image part ordering</name>
<files>src/app/api/generate/route.ts</files>
<action>
In generateWithGemini(), change the requestParts array construction to place images BEFORE text prompt. The Gemini SDK documentation shows image editing works with [inlineData, text] order, not [text, inlineData].
Current code (around line 59):
```
const requestParts = [
{ text: prompt }, // Text first - WRONG for image-to-image
...imageData.map(...) // Images second
];
```
Change to:
```
const requestParts = [
...imageData.map(...) // Images first - correct for image editing
{ text: prompt }, // Text second
];
```
WHY: Gemini's image generation models treat the first content type as primary input. For text-to-image, text should be first. For image-to-image (editing), images should be first so the model knows it's modifying existing images.
IMPORTANT: Only reorder when images are present. If no images, text should still be the only part.
</action>
<verify>
Build succeeds with `npm run build`. Manual test: Create workflow with ImageInput → GenerateImage (nano-banana-pro) → Output, connect an image, add prompt like "make it blue", run workflow. Output should visually reference the input image.
</verify>
<done>
When images are connected to a Gemini GenerateImage node, the generated output incorporates/transforms the input image based on the prompt.
</done>
</task>
<task type="auto">
<name>Task 2: Unify image hashing to MD5 across all save operations</name>
<files>src/utils/imageStorage.ts</files>
<action>
Replace the position-based sampling hash in imageStorage.ts with MD5 content hashing (matching save-generation/route.ts pattern).
The current approach at line 209-211 uses a weak hash based on string length and sampled substrings:
```
const hash = `${folder}-${len}-${imageData.substring(50, 100)}-${imageData.substring(mid, mid + 50)}-${imageData.substring(Math.max(0, len - 50))}`;
```
This is problematic because:
1. Different hash method than save-generation API (MD5)
2. Same image can get different hashes if saved via different paths
3. Position-based sampling is weak for dedup (similar images may have same samples)
Replace with:
1. Import crypto at top: `import crypto from "crypto";`
2. Create helper: `function computeContentHash(data: string): string { return crypto.createHash("md5").update(data).digest("hex"); }`
3. Replace the hash computation: `const hash = `${folder}-${computeContentHash(imageData)}`;` (folder prefix still needed to separate inputs/generations)
WHY: MD5 is already used in save-generation (Phase 13 decision), provides reliable deduplication, and is fast enough for our use case.
</action>
<verify>
Build succeeds with `npm run build`. TypeScript types check with no errors.
</verify>
<done>
imageStorage.ts uses MD5 hashing, consistent with save-generation API. Same image saved twice gets same hash and is deduplicated.
</done>
</task>
<task type="checkpoint:human-verify" gate="blocking">
<what-built>
Fixed Gemini image-to-image generation (part ordering) and unified MD5 hashing for deduplication.
</what-built>
<how-to-verify>
1. Run: `npm run dev`
2. Create a new workflow with:
- ImageInput node (load any test image)
- GenerateImage node (select nano-banana-pro model)
- Prompt node with text like "add a sunset background" or "make it black and white"
- Output node
3. Connect: ImageInput → GenerateImage (image handle), Prompt → GenerateImage (text handle)
4. Run the workflow
5. Verify: The generated image should visually show the transformation applied to the input image (not a completely new unrelated image)
6. Check generations folder: No duplicate files for the same generated content
</how-to-verify>
<resume-signal>Type "approved" if image-to-image works correctly, or describe issues</resume-signal>
</task>
</tasks>
<verification>
Before declaring phase complete:
- [ ] `npm run build` succeeds without errors
- [ ] `npm test` passes all existing tests
- [ ] Gemini image-to-image generation produces output that transforms the input image
- [ ] No TypeScript errors in modified files
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- Image-to-image generation with nano-banana-pro produces visually related output
- Deduplication uses consistent MD5 hashing across all image save paths
- No regression in text-to-image generation (still works when no image connected)
</success_criteria>
<output>
After completion, create `.planning/phases/21-fix-image-input-deduplication/21-01-SUMMARY.md`
</output>
Loading…
Cancel
Save