Google AI Studio defaults to 50 models per page. Set pageSize=1000
to maximize per-page results and follow nextPageToken to fetch all
available models across pages. Also fixes query param separator when
base URL already contains query string.
Replace inline `provider === "gemini"` checks in chatCore.ts and auth.ts
with shared hasPerModelQuota() and lockModelIfPerModelQuota() from
accountFallback.ts. Also adds max-cooldown preservation to lockModel()
to prevent race conditions from overwriting longer lockouts.
isModelLocked() was called to lock models on 429 but never checked
when selecting connections. Requests to a locked model would still
route to it, causing unnecessary repeated 429s.
Gemini AI Studio enforces per-model quotas. Previously a 429 on
gemini-2.5-pro would mark the entire connection as credits_exhausted,
blocking all models on that API key.
Three-layer fix:
- chatCore: lock model only (not connection) for RATE_LIMITED and
QUOTA_EXHAUSTED errors from Gemini
- auth: early-return with model-only lockout before terminal status
check, so credits_exhausted is never set on the connection
- rateLimitManager: use model-scoped limiter keys for Gemini so the
Bottleneck queue pauses only the affected model, not the connection
- chat: skip markAccountExhaustedFrom429 for Gemini (per-model quotas)
Gemini AI Studio has per-model quota limits. When one model hits its
quota (429), other models on the same API key may still be available.
- Use lockModel() for 429s on Gemini (model-only lockout, connection
stays active for other models)
- Skip markAccountExhaustedFrom429 for Gemini (prevents deprioritizing
the entire connection in credential selection)
- Apply model-only 404 lockout for Gemini too (deprecated/unavailable
models shouldn't disable the provider)
Match reset() behavior — clear lastFailureTime when recovering from
OPEN state to avoid stale timestamps in persisted state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Show import progress dialog when adding Gemini API key with model
list, completion status, and Close button
- Remove hardcoded Gemini model registry — models come exclusively
from Google API sync per API key
- Hide "Import from /models" button for Gemini (sync handles it)
- Remove server-side fire-and-forget auto-sync (client handles it)
- Categorize synced Gemini models by endpoint type in catalog:
embedding, image, and audio (transcription + speech)
- Add modelsImported and close i18n keys to all 33 languages
Combo handlers call _onSuccess()/_onFailure() directly instead of
execute(), bypassing the OPEN→HALF_OPEN→CLOSED transition. After
resetTimeout elapses, canExecute() returns true and requests flow
through, but _onSuccess() only reset failureCount without changing
state — leaving the breaker permanently OPEN with 0 failures.
Handle OPEN state in both methods: _onSuccess() now transitions
OPEN→CLOSED, _onFailure() skips redundant re-transition.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-sync is fire-and-forget on the server, so the dashboard needs to
poll for model updates after saving a Gemini key (3s delay). On delete,
refresh models immediately since DB cleanup is synchronous.
Removed hardcoded registry fallback for Gemini in dashboard, catalog,
and v1beta endpoints. Without synced models (no API keys), Gemini shows
nothing. Hardcoded entries are always removed from v1beta regardless
of sync result.
Store synced models keyed by providerId:connectionId so each API key's
models are tracked separately. On read, union across all connections.
On connection delete, remove only that key's models. Models with no
remaining connections are automatically excluded.
Add 9 new API-key providers for image, video, and media generation:
- Replicate (rep/) — ML model marketplace with passthrough models
- fal.ai (fal/) — fast inference for generative media
- Novita AI (novita/) — image/video generation platform
- Segmind (seg/) — image generation models
- Runware (rw/) — real-time image generation
- WaveSpeed AI (ws/) — fast media generation
- PiAPI (pi/) — multi-model API gateway
- GoAPI (ggo/) — aggregated AI API access
- LaoZhang AI (lz/) — multi-provider proxy
These providers support image/video/audio endpoints natively via
OpenAI-compatible format, solving the gap where only chat-focused
providers were registered.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Align CacheTrends interface with API response (cachedRequests instead of hits/misses/hitRate)
- Update bar chart rendering to use cachedRequests field from getCacheTrend()
- Remove duplicate CacheStatsCard from cache overview (already in settings AI tab)
- Fix tooltip to use i18n translations instead of hardcoded English
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Add "memory" and "skills" entries to HIDEABLE_SIDEBAR_ITEM_IDS and PRIMARY_SIDEBAR_ITEMS
- Add sidebar translation keys for memory and skills pages
- Add complete "memory" and "skills" i18n sections to en.json with all UI labels
- Replace all hardcoded English text in memory/page.tsx with useTranslations() calls
Memory and Skills pages now appear in the sidebar and render with proper i18n support.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>