fix(tui_gateway): manual /compress keeps the session workspace in the stored prompt, so the next resume hits the prompt cache - #120158
Conversation
session.compress runs compress_now on the RPC thread without the session context, so the compaction-boundary system-prompt rebuild resolved the backend's cwd (the process HOME) and persisted a prompt whose cwd line every later process rejects as stale runtime. The next resume (TUI or 'hermes chat --resume') then rebuilt the prompt from scratch - a second prompt-cache miss right after the sanctioned compaction one - and, on the oneshot path, skipped the tools pin. Bind the session cwd exactly like the sibling prompt-persist sites (server.py _persist_live_session_system_prompt, methods_slash.py). Exposed by tests/e2e/core/history/test_prefix_stability.py[tui_gateway_restarts].
Invariant for the previous commit: the compaction-boundary work inside _compress_session_history resolves the session's workspace, not the backend process cwd, and the binding does not leak past the call. Red on origin/main.
PR Review — #120158 (P0 monitor pass)Premise (verified): Change: 6 LOC, one Tests: Non-blocking: the nested bind passes no Looks good: fixed at the shared choke point, matches the established pattern, cache impact measured end to end (E2E prefix-stability run in the body). Merge decision stays with the maintainer. |
A manual
/compressin the TUI/Desktop no longer persists a system prompt pointing at the backend's home directory, so the next resume reuses it instead of rebuilding it and missing the prompt cache a second time.tui_gateway/session_compression.py::_compress_session_historybinds the session context and cwd (_set_session_context(key, cwd=_session_cwd(session))) aroundcompress_now, then clears it. This matches the other RPC-thread sites that persist or inspect the prompt (server.py::_persist_live_session_system_prompt,methods_slash.py,model_switch.py).session.compressRPC, thecommand.dispatchcompress branch, and theslash.execmirror.tests/tui_gateway/test_compress_session_cwd.py. The work done at the compaction boundary must resolve the session workspace, and the binding must not leak past the call. It is red onorigin/main(it resolves the process cwd) and green with the fix.Root cause:
session.compressruns on the RPC thread, which has no session context. So the system-prompt rebuild at the compaction boundary resolved the backend's cwd (the processHOME) and stored it. Every later process (a gateway resume orhermes chat --resume) rejected that stored prompt as stale runtime and rebuilt it. That caused a second full cache miss right after the sanctioned compaction miss, and on the oneshot path the tools pin was skipped too.Live repro: E2E
tests/e2e/core/history/test_prefix_stability.py -k tui_gateway_restartsdrives realpython -m tui_gateway.entryprocesses, one durable session, with the cwd flipping between hops.origin/main07646a7):request 9 (in hop 4 (gw in work-b)): messages[0] (system) changed; first diverging byte at 6382: '…/home\nScratch directory…' vs '…/work-a\nScratch directory…', 1 failedThe E2E file isn't part of this PR. It lands separately with the core E2E-suite PR. I copied it in temporarily for the red/green run above.
test_compress_session_cwd.pyonorigin/main/…/test_manual_compress_runs_unde0!=/…/workspace)test_compress_session_cwd.pywith fixscripts/run_tests.sh tests/tui_gateway/test_tui_gateway_server.pyhit the per-file 300s cap at load ~90, and re-run alone (with both compress files) it gave 627 passed. One unrelated timing flake intest_hosted_room_driver_runtime.pypassed on retryruff check,check_no_tmp_literals.py,git diff --checkDuplicate sweep: no open or closed PR binds the session cwd around manual compression. I searched
compress cwd,session.compress,compress_now session context,compress system prompt cwd stale,compress cache miss resume,_compress_session_history,session cwd compress tuiandstale runtime system prompt rebuild./inittargets the session's active directory instead of the process cwd). It's the same class (an RPC-thread handler resolving the process cwd), but a different call site. Neither PR supersedes the other.Infographic