import { afterAll, afterEach, beforeAll, beforeEach, expect, mock, test } from "bun:test"; import { GlobalRegistrator } from "@happy-dom/global-registrator"; import { act } from "react"; import { createRoot, type Root } from "react-dom/client"; import { ComposerCapabilitiesMenuBody } from "../composer-capabilities-menu-body"; import { instructionSections } from "../session/model-context-inspector"; import { capabilityAvailability, draftFromRequest, requestFromDraft, type AgentCapabilityDraft, } from "../../lib/agent-capabilities"; import { AgentCapabilityPicker, AgentCapabilitySummary } from "./agent-capability-picker"; let container: HTMLDivElement; let root: Root; beforeAll(() => { GlobalRegistrator.register(); ( globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean } ).IS_REACT_ACT_ENVIRONMENT = true; }); beforeEach(() => { container = document.createElement("div"); document.body.append(container); root = createRoot(container); }); afterEach(async () => { await act(async () => root.unmount()); container.remove(); }); afterAll(() => GlobalRegistrator.unregister()); const noWebSearch = capabilityAvailability({ capabilities: [{ id: "webSearch", available: false, reason: "off" }], }); test("the picker shows product words, disables what the server doesn't offer, and edits the draft", async () => { let draft: AgentCapabilityDraft = draftFromRequest("none"); const change = mock((next: AgentCapabilityDraft) => { draft = next; }); await act(async () => root.render( , ), ); const text = container.textContent ?? ""; expect(text).toContain("Everything this workspace offers"); expect(text).toContain("Only what you choose"); expect(text).not.toMatch(/goal_set|knowledge_search|web_search/); const webSearch = container.querySelector( '[data-capability="webSearch"] input[type=checkbox]', )!; expect(webSearch.disabled).toBe(true); expect(container.querySelector('[data-capability="webSearch"]')?.textContent).toContain( "Not enabled on this server", ); const goals = container.querySelector( '[data-capability="goals"] input[type=checkbox]', )!; await act(async () => goals.click()); expect(requestFromDraft(draft, noWebSearch)).toEqual({ from: "none", goals: true }); }); test("a read-only picker changes nothing", async () => { const change = mock(); await act(async () => root.render( , ), ); for (const input of container.querySelectorAll("input[type=checkbox]")) { expect(input.disabled).toBe(true); } expect(container.textContent).toContain("Only workspace admins can change these."); }); test("the summary lists what is on, then what is off and what the server doesn't offer", async () => { await act(async () => root.render( , ), ); const on = [...container.querySelectorAll("[data-capability]")].map((row) => row.getAttribute("data-capability"), ); expect(on).toEqual(["humanInput", "skills", "knowledge"]); expect(container.textContent).toContain("Uses installed Skills."); expect(container.textContent).toContain("Off: Images and video, Goals"); expect(container.textContent).toContain("Not enabled on this server: Web search."); }); test("composer capabilities: read-only until Customize for this chat, then toggles", async () => { const onCustomizedChange = mock(); const onChange = mock(); const render = (customized: boolean) => root.render( {}} />, ); await act(async () => render(false)); const customize = container.querySelector( 'button[aria-label="Customize for this chat"]', )!; expect(customize.getAttribute("aria-checked")).toBe("false"); const readOnlyGoals = container.querySelector( 'button[aria-label="Goals, off"]', )!; // Reachable (not disabled) but read as unavailable, and clicking changes nothing. expect(readOnlyGoals.disabled).toBe(false); expect(readOnlyGoals.getAttribute("aria-disabled")).toBe("true"); await act(async () => readOnlyGoals.click()); expect(onChange).not.toHaveBeenCalled(); expect(container.textContent).toContain("2 of 3 connected apps on"); await act(async () => customize.click()); expect(onCustomizedChange).toHaveBeenCalledWith(true); await act(async () => render(true)); const goals = container.querySelector('button[aria-label="Goals"]')!; expect(goals.getAttribute("role")).toBe("switch"); await act(async () => goals.click()); expect(requestFromDraft(onChange.mock.calls[0]![0])).toEqual({ from: "none", goals: true, workspaceConnectors: true, }); }); test("inspector sections slice prompt modules out of the operational contract", () => { const content = "Base.\n\nRuntime."; const sections = instructionSections([ { id: "identity", title: "Identity", content: "Me.", utf8Bytes: 3, estimatedTokens: 1 }, { id: "operational_contract", title: "Operational contract", content, utf8Bytes: content.length, estimatedTokens: 4, modules: [ { id: "base_behavior", chars: 5 }, { id: "runtime_mechanics", chars: 8 }, ], }, ]); expect(sections.map((section) => [section.title, section.text, section.depth])).toEqual([ ["Identity", "Me.", 0], ["Operational contract", content, 0], ["Base behavior", "Base.", 1], ["Runtime mechanics", "Runtime.", 1], ]); // Lengths that don't add up keep the layer whole. expect( instructionSections([ { id: "operational_contract", title: "Operational contract", content, utf8Bytes: content.length, estimatedTokens: 4, modules: [{ id: "base_behavior", chars: 99 }], }, ]), ).toHaveLength(1); });