Skip to content

fix: persist context_length/threshold_tokens/last_prompt_tokens in Session model#1341

Closed
jasonjcwu wants to merge 1 commit intonesquena:masterfrom
jasonjcwu:jasonjcwu/fix/session-context-fields
Closed

fix: persist context_length/threshold_tokens/last_prompt_tokens in Session model#1341
jasonjcwu wants to merge 1 commit intonesquena:masterfrom
jasonjcwu:jasonjcwu/fix/session-context-fields

Conversation

@jasonjcwu
Copy link
Copy Markdown
Contributor

These fields are written by streaming.py during context compression but were never stored in the Session object — causing the context window indicator to show 0% after a page reload.

Changes:

  • Session.init accepts context_length, threshold_tokens, last_prompt_tokens
  • save() includes them in METADATA_FIELDS (written before messages array)
  • compact() exposes them for the GET /api/session response
  • routes.py returns them alongside existing usage fields

…ssion model

These fields are written by streaming.py during context compression but
were never stored in the Session object — causing the context window
indicator to show 0% after a page reload.

Changes:
- Session.__init__ accepts context_length, threshold_tokens, last_prompt_tokens
- save() includes them in METADATA_FIELDS (written before messages array)
- compact() exposes them for the GET /api/session response
- routes.py returns them alongside existing usage fields
nesquena-hermes added a commit that referenced this pull request Apr 30, 2026
Pre-release Opus + nesquena review on v0.50.246 caught that PR #1341
added the data-structure scaffolding (Session.__init__ accepts the 3
fields, save() persists them, compact() exposes them, GET /api/session
returns them) but did NOT add the writer that actually populates them.

Without a writer, the user-visible bug (context-ring shows 0% after
page reload) was NOT fixed by #1341 alone — the fields stayed None
forever because nothing wrote to s.context_length anywhere.

Adds the writer at api/streaming.py:2188 (post-merge per-turn save block,
before s.save()) so the values from agent.context_compressor land on
disk and survive page reloads.

Also moves the SSE usage payload comment to clarify that the live SSE
payload and the session-level persistence are now distinct paths
(payload below, persistence above).

Adds tests/test_pr1341_context_window_persistence.py — 6 structural +
round-trip tests covering Session __init__/save/compact, the routes
response, and the streaming.py writer placement.

Closes #1318 (the actual user-visible bug, not just the scaffolding).
@nesquena-hermes
Copy link
Copy Markdown
Collaborator

Shipped in v0.50.246 via batch release PR #1343 (merge commit dec4b486). Thanks @fxd-jason! 🙏

Live now at https://github.com/nesquena/hermes-webui/releases/tag/v0.50.246.

Released alongside 4 other contributor fixes — see the v0.50.246 entry in CHANGELOG.md.

