Skip to content

fix(app): automatically send queued messages - #2695

Draft
MikoyChinese wants to merge 2 commits into
getpaseo:mainfrom
MikoyChinese:fix/queued-message-auto-drain
Draft

fix(app): automatically send queued messages#2695
MikoyChinese wants to merge 2 commits into
getpaseo:mainfrom
MikoyChinese:fix/queued-message-auto-drain

Conversation

@MikoyChinese

Copy link
Copy Markdown

Linked issue

Closes #2693

Type of change

  • Bug fix
  • New feature
  • Enhancement
  • Refactor
  • Docs

What does this PR do

Queued follow-up messages could remain pending after the active turn completed. A timeline turn_completed event optimistically updated the shared UI agent state to idle before the authoritative directory update arrived, so the later directory update no longer observed a running-to-idle transition and did not drain the queue.

This change keeps the last authoritative daemon state inside AgentDirectoryReplica. Timeline state remains available for optimistic UI updates, while queue draining is triggered only by authoritative running-to-non-running transitions. Archived agents do not drain. The existing FIFO, one-message-per-turn, failure restoration, attachment, snapshot, reconnect, remove, and re-add behavior is preserved.

How did you verify it

Reproduction before the fix

The regression test applies the same event order as the report:

  1. Authoritative agent state is running.
  2. turn_completed optimistically changes the shared UI state to idle.
  3. The authoritative idle agent_update arrives.

Against the old implementation, the test failed with:

Expected: ["agent"]
Received: []

The same test passes after the fix and observes exactly one stopped-running callback.

Automated checks

Run from packages/app where noted:

npx vitest run src/runtime/directory-sync/agent-replica.test.ts --bail=1
3 tests passed

npx vitest run src/runtime/host-runtime.test.ts --bail=1
60 tests passed

npx vitest run src/utils/agent-directory-sync.test.ts --bail=1
4 tests passed

npx vitest run src/utils/agent-directory-reconciliation.test.ts --bail=1
6 tests passed

npm run test:e2e -- e2e/agent-message-submission.spec.ts
1 test passed (41.8s)

The Playwright test uses a real isolated daemon and deterministic provider. It holds the authoritative idle update until after turn_completed has optimistically changed the UI state, then verifies that releasing the update automatically sends the queued message, removes the queue row, and starts the next turn.

Run from the repository root:

npm run build:server
passed

npm run typecheck
passed

npm run lint
0 warnings, 0 errors

npm run format
passed

npm run format:check
passed

git diff --check
passed

HostRuntime coverage also checks FIFO order, one message per turn, original message IDs, duplicate-drain prevention, failed-send restoration, image encoding, uploaded files, modern Forge attachments, and legacy GitHub attachments.

Platform coverage

Platform Tested Notes
iOS No Not tested
Android No Not tested
Web Yes Playwright with a real isolated daemon on Linux
Desktop macOS No Not tested
Desktop Windows Partial Original issue reproduced on v0.2.4; fixed desktop build not yet manually tested
Desktop Linux No Not tested as an Electron build

This is a draft because post-fix Windows desktop manual QA and interaction video are still pending.

Checklist

  • One focused change
  • npm run typecheck passes
  • npm run lint passes
  • npm run format passes
  • QA evidence
  • Tests added or updated where it made sense

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Queued follow-up does not send after the active turn completes

1 participant