Skip to content

gui: a model the Settings pick has to be one magpie serves - #1073

Open
TryWorld2026 wants to merge 2 commits into
yetone:mainfrom
TryWorld2026:fix/settings-model-must-be-served
Open

TryWorld2026 wants to merge 2 commits into
yetone:mainfrom
TryWorld2026:fix/settings-model-must-be-served

Conversation

@TryWorld2026

@TryWorld2026 TryWorld2026 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

gui: a model the Settings pick has to be one magpie serves

What is wrong

The three Settings model picks — Codex's thread titles, the model that
describes images, and the model that generates them — were validated with
provider.Resolve, which answers for any model spelled under a provider
that is on. So fake/missing and fake/ were accepted and saved, and every
image description, every drawing and every thread title then went to the vendor
on a model it does not list. Codex drops a title it failed to write, so the
thread stayed untitled.

The usual cause is a real model picked first and its provider renaming or
retiring it afterwards.

What changed

Each pick now checks the list its own picker offers:

  • provider.Served for Codex's titles and the vision model, which keeps
    unlisted providers and routing groups and refuses a known provider with an
    unknown or empty model name;
  • the models an on provider draws with (gateway.Drawers, gathered by the new
    imageGens) for image generation, whose image models are not all in the
    served catalog — a plan draws with models it does not chat with.

The Settings page re-sends its own picks with every save, so a value already
saved is checked again rather than kept: one its provider stopped serving is
refused. provider.Resolve itself stays permissive and is not the validator
for these settings, which is what the reference says of it.

POST /api/settings/codex-auto-review already validates against
provider.Served; this PR does not change it.

Semantic change (GUI app shell)

  • Before: a pick that no provider serves was saved and used on the next image
    description, drawing or thread title, with nothing said.
  • After: such a pick answers 400 with the reason and leaves the saved value
    untouched. A value the provider stopped serving is refused on the next save
    rather than kept.
  • Reference: docs/subsystems/gui-shell.md
    (updated in this PR); implementation Handler and imageGens in
    internal/gui/api.go.

Verification

  • TestSettingsModelMustBeServed fails without the change, with fake/missing
    and fake/ answering 200 on all three endpoints, and passes with it: it also
    covers a served model that draws nothing and a stale pick re-sent by another
    save.
  • Focused settings, Codex titles and auto-review tests; go vet -tags nogui ./internal/gui; the windows, darwin and linux builds.
  • The full internal/gui suite has four failures that reproduce the same way
    without this change (TempDir cleanup on Windows, a stale purpose catalog and
    an update relaunch). The Playwright suite was not run: this PR touches no
    string in internal/gui/assets, so no t() key changed.

🎬 界面预览

CI 用这个 PR 的代码构建并真实运行 magpie(沙盒环境,配置了真实的 DeepSeek key),按改动自动操作、截图和录屏 · 2681c8b · 运行记录

改动(按代码):设置页三处模型选择(Codex 会话标题、图像识别、图像生成)改为在保存时按各自选择器列出的清单校验:模型不在清单里就返回 400 并保留原值,不再静默保存;同时把图像生成的候选清单抽成 imageGens(选择器内容不变)。

Warning

描述与代码不符:描述说「设置页每次保存都会重发自己的选择,因而已保存的值会被重新校验,供应商停止提供的值会被拒绝而不是保留」;diff 里只在取值与已保存值不同时才校验(vision/imageGen 与 cur 比较,标题同理),重发同一个已保存的旧值仍然通过并原样保留——与描述写的语义相反,diff 的注释也明确说旧值「保留,不拒绝」。

Note

沙盒里看不到:沙盒里这三个选择器只列出 magpie 实际提供的模型(图像生成只列出 gateway.Drawers 画图用的模型),界面上选不出不在清单里的模型,因此「保存被拒 400 及随之出现在页面上的报错」这条新行为无法在沙盒里演示;同样也没有「模型被供应商改名/下架后残留的旧值」这种状态可造。只能展示这三个选择器本身的候选清单。

播放录屏

▶️ 点图打开录屏(可暂停、拖动)· 直接下载 mp4 · 红线是鼠标轨迹,红色圆环是点击

