22
33import json
44import subprocess
5+ import threading
6+ import time
7+ import urllib .request
58from pathlib import Path
69from typing import Any , cast
710
@@ -16,6 +19,46 @@ def test_resolve_backend_prefers_model_prefix() -> None:
1619 assert server .resolve_backend ("gpt-5.4" , default_backend = "codex" ) == "codex"
1720
1821
22+ def test_resolve_request_model_uses_backend_default_when_model_is_omitted () -> None :
23+ assert server .resolve_request_model ({}, default_backend = "codex" ) == "codex/gpt-5.4"
24+ assert server .resolve_request_model ({}, default_backend = "claude" ) == "claude/claude-sonnet-4-6"
25+ assert (
26+ server .resolve_request_model ({"model" : "claude/claude-sonnet-4-6" }, default_backend = "codex" )
27+ == "claude/claude-sonnet-4-6"
28+ )
29+
30+
31+ def test_http_server_uses_backend_default_model_when_request_omits_model (
32+ monkeypatch : pytest .MonkeyPatch , tmp_path : Path
33+ ) -> None :
34+ def fake_run_backend (* , backend : str , prompt : str , model : str | None , workdir : Path ) -> str :
35+ return f"backend={ backend } ;model={ model } ;workdir={ workdir .name } "
36+
37+ monkeypatch .setattr (server , "run_backend" , fake_run_backend )
38+
39+ httpd = server .make_server ("127.0.0.1" , 0 , default_backend = "claude" , workdir = tmp_path )
40+ thread = threading .Thread (target = httpd .serve_forever , daemon = True )
41+ thread .start ()
42+ time .sleep (0.05 )
43+ try :
44+ req = urllib .request .Request (
45+ f"http://127.0.0.1:{ httpd .server_address [1 ]} /v1/chat/completions" ,
46+ data = json .dumps ({"messages" : [{"role" : "user" , "content" : "Say hi." }]}).encode ("utf-8" ),
47+ headers = {"Content-Type" : "application/json" },
48+ )
49+ with urllib .request .urlopen (req ) as resp :
50+ payload = json .loads (resp .read ().decode ("utf-8" ))
51+ finally :
52+ httpd .shutdown ()
53+ httpd .server_close ()
54+ thread .join (timeout = 2 )
55+
56+ assert payload ["model" ] == "claude/claude-sonnet-4-6"
57+ assert payload ["choices" ][0 ]["message" ]["content" ].startswith (
58+ "backend=claude;model=claude/claude-sonnet-4-6"
59+ )
60+
61+
1962def test_build_chat_prompt_from_messages_preserves_roles () -> None :
2063 payload = {
2164 "messages" : [
0 commit comments