Skip to content

fix(settings): accept the image model a signed-in vendor account offers - #1455

Merged
vastsa merged 1 commit into
mainfrom
fix/image-model-selection
Oct 7, 2026
Merged

vastsa merged 1 commit into
mainfrom
fix/image-model-selection

Conversation

@vastsa

@vastsa vastsa commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Problem

Settings > Models > Image generation model lists the image model a signed-in
ChatGPT (Codex) account answers with (gpt-image-2.5, gpt-image-2), but
picking one saved nothing: no toast, no write, and the menu stayed at its
placeholder.

Root cause

A vendor account's image model is deliberately never stored in
provider.models — the account's chat routes do not serve it — so it reaches
the picker only through vendorAccountImageCandidates(). The picker row
composed its options from the stored candidate list plus those vendor
candidates, while setImageGenerationDefault validated the choice against the
stored list alone. With no candidate list stored yet (a fresh install),
settings.imageGenerationModels contributes nothing, isImageCandidate
returned false, and the handler returned silently.

Reproduced against a local data dir holding a signed-in OpenAI (ChatGPT Plus/Pro) row (vendorKey: openai-codex, authKind: oauth, credential
present) and imageGeneration: null:

before, candidates = []
before, gpt-image-2.5 accepted = false
after,  candidates = [{providerId: <account>, modelId: "gpt-image-2.5"}, {... "gpt-image-2"}]
after,  gpt-image-2.5 offered and available = true

Change

  • components/settings/image-generation-default.ts: new
    imageGenerationPickerCandidates(stored, active, providers) — the single
    composition of stored candidates, the legacy single-binding fallback, and a
    signed-in vendor account's image model — plus
    isImageGenerationPickerCandidate.
  • ImageGenerationModelRow.tsx: renders its options from that helper.
  • ModelConfigPage.tsx: validates the choice against the very same list, and
    the chat-model exclusion reuses one membership predicate instead of a local
    copy of the same rule.
  • Tests: the candidate list is pinned (vendor account offered, signed-out
    account and other vendors refused, an explicitly cleared list is not
    resurrected, the legacy fallback still applies) and a contract test holds the
    row and the page to the same helper. Two stale source assertions were updated.

No other behavior changes: an explicitly cleared candidate list still does not
come back, a missing list still falls back to the legacy single binding, and
the row's availability rules are untouched.

Verification

Task-candidate run in the dedicated worktree on 278e929ca (origin/main):

  • node --test test/*.test.mjs (apps/desktop) → 3591 pass / 0 fail
  • tsc -p tsconfig.json --noEmit (apps/desktop) → clean
  • check-style-tokens, biome lint, check-architecture,
    check-agent-policy-sync, check-release-docs, check:pr-base → pass
  • electron-vite build → OK

Not run: UI E2E (verify:ui:*); the change is renderer-only and the affected
surface is covered by the tests above.

Choosing the image model a ChatGPT (Codex) account offers under Settings >
Models > Image generation model saved nothing. The picker row composed its
options from the stored candidate list plus the image model a signed-in
vendor account answers with, while the settings page validated the choice
against the stored list alone. That list never contains a vendor account's
image model — it is not one of the provider's chat models — so the choice
was refused and the handler returned silently: no toast, no write, a menu
that looked inert.

The offer and the acceptance now read one list, composed by
imageGenerationPickerCandidates, and one membership rule decides candidate
identity for both the picker and the chat-model exclusion. Nothing else
changes: an explicitly cleared candidate list is still not resurrected, a
missing list still falls back to the legacy single binding, and a
signed-out account or another vendor still offers no image model.
Copilot AI balanced review requested due to automatic review settings October 7, 2026 14:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@vastsa
vastsa merged commit e84dc23 into main Oct 7, 2026
5 checks passed

This branch was previously deployed

1 inactive deployment
Preview — a528c26e Deployed Oct 7, 2026 by vercel[bot]
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.

2 participants