Files
aiturk-hermes-ide/tests/agent/test_native_preflight_estimate.py

149 lines
5.4 KiB
Python

"""Native Responses preflight must count the checkpoint-pruned wire (#96155)."""
from types import SimpleNamespace
from agent.codex_responses_adapter import estimate_native_responses_preflight_tokens
from agent.model_metadata import estimate_request_tokens_rough
from agent.turn_context import _preflight_request_tokens
def _codex_agent(**over):
agent = SimpleNamespace(
api_mode="codex_responses",
provider="openai-codex",
model="gpt-5.6",
base_url="https://chatgpt.com/backend-api/codex",
_base_url_hostname="chatgpt.com",
_base_url_lower="https://chatgpt.com/backend-api/codex",
codex_responses_native_compaction=True,
compression_enabled=True,
_codex_reasoning_replay_enabled=True,
context_compressor=SimpleNamespace(threshold_tokens=765_000),
tools=None,
)
for key, value in over.items():
setattr(agent, key, value)
return agent
def _history_with_checkpoint():
# Pre-checkpoint assistant/tool rows are dropped from the wire; user
# asks are retained. A durable estimate that counts those dropped rows
# is what falsely tripped local compression in #96155.
pre = []
for i in range(30):
pre.append({"role": "user", "content": f"ask {i}"})
pre.append({"role": "assistant", "content": "working " + ("tool output " * 400)})
pre.append(
{
"role": "tool",
"content": "result " + ("payload " * 400),
"tool_call_id": f"call-{i}",
}
)
checkpoint_turn = {
"role": "assistant",
"content": "checkpointed turn",
"codex_reasoning_items": [
{
"type": "compaction",
"encrypted_content": "blob",
"_issuer_kind": "codex_backend",
}
],
}
tail = [{"role": "user", "content": "follow-up after checkpoint"}]
return pre + [checkpoint_turn] + tail
def test_returns_none_when_api_mode_is_not_codex_responses():
agent = _codex_agent(api_mode="chat_completions")
assert estimate_native_responses_preflight_tokens(agent, _history_with_checkpoint()) is None
def test_returns_none_when_native_compaction_is_disabled():
agent = _codex_agent(codex_responses_native_compaction=False)
assert estimate_native_responses_preflight_tokens(agent, _history_with_checkpoint()) is None
def test_returns_none_when_model_is_outside_gpt56_family():
agent = _codex_agent(model="gpt-5.2")
assert estimate_native_responses_preflight_tokens(agent, _history_with_checkpoint()) is None
def test_pruned_estimate_is_far_below_durable_transcript():
agent = _codex_agent()
messages = _history_with_checkpoint()
generic = estimate_request_tokens_rough(messages)
native = estimate_native_responses_preflight_tokens(agent, messages)
assert native is not None
assert generic > native * 2
assert native < 8_000
def test_preflight_wrapper_uses_pruned_estimate_when_eligible():
agent = _codex_agent()
messages = _history_with_checkpoint()
native = estimate_native_responses_preflight_tokens(agent, messages)
wrapped = _preflight_request_tokens(agent, messages, "")
assert native is not None
assert wrapped == native
def test_preflight_wrapper_falls_back_to_generic_when_ineligible():
agent = _codex_agent(api_mode="chat_completions")
messages = _history_with_checkpoint()
generic = estimate_request_tokens_rough(messages)
assert _preflight_request_tokens(agent, messages, "") == generic
# ── Mid-turn pre-API guard parity (#96995) ────────────────────────────────
# The mid-turn guard in conversation_loop must measure the same pruned wire
# payload the turn-prologue preflight does (#96644/#96155); before #96995 it
# used the generic durable-history estimate and false-tripped 600s local
# compression on compacted native-Codex sessions.
def test_midturn_pressure_uses_pruned_estimate_when_eligible():
from agent.conversation_loop import (
_midturn_request_pressure_tokens,
estimate_messages_tokens_rough,
)
agent = _codex_agent()
messages = [{"role": "system", "content": "be brief"}] + _history_with_checkpoint()
native = estimate_native_responses_preflight_tokens(
agent, messages, system_prompt="be brief"
)
generic = estimate_messages_tokens_rough(messages)
assert native is not None
assert generic > native * 2
# The assembled api_messages carry the system row; the helper must not
# double-count it (converter skips system rows, system_prompt adds it once).
assert _midturn_request_pressure_tokens(
agent, messages, "be brief", generic
) == native
def test_midturn_pressure_falls_back_to_generic_plus_tools_when_ineligible():
from agent.conversation_loop import (
_estimate_tools_tokens_rough,
_midturn_request_pressure_tokens,
estimate_messages_tokens_rough,
)
agent = _codex_agent(
api_mode="chat_completions",
tools=[{"type": "function", "function": {"name": "t", "parameters": {}}}],
)
messages = [{"role": "system", "content": "be brief"}] + _history_with_checkpoint()
approx = estimate_messages_tokens_rough(messages)
assert _midturn_request_pressure_tokens(
agent, messages, "be brief", approx
) == approx + _estimate_tools_tokens_rough(agent.tools)