# AI Configuration Refactor - Master Overview **Created:** January 4, 2026 **Goal:** Clean, unified AI configuration with single source of truth --- ## Documentation Files | File | Purpose | |------|---------| | [REFACTOR-OVERVIEW.md](REFACTOR-OVERVIEW.md) | This file - master overview | | [implementation-plan-for-ai-models-and-cost.md](implementation-plan-for-ai-models-and-cost.md) | Detailed implementation plan with schema changes | | [safe-migration-and-testing-plan.md](safe-migration-and-testing-plan.md) | Testing strategy and verification steps | --- ## What We're Fixing ### Current Problems 1. **Duplicate configuration sources** - `AIModelConfig` (database) has model definitions - `GlobalIntegrationSettings` (database) has hardcoded CHOICES duplicating the same info - `constants.py` has `MODEL_RATES` and `IMAGE_MODEL_RATES` hardcoded - Frontend `Settings.tsx` has hardcoded model choices 2. **Broken/inconsistent data** - `GlobalIntegrationSettings.runware_model = "bria:10@1"` but this model doesn't exist - `GlobalIntegrationSettings.openai_model = "gpt-4o-mini"` but default should be `gpt-5.1` 3. **API keys mixed with model config** - `GlobalIntegrationSettings` stores both API keys and model preferences - No separation of concerns - Can't easily extend to other integrations (email, payment, etc.) 4. **Credit calculation scattered** - `CreditCostConfig` for token-based operations - `ModelRegistry.calculate_cost()` for image costs - No clear per-model credit rate --- ## Target State ### Single Source of Truth ``` IntegrationProvider (NEW) ├── openai (api_key, active) ├── runware (api_key, active) ├── resend (api_key, active) ← future ├── stripe (api_key, webhook_secret, active) ← future └── ... AIModelConfig (ENHANCED) ├── Text Models │ ├── gpt-5.1 (is_default=true, tokens_per_credit=1000) │ ├── gpt-4o (tokens_per_credit=1000) │ └── gpt-4o-mini (tokens_per_credit=10000) └── Image Models ├── runware:97@1 (credits_per_image=1, quality_tier=basic) ├── dall-e-3 (is_default=true, credits_per_image=5, quality_tier=quality) └── google:4@2 (credits_per_image=15, quality_tier=premium) ``` ### No More Hardcoding - **Backend**: Remove `MODEL_RATES`, `IMAGE_MODEL_RATES` from constants.py - **Backend**: Remove hardcoded CHOICES from `GlobalIntegrationSettings` - **Backend**: `ModelRegistry` always uses database, no fallbacks - **Frontend**: Load model choices from API endpoint ### Clear Credit Calculation | Model Type | How Credits Calculated | |------------|----------------------| | Text | `ceil(total_tokens / tokens_per_credit)` from AIModelConfig | | Image | `credits_per_image * num_images` from AIModelConfig | --- ## Migration Phases Summary | Phase | What Changes | Risk | Rollback | |-------|--------------|------|----------| | 1 | Add new models/fields | None - additive only | Drop new tables | | 2 | Add parallel code paths | Low - old code untouched | Remove new methods | | 3 | IntegrationProvider for keys | Medium - API key loading | Revert key loading | | 4 | Switch to new credit calc | Medium - financial impact | Revert credit service | | 5 | Create API endpoint | None - new endpoint | Remove endpoint | | 6 | Update frontend | Low - UI only | Revert frontend | | 7 | Cleanup legacy code | High if bugs found | Restore from backup | **Rule:** Run full test suite after EACH phase before proceeding. --- ## Files Being Modified ### Backend Files | File | Changes | |------|---------| | `billing/models.py` | Add IntegrationProvider, add fields to AIModelConfig | | `ai/model_registry.py` | Add `get_default_model()`, remove constants fallback | | `ai/ai_core.py` | Use IntegrationProvider for API keys | | `ai/constants.py` | Remove MODEL_RATES, IMAGE_MODEL_RATES | | `billing/services/credit_service.py` | Model-based credit calculation | | `modules/system/global_settings_models.py` | Remove API keys, hardcoded choices | | `api/views/system.py` | Add `/api/v1/system/ai-models/` endpoint | ### Frontend Files | File | Changes | |------|---------| | `src/pages/Sites/Settings.tsx` | Load models from API, remove hardcodes | ### New Files | File | Purpose | |------|---------| | `tests/test_ai_system_integration.py` | Integration tests for migration | --- ## Credit Values (Final) ### Text Models (per 1 credit) | Model | Tokens per Credit | Example: 5000 tokens | |-------|-------------------|---------------------| | gpt-5.1 | 1,000 | 5 credits | | gpt-4o | 1,000 | 5 credits | | gpt-4o-mini | 10,000 | 1 credit | ### Image Models (per image) | Model | Credits per Image | UI Display | |-------|-------------------|------------| | runware:97@1 | 1 | "Basic (1 credit/image)" | | dall-e-3 | 5 | "Quality (5 credits/image)" | | google:4@2 | 15 | "Premium (15 credits/image)" | --- ## Execution Paths That Must Keep Working All these paths use the same AI functions and must work identically after migration: 1. **Manual Buttons** (Planner/Writer pages) - Cluster Keywords → `auto_cluster` - Generate Ideas → `generate_ideas` - Generate Content → `generate_content` - Extract Prompts → `generate_image_prompts` - Generate Images → `generate_images` 2. **Automation Manual Run** (Automation page → Run Now) - Same AI functions called via AutomationService 3. **Scheduled Automation** (Celery Beat scheduler) - Same AI functions called via scheduled tasks 4. **Direct Services** (Linker, Optimizer modules) - Use CreditService directly for credit deduction --- ## Success Criteria Migration is **COMPLETE** when: - [ ] All integration tests pass - [ ] All manual test checklist items pass - [ ] No errors in production logs for 1 week - [ ] Credit calculations match expected values - [ ] All execution paths work (manual, automation, scheduled) - [ ] Frontend loads models dynamically from API - [ ] No legacy code remains: - [ ] No `MODEL_RATES` / `IMAGE_MODEL_RATES` in constants.py - [ ] No API keys in `GlobalIntegrationSettings` - [ ] No hardcoded models in frontend - [ ] No fallback to constants in `ModelRegistry` - [ ] No unused fields in `GlobalIntegrationSettings` --- ## Quick Reference Commands ```bash # Run integration tests docker exec igny8_backend python manage.py test igny8_core.tests.test_ai_system_integration -v 2 # Check AIModelConfig docker exec igny8_backend python manage.py shell -c " from igny8_core.business.billing.models import AIModelConfig for m in AIModelConfig.objects.all().order_by('model_type'): print(f'{m.model_name}: {m.model_type}, default={m.is_default}') " # Check recent credit usage docker exec igny8_backend python manage.py shell -c " from igny8_core.business.billing.models import CreditUsageLog for log in CreditUsageLog.objects.order_by('-created_at')[:10]: print(f'{log.operation_type}: {log.credits_used} credits') " # Check account credits docker exec igny8_backend python manage.py shell -c " from igny8_core.auth.models import Account for acc in Account.objects.all(): print(f'{acc.name}: {acc.credits} credits') " ```