feat(site): add Opus 4.8 known model (#25839) (#25853)

Cherry-pick of https://github.com/coder/coder/pull/25839

Original PR: #25839 — feat(site): add Opus 4.8 known model
Merge commit: 9448624d2d
Requested by: @ibetitsmike

Co-authored-by: Thomas Kosiewski <tk@coder.com>
This commit is contained in:
github-actions[bot]
2026-05-29 19:59:47 -04:00
committed by GitHub
parent 2d640eaf76
commit 295d2de5d7
4 changed files with 43 additions and 10 deletions
@@ -1374,9 +1374,9 @@ export const AnthropicKnownModelHappyPath: Story = {
await openKnownModelPopover(body);
const options = await body.findAllByRole("option");
await userEvent.click(findOptionByText(options, "claude-opus-4-7"));
await userEvent.click(findOptionByText(options, "claude-opus-4-8"));
await expectModelIdentifierValue(body, "claude-opus-4-7");
await expectModelIdentifierValue(body, "claude-opus-4-8");
await expect(body.getByLabelText(/Context limit/i)).toHaveValue("1000000");
await expandSection(body, "Advanced");
@@ -1858,7 +1858,7 @@ export const KnownModelAutoHidePopoverWhenNoMatches: Story = {
name: /Model Identifier/i,
});
await userEvent.click(input);
await expect(await body.findByText("Claude Opus 4.7")).toBeInTheDocument();
await expect(await body.findByText("Claude Opus 4.8")).toBeInTheDocument();
await userEvent.clear(input);
await userEvent.type(input, "claude-opus-4-5");
@@ -22,6 +22,7 @@ describe("anthropicKnownModels", () => {
(knownModel) => knownModel.modelIdentifier,
),
).toEqual([
"claude-opus-4-8",
"claude-opus-4-7",
"claude-opus-4-6",
"claude-sonnet-4-6",
@@ -31,7 +32,11 @@ describe("anthropicKnownModels", () => {
});
it("declares Anthropic reasoning defaults by API support", () => {
for (const modelIdentifier of ["claude-opus-4-7", "claude-opus-4-6"]) {
for (const modelIdentifier of [
"claude-opus-4-8",
"claude-opus-4-7",
"claude-opus-4-6",
]) {
const knownModel = requireAnthropicKnownModel(modelIdentifier);
expect(knownModel.reasoningEffort).toBe("high");
@@ -54,6 +59,7 @@ describe("anthropicKnownModels", () => {
expect(
anthropicKnownModels.map((knownModel) => knownModel.modelIdentifier),
).toEqual([
"claude-opus-4-8",
"claude-opus-4-7",
"claude-opus-4-6",
"claude-sonnet-4-6",
@@ -64,8 +70,16 @@ describe("anthropicKnownModels", () => {
for (const knownModel of anthropicKnownModels) {
expect(knownModel.provider).toBe("anthropic");
expect(knownModel.sourceMetadata.sourceName).toBe("models.dev");
expect(knownModel.sourceMetadata.sourceRetrievedAt).toBe("2026-04-30");
expect(knownModel.sourceMetadata.sourceRetrievedAt).not.toBe("");
expect(knownModel.sourceMetadata.lastUpdated).not.toBe("");
}
expect(
requireAnthropicKnownModel("claude-opus-4-8").sourceMetadata,
).toEqual({
sourceName: "models.dev",
sourceRetrievedAt: "2026-05-29",
lastUpdated: "2026-05-28",
});
});
});
@@ -10,14 +10,33 @@ import type { KnownModel } from "./types";
// catalog and should be reviewed when the catalog is refreshed.
//
// Reasoning configuration is split per model based on Anthropic API support:
// models that support adaptive thinking (Opus 4.7, Opus 4.6, Sonnet 4.6)
// carry `reasoningEffort`, which Coder maps to `thinking.type: "adaptive"`
// with the `effort` parameter. Models that do not (Haiku 4.5, Sonnet 4.5)
// models that support adaptive thinking (Opus 4.8, Opus 4.7, Opus 4.6,
// Sonnet 4.6) carry `reasoningEffort`, which Coder maps to
// `thinking.type: "adaptive"` with the `effort` parameter. Models that do not
// (Haiku 4.5, Sonnet 4.5)
// carry `thinkingBudgetTokens` instead, which Coder maps to the legacy
// `thinking.type: "enabled"` path with `budget_tokens`. Setting `effort` on
// the legacy path produces an "adaptive thinking is not supported on this
// model" HTTP 400 from Anthropic.
export const anthropicKnownModels = [
{
provider: "anthropic",
modelIdentifier: "claude-opus-4-8",
displayName: "Claude Opus 4.8",
aliases: [],
contextLimit: 1_000_000,
maxOutputTokens: 128_000,
reasoningEffort: "high",
inputCost: 5,
outputCost: 25,
cacheReadCost: 0.5,
cacheWriteCost: 6.25,
sourceMetadata: {
sourceName: "models.dev",
sourceRetrievedAt: "2026-05-29",
lastUpdated: "2026-05-28",
},
},
{
provider: "anthropic",
modelIdentifier: "claude-opus-4-7",
@@ -294,7 +294,7 @@ describe("applyKnownModelDefaults", () => {
values: buildInitialModelFormValues(),
initialValues: buildInitialModelFormValues(),
provider: "anthropic",
knownModel: requireKnownModel("anthropic", "claude-opus-4-7"),
knownModel: requireKnownModel("anthropic", "claude-opus-4-8"),
});
expect(getPath(result.values, "config.anthropic.effort")).toBe("high");
@@ -327,7 +327,7 @@ describe("applyKnownModelDefaults", () => {
values: buildInitialModelFormValues(),
initialValues: buildInitialModelFormValues(),
provider: "anthropic",
knownModel: requireKnownModel("anthropic", "claude-opus-4-7"),
knownModel: requireKnownModel("anthropic", "claude-opus-4-8"),
});
expect(getPath(result.values, "config.anthropic.sendReasoning")).toBe("");