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

View File

@@ -47,6 +47,28 @@ export function getSmallFastModel(): ModelName {
return process.env.ANTHROPIC_SMALL_FAST_MODEL || getDefaultHaikuModel() 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 { export function isNonCustomOpusModel(model: ModelName): boolean {
return ( return (
model === getModelStrings().opus40 || model === getModelStrings().opus40 ||