fix(cloud-task): make question answered state durable across chat switches and restarts#3241
Conversation
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
…tches and restarts Since questions relay over the durable event stream (#3199, #3215), users report that switching chats resets answered questions. Two gaps cause it: 1. The question card held its in-progress step answers in component state. Switching chats unmounts the card, so every answer selected so far was wiped and the card restarted at question 1 on return. The answers now live in a view store keyed by toolCallId, and the card restores them (including free-text input, via a new ActionSelector initialCustomInput seed) on remount. Submit and cancel clear the draft. 2. A question answered after its run terminalized (the resume-as-prompt path) never got a `_posthog/permission_resolved` record: the sandbox that would write one is gone, so the request stays pending in the persisted log forever and any log derivation that escapes the in-memory guards (app restart, another device, a session rebuild) re-surfaces the answered question as a fresh card. The client now appends the resolved marker to the owning run's log itself, tracks responded requestIds so stale snapshots (a marker not yet flushed to storage) cannot re-add them, and the watcher dedups replayed permission_request frames by stream id — they previously bypassed the seenEventIds guard entirely. Generated-By: PostHog Code Task-Id: 9c723d92-b8ef-4c9f-9317-2f53b4644f33
b5c7a04 to
2e05b82
Compare
React Doctor flagged exhaustive-deps on the question card: allQuestions was re-parsed (Zod safeParse) and re-allocated on every render, so every useCallback depending on it re-created each render. Wrap the parse in useMemo keyed on toolCall._meta. Generated-By: PostHog Code Task-Id: 9c723d92-b8ef-4c9f-9317-2f53b4644f33
There was a problem hiding this comment.
The PR exceeds the auto-approval size ceiling (671 lines, 10 files) and has zero reviews. The changes are focused and well-tested, but they touch session permission handling, cloud run log mutation (appending to run logs), and state durability across restarts — all meaningful behavioral changes that warrant at least one human reviewer before merging.
|
Reviews (1): Last reviewed commit: "fix(ui): memoize question meta parsing f..." | Re-trigger Greptile |
Problem
A question's answered state was never durable.
question responses were stored in component state, so switching chats unmounted the permission card and reset all progress. Returning to the chat always restarted multi-step questions from the beginning.
permission requests answered after a run had already terminated were never durably marked as resolved. The response resumed on a new run, but no
_posthog/permission_resolvedentry was written, allowing the same request to reappear after app reloads, session rebuilds, on another device, or from stale snapshots. Replayedpermission_requestevents also bypassed stream deduplication.Fix
persist in-progress question drafts in a shared Zustand store keyed by
toolCallId, preserving step progress and free-text input across remounts. Drafts are cleared on submit or cancel.write
_posthog/permission_resolvedto the run log when resolving or cancelling terminal permission requests, ensuring responses are durably recorded even after the original sandbox has exited.prevent duplicate permission prompts by tracking responded request IDs until the durable log entry is available, and deduplicate all replayed SSE events, including
permission_requestframes.