Skip to content

feat: keep assistant conversations per user in sessionStorage - #556

Merged
caitlon merged 1 commit into
devfrom
feat/assistant-chat-storage
Oct 9, 2026
Merged

caitlon merged 1 commit into
devfrom
feat/assistant-chat-storage

Conversation

@caitlon

@caitlon caitlon commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Problem

A conversation with the assistant lives only in the hook's memory, so a reload or a closed panel loses it, and a shared browser could leak one user's thread to the next.

Change

useAssistantChat loads its thread from sessionStorage under assistant-chat:<userId>:<projectId|general> and writes it back when a turn is appended, settles or is cleared, never on mount and never per token. Invalid entries are dropped on load, a pending answer becomes cut, empty or not, so a lost answer stays visible, and the loaded copy is capped at 40 messages. A stored message whose error, sources, toolsUsed, checks or timing has the wrong shape is dropped like any other invalid entry. clearAssistantHistory() removes every stored thread and bumps a module-level epoch; a hook instance whose thread was loaded under an older epoch no longer writes, so a sign-out that runs before React unmounts the panel cannot write the in-flight thread back. The unmount cleanup only aborts the request in flight. AssistantRoot clears the history in its existing sign-out listener, before it closes the panel. Storage failures (QuotaExceededError, blocked storage) are caught.

Verification

useAssistantChat.test.ts gains 27 new it and it.each declarations (37 test cases once the tables run) and AssistantRoot.test.tsx gains 2 (2 cases); the hook file now runs 86 cases against 49 before. They cover: load and save round trip, cap, invalid entries and the shape check on the optional parts, user and project swaps while mounted, mount writes nothing, an idle conversation cleared removes its key, a clear with a token render still on its way, sign-out then unmount with a turn in flight leaves storage empty, sign-out then settle leaves it empty, QuotaExceededError does not throw, blocked storage, a stored empty pending answer loads as cut, and the sign-out listener clearing before it closes. Two existing tests and two beforeEach blocks changed: in useAssistantChat.test.ts, the beforeEach also clears sessionStorage, "empties the conversation and aborts the request in flight" now also asserts the stored copy is dropped, and "aborts the request when the hook unmounts" now asserts the partial is not stored; in AssistantRoot.test.tsx the beforeEach also clears sessionStorage. npm run lint, npm run typecheck, npm run test:coverage (thresholds hold) and ./scripts/ci/ci-local.sh fast are green.

Migrations

None.

Screenshots

None, no UI change.

@caitlon caitlon added this to the v1.1-polish milestone Oct 9, 2026
@caitlon caitlon added type:feature New functionality area:frontend React frontend labels Oct 9, 2026
@caitlon caitlon self-assigned this Oct 9, 2026
@greptile-apps

greptile-apps Bot commented Oct 9, 2026

Copy link
Copy Markdown

Automatic reviews are disabled for this repository.

@github-actions github-actions Bot added the size:L 601 to 1000 changed lines. Over the 300 to 600 target. label Oct 9, 2026
@sonarqubecloud

sonarqubecloud Bot commented Oct 9, 2026

Copy link
Copy Markdown

@caitlon
caitlon merged commit d57e690 into dev Oct 9, 2026
24 of 31 checks passed
@caitlon
caitlon deleted the feat/assistant-chat-storage branch October 9, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:frontend React frontend size:L 601 to 1000 changed lines. Over the 300 to 600 target. type:feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant