Skip to content

feat(routing): route Codex thread descriptions independently - #1198

Open
congee949 wants to merge 3 commits into
yetone:mainfrom
congee949:codex-thread-description-routing
Open

congee949 wants to merge 3 commits into
yetone:mainfrom
congee949:codex-thread-description-routing

Conversation

@congee949

@congee949 congee949 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add codexDescriptions, so thread_description can use a selected Magpie model or routing group while the empty default preserves Codex's original request
  • wrap the selected model's answer as description-only JSON and preserve the request kind, without changing codexTitles
  • show thread_description as its own Description purpose and keep the setting across unrelated Settings saves

This is the first concrete slice of #742. It does not add the general per-purpose routing proposed there, and it intentionally has no Off mode until Codex's handling of an empty description is verified.

Test plan

  • go test -tags nogui ./internal/gateway -run 'TestCodexTitlesSetting|TestCodexDescriptionsSetting|TestDescriptionJSON|TestTitleJSON'
  • go test -tags nogui ./internal/usage -run TestPurposeFilter
  • go test -tags nogui ./internal/gui -run 'TestSettingsSaveKeepsWhatItDoesNotSend|TestCodexDescriptionsSetting|TestCodexTitlesSetting'
  • Trigger a real Codex description request and confirm the sidebar accepts the returned description
  • Run the GUI Playwright coverage for the new Settings row

🎬 界面预览

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

改动(按代码):网关开始独立处理 Codex 的会话描述请求(thread_description):设置 › 常规 里「Codex 会话标题」下方新增一行「Codex 会话描述」,可从 Codex 自带的 ChatGPT 模型切换到 magpie 的任意模型或路由组;用量与路由中该用途显示为「描述」。

Note

沙盒里看不到:用量/路由页把 thread_description 记为「描述」这一处,以及描述请求真正改道后模型回答被包成 {"description": …} 的效果,都要有真实的 thread_description 请求才会出现;这类请求由 Codex 自己发出,沙盒现有记录里没有,因此只能看到设置页新增的这一行,看不到用量里的「描述」标签与实际改道结果。

播放录屏

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

设置里的 Codex 会话描述行

「Codex 会话标题」下方新增的「Codex 会话描述」一行

「Codex 会话标题」下方新增的「Codex 会话描述」一行

展开的选择列表,可以看看都有哪些项

展开的选择列表,可以看看都有哪些项

选完之后这一行,以及它上方「Codex 会话标题」那一行

选完之后这一行,以及它上方「Codex 会话标题」那一行

Add a description-model setting that preserves the description-only response schema without changing title routing.
@congee949
congee949 deployed to ui-preview October 7, 2026 15:52 — with GitHub Actions Active
github-actions Bot added a commit that referenced this pull request Oct 7, 2026

@yetone yetone left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for this. Routing thread_description on its own is useful, and with a model set it works end to end: I checked it at b528a04 in a sandbox gateway on both /v1/responses and /backend-api/codex/responses, and the usage record shows the thread_description kind. A few things before it can merge:

  1. Codex on magpie with the setting empty. codexTitlesTo falls back to routing titles when Codex itself runs on magpie (#743), but codexDescriptionsTo doesn't. With Codex on a Chat-backed magpie model and no description model set, the upstream gets no schema, returns plain text, and Codex shows no description. Could codexDescriptionsTo fall back the same way?
  2. Translations. The three new strings have zh but no ja or de, so gui-ja and gui-de fail in both engines. The new "Description" purpose label from usage/purpose.go has no translation at all, so it shows in English in Usage and Routing.
  3. Tests. Codex's real thread_description schema (from ChatGPT.app) is {"description":{"type":"string","minLength":1}} with no maxLength; please build the fixtures from that instead of maxLength:24. Nothing fails when noDescription never flags a reply, so please add a case with an unusable reply. The new TestPurposeFilter row passes without the purpose.go change, because unknown kinds already show as kind:<kind>; please check the label instead.
  4. Small things. Please move the renderCodexTitles (#705) comment back above its function, and add the new row to the list of settings hidden in gateway mode in docs/reference.md.

Ran: go vet (darwin, linux, windows), builds, Go tests for gateway, gui, usage and settings (pass), go generate ./internal/usage (no diff), targeted breaks of the source, a sandbox gateway with a fake upstream, and the focused GUI set in Chromium and WebKit (71/73; the 2 failures are gui-ja and gui-de).

Wrap descriptions for Codex on Magpie when no model is selected, and cover the real schema, unusable replies, translations, and gateway-mode documentation.
@congee949
congee949 deployed to ui-preview October 7, 2026 22:34 — with GitHub Actions Active
github-actions Bot added a commit that referenced this pull request Oct 7, 2026

@yetone yetone left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Re-reviewed at ac79156. Thanks, most of the earlier points are addressed, and each fix is caught by its test:

  • without the fallback, TestCodexDescriptionFallbackOnMagpie fails
  • with check never flagging, TestNoDescription fails
  • without the purpose.go line, TestDescriptionPurposeLabel fails

ja and de pass, and the fixtures use Codex's real schema.

Still needed:

  1. zh-TW. main now has a "zh-TW" block in i18n.js, and after merging gui-zh-tw fails with 4 strings missing: "Codex thread descriptions", its two subtitles, and "Description". Please add their Traditional Chinese.
  2. The renderCodexTitles comment. It is now above renderCodexTitles, but the old copy is still above renderCodexDescriptions and describes the titles picker. Please replace it with a comment for the description picker.

Nits:

  • The description fallback is tested only on /v1/responses (ours=true). A case on /backend-api/codex/responses with a provider/model would cover the other call site.
  • descriptionShape's MaxLength and its comment ("Its max length is all magpie needs") come from the earlier made-up schema. Codex's real schema has no max length, so drop it, or say it is only a guard.
  • A real Codex thread_description run is still unchecked in the test plan.

Ran at ac79156, merged onto e4882f9:

  • go vet -tags nogui on linux, windows and darwin for gateway, gui, usage and settings: clean
  • go test for those four packages: ok
  • go generate ./internal/usage: no diff
  • GUI in Chromium and WebKit: codex-titles, gateway-mode, purpose-filter, routing-purpose-state, settings-sections, settings-groups, settings-shortcut, click-scroll and codex-memories-settings (82/82); gui-ja, gui-de and i18n-keys pass; gui-zh-tw fails (point 1)

@congee949
congee949 deployed to ui-preview October 9, 2026 08:22 — with GitHub Actions Active
@congee949

Copy link
Copy Markdown
Contributor Author

Updated the branch onto current main and addressed the remaining review points:

  • Added all four Traditional Chinese strings, with placeholder/tag parity.
  • Replaced the stale title-picker comment above renderCodexDescriptions.
  • Added the empty-setting fallback test on both /v1/responses and /backend-api/codex/responses with a provider/model request.
  • Removed the invented descriptionShape.MaxLength; real Codex's nonempty description schema has no max length.
  • Preserved current main's compaction handling while resolving the merge conflict.
  • Added the title/description routing boundary to docs/subsystems/gateway-routing.md.

Verification on the updated branch:

  • Focused go test -tags nogui for gateway, gui, settings and usage: pass (settings has no tests matching the focused pattern).
  • go vet -tags nogui for those four packages: pass; compiler emitted the existing darwin CGImageAlphaInfo/CGBitmapInfo warning.
  • Browser tests for codex-titles, gui-zh-tw, gui-ja, gui-de and i18n-keys: 14 pass, 0 fail, Chromium and WebKit. These check languages and the existing title picker; a new description-picker end-to-end browser case remains to be added.
  • git diff --check: pass.

Real Codex sidebar description acceptance remains unchecked. The production gateway was not replaced. Full repository tests/builds and the full GUI suite were not run here; the focused results above do not establish those suites passed.

October 3–9 local logs also show 66 final response-protection failures, all thread_description, including failures after the installed 0.1.1137 process started. Evidence was added to #1270; the published compact fallback is a different path. This PR supplies independent description routing rather than changing ChatGPT's protection mechanism.

github-actions Bot added a commit that referenced this pull request Oct 9, 2026

This branch was successfully deployed

1 active deployment
ui-preview — 6c5b2a47 Deployed Oct 9, 2026 by congee949 via record #1101
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