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.
This commit is contained in:
Susana Ferreira
2026-08-20 12:55:51 +00:00
committed by GitHub
parent 36bae07a9b
commit d58788cb23
3 changed files with 35 additions and 7 deletions
+2 -2
View File
@@ -213,7 +213,7 @@ https://github.com/coder/coder/blob/release/<VERSION>/coderd/aibridge/prices/dat
Replace `<VERSION>` 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
@@ -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"],
@@ -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<{
<div className="overflow-hidden rounded-lg border border-solid border-border">
<CollapsibleSection
title="Cost estimate"
description="Estimated price per million tokens in USD. Prices are read-only."
description={
<>
Estimated price per million tokens in USD. Prices are read-only.{" "}
Model prices are managed by AI Gateway.{" "}
<Link
href={docs(
"/ai-coder/ai-gateway/cost-controls#configure-model-prices",
)}
size="sm"
>
Learn how to configure model prices.
</Link>
</>
}
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<{
</div>
<div className="flex items-center justify-end gap-3">
<Link to="/ai/settings/models">
<RouterLink to="/ai/settings/models">
<Button variant="outline" type="button">
Cancel
</Button>
</Link>
</RouterLink>
<Button type="submit" disabled={!canSubmit}>
{isSaving && <Spinner loading />}
{isEditing