Skip to content
Closed
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
20 changes: 19 additions & 1 deletion agent/transports/codex.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,26 @@
streaming, or the _run_codex_stream() call path.
"""

import hashlib
from typing import Any, Dict, List, Optional


_MAX_PROMPT_CACHE_KEY_LENGTH = 64
_PROMPT_CACHE_KEY_HASH_LENGTH = 16


def _prompt_cache_key_from_session_id(session_id: Any) -> str:
"""Return a stable Responses prompt_cache_key within provider limits."""
cache_key = str(session_id or "").strip()
if len(cache_key) <= _MAX_PROMPT_CACHE_KEY_LENGTH:
return cache_key

digest = hashlib.sha256(cache_key.encode("utf-8")).hexdigest()[
:_PROMPT_CACHE_KEY_HASH_LENGTH
]
prefix_length = _MAX_PROMPT_CACHE_KEY_LENGTH - _PROMPT_CACHE_KEY_HASH_LENGTH - 1
return f"{cache_key[:prefix_length]}-{digest}"

from agent.transports.base import ProviderTransport
from agent.transports.types import NormalizedResponse, ToolCall

Expand Down Expand Up @@ -101,7 +119,7 @@ def build_kwargs(

session_id = params.get("session_id")
if not is_github_responses and session_id:
kwargs["prompt_cache_key"] = session_id
kwargs["prompt_cache_key"] = _prompt_cache_key_from_session_id(session_id)

if reasoning_enabled and is_xai_responses:
from agent.model_metadata import grok_supports_reasoning_effort
Expand Down
38 changes: 27 additions & 11 deletions tests/agent/transports/test_codex_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ def test_basic_kwargs(self, transport):
{"role": "user", "content": "Hello"},
]
kw = transport.build_kwargs(
model="gpt-5.4",
model="test-model",
messages=messages,
tools=[],
)
assert kw["model"] == "gpt-5.4"
assert kw["model"] == "test-model"
assert kw["instructions"] == "You are helpful."
assert "input" in kw
assert kw["store"] is False
Expand All @@ -59,42 +59,58 @@ def test_system_extracted_from_messages(self, transport):
{"role": "system", "content": "Custom system prompt"},
{"role": "user", "content": "Hi"},
]
kw = transport.build_kwargs(model="gpt-5.4", messages=messages, tools=[])
kw = transport.build_kwargs(model="test-model", messages=messages, tools=[])
assert kw["instructions"] == "Custom system prompt"

def test_no_system_uses_default(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(model="gpt-5.4", messages=messages, tools=[])
kw = transport.build_kwargs(model="test-model", messages=messages, tools=[])
assert kw["instructions"] # should be non-empty default

def test_reasoning_config(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=messages, tools=[],
model="test-model", messages=messages, tools=[],
reasoning_config={"effort": "high"},
)
assert kw.get("reasoning", {}).get("effort") == "high"

def test_reasoning_disabled(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=messages, tools=[],
model="test-model", messages=messages, tools=[],
reasoning_config={"enabled": False},
)
assert "reasoning" not in kw or kw.get("include") == []

def test_session_id_sets_cache_key(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=messages, tools=[],
model="test-model", messages=messages, tools=[],
session_id="test-session-123",
)
assert kw.get("prompt_cache_key") == "test-session-123"

def test_long_session_id_sets_bounded_stable_cache_key(self, transport):
messages = [{"role": "user", "content": "Hi"}]
session_id = "cron_mdjob_agentfile-maintenance--agents-md-review_20260508_050008"

first = transport.build_kwargs(
model="test-model", messages=messages, tools=[], session_id=session_id
)
second = transport.build_kwargs(
model="test-model", messages=messages, tools=[], session_id=session_id
)

assert len(session_id) == 66
assert first["prompt_cache_key"] == second["prompt_cache_key"]
assert len(first["prompt_cache_key"]) <= 64
assert first["prompt_cache_key"] != session_id

def test_github_responses_no_cache_key(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=messages, tools=[],
model="test-model", messages=messages, tools=[],
session_id="test-session",
is_github_responses=True,
)
Expand All @@ -103,15 +119,15 @@ def test_github_responses_no_cache_key(self, transport):
def test_max_tokens(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=messages, tools=[],
model="test-model", messages=messages, tools=[],
max_tokens=4096,
)
assert kw.get("max_output_tokens") == 4096

def test_codex_backend_no_max_output_tokens(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=messages, tools=[],
model="test-model", messages=messages, tools=[],
max_tokens=4096,
is_codex_backend=True,
)
Expand Down Expand Up @@ -143,7 +159,7 @@ def test_xai_headers_preserve_request_override_headers(self, transport):
def test_minimal_effort_clamped(self, transport):
messages = [{"role": "user", "content": "Hi"}]
kw = transport.build_kwargs(
model="gpt-5.4", messages=messages, tools=[],
model="test-model", messages=messages, tools=[],
reasoning_config={"effort": "minimal"},
)
# "minimal" should be clamped to "low"
Expand Down