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<{
- + - +