fix: normalize Codex handoff base URL

This commit is contained in:
mol 2026-07-17 16:33:52 +00:00
parent 6c863ae9c9
commit 04783d11d8
2 changed files with 16 additions and 6 deletions

View file

@ -24808,7 +24808,7 @@ def _handle_handoff_summary(handler, body):
codex_kwargs = agent._build_api_kwargs(api_messages) codex_kwargs = agent._build_api_kwargs(api_messages)
codex_kwargs.pop("tools", None) codex_kwargs.pop("tools", None)
codex_provider = str(getattr(agent, "provider", "") or "").strip().lower() codex_provider = str(getattr(agent, "provider", "") or "").strip().lower()
codex_base_url = str(getattr(agent, "base_url", "") or "").lower() codex_base_url = str(getattr(agent, "base_url", "") or "").strip().lower()
is_chatgpt_codex = ( is_chatgpt_codex = (
codex_provider == "openai-codex" codex_provider == "openai-codex"
or ( or (

View file

@ -504,21 +504,31 @@ def test_handoff_summary_retries_once_when_length_limit_reached(monkeypatch):
@pytest.mark.parametrize( @pytest.mark.parametrize(
("provider", "base_url", "expects_output_cap"), ("provider", "base_url", "expects_output_cap", "expects_normalized_base_url"),
[ [
("openai-codex", "https://chatgpt.com/backend-api/codex", False), ("openai-codex", "https://chatgpt.com/backend-api/codex", False, False),
("custom:chatgpt-codex", "https://chatgpt.com/backend-api/codex", False), ("custom:chatgpt-codex", "https://chatgpt.com/backend-api/codex", False, False),
("custom:responses-proxy", "https://responses.example/v1", True), ("custom:chatgpt-codex", " https://chatgpt.com/backend-api/codex ", False, True),
("custom:responses-proxy", "https://responses.example/v1", True, False),
], ],
) )
def test_handoff_summary_codex_output_cap_matches_provider_compatibility( def test_handoff_summary_codex_output_cap_matches_provider_compatibility(
monkeypatch, provider, base_url, expects_output_cap, monkeypatch, provider, base_url, expects_output_cap, expects_normalized_base_url,
): ):
"""ChatGPT Codex rejects the cap, while other Responses transports retain it.""" """ChatGPT Codex rejects the cap, while other Responses transports retain it."""
import api.config as cfg import api.config as cfg
import api.models as models import api.models as models
import api.routes as routes import api.routes as routes
if expects_normalized_base_url:
real_urlsplit = routes.urlsplit
def _strict_urlsplit(value):
assert value == value.strip()
return real_urlsplit(value)
monkeypatch.setattr(routes, "urlsplit", _strict_urlsplit)
monkeypatch.setattr(routes, "require", lambda body, *keys: None) monkeypatch.setattr(routes, "require", lambda body, *keys: None)
monkeypatch.setattr(routes, "bad", lambda _handler, msg, status=400: {"ok": False, "error": msg, "status": status}) monkeypatch.setattr(routes, "bad", lambda _handler, msg, status=400: {"ok": False, "error": msg, "status": status})
monkeypatch.setattr(routes, "j", lambda _handler, payload, status=200, extra_headers=None: payload) monkeypatch.setattr(routes, "j", lambda _handler, payload, status=200, extra_headers=None: payload)