fix(model-stub): GET /v1/models also answers Codex's models shape

Merged
TE
2d ago
+9-4

Leo asked: "Is there a way we can do a 99% true test incl. an account without needing an actual Claude or codex or whomever login?" The shared model stub is that test for Claude Code. #35496 found two gaps that keep Codex turns on it from passing. This PR fixes the first one.

What changes

Codex 0.164 decodes GET {base_url}/models as {"models": [ModelInfo]} (ModelsResponse in codex-rs protocol/src/openai_models.rs). The stub only answered "data", so on every Codex run it logged failed to refresh available models: ... failed to decode models response. The answer now also carries "models": []. Codex decodes that and keeps its fallback model metadata. Anthropic and OpenAI clients still read "data".

The decode error was noise, not why Codex turns failed. The real cause is that Codex's default catalog model runs in "code mode": it sends its tools as an additional_tools input item with one JavaScript exec tool, and the stub doesn't speak that. A journey that names its own model (model = "stub-model") gets the plain exec_command tool and a full tool round trip. That fix, together with keeping the fake sign-in off chatgpt.com, goes in the journey's Codex config in a separate PR.

Test

python3 tests/fixtures/model-stub/test_model_stub.py

  • On f89c0a709bbf (the regression commit alone): KeyError: 'models', 1 error out of 17 tests.
  • On this head: all 17 tests pass.

Observed / Not run

  • Observed: the stdlib test run above. Real codex exec (codex-cli 0.164.0) against this exact model_stub.py, on a Linux host with a scratch CODEX_HOME, a made-up ChatGPT sign-in and the journey's provider config. Before: 2-3 failed to decode models response errors per run. After: 0.
  • Not run: the Cloud journey with --agent codex --model stub. That needs the config PR as well.

Changelog

none

Part of manaflow-ai/cmuxterm-hq#7067.

Agent session: agent session

🤖 Generated with Claude Code


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes the model stub's GET /v1/models response so Codex 0.164 can decode it without logging failed to decode models response on every run.

  • Codex expects a {"models": [...]} shape; the stub now returns an empty models list alongside the existing data list, so Codex keeps its fallback model metadata and Anthropic/OpenAI clients are unaffected.
  • Adds a test assertion that the response carries models.