core: auto-dismiss suggestion and question prompts once a new user message is queued, so a queued follow-up runs immediately instead of stalling behind a tool waiting on esc

This commit is contained in:
Alex Alecu
2026-04-22 17:49:44 +03:00
parent 5221569844
commit 6d45e33efb
5 changed files with 286 additions and 1 deletions
@@ -1,8 +1,10 @@
import { Bus } from "../../bus"
import { BusEvent } from "../../bus/bus-event"
import { Identifier } from "../../id/id"
import { SessionID } from "../../session/schema"
import { Log } from "../../util/log"
import z from "zod"
import { KiloSessionPromptQueue } from "../session/prompt-queue"
export namespace Suggestion {
const log = Log.create({ service: "suggestion" })
@@ -90,6 +92,14 @@ export namespace Suggestion {
blocking?: boolean
tool?: { messageID: string; callID: string }
}): Promise<Action> {
// Auto-dismiss if a newer prompt is already queued on this session.
// Synchronous check immediately before the pending set, so there's no
// interleaving with dismissAll called from SessionPrompt.prompt.
if (KiloSessionPromptQueue.hasFollowup(SessionID.make(input.sessionID))) {
log.info("auto-dismissed — followup queued", { sessionID: input.sessionID })
throw new DismissedError()
}
const s = { pending }
const id = Identifier.ascending("suggestion")
+12
View File
@@ -8,6 +8,9 @@ import { Log } from "@/util/log"
import { withStatics } from "@/util/schema"
import { QuestionID } from "./schema"
import { makeRuntime } from "@/effect/run-service" // kilocode_change
// kilocode_change start
import { KiloSessionPromptQueue } from "@/kilocode/session/prompt-queue"
// kilocode_change end
export namespace Question {
const log = Log.create({ service: "question" })
@@ -195,6 +198,15 @@ export namespace Question {
blocking: input.blocking, // kilocode_change
tool: input.tool,
})
// kilocode_change start — auto-dismiss when a newer prompt is queued on this session,
// otherwise a tool that calls Question.ask after the queue event would block the run.
if (KiloSessionPromptQueue.hasFollowup(input.sessionID)) {
log.info("auto-dismissed — followup queued", { sessionID: input.sessionID })
return yield* Effect.fail(new RejectedError())
}
// kilocode_change end
pending.set(id, { info, deferred })
yield* bus.publish(Event.Asked, info)