fix: cancel trailing async jobs on session switch to prevent wasted LLM turns (#1643)
When a unit spawns background jobs via async_bash, job completion callbacks fire follow-up messages after agent_end has resolved. The auto-loop has moved on but the previous session's LLM processes these follow-ups, adding 12-45s of wasted time and ~14 unnecessary turns per unit. Two complementary fixes: 1. Cancel all running background jobs on session_before_switch so completion callbacks never fire for the old session. 2. Clear the follow-up queue after runUnit() completes as defense-in-depth, discarding any already-queued notifications before the next session starts. Closes #1642 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2d08391649
commit
b124b79a12
2 changed files with 25 additions and 0 deletions
|
|
@ -78,6 +78,17 @@ export default function AsyncJobs(pi: ExtensionAPI) {
|
|||
});
|
||||
});
|
||||
|
||||
pi.on("session_before_switch", async () => {
|
||||
if (manager) {
|
||||
// Cancel all running background jobs — their results are no longer
|
||||
// relevant to the new session and would produce wasteful follow-up
|
||||
// notifications that trigger empty LLM turns (#1642).
|
||||
for (const job of manager.getRunningJobs()) {
|
||||
manager.cancel(job.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pi.on("session_shutdown", async () => {
|
||||
if (manager) {
|
||||
manager.shutdown();
|
||||
|
|
|
|||
|
|
@ -287,6 +287,20 @@ export async function runUnit(
|
|||
status: result.status,
|
||||
});
|
||||
|
||||
// Discard trailing follow-up messages (e.g. async_job_result notifications)
|
||||
// from the completed unit. Without this, queued follow-ups trigger wasteful
|
||||
// LLM turns before the next session can start (#1642).
|
||||
// clearQueue() lives on AgentSession but isn't part of the typed
|
||||
// ExtensionCommandContext interface — call it via runtime check.
|
||||
try {
|
||||
const cmdCtxAny = s.cmdCtx as Record<string, unknown> | null;
|
||||
if (typeof cmdCtxAny?.clearQueue === "function") {
|
||||
(cmdCtxAny.clearQueue as () => unknown)();
|
||||
}
|
||||
} catch {
|
||||
// Non-fatal — clearQueue may not be available in all contexts
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue