fix: cancel cleanup no longer depends on SSE event (closes #299)

cancelStream() now clears S.activeStreamId, calls setBusy(false),
setStatus(''), and hides the cancel button directly after the cancel
API request completes. Previously cleanup depended on the SSE 'cancel'
event, which never arrived if the connection was already closed —
leaving 'Cancelling...' status and busy spinner stuck indefinitely.

The SSE cancel handler in messages.js still fires when the connection
is alive and performs additional cleanup (adds 'Task cancelled.' message,
clears tool cards). All operations are idempotent.

9 new tests in tests/test_sprint36.py.

Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
This commit is contained in:
nesquena-hermes
2026-04-12 11:08:59 -07:00
committed by GitHub
parent 74a4263056
commit bd3ec45aa9
3 changed files with 187 additions and 3 deletions

View File

@@ -6,6 +6,11 @@
---
## [v0.49.4] Cancel stream cleanup guaranteed (PR #309, fixes #299)
- **Reliable cancel cleanup** (closes #299): `cancelStream()` no longer depends on the SSE `cancel` event to clear busy state and status text. Previously, if the SSE connection was already closed when cancel fired, "Cancelling..." would linger indefinitely. Now `cancelStream()` clears `S.activeStreamId`, calls `setBusy(false)`, `setStatus('')`, and hides the cancel button directly after the cancel API request — regardless of SSE connection state. The SSE cancel handler still runs when the connection is alive (all operations are idempotent).
- 9 new tests in `tests/test_sprint36.py`; 740 tests total (up from 731)
## [v0.49.3] Session title guard + breadcrumb nav + wider panel (PRs #301, #302)
- **Preserve user-renamed session titles** (PR #301 / closes #300): `title_from()` now only runs when the session title is still `'Untitled'`. Previously it overwrote user-assigned titles on every conversation turn.