14 KiB
Image Studio Editing Feature Implementation Plan
Status: 📋 PLANNED - Ready for Phase 2 Implementation
Based On: Architecture Proposal, Enhancement Proposal, Code Patterns Reference
Timeline: Week 2 (Phase 2)
🎯 Implementation Goals
- ✅ Add
generate_image_edit()tomain_image_generation.py(reuses Phase 1 helpers) - ✅ Create
ImageEditProviderprotocol following existing pattern - ✅ Create
WaveSpeedEditProviderwith 14 editing models - ✅ Refactor
EditStudioServiceto use unified entry point - ✅ Add model selection UI to frontend
- ✅ Ensure backward compatibility with existing Stability AI editing
📋 Step-by-Step Implementation Plan
Step 1: Extend Provider Protocol (Day 1)
File: backend/services/llm_providers/image_generation/base.py
Action: Add ImageEditProvider protocol following ImageGenerationProvider pattern
class ImageEditProvider(Protocol):
"""Protocol for image editing providers."""
def edit(
self,
image_base64: str,
prompt: str,
operation: str,
options: ImageEditOptions
) -> ImageGenerationResult:
...
Benefits:
- ✅ Consistent with existing
ImageGenerationProviderpattern - ✅ Easy to add new editing providers later
- ✅ Type-safe interface
Step 2: Create ImageEditOptions Dataclass (Day 1)
File: backend/services/llm_providers/image_generation/base.py
Action: Add ImageEditOptions dataclass for editing operations
@dataclass
class ImageEditOptions:
image_base64: str
prompt: str
operation: str # "general_edit", "inpaint", "outpaint", etc.
mask_base64: Optional[str] = None
negative_prompt: Optional[str] = None
model: Optional[str] = None
width: Optional[int] = None
height: Optional[int] = None
guidance_scale: Optional[float] = None
steps: Optional[int] = None
seed: Optional[int] = None
extra: Optional[Dict[str, Any]] = None
Step 3: Create WaveSpeedEditProvider (Day 2-3)
File: backend/services/llm_providers/image_generation/wavespeed_edit_provider.py
Action: Create provider following WaveSpeedImageProvider pattern
Key Features:
- ✅ Reuses
WaveSpeedClient- Same client as generation - ✅ Model Registry -
SUPPORTED_MODELSdict with 14 models - ✅ Cost Calculation - Model-specific costs
- ✅ Validation - Model and parameter validation
- ✅ Error Handling - Consistent error patterns
Models to Support (14 total):
-
Budget Tier ($0.02-$0.03):
qwen-image/edit- $0.02qwen-image/edit-plus- $0.02step1x-edit- $0.03hidream-e1-full- $0.024bytedance/seededit-v3- $0.027
-
Mid Tier ($0.035-$0.04):
alibaba/wan-2.5/image-edit- $0.035flux-kontext-pro- $0.04flux-kontext-pro/multi- $0.04
-
Premium Tier ($0.08-$0.15):
flux-kontext-max- $0.08ideogram-character- $0.10-$0.20google/nano-banana-pro/edit-ultra- $0.15 (4K) / $0.18 (8K)
-
Variable Pricing:
openai/gpt-image-1- $0.011-$0.250 (quality-based)
-
Specialized:
z-image-turbo-inpaint- $0.02 (inpainting)image-zoom-out- $0.02 (outpainting)
Implementation Pattern:
class WaveSpeedEditProvider(ImageEditProvider):
"""WaveSpeed AI image editing provider - REUSES client pattern."""
SUPPORTED_MODELS = {
"qwen-edit": {
"model_path": "wavespeed-ai/qwen-image/edit",
"cost": 0.02,
"max_resolution": (2048, 2048),
"capabilities": ["general_edit", "style_transfer"],
},
# ... 13 more models
}
def __init__(self, api_key: Optional[str] = None):
self.client = WaveSpeedClient(api_key=api_key) # ✅ REUSE client
def edit(self, image_base64: str, prompt: str, operation: str, options: ImageEditOptions) -> ImageGenerationResult:
# ✅ REUSES same client call pattern
model_info = self.SUPPORTED_MODELS.get(options.model)
image_bytes = self.client.edit_image(
model=model_info["model_path"],
image_base64=image_base64,
prompt=prompt,
**options.to_dict()
)
# ✅ REUSES same result format
return ImageGenerationResult(...)
Step 4: Add generate_image_edit() Function (Day 4)
File: backend/services/llm_providers/main_image_generation.py
Action: Add unified entry point for editing operations
Key Features:
- ✅ Reuses
_validate_image_operation()helper (Phase 1) - ✅ Reuses
_track_image_operation_usage()helper (Phase 1) - ✅ Provider routing - Routes to appropriate provider
- ✅ Standardized returns -
ImageGenerationResult - ✅ Error handling - Consistent error patterns
Implementation:
def generate_image_edit(
image_base64: str,
prompt: str,
operation: str = "general_edit",
model: Optional[str] = None,
options: Optional[Dict[str, Any]] = None,
user_id: Optional[str] = None
) -> ImageGenerationResult:
"""
Generate edited image - REUSES validation and tracking helpers.
Args:
image_base64: Base64-encoded input image
prompt: Edit instruction prompt
operation: Type of edit operation
model: Model ID to use (default: auto-select)
options: Additional options (mask, negative_prompt, etc.)
user_id: User ID for validation and tracking
Returns:
ImageGenerationResult with edited image
"""
# 1. REUSE: Validation helper
_validate_image_operation(
user_id=user_id,
operation_type="image-edit",
num_operations=1,
log_prefix="[Image Edit]"
)
# 2. Get provider (REUSES provider pattern)
provider = _get_edit_provider(model or "wavespeed")
# 3. Prepare options
edit_options = ImageEditOptions(
image_base64=image_base64,
prompt=prompt,
operation=operation,
**options or {}
)
# 4. Edit
result = provider.edit(edit_options)
# 5. REUSE: Tracking helper
if user_id and result and result.image_bytes:
_track_image_operation_usage(
user_id=user_id,
provider=result.provider,
model=result.model,
operation_type="image-edit",
result_bytes=result.image_bytes,
cost=result.metadata.get("estimated_cost", 0.0),
prompt=prompt,
endpoint="/image-generation/edit",
metadata=result.metadata,
log_prefix="[Image Edit]"
)
return result
Step 5: Add Provider Selection Helper (Day 4)
File: backend/services/llm_providers/main_image_generation.py
Action: Add _get_edit_provider() helper following _get_provider() pattern
def _get_edit_provider(provider_name: str):
"""Get editing provider instance.
Args:
provider_name: Provider name ("wavespeed", "stability", etc.)
Returns:
ImageEditProvider instance
"""
if provider_name == "wavespeed":
return WaveSpeedEditProvider()
elif provider_name == "stability":
# Keep existing Stability editing support
return StabilityEditProvider() # If exists, or wrap existing
else:
raise ValueError(f"Unknown edit provider: {provider_name}")
Step 6: Refactor EditStudioService (Day 5)
File: backend/services/image_studio/edit_service.py
Action: Update to use unified generate_image_edit() entry point
Changes:
- ✅ Remove direct provider calls - Use unified entry point
- ✅ Keep existing operations - Stability AI operations still work
- ✅ Add WaveSpeed model selection - New models available
- ✅ Maintain backward compatibility - Existing API unchanged
Implementation:
# In EditStudioService.process_edit()
# For WaveSpeed models
if request.provider == "wavespeed" or (request.provider is None and request.model and request.model.startswith("wavespeed")):
from services.llm_providers.main_image_generation import generate_image_edit
result = generate_image_edit(
image_base64=request.image_base64,
prompt=request.prompt or "",
operation=request.operation,
model=request.model,
options={
"mask_base64": request.mask_base64,
"negative_prompt": request.negative_prompt,
# ... other options
},
user_id=user_id
)
image_bytes = result.image_bytes
else:
# Keep existing Stability AI editing logic
image_bytes = await self._handle_stability_edit(...)
Step 7: Update API Endpoint (Day 5)
File: backend/routers/image_studio.py
Action: Add model parameter to edit endpoint
Changes:
- ✅ Add
modelparameter to request schema - ✅ Pass model to
EditStudioService - ✅ Maintain backward compatibility (model optional)
Step 8: Frontend Model Selector (Day 6-7)
File: frontend/src/components/ImageStudio/EditStudio.tsx
Action: Add model selection UI
Features:
- ✅ Model Dropdown - List all 14 editing models
- ✅ Cost Display - Show cost per model
- ✅ Quality Tiers - Group by Budget/Mid/Premium
- ✅ Smart Recommendations - Auto-suggest based on operation type
- ✅ Side-by-Side Comparison - Compare different models (optional)
UI Components:
<ModelSelector
models={editingModels}
selectedModel={selectedModel}
onModelChange={setSelectedModel}
showCost={true}
showQuality={true}
recommendations={getRecommendations(operation)}
/>
Step 9: Testing & Verification (Day 8-10)
Test Cases:
- ✅ All 14 models work - Test each model with sample edits
- ✅ Validation works - Pre-flight validation for editing
- ✅ Tracking works - Usage tracking for editing operations
- ✅ Error handling - Invalid models, API failures, etc.
- ✅ Backward compatibility - Existing Stability editing still works
- ✅ Frontend integration - Model selector works correctly
- ✅ Cost calculation - Correct costs tracked per model
📊 Implementation Checklist
Backend
- Add
ImageEditProviderprotocol tobase.py - Add
ImageEditOptionsdataclass tobase.py - Create
WaveSpeedEditProviderclass - Add 14 editing models to
SUPPORTED_MODELS - Implement
edit()method for each model - Add
generate_image_edit()tomain_image_generation.py - Add
_get_edit_provider()helper - Refactor
EditStudioServiceto use unified entry - Update API endpoint to accept
modelparameter - Test all 14 models
Frontend
- Add model selector component
- Update
EditStudio.tsxwith model dropdown - Add cost display per model
- Add quality tier grouping
- Add smart recommendations
- Test model selection flow
Documentation
- Update API documentation
- Add model comparison guide
- Update user documentation
🎯 Success Criteria
- ✅ All 14 WaveSpeed editing models integrated
- ✅ Unified entry point -
generate_image_edit()works - ✅ Reuses Phase 1 helpers - Validation and tracking
- ✅ Backward compatible - Existing Stability editing works
- ✅ Frontend model selection - Users can choose models
- ✅ Cost tracking - Correct costs tracked per model
- ✅ No regressions - All existing functionality works
📝 Files to Create/Modify
New Files
backend/services/llm_providers/image_generation/wavespeed_edit_provider.py
Modified Files
backend/services/llm_providers/image_generation/base.py- Add protocol and optionsbackend/services/llm_providers/main_image_generation.py- Addgenerate_image_edit()backend/services/image_studio/edit_service.py- Use unified entrybackend/routers/image_studio.py- Add model parameterfrontend/src/components/ImageStudio/EditStudio.tsx- Add model selector
🔄 Integration with Existing Code
Reuses Phase 1 Helpers
- ✅
_validate_image_operation()- Pre-flight validation - ✅
_track_image_operation_usage()- Usage tracking
Follows Existing Patterns
- ✅ Provider protocol pattern (like
ImageGenerationProvider) - ✅ Model registry pattern (like
WaveSpeedImageProvider.SUPPORTED_MODELS) - ✅ Client reuse pattern (uses
WaveSpeedClient) - ✅ Result format pattern (returns
ImageGenerationResult)
Maintains Compatibility
- ✅ Existing Stability AI editing still works
- ✅ API endpoints backward compatible
- ✅ Frontend components work with or without model selection
🚀 Timeline
- Day 1: Protocol and options dataclass
- Day 2-3: WaveSpeedEditProvider with all 14 models
- Day 4:
generate_image_edit()function - Day 5: Refactor EditStudioService
- Day 6-7: Frontend model selector
- Day 8-10: Testing and bug fixes
Total: ~10 days (2 weeks with buffer)
📚 Related Documentation
- Image Studio Architecture Proposal
- Image Studio Enhancement Proposal
- WaveSpeed Models Reference
- Code Patterns Reference
- Phase 1 Implementation Summary
Ready for Phase 2 Implementation - Editing Feature