### Summary
Addresses [IJAI-1783](https://youtrack.jetbrains.com/issue/IJAI-1783).
An organization can restrict the models its JetBrains gateway serves,
but a session routed through `providers/set` offered Codex's whole
catalogue, so the picker showed models the gateway then refused.
`providers/set` now lists the gateway's models before it responds, and
the adapter reports only the Codex models the gateway lists.
- `GET {baseUrl}/models` with the headers Codex sends to the gateway
(`X-Client-Feature-ID: codex` plus the `providers/set` headers); OpenAI
format, `data[].id`. The listing is stored with the gateway config, so a
provider restart reuses it, and setting the same configuration again
does not list again.
- `fetchAvailableModels` narrows `model/list`, so new, resumed, loaded
and forked sessions and `unstable_setSessionModel` all see the same
list. Ids match without case and date suffix; exactly one narrowed model
stays `isDefault`.
- A thread model the gateway does not list is replaced by the narrowed
default, also on `turn/start`; a model the gateway lists but Codex's
catalogue lacks is kept. Sessions open across `providers/set` or
`providers/disable` take the models of the restarted app-server, and the
client gets a `config_option_update`. A listing that matches no Codex
model leaves the session with no model: there is no model config option
at all.
- A 4xx answer means the gateway has no listing: `providers/set`
succeeds and nothing is narrowed. Any other failed listing (network
error, 5xx, malformed body, 10 s timeout) fails `providers/set` with
`internal_error`, and the current routing stays. A listing that finishes
after a newer `providers/set` or `providers/disable` was applied is
dropped (a newer request that failed drops nothing), and the routing
goes to the client a provider restart installed. A `baseUrl` that is not
an http(s) URL, accepted on v1 before, now fails with `invalid_params`;
an invalid header or a base URL with credentials fails without repeating
the value.
- The `gateway` auth method and providers from the Codex config
(`config.toml`, `CODEX_CONFIG`) are not listed. `readme-dev.md`
describes the behaviour.
### Not covered
Title generation (`gpt-5.6-luna`), subagents, `/review` and compaction
choose their own model and are not checked against the listing.
### Verification
```bash
npm run typecheck
npm run build
npm test # 1755 passed, 36 skipped
```
`gateway-model-discovery.test.ts` covers the request and headers,
narrowing and the default, the replaced thread model on `turn/start`,
failing `providers/set` (HTTP error, malformed body, network error) with
the routing kept, the empty list, no listing without `providers/set` or
for the gateway auth method, `providers/disable`, reuse, and the
provider restart. Tests that call `providers/set` stub the listing
(`stubGatewayModelListing`). Checked locally against the JetBrains
gateway with an earlier build of this branch: the adapter's log shows
`/models` answering `gpt-5.6-sol`, `gpt-6-sol`, `gpt-6.1-sol` in one
session and an empty list with only Bedrock configured; the empty-list
and failing-listing behaviour of the final build is covered by the tests
only.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>