[eric] client-pool: stop hashing the compaction cutoff, it respawned the CLI every turn past 65% context

This commit is contained in:
ciregenz
2026-07-31 01:17:14 -07:00
parent 970144ce2b
commit 71f480ecfd
3 changed files with 79 additions and 60 deletions
@@ -40,11 +40,16 @@ p_last_field_digests: Dict[str, Dict[str, str]] = {}
def boot_fingerprint(options_kwargs: Dict, session: AgentSession) -> str:
"""Hash of every input the CLI subprocess freezes at boot. Includes the full mcp_servers config
(so MCPActivate / model-env changes respawn), the composed system prompt (so per-turn selection
context respawns instead of silently not applying), branch, and the compaction cutoff (else a
live client would keep the untrimmed transcript forever)."""
context respawns instead of silently not applying), and the branch.
The compaction cutoff is deliberately NOT hashed. It only ever changes prompt_content (the
rebuilt history prefix), which is sent per query, never frozen at boot, and on the resume path
the CLI replays its own untrimmed transcript regardless. Every path that does rebuild history
(needs_fresh_session / needs_fork / fork) already forces a respawn through force_respawn. Hashing
it bought nothing and cost a full CLI respawn on EVERY turn once a session crossed
compact_threshold_pct, measured at +1.0s TTFT per turn."""
frozen = {k: v for k, v in options_kwargs.items() if k not in P_NON_BOOT_KEYS}
frozen["p_branch"] = session.active_branch_id
frozen["p_compacted_through"] = session.compacted_through_msg_id
# Pool diagnostics (OPENSWARM_POOL_DIAG=1): on a respawn, names WHICH boot field drifted; the tool for debugging respawn churn (e.g. the thinking short/long-prompt flip) in the field.
if os.environ.get("OPENSWARM_POOL_DIAG") == "1":
digests = {k: hashlib.sha256(json.dumps(v, sort_keys=True, default=str).encode()).hexdigest()[:10] for k, v in frozen.items()}
+67
View File
@@ -0,0 +1,67 @@
"""What the client pool's boot fingerprint does and does NOT hash.
Reuse is gated on this hash, so anything the CLI subprocess freezes at boot must be in it (a stale
live client is the bug it exists to prevent), and anything sent per query must be out of it (hashing
those respawns the CLI for nothing, which is exactly what the compaction cutoff used to do)."""
import pytest
from backend.apps.agents.core.models import AgentSession
from backend.apps.agents.manager.run.client_pool import boot_fingerprint
BASE_KWARGS = {
"model": "haiku",
"cwd": "/tmp/ws",
"system_prompt": {"type": "preset", "preset": "claude_code"},
"allowed_tools": ["Read"],
"disallowed_tools": ["mcp__claude_ai_*"],
"mcp_servers": {"openswarm-mcp-meta": {"command": "python", "args": ["m.py"], "type": "stdio"}},
"can_use_tool": lambda: None,
"stderr": lambda line: None,
"hooks": {"PreToolUse": []},
}
def make_session() -> AgentSession:
return AgentSession(name="t", model="haiku", mode="agent")
def test_fingerprint_stable_across_per_turn_keys():
s = make_session()
a = boot_fingerprint(dict(BASE_KWARGS), s)
changed = dict(BASE_KWARGS)
changed["can_use_tool"] = lambda: 1
changed["stderr"] = lambda line: 1
changed["hooks"] = {"PreToolUse": ["different"]}
changed["resume"] = "sdk-session-xyz"
changed["fork_session"] = True
assert boot_fingerprint(changed, s) == a
def test_fingerprint_ignores_the_compaction_cutoff():
"""The cutoff only rewrites prompt_content, which is sent per query and never frozen at boot,
and every path that rebuilds history already forces a respawn. Hashing it respawned the CLI on
every turn past compact_threshold_pct for zero token saving (+1.0s TTFT per turn, measured)."""
s = make_session()
before = boot_fingerprint(dict(BASE_KWARGS), s)
for cutoff in ("msg42", "msg43", "msg44"):
s.compacted_through_msg_id = cutoff
assert boot_fingerprint(dict(BASE_KWARGS), s) == before
@pytest.mark.parametrize("mutate", [
lambda k, s: k.__setitem__("mcp_servers", {**k["mcp_servers"], "x": {"command": "node", "type": "stdio"}}),
lambda k, s: k.__setitem__("system_prompt", {"type": "preset", "preset": "claude_code", "append": "sel"}),
lambda k, s: k.__setitem__("model", "gpt-5-mini"),
lambda k, s: k.__setitem__("cwd", "/tmp/other"),
lambda k, s: k.__setitem__("allowed_tools", ["Read", "Bash"]),
lambda k, s: k.__setitem__("tools", ["Read", "Bash", "ToolSearch"]),
lambda k, s: setattr(s, "active_branch_id", "branch2"),
])
def test_fingerprint_changes_on_boot_inputs(mutate):
s = make_session()
kwargs = dict(BASE_KWARGS)
kwargs["mcp_servers"] = dict(BASE_KWARGS["mcp_servers"])
before = boot_fingerprint(kwargs, s)
mutate(kwargs, s)
assert boot_fingerprint(kwargs, s) != before
+4 -57
View File
@@ -1,19 +1,16 @@
"""Invariant + seeded-simulation tests for the persistent-client pool (lever A of the TTFT work).
Proves the red-teamed safety properties hold by construction: fingerprint-gated reuse, respawn on
any boot-input change, pop-first disposal, never-raising teardown, and (seeded sim) that random op
sequences never reuse a stale client, never double-boot needlessly, and always recover a dead one."""
Proves the red-teamed safety properties hold by construction: fingerprint-gated reuse, pop-first
disposal, never-raising teardown, idle/LRU reclaim, and (seeded sim) that random op sequences never
reuse a stale client, never double-boot needlessly, and always recover a dead one. What the
fingerprint itself hashes lives in test_boot_fingerprint.py."""
import asyncio
import random
from typing import Dict, List
import pytest
from backend.apps.agents.core.models import AgentSession
from backend.apps.agents.manager.run.client_pool import (
ClientHandle,
acquire_client,
boot_fingerprint,
dispose_all_clients,
dispose_client,
dispose_client_soon,
@@ -39,56 +36,6 @@ class FakeClient:
raise RuntimeError("teardown boom")
def make_session(branch: str = "main", compacted: str | None = None) -> AgentSession:
s = AgentSession(name="t", model="haiku", mode="agent")
s.active_branch_id = branch
s.compacted_through_msg_id = compacted
return s
BASE_KWARGS = {
"model": "haiku",
"cwd": "/tmp/ws",
"system_prompt": {"type": "preset", "preset": "claude_code"},
"allowed_tools": ["Read"],
"disallowed_tools": ["mcp__claude_ai_*"],
"mcp_servers": {"openswarm-mcp-meta": {"command": "python", "args": ["m.py"], "type": "stdio"}},
"can_use_tool": lambda: None,
"stderr": lambda line: None,
"hooks": {"PreToolUse": []},
}
def test_fingerprint_stable_across_per_turn_keys():
s = make_session()
a = boot_fingerprint(dict(BASE_KWARGS), s)
changed = dict(BASE_KWARGS)
changed["can_use_tool"] = lambda: 1
changed["stderr"] = lambda line: 1
changed["hooks"] = {"PreToolUse": ["different"]}
changed["resume"] = "sdk-session-xyz"
changed["fork_session"] = True
assert boot_fingerprint(changed, s) == a
@pytest.mark.parametrize("mutate", [
lambda k, s: k.__setitem__("mcp_servers", {**k["mcp_servers"], "x": {"command": "node", "type": "stdio"}}),
lambda k, s: k.__setitem__("system_prompt", {"type": "preset", "preset": "claude_code", "append": "sel"}),
lambda k, s: k.__setitem__("model", "gpt-5-mini"),
lambda k, s: k.__setitem__("cwd", "/tmp/other"),
lambda k, s: k.__setitem__("allowed_tools", ["Read", "Bash"]),
lambda k, s: setattr(s, "active_branch_id", "branch2"),
lambda k, s: setattr(s, "compacted_through_msg_id", "msg42"),
])
def test_fingerprint_changes_on_boot_inputs(mutate):
s = make_session()
kwargs = dict(BASE_KWARGS)
kwargs["mcp_servers"] = dict(BASE_KWARGS["mcp_servers"])
before = boot_fingerprint(kwargs, s)
mutate(kwargs, s)
assert boot_fingerprint(kwargs, s) != before
def test_reuse_respawn_force_and_teardown():
async def run():
pool: Dict[str, ClientHandle] = {}