Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user