Fix worker conversation cleanup mappings

Ensure reverse mappings for worker conversations are removed during cleanup and dispose.

- In cleanupWorkerConversation, retrieve the conversation ID for the agent and delete the reverse mapping (workerAgentIdByConversationId) when cleaning up a worker.
- When disposing the meme loop worker, clear the reverse mapping map (workerAgentIdByConversationId) along with workerConversationByAgentId.
- Add unit tests (src/services/agentInstance/__tests__/workerCleanup.test.ts) to verify: cleanupWorkerConversation removes the reverse mapping for a single agent, and disposeMemeLoopWorker clears all worker conversation maps and worker references.
This commit is contained in:
linonetwo 2026-04-03 22:32:44 +08:00 committed by lin onetwo
parent 143496fdf2
commit 5d3a2cef16
2 changed files with 62 additions and 0 deletions

View file

@ -0,0 +1,57 @@
import { describe, expect, it } from 'vitest';
import { container } from '@services/container';
import type { IAgentInstanceService } from '@services/agentInstance/interface';
import serviceIdentifier from '@services/serviceIdentifier';
describe('AgentInstanceService worker cleanup', () => {
it('cleans reverse worker conversation mapping when a single worker conversation is cleaned up', () => {
const service = container.get<IAgentInstanceService>(serviceIdentifier.AgentInstance) as unknown as {
workerConversationByAgentId: Map<string, string>;
workerAgentIdByConversationId: Map<string, string>;
workerConversationCleanupByAgentId: Map<string, () => void>;
cleanupWorkerConversation: (agentId: string) => void;
};
const agentId = 'agent-cleanup-test';
const conversationId = 'worker-conversation-cleanup-test';
service.workerConversationByAgentId.set(agentId, conversationId);
service.workerAgentIdByConversationId.set(conversationId, agentId);
service.workerConversationCleanupByAgentId.set(agentId, () => undefined);
service.cleanupWorkerConversation(agentId);
expect(service.workerConversationCleanupByAgentId.has(agentId)).toBe(false);
expect(service.workerAgentIdByConversationId.has(conversationId)).toBe(false);
service.workerConversationByAgentId.delete(agentId);
});
it('clears reverse worker conversation mappings when disposing the worker', async () => {
const service = container.get<IAgentInstanceService>(serviceIdentifier.AgentInstance) as unknown as {
workerConversationByAgentId: Map<string, string>;
workerAgentIdByConversationId: Map<string, string>;
workerConversationCleanupByAgentId: Map<string, () => void>;
memeLoopNativeWorker?: { terminate: () => Promise<void> };
memeLoopWorker?: unknown;
disposeMemeLoopWorker: () => Promise<void>;
};
const agentId = 'agent-dispose-test';
const conversationId = 'worker-conversation-dispose-test';
service.workerConversationByAgentId.set(agentId, conversationId);
service.workerAgentIdByConversationId.set(conversationId, agentId);
service.workerConversationCleanupByAgentId.set(agentId, () => undefined);
service.memeLoopNativeWorker = {
terminate: async () => undefined,
};
service.memeLoopWorker = {};
await service.disposeMemeLoopWorker();
expect(service.workerConversationByAgentId.size).toBe(0);
expect(service.workerAgentIdByConversationId.size).toBe(0);
expect(service.workerConversationCleanupByAgentId.size).toBe(0);
expect(service.memeLoopNativeWorker).toBeUndefined();
expect(service.memeLoopWorker).toBeUndefined();
});
});

View file

@ -1513,6 +1513,7 @@ Result: ${JSON.stringify(approvalPrompt)}
}
private cleanupWorkerConversation(agentId: string): void {
const workerConversationId = this.workerConversationByAgentId.get(agentId);
const cleanup = this.workerConversationCleanupByAgentId.get(agentId);
if (cleanup) {
try {
@ -1522,6 +1523,9 @@ Result: ${JSON.stringify(approvalPrompt)}
}
this.workerConversationCleanupByAgentId.delete(agentId);
}
if (workerConversationId) {
this.workerAgentIdByConversationId.delete(workerConversationId);
}
}
private async cancelWorkerConversation(agentId: string): Promise<void> {
@ -2055,6 +2059,7 @@ Result: ${JSON.stringify(approvalPrompt)}
}
this.workerConversationCleanupByAgentId.delete(agentId);
}
this.workerAgentIdByConversationId.clear();
this.workerConversationByAgentId.clear();
if (this.memeLoopNativeWorker) {