Repository navigation
fix(client): clear pending prompts the transcript shows were delivered - #61679
Conversation
There was a problem hiding this comment.
The change looks sound. I ran the new tests against the base data.ts: both fail there and pass with this change. The full packages/client suite (259 tests) and tsc --noEmit pass. I also traced the reconnect path. Disconnecting invalidates the cached reads, and the TUI then reloads the inbox and the transcript at the same time. The fix holds whichever finishes first, since removePending records the removal for a concurrent inbox read. I couldn't drive this end to end in the TUI because it needs the event stream dropped mid-delivery.
Public API is unchanged: this only changes internal client state handling.
No blocking concerns.
There was a problem hiding this comment.
The new commit is correct. The "free usage limit" fixture listed msg_queued_user as both waiting in the inbox and already delivered in the transcript, which real data can't do. Now that a transcript read clears delivered rows, that test failed until the message came out of the transcript fixture. I confirmed it fails with the old fixture and passes with the new one. tsc in packages/tui gives the same errors as on the base.
Public API is unchanged. No new concerns.
Issue for this PR
Closes #
Type of change
What does this PR do?
A submitted prompt is shown as Pending right away and stays in the client's outbox until its
session.inbox.enqueuedevent arrives. The event stream has no replay, so if that event is lost in a reconnect, the row never leaves the outbox. In an idle session the prompt is delivered within milliseconds, so the inbox read after the reconnect doesn't find it, and the outbox guard keeps it. The prompt shows as Pending forever, even though it already ran. This was seen in the desktop app connected to a remote server; the TUI shares the same data layer.Transcript reads only return delivered input. Now, when
message.syncreturns a message whose ID is a pending row, the client takes it out of the outbox and removes the row. The reload after a reconnect (and the first load when a session is opened) clears stuck prompts that way.How did you verify your code works?
Two new tests in
packages/client/test/solid-inbox-race.test.ts: one drops only the delivery event, the other drops every event after the POST succeeds and checks that a later inbox read doesn't bring the row back. Both fail without the change.bun test(259 tests) andtsc --noEmitpass inpackages/client.Checklist
Added by the opencode bot (AI-generated).
Fixes #56748
Related: #59615