From d58788cb233424a0a999bd2f512b4a060069e886 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Thu, 20 Aug 2026 13:55:51 +0100 Subject: [PATCH] fix: clarify AI model price configuration (#28372) ## Description Model prices displayed in the Agents model form are read-only because they are managed by AI Gateway. Add guidance and a link to the model price configuration documentation, and rename the related documentation subsection to **Configure model prices**. > [!NOTE] > Generated with Coder Agents by @ssncferreira. --- docs/ai-coder/ai-gateway/cost-controls.md | 4 +-- .../components/ModelForm.stories.tsx | 13 ++++++++++ .../ModelsPage/components/ModelFormFields.tsx | 25 +++++++++++++++---- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/docs/ai-coder/ai-gateway/cost-controls.md b/docs/ai-coder/ai-gateway/cost-controls.md index c63c36b92a5..5847531d841 100644 --- a/docs/ai-coder/ai-gateway/cost-controls.md +++ b/docs/ai-coder/ai-gateway/cost-controls.md @@ -213,7 +213,7 @@ https://github.com/coder/coder/blob/release//coderd/aibridge/prices/dat Replace `` with a Coder minor version, for example `2.36`. To use your own price for any of these models, see -[Set model prices](#set-model-prices). +[Configure model prices](#configure-model-prices). > [!IMPORTANT] > Spend is an approximation. It can differ from what the provider bills, and @@ -234,7 +234,7 @@ value means spend is under-counted. Because the price book ships with the release, a newly launched model is unpriced until you upgrade Coder or set a price for it yourself. -### Set model prices +### Configure model prices Use the experimental `coder exp ai-model-prices` command to set model prices for your deployment. It requires AI Governance, which is included with a diff --git a/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx b/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx index d7eeea19fbc..aa8eb6d03a2 100644 --- a/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx +++ b/site/src/pages/AISettingsPage/ModelsPage/components/ModelForm.stories.tsx @@ -466,6 +466,19 @@ export const CostEstimateFieldsAreImmutable: Story = { await userEvent.click( canvas.getByRole("button", { name: /cost estimate/i }), ); + await expect( + canvas.getByText(/model prices are managed by AI Gateway/i), + ).toBeVisible(); + await expect( + canvas.getByRole("link", { + name: /learn how to configure model prices/i, + }), + ).toHaveAttribute( + "href", + expect.stringContaining( + "/ai-coder/ai-gateway/cost-controls#configure-model-prices", + ), + ); const expectedValues: [RegExp, string][] = [ [/^input$/i, "3"], diff --git a/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx b/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx index 4177ff44121..45f99ef2a5d 100644 --- a/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx +++ b/site/src/pages/AISettingsPage/ModelsPage/components/ModelFormFields.tsx @@ -1,7 +1,7 @@ import type { FormikContextType } from "formik"; import { ChevronDownIcon, ChevronRightIcon, InfoIcon } from "lucide-react"; import type { FC, ReactNode } from "react"; -import { Link } from "react-router"; +import { Link as RouterLink } from "react-router"; import { getVisibleProviderFields } from "#/api/chatModelOptions"; import type * as TypesGen from "#/api/typesGenerated"; import { Button } from "#/components/Button/Button"; @@ -18,6 +18,7 @@ import { InputGroupInput, } from "#/components/InputGroup/InputGroup"; import { Label } from "#/components/Label/Label"; +import { Link } from "#/components/Link/Link"; import { Spinner } from "#/components/Spinner/Spinner"; import { Tooltip, @@ -37,12 +38,13 @@ import type { ModelFormValues, } from "#/pages/AgentsPage/components/ChatModelAdminPanel/modelConfigFormLogic"; import { cn } from "#/utils/cn"; +import { docs } from "#/utils/docs"; import type { FormHelpers } from "#/utils/formUtils"; import { ModelFormProviderSelect } from "./ModelFormProviderSelect"; const CollapsibleSection: FC<{ title: string; - description: string; + description: ReactNode; open: boolean; onOpenChange: (open: boolean) => void; className?: string; @@ -246,7 +248,20 @@ export const ModelFormFields: FC<{
+ Estimated price per million tokens in USD. Prices are read-only.{" "} + Model prices are managed by AI Gateway.{" "} + + Learn how to configure model prices. + + + } open={showCostEstimate} onOpenChange={setShowCostEstimate} contentClassName="grid grid-cols-2 gap-3 pt-3 pl-6 sm:grid-cols-4" @@ -342,11 +357,11 @@ export const ModelFormFields: FC<{
- + - +