fix(ai-chat): reset chat on New chat during the first turn's stream (#161) #162
Closed
Ghost
wants to merge 3 commits from
fix/ai-chat-new-chat-during-stream into develop
pull from: fix/ai-chat-new-chat-during-stream
merge into: vvzvlad:develop
vvzvlad:main
vvzvlad:test/244-part-b
vvzvlad:fix/255-ws-redis-adapter-leak
vvzvlad:feat/251-intentional-clear
vvzvlad:fix/252-e2e-open-handles
vvzvlad:feat/184-autonomous-agent-runs
vvzvlad:feat/221-image-captions
vvzvlad:feat/git-sync
vvzvlad:refactor/193-tool-spec-registry
vvzvlad:fix/244-dataloss-bugs
vvzvlad:fix/embeddings-reindex-progress
vvzvlad:develop
vvzvlad:feature/offline-sync
vvzvlad:feat/229-catalog-yaml
vvzvlad:feat/243-blob-sandbox
vvzvlad:feat/228-inline-footnotes
vvzvlad:fix/qa-ui-bugs-216-218
vvzvlad:feature/agent-roles-catalog
vvzvlad:fix/share-alias-rename
vvzvlad:fix/ai-chat-empty-render
vvzvlad:feat/191-chat-doc-binding
vvzvlad:feat/201-temporary-notes
vvzvlad:feat/198-interrupt-agent
vvzvlad:feat/ai-chat-full-history
vvzvlad:feat/199-ai-generate-title
vvzvlad:feat/205-share-aliases
vvzvlad:batch/issues-189-187-170
vvzvlad:feat/170-mcp-test-button
vvzvlad:feat/189-context-badge
vvzvlad:feat/198-interrupt-agent-send-now
vvzvlad:fix/issues-190-159
vvzvlad:fix/ai-chat-stream-perf
vvzvlad:batch/issues-2026-06-25
vvzvlad:feat/ai-chat-persistent-history
vvzvlad:fix/ai-chat-copy-chat-wysiwyg
vvzvlad:fix/ai-stream-reset-resilience
vvzvlad:fix/ai-stream-undici-timeout
vvzvlad:fix/footnote-review-1227-followup
vvzvlad:fix/ai-chat-token-counter-realtime
vvzvlad:docs/manual-qa-test-plan
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8f9d7fe0bd |
test(ai-chat): cover the #161 New-chat-during-stream reset + changelog
Address PR #162 review must-fixes: - CHANGELOG: add an [Unreleased] > Fixed bullet for #161 (New chat during the first turn's stream now resets the thread; a late refetch/onFinish from the abandoned thread no longer pulls the user back in). - Re-anchor the stale startNewChat/cancelPendingAdoption test to selectChat: startNewChat now calls startFreshThread, but cancelPendingAdoption still backs selectChat, so the disarm guard is decoupled and kept valid. - Add a test pinning that startFreshThread() disarms the armed error-path fallback (the justification for dropping cancelPendingAdoption from startNewChat). - Add a ChatThread render test (mocked useChat) asserting the onError branch forwards onTurnFinished(undefined, threadKey). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
4d69518037 |
Merge branch 'develop' into fix/ai-chat-new-chat-during-stream (#162)
Resolve the PR #162 review blocker: the branch no longer merged into develop after #174 (onServerChatId early adoption) and #183 (server-sourced Copy/export) landed, which touched the same files. Conflict resolution (ai-chat-window.tsx, chat-thread.tsx, use-chat-session.ts): - Keep develop's onServerChatId wiring (#174) intact in all three files. - Keep develop's removal of the old liveStateRef / liveThreadRef / MutableRefObject live-export mechanism (deleted by #174/#183); it was only inherited by this branch and is not part of #161 — not resurrected. - Graft #162's actual fix on top: startFreshThread() (unconditional remount even when activeChatId stays null) and the abandoned-thread guard (threadKeyRef + finishingThreadKey on onTurnFinished, forwarded as ChatThread's threadKey through onFinish/onError). Also apply the review's simplification: drop the now-redundant cancelPendingAdoption() call inside startNewChat (startFreshThread() already nulls pendingNewChatRef); the export stays, still used by selectChat. ai-chat client suite green (176 passed), no conflict markers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
cee231b136 |
fix(ai-chat): reset chat on New chat during the first turn's stream (#161)
Pressing "New chat" while a brand-new chat's first turn was still streaming only removed the role badge — the thread, session and stream were kept. The thread remount is driven by a render-phase reconciler in useChatSession that fires only when activeChatId !== thread.chatId; on a not-yet-adopted new chat both are null, so startNewChat's setActiveChatId(null) was a no-op and nothing remounted. - useChatSession: add startFreshThread(), which unconditionally dispatches a reconcile to a fresh mount key so ChatThread remounts even when activeChatId stays null. startNewChat now calls it. - Guard against the abandoned thread's late finish: ai@6's useChat does not abort on unmount and proxies its callbacks, so onFinish/onError of the chat the user just left still fire and would adopt it back. onTurnFinished now takes the finishing thread's key and, when it no longer matches the mounted thread, only refreshes the chat list — no adoption, no fallback arming, no per-chat message invalidation. ChatThread forwards its threadKey in both onFinish and onError. An omitted key (legacy callers/tests) counts as the current thread, preserving the #137 adoption behavior. Tests: 3 new useChatSession cases (fresh-thread remount with activeChatId null, abandoned-thread finish rejected, current-thread finish still adopts). Full ai-chat suite green (183). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |