fix: prevent send queue flicker when the agent is idle

Claim idle conversation inputs before publishing queue changes so immediately dispatched messages do not briefly appear as pending. Preserve busy conversation queueing and add a regression assertion for notification ordering.

Validation: 369 focused tests, typecheck, and changed-file lint passed. Full-suite runs timed out with failures in other modules; repository lint reports errors in the existing story-graph demo.

Release note: Fix a brief pending-queue flash when sending a message while the agent is idle.
This commit is contained in:
mesalogo
2026-09-16 16:35:13 +08:00
parent 7e11d1099a
commit cc9ea7c718
2 changed files with 17 additions and 10 deletions
+14 -6
View File
@@ -7342,7 +7342,7 @@ describe('registerIpcHandlers agent terminal state', () => {
await harness.dispose()
})
it('dispatches and accepts a queued user message through the renderer', async () => {
it('claims an idle user message before notifying the renderer and accepts its dispatch', async () => {
const runtime = {
runtimeId: 'model',
capability: 'chat',
@@ -7406,14 +7406,22 @@ describe('registerIpcHandlers agent terminal state', () => {
const enqueueHandler = electronMocks.handlers.get(
ipcChannels.conversationQueueEnqueueUser
)
harness.webContents.send.mockClear()
expect(
enqueueHandler?.(trustedEvent(harness.webContents), input)
).toEqual(item)
await vi.waitFor(() =>
expect(harness.webContents.send).toHaveBeenCalledWith(
ipcChannels.conversationQueueDispatch,
{ item, input }
)
expect(harness.webContents.send).toHaveBeenCalledWith(
ipcChannels.conversationQueueDispatch,
{ item, input }
)
const queueChangeIndex = harness.webContents.send.mock.calls.findIndex(
([channel]) => channel === ipcChannels.conversationQueueChanged
)
expect(queueChangeIndex).toBeGreaterThanOrEqual(0)
expect(
harness.assistantDatabase.claimConversationQueueItem.mock.invocationCallOrder[0]
).toBeLessThan(
harness.webContents.send.mock.invocationCallOrder[queueChangeIndex] ?? 0
)
await harness.handler?.(trustedEvent(harness.webContents), {
+3 -4
View File
@@ -6947,13 +6947,12 @@ export function registerIpcHandlers(
contextManager.remove(attachment.id)
}
rendererReadyConversationQueues.add(item.conversationId)
publishConversationQueueChange(item.conversationId)
if (!isConversationExecuting(item.conversationId)) {
readyConversationQueues.add(item.conversationId)
setTimeout(() => {
void pumpConversationQueue(item.conversationId)
}, 0)
// Claim idle sends before exposing pending items to the renderer.
void pumpConversationQueue(item.conversationId)
}
publishConversationQueueChange(item.conversationId)
return item
}
)