Files
hermes-webui/tests/test_issue3225_rename_sync.py
nesquena-hermes 9b933e2c83
Some checks failed
Release & Docker / release (push) Has been cancelled
Release v0.51.266 — Release IH (stage-r16) (#3641)
## Release v0.51.266 — Release IH (stage-r16)

One agent-authored APPROVED fix + two un-held streaming/SSE fixes.

### Fixed
| Issue/PR | Author | Fix |
|----------|--------|-----|
| #3635 (#3637) | @nesquena-hermes (nesquena APPROVED) | Composer profile chip reads `S.activeProfile` again — a #3331 regression keyed it on the loaded session's profile, so opening a cross-profile session made the chip disagree with the dropdown checkmark and misrepresent where the next message routes. #3331's project/session-op scoping is unaffected. |
| #3587 (#3605) | @rodboev | Reasoning persists to the correct intermediate assistant message in multi-turn tool flows. The index only advanced in `on_interim_assistant` (suppressed for contentless tool-call messages) → post-tool reasoning was mis-attributed; it now also advances at the `on_tool` boundary, guarded against over-increment. **(un-held — finding resolved)** |
| #2660 (#3558) | @franksong2702 | Session-event SSE no longer wakes every tab across profiles and never drops a relevant refresh — profile attached when known, root/`default` aliases stay unscoped, and the `maxsize=1` queue falls back to unscoped refresh-all on a profile-mismatch coalesce. **(un-held — both findings resolved)** |

### Gate
- Full pytest suite: **7770 passed, 0 failed**
- ESLint: CLEAN · ruff: CLEAN · browser-smoke: CLEAN
- Codex (regression): **SAFE TO SHIP** — chip matches dropdown/routing (no #3331 scoping regression), reasoning-index advance composes with the agent's tool/interim callback ordering, session-events coalesce safely with no dropped refresh and no profile data leak (`/api/sessions` still server-side filtered).

Co-authored-by: nesquena <nesquena@users.noreply.github.com>
Co-authored-by: rodboev <rodboev@users.noreply.github.com>
Co-authored-by: franksong2702 <franksong2702@users.noreply.github.com>
2026-06-05 00:44:03 -07:00

32 lines
1.6 KiB
Python

"""Regression coverage: WebUI session rename writes through to state.db (#3225).
The /api/session/rename handler must call _sync_session_title_to_insights(s),
just like the sibling /api/session/title/regenerate handler does, so a rename
propagates the new title to the agent's state.db. Without it the TUI and CLI
keep showing the stale name. Static source-text assertion that mirrors
test_regenerate_endpoint_syncs_title_to_state_db_when_enabled.
"""
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
ROUTES_PY = (ROOT / "api" / "routes.py").read_text(encoding="utf-8")
def test_rename_endpoint_syncs_title_to_state_db():
start_idx = ROUTES_PY.index('"/api/session/rename"')
end_idx = ROUTES_PY.index('"/api/session/title/regenerate"', start_idx)
block = ROUTES_PY[start_idx:end_idx]
assert "_sync_session_title_to_insights(s)" in block, (
"rename handler must call _sync_session_title_to_insights(s) so the "
"new title reaches state.db, matching the regenerate handler"
)
assert 'publish_session_list_changed("session_rename", profile=getattr(s, "profile", None))' in block
# Sync must run BEFORE the list-changed publish, matching the regenerate
# handler, so SSE subscribers refresh after state.db holds the new title.
sync_idx = block.index("_sync_session_title_to_insights(s)")
publish_idx = block.index('publish_session_list_changed("session_rename", profile=getattr(s, "profile", None))')
assert sync_idx < publish_idx, (
"rename must sync to state.db before publishing the list-changed event"
)