import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "bun:test"; import * as path from "node:path"; import { Agent } from "@oh-my-pi/pi-agent-core"; import type { Model } from "@oh-my-pi/pi-ai"; import { getBundledModel } from "@oh-my-pi/pi-catalog/models"; import { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry"; import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings"; import { AgentSession } from "@oh-my-pi/pi-coding-agent/session/agent-session"; import { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage"; import { SessionManager } from "@oh-my-pi/pi-coding-agent/session/session-manager"; import { TempDir } from "@oh-my-pi/pi-utils"; describe("AgentSession advisor toggle", () => { let sharedDir: TempDir; let authStorage: AuthStorage; let modelRegistry: ModelRegistry; let model: Model; beforeAll(async () => { sharedDir = TempDir.createSync("@pi-advisor-toggle-shared-"); authStorage = await AuthStorage.create(path.join(sharedDir.path(), "testauth.db")); authStorage.setRuntimeApiKey("anthropic", "test-key"); modelRegistry = new ModelRegistry(authStorage); const bundled = getBundledModel("anthropic", "claude-sonnet-4-5"); if (!bundled) throw new Error("Expected built-in anthropic model to exist"); model = bundled; }); afterAll(async () => { authStorage.close(); try { await sharedDir.remove(); } catch {} }); let tempDir: TempDir; let session: AgentSession; let sessionManager: SessionManager; beforeEach(async () => { tempDir = TempDir.createSync("@pi-advisor-toggle-"); sessionManager = SessionManager.create(tempDir.path(), tempDir.path()); const agent = new Agent({ initialState: { model, systemPrompt: ["Test"], tools: [], messages: [], }, }); const settings = Settings.isolated({ "compaction.enabled": false }); session = new AgentSession({ agent, sessionManager, settings, modelRegistry, advisorReadOnlyTools: [], }); }); afterEach(async () => { await session.dispose(); try { await tempDir.remove(); } catch {} }); it("starts with advisor disabled", () => { expect(session.isAdvisorActive()).toBe(false); expect(session.settings.get("advisor.enabled")).toBe(false); expect(session.formatAdvisorStatus()).toBe("Advisor is disabled."); }); it("toggle enables the advisor and runtime", () => { session.settings.setModelRole("advisor", "anthropic/claude-sonnet-4-5"); const active = session.toggleAdvisorEnabled(); expect(active).toBe(true); expect(session.isAdvisorActive()).toBe(true); expect(session.settings.get("advisor.enabled")).toBe(true); expect(session.formatAdvisorStatus()).toContain("Advisor is enabled (anthropic/claude-sonnet-4-5)"); }); it("toggle disables the advisor and runtime", () => { session.settings.setModelRole("advisor", "anthropic/claude-sonnet-4-5"); session.toggleAdvisorEnabled(); const active = session.toggleAdvisorEnabled(); expect(active).toBe(false); expect(session.isAdvisorActive()).toBe(false); expect(session.settings.get("advisor.enabled")).toBe(false); }); it("setAdvisorEnabled reports inactive when no advisor model is assigned", () => { const active = session.setAdvisorEnabled(true); expect(active).toBe(false); expect(session.isAdvisorActive()).toBe(false); expect(session.settings.get("advisor.enabled")).toBe(true); expect(session.formatAdvisorStatus()).toBe( "Advisor setting is enabled, but no model is assigned to the 'advisor' role.", ); }); });