diff --git a/.changeset/fix-background-subagent-ghost-tasks.md b/.changeset/fix-background-subagent-ghost-tasks.md new file mode 100644 index 0000000000..818b8a9bd5 --- /dev/null +++ b/.changeset/fix-background-subagent-ghost-tasks.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Fix background subagents rejected by the running-task limit lingering as permanent "running" entries in the task panel. diff --git a/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts b/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts index 330549a1f5..6ca178ed7f 100644 --- a/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts +++ b/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts @@ -75,6 +75,7 @@ import { } from '#/app/agentProfileCatalog/profile-shared'; import { ILogService } from '#/_base/log/log'; import { IConfigService } from '#/app/config/config'; +import { IEventBus } from '#/app/event/eventBus'; import { IFlagService } from '#/app/flag/flag'; import { IModelCatalog } from '#/kosong/model/catalog'; import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; @@ -83,7 +84,11 @@ import { ISessionProcessRunner } from '#/session/process/processRunner'; import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; -import { emitAgentRunSpawned, mirrorAgentRun } from '#/session/subagent/mirrorAgentRun'; +import { + emitAgentRunFailed, + emitAgentRunSpawned, + mirrorAgentRun, +} from '#/session/subagent/mirrorAgentRun'; import { ISessionSubagentService } from '#/session/subagent/subagent'; import { buildSubagentModelDescriptions, @@ -474,14 +479,13 @@ export class SubagentTool implements ISubagentTool { subagentType: handle.profileName, error, }); - const message = error instanceof Error ? error.message : String(error); - return { - output: - isError2(error) && error.code === ErrorCodes.TASK_LIMIT_EXCEEDED - ? 'Too many background tasks are already running.' - : message, - isError: true, - }; + const message = registrationFailureMessage(error); + emitAgentRunFailed( + this.lifecycle.get(this.callerAgentId)?.accessor.get(IEventBus), + handle.agentId, + message, + ); + return { output: message, isError: true }; } if (runInBackground) { @@ -635,6 +639,13 @@ function launchErrorMessage(error: unknown, signal: AbortSignal): string { return error instanceof Error ? error.message : String(error); } +function registrationFailureMessage(error: unknown): string { + if (isError2(error) && error.code === ErrorCodes.TASK_LIMIT_EXCEEDED) { + return 'Too many background tasks are already running.'; + } + return error instanceof Error ? error.message : String(error); +} + function formatSubagentStoppedMessage(reason: string | undefined): string { const normalized = reason?.trim(); if (normalized === userCancellationReason().message) return USER_INTERRUPTED_SUBAGENT_MESSAGE; diff --git a/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts b/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts index 095a1cb705..19a10b955b 100644 --- a/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts +++ b/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts @@ -129,6 +129,18 @@ export function emitAgentRunSpawned( }); } +export function emitAgentRunFailed( + eventBus: IEventBus | undefined, + targetAgentId: string, + error: string, +): void { + eventBus?.publish({ + type: 'subagent.failed', + subagentId: targetAgentId, + error, + }); +} + export async function mirrorAgentRun( requester: IAgentScopeHandle, run: AgentRunHandle, @@ -174,11 +186,7 @@ export async function mirrorAgentRun( return result; } catch (error) { if (!isAbortError(error) && !shouldSuppressFailure(options, error)) { - eventBus?.publish({ - type: 'subagent.failed', - subagentId: run.agentId, - error: errorMessage(error), - }); + emitAgentRunFailed(eventBus, run.agentId, errorMessage(error)); } throw error; } diff --git a/packages/agent-core-v2/test/tool/tool.test.ts b/packages/agent-core-v2/test/tool/tool.test.ts index 14709c15a2..46618e9987 100644 --- a/packages/agent-core-v2/test/tool/tool.test.ts +++ b/packages/agent-core-v2/test/tool/tool.test.ts @@ -1748,6 +1748,20 @@ describe('Agent tool execution contract', () => { output: 'Too many background tasks are already running.', }); expect(lifecycle.create).toHaveBeenCalledTimes(2); + + const events = lifecycle.publishedEvents; + const spawnedIndex = events.findIndex( + (event) => event.type === 'subagent.spawned' && event.subagentId === 'agent-second', + ); + const failedEvents = events.filter( + (event) => event.type === 'subagent.failed' && event.subagentId === 'agent-second', + ); + expect(spawnedIndex).toBeGreaterThanOrEqual(0); + expect(failedEvents).toHaveLength(1); + expect(events.indexOf(failedEvents[0]!)).toBeGreaterThan(spawnedIndex); + expect(failedEvents[0]).toMatchObject({ + error: 'Too many background tasks are already running.', + }); completions[0]?.resolve({ summary: 'finished later' }); });