diff --git a/packages/coding-agent/src/core/agent-session.ts b/packages/coding-agent/src/core/agent-session.ts index 0f5aa1105..e4f53004b 100644 --- a/packages/coding-agent/src/core/agent-session.ts +++ b/packages/coding-agent/src/core/agent-session.ts @@ -1141,19 +1141,17 @@ export class AgentSession { if (event.type === "message_start" && event.message.role === "user") { this._overflowRecoveryAttempted = false; const messageText = contentText(event.message.content, ""); - if (messageText) { - // Check steering queue first - const steeringIndex = this._steeringMessages.indexOf(messageText); - if (steeringIndex !== -1) { - this._steeringMessages.splice(steeringIndex, 1); + // Check steering queue first + const steeringIndex = this._steeringMessages.indexOf(messageText); + if (steeringIndex !== -1) { + this._steeringMessages.splice(steeringIndex, 1); + this._emitQueueUpdate(); + } else { + // Check follow-up queue + const followUpIndex = this._followUpMessages.indexOf(messageText); + if (followUpIndex !== -1) { + this._followUpMessages.splice(followUpIndex, 1); this._emitQueueUpdate(); - } else { - // Check follow-up queue - const followUpIndex = this._followUpMessages.indexOf(messageText); - if (followUpIndex !== -1) { - this._followUpMessages.splice(followUpIndex, 1); - this._emitQueueUpdate(); - } } } // Normalize queued images at delivery, before events and persistence see the message, diff --git a/packages/coding-agent/test/suite/agent-session-queue.test.ts b/packages/coding-agent/test/suite/agent-session-queue.test.ts index d198cbd2d..39a4470d2 100644 --- a/packages/coding-agent/test/suite/agent-session-queue.test.ts +++ b/packages/coding-agent/test/suite/agent-session-queue.test.ts @@ -437,6 +437,35 @@ describe("AgentSession queue characterization", () => { expect(harness.session.pendingMessageCount).toBe(0); }); + it("removes an image-only steering message after delivery", async () => { + const waiting = await createWaitingHarness(); + const { harness, waitForToolStart, promptPromise, releaseToolExecution } = waiting; + harnesses.push(harness); + let sawImage = false; + + harness.setResponses([ + fauxAssistantMessage(fauxToolCall("wait", {}), { stopReason: "toolUse" }), + (context) => { + const user = [...context.messages].reverse().find((message) => message.role === "user"); + sawImage = + user?.role === "user" && + typeof user.content !== "string" && + user.content.some((part) => part.type === "image"); + return fauxAssistantMessage("done"); + }, + ]); + + await waitForToolStart; + await harness.session.steer("", [{ type: "image", mimeType: "image/png", data: "ZmFrZQ==" }]); + expect(harness.session.pendingMessageCount).toBe(1); + releaseToolExecution(); + await promptPromise; + + expect(sawImage).toBe(true); + expect(harness.session.agent.hasQueuedMessages()).toBe(false); + expect(harness.session.pendingMessageCount).toBe(0); + }); + it("throws when queueing an extension command with steer", async () => { const harness = await createHarness({ extensionFactories: [