import {
  render,
  screen,
  fireEvent,
  waitFor,
  within,
} from "@testing-library/react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import { AgentEditor } from "./AgentEditor";
import { useConfigStore } from "@/store/configStore";
import {
  Agent,
  AgentPoliciesByAgent,
  normalizeAgentUpdates,
  SHARED_CONTEXT_FILE_PLACEHOLDER,
} from "@/types/config";
import { useTools } from "@/hooks/useTools";

// Mock the store
vi.mock("@/store/configStore", () => ({
  useConfigStore: vi.fn(),
}));

vi.mock("@/components/ui/toaster", () => ({
  toast: vi.fn(),
}));

// Mock useTools hook
vi.mock("@/hooks/useTools", () => ({
  useTools: vi.fn(() => ({
    tools: [
      {
        name: "calculator",
        display_name: "Calculator",
        setup_type: "none",
        status: "available",
      },
      {
        name: "delegate",
        display_name: "Agent Delegation",
        setup_type: "none",
        status: "available",
      },
      {
        name: "file",
        display_name: "File",
        setup_type: "none",
        status: "available",
      },
    ],
    loading: false,
    statusAuthoritative: true,
  })),
}));

vi.mock("@/hooks/useSkills", () => ({
  useSkills: vi.fn(() => ({
    skills: [
      {
        name: "debugging",
        description: "Debug issues quickly",
        origin: "bundled",
        can_edit: false,
      },
      {
        name: "code-review",
        description: "Perform code reviews",
        origin: "user",
        can_edit: true,
      },
    ],
    loading: false,
  })),
}));

describe("AgentEditor", () => {
  const makeAgentPolicies = (
    overrides: Partial<AgentPoliciesByAgent[string]> = {},
  ): AgentPoliciesByAgent => ({
    test_agent: {
      agent_name: "test_agent",
      is_private: false,
      effective_execution_scope: null,
      scope_label: "unscoped",
      scope_source: "unscoped",
      dashboard_credentials_supported: true,
      team_eligibility_reason: null,
      private_knowledge_base_id: null,
      private_workspace_enabled: false,
      private_agent_knowledge_enabled: false,
      ...overrides,
    },
  });

  const mockAgent: Agent = {
    id: "test_agent",
    display_name: "Test Agent",
    role: "Test role",
    tools: ["calculator"],
    skills: ["debugging"],
    instructions: ["Test instruction"],
    rooms: ["test_room"],
    knowledge_bases: ["research"],
    learning: true,
    learning_mode: "always",
  };

  const mockConfig = {
    models: {
      default: { provider: "test", id: "test-model" },
      custom: { provider: "custom", id: "custom-model" },
    },
    memory: {
      backend: "mem0",
      embedder: {
        provider: "openai",
        config: { model: "text-embedding-3-small" },
      },
    },
    agents: { test_agent: mockAgent },
    knowledge_bases: {
      legal: { path: "./legal", watch: true },
      research: { path: "./research", watch: true },
    },
    defaults: {},
  };

  const mockStore = {
    agents: [mockAgent],
    rooms: [
      {
        id: "test_room",
        display_name: "Test Room",
        description: "Test room",
        agents: ["test_agent"],
      },
      {
        id: "other_room",
        display_name: "Other Room",
        description: "Another room",
        agents: [],
      },
    ],
    selectedAgentId: "test_agent",
    updateAgent: vi.fn(),
    setAgentPrivateEnabled: vi.fn(),
    deleteAgent: vi.fn(),
    saveConfig: vi.fn().mockResolvedValue({ status: "saved" }),
    config: mockConfig,
    agentPoliciesByAgent: makeAgentPolicies(),
    isDirty: false,
    diagnostics: [],
    selectAgent: vi.fn(),
    getAgentToolOverrides: vi.fn(() => null),
  };

  beforeEach(() => {
    vi.clearAllMocks();
    (useConfigStore as any).mockReturnValue(mockStore);
    (useTools as any).mockReturnValue({
      tools: [
        {
          name: "calculator",
          display_name: "Calculator",
          setup_type: "none",
          status: "available",
        },
        {
          name: "delegate",
          display_name: "Agent Delegation",
          setup_type: "none",
          status: "available",
        },
        {
          name: "file",
          display_name: "File",
          setup_type: "none",
          status: "available",
        },
      ],
      loading: false,
      statusAuthoritative: true,
    });
  });

  it("renders without infinite loops", () => {
    const { container } = render(<AgentEditor />);
    expect(container).toBeTruthy();
  });

  it("requests agent-scoped tools for the selected agent", () => {
    render(<AgentEditor />);

    expect(useTools).toHaveBeenCalledWith("test_agent", null);
  });

  it("requests tools using inherited defaults.worker_scope", () => {
    const inheritedScopeAgent = {
      ...mockAgent,
      worker_scope: undefined,
      private: undefined,
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [inheritedScopeAgent],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          worker_scope: "user",
        },
      },
      agentPoliciesByAgent: makeAgentPolicies({
        effective_execution_scope: "user",
        scope_label: "worker_scope=user",
        scope_source: "defaults.worker_scope",
        dashboard_credentials_supported: false,
      }),
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);

    expect(useTools).toHaveBeenCalledWith("test_agent", "user");
  });

  it("shows inherited default tools even when defaults.tools is omitted from authored config", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      config: {
        ...mockConfig,
        defaults: {},
      },
      agents: [{ ...mockAgent, include_default_tools: undefined }],
    });

    render(<AgentEditor />);

    expect(screen.getByLabelText("worker scheduler")).toBeInTheDocument();
  });

  it("shows compress tool results helper with inherited off default when omitted", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      config: {
        ...mockConfig,
        defaults: {},
      },
      agents: [{ ...mockAgent, compress_tool_results: undefined }],
    });

    render(<AgentEditor />);

    expect(
      screen.getByText(
        "Compress tool results in history to save context (global default: off). On Anthropic/Vertex Claude, enabling this can invalidate prompt-cache prefixes.",
      ),
    ).toBeInTheDocument();
  });

  it("fails closed when agent policy preview is unavailable", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agentPoliciesByAgent: {},
    });

    render(<AgentEditor />);

    expect(useTools).toHaveBeenCalledWith(null, undefined);
    expect(
      screen.getByText(
        "Agent policy preview is unavailable. Save or refresh to re-validate tool scope support for this draft.",
      ),
    ).toBeInTheDocument();
    expect(
      screen.getByText(
        "Tool availability preview is unavailable while agent policy preview is unavailable. Save or refresh to validate tool assignments.",
      ),
    ).toBeInTheDocument();
    expect(
      screen.queryByText("Selected But Unavailable"),
    ).not.toBeInTheDocument();
    expect(
      screen.queryByText(
        "This tool is no longer available in the current registry. Uncheck it to remove it.",
      ),
    ).not.toBeInTheDocument();
  });

  it("prefers the unavailable preview message over generic tool loading", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agentPoliciesByAgent: {},
    });
    (useTools as any).mockReturnValue({
      tools: [],
      loading: true,
      statusAuthoritative: true,
    });

    render(<AgentEditor />);

    expect(
      screen.getByText(
        "Tool availability preview is unavailable while agent policy preview is unavailable. Save or refresh to validate tool assignments.",
      ),
    ).toBeInTheDocument();
    expect(
      screen.queryByText("Loading available tools..."),
    ).not.toBeInTheDocument();
  });

  it("shows selectable setup-required tools instead of hiding them", () => {
    (useTools as any).mockReturnValue({
      tools: [
        {
          name: "calculator",
          display_name: "Calculator",
          setup_type: "none",
          status: "available",
        },
        {
          name: "weather",
          display_name: "Weather",
          setup_type: "api_key",
          status: "requires_config",
          dashboard_configuration_supported: true,
        },
      ],
      loading: false,
    });

    render(<AgentEditor />);

    expect(screen.getByText("Setup Required")).toBeInTheDocument();
    expect(screen.getByLabelText("Weather")).toBeInTheDocument();
  });

  it("shows backend tool descriptions inline and rich metadata in a details popover", () => {
    (useTools as any).mockReturnValue({
      tools: [
        {
          name: "shell",
          display_name: "Shell Commands",
          description:
            "Run shell commands in the agent workspace with timeout handling.",
          helper_text: "Use this for tests, scripts, and workspace automation.",
          setup_type: "none",
          status: "available",
          default_execution_target: "worker",
          docs_url: "https://docs.example.com/shell",
          dependencies: ["bash"],
          function_names: [
            "run_command",
            "read_process",
            "stop_process",
            "list_processes",
            "send_stdin",
            "write_file",
            "extra_function",
          ],
        },
        {
          name: "file",
          display_name: "File",
          description: "Read and write workspace files.",
          setup_type: "none",
          status: "available",
        },
      ],
      loading: false,
      statusAuthoritative: true,
    });

    render(<AgentEditor />);

    const inlineSummary = screen.getByText(
      "Run shell commands in the agent workspace with timeout handling.",
    );
    expect(inlineSummary).toBeInTheDocument();
    expect(inlineSummary).toHaveClass("line-clamp-2");
    expect(
      screen.getByRole("checkbox", { name: "Shell Commands" }),
    ).not.toHaveAttribute("aria-label");

    fireEvent.click(
      screen.getByRole("button", {
        name: "Show Shell Commands tool details",
      }),
    );

    const details = screen.getByRole("dialog", {
      name: "Shell Commands tool details",
    });
    expect(
      within(details).getByText(
        "Use this for tests, scripts, and workspace automation.",
      ),
    ).toBeInTheDocument();
    expect(
      within(details).getByRole("link", { name: "Open documentation" }),
    ).toHaveAttribute("href", "https://docs.example.com/shell");
    expect(within(details).getByText("Setup")).toBeInTheDocument();
    expect(within(details).getByText("None")).toBeInTheDocument();
    expect(within(details).getByText("Default Runtime")).toBeInTheDocument();
    expect(within(details).getByText("Worker")).toBeInTheDocument();
    expect(within(details).getByText("run_command")).toBeInTheDocument();
    expect(within(details).getByText("+1 more")).toBeInTheDocument();
  });

  it("omits placeholder noise for tools without optional metadata", () => {
    (useTools as any).mockReturnValue({
      tools: [
        {
          name: "file",
          display_name: "File",
          description: "Read and write workspace files.",
          setup_type: "none",
          status: "available",
          docs_url: "javascript:alert(1)",
        },
      ],
      loading: false,
      statusAuthoritative: true,
    });

    render(<AgentEditor />);

    expect(
      screen.getByText("Read and write workspace files."),
    ).toBeInTheDocument();
    fireEvent.click(
      screen.getByRole("button", { name: "Show File tool details" }),
    );

    const details = screen.getByRole("dialog", {
      name: "File tool details",
    });
    expect(
      within(details).queryByText("No helper text"),
    ).not.toBeInTheDocument();
    expect(
      within(details).queryByText("No documentation"),
    ).not.toBeInTheDocument();
    expect(within(details).queryByText("No functions")).not.toBeInTheDocument();
    expect(
      within(details).queryByRole("link", { name: "Open documentation" }),
    ).not.toBeInTheDocument();
  });

  it("shows customized indicators and opens the inline tool settings panel for checked tools", () => {
    const shellAgent = { ...mockAgent, tools: ["shell"] };
    const getAgentToolOverrides = vi.fn((agentId: string, toolName: string) =>
      agentId === "test_agent" && toolName === "shell"
        ? { extra_env_passthrough: ["GITEA_TOKEN"] }
        : null,
    );

    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [shellAgent],
      config: {
        ...mockConfig,
        agents: { test_agent: shellAgent },
      },
      getAgentToolOverrides,
    });
    (useTools as any).mockReturnValue({
      tools: [
        {
          name: "shell",
          display_name: "Shell Commands",
          setup_type: "none",
          status: "available",
          agent_override_fields: [
            {
              name: "extra_env_passthrough",
              label: "Env Passthrough",
              type: "string[]",
            },
          ],
        },
      ],
      loading: false,
      statusAuthoritative: true,
    });

    render(<AgentEditor />);

    expect(screen.getByText("Customized")).toBeInTheDocument();
    expect(
      screen.getByRole("checkbox", { name: "Shell Commands" }),
    ).toHaveAttribute("aria-label", "Shell Commands");
    fireEvent.click(screen.getByRole("button", { name: "Shell Commands" }));

    expect(
      screen.getByText("Shell Commands — Per-Agent Settings"),
    ).toBeInTheDocument();
    expect(screen.getByDisplayValue("GITEA_TOKEN")).toBeInTheDocument();
  });

  it("keeps selected unsupported tools visible so they can be removed", async () => {
    const invalidToolAgent = { ...mockAgent, tools: ["gmail"] };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [invalidToolAgent],
      config: {
        ...mockConfig,
        agents: { test_agent: invalidToolAgent },
      },
    });
    (useTools as any).mockReturnValue({
      tools: [
        {
          name: "gmail",
          display_name: "Gmail",
          setup_type: "oauth",
          status: "requires_config",
          execution_scope_supported: false,
        },
      ],
      loading: false,
    });

    render(<AgentEditor />);

    await waitFor(() => {
      expect(screen.getByText("Selected But Unavailable")).toBeInTheDocument();
      expect(screen.getByLabelText("Gmail")).toBeInTheDocument();
      expect(
        screen.getByText(
          "Not supported for this execution scope. Uncheck it to remove it.",
        ),
      ).toBeInTheDocument();
    });
  });

  it("displays selected agent details", () => {
    render(<AgentEditor />);

    expect(screen.getByDisplayValue("Test Agent")).toBeTruthy();
    expect(screen.getByDisplayValue("Test role")).toBeTruthy();
    expect(screen.getByDisplayValue("Test instruction")).toBeTruthy();
    // Rooms are now displayed as checkboxes, not input fields
    const testRoomCheckbox = screen.getByRole("checkbox", {
      name: /Test Room/i,
    });
    expect(testRoomCheckbox).toBeChecked();
  });

  it("clears zero history runs instead of writing them through", async () => {
    render(<AgentEditor />);

    const historyRunsInput = screen.getByLabelText("History Runs");
    fireEvent.change(historyRunsInput, { target: { value: "0" } });

    await waitFor(() => {
      expect(mockStore.updateAgent).toHaveBeenCalledWith("test_agent", {
        num_history_runs: null,
      });
    });
  });

  it("shows empty state when no agent is selected", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      selectedAgentId: null,
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);
    expect(screen.getByText("Select an agent to edit")).toBeTruthy();
  });

  it("calls updateAgent when form fields change", async () => {
    render(<AgentEditor />);

    const displayNameInput = screen.getByLabelText("Display Name");
    fireEvent.change(displayNameInput, { target: { value: "Updated Agent" } });

    // Wait a bit to ensure the update is called
    await waitFor(() => {
      expect(mockStore.updateAgent).toHaveBeenCalled();
    });
  });

  it("does not cause infinite update loops when updateAgent is called", async () => {
    let updateCount = 0;
    const trackingUpdateAgent = vi.fn((_id, _updates) => {
      updateCount++;
      // Simulate what the real updateAgent does - updates the agent in the store
      mockStore.agents = mockStore.agents.map((agent) =>
        agent.id === _id ? { ...agent, ..._updates } : agent,
      );
    });

    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      updateAgent: trackingUpdateAgent,
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);

    const displayNameInput = screen.getByLabelText("Display Name");
    fireEvent.change(displayNameInput, { target: { value: "Updated Agent" } });

    // Wait to see if multiple updates occur
    await waitFor(() => {
      expect(updateCount).toBeGreaterThan(0);
    });

    // The update count should be reasonable (not hundreds/thousands)
    expect(updateCount).toBeLessThan(10);
  });

  it("handles save button click", async () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      isDirty: true,
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);

    const saveButton = screen.getByRole("button", { name: /save/i });
    expect(saveButton).not.toBeDisabled();

    fireEvent.click(saveButton);

    await waitFor(() => {
      expect(mockStore.saveConfig).toHaveBeenCalled();
    });
  });

  it("shows a toast when a save is superseded by newer draft edits", async () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      isDirty: true,
      rooms: mockStore.rooms,
      saveConfig: vi.fn().mockResolvedValue({ status: "stale" }),
    });

    render(<AgentEditor />);

    fireEvent.click(screen.getByRole("button", { name: /save/i }));

    const { toast } = await import("@/components/ui/toaster");
    await waitFor(() => {
      expect(toast).toHaveBeenCalledWith({
        title: "Save Failed",
        description: "Save was superseded by newer draft edits.",
        variant: "destructive",
      });
    });
  });

  it("renders backend validation errors for private fields", () => {
    const privateAgent: Agent = {
      ...mockAgent,
      private: {
        per: "user",
        root: "../outside",
        template_dir: "   ",
        context_files: ["../SOUL.md"],
        knowledge: {
          enabled: true,
          path: "../memory",
          watch: true,
        },
      },
    };

    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [privateAgent],
      config: {
        ...mockConfig,
        agents: {
          test_agent: privateAgent,
        },
      },
      diagnostics: [
        {
          kind: "global",
          message: "Configuration validation failed",
          blocking: false,
        },
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "private", "root"],
            msg: "private.root must stay within the private instance root",
            type: "value_error",
          },
        },
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "private", "template_dir"],
            msg: "template_dir must not be blank",
            type: "value_error",
          },
        },
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "private", "context_files"],
            msg: "private.context_files must stay under the private root",
            type: "value_error",
          },
        },
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "private", "knowledge", "path"],
            msg: "private.knowledge.path must stay under the private root",
            type: "value_error",
          },
        },
      ],
    });

    render(<AgentEditor />);

    expect(
      screen.getByText(
        "private.root must stay within the private instance root",
      ),
    ).toBeInTheDocument();
    expect(
      screen.getByText("template_dir must not be blank"),
    ).toBeInTheDocument();
    expect(
      screen.getByText(
        "private.context_files must stay under the private root",
      ),
    ).toBeInTheDocument();
    expect(
      screen.getByText(
        "private.knowledge.path must stay under the private root",
      ),
    ).toBeInTheDocument();
  });

  it("disables save button when not dirty", () => {
    render(<AgentEditor />);

    const saveButton = screen.getByRole("button", { name: /save/i });
    expect(saveButton).toBeDisabled();
  });

  it("handles delete button click with confirmation", () => {
    const confirmSpy = vi.spyOn(window, "confirm").mockReturnValue(true);

    render(<AgentEditor />);

    const deleteButton = screen.getByRole("button", { name: /delete/i });
    fireEvent.click(deleteButton);

    expect(confirmSpy).toHaveBeenCalledWith(
      "Are you sure you want to delete this agent?",
    );
    expect(mockStore.deleteAgent).toHaveBeenCalledWith("test_agent");

    confirmSpy.mockRestore();
  });

  it("does not delete when user cancels confirmation", () => {
    const confirmSpy = vi.spyOn(window, "confirm").mockReturnValue(false);

    render(<AgentEditor />);

    const deleteButton = screen.getByRole("button", { name: /delete/i });
    fireEvent.click(deleteButton);

    expect(mockStore.deleteAgent).not.toHaveBeenCalled();

    confirmSpy.mockRestore();
  });

  it("adds and removes instructions", () => {
    render(<AgentEditor />);

    // Find add instruction button
    const addInstructionButton = screen.getByTestId("add-instruction-button");

    fireEvent.click(addInstructionButton);

    // Should have called updateAgent with new instruction
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        instructions: ["Test instruction", ""],
      }),
    );
  });

  it("adds and removes rooms", () => {
    render(<AgentEditor />);

    // Test Room checkbox should be checked initially
    const testRoomCheckbox = screen.getByRole("checkbox", {
      name: /Test Room/i,
    });
    expect(testRoomCheckbox).toBeChecked();

    // Uncheck Test Room
    fireEvent.click(testRoomCheckbox);
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        rooms: [],
      }),
    );

    // Check Other Room
    const otherRoomCheckbox = screen.getByRole("checkbox", {
      name: /Other Room/i,
    });
    fireEvent.click(otherRoomCheckbox);
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        rooms: ["other_room"],
      }),
    );
  });

  it("enables requester-private state with the default private scope", async () => {
    render(<AgentEditor />);

    fireEvent.click(screen.getByLabelText("Enable requester-private state"));

    await waitFor(() => {
      expect(mockStore.setAgentPrivateEnabled).toHaveBeenCalledWith(
        "test_agent",
        true,
      );
    });
  });

  it("clears explicit worker_scope when enabling private state", async () => {
    const scopedAgent: Agent = {
      ...mockAgent,
      worker_scope: "user_agent",
    };

    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [scopedAgent],
      config: {
        ...mockConfig,
        agents: {
          test_agent: scopedAgent,
        },
      },
    });

    render(<AgentEditor />);

    fireEvent.click(screen.getByLabelText("Enable requester-private state"));

    await waitFor(() => {
      expect(mockStore.setAgentPrivateEnabled).toHaveBeenCalledWith(
        "test_agent",
        true,
      );
    });
  });

  it("restores prior worker_scope when private mode is disabled after rerender", async () => {
    const scopedAgent: Agent = {
      ...mockAgent,
      worker_scope: "user_agent",
    };

    let state = {
      ...mockStore,
      agents: [scopedAgent],
      config: {
        ...mockConfig,
        agents: {
          test_agent: scopedAgent,
        },
      },
    };
    const updateAgent = vi.fn((agentId: string, updates: Partial<Agent>) => {
      const currentAgent = state.agents.find((agent) => agent.id === agentId);
      if (!currentAgent) {
        return;
      }
      const normalizedUpdates = normalizeAgentUpdates(currentAgent, updates);
      const nextAgent = { ...currentAgent, ...normalizedUpdates };
      state = {
        ...state,
        agents: state.agents.map((agent) =>
          agent.id === agentId ? nextAgent : agent,
        ),
        config: {
          ...state.config,
          agents: {
            ...state.config.agents,
            [agentId]: nextAgent,
          },
        },
        updateAgent,
      };
    });
    const privateWorkerScopeBackups: Record<
      string,
      Agent["worker_scope"] | null
    > = {};
    const setAgentPrivateEnabled = vi.fn(
      (agentId: string, enabled: boolean) => {
        const currentAgent = state.agents.find((agent) => agent.id === agentId);
        if (!currentAgent) {
          return;
        }
        if (enabled) {
          privateWorkerScopeBackups[agentId] =
            currentAgent.worker_scope ?? null;
          updateAgent(agentId, { private: { per: "user" } });
          return;
        }
        const restoredWorkerScope = privateWorkerScopeBackups[agentId];
        delete privateWorkerScopeBackups[agentId];
        updateAgent(
          agentId,
          restoredWorkerScope != null
            ? { private: undefined, worker_scope: restoredWorkerScope }
            : { private: undefined },
        );
      },
    );
    state = { ...state, updateAgent, setAgentPrivateEnabled };
    (useConfigStore as any).mockImplementation(() => state);

    const view = render(<AgentEditor />);

    const privateToggle = screen.getByLabelText(
      "Enable requester-private state",
    );
    fireEvent.click(privateToggle);
    await waitFor(() => {
      expect(state.agents[0].private).toEqual({ per: "user" });
      expect(state.agents[0].worker_scope).toBeUndefined();
    });

    view.rerender(<AgentEditor />);
    fireEvent.click(screen.getByLabelText("Enable requester-private state"));

    await waitFor(() => {
      expect(setAgentPrivateEnabled).toHaveBeenNthCalledWith(
        1,
        "test_agent",
        true,
      );
      expect(setAgentPrivateEnabled).toHaveBeenNthCalledWith(
        2,
        "test_agent",
        false,
      );
      expect(state.agents[0].private).toBeUndefined();
      expect(state.agents[0].worker_scope).toBe("user_agent");
    });
  });

  it("renders and updates private agent fields", async () => {
    const privateAgent: Agent = {
      ...mockAgent,
      private: {
        per: "user_agent",
        root: "mind_data",
        template_dir: "./mind_template",
        context_files: ["SOUL.md"],
        knowledge: {
          enabled: true,
          path: "memory",
          watch: true,
        },
      },
    };

    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [privateAgent],
      config: {
        ...mockConfig,
        agents: {
          test_agent: privateAgent,
        },
      },
    });

    render(<AgentEditor />);

    expect(screen.getByDisplayValue("mind_data")).toBeInTheDocument();
    expect(screen.getByDisplayValue("./mind_template")).toBeInTheDocument();
    expect(screen.getByDisplayValue("SOUL.md")).toBeInTheDocument();
    expect(screen.getByDisplayValue("memory")).toBeInTheDocument();

    fireEvent.change(screen.getByLabelText("Private Root"), {
      target: { value: "updated_data" },
    });

    await waitFor(() => {
      expect(mockStore.updateAgent).toHaveBeenCalledWith(
        "test_agent",
        expect.objectContaining({
          private: expect.objectContaining({
            per: "user_agent",
            root: "updated_data",
          }),
        }),
      );
    });
  });

  it("enables private knowledge with a default path", async () => {
    let state = {
      ...mockStore,
      agents: [{ ...mockAgent }],
      config: {
        ...mockConfig,
        agents: {
          test_agent: { ...mockAgent },
        },
      },
    };
    const updateAgent = vi.fn((agentId: string, updates: Partial<Agent>) => {
      const currentAgent = state.agents.find((agent) => agent.id === agentId);
      if (!currentAgent) {
        return;
      }
      const normalizedUpdates = normalizeAgentUpdates(currentAgent, updates);
      const nextAgent = { ...currentAgent, ...normalizedUpdates };
      state = {
        ...state,
        agents: state.agents.map((agent) =>
          agent.id === agentId ? nextAgent : agent,
        ),
        config: {
          ...state.config,
          agents: {
            ...state.config.agents,
            [agentId]: nextAgent,
          },
        },
        updateAgent,
      };
    });
    const setAgentPrivateEnabled = vi.fn(
      (agentId: string, enabled: boolean) => {
        const currentAgent = state.agents.find((agent) => agent.id === agentId);
        if (!currentAgent) {
          return;
        }
        if (enabled) {
          updateAgent(agentId, { private: { per: "user" } });
          return;
        }
        updateAgent(agentId, { private: undefined });
      },
    );
    state = { ...state, updateAgent, setAgentPrivateEnabled };
    (useConfigStore as any).mockImplementation(() => state);

    const view = render(<AgentEditor />);

    fireEvent.click(screen.getByLabelText("Enable requester-private state"));
    view.rerender(<AgentEditor />);
    fireEvent.click(screen.getByLabelText("Enable private knowledge"));

    await waitFor(() => {
      expect(state.agents[0].private).toEqual({
        per: "user",
        knowledge: {
          enabled: true,
          path: "memory",
          watch: true,
        },
      });
    });
  });

  it("updates private knowledge description", async () => {
    const privateAgent: Agent = {
      ...mockAgent,
      private: {
        per: "user",
        knowledge: {
          enabled: true,
          path: "memory",
          watch: true,
        },
      },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [privateAgent],
      config: {
        ...mockConfig,
        agents: {
          test_agent: privateAgent,
        },
      },
      agentPoliciesByAgent: makeAgentPolicies({
        is_private: true,
        effective_execution_scope: "user",
        scope_label: "private.per=user",
        scope_source: "private.per",
        private_workspace_enabled: true,
        private_agent_knowledge_enabled: true,
      }),
    });

    render(<AgentEditor />);

    fireEvent.change(screen.getByLabelText("Private Knowledge Description"), {
      target: {
        value: "Requester-private notes, preferences, and working memory.",
      },
    });

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        private: expect.objectContaining({
          knowledge: expect.objectContaining({
            description:
              "Requester-private notes, preferences, and working memory.",
          }),
        }),
      }),
    );
  });

  it("drops empty compaction overrides during normalization", () => {
    expect(
      normalizeAgentUpdates(mockAgent, { compaction: {} }).compaction,
    ).toBeUndefined();
    expect(
      normalizeAgentUpdates(
        { ...mockAgent, compaction: { enabled: true, threshold_tokens: 2000 } },
        { compaction: { threshold_tokens: undefined, model: "   " } },
      ).compaction,
    ).toBeUndefined();
  });

  it("preserves explicit disabled compaction overrides during normalization", () => {
    expect(
      normalizeAgentUpdates(mockAgent, { compaction: { enabled: false } })
        .compaction,
    ).toEqual({
      enabled: false,
    });
  });

  it("preserves explicit compaction model clears during normalization", () => {
    expect(
      normalizeAgentUpdates(mockAgent, { compaction: { model: null } })
        .compaction,
    ).toEqual({
      model: null,
    });
  });

  it("preserves explicit compaction fallback model clears during normalization", () => {
    expect(
      normalizeAgentUpdates(mockAgent, { compaction: { fallback_model: null } })
        .compaction,
    ).toEqual({
      fallback_model: null,
    });
  });

  it("enables authored compaction overrides and clears the inherited sibling threshold", () => {
    expect(
      normalizeAgentUpdates(mockAgent, {
        compaction: {
          threshold_percent: 0.6,
          threshold_tokens: null,
        },
      }).compaction,
    ).toEqual({
      enabled: true,
      threshold_percent: 0.6,
      threshold_tokens: null,
    });
  });

  it("preserves replay-window-only compaction overrides as enabled", () => {
    expect(
      normalizeAgentUpdates(mockAgent, {
        compaction: { replay_window_tokens: 200_000 },
      }).compaction,
    ).toEqual({
      enabled: true,
      replay_window_tokens: 200_000,
    });
  });

  it("preserves timeout-only compaction overrides as enabled", () => {
    expect(
      normalizeAgentUpdates(mockAgent, {
        compaction: { timeout_seconds: 300 },
      }).compaction,
    ).toEqual({
      enabled: true,
      timeout_seconds: 300,
    });
  });

  it("authors a replay window from the editor", async () => {
    render(<AgentEditor />);

    fireEvent.change(screen.getByLabelText("Replay Window Tokens"), {
      target: { value: "200000" },
    });

    await waitFor(() => {
      expect(mockStore.updateAgent).toHaveBeenCalledWith(
        "test_agent",
        expect.objectContaining({
          compaction: { replay_window_tokens: 200_000 },
        }),
      );
    });
  });

  it("treats authored compaction overrides as enabled in the editor", () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: { threshold_tokens: 2000 },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        agents: { test_agent: compactionAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByRole("checkbox", {
        name: /enable automatic required compaction/i,
      }),
    ).toBeChecked();
  });

  it("treats a timeout-only override as enabled even when defaults disable compaction", () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: { timeout_seconds: 300 },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        agents: { test_agent: compactionAgent },
        defaults: { ...mockConfig.defaults, compaction: { enabled: false } },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByRole("checkbox", {
        name: /enable automatic required compaction/i,
      }),
    ).toBeChecked();
  });

  it("clears invalid compaction integer input instead of writing NaN", async () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: { enabled: true, threshold_tokens: 2000 },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        agents: { test_agent: compactionAgent },
      },
    });

    render(<AgentEditor />);

    fireEvent.change(screen.getByLabelText("Threshold Tokens"), {
      target: { value: "abc" },
    });

    await waitFor(() => {
      expect(mockStore.updateAgent).toHaveBeenCalledWith(
        "test_agent",
        expect.objectContaining({
          compaction: { enabled: true },
        }),
      );
    });
  });

  it("clears the compaction model as an explicit null override", async () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: { enabled: true, model: "summary-model" },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        agents: { test_agent: compactionAgent },
      },
    });

    render(<AgentEditor />);

    fireEvent.change(screen.getByLabelText("Compaction Model"), {
      target: { value: "" },
    });

    await waitFor(() => {
      expect(mockStore.updateAgent).toHaveBeenCalledWith(
        "test_agent",
        expect.objectContaining({
          compaction: { enabled: true, model: null },
        }),
      );
    });
  });

  it("shows automatic required compaction as disabled for a pure model clear when defaults are disabled", () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: { model: null },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          compaction: {
            enabled: false,
            reserve_tokens: 16384,
            threshold_percent: 0.8,
          },
        },
        agents: { test_agent: compactionAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByLabelText("Enable automatic required compaction"),
    ).not.toBeChecked();
  });

  it("shows automatic required compaction as disabled for a pure fallback model clear when defaults are disabled", () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: { fallback_model: null },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          compaction: {
            enabled: false,
            reserve_tokens: 16384,
            threshold_percent: 0.8,
          },
        },
        agents: { test_agent: compactionAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByLabelText("Enable automatic required compaction"),
    ).not.toBeChecked();
  });

  it("shows automatic required compaction as disabled for an empty authored override when defaults are disabled", () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: {},
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          compaction: {
            enabled: false,
            reserve_tokens: 16384,
            threshold_percent: 0.8,
          },
        },
        agents: { test_agent: compactionAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByLabelText("Enable automatic required compaction"),
    ).not.toBeChecked();
  });

  it("shows replay-window-only compaction as enabled when defaults are disabled", () => {
    const compactionAgent: Agent = {
      ...mockAgent,
      compaction: { replay_window_tokens: 200_000 },
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [compactionAgent],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          compaction: {
            enabled: false,
            reserve_tokens: 16384,
            threshold_percent: 0.8,
          },
        },
        agents: { test_agent: compactionAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByLabelText("Enable automatic required compaction"),
    ).toBeChecked();
  });

  it("shows automatic required compaction as enabled when defaults.compaction is omitted", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [mockAgent],
      config: {
        ...mockConfig,
        defaults: {},
        agents: { test_agent: mockAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByLabelText("Enable automatic required compaction"),
    ).toBeChecked();
  });

  it("shows automatic required compaction as disabled when defaults.compaction is null", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [mockAgent],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          compaction: null,
        },
        agents: { test_agent: mockAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByLabelText("Enable automatic required compaction"),
    ).not.toBeChecked();
  });

  it("shows automatic required compaction as enabled when defaults.compaction is an authored empty object", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [mockAgent],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          compaction: {},
        },
        agents: { test_agent: mockAgent },
      },
    });

    render(<AgentEditor />);

    expect(
      screen.getByLabelText("Enable automatic required compaction"),
    ).toBeChecked();
  });

  it("shows field-level history and compaction validation errors", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      diagnostics: [
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "num_history_runs"],
            msg: "History runs must be at least 1.",
            type: "value_error",
          },
        },
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "num_history_messages"],
            msg: "History messages must be at least 1.",
            type: "value_error",
          },
        },
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "max_tool_calls_from_history"],
            msg: "Max tool calls must be at least 0.",
            type: "value_error",
          },
        },
        {
          kind: "validation",
          issue: {
            loc: ["agents", "test_agent", "compaction"],
            msg: "Compaction config is invalid.",
            type: "value_error",
          },
        },
      ],
    });

    render(<AgentEditor />);

    expect(
      screen.getByText("History runs must be at least 1."),
    ).toBeInTheDocument();
    expect(
      screen.getByText("History messages must be at least 1."),
    ).toBeInTheDocument();
    expect(
      screen.getByText("Max tool calls must be at least 0."),
    ).toBeInTheDocument();
    expect(
      screen.getByText("Compaction config is invalid."),
    ).toBeInTheDocument();
  });

  it("uses the canonical shared context placeholder", async () => {
    const agentWithoutContextFiles: Agent = {
      ...mockAgent,
      context_files: [],
    };

    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [agentWithoutContextFiles],
      config: {
        ...mockConfig,
        agents: {
          test_agent: agentWithoutContextFiles,
        },
      },
    });

    render(<AgentEditor />);

    fireEvent.click(screen.getByTestId("add-context-file-button"));

    expect(
      screen.getByPlaceholderText(SHARED_CONTEXT_FILE_PLACEHOLDER),
    ).toBeInTheDocument();
  });

  it("updates knowledge bases when checkboxes are toggled", () => {
    render(<AgentEditor />);

    const researchCheckbox = screen.getByRole("checkbox", {
      name: /research/i,
    });
    expect(researchCheckbox).toBeChecked();

    const legalCheckbox = screen.getByRole("checkbox", { name: /legal/i });
    fireEvent.click(legalCheckbox);
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        knowledge_bases: ["research", "legal"],
      }),
    );

    fireEvent.click(researchCheckbox);
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        knowledge_bases: ["legal"],
      }),
    );
  });

  it("hides delegate from the tools picker", () => {
    render(<AgentEditor />);

    // calculator and file should appear as checkboxes
    expect(screen.getByRole("checkbox", { name: "Calculator" })).toBeTruthy();
    expect(screen.getByRole("checkbox", { name: "File" })).toBeTruthy();

    // delegate should NOT appear even though useTools returns it
    expect(
      screen.queryByRole("checkbox", { name: /agent delegation/i }),
    ).toBeNull();
  });

  it("updates tools when checkboxes are toggled", () => {
    render(<AgentEditor />);

    // Find the calculator checkbox (should be checked) — use exact name to
    // distinguish from the worker-tools checkboxes which have "worker ..." labels
    const calculatorCheckbox = screen.getByRole("checkbox", {
      name: "Calculator",
    });
    expect(calculatorCheckbox).toBeChecked();

    // Uncheck it
    fireEvent.click(calculatorCheckbox);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        tools: [],
      }),
    );

    // Check another tool
    const fileCheckbox = screen.getByRole("checkbox", { name: "File" });
    fireEvent.click(fileCheckbox);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        tools: ["file"],
      }),
    );
  });

  it("updates skills when checkboxes are toggled", async () => {
    render(<AgentEditor />);

    const debuggingCheckbox = await screen.findByRole("checkbox", {
      name: /debugging/i,
    });
    expect(debuggingCheckbox).toBeChecked();

    fireEvent.click(debuggingCheckbox);
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        skills: [],
      }),
    );

    const codeReviewCheckbox = screen.getByRole("checkbox", {
      name: /code-review/i,
    });
    fireEvent.click(codeReviewCheckbox);
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        skills: ["code-review"],
      }),
    );
  });

  it("renders missing assigned skills so they can be removed", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [
        {
          ...mockAgent,
          skills: ["ghost-skill"],
        },
      ],
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);

    const ghostSkillCheckbox = screen.getByRole("checkbox", {
      name: /ghost-skill/i,
    });
    expect(ghostSkillCheckbox).toBeChecked();

    fireEvent.click(ghostSkillCheckbox);
    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        skills: [],
      }),
    );
  });

  it("handles model selection", () => {
    render(<AgentEditor />);

    // Open the select dropdown
    const modelSelect = screen.getByLabelText("Model");
    fireEvent.click(modelSelect);

    // Select a different model
    const customOption = screen.getByRole("option", { name: "custom" });
    fireEvent.click(customOption);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        model: "custom",
      }),
    );
  });

  it("updates memory backend when selected", () => {
    render(<AgentEditor />);

    const memoryBackendSelect = screen.getByLabelText("Memory Backend");
    fireEvent.click(memoryBackendSelect);

    const fileOption = screen.getByRole("option", {
      name: "File (markdown memory)",
    });
    fireEvent.click(fileOption);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        memory_backend: "file",
      }),
    );
  });

  it("updates memory backend to disabled when none is selected", () => {
    render(<AgentEditor />);

    const memoryBackendSelect = screen.getByLabelText("Memory Backend");
    fireEvent.click(memoryBackendSelect);

    const disabledOption = screen.getByRole("option", {
      name: "Disabled (stateless)",
    });
    fireEvent.click(disabledOption);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        memory_backend: "none",
      }),
    );
  });

  it("clears memory backend override when inherit is selected", () => {
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [{ ...mockAgent, memory_backend: "file" }],
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);

    const memoryBackendSelect = screen.getByLabelText("Memory Backend");
    fireEvent.click(memoryBackendSelect);

    const inheritOption = screen.getByRole("option", {
      name: /Inherit global/i,
    });
    fireEvent.click(inheritOption);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        memory_backend: undefined,
      }),
    );
  });

  it("updates learning mode when selected", () => {
    render(<AgentEditor />);

    const modeSelect = screen.getByLabelText("Learning Mode");
    fireEvent.click(modeSelect);

    const agenticOption = screen.getByRole("option", {
      name: "Agentic (tool-driven)",
    });
    fireEvent.click(agenticOption);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        learning_mode: "agentic",
      }),
    );
  });

  it("uses config defaults when agent learning fields are omitted", () => {
    const agentWithoutLearning = {
      ...mockAgent,
      learning: undefined,
      learning_mode: undefined,
    };
    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      agents: [agentWithoutLearning],
      config: {
        ...mockConfig,
        defaults: {
          ...mockConfig.defaults,
          learning: false,
          learning_mode: "agentic",
        },
      },
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);

    const learningCheckbox = screen.getByRole("checkbox", {
      name: /enable learning/i,
    });
    expect(learningCheckbox).not.toBeChecked();
    expect(screen.getByLabelText("Learning Mode")).toHaveTextContent(
      "Agentic (tool-driven)",
    );
  });

  it("updates learning when checkbox is toggled", () => {
    render(<AgentEditor />);

    const learningCheckbox = screen.getByRole("checkbox", {
      name: /enable learning/i,
    });
    expect(learningCheckbox).toBeChecked();

    fireEvent.click(learningCheckbox);

    expect(mockStore.updateAgent).toHaveBeenCalledWith(
      "test_agent",
      expect.objectContaining({
        learning: false,
      }),
    );
  });

  describe("worker_tools inheritance", () => {
    const twoToolAgent = { ...mockAgent, tools: ["calculator", "file"] };

    it("shows inherited defaults as checked with (default) label", () => {
      (useConfigStore as any).mockReturnValue({
        ...mockStore,
        agents: [{ ...twoToolAgent, worker_tools: undefined }],
        config: {
          ...mockConfig,
          defaults: { ...mockConfig.defaults, worker_tools: ["calculator"] },
        },
        rooms: mockStore.rooms,
      });

      render(<AgentEditor />);

      const workerCalc = screen.getByRole("checkbox", {
        name: "worker calculator",
      });
      expect(workerCalc).toBeChecked();
      expect(screen.getByText("calculator (default)")).toBeTruthy();

      const workerFile = screen.getByRole("checkbox", { name: "worker file" });
      expect(workerFile).not.toBeChecked();
    });

    it("seeds from defaults on first toggle so other defaults are preserved", () => {
      (useConfigStore as any).mockReturnValue({
        ...mockStore,
        agents: [{ ...twoToolAgent, worker_tools: undefined }],
        config: {
          ...mockConfig,
          defaults: { ...mockConfig.defaults, worker_tools: ["calculator"] },
        },
        rooms: mockStore.rooms,
      });

      render(<AgentEditor />);

      // Toggle file ON — should seed from defaults first, so calculator stays
      const workerFile = screen.getByRole("checkbox", { name: "worker file" });
      fireEvent.click(workerFile);

      expect(mockStore.updateAgent).toHaveBeenCalledWith(
        "test_agent",
        expect.objectContaining({
          worker_tools: ["calculator", "file"],
        }),
      );
    });

    it("renders empty list as explicit disable (all unchecked, no default labels)", () => {
      (useConfigStore as any).mockReturnValue({
        ...mockStore,
        agents: [{ ...twoToolAgent, worker_tools: [] }],
        config: {
          ...mockConfig,
          defaults: { ...mockConfig.defaults, worker_tools: ["calculator"] },
        },
        rooms: mockStore.rooms,
      });

      render(<AgentEditor />);

      const workerCalc = screen.getByRole("checkbox", {
        name: "worker calculator",
      });
      expect(workerCalc).not.toBeChecked();

      const workerFile = screen.getByRole("checkbox", { name: "worker file" });
      expect(workerFile).not.toBeChecked();

      // No worker tool label should show "(default)"
      expect(screen.queryByText("calculator (default)")).toBeNull();
      expect(screen.queryByText("file (default)")).toBeNull();
    });
  });

  it("regression test: form updates should not cause infinite loops", async () => {
    let updateCount = 0;
    const trackingUpdateAgent = vi.fn((_id, _updates) => {
      updateCount++;
    });

    (useConfigStore as any).mockReturnValue({
      ...mockStore,
      updateAgent: trackingUpdateAgent,
      rooms: mockStore.rooms,
    });

    render(<AgentEditor />);

    // Simulate typing in the display name field
    const displayNameInput = screen.getByLabelText("Display Name");

    // Type several characters
    fireEvent.change(displayNameInput, { target: { value: "U" } });
    fireEvent.change(displayNameInput, { target: { value: "Up" } });
    fireEvent.change(displayNameInput, { target: { value: "Updated" } });

    // Wait a bit to ensure any potential loops would have time to manifest
    await new Promise((resolve) => setTimeout(resolve, 100));

    // Each change should result in exactly one update call
    expect(updateCount).toBe(3);

    // Now test that rapid changes don't cause exponential updates
    updateCount = 0;
    for (let i = 0; i < 10; i++) {
      fireEvent.change(displayNameInput, { target: { value: `Updated ${i}` } });
    }

    await new Promise((resolve) => setTimeout(resolve, 100));

    // Should be exactly 10 updates, not hundreds or thousands
    expect(updateCount).toBe(10);
  });
});
