mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-09 13:21:42 +00:00
fix(tui_gateway): don't fall back context_used to cumulative session_total_tokens
_get_usage substituted the cumulative lifetime session_total_tokens into the current-window context_used when an external context engine did not report last_prompt_tokens, producing impossible status-bar readings (e.g. 1.9m/120k clamped to 100%). Populate context_used/percent only from a real current occupancy; leave the gauge unset otherwise. The built-in compressor always reports last_prompt_tokens, so it's unaffected. Fixes #50421.
This commit is contained in:
parent
6c3545d9e9
commit
83b7c52ece
2 changed files with 56 additions and 4 deletions
|
|
@ -8474,3 +8474,42 @@ class TestResolveRuntimeWithFallback:
|
|||
|
||||
assert agent.model == "gpt-5.5"
|
||||
assert captured["provider"] == "deepseek"
|
||||
|
||||
|
||||
def test_get_usage_does_not_substitute_cumulative_total_for_context_used():
|
||||
"""An external context engine that does not report last_prompt_tokens must
|
||||
not have the cumulative lifetime session_total_tokens shown as its current
|
||||
context occupancy — that substitution produced impossible 1.9m/120k (100%)
|
||||
status-bar readings (#50421). With no real current occupancy known,
|
||||
context_used/percent stay unset rather than wrong."""
|
||||
agent = types.SimpleNamespace(
|
||||
model="test-model",
|
||||
session_total_tokens=1_900_000,
|
||||
context_compressor=types.SimpleNamespace(
|
||||
last_prompt_tokens=0,
|
||||
context_length=120_000,
|
||||
compression_count=0,
|
||||
),
|
||||
)
|
||||
usage = server._get_usage(agent)
|
||||
assert usage.get("context_used") != 1_900_000
|
||||
assert "context_used" not in usage
|
||||
assert "context_percent" not in usage
|
||||
|
||||
|
||||
def test_get_usage_reports_real_current_occupancy():
|
||||
"""When the compressor reports a real current prompt size, context_used is
|
||||
that value (not the cumulative total) and the percent is sane."""
|
||||
agent = types.SimpleNamespace(
|
||||
model="test-model",
|
||||
session_total_tokens=1_900_000,
|
||||
context_compressor=types.SimpleNamespace(
|
||||
last_prompt_tokens=60_000,
|
||||
context_length=120_000,
|
||||
compression_count=2,
|
||||
),
|
||||
)
|
||||
usage = server._get_usage(agent)
|
||||
assert usage["context_used"] == 60_000
|
||||
assert usage["context_max"] == 120_000
|
||||
assert usage["context_percent"] == 50
|
||||
|
|
|
|||
|
|
@ -2964,12 +2964,25 @@ def _get_usage(agent) -> dict:
|
|||
}
|
||||
comp = getattr(agent, "context_compressor", None)
|
||||
if comp:
|
||||
ctx_used = getattr(comp, "last_prompt_tokens", 0) or usage["total"] or 0
|
||||
# context_used is the *current-window* occupancy. Do NOT fall back to
|
||||
# usage["total"] (cumulative lifetime session_total_tokens): for an
|
||||
# external context engine that doesn't report last_prompt_tokens that
|
||||
# substitution showed lifetime totals as the live context fill, yielding
|
||||
# impossible readings such as 1.9m/120k clamped to 100% (#50421).
|
||||
#
|
||||
# Per the issue, populate context_used/percent only from a *real*
|
||||
# current-occupancy value and "leave it unknown otherwise" — so a falsy
|
||||
# last_prompt_tokens (0 or missing, i.e. an engine that doesn't track
|
||||
# per-window occupancy) intentionally emits no gauge rather than a
|
||||
# fabricated 0% or the old cumulative reading. The built-in compressor
|
||||
# always reports a real last_prompt_tokens once a turn runs, so it is
|
||||
# unaffected.
|
||||
last_prompt = getattr(comp, "last_prompt_tokens", 0) or 0
|
||||
ctx_max = getattr(comp, "context_length", 0) or 0
|
||||
if ctx_max:
|
||||
usage["context_used"] = ctx_used
|
||||
if ctx_max and last_prompt:
|
||||
usage["context_used"] = last_prompt
|
||||
usage["context_max"] = ctx_max
|
||||
usage["context_percent"] = max(0, min(100, round(ctx_used / ctx_max * 100)))
|
||||
usage["context_percent"] = max(0, min(100, round(last_prompt / ctx_max * 100)))
|
||||
usage["compressions"] = getattr(comp, "compression_count", 0) or 0
|
||||
# Live count of background/async subagents still running (delegate_task
|
||||
# batches + background single delegations). Mirrors the classic CLI status
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue