The Codex app resumes a thread on the provider it was started on, kept in
Codex's state database (app-server thread_processor.rs:
merge_persisted_resume_metadata), whatever config.toml's model_provider is
now, and loads no config for it when config.toml has no table of that id
(core config: "Model provider `{id}` not found"). CC Switch puts every
third-party thread on "custom" and rewrites config.toml whole when it
switches, so a switch to its official provider leaves those threads with no
table, and the app can't open them. magpie never removes [model_providers.custom],
but nothing put it back either.
While magpie is wired into Codex (takeTables: set, Join and Sync), each
provider a thread in state_*.sqlite names that config.toml has none of
(table, inline or dotted) gets a table pointed at magpie's gateway, as
CC Switch's own tables already are. Codex's built-in providers (openai,
ollama, lmstudio, amazon-bedrock[-runtime], ollama-chat) and magpie's own
are left out, and a provider the user has stays as it is. The table stays
when Codex steps off magpie, as magpie's own does, for the threads that
name it. Not wired, nothing is written. sessions.CodexThreadProviders reads
the distinct model_provider of the threads table, read-only.
Run:
- Real Codex 0.161 in a sandbox HOME: `codex exec` recorded a thread under
a [model_providers.custom] pointed at a fake Responses server, the table
was removed, and the app-server's thread/resume answered "failed to load
configuration: Model provider `custom` not found" (the reporter's error).
With this build's `magpie codex fakerelay/m1` (sandbox HOME, gateway on
127.0.0.1:3546), [model_providers.custom] was written to the gateway, the
same thread/resume succeeded, and a turn on it completed through magpie to
the provider (its request reached the fake). The thread kept "custom".
- TestCodexWritesTablesThreadsName (signed in and not) fails without the
call ("custom not written through magpie"), and its inline case fails
without the parsed check ("edited TOML is invalid: key inl should be a
table"); TestCodexThreadTablesOnlyWired.
- gofmt -l, go vet, GOOS=linux/windows go vet -tags nogui on agent and
sessions, GOOS=linux go build -tags nogui, GOOS=windows go build, and
go test -tags nogui ./... under a temp HOME. One full run failed
TestSetAnswersWhileDevinAndProvidersHang (internal/gui, set took 1.6s
against its 1.5s wall-clock bound; Claude only, Codex not wired, so this
code isn't on its path); it passes alone 5/5 (0.19-0.42s) and in a rerun
of gui, agent and sessions together.