import { describe, expect, it } from 'vitest';
import { Agent } from '../agent.js';
import { MockMessageModel } from '../../__fixtures__/mock-message-model.js';
import { SlidingWindowConversationManager } from '../../conversation-manager/sliding-window-conversation-manager.js';
import { SummarizingConversationManager } from '../../conversation-manager/summarizing-conversation-manager.js';
import { ContextOffloader } from '../../vended-plugins/context-offloader/plugin.js';
import { InMemoryStorage } from '../../vended-plugins/context-offloader/storage.js';
function internals(agent) {
    return agent;
}
function getConversationManager(agent) {
    return internals(agent)._conversationManager;
}
function getPending(agent) {
    return internals(agent)._pluginRegistry._pending;
}
describe('Agent contextManager', () => {
    describe('when undefined (default)', () => {
        it('uses SlidingWindowConversationManager', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const agent = new Agent({ model });
            expect(getConversationManager(agent)).toBeInstanceOf(SlidingWindowConversationManager);
        });
        it('does not add ContextOffloader plugin', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const agent = new Agent({ model });
            const pending = getPending(agent);
            expect(pending.find((p) => p.name === 'strands:context-offloader')).toBeUndefined();
        });
    });
    describe('when "auto"', () => {
        it('uses SummarizingConversationManager', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const agent = new Agent({ model, contextManager: 'auto' });
            expect(getConversationManager(agent)).toBeInstanceOf(SummarizingConversationManager);
        });
        it('sets summaryRatio to 0.3', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const agent = new Agent({ model, contextManager: 'auto' });
            const conversationManager = getConversationManager(agent);
            expect(conversationManager._summaryRatio).toBe(0.3);
        });
        it('enables proactive compression at 0.85', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const agent = new Agent({ model, contextManager: 'auto' });
            const conversationManager = getConversationManager(agent);
            expect(conversationManager._compressionThreshold).toBe(0.85);
        });
        it('adds ContextOffloader plugin with benchmark defaults', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const agent = new Agent({ model, contextManager: 'auto' });
            const pending = getPending(agent);
            const offloader = pending.find((p) => p.name === 'strands:context-offloader');
            expect(offloader).toBeDefined();
            expect(offloader._maxResultTokens).toBe(1500);
            expect(offloader._previewTokens).toBe(750);
            expect(offloader._storage).toBeInstanceOf(InMemoryStorage);
        });
    });
    describe('coexistence with conversationManager', () => {
        it('respects user-provided conversationManager', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const userCm = new SlidingWindowConversationManager({ windowSize: 20 });
            const agent = new Agent({ model, contextManager: 'auto', conversationManager: userCm });
            expect(getConversationManager(agent)).toBe(userCm);
        });
        it('still adds ContextOffloader when user provides conversationManager', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const userCm = new SlidingWindowConversationManager({ windowSize: 20 });
            const agent = new Agent({ model, contextManager: 'auto', conversationManager: userCm });
            const pending = getPending(agent);
            expect(pending.find((p) => p.name === 'strands:context-offloader')).toBeDefined();
        });
        it('does not add duplicate ContextOffloader if user provides one', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            const userOffloader = new ContextOffloader({
                storage: new InMemoryStorage(),
                maxResultTokens: 3000,
                previewTokens: 1000,
            });
            const agent = new Agent({ model, contextManager: 'auto', plugins: [userOffloader] });
            const pending = getPending(agent);
            const offloaders = pending.filter((p) => p.name === 'strands:context-offloader');
            expect(offloaders).toHaveLength(1);
            expect(offloaders[0]._maxResultTokens).toBe(3000);
        });
    });
    describe('stateful model', () => {
        it('throws when used with a stateful model', () => {
            class StatefulModel extends MockMessageModel {
                get stateful() {
                    return true;
                }
            }
            const model = new StatefulModel().addTurn({ type: 'textBlock', text: 'hi' });
            expect(() => new Agent({ model, contextManager: 'auto' })).toThrow('stateful model');
        });
    });
    describe('unsupported value', () => {
        it('throws for invalid contextManager value', () => {
            const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'hi' });
            expect(() => new Agent({ model, contextManager: 'manual' })).toThrow('Unsupported contextManager value');
        });
    });
});
//# sourceMappingURL=agent.context-manager.test.js.map