mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-04 04:17:38 +00:00
fix(cliproxy): preserve explicit Claude long-context intent
- centralize Anthropic model-key [1m] handling in shared helpers - keep dashboard preset and editor writes consistent across all Claude tiers - add explicit api create and help guidance for --1m/--no-1m Refs #789
This commit is contained in:
@@ -4,6 +4,16 @@
|
||||
|
||||
/** Extended context suffix recognized by Claude Code. */
|
||||
export const EXTENDED_CONTEXT_SUFFIX = '[1m]';
|
||||
export const ANTHROPIC_MODEL_ENV_KEYS = [
|
||||
'ANTHROPIC_MODEL',
|
||||
'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
||||
'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
||||
'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
||||
] as const;
|
||||
|
||||
export type AnthropicModelEnvKey = (typeof ANTHROPIC_MODEL_ENV_KEYS)[number];
|
||||
|
||||
const ANTHROPIC_MODEL_ENV_KEY_SET = new Set<string>(ANTHROPIC_MODEL_ENV_KEYS);
|
||||
|
||||
/** Check if model is a native Gemini model (auto-enabled behavior). */
|
||||
export function isNativeGeminiModel(modelId: string): boolean {
|
||||
@@ -27,3 +37,64 @@ export function stripExtendedContextSuffix(model: string): string {
|
||||
if (!model) return model;
|
||||
return hasExtendedContextSuffix(model) ? model.slice(0, -EXTENDED_CONTEXT_SUFFIX.length) : model;
|
||||
}
|
||||
|
||||
/** True when key belongs to Anthropic model mapping state. */
|
||||
export function isAnthropicModelEnvKey(key: string): key is AnthropicModelEnvKey {
|
||||
return ANTHROPIC_MODEL_ENV_KEY_SET.has(key);
|
||||
}
|
||||
|
||||
/** Strip transient config suffixes so model IDs can be checked against catalogs. */
|
||||
export function stripModelConfigurationSuffixes(modelId: string): string {
|
||||
return stripExtendedContextSuffix(modelId.trim()).replace(/\([^)]+\)$/, '');
|
||||
}
|
||||
|
||||
/** Whether any saved Anthropic model mapping explicitly requests [1m]. */
|
||||
export function hasAnthropicExtendedContextEnabled(
|
||||
env: Partial<Record<string, string | undefined>>
|
||||
): boolean {
|
||||
return ANTHROPIC_MODEL_ENV_KEYS.some((key) => {
|
||||
const value = env[key];
|
||||
return typeof value === 'string' && hasExtendedContextSuffix(value);
|
||||
});
|
||||
}
|
||||
|
||||
/** Apply or strip [1m] across Anthropic model mappings while honoring compatibility. */
|
||||
export function applyExtendedContextPreferenceToAnthropicModels<
|
||||
T extends Record<string, string | undefined>,
|
||||
>(
|
||||
env: T,
|
||||
enabled: boolean,
|
||||
options: {
|
||||
supportsExtendedContext?: (modelId: string, key: AnthropicModelEnvKey) => boolean;
|
||||
} = {}
|
||||
): T {
|
||||
const nextEnv: Record<string, string | undefined> = { ...env };
|
||||
|
||||
for (const key of ANTHROPIC_MODEL_ENV_KEYS) {
|
||||
const value = nextEnv[key];
|
||||
if (typeof value !== 'string' || value.trim().length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const modelId = stripModelConfigurationSuffixes(value);
|
||||
const supported = options.supportsExtendedContext?.(modelId, key) ?? true;
|
||||
nextEnv[key] =
|
||||
enabled && supported ? applyExtendedContextSuffix(value) : stripExtendedContextSuffix(value);
|
||||
}
|
||||
|
||||
return nextEnv as T;
|
||||
}
|
||||
|
||||
/** Detect Claude model identifiers, regardless of transient [1m]/(thinking) suffixes. */
|
||||
export function isClaudeModelId(modelId: string): boolean {
|
||||
return stripModelConfigurationSuffixes(modelId).toLowerCase().startsWith('claude-');
|
||||
}
|
||||
|
||||
/**
|
||||
* Conservative Claude long-context support heuristic for generic API profile flows.
|
||||
* Haiku stays plain; Opus/Sonnet default to opt-in [1m].
|
||||
*/
|
||||
export function likelySupportsClaudeExtendedContext(modelId: string): boolean {
|
||||
const baseModel = stripModelConfigurationSuffixes(modelId).toLowerCase();
|
||||
return baseModel.startsWith('claude-') && !baseModel.startsWith('claude-haiku-');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user