Skip to content

Make image model visibility provider-aware - #210

Merged
faetalize merged 9 commits into
mainfrom
feature/206-image-model-visibility
Jul 10, 2026
Merged

Make image model visibility provider-aware#210
faetalize merged 9 commits into
mainfrom
feature/206-image-model-visibility

Conversation

@faetalize

Copy link
Copy Markdown
Owner

Summary

  • Make image generation and editing selectors filter image models by provider route availability.
  • Export current API key and premium endpoint route state from the API key component.
  • Normalize saved image model settings against visible provider routes and guard image sends from hidden selections.
  • Add provider visibility and selector reactivity tests.

Tests

  • npm run lint
  • npm run type-check
  • npm run test:vitest -- tests/unit/models.test.ts tests/integration/settings/image-model-selectors.test.ts
  • npm run test:vitest -- tests/integration/messages/message-send.test.ts
  • npm run test

close #206

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploying zodiac with  Cloudflare Pages  Cloudflare Pages

Latest commit: acf709a
Status: ✅  Deploy successful!
Preview URL: https://1fa968d6.zodiac-c9y.pages.dev
Branch Preview URL: https://feature-206-image-model-visi.zodiac-c9y.pages.dev

View logs

@faetalize faetalize left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated multi-angle code review. Three confirmed correctness bugs share one root cause: every production IMAGE_MODELS entry is EDGE-only, yet EDGE availability is wired to the premium-preference checkbox (isPremiumEndpointToggleEnabled()) rather than actual edge/credit eligibility. As a result, any user with that toggle off — logged-in free-tier users who hold image credits, and paid users who simply disable it — now sees zero visible image models and is blocked from generating, where the old type === "all" credit check let them through. Separately, the new reconcile → synthetic changesaveSettings path persists "" over the user's saved image-model choice. Details are inline.

Note: I also checked the image-editing isImagePremiumEndpointPreferred shortcut (isImageEditingActive() || …). It is not currently triggerable (all editing models are EDGE-only, so validateVisibleImageModelSelection blocks first), but it would become a real routing bug if a non-EDGE editing model is ever added — worth a guarding comment.

Comment thread src/components/static/ApiKeyInput.component.ts Outdated
Comment thread src/components/static/ImageModelSelector.component.ts Outdated
Comment thread src/services/Settings.service.ts
Comment thread src/components/static/ImageEditModelSelector.component.ts Outdated
Comment thread src/components/static/ApiKeyInput.component.ts Outdated
Comment thread src/components/static/ImageEditModelSelector.component.ts Outdated
Comment thread src/components/static/ImageModelSelector.component.ts Outdated
Comment thread src/components/static/ImageEditModelSelector.component.ts
Comment thread src/services/Settings.service.ts Outdated
Comment thread tests/integration/settings/image-model-selectors.test.ts Outdated
@faetalize

Copy link
Copy Markdown
Owner Author

Reworked this in 4162669: replaced the provider-aware visibility filtering with a show-all + validate-at-send approach, driven by a pure route resolver (src/utils/imageModelRouting.ts), plus a second image-specific premium toggle (preferPremiumImageEndpoint) that is credit-gated (not pro-gated), with a hidden toggle counting as off.

This addresses the earlier review — mapping each finding:

# Finding Status
1 EDGE gated on the premium checkbox Resolved — routing now goes through the resolver; the image toggle is credit-gated, not pro-gated
2 Runtime preference wipe (synthetic change) Resolved — reconcile removed; selectors are static
3 Load-time preference wipe ("") Resolved — Settings.service falls back to DEFAULT, never ""
4 Phantom default in getSelectedEditingModel Resolved — no empty state; reverted to the simple form
5 switch with no default Resolved — that function was removed
6 ~64 lines duplicated across selectors Resolved — reconcile machinery deleted
7 Dead guard / rebuild churn Resolved — reconcile removed
8 getSelectableImageEditModels recomputed 3× Resolved — reverted
9 Settings.service import-contract widening Resolved — no longer imports ApiKeyInput
10 Test leaks window listeners Fixed — per-test afterEach cleanup added

The inline comments above are anchored to lines that were rewritten or deleted, so they should now show as outdated.

Replace the provider-aware visibility filtering with a show-all + validate-at-send approach driven by a pure route resolver.

- Add src/utils/imageModelRouting.ts: resolveImageModelRoute(model, preferEdge, availability) -> {route: edge|google|openrouter} | {route: null, reason}, strict (preferEdge = edge-only, else BYOK-only). Covered by unit tests.
- Add a second, image-specific premium toggle (preferPremiumImageEndpoint), credit-gated (not pro-gated) so free users with image credits keep access. A hidden toggle counts as off, so no-credit users route via BYOK instead of getting stranded on prefer-edge.
- Revert the image/image-edit selectors to static population; remove the reconcile machinery, synthetic change events, and the empty-state placeholder.
- Settings.service image-model fallbacks are validity-only again (never persist "").
- Message.service resolves the route at send time and warns with a reason-specific, actionable toast; the chat-model API-key gate no longer applies to image requests.
- Remove the now-dead imageModelVisibility util and update tests.

Resolves the correctness/cleanup findings from the earlier review (preference wipes, free-user lockout, duplication, widened import contract).
@faetalize
faetalize force-pushed the feature/206-image-model-visibility branch from 4162669 to 5221ab0 Compare July 9, 2026 12:04
@faetalize
faetalize merged commit a311d21 into main Jul 10, 2026
2 checks passed
@faetalize
faetalize deleted the feature/206-image-model-visibility branch July 10, 2026 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make image model UI visibility reactive to providers and user state

1 participant