diff options
| author | Adam Malczewski <[email protected]> | 2026-06-07 02:41:37 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-07 02:41:37 +0900 |
| commit | 1144a8027a3d0446e407f98c5cddc3a8c78831d5 (patch) | |
| tree | ac7d0039262cbc73ed418795524d17a16799ba47 /src/core/chunks/reducer.ts | |
| parent | 1973da082ea69e123433e12a560cf1e3cbb04376 (diff) | |
| download | dispatch-web-1144a8027a3d0446e407f98c5cddc3a8c78831d5.tar.gz dispatch-web-1144a8027a3d0446e407f98c5cddc3a8c78831d5.zip | |
fix: optimistic user message echo + tabs persistence
Bug 1 (sent message didn't appear until turn end): the transcript only folded
assistant AgentEvents, so the user's own message showed only after turn-sealed
resync. Add core/chunks appendUserMessage() (provisional user chunk, superseded
on history sync) and call it in chat send() — the message now renders instantly.
Bug 2 (tabs didn't persist on refresh): the app passed { storage: undefined }
to createLocalStore, which the adapter treats as a no-op store, so nothing was
saved. Default to globalThis.localStorage. Regression test exercises the
non-injected path.
Also updated app store tests for the echo (assistant-vs-user chunk filtering).
Verified: svelte-check 0/0, vitest 288 (stable x2), biome clean, build ok.
Diffstat (limited to 'src/core/chunks/reducer.ts')
| -rw-r--r-- | src/core/chunks/reducer.ts | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/core/chunks/reducer.ts b/src/core/chunks/reducer.ts index 0a8ea54..d3b999d 100644 --- a/src/core/chunks/reducer.ts +++ b/src/core/chunks/reducer.ts @@ -166,3 +166,19 @@ export function foldEvent(state: TranscriptState, event: AgentEvent): Transcript } } } + +/** + * Optimistically append a user message to the provisional list. + * Flushes any in-progress accumulating chunk first (defensively). + * The provisional user chunk is superseded when applyHistory receives + * the authoritative committed chunks after a turn seals. + */ +export function appendUserMessage(state: TranscriptState, text: string): TranscriptState { + const provisional = flushAccumulating(state.provisional, state.accumulating); + const userChunk: Chunk = { type: "text", text }; + return { + ...state, + provisional: [...provisional, { role: "user", chunk: userChunk }], + accumulating: null, + }; +} |
