diff --git a/apps/web/app/settings/agents/page.tsx b/apps/web/app/settings/agents/page.tsx index 0adeda507e..4b93d7f221 100644 --- a/apps/web/app/settings/agents/page.tsx +++ b/apps/web/app/settings/agents/page.tsx @@ -14,11 +14,8 @@ import { import { Badge } from "@kandev/ui/badge"; import { Button } from "@kandev/ui/button"; import { Card, CardContent } from "@kandev/ui/card"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@kandev/ui/select"; import { Separator } from "@kandev/ui/separator"; -import { useAppStore, useAppStoreApi } from "@/components/state-provider"; -import { useToast } from "@/components/toast-provider"; -import { updateWorkspaceAction } from "@/app/actions/workspaces"; +import { useAppStore } from "@/components/state-provider"; import { createCustomTUIAgent, listAgentDiscovery, @@ -372,72 +369,6 @@ function AgentProfilesSection({ savedAgents }: AgentProfilesSectionProps) { ); } -function ConfigChatAgentSection() { - const workspace = useAppStore( - (s) => s.workspaces.items.find((w) => w.id === s.workspaces.activeId) ?? null, - ); - const profiles = useAppStore((s) => s.agentProfiles.items ?? []); - const currentProfileId = workspace?.default_config_agent_profile_id ?? ""; - const [saving, setSaving] = useState(false); - const { toast } = useToast(); - - const storeApi = useAppStoreApi(); - - const handleChange = async (value: string) => { - const effectiveValue = value === "none" ? "" : value; - if (!workspace) return; - setSaving(true); - try { - await updateWorkspaceAction(workspace.id, { - default_config_agent_profile_id: effectiveValue, - }); - const { workspaces, setWorkspaces } = storeApi.getState(); - setWorkspaces( - workspaces.items.map((w) => - w.id === workspace.id ? { ...w, default_config_agent_profile_id: effectiveValue } : w, - ), - ); - toast({ title: "Configuration agent updated", variant: "success" }); - } catch (error) { - toast({ - title: "Failed to update", - description: error instanceof Error ? error.message : "Unknown error", - variant: "error", - }); - } finally { - setSaving(false); - } - }; - - if (!workspace) return null; - - return ( -
- -
-

Configuration Chat Agent

-

- Choose which agent profile to use for the Configuration Chat. This agent can manage your - workflows, agent profiles, and MCP configuration. -

-
- -
- ); -} - function useAgentPageState() { const { items: discoveryAgents, loading: discoveryLoading } = useAgentDiscovery(); const savedAgents = useAppStore((state) => state.settingsAgents.items); @@ -563,8 +494,6 @@ export default function AgentsSettingsPage() { - - ; + return ( +
+ + +
+ ); } diff --git a/apps/web/components/settings/config-chat-agent-section.tsx b/apps/web/components/settings/config-chat-agent-section.tsx new file mode 100644 index 0000000000..3d0fa1d6e0 --- /dev/null +++ b/apps/web/components/settings/config-chat-agent-section.tsx @@ -0,0 +1,74 @@ +"use client"; + +import { useState } from "react"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@kandev/ui/select"; +import { Separator } from "@kandev/ui/separator"; +import { useAppStore, useAppStoreApi } from "@/components/state-provider"; +import { useToast } from "@/components/toast-provider"; +import { updateWorkspaceAction } from "@/app/actions/workspaces"; + +export function ConfigChatAgentSection() { + const workspace = useAppStore( + (s) => s.workspaces.items.find((w) => w.id === s.workspaces.activeId) ?? null, + ); + const profiles = useAppStore((s) => s.agentProfiles.items ?? []); + const currentProfileId = workspace?.default_config_agent_profile_id ?? ""; + const [saving, setSaving] = useState(false); + const { toast } = useToast(); + + const storeApi = useAppStoreApi(); + + const handleChange = async (value: string) => { + const effectiveValue = value === "none" ? "" : value; + if (!workspace) return; + setSaving(true); + try { + await updateWorkspaceAction(workspace.id, { + default_config_agent_profile_id: effectiveValue, + }); + const { workspaces, setWorkspaces } = storeApi.getState(); + setWorkspaces( + workspaces.items.map((w) => + w.id === workspace.id ? { ...w, default_config_agent_profile_id: effectiveValue } : w, + ), + ); + toast({ title: "Configuration agent updated", variant: "success" }); + } catch (error) { + toast({ + title: "Failed to update", + description: error instanceof Error ? error.message : "Unknown error", + variant: "error", + }); + } finally { + setSaving(false); + } + }; + + if (!workspace) return null; + + return ( +
+ +
+

Configuration Chat Agent

+

+ Choose which agent profile to use for the Configuration Chat. This agent can manage your + workflows, agent profiles, and MCP configuration. +

+
+ +
+ ); +} diff --git a/apps/web/e2e/tests/settings/utility-agents.spec.ts b/apps/web/e2e/tests/settings/utility-agents.spec.ts index 14927479d0..cfe05b747f 100644 --- a/apps/web/e2e/tests/settings/utility-agents.spec.ts +++ b/apps/web/e2e/tests/settings/utility-agents.spec.ts @@ -192,4 +192,30 @@ test.describe("Utility Agents settings page", () => { [], ); }); + + test("Configuration Chat Agent section lives here, not on the agents page", async ({ + testPage, + }) => { + // Regression guard for the move from /settings/agents to /settings/utility-agents. + await testPage.goto("/settings/utility-agents"); + await expect( + testPage.getByRole("heading", { name: "Utility Agents", exact: true }), + ).toBeVisible({ timeout: 15_000 }); + await expect( + testPage.getByRole("heading", { name: "Configuration Chat Agent", exact: true }), + ).toBeVisible(); + await expect( + testPage.getByText( + "Choose which agent profile to use for the Configuration Chat. This agent can manage your workflows, agent profiles, and MCP configuration.", + ), + ).toBeVisible(); + + await testPage.goto("/settings/agents"); + await expect(testPage.getByRole("heading", { name: "Agents", exact: true })).toBeVisible({ + timeout: 15_000, + }); + await expect( + testPage.getByRole("heading", { name: "Configuration Chat Agent", exact: true }), + ).toHaveCount(0); + }); });