diff --git a/src/agent/mock-manager.test.ts b/src/agent/mock-manager.test.ts index 05a5043..18f97e2 100644 --- a/src/agent/mock-manager.test.ts +++ b/src/agent/mock-manager.test.ts @@ -687,6 +687,97 @@ describe('MockAgentManager', () => { }); }); + // =========================================================================== + // Decompose mode (plan to tasks) + // =========================================================================== + + describe('decompose mode', () => { + it('should spawn agent in decompose mode', async () => { + const agent = await manager.spawn({ + name: 'decomposer', + taskId: 'plan-1', + prompt: 'Decompose this plan', + mode: 'decompose', + }); + expect(agent.mode).toBe('decompose'); + }); + + it('should complete with tasks on decompose_complete', async () => { + manager.setScenario('decomposer', { + status: 'decompose_complete', + tasks: [ + { number: 1, name: 'Task 1', description: 'First task', type: 'auto', dependencies: [] }, + { number: 2, name: 'Task 2', description: 'Second task', type: 'auto', dependencies: [1] }, + ], + }); + + await manager.spawn({ name: 'decomposer', taskId: 'plan-1', prompt: 'test', mode: 'decompose' }); + await vi.advanceTimersByTimeAsync(100); + + // Verify agent:stopped event with decompose_complete reason + const stoppedEvent = eventBus.emittedEvents.find((e) => e.type === 'agent:stopped') as AgentStoppedEvent | undefined; + expect(stoppedEvent).toBeDefined(); + expect(stoppedEvent?.payload.reason).toBe('decompose_complete'); + }); + + it('should pause on questions in decompose mode', async () => { + manager.setScenario('decomposer', { + status: 'questions', + questions: [{ id: 'q1', question: 'How many tasks?' }], + }); + + await manager.spawn({ name: 'decomposer', taskId: 'plan-1', prompt: 'test', mode: 'decompose' }); + await vi.advanceTimersByTimeAsync(100); + + // Verify agent pauses for questions + const stoppedEvent = eventBus.emittedEvents.find((e) => e.type === 'agent:waiting'); + expect(stoppedEvent).toBeDefined(); + + // Check agent status + const agent = await manager.getByName('decomposer'); + expect(agent?.status).toBe('waiting_for_input'); + }); + + it('should emit stopped event with decompose_complete reason', async () => { + manager.setScenario('decompose-done', { + status: 'decompose_complete', + delay: 0, + tasks: [ + { number: 1, name: 'Setup', description: 'Initial setup', type: 'auto', dependencies: [] }, + ], + }); + + await manager.spawn({ + name: 'decompose-done', + taskId: 'plan-1', + prompt: 'test', + mode: 'decompose', + }); + await vi.runAllTimersAsync(); + + const stopped = eventBus.emittedEvents.find((e) => e.type === 'agent:stopped') as AgentStoppedEvent | undefined; + expect(stopped?.payload.reason).toBe('decompose_complete'); + }); + + it('should set result message with task count', async () => { + manager.setScenario('decomposer', { + status: 'decompose_complete', + tasks: [ + { number: 1, name: 'Task 1', description: 'First', type: 'auto', dependencies: [] }, + { number: 2, name: 'Task 2', description: 'Second', type: 'checkpoint:human-verify', dependencies: [1] }, + { number: 3, name: 'Task 3', description: 'Third', type: 'auto', dependencies: [1, 2] }, + ], + }); + + const agent = await manager.spawn({ name: 'decomposer', taskId: 'plan-1', prompt: 'test', mode: 'decompose' }); + await vi.runAllTimersAsync(); + + const result = await manager.getResult(agent.id); + expect(result?.success).toBe(true); + expect(result?.message).toBe('Decomposed into 3 tasks'); + }); + }); + // =========================================================================== // Structured question data (new schema tests) // ===========================================================================