fix(agent): release task spawn slot when progress reporting throws

In #registerSpawnJob the markRunning()/reportProgress() calls sat between
semaphore.acquire() and the try whose finally releases the slot. If progress
reporting threw there, the acquired task.maxConcurrency slot leaked and
permanently shrank subagent concurrency. Move those statements inside the try
so finally always releases. The abort-before-execution branch is unchanged
(releases once and throws before the try is entered — not a double release).

Refs #3464
This commit is contained in:
can1357
2026-06-25 20:48:38 +02:00
parent ecd6f608e5
commit 06ca03dbd8
2 changed files with 7 additions and 6 deletions
+1
View File
@@ -12,6 +12,7 @@
- Fixed manual `/compact` leaving `session.isCompacting` false while active-turn abort teardown awaited, so the first steer/follow-up typed during compaction startup now routes through the compaction queue instead of being lost. ([#3485](https://github.com/can1357/oh-my-pi/issues/3485))
- Fixed ollama-cloud task/subagent fan-out exceeding the provider's three-request concurrency cap by adding a provider-specific subagent limiter, and let configured task/smol/advisor model roles inherit the default retry fallback chain when they do not define their own chain. ([#3464](https://github.com/can1357/oh-my-pi/issues/3464))
- Fixed the per-provider subagent concurrency limiter (e.g. `providers.ollama-cloud.maxConcurrency`) being replaced with a fresh semaphore whenever the configured limit changed, which orphaned the in-flight slots on the old instance and let a runtime or mixed limit value exceed the cap. The limiter now resizes a single shared semaphore in place — raising the ceiling admits queued waiters immediately, lowering it drains in-flight holders without admitting past the new cap. ([#3464](https://github.com/can1357/oh-my-pi/issues/3464))
- Fixed a background-task spawn slot leaking from the `task.maxConcurrency` limiter when progress reporting threw between acquiring the slot and entering the guarded run: `markRunning`/`reportProgress` now run inside the try whose `finally` releases the semaphore, so a failed progress report can no longer permanently shrink subagent concurrency. ([#3464](https://github.com/can1357/oh-my-pi/issues/3464))
## [16.1.19] - 2026-06-25
+6 -6
View File
@@ -798,13 +798,13 @@ export class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskToolDetai
onSettled?.(true);
throw new Error("Aborted before execution");
}
markRunning();
progress.status = "running";
await reportProgress(
`Running background task ${agentId}...`,
buildDetails("running", ownJobId) as unknown as Record<string, unknown>,
);
try {
markRunning();
progress.status = "running";
await reportProgress(
`Running background task ${agentId}...`,
buildDetails("running", ownJobId) as unknown as Record<string, unknown>,
);
const result = await this.#executeSync(
toolCallId,
spawnParams,