Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions tests/fixtures/model-stub/model_stub.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
with ANTHROPIC_BASE_URL=http://127.0.0.1:PORT;
- OpenAI Responses (POST /v1/responses, streamed or not), for Codex with a model provider whose base_url is
http://127.0.0.1:PORT/v1.
GET /v1/models answers both shapes. Standard library only, Python 3.9+, so it runs on a runner, a Cloud machine
or a Mac as it is.
GET /v1/models answers both shapes, plus Codex's {"models": [...]}. Standard library only, Python 3.9+, so it runs
on a runner, a Cloud machine or a Mac as it is.

A script says what the model does. It is JSON: {"version": 1, "steps": [...]}. A request's step is the number of
tool results already in its conversation, so the reply never depends on server state, and a retried request gets
Expand Down Expand Up @@ -279,7 +279,9 @@ def do_GET(self) -> None:
stub.log({"protocol": "-", "method": "GET", "path": path, "cred_sha256": credential_sha256(self.headers)})
if path.endswith("/models"):
model = {"id": "stub-model", "object": "model", "type": "model", "display_name": "Model stub", "created": 0, "owned_by": "stub"}
return self._json(200, {"object": "list", "data": [model], "has_more": False, "first_id": "stub-model", "last_id": "stub-model"})
# "data" is the Anthropic and OpenAI list; "models" is Codex's (empty: it keeps its fallback model metadata).
return self._json(200, {"object": "list", "data": [model], "has_more": False, "first_id": "stub-model", "last_id": "stub-model",
"models": []})
return self._json(200, {})

def do_POST(self) -> None:
Expand Down
5 changes: 4 additions & 1 deletion tests/fixtures/model-stub/test_model_stub.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ def test_count_tokens_and_models(self) -> None:
_, text = post(self.base + "/v1/messages/count_tokens", {"messages": []})
self.assertEqual(json.loads(text), {"input_tokens": 10})
with urllib.request.urlopen(self.base + "/v1/models", timeout=10) as r:
self.assertEqual(json.loads(r.read())["data"][0]["id"], "stub-model")
models = json.loads(r.read())
self.assertEqual(models["data"][0]["id"], "stub-model")
# Codex decodes {"models": [ModelInfo]}; an empty list leaves it on its fallback model metadata.
self.assertEqual(models["models"], [])
with urllib.request.urlopen(self.base + "/__stub/info", timeout=10) as r:
self.assertEqual(json.loads(r.read())["version"], model_stub.STUB_VERSION)

Expand Down
Loading