diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index a2b0cdc5..8dd7faf6 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -12,7 +12,7 @@ None - ✅ **v1.0 Multi-Provider Support** - Phases 1-6 (shipped 2026-01-11) - ✅ **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 @@ -268,7 +268,7 @@ Plans: **Depends on**: Phase 20 **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 -**Plans**: TBD +**Plans**: 1 plan **Issues:** 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 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 @@ -295,10 +295,25 @@ Plans: Plans: - [ ] 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 **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 | |-------|-----------|----------------|--------|-----------| @@ -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 | | 19. Type Refactoring | 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 | - | +| 23. Model Browser Improvements | v1.2 | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 21414726..0c14c569 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -9,10 +9,10 @@ See: .planning/PROJECT.md (updated 2026-01-09) ## Current Position -Phase: 18 of 22 (API Route Tests) -Plan: 5 of 5 in current phase -Status: Phase complete -Last activity: 2026-01-13 - Completed 18-05-PLAN.md +Phase: 21 of 23 (Fix Image Input & Deduplication) +Plan: 1 of 1 in current phase +Status: Planned +Last activity: 2026-01-13 - Created 21-01-PLAN.md Progress: █████████░ 93% @@ -124,10 +124,11 @@ Recent decisions affecting current work: - 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 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 Last session: 2026-01-13 -Stopped at: Phase 22 planned (1 plan created) +Stopped at: Phase 21 planned (1 plan created) 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) diff --git a/.planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md b/.planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md new file mode 100644 index 00000000..6e65b31f --- /dev/null +++ b/.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 +--- + + +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. + + + +~/.claude/get-shit-done/workflows/execute-phase.md +~/.claude/get-shit-done/templates/summary.md +~/.claude/get-shit-done/references/checkpoints.md + + + +@.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 + + + + + + Task 1: Fix Gemini image-to-image part ordering + src/app/api/generate/route.ts + +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. + + +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. + + +When images are connected to a Gemini GenerateImage node, the generated output incorporates/transforms the input image based on the prompt. + + + + + Task 2: Unify image hashing to MD5 across all save operations + src/utils/imageStorage.ts + +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. + + +Build succeeds with `npm run build`. TypeScript types check with no errors. + + +imageStorage.ts uses MD5 hashing, consistent with save-generation API. Same image saved twice gets same hash and is deduplicated. + + + + + +Fixed Gemini image-to-image generation (part ordering) and unified MD5 hashing for deduplication. + + + 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 + + Type "approved" if image-to-image works correctly, or describe issues + + + + + +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 + + + +- 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) + + + +After completion, create `.planning/phases/21-fix-image-input-deduplication/21-01-SUMMARY.md` +