From 192ed4bdce513d7f5a9c791b48d1241453e12c4d Mon Sep 17 00:00:00 2001 From: zhb <50901800+zhbdesign@users.noreply.github.com> Date: Tue, 23 Jun 2026 19:27:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AC=AC=E4=B8=89=E6=96=B9AP?= =?UTF-8?q?I=E5=9C=A8=E5=93=8D=E5=BA=94=E4=B8=AD=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84model=E4=B8=8E=E8=AF=B7=E6=B1=82=E7=9A=84modelid?= =?UTF-8?q?=E4=B8=8D=E4=B8=80=E8=87=B4=E5=AF=BC=E8=87=B4=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E6=98=BE=E7=A4=BA200000?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复第三方API在响应中返回的model与请求的modelid不一致导致上下文显示200000 --- src/server/services/sessionService.ts | 66 ++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/server/services/sessionService.ts b/src/server/services/sessionService.ts index 303eb101..31b87b1f 100644 --- a/src/server/services/sessionService.ts +++ b/src/server/services/sessionService.ts @@ -1376,8 +1376,21 @@ export class SessionService { if (activeId) providerIds.push(activeId) } + // Provider env model keys — these are the configured model names that + // should be used as fallback matching keys when the transcript model name + // (from the API response) doesn't match the modelContextWindows keys. + // Third-party APIs may return model names with provider-specific suffixes + // (e.g. "LongCat-2.0-Preview-LongCatAI" instead of "LongCat-2.0-Preview"). + const providerEnvModelKeys = [ + 'ANTHROPIC_MODEL', + 'ANTHROPIC_DEFAULT_HAIKU_MODEL', + 'ANTHROPIC_DEFAULT_SONNET_MODEL', + 'ANTHROPIC_DEFAULT_OPUS_MODEL', + ] as const + for (const providerId of providerIds) { const env = await this.providerService.getProviderRuntimeEnv(providerId).catch(() => null) + // Step 1: Try matching the transcript model name directly (current behavior) const contextWindow = getModelContextWindowFromEnvValue( model, env?.[MODEL_CONTEXT_WINDOWS_ENV_KEY], @@ -1387,6 +1400,27 @@ export class SessionService { return MODEL_CONTEXT_WINDOW_DEFAULT } return contextWindow + } + // Step 2: If transcript model name didn't match, try matching with + // the provider's configured model names as fallback keys. + // This handles the case where the API response returns a model name + // that differs from the user-configured model name (e.g. provider + // appends its own suffix like "-LongCatAI"). + if (env && rawContextWindows) { + for (const envKey of providerEnvModelKeys) { + const configuredModel = env[envKey] + if (!configuredModel) continue + const fallbackWindow = getModelContextWindowFromEnvValue( + configuredModel, + rawContextWindows, + ) + if (fallbackWindow !== undefined) { + if (fallbackWindow > MODEL_CONTEXT_WINDOW_DEFAULT && is1mContextDisabled()) { + return MODEL_CONTEXT_WINDOW_DEFAULT + } + return fallbackWindow + } + } } } @@ -1400,15 +1434,45 @@ export class SessionService { private async getUniqueSavedProviderContextWindow(model: string): Promise { const { providers } = await this.providerService.listProviders().catch(() => ({ providers: [] })) const matches: number[] = [] + const providerEnvModelKeys = [ + 'ANTHROPIC_MODEL', + 'ANTHROPIC_DEFAULT_HAIKU_MODEL', + 'ANTHROPIC_DEFAULT_SONNET_MODEL', + 'ANTHROPIC_DEFAULT_OPUS_MODEL', + ] as const for (const provider of providers) { const env = await this.providerService.getProviderRuntimeEnv(provider.id).catch(() => null) - const contextWindow = getModelContextWindowFromEnvValue( + // Step 1: Try matching the transcript model name directly + const contextWindow = getModelContextWindowFromEnvValue( model, env?.[MODEL_CONTEXT_WINDOWS_ENV_KEY], ) if (contextWindow !== undefined) { matches.push(contextWindow) + continue + } + + // Step 2: Fallback — try matching with provider's configured model names + if (env && rawContextWindows) { + for (const envKey of providerEnvModelKeys) { + const configuredModel = env[envKey] + if (!configuredModel) continue + const fallbackWindow = getModelContextWindowFromEnvValue( + configuredModel, + rawContextWindows, + ) + if (fallbackWindow !== undefined) { + traceDebug('CTX_WIN', 'getUniqueSavedProviderContextWindow — fallback match via configured model', { + transcriptModel: model, + configuredModel, + envKey, + fallbackWindow, + }) + matches.push(fallbackWindow) + break // One match per provider is enough + } + } } }