diff --git a/docs/ai-coder/agents/getting-started.md b/docs/ai-coder/agents/getting-started.md index 4678e65366..6120644519 100644 --- a/docs/ai-coder/agents/getting-started.md +++ b/docs/ai-coder/agents/getting-started.md @@ -195,7 +195,7 @@ deployment. Use this to encode organizational conventions: - Required review processes before merging. - Any guardrails specific to your environment. -Configure the system prompt from **AI Settings** > **Instructions** +Configure the system prompt from **AI Settings** > **Coder Agents** > **Instructions** or via the API at `PUT /api/experimental/chats/config/system-prompt`. See [Platform Controls](./platform-controls/index.md) for details. diff --git a/docs/ai-coder/agents/platform-controls/index.md b/docs/ai-coder/agents/platform-controls/index.md index 94ad362d7c..e702ea5f07 100644 --- a/docs/ai-coder/agents/platform-controls/index.md +++ b/docs/ai-coder/agents/platform-controls/index.md @@ -52,7 +52,7 @@ Administrators can set a system prompt that applies to all agent sessions. This is useful for establishing organizational conventions: coding standards, commit message formats, preferred libraries, or repository-specific context. -This setting is available under **AI Settings** > **Instructions** and is only accessible to administrators. Developers do not see or interact with it. +This setting is available under **AI Settings** > **Coder Agents** > **Instructions** and is only accessible to administrators. Developers do not see or interact with it. ### Plan mode instructions @@ -61,7 +61,7 @@ enters plan mode. These instructions supplement the built-in planning behavior and are useful for organization-specific planning requirements such as required plan sections, approval checkpoints, or review workflows. -This setting is available under **AI Settings** > **Instructions**. Developers do not edit it directly. +This setting is available under **AI Settings** > **Coder Agents** > **Instructions**. Developers do not edit it directly. The same value is exposed over the experimental chat configuration API: diff --git a/docs/ai-coder/agents/platform-controls/mcp-servers.md b/docs/ai-coder/agents/platform-controls/mcp-servers.md index 70846ce315..3e8b500655 100644 --- a/docs/ai-coder/agents/platform-controls/mcp-servers.md +++ b/docs/ai-coder/agents/platform-controls/mcp-servers.md @@ -4,12 +4,12 @@ Administrators can register external MCP servers that provide additional tools for agent chat sessions. Configured servers are injected into or offered to users during chat depending on the availability policy. -This is an admin-only feature accessible at **AI Settings** > **MCP servers** +This is an admin-only feature accessible at **AI Settings** > **Coder Agents** > **MCP servers** (`/ai/settings/mcp-servers`). ## Add an MCP server -1. Navigate to **AI Settings** > **MCP servers**. +1. Navigate to **AI Settings** > **Coder Agents** > **MCP servers**. 1. Click **Add**. 1. Fill in the configuration fields described below. 1. Click **Save**. diff --git a/site/src/modules/management/AISettingsSidebarView.stories.tsx b/site/src/modules/management/AISettingsSidebarView.stories.tsx new file mode 100644 index 0000000000..2a952ca982 --- /dev/null +++ b/site/src/modules/management/AISettingsSidebarView.stories.tsx @@ -0,0 +1,85 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { reactRouterParameters } from "storybook-addon-remix-react-router"; +import { MockNoPermissions, MockPermissions } from "#/testHelpers/entities"; +import AISettingsSidebarView from "./AISettingsSidebarView"; + +const meta: Meta = { + title: "modules/management/AISettingsSidebarView", + component: AISettingsSidebarView, + args: { + permissions: MockPermissions, + }, + parameters: { + reactRouter: reactRouterParameters({ + location: { path: "/ai/settings/coder-agents" }, + routing: [ + { path: "/ai/settings/governance", useStoryElement: true }, + { path: "/ai/settings/gateway-keys", useStoryElement: true }, + { path: "/ai/settings/providers", useStoryElement: true }, + { path: "/ai/settings/coder-agents", useStoryElement: true }, + { path: "/ai/settings/models", useStoryElement: true }, + { path: "/ai/settings/mcp-servers", useStoryElement: true }, + { path: "/ai/settings/templates", useStoryElement: true }, + { path: "/ai/settings/spend", useStoryElement: true }, + { path: "/ai/settings/instructions", useStoryElement: true }, + { path: "/ai/settings/lifecycle", useStoryElement: true }, + ], + }), + }, +}; + +export default meta; +type Story = StoryObj; + +export const CoderAgentsActive: Story = {}; + +export const ModelsActive: Story = { + parameters: { + reactRouter: reactRouterParameters({ + location: { path: "/ai/settings/models" }, + routing: [{ path: "/ai/settings/models", useStoryElement: true }], + }), + }, +}; + +export const SpendActive: Story = { + parameters: { + reactRouter: reactRouterParameters({ + location: { path: "/ai/settings/spend" }, + routing: [{ path: "/ai/settings/spend", useStoryElement: true }], + }), + }, +}; + +export const LifecycleActive: Story = { + parameters: { + reactRouter: reactRouterParameters({ + location: { path: "/ai/settings/lifecycle" }, + routing: [{ path: "/ai/settings/lifecycle", useStoryElement: true }], + }), + }, +}; + +export const ProvidersActive: Story = { + parameters: { + reactRouter: reactRouterParameters({ + location: { path: "/ai/settings/providers" }, + routing: [{ path: "/ai/settings/providers", useStoryElement: true }], + }), + }, +}; + +export const NoDeploymentConfig: Story = { + args: { + permissions: { + ...MockPermissions, + editDeploymentConfig: false, + }, + }, +}; + +export const NoPermissions: Story = { + args: { + permissions: MockNoPermissions, + }, +}; diff --git a/site/src/modules/management/AISettingsSidebarView.tsx b/site/src/modules/management/AISettingsSidebarView.tsx index 66ec8c8867..875055f047 100644 --- a/site/src/modules/management/AISettingsSidebarView.tsx +++ b/site/src/modules/management/AISettingsSidebarView.tsx @@ -1,15 +1,36 @@ -import type { FC } from "react"; +import type { FC, ReactNode } from "react"; +import { NavLink } from "react-router"; import { Sidebar as BaseSidebar, SettingsSidebarNavItem as SidebarNavItem, } from "#/components/Sidebar/Sidebar"; import type { Permissions } from "#/modules/permissions"; +import { cn } from "#/utils/cn"; interface AISettingsSidebarViewProps { /** Site-wide permissions. */ permissions: Permissions; } +const SubNavItem: FC<{ href: string; children?: ReactNode }> = ({ + href, + children, +}) => ( + + cn( + "relative -ml-px text-sm text-content-secondary no-underline font-medium py-2 pl-4 pr-3 transition-colors", + "border-0 border-solid border-l border-l-transparent hover:text-content-primary", + isActive && + "border-l-content-primary font-semibold text-content-primary", + ) + } + > + {children} + +); + const AISettingsSidebarView: FC = ({ permissions, }) => { @@ -23,7 +44,7 @@ const AISettingsSidebarView: FC = ({ )} {permissions.viewAIGatewayKeys && ( - AI Gateway Keys + AI Gateway keys )} {permissions.viewAnyAIProvider && ( @@ -32,35 +53,23 @@ const AISettingsSidebarView: FC = ({ )} {permissions.editDeploymentConfig && ( - Models - )} - {permissions.editDeploymentConfig && ( - Spend - )} - {permissions.editDeploymentConfig && ( - - Instructions - - )} - {permissions.editDeploymentConfig && ( - - Coder Agents - - )} - {permissions.editDeploymentConfig && ( - - Lifecycle - - )} - {permissions.editDeploymentConfig && ( - - Templates - - )} - {permissions.editDeploymentConfig && ( - - MCP servers - + <> + + Coder Agents + +
+ Models + + MCP servers + + Templates + Spend + + Instructions + + Lifecycle +
+ )}