mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 14:25:51 +00:00
feat: 添加 model/provider 层改进
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,18 +28,6 @@ import { getAPIProvider } from './providers.js'
|
||||
import { LIGHTNING_BOLT } from '../../constants/figures.js'
|
||||
import { isModelAllowed } from './modelAllowlist.js'
|
||||
import { type ModelAlias, isModelAlias } from './aliases.js'
|
||||
|
||||
/**
|
||||
* Returns true if the value is a model alias or a model alias with a suffix
|
||||
* like [1m] (e.g. "opus", "opus[1m]", "sonnet", "haiku[1m]").
|
||||
* Used to guard against infinite recursion when getDefault*Model() falls back
|
||||
* to the user-specified setting — an alias like "opus[1m]" would cause
|
||||
* parseUserSpecifiedModel → getDefaultOpusModel → parseUserSpecifiedModel loop.
|
||||
*/
|
||||
function isAliasOrAliasWithSuffix(value: string): boolean {
|
||||
const base = value.replace(/\[1m\]$/i, '').trim()
|
||||
return isModelAlias(base)
|
||||
}
|
||||
import { capitalize } from '../stringUtils.js'
|
||||
|
||||
export type ModelShortName = string
|
||||
@@ -64,7 +52,8 @@ export function isNonCustomOpusModel(model: ModelName): boolean {
|
||||
model === getModelStrings().opus40 ||
|
||||
model === getModelStrings().opus41 ||
|
||||
model === getModelStrings().opus45 ||
|
||||
model === getModelStrings().opus46
|
||||
model === getModelStrings().opus46 ||
|
||||
model === getModelStrings().opus47
|
||||
)
|
||||
}
|
||||
|
||||
@@ -138,21 +127,14 @@ export function getDefaultOpusModel(): ModelName {
|
||||
if (process.env.ANTHROPIC_DEFAULT_OPUS_MODEL) {
|
||||
return process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
||||
}
|
||||
// Fall back to user's configured model — custom providers may not
|
||||
// recognize hardcoded Anthropic model IDs.
|
||||
// Skip if the user setting is a model alias (e.g. "opus", "opus[1m]") to
|
||||
// avoid infinite recursion: parseUserSpecifiedModel(alias) → getDefaultOpusModel().
|
||||
const userSpecifiedOpus = getUserSpecifiedModelSetting()
|
||||
if (userSpecifiedOpus && !isAliasOrAliasWithSuffix(userSpecifiedOpus)) {
|
||||
return parseUserSpecifiedModel(userSpecifiedOpus)
|
||||
}
|
||||
// 3P providers (Bedrock, Vertex, Foundry) — kept as a separate branch
|
||||
// even when values match, since 3P availability lags firstParty and
|
||||
// these will diverge again at the next model launch.
|
||||
// 3P providers (Bedrock, Vertex, Foundry) all publish Opus 4.7 in sync
|
||||
// with firstParty as of 2026-04-17 (AWS Bedrock, Google Vertex AI, and
|
||||
// Microsoft Foundry announcements and model catalogs all confirm). The
|
||||
// branch is kept as a structural hook in case a future launch lags on 3P.
|
||||
if (provider !== 'firstParty') {
|
||||
return getModelStrings().opus46
|
||||
return getModelStrings().opus47
|
||||
}
|
||||
return getModelStrings().opus46
|
||||
return getModelStrings().opus47
|
||||
}
|
||||
|
||||
// @[MODEL LAUNCH]: Update the default Sonnet model (3P providers may lag so keep defaults unchanged).
|
||||
@@ -173,14 +155,6 @@ export function getDefaultSonnetModel(): ModelName {
|
||||
if (process.env.ANTHROPIC_DEFAULT_SONNET_MODEL) {
|
||||
return process.env.ANTHROPIC_DEFAULT_SONNET_MODEL
|
||||
}
|
||||
// Fall back to user's configured model (ANTHROPIC_MODEL / settings) —
|
||||
// custom providers (proxies, national clouds) may not recognize the
|
||||
// hardcoded Anthropic model IDs.
|
||||
// Skip if the user setting is a model alias to avoid infinite recursion.
|
||||
const userSpecified = getUserSpecifiedModelSetting()
|
||||
if (userSpecified && !isAliasOrAliasWithSuffix(userSpecified)) {
|
||||
return parseUserSpecifiedModel(userSpecified)
|
||||
}
|
||||
// Default to Sonnet 4.5 for 3P since they may not have 4.6 yet
|
||||
if (provider !== 'firstParty') {
|
||||
return getModelStrings().sonnet45
|
||||
@@ -203,13 +177,6 @@ export function getDefaultHaikuModel(): ModelName {
|
||||
if (process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL) {
|
||||
return process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL
|
||||
}
|
||||
// Fall back to user's configured model — custom providers may not
|
||||
// recognize hardcoded Anthropic model IDs.
|
||||
// Skip if the user setting is a model alias to avoid infinite recursion.
|
||||
const userSpecifiedHaiku = getUserSpecifiedModelSetting()
|
||||
if (userSpecifiedHaiku && !isAliasOrAliasWithSuffix(userSpecifiedHaiku)) {
|
||||
return parseUserSpecifiedModel(userSpecifiedHaiku)
|
||||
}
|
||||
|
||||
// Haiku 4.5 is available on all platforms (first-party, Foundry, Bedrock, Vertex)
|
||||
return getModelStrings().haiku45
|
||||
@@ -296,6 +263,9 @@ export function firstPartyNameToCanonical(name: ModelName): ModelShortName {
|
||||
name = name.toLowerCase()
|
||||
// Special cases for Claude 4+ models to differentiate versions
|
||||
// Order matters: check more specific versions first (4-5 before 4)
|
||||
if (name.includes('claude-opus-4-7')) {
|
||||
return 'claude-opus-4-7'
|
||||
}
|
||||
if (name.includes('claude-opus-4-6')) {
|
||||
return 'claude-opus-4-6'
|
||||
}
|
||||
@@ -366,9 +336,9 @@ export function getClaudeAiUserDefaultModelDescription(
|
||||
): string {
|
||||
if (isMaxSubscriber() || isTeamPremiumSubscriber()) {
|
||||
if (isOpus1mMergeEnabled()) {
|
||||
return `Opus 4.6 with 1M context · Most capable for complex work${fastMode ? getOpus46PricingSuffix(true) : ''}`
|
||||
return `Opus 4.7 with 1M context · Most capable for complex work${fastMode ? getOpusPricingSuffix(true) : ''}`
|
||||
}
|
||||
return `Opus 4.6 · Most capable for complex work${fastMode ? getOpus46PricingSuffix(true) : ''}`
|
||||
return `Opus 4.7 · Most capable for complex work${fastMode ? getOpusPricingSuffix(true) : ''}`
|
||||
}
|
||||
return 'Sonnet 4.6 · Best for everyday tasks'
|
||||
}
|
||||
@@ -377,12 +347,12 @@ export function renderDefaultModelSetting(
|
||||
setting: ModelName | ModelAlias,
|
||||
): string {
|
||||
if (setting === 'opusplan') {
|
||||
return 'Opus 4.6 in plan mode, else Sonnet 4.6'
|
||||
return 'Opus 4.7 in plan mode, else Sonnet 4.6'
|
||||
}
|
||||
return renderModelName(parseUserSpecifiedModel(setting))
|
||||
}
|
||||
|
||||
export function getOpus46PricingSuffix(fastMode: boolean): string {
|
||||
export function getOpusPricingSuffix(fastMode: boolean): string {
|
||||
if (getAPIProvider() !== 'firstParty') return ''
|
||||
const pricing = formatModelPricing(getOpus46CostTier(fastMode))
|
||||
const fastModeIndicator = fastMode ? ` (${LIGHTNING_BOLT})` : ''
|
||||
@@ -426,6 +396,10 @@ export function renderModelSetting(setting: ModelName | ModelAlias): string {
|
||||
*/
|
||||
export function getPublicModelDisplayName(model: ModelName): string | null {
|
||||
switch (model) {
|
||||
case getModelStrings().opus47:
|
||||
return 'Opus 4.7'
|
||||
case getModelStrings().opus47 + '[1m]':
|
||||
return 'Opus 4.7 (1M context)'
|
||||
case getModelStrings().opus46:
|
||||
return 'Opus 4.6'
|
||||
case getModelStrings().opus46 + '[1m]':
|
||||
@@ -549,9 +523,10 @@ export function parseUserSpecifiedModel(
|
||||
|
||||
// Opus 4/4.1 are no longer available on the first-party API (same as
|
||||
// Claude.ai) — silently remap to the current Opus default. The 'opus'
|
||||
// alias already resolves to 4.6, so the only users on these explicit
|
||||
// strings pinned them in settings/env/--model/SDK before 4.5 launched.
|
||||
// 3P providers may not yet have 4.6 capacity, so pass through unchanged.
|
||||
// alias resolves to the current default Opus (4.7), so the only users
|
||||
// on these explicit strings pinned them in settings/env/--model/SDK
|
||||
// before 4.5 launched. 3P providers may not yet have 4.6/4.7 capacity,
|
||||
// so pass through unchanged.
|
||||
if (
|
||||
getAPIProvider() === 'firstParty' &&
|
||||
isLegacyOpusFirstParty(modelString) &&
|
||||
@@ -654,6 +629,9 @@ export function getMarketingNameForModel(modelId: string): string | undefined {
|
||||
const has1m = modelId.toLowerCase().includes('[1m]')
|
||||
const canonical = getCanonicalName(modelId)
|
||||
|
||||
if (canonical.includes('claude-opus-4-7')) {
|
||||
return has1m ? 'Opus 4.7 (with 1M context)' : 'Opus 4.7'
|
||||
}
|
||||
if (canonical.includes('claude-opus-4-6')) {
|
||||
return has1m ? 'Opus 4.6 (with 1M context)' : 'Opus 4.6'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user