Skip to content

Commit 5d942ea

Browse files
committed
fix(coding-agent): drop a queued custom message when disposal begins during image preparation
1 parent b42533e commit 5d942ea

2 files changed

Lines changed: 37 additions & 32 deletions

File tree

‎packages/coding-agent/src/session/agent-session.ts‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8544,11 +8544,12 @@ export class AgentSession implements SettingsScope {
85448544
const descriptionNotice = preprocessed
85458545
? preprocessed.descriptionNotice
85468546
: await this.#buildSkillImageDescriptionNotice(normalizedAppMessage);
8547-
// abort() clears the steer/follow-up queues; a message still being normalized when it
8548-
// lands must not be queued afterwards and restart the stopped run (as in #queueUserMessage).
8547+
// abort() clears the steer/follow-up queues and disposal flushes every queue; a message
8548+
// still being prepared when either lands must not be queued afterwards (as in #queueUserMessage).
85498549
if (
8550-
deliverAs !== "aside" &&
8551-
(this.#promptGeneration !== promptGeneration || this.#sessionGeneration !== sessionGeneration)
8550+
this.#isDisposed ||
8551+
(deliverAs !== "aside" &&
8552+
(this.#promptGeneration !== promptGeneration || this.#sessionGeneration !== sessionGeneration))
85528553
) {
85538554
return false;
85548555
}

‎packages/coding-agent/test/agent-session-send-user-message-expand.test.ts‎

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -141,35 +141,39 @@ describe("AgentSession.sendUserMessage expandPromptTemplates", () => {
141141
expect(observedTurns).toHaveLength(0);
142142
});
143143

144-
it("reports a queued custom message dropped by abort during image normalization", async () => {
145-
const normalizing = Promise.withResolvers<void>();
146-
const normalized = Promise.withResolvers<void>();
147-
vi.spyOn(imageLoading, "normalizeModelContextImages").mockImplementation(async images => {
148-
normalizing.resolve();
149-
await normalized.promise;
150-
return images;
144+
for (const [label, interrupt] of [
145+
["abort", (target: AgentSession) => target.abort()],
146+
["disposal", (target: AgentSession) => target.beginDispose()],
147+
] as const) {
148+
it(`reports a queued custom message dropped by ${label} during image normalization`, async () => {
149+
const normalizing = Promise.withResolvers<void>();
150+
const normalized = Promise.withResolvers<void>();
151+
vi.spyOn(imageLoading, "normalizeModelContextImages").mockImplementation(async images => {
152+
normalizing.resolve();
153+
await normalized.promise;
154+
return images;
155+
});
156+
const send = session.promptCustomMessage(
157+
{
158+
customType: SKILL_PROMPT_MESSAGE_TYPE,
159+
content: [
160+
{ type: "text", text: "skill body" },
161+
{ type: "image", data: "aW1n", mimeType: "image/png" },
162+
],
163+
display: true,
164+
attribution: "user",
165+
},
166+
{ streamingBehavior: "followUp", queueOnly: true },
167+
);
168+
await normalizing.promise;
169+
await interrupt(session);
170+
normalized.resolve();
171+
172+
expect(await send).toBe(false);
173+
expect(session.queuedMessageCount).toBe(0);
174+
expect(observedTurns).toHaveLength(0);
151175
});
152-
const send = session.promptCustomMessage(
153-
{
154-
customType: SKILL_PROMPT_MESSAGE_TYPE,
155-
content: [
156-
{ type: "text", text: "skill body" },
157-
{ type: "image", data: "aW1n", mimeType: "image/png" },
158-
],
159-
display: true,
160-
attribution: "user",
161-
},
162-
{ streamingBehavior: "followUp", queueOnly: true },
163-
);
164-
await normalizing.promise;
165-
await session.abort();
166-
normalized.resolve();
167-
168-
expect(await send).toBe(false);
169-
await session.waitForIdle();
170-
expect(session.queuedMessageCount).toBe(0);
171-
expect(observedTurns).toHaveLength(0);
172-
});
176+
}
173177

174178
it("delivers an agent-attributed expanded skill as a user-role message", async () => {
175179
await session.sendUserMessage("/skill:demo relay", { expandPromptTemplates: true, attribution: "agent" });

0 commit comments

Comments
 (0)