agent-manager.session-reuse.test.js 2.24 KB
import { describe, it, expect, vi, beforeEach } from 'vitest';

const AgentManager = require('../../core/agent-manager');

// Mock logging to prevent initialization issues
vi.mock('../../core/logging', () => ({
  getGlobalLogManager: () => ({
    initialized: false,
    getOrCreateSession: () => null,
  }),
  waitForGlobalLogManager: () => Promise.resolve(),
}));

describe('AgentManager ACP session reuse', () => {
  let manager;

  const testConfig = {
    clients: {
      'claude-local': {
        type: 'process',
        command: 'claude',
        args: ['--print'],
      },
    },
    agents: {
      'claude-coder': {
        type: 'executor',
        protocol: 'acp',
        transport: 'pipe',
        client: 'claude-local',
        prompt: './agents/coder.md',
      },
    },
  };

  beforeEach(() => {
    manager = new AgentManager(testConfig, '/tmp/test-workdir');

    // Mock hookRunner to return Promises
    manager.hookRunner = {
      run: vi.fn().mockResolvedValue(undefined),
    };

    // Mock prompt builder
    manager.buildFullPrompt = vi.fn((name, task) => task);
  });

  it('reuses session pool for repeated calls of the same agent', async () => {
    let callCount = 0;
    // Mock _runViaProtocol to bypass SessionPool and stream-executor
    manager._runViaProtocol = vi.fn(async (agentName, agent, resolved, fullPrompt) => {
      callCount++;
      return { agent: agentName, output: `OUTPUT:${fullPrompt}`, status: 'success' };
    });

    const r1 = await manager.callAgent('claude-coder', 'P1');
    const r2 = await manager.callAgent('claude-coder', 'P2');

    expect(r1.output).toBe('OUTPUT:P1');
    expect(r2.output).toBe('OUTPUT:P2');
    expect(manager._runViaProtocol).toHaveBeenCalledTimes(2);
  });

  it('propagates transport error and calls post-task-failure hook', async () => {
    const transportError = new Error('Transport closed');

    manager._runViaProtocol = vi.fn()
      .mockRejectedValueOnce(transportError);

    await expect(manager.callAgent('claude-coder', 'P1')).rejects.toThrow('Transport closed');

    // post-task-failure hook should have been called
    const failureCalls = manager.hookRunner.run.mock.calls.filter(
      c => c[0] === 'post-task-failure'
    );
    expect(failureCalls.length).toBe(1);
  });
});