refactor(runtime): one compact-runtime selection rule for route and dispatch

The chat route repeated the compact (clean v3) eligibility decision inline
to prepare the turn's context resolution, while the agent loop dispatched
on the contract stamp set by a separate, later condition. The two could
drift, and already disagreed for a user whose privileges demote the turn
to plain chat: the route prepared a compact resolution that no compact
runtime used.

src/agent_runtime/runtime_selection.py (no imports) now owns the rule:

- uses_compact_preview_runtime(): clean route requested, contract policy
  enabled, agent mode, agent permitted, not an image generation session.
- is_compact_preview_contract() and COMPACT_PREVIEW_MODE for the stamp.

The route evaluates the rule once, before context preparation, where all
of its facts are final (the agent privilege is read through the same
_request_privileges helper the later enforcement uses). That one value
gates the typed context resolution and is the _clean_v3_preview flag that
stamps the contract; inside the agent-contract branch it equals the
previous condition, so stamping behavior is unchanged. The agent loop
dispatches through is_compact_preview_contract(), and the compact runtime's
MODE is the shared constant.

A route-level matrix drives the real agent loop and asserts that route
preparation and compact dispatch agree for compact, escalated, configured
compact/full, regular, TUI, privilege-denied and image-generation turns.
This commit is contained in:
Alexandre Teixeira
2026-10-01 22:46:08 +01:00
parent 0054557027
commit 57fe9946c2
5 changed files with 197 additions and 19 deletions
+2 -1
View File
@@ -84,6 +84,7 @@ from src.tool_types import ToolBlock
from src.turn_contract import selected_tools_for_request, with_turn_contract
from src.agent_runtime.journal import propose_action, execute_action
from src.agent_runtime.completion import with_completion_gate
from src.agent_runtime.runtime_selection import is_compact_preview_contract
from src.teacher_escalation import with_teacher_takeover, request_teacher_takeover
from src.tool_utils import _truncate, get_mcp_manager
from src.agent_tools import (
@@ -20461,7 +20462,7 @@ async def stream_agent_loop(
),
)
if turn_contract is not None and turn_contract.selection_mode == 'clean_compact_v3_preview':
if is_compact_preview_contract(turn_contract):
from src.clean_agent_preview import stream_preview
async for chunk in stream_preview(
endpoint_url=endpoint_url, model=model, messages=messages, headers=headers,
+44
View File
@@ -0,0 +1,44 @@
"""Whether a turn runs on the compact (clean v3) preview runtime.
The chat route decides this once, from facts known before context
preparation, and uses that one value both to prepare the turn (its typed
context resolution) and to stamp the turn contract's selection mode. The
agent loop dispatches on that stamp. Keeping both sides here, with no other
imports, means preparation and dispatch read one rule and cannot drift.
Runtime selection is not authority: it grants or denies no operation.
"""
COMPACT_PREVIEW_MODE = "clean_compact_v3_preview"
def uses_compact_preview_runtime(
*,
clean_route_requested: bool,
turn_contract_enabled: bool,
agent_mode: bool,
agent_permitted: bool,
image_generation: bool,
) -> bool:
"""The single compact-runtime eligibility rule for one turn.
``turn_contract_enabled`` is the route's contract policy for this turn
(exact approvals, TUI surface and full-schema routes opt out).
``agent_permitted`` is false when the user's privileges demote the turn
to plain chat; image generation sessions run their own execution path.
"""
return bool(
clean_route_requested
and turn_contract_enabled
and agent_mode
and agent_permitted
and not image_generation
)
def is_compact_preview_contract(turn_contract) -> bool:
"""Whether a turn contract was stamped for the compact runtime."""
return (
turn_contract is not None
and getattr(turn_contract, "selection_mode", None) == COMPACT_PREVIEW_MODE
)
+2 -1
View File
@@ -21,6 +21,7 @@ import httpx
import jsonschema
from src.context_compactor import prune_multimodal_images, trim_for_context
from src.agent_runtime.runtime_selection import COMPACT_PREVIEW_MODE
from src import agent_runs
from src.agent_evidence import command_has_mutation_effect, workspace_artifact_is_usable
from src.tool_capabilities import ToolEffect, ToolRunSecurityContext, capabilities_for_action
@@ -47,7 +48,7 @@ from src.model_profiles import (
)
ENDPOINT_ID = 'cleanv3'
MODE = 'clean_compact_v3_preview'
MODE = COMPACT_PREVIEW_MODE
class ProviderStreamError(Exception):