From 32442e132b46fd919d391c92806a28ab539a9c4c Mon Sep 17 00:00:00 2001 From: EMRG Evolution Date: Thu, 13 Aug 2026 22:04:31 +0800 Subject: [PATCH] emrg: TUI status bar shows current context message count (rant 21:52:18) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The status bar '· N msgs ·' showed the locally-tracked total message count (including compacted history), not the actual messages sent to the LLM. Daemon now reports the authoritative current-context size on every done frame (system + history + user + tool results + assistant replies, rebuilt after auto-compact) via context_messages; TUI uses it instead of the +1 local approximation (falls back to +1 when absent). +1 e2e test asserting context_messages == 5 for a one-round tool flow (system+user+assistant-tool +tool-result+assistant). --- emrg/client/app.py | 9 ++++++++- emrg/server/daemon.py | 6 ++++++ tests/test_ws_e2e.py | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/emrg/client/app.py b/emrg/client/app.py index c873f03..21f92cd 100644 --- a/emrg/client/app.py +++ b/emrg/client/app.py @@ -556,7 +556,14 @@ async def _reconnect(): _last_center = server_id or "emrg" status.update(center=_last_center) term.set_title(f"{session_title or session_id} @ {project_name}") - msg_count += 1; _update_left_extra() + # rant 21:52:18: daemon's done frame reports the authoritative + # current-context message count (system + history + tool results); + # fall back to the local +1 approximation when absent. + if data.get("context_messages") is not None: + msg_count = int(data["context_messages"]) + else: + msg_count += 1 + _update_left_extra() term.render() if "error" in data: err = data["error"]; logger.error("server error: %s", err) diff --git a/emrg/server/daemon.py b/emrg/server/daemon.py index efb3092..5220de2 100644 --- a/emrg/server/daemon.py +++ b/emrg/server/daemon.py @@ -2274,6 +2274,8 @@ async def _run_tool_loop( "done": True, "delta": False, "session_id": session.session_id, + # rant 21:52:18: authoritative current-context message count. + "context_messages": len(messages), }) # Fire-and-forget: reflect on whether to save memories @@ -2448,6 +2450,10 @@ async def _run_tool_loop( "done": True, "delta": False, "session_id": session.session_id, + # rant 21:52:18: current LLM context size (system + history + + # user + all tool results + assistant replies) — authoritative + # for the TUI status bar message count. + "context_messages": len(messages), }) # Fire-and-forget: reflect on whether to save memories diff --git a/tests/test_ws_e2e.py b/tests/test_ws_e2e.py index 574abd1..4f357ba 100644 --- a/tests/test_ws_e2e.py +++ b/tests/test_ws_e2e.py @@ -222,6 +222,7 @@ async def _test(): } await ws.send(json.dumps(task, ensure_ascii=False)) got_delta = got_tool = got_done = False + context_messages = None while True: frame = await asyncio.wait_for(ws.recv(), timeout=10) resp = json.loads(frame) @@ -231,8 +232,14 @@ async def _test(): got_tool = True if resp.get("done"): got_done = True + # rant 21:52:18: done frame must report the + # current LLM context size — system(1) + user(1) + # + assistant(tool_calls)(1) + tool result(1) + + # final assistant(1) = 5 for this one-round flow. + context_messages = resp.get("context_messages") break assert got_delta and got_tool and got_done + assert context_messages == 5 finally: await ws.close() finally: