diff --git a/src/client/consts.ts b/src/client/consts.ts index 0a4ade7..91d40db 100644 --- a/src/client/consts.ts +++ b/src/client/consts.ts @@ -6,7 +6,6 @@ import type { } from './types'; import { EXTERNAL_URLS } from '../consts'; -export const OFFICIAL_DEEPSEEK_API_HOST = 'api.deepseek.com'; export const MAX_DIAGNOSTIC_FIELD_LENGTH = 300; export const API_PROVIDER_HTTP_ERROR_LINKS: Readonly< diff --git a/src/client/error/index.ts b/src/client/error/index.ts index de3f428..ac34bc3 100644 --- a/src/client/error/index.ts +++ b/src/client/error/index.ts @@ -1,10 +1,7 @@ +import { isOfficialDeepSeekBaseUrl } from '../../endpoint'; import { t } from '../../i18n'; import { safeStringify } from '../../json'; -import { - API_PROVIDER_HTTP_ERROR_LINKS, - MAX_DIAGNOSTIC_FIELD_LENGTH, - OFFICIAL_DEEPSEEK_API_HOST, -} from '../consts'; +import { API_PROVIDER_HTTP_ERROR_LINKS, MAX_DIAGNOSTIC_FIELD_LENGTH } from '../consts'; import { getNetworkErrorCauseInfo, getNetworkErrorCode, getNetworkErrorMessage } from './network'; import type { ApiProviderId, @@ -322,12 +319,7 @@ function escapeBoldText(value: string): string { } function identifyApiProvider(baseUrl: string): ApiProviderId | undefined { - try { - const hostname = new URL(baseUrl).hostname.toLowerCase(); - return hostname === OFFICIAL_DEEPSEEK_API_HOST ? 'deepseek' : undefined; - } catch { - return undefined; - } + return isOfficialDeepSeekBaseUrl(baseUrl) ? 'deepseek' : undefined; } function getHttpErrorLinkStatusKey(status: number): HttpErrorLinkStatusKey | undefined { diff --git a/src/endpoint.ts b/src/endpoint.ts new file mode 100644 index 0000000..019ce07 --- /dev/null +++ b/src/endpoint.ts @@ -0,0 +1,13 @@ +export const OFFICIAL_DEEPSEEK_API_HOST = 'api.deepseek.com'; + +export function isOfficialDeepSeekBaseUrl(baseUrl: string): boolean { + try { + return new URL(baseUrl).hostname.toLowerCase() === OFFICIAL_DEEPSEEK_API_HOST; + } catch { + return false; + } +} + +export function normalizeBaseUrl(baseUrl: string): string { + return baseUrl.trim().replace(/\/+$/u, ''); +} diff --git a/src/provider/pricing/currency.ts b/src/provider/pricing/currency.ts index 604f2ef..2211bb9 100644 --- a/src/provider/pricing/currency.ts +++ b/src/provider/pricing/currency.ts @@ -1,7 +1,7 @@ import vscode from 'vscode'; import { AuthManager } from '../../auth'; -import { OFFICIAL_DEEPSEEK_API_HOST } from '../../client/consts'; import { getBaseUrl } from '../../config'; +import { isOfficialDeepSeekBaseUrl, normalizeBaseUrl } from '../../endpoint'; import { logger } from '../../logger'; import type { PricingCurrency } from '../../types'; @@ -133,18 +133,6 @@ export class BalanceCurrencyResolver { } } -export function isOfficialDeepSeekBaseUrl(baseUrl: string): boolean { - try { - return new URL(baseUrl).hostname.toLowerCase() === OFFICIAL_DEEPSEEK_API_HOST; - } catch { - return false; - } -} - -export function normalizeBaseUrl(baseUrl: string): string { - return baseUrl.trim().replace(/\/+$/u, ''); -} - function getLocaleFallbackCurrency(): PricingCurrency { return vscode.env.language.toLowerCase().startsWith('zh') ? 'CNY' : 'USD'; } diff --git a/src/provider/request.ts b/src/provider/request.ts index b9dcf90..c143325 100644 --- a/src/provider/request.ts +++ b/src/provider/request.ts @@ -3,6 +3,7 @@ import { AuthManager } from '../auth'; import { DeepSeekClient } from '../client'; import { getApiModelId, getBaseUrl, getMaxTokens } from '../config'; import { MODELS } from '../consts'; +import { isOfficialDeepSeekBaseUrl } from '../endpoint'; import { t } from '../i18n'; import type { DeepSeekRequest } from '../types'; import { convertMessages, countMessageChars } from './convert'; @@ -60,7 +61,8 @@ export async function prepareChatRequest({ throw new Error(t('auth.notConfigured')); } - const client = new DeepSeekClient(getBaseUrl(), apiKey); + const baseUrl = getBaseUrl(); + const client = new DeepSeekClient(baseUrl, apiKey); const modelDef = MODELS.find((m) => m.id === modelInfo.id); const isThinkingModel = modelDef?.capabilities.thinking ?? false; const maxTokens = getMaxTokens(); @@ -86,7 +88,11 @@ export async function prepareChatRequest({ const configuredThinkingEffort = getConfiguredThinkingEffort( options as ModelConfigurationOptions, ); - const thinkingEffort = shouldForceThinkingNone(requestKind) ? 'none' : configuredThinkingEffort; + // Only force helper requests into disabled thinking on the official API. + // Custom endpoints keep their configured effort to preserve pre-#137 request shape. + const forceNoneThinking = + shouldForceThinkingNone(requestKind) && isOfficialDeepSeekBaseUrl(baseUrl); + const thinkingEffort = forceNoneThinking ? 'none' : configuredThinkingEffort; const request: DeepSeekRequest = { ...baseRequest, ...(isThinkingModel