nesquena-hermes added a commit that referenced this pull request Apr 30, 2026
…mpressor missing (#1318 follow-up) (#1348)

* fix(streaming): fallback to model_metadata for context_length when compressor missing (#1318 follow-up)

PR #1318 (shipped in v0.50.246 via PR #1341 + commit a5c10d5) persisted
context_length on the session so the context-ring indicator survives
page reloads. But the writer only fired when agent.context_compressor
was present and reported a non-zero value. Fresh agents, interrupted
streams, or compressors without the attribute would still leave
s.context_length=0 — and the indicator would still show 0% on reload.

This follow-up adds a fallback that calls
agent.model_metadata.get_model_context_length(model, base_url) when the
compressor didn't populate the value. The function returns a sensible
static context window for any known model (with a 256K default for
unknown models). Wrapped in a broad try/except because older
hermes-agent builds may not expose the helper.

Sourced from PR #1344 (@jasonjcwu) — extracted into this focused
follow-up after #1344 was closed as superseded by #1341.

Adds 6 structural tests covering: import + call presence, falsy-gate,
agent.model/base_url passing, exception swallowing, save() ordering,
result assignment.

Closes the data-flow gap in #1318 for the compressor-missing case.

* test: relax pr1341 block-size assertion to accommodate the new fallback

---------

Co-authored-by: nesquena-hermes <[email protected]>
pull Bot pushed a commit to JamesWilliam1977/hermes-webui that referenced this pull request Apr 30, 2026
pull Bot pushed a commit to JamesWilliam1977/hermes-webui that referenced this pull request Apr 30, 2026
Combines:
- 4 contributor PRs (nesquena#1335 user fenced code, nesquena#1337 mermaid+cache-bust,
  nesquena#1339 fallback_providers list, nesquena#1341 context_length persistence)
- Self-built nesquena#1338 (cancel data-loss + activity panel) — already
  independently APPROVED by nesquena before absorption
- CONTRIBUTORS.md and markdown refresh from nesquena#1340

See CHANGELOG.md for the full list with author credit.
JKJameson pushed a commit to JKJameson/hermes-webui that referenced this pull request Apr 30, 2026
…ength (nesquena#1349)

Frontend companion to backend fix in v0.50.246 (nesquena#1341 + a5c10d5).
Default context window to 128K when usage.context_length is falsy.
Show '(est. 128K)' label when using the default.
Use input_tokens as fallback for last_prompt_tokens.

Co-authored-by: jasonjcwu <[email protected]>
GeoffBao pushed a commit to GeoffBao/hermes-webui that referenced this pull request May 1, 2026
GeoffBao pushed a commit to GeoffBao/hermes-webui that referenced this pull request May 1, 2026
Combines:
- 4 contributor PRs (nesquena#1335 user fenced code, nesquena#1337 mermaid+cache-bust,
  nesquena#1339 fallback_providers list, nesquena#1341 context_length persistence)
- Self-built nesquena#1338 (cancel data-loss + activity panel) — already
  independently APPROVED by nesquena before absorption
- CONTRIBUTORS.md and markdown refresh from nesquena#1340

See CHANGELOG.md for the full list with author credit.
GeoffBao pushed a commit to GeoffBao/hermes-webui that referenced this pull request May 1, 2026
…a#1318 fix

Pre-release Opus + nesquena review on v0.50.246 caught that PR nesquena#1341
added the data-structure scaffolding (Session.__init__ accepts the 3
fields, save() persists them, compact() exposes them, GET /api/session
returns them) but did NOT add the writer that actually populates them.

Without a writer, the user-visible bug (context-ring shows 0% after
page reload) was NOT fixed by nesquena#1341 alone — the fields stayed None
forever because nothing wrote to s.context_length anywhere.

Adds the writer at api/streaming.py:2188 (post-merge per-turn save block,
before s.save()) so the values from agent.context_compressor land on
disk and survive page reloads.

Also moves the SSE usage payload comment to clarify that the live SSE
payload and the session-level persistence are now distinct paths
(payload below, persistence above).

Adds tests/test_pr1341_context_window_persistence.py — 6 structural +
round-trip tests covering Session __init__/save/compact, the routes
response, and the streaming.py writer placement.

Closes nesquena#1318 (the actual user-visible bug, not just the scaffolding).
GeoffBao pushed a commit to GeoffBao/hermes-webui that referenced this pull request May 1, 2026
…mpressor missing (nesquena#1318 follow-up) (nesquena#1348)

* fix(streaming): fallback to model_metadata for context_length when compressor missing (nesquena#1318 follow-up)

PR nesquena#1318 (shipped in v0.50.246 via PR nesquena#1341 + commit a5c10d5) persisted
context_length on the session so the context-ring indicator survives
page reloads. But the writer only fired when agent.context_compressor
was present and reported a non-zero value. Fresh agents, interrupted
streams, or compressors without the attribute would still leave
s.context_length=0 — and the indicator would still show 0% on reload.

This follow-up adds a fallback that calls
agent.model_metadata.get_model_context_length(model, base_url) when the
compressor didn't populate the value. The function returns a sensible
static context window for any known model (with a 256K default for
unknown models). Wrapped in a broad try/except because older
hermes-agent builds may not expose the helper.

Sourced from PR nesquena#1344 (@jasonjcwu) — extracted into this focused
follow-up after nesquena#1344 was closed as superseded by nesquena#1341.

Adds 6 structural tests covering: import + call presence, falsy-gate,
agent.model/base_url passing, exception swallowing, save() ordering,
result assignment.

Closes the data-flow gap in nesquena#1318 for the compressor-missing case.

* test: relax pr1341 block-size assertion to accommodate the new fallback

---------

Co-authored-by: nesquena-hermes <[email protected]>
GeoffBao pushed a commit to GeoffBao/hermes-webui that referenced this pull request May 1, 2026
…ength (nesquena#1349)

Frontend companion to backend fix in v0.50.246 (nesquena#1341 + a5c10d5).
Default context window to 128K when usage.context_length is falsy.
Show '(est. 128K)' label when using the default.
Use input_tokens as fallback for last_prompt_tokens.

Co-authored-by: jasonjcwu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants