Address Codex OAuth review feedback

This commit is contained in:
JOBOYA 2026-05-12 10:56:42 +02:00
parent 975b2ccd18
commit 8022f48d1a
3 changed files with 69 additions and 5 deletions

View file

@ -206,7 +206,7 @@ def _post_codex_responses(
"Authorization": f"Bearer {credentials.access_token}",
"Accept": "text/event-stream",
"Content-Type": "application/json",
"version": "strix-codex-oauth",
"User-Agent": "strix-codex-oauth",
}
if credentials.account_id:
headers["ChatGPT-Account-ID"] = credentials.account_id

View file

@ -10,7 +10,7 @@ from litellm import acompletion, completion_cost, stream_chunk_builder, supports
from litellm.utils import supports_prompt_caching, supports_vision
from strix.config import Config
from strix.llm.codex_oauth import complete_codex_oauth
from strix.llm.codex_oauth import CodexOAuthError, complete_codex_oauth
from strix.llm.config import LLMConfig
from strix.llm.memory_compressor import MemoryCompressor, get_message_tokens
from strix.llm.utils import (
@ -314,9 +314,6 @@ class LLM:
self._total_stats.input_tokens += usage.get("input_tokens", 0)
self._total_stats.output_tokens += usage.get("output_tokens", 0)
if content:
yield LLMResponse(content=content)
content = _THINKING_BLOCK_RE.sub("", content)
content = normalize_tool_format(content)
content = fix_incomplete_tool_call(_truncate_to_first_function(content))
@ -384,6 +381,8 @@ class LLM:
return 0.0
def _should_retry(self, e: Exception) -> bool:
if isinstance(e, CodexOAuthError):
return False
code = getattr(e, "status_code", None) or getattr(
getattr(e, "response", None), "status_code", None
)

View file

@ -4,13 +4,16 @@ from pathlib import Path
import pytest
from strix.llm.codex_oauth import (
CodexOAuthCredentials,
CodexOAuthError,
_post_codex_responses,
build_codex_responses_payload,
load_codex_oauth_credentials,
parse_responses_sse_events,
refresh_codex_oauth_credentials,
)
from strix.llm.config import LLMConfig
from strix.llm.llm import LLM
def test_llm_config_detects_codex_oauth_provider(monkeypatch: pytest.MonkeyPatch) -> None:
@ -22,6 +25,41 @@ def test_llm_config_detects_codex_oauth_provider(monkeypatch: pytest.MonkeyPatch
assert config.codex_model == "gpt-5.5"
def test_llm_does_not_retry_codex_oauth_errors(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("STRIX_LLM", "codex/gpt-5.5")
llm = LLM(LLMConfig())
assert llm._should_retry(CodexOAuthError("Run `codex login` first.")) is False
@pytest.mark.asyncio
async def test_codex_oauth_stream_yields_single_processed_response(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setenv("STRIX_LLM", "codex/gpt-5.5")
def fake_complete_codex_oauth(*args, **kwargs):
return (
"<thinking>hidden</thinking><function=finish><parameter=summary>done</parameter></function>",
{"input_tokens": 1, "output_tokens": 2},
)
monkeypatch.setattr("strix.llm.llm.complete_codex_oauth", fake_complete_codex_oauth)
llm = LLM(LLMConfig())
responses = [
response
async for response in llm._stream_codex_oauth([{"role": "user", "content": "Hi"}])
]
assert len(responses) == 1
assert "<thinking>" not in responses[0].content
assert responses[0].tool_invocations
assert llm._total_stats.input_tokens == 1
assert llm._total_stats.output_tokens == 2
def test_load_codex_oauth_credentials_reads_codex_auth_json(tmp_path: Path) -> None:
auth_file = tmp_path / "auth.json"
auth_file.write_text(
@ -95,6 +133,33 @@ def test_refresh_codex_oauth_credentials_persists_new_tokens(tmp_path: Path) ->
assert calls[0][1]["json"]["grant_type"] == "refresh_token"
def test_post_codex_responses_uses_user_agent_header(
monkeypatch: pytest.MonkeyPatch,
) -> None:
calls = []
class FakeResponse:
pass
def fake_post(url: str, **kwargs):
calls.append((url, kwargs))
return FakeResponse()
monkeypatch.setattr("strix.llm.codex_oauth.requests.post", fake_post)
response = _post_codex_responses(
"https://example.test/codex",
CodexOAuthCredentials(access_token="access-token", account_id="account-id"),
{"model": "gpt-5.5"},
60,
)
assert isinstance(response, FakeResponse)
headers = calls[0][1]["headers"]
assert headers["User-Agent"] == "strix-codex-oauth"
assert "version" not in headers
def test_build_codex_responses_payload_converts_chat_messages() -> None:
payload = build_codex_responses_payload(
model="gpt-5.5",