feat: compact 模型降级为 -1 模式(Opus→Sonnet, Sonnet→Haiku)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
claude-code-best
2026-04-14 09:56:22 +08:00
parent ac0ca4a481
commit e458d6391d
2 changed files with 25 additions and 2 deletions

View File

@@ -103,6 +103,7 @@ import {
getMaxOutputTokensForModel,
queryModelWithStreaming,
} from '../api/claude.js'
import { getCompactModel } from '../../utils/model/model.js'
import {
getPromptTooLongTokenGap,
PROMPT_TOO_LONG_ERROR_MESSAGE,
@@ -1314,13 +1315,13 @@ async function streamCompactSummary({
const appState = context.getAppState()
return appState.toolPermissionContext
},
model: context.options.mainLoopModel,
model: getCompactModel(context.options.mainLoopModel),
toolChoice: undefined,
isNonInteractiveSession: context.options.isNonInteractiveSession,
hasAppendSystemPrompt: !!context.options.appendSystemPrompt,
maxOutputTokensOverride: Math.min(
COMPACT_MAX_OUTPUT_TOKENS,
getMaxOutputTokensForModel(context.options.mainLoopModel),
getMaxOutputTokensForModel(getCompactModel(context.options.mainLoopModel)),
),
querySource: 'compact',
agents: context.options.agentDefinitions.activeAgents,

View File

@@ -47,6 +47,28 @@ export function getSmallFastModel(): ModelName {
return process.env.ANTHROPIC_SMALL_FAST_MODEL || getDefaultHaikuModel()
}
/**
* Get the model to use for compaction, one tier below the current model.
* Opus → Sonnet, Sonnet → Haiku, Haiku → Haiku (already lowest).
* Preserves [1m] suffix only if the target family supports it (sonnet/opus).
*/
export function getCompactModel(model: ModelName): ModelName {
const has1m = model.endsWith('[1m]')
const baseModel = has1m ? model.slice(0, -4) : model
const canonical = getCanonicalName(baseModel)
// Opus family → Sonnet
if (canonical.includes('opus')) {
return getDefaultSonnetModel()
}
// Sonnet family → Haiku
if (canonical.includes('sonnet')) {
return getDefaultHaikuModel()
}
// Haiku or unknown → Haiku (lowest tier)
return getDefaultHaikuModel()
}
export function isNonCustomOpusModel(model: ModelName): boolean {
return (
model === getModelStrings().opus40 ||