Codex 会话标题的模型选择器

设置 · 常规:Codex 会话标题一行当前的取值

设置 · 常规:Codex 会话标题一行当前的取值

Codex 会话标题选择器展开后的模型清单

Codex 会话标题选择器展开后的模型清单

设置 · 模型页的两个模型选择

设置 · 模型:图像识别与图像生成两个模型选择

设置 · 模型:图像识别与图像生成两个模型选择

设置 · 模型页向下滚动后的模型选择区域

设置 · 模型页向下滚动后的模型选择区域

github-actions Bot added a commit that referenced this pull request Oct 7, 2026
@TryWorld2026
TryWorld2026 force-pushed the fix/settings-model-must-be-served branch from e985f90 to 70a7723 Compare October 7, 2026 00:59
github-actions Bot added a commit that referenced this pull request Oct 7, 2026
@TryWorld2026
TryWorld2026 force-pushed the fix/settings-model-must-be-served branch from 70a7723 to 0e38cc4 Compare October 7, 2026 13:29
github-actions Bot added a commit that referenced this pull request Oct 7, 2026
github-actions Bot added a commit that referenced this pull request Oct 9, 2026
@TryWorld2026
TryWorld2026 force-pushed the fix/settings-model-must-be-served branch from 515df08 to b8959a7 Compare October 10, 2026 10:46
github-actions Bot added a commit that referenced this pull request Oct 10, 2026
TryWorld2026 and others added 2 commits October 10, 2026 18:54
provider.Resolve answers for any model spelled under a provider that is on,
so the codex-titles, image recognition and image generation endpoints saved
"fake/missing" and "fake/". Every image description, every drawing and every
thread title then went to the vendor on a model it doesn't list, and Codex
drops a title it failed to write, so the thread stayed untitled. The usual
cause is a real model picked first and its provider renaming or retiring it
afterwards.

Each of the three now checks the list its own picker offers: provider.Served
for Codex's titles and the vision model, which keeps unlisted providers and
routing groups, and gateway.Drawers for image generation, whose image models
are not all in the served catalog (a plan draws with models it doesn't chat
with). The Settings page re-sends its own picks with every save, so a value
already saved is checked again rather than kept. Resolve itself stays
permissive.

TestSettingsModelMustBeServed fails without the change, with fake/missing and
fake/ answering 200 on all three endpoints, and passes with it: it also covers
a served model that draws nothing and a stale pick re-sent by another save.
Focused settings, Codex titles and auto-review tests, go vet ./internal/gui,
and the windows, darwin and linux builds pass. The full internal/gui suite has
four failures that reproduce the same way without this change (TempDir cleanup
on Windows, a stale purpose catalog and an update relaunch).
POST /api/settings checked the image recognition and image generation
picks whether or not they had just changed, because prefsKeep re-sends
the page's own picks with every save. So a user whose vision model a
vendor retired, or whose account lost the plan that drew with it, got 400
on every save from then on: the theme, the language, the tray, every
setting the page has, none of which could be changed until they cleared a
pick they could no longer see. The page re-sends its picks because a
save is one whole object; that is what made this worse than it looks.

A pick is checked when it is the one the user just made, and kept as it
is otherwise, as Searcher already did beside them. What the guard is for
is unchanged: Resolve accepts any name under a provider that is on, so
fake/missing and fake/ were saved as though they were models, and the
image description or the drawing then went to a vendor on a model it does
not list.

TestSettingsModelMustBeServed now seeds a stale pick on disk and saves a
theme with the page sending it back, which is the case that answered 400:
both picks, the theme with them saved, the pick left alone. A pick just
made at a model magpie does not serve is still refused, so the guard is
not weakened. Codex's titles keep their own endpoint's check, which was
always only for a pick just made.
@TryWorld2026
TryWorld2026 force-pushed the fix/settings-model-must-be-served branch from b8959a7 to 2681c8b Compare October 10, 2026 11:02
github-actions Bot added a commit that referenced this pull request Oct 10, 2026

This branch was successfully deployed

1 active deployment
ui-preview — 2681c8b5 Deployed Oct 10, 2026 by TryWorld2026 via record #1134
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.

1 participant