diff --git a/README.md b/README.md
index c028e26..bfd8ece 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
**Pick DeepSeek V4 from the Copilot Chat model picker — and keep everything else Copilot already gives you.**
-
+
Love DeepSeek's price-performance but don't want to give up GitHub Copilot's agent mode, tool calling, and polished UI? This extension drops **DeepSeek V4 Pro & Flash** straight into the Copilot Chat model selector — with **vision**, **thinking mode**, and your own API key.
@@ -45,7 +45,7 @@ This proxy is a compatibility bridge; if DeepSeek native vision becomes availabl
### Thinking Mode with Reasoning Effort Control
-Full support for DeepSeek V4's `reasoning_content`. Use Copilot Chat's native model picker menu to choose `none` (off), `high` (balanced, default), or `max` (deep reasoning for hard agent tasks).
+Full support for DeepSeek V4's `reasoning_content`. DeepSeek V4 Flash offers `none` (off), `low` (light reasoning), `high` (balanced, default), and `max` (deep reasoning for hard agent tasks). DeepSeek V4 Pro currently offers `none`, `high`, and `max`, matching the effort levels implemented by the official API.
### Inherits Every Copilot Capability
Because this plugs into Copilot's native provider API, you get the full stack for free:
@@ -88,10 +88,10 @@ Install from the registry used by your editor:
## Models
-| Model | Best For |
-|---|---|
-| **DeepSeek V4 Flash** | Fast everyday coding, quick edits, cheap iteration |
-| **DeepSeek V4 Pro** | Complex refactors, agent tasks, deep reasoning |
+| Model | Thinking Effort | Best For |
+|---|---|---|
+| **DeepSeek V4 Flash** | `none` / `low` / `high` / `max` | Fast everyday coding, quick edits, cheap iteration |
+| **DeepSeek V4 Pro** | `none` / `high` / `max` | Complex refactors, agent tasks, deep reasoning |
Both support optional thinking mode, tool calling, and 1M token context.
diff --git a/README.zh-cn.md b/README.zh-cn.md
index cac586a..aad256f 100644
--- a/README.zh-cn.md
+++ b/README.zh-cn.md
@@ -18,7 +18,7 @@
**在 Copilot Chat 模型选择器中直接使用 DeepSeek V4——无需离开你熟悉的 Copilot 工作流。**
-
+
喜欢 DeepSeek 的性价比,但不想放弃 GitHub Copilot 的 Agent 模式、工具调用和成熟的交互体验?本扩展将 **DeepSeek V4 Pro 和 Flash** 直接接入 Copilot Chat 模型选择器,支持**视觉识别**、**思考模式**,使用你自己的 API Key。
@@ -45,7 +45,7 @@ DeepSeek V4 是纯文本模型。将截图拖入聊天,本扩展会自动将
### 思考模式与推理深度控制
-完整支持 DeepSeek V4 的 `reasoning_content`。通过 Copilot Chat 模型选择器的菜单选择 `停用`、`标准`(均衡,默认)或 `深度`(适用于复杂 Agent 任务)。
+完整支持 DeepSeek V4 的 `reasoning_content`。DeepSeek V4 Flash 可选择 `停用`、`轻量`、`标准`(均衡,默认)或 `深度`(适用于复杂 Agent 任务);DeepSeek V4 Pro 目前提供 `停用`、`标准` 和 `深度`,与官方 API 已实现的推理档位保持一致。
### 继承全部 Copilot 能力
由于本扩展接入的是 Copilot 的原生 provider API,你免费获得完整能力栈:
@@ -88,10 +88,10 @@ API Key 存储在 VS Code 的 `SecretStorage` 中(macOS 钥匙串 / Windows
## 模型
-| 模型 | 适用场景 |
-|---|---|
-| **DeepSeek V4 Flash** | 日常快速编码、小改动、低成本迭代 |
-| **DeepSeek V4 Pro** | 复杂重构、Agent 任务、深度推理 |
+| 模型 | 思考深度 | 适用场景 |
+|---|---|---|
+| **DeepSeek V4 Flash** | `停用` / `轻量` / `标准` / `深度` | 日常快速编码、小改动、低成本迭代 |
+| **DeepSeek V4 Pro** | `停用` / `标准` / `深度` | 复杂重构、Agent 任务、深度推理 |
两者均支持可选的思考模式、工具调用和 1M Token 上下文。
diff --git a/src/consts.ts b/src/consts.ts
index b087544..92c9362 100644
--- a/src/consts.ts
+++ b/src/consts.ts
@@ -59,7 +59,11 @@ export const MODELS: ModelDefinition[] = [
capabilities: {
toolCalling: DEEPSEEK_TOOLS_LIMIT,
imageInput: true,
- thinking: true,
+ thinking: {
+ supportedEfforts: ['low', 'high', 'max'],
+ defaultEffort: 'high',
+ canDisable: true,
+ },
},
requiresThinkingParam: true,
pricing: {
@@ -79,7 +83,11 @@ export const MODELS: ModelDefinition[] = [
capabilities: {
toolCalling: DEEPSEEK_TOOLS_LIMIT,
imageInput: true,
- thinking: true,
+ thinking: {
+ supportedEfforts: ['high', 'max'],
+ defaultEffort: 'high',
+ canDisable: true,
+ },
},
requiresThinkingParam: true,
pricing: {
diff --git a/src/i18n.ts b/src/i18n.ts
index 847eac4..d5bb9a6 100644
--- a/src/i18n.ts
+++ b/src/i18n.ts
@@ -37,6 +37,8 @@ const zh: Translations = {
'status.thinking': '思考模式',
'thinking.none': '停用',
'thinking.none.desc': '停用思考,响应更快',
+ 'thinking.low': '轻量',
+ 'thinking.low.desc': '轻量推理,适合快速编辑和简单任务',
'thinking.high': '标准',
'thinking.high.desc': '推荐日常使用',
'thinking.max': '深度',
@@ -227,6 +229,8 @@ const en: Translations = {
'status.thinking': 'Thinking Effort',
'thinking.none': 'None',
'thinking.none.desc': 'Disable thinking for faster responses',
+ 'thinking.low': 'Low',
+ 'thinking.low.desc': 'Light reasoning for quick edits and simple tasks',
'thinking.high': 'High',
'thinking.high.desc': 'Recommended for most tasks',
'thinking.max': 'Max',
diff --git a/src/provider/models.ts b/src/provider/models.ts
index 010e30b..4a9de50 100644
--- a/src/provider/models.ts
+++ b/src/provider/models.ts
@@ -1,6 +1,11 @@
import vscode from 'vscode';
import { t } from '../i18n';
-import type { ModelDefinition, PricingCurrency } from '../types';
+import type {
+ ModelDefinition,
+ PricingCurrency,
+ ReasoningEffort,
+ ThinkingCapability,
+} from '../types';
import { toModelCostInfo, type ModelCostInformation } from './pricing/costs';
/**
@@ -14,7 +19,7 @@ import { toModelCostInfo, type ModelCostInformation } from './pricing/costs';
* metadata and per-model configuration controls.
*/
-export type ThinkingEffort = 'none' | 'high' | 'max';
+export type ThinkingEffort = 'none' | ReasoningEffort;
export type ModelConfigurationOptions = vscode.ProvideLanguageModelChatResponseOptions & {
readonly modelConfiguration?: Record;
@@ -38,6 +43,7 @@ export function toChatInfo(
): ModelPickerChatInformation {
const modelDetail = resolveModelText(m, 'detail') ?? m.detail;
const modelTooltip = resolveModelText(m, 'tooltip');
+ const thinkingCapability = m.capabilities.thinking;
return {
id: m.id,
name: m.name,
@@ -55,45 +61,58 @@ export function toChatInfo(
imageInput: m.capabilities.imageInput,
},
...toModelCostInfo(m, pricingCurrency),
- ...(m.capabilities.thinking ? { configurationSchema: buildThinkingEffortSchema() } : {}),
+ ...(thinkingCapability
+ ? { configurationSchema: buildThinkingEffortSchema(thinkingCapability) }
+ : {}),
};
}
-export function getConfiguredThinkingEffort(options: ModelConfigurationOptions): ThinkingEffort {
+export function getConfiguredThinkingEffort(
+ options: ModelConfigurationOptions,
+ thinkingCapability: ThinkingCapability,
+): ThinkingEffort {
const configuredEffort =
options.modelConfiguration?.reasoningEffort ?? options.configuration?.reasoningEffort;
- if (configuredEffort === 'none') {
+ if (configuredEffort === 'none' && thinkingCapability.canDisable) {
return 'none';
}
- if (configuredEffort === 'high') {
- return 'high';
+ if (isSupportedReasoningEffort(configuredEffort, thinkingCapability)) {
+ return configuredEffort;
}
- return configuredEffort === 'max' ? 'max' : 'high';
+ return thinkingCapability.defaultEffort;
}
-function buildThinkingEffortSchema() {
+function buildThinkingEffortSchema(thinkingCapability: ThinkingCapability) {
+ const efforts: ThinkingEffort[] = [
+ ...(thinkingCapability.canDisable ? (['none'] as const) : []),
+ ...thinkingCapability.supportedEfforts,
+ ];
+
return {
properties: {
reasoningEffort: {
type: 'string',
title: t('status.thinking'),
- enum: ['none', 'high', 'max'],
- enumItemLabels: [t('thinking.none'), t('thinking.high'), t('thinking.max')],
- enumDescriptions: [
- t('thinking.none.desc'),
- t('thinking.high.desc'),
- t('thinking.max.desc'),
- ],
- default: 'high',
+ enum: efforts,
+ enumItemLabels: efforts.map((effort) => t(`thinking.${effort}`)),
+ enumDescriptions: efforts.map((effort) => t(`thinking.${effort}.desc`)),
+ default: thinkingCapability.defaultEffort,
group: 'navigation',
},
},
} as const;
}
+function isSupportedReasoningEffort(
+ value: unknown,
+ thinkingCapability: ThinkingCapability,
+): value is ReasoningEffort {
+ return thinkingCapability.supportedEfforts.some((effort) => effort === value);
+}
+
function resolveModelText(m: ModelDefinition, field: 'detail' | 'tooltip'): string | undefined {
const suffix = m.id.startsWith('deepseek-v4-') ? m.id.slice('deepseek-v4-'.length) : m.id;
const key = `model.${suffix}.${field}`;
diff --git a/src/provider/request.ts b/src/provider/request.ts
index c143325..0ee62a8 100644
--- a/src/provider/request.ts
+++ b/src/provider/request.ts
@@ -64,7 +64,8 @@ export async function prepareChatRequest({
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 thinkingCapability = modelDef?.capabilities.thinking;
+ const isThinkingModel = Boolean(thinkingCapability);
const maxTokens = getMaxTokens();
const visionResolution = await resolveImageMessages(messages, token, getVisionDescriber);
@@ -85,9 +86,9 @@ export async function prepareChatRequest({
request: baseRequest,
inputMessages: messages,
});
- const configuredThinkingEffort = getConfiguredThinkingEffort(
- options as ModelConfigurationOptions,
- );
+ const configuredThinkingEffort = thinkingCapability
+ ? getConfiguredThinkingEffort(options as ModelConfigurationOptions, thinkingCapability)
+ : 'none';
// 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 =
diff --git a/src/types.ts b/src/types.ts
index f9e9689..92e19cf 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -4,6 +4,9 @@
// ---- API request/response types ----
+/** API-level reasoning efforts. Disabling thinking is modeled separately. */
+export type ReasoningEffort = 'low' | 'high' | 'max';
+
export interface DeepSeekMessage {
role: 'system' | 'user' | 'assistant' | 'tool';
content: string;
@@ -48,7 +51,7 @@ export interface DeepSeekRequest {
tools?: DeepSeekTool[];
tool_choice?: 'none' | 'auto' | 'required';
thinking?: { type: 'enabled' | 'disabled' };
- reasoning_effort?: 'high' | 'max';
+ reasoning_effort?: ReasoningEffort;
stream_options?: {
include_usage: boolean;
};
@@ -103,6 +106,13 @@ export interface ModelPricing {
output: number;
}
+export interface ThinkingCapability {
+ /** Effort values this model implements and may receive in API requests. */
+ supportedEfforts: readonly ReasoningEffort[];
+ defaultEffort: ReasoningEffort;
+ canDisable: boolean;
+}
+
export interface ModelDefinition {
id: string;
name: string;
@@ -114,7 +124,7 @@ export interface ModelDefinition {
capabilities: {
toolCalling: boolean | number;
imageInput: boolean;
- thinking: boolean;
+ thinking: ThinkingCapability | false;
};
requiresThinkingParam: boolean;
pricing?: Readonly>;