4 Commits
Author SHA1 Message Date
Jason 8347e1ab03 refactor(forms): drop the fetch-count toast when the model picker opens
A successful fetch from a model list header now opens the picker dialog,
which already shows how many models came back, so the "fetched N models"
toast only repeated it. Claude Code Aggregation, Codex with a model list
and OpenCode / MiniMax Code no longer show it there. The fetch buttons that
don't open the picker (the Codex default model field, the Claude Code model
mapping) keep it, and the empty-list and error toasts are unchanged.
2026-10-11 22:51:29 +08:00
Jason f724474590 feat(forms): pick fetched models in a dialog that can also remove them
The fetched-model picker was an inline box under the model list that could
only add models: configured ones showed as checked and disabled. It is now
a dialog opened from the list header (Claude Code Aggregation, both Codex
model list layouts, OpenCode and MiniMax Code). A successful fetch opens it;
after that the button reads "Select models" and opens it without fetching
again, with a refresh button inside.

A checkbox now means "in the list": configured models start checked and
unchecking removes their rows on Apply, while Cancel changes nothing. Rows
that stay keep their order and fields, new picks are appended and get their
parameters filled. Configured models the provider did not return are listed
first in their own group so they can be removed too. In Codex, removing the
default model's row moves the default to the new first row, as deleting
the row does. The dialog has search, select all / none for the visible
models, a selected-only filter and a selected count.

Replaces fetchedModelsTitle, modelAlreadyAdded and addSelectedModels with
providerForm.modelPicker.*.
2026-10-11 22:51:29 +08:00
小七 315aeda7cf fix(model-fetch): honor provider header overrides when fetching models (#7760)
* fix(model-fetch): honor provider header overrides when fetching models

The backend command `fetch_models_for_config` already accepts
`request_headers` and the Pi form passes them, but the Claude and Codex
forms never forwarded the provider's local-proxy Header override JSON,
so gateways that require extra headers (e.g. Cloudflare AI Gateway's
`cf-aig-authorization`) rejected the GET /v1/models probe
(fixes #7747).

Parse the Header override JSON with the shared `parseHeaderOverrideJson`
rules via a new `modelFetchRequestHeaders` helper and send the validated
headers along with the model fetch in both forms; invalid or empty
overrides silently fall back to a plain fetch while the form field keeps
surfacing the validation error.

Fixes #7747

Generated-by: GLM-5.3-Flash (ZCode)

* fix(codex): invalidate fetched models when header overrides change

The header override field feeds model fetching (requestHeaders), but
only handleFetchModels picked it up as a callback dependency. The
invalidation effect that bumps fetchModelsSeqRef and clears
fetchedModels did not list it, so after a fetch completed (or while one
was in flight) editing only the header override kept the previous
identity's model list on screen; users could select models the current
identity cannot access into the default model or the model mapping.
The Grok Build form reuses this component and inherits the fix.

Add localProxyHeadersOverride to the invalidation effect's dependencies
alongside Base URL / API Key / custom UA, and cover both regression
scenarios with component tests: editing the override after a completed
fetch clears the list, and an in-flight response is dropped by the seq
guard when the override changes while the request is pending.

ClaudeFormFields needs no matching change: it has no model-list
invalidation effect at all (its fetchedModels also survive Base URL /
API Key edits), which is pre-existing behavior outside this PR's scope.

Generated-by: GLM-5.3-Flash (ZCode)

* test(codex): cover modelFetchRequestHeaders in the modelFetch test mock

CodexFormFields.modelFetch.test.tsx replaces the whole model-fetch module
with an enumerated factory mock, so the new modelFetchRequestHeaders export
crashed the four scenarios that trigger the fetch-models path ("No
modelFetchRequestHeaders export is defined on the mock"), and the config
route assertion needed the new trailing options argument.

Add the missing export to the mock factory and pin the extra
{ requestHeaders } argument; no production code touched.

Generated-by: GLM-5.3-Flash (ZCode)
2026-10-10 22:39:59 +08:00
f9db9f7056 feat(codex): support GitHub Copilot managed accounts with Responses/Chat routing (#7157)
Add a GitHub Copilot preset for Codex that uses a managed GitHub account.
The local route resolves each request's model against the account's live
Copilot /models catalogue and picks the upstream protocol the model
advertises (native Responses first, Chat Completions as fallback in auto
mode), with an optional explicit protocol override.

- Response handling, the opaque-state rectifier and Stack web_search
  stripping follow the transport actually used for each request rather
  than the stored apiFormat.
- Fetching models fills the catalogue from the account's live prompt
  limit, parallel tool calls and reasoning levels; presets keep
  conservative fallbacks.
- Codex only treats a card as managed Copilot by its provider type, so
  self-hosted relays keep their own key and endpoint.
- Copilot request identity headers are shared between the Claude and
  Codex paths.

Co-authored-by: yuwk <52391318+ump45nose@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-10-08 00:10:45 +08:00