Repository navigation
Commit 1ad4f14
committed
fix(chat): a teardown invalidates in-flight work instead of racing it
Review on #83, and the first point is sharp: the teardown was losing a race it did not know
it was in.
Closing the tab mid-stream calls abort(), and the abort lands in handleSend's catch AFTER
resetConversationState has already cleared `conversation` — where the abort branch pushed
the partial reply straight back in. The result was a dangling assistant turn with no user
turn in front of it, shipped to the model on the next send: exactly the leak the teardown
exists to prevent, reintroduced by the teardown's own abort().
agentFlow's finally was worse than reported. runAgent holds `agentMessages` BY REFERENCE,
so a teardown that rebinds the global leaves the run pushing into an orphaned array — and
then `agentMessages.slice(sessTurnStart)` slices the NEW empty one with an index into the
old, recording an empty turn against the wrong session. `abort = null` and
`currentCheckpoint = null` are worse still: those clobber whatever turn came next, leaving
a fresh run unstoppable and its checkpoint unclosed.
Fixed with an epoch. resetConversationState bumps `conversationEpoch` FIRST — before
clearing anything, so an abort landing mid-teardown already reads as stale — and each turn
captures the epoch before installing its AbortController, then checks it before writing
anything back. It also now clears pending approvals/questions, which the guarded finally no
longer does on a torn-down turn.
Second point: the chatStartLocation docstring still called `secondarySidebar` a supported
surface ("kept because the sidebar is the right answer when…") while the code below mapped
it away as legacy. In-code documentation sitting directly on top of the change is the worst
place to leave a contradiction.
Guards, each bypass-verified by reverting the fix:
- the teardown no longer invalidating in-flight work
- the epoch bumped AFTER clearing, which leaves the race window open
- handleSend pushing back without checking; the finally nulling a new turn's controller
- agentFlow's finally clobbering the next turn
- the epoch captured after the controller is installed
- the docstring dropping the legacy marker
Caught while wiring it: handleSend referenced `epoch` without capturing it — a
ReferenceError at runtime that `node --check` cannot see, because it only checks syntax.
23 tests in chatSurface, 34 suites green.1 parent 6fd14c2 commit 1ad4f14
2 files changed
Lines changed: 85 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
66 | 70 | | |
67 | 71 | | |
68 | 72 | | |
| |||
1123 | 1127 | | |
1124 | 1128 | | |
1125 | 1129 | | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
1126 | 1136 | | |
1127 | 1137 | | |
1128 | 1138 | | |
| |||
1594 | 1604 | | |
1595 | 1605 | | |
1596 | 1606 | | |
| 1607 | + | |
1597 | 1608 | | |
1598 | 1609 | | |
1599 | 1610 | | |
| |||
1689 | 1700 | | |
1690 | 1701 | | |
1691 | 1702 | | |
| 1703 | + | |
| 1704 | + | |
| 1705 | + | |
| 1706 | + | |
| 1707 | + | |
| 1708 | + | |
1692 | 1709 | | |
1693 | 1710 | | |
1694 | 1711 | | |
| |||
1736 | 1753 | | |
1737 | 1754 | | |
1738 | 1755 | | |
| 1756 | + | |
1739 | 1757 | | |
1740 | 1758 | | |
1741 | 1759 | | |
| |||
1764 | 1782 | | |
1765 | 1783 | | |
1766 | 1784 | | |
| 1785 | + | |
| 1786 | + | |
| 1787 | + | |
| 1788 | + | |
| 1789 | + | |
1767 | 1790 | | |
1768 | 1791 | | |
1769 | 1792 | | |
| |||
1772 | 1795 | | |
1773 | 1796 | | |
1774 | 1797 | | |
1775 | | - | |
| 1798 | + | |
| 1799 | + | |
| 1800 | + | |
1776 | 1801 | | |
1777 | 1802 | | |
1778 | 1803 | | |
| |||
2369 | 2394 | | |
2370 | 2395 | | |
2371 | 2396 | | |
2372 | | - | |
2373 | | - | |
2374 | | - | |
2375 | | - | |
| 2397 | + | |
| 2398 | + | |
| 2399 | + | |
| 2400 | + | |
| 2401 | + | |
| 2402 | + | |
2376 | 2403 | | |
2377 | 2404 | | |
2378 | 2405 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
401 | 401 | | |
402 | 402 | | |
403 | 403 | | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
404 | 457 | | |
0 commit comments