fix(coding-agent): coalesced queued steer flushes to avoid AgentBusyError interrupt races

- Coalesced repeated interrupt-and-flush calls into one queued-steer resume flow.
- Retried queued continues on AgentBusyError after waitForIdle up to a 30s timeout.
- Handled queue-flush failures in input controllers with warning logs and TUI error display.
This commit is contained in:
can1357
2026-06-13 15:52:25 +02:00
parent 69051241f1
commit 39efdfe91b
5 changed files with 211 additions and 6 deletions
@@ -412,7 +412,14 @@ export class InputController {
const queuedMessages = this.ctx.session.getQueuedMessages();
if (queuedMessages.steering.length > 0) {
this.ctx.notifyInterrupting();
await this.ctx.session.interruptAndFlushQueuedMessages({ reason: USER_INTERRUPT_LABEL });
try {
await this.ctx.session.interruptAndFlushQueuedMessages({ reason: USER_INTERRUPT_LABEL });
} catch (error) {
logger.warn("queued steer interrupt failed", {
error: error instanceof Error ? error.message : String(error),
});
this.ctx.showError(error instanceof Error ? error.message : String(error));
}
this.ctx.updatePendingMessagesDisplay();
this.ctx.ui.requestRender();
return;
@@ -696,7 +703,14 @@ export class InputController {
if (!text) {
// Mirror the empty-submit steer flush against the focused session.
if (target.isStreaming && target.getQueuedMessages().steering.length > 0) {
await target.interruptAndFlushQueuedMessages({ reason: USER_INTERRUPT_LABEL });
try {
await target.interruptAndFlushQueuedMessages({ reason: USER_INTERRUPT_LABEL });
} catch (error) {
logger.warn("focused queued steer interrupt failed", {
error: error instanceof Error ? error.message : String(error),
});
this.ctx.showError(error instanceof Error ? error.message : String(error));
}
this.ctx.updatePendingMessagesDisplay();
this.ctx.ui.requestRender();
}