Skip to content

Commit 8e7a2e7

Browse files
feat: Update Claude Sonnet 4 context window to 1 million tokens (#7005)
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
1 parent bbe3362 commit 8e7a2e7

File tree

24 files changed

+150
-6
lines changed

24 files changed

+150
-6
lines changed

packages/types/src/provider-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const anthropicSchema = apiModelIdProviderModelSchema.extend({
9999
apiKey: z.string().optional(),
100100
anthropicBaseUrl: z.string().optional(),
101101
anthropicUseAuthToken: z.boolean().optional(),
102+
anthropicBeta1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window
102103
})
103104

104105
const claudeCodeSchema = apiModelIdProviderModelSchema.extend({

packages/types/src/providers/anthropic.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,25 @@ export const anthropicDefaultModelId: AnthropicModelId = "claude-sonnet-4-202505
88
export const anthropicModels = {
99
"claude-sonnet-4-20250514": {
1010
maxTokens: 64_000, // Overridden to 8k if `enableReasoningEffort` is false.
11-
contextWindow: 200_000,
11+
contextWindow: 200_000, // Default 200K, extendable to 1M with beta flag 'context-1m-2025-08-07'
1212
supportsImages: true,
1313
supportsComputerUse: true,
1414
supportsPromptCache: true,
15-
inputPrice: 3.0, // $3 per million input tokens
16-
outputPrice: 15.0, // $15 per million output tokens
15+
inputPrice: 3.0, // $3 per million input tokens (≤200K context)
16+
outputPrice: 15.0, // $15 per million output tokens (≤200K context)
1717
cacheWritesPrice: 3.75, // $3.75 per million tokens
1818
cacheReadsPrice: 0.3, // $0.30 per million tokens
1919
supportsReasoningBudget: true,
20+
// Tiered pricing for extended context (requires beta flag 'context-1m-2025-08-07')
21+
tiers: [
22+
{
23+
contextWindow: 1_000_000, // 1M tokens with beta flag
24+
inputPrice: 6.0, // $6 per million input tokens (>200K context)
25+
outputPrice: 22.5, // $22.50 per million output tokens (>200K context)
26+
cacheWritesPrice: 7.5, // $7.50 per million tokens (>200K context)
27+
cacheReadsPrice: 0.6, // $0.60 per million tokens (>200K context)
28+
},
29+
],
2030
},
2131
"claude-opus-4-1-20250805": {
2232
maxTokens: 8192,

src/api/providers/anthropic.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
4545
const cacheControl: CacheControlEphemeral = { type: "ephemeral" }
4646
let { id: modelId, betas = [], maxTokens, temperature, reasoning: thinking } = this.getModel()
4747

48+
// Add 1M context beta flag if enabled for Claude Sonnet 4
49+
if (modelId === "claude-sonnet-4-20250514" && this.options.anthropicBeta1MContext) {
50+
betas.push("context-1m-2025-08-07")
51+
}
52+
4853
switch (modelId) {
4954
case "claude-sonnet-4-20250514":
5055
case "claude-opus-4-1-20250805":
@@ -236,7 +241,23 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
236241
getModel() {
237242
const modelId = this.options.apiModelId
238243
let id = modelId && modelId in anthropicModels ? (modelId as AnthropicModelId) : anthropicDefaultModelId
239-
const info: ModelInfo = anthropicModels[id]
244+
let info: ModelInfo = anthropicModels[id]
245+
246+
// If 1M context beta is enabled for Claude Sonnet 4, update the model info
247+
if (id === "claude-sonnet-4-20250514" && this.options.anthropicBeta1MContext) {
248+
// Use the tier pricing for 1M context
249+
const tier = info.tiers?.[0]
250+
if (tier) {
251+
info = {
252+
...info,
253+
contextWindow: tier.contextWindow,
254+
inputPrice: tier.inputPrice,
255+
outputPrice: tier.outputPrice,
256+
cacheWritesPrice: tier.cacheWritesPrice,
257+
cacheReadsPrice: tier.cacheReadsPrice,
258+
}
259+
}
260+
}
240261

241262
const params = getModelParams({
242263
format: "anthropic",

webview-ui/src/components/settings/ModelInfoView.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ export const ModelInfoView = ({
4141
supportsLabel={t("settings:modelInfo.supportsPromptCache")}
4242
doesNotSupportLabel={t("settings:modelInfo.noPromptCache")}
4343
/>,
44+
typeof modelInfo?.contextWindow === "number" && modelInfo.contextWindow > 0 && (
45+
<>
46+
<span className="font-medium">{t("settings:modelInfo.contextWindow")}</span>{" "}
47+
{modelInfo.contextWindow?.toLocaleString()} tokens
48+
</>
49+
),
4450
typeof modelInfo?.maxTokens === "number" && modelInfo.maxTokens > 0 && (
4551
<>
4652
<span className="font-medium">{t("settings:modelInfo.maxOutput")}:</span>{" "}

webview-ui/src/components/settings/providers/Anthropic.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { ProviderSettings } from "@roo-code/types"
66

77
import { useAppTranslation } from "@src/i18n/TranslationContext"
88
import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink"
9+
import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel"
910

1011
import { inputEventTransform, noTransform } from "../transforms"
1112

@@ -16,9 +17,13 @@ type AnthropicProps = {
1617

1718
export const Anthropic = ({ apiConfiguration, setApiConfigurationField }: AnthropicProps) => {
1819
const { t } = useAppTranslation()
20+
const selectedModel = useSelectedModel(apiConfiguration)
1921

2022
const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl)
2123

24+
// Check if the current model supports 1M context beta
25+
const supports1MContextBeta = selectedModel?.id === "claude-sonnet-4-20250514"
26+
2227
const handleInputChange = useCallback(
2328
<K extends keyof ProviderSettings, E>(
2429
field: K,
@@ -79,6 +84,20 @@ export const Anthropic = ({ apiConfiguration, setApiConfigurationField }: Anthro
7984
</>
8085
)}
8186
</div>
87+
{supports1MContextBeta && (
88+
<div>
89+
<Checkbox
90+
checked={apiConfiguration?.anthropicBeta1MContext ?? false}
91+
onChange={(checked: boolean) => {
92+
setApiConfigurationField("anthropicBeta1MContext", checked)
93+
}}>
94+
{t("settings:providers.anthropic1MContextBetaLabel")}
95+
</Checkbox>
96+
<div className="text-sm text-vscode-descriptionForeground mt-1 ml-6">
97+
{t("settings:providers.anthropic1MContextBetaDescription")}
98+
</div>
99+
</div>
100+
)}
82101
</>
83102
)
84103
}

webview-ui/src/components/ui/hooks/useSelectedModel.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,41 @@ function getSelectedModel({
291291
default: {
292292
provider satisfies "anthropic" | "gemini-cli" | "human-relay" | "fake-ai"
293293
const id = apiConfiguration.apiModelId ?? anthropicDefaultModelId
294-
const info = anthropicModels[id as keyof typeof anthropicModels]
295-
return { id, info }
294+
const baseInfo = anthropicModels[id as keyof typeof anthropicModels]
295+
296+
// Apply 1M context beta tier pricing for Claude Sonnet 4
297+
if (
298+
provider === "anthropic" &&
299+
id === "claude-sonnet-4-20250514" &&
300+
apiConfiguration.anthropicBeta1MContext &&
301+
baseInfo
302+
) {
303+
// Type assertion since we know claude-sonnet-4-20250514 has tiers
304+
const modelWithTiers = baseInfo as typeof baseInfo & {
305+
tiers?: Array<{
306+
contextWindow: number
307+
inputPrice?: number
308+
outputPrice?: number
309+
cacheWritesPrice?: number
310+
cacheReadsPrice?: number
311+
}>
312+
}
313+
const tier = modelWithTiers.tiers?.[0]
314+
if (tier) {
315+
// Create a new ModelInfo object with updated values
316+
const info: ModelInfo = {
317+
...baseInfo,
318+
contextWindow: tier.contextWindow,
319+
inputPrice: tier.inputPrice ?? baseInfo.inputPrice,
320+
outputPrice: tier.outputPrice ?? baseInfo.outputPrice,
321+
cacheWritesPrice: tier.cacheWritesPrice ?? baseInfo.cacheWritesPrice,
322+
cacheReadsPrice: tier.cacheReadsPrice ?? baseInfo.cacheReadsPrice,
323+
}
324+
return { id, info }
325+
}
326+
}
327+
328+
return { id, info: baseInfo }
296329
}
297330
}
298331
}

webview-ui/src/i18n/locales/ca/settings.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/de/settings.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@
258258
"anthropicApiKey": "Anthropic API Key",
259259
"getAnthropicApiKey": "Get Anthropic API Key",
260260
"anthropicUseAuthToken": "Pass Anthropic API Key as Authorization header instead of X-Api-Key",
261+
"anthropic1MContextBetaLabel": "Enable 1M context window (Beta)",
262+
"anthropic1MContextBetaDescription": "Extends context window to 1 million tokens for Claude Sonnet 4",
261263
"cerebrasApiKey": "Cerebras API Key",
262264
"getCerebrasApiKey": "Get Cerebras API Key",
263265
"chutesApiKey": "Chutes API Key",
@@ -726,6 +728,7 @@
726728
"noComputerUse": "Does not support computer use",
727729
"supportsPromptCache": "Supports prompt caching",
728730
"noPromptCache": "Does not support prompt caching",
731+
"contextWindow": "Context Window:",
729732
"maxOutput": "Max output",
730733
"inputPrice": "Input price",
731734
"outputPrice": "Output price",

webview-ui/src/i18n/locales/es/settings.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)