Skip to content

Commit d1a0fc4

Browse files
authored
feat(config): add configurable request headers (#266)
Add `deepseek-copilot.requestHeaders` for custom headers through native VS Code Settings or JSON, with an empty default and case-insensitive merging. Closes #264
1 parent 04bd2fa commit d1a0fc4

13 files changed

Lines changed: 146 additions & 6 deletions

.vscodeignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ tsconfig.json
1414
*.vsix
1515
.vscode-test/
1616
.dev/**
17+
docs/**
1718
dist/**
1819
package-lock.json
1920
.DS_Store

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ All three support optional thinking mode, tool calling, and 1M token context. Fl
104104
| Setting | Default | Description |
105105
|---|---|---|
106106
| `deepseek-copilot.baseUrl` | `https://api.deepseek.com` | API endpoint — change for self-hosted / proxied deployments |
107+
| `deepseek-copilot.requestHeaders` | `{}` | Custom headers for chat completions. [Configuration guide](https://github.com/Vizards/deepseek-v4-for-copilot/blob/main/docs/settings/request-headers.en.md) |
107108
| `deepseek-copilot.maxTokens` | `0` | Max output tokens (`0` = no limit). Useful for cost control |
108109
| `deepseek-copilot.modelIdOverrides` | prefilled official ID map | API model IDs to send for DeepSeek V4 Flash, Pro, and Flash Vision Exp. Change only for compatible third-party APIs with different model names |
109110
| `deepseek-copilot.debugMode` | `minimal` | Diagnostic mode: `minimal` for token usage only, `metadata` for privacy-preserving logs, or `verbose` for full request dumps and pipeline snapshots under extension global storage. Full dumps may include sensitive prompt text, tool schemas, file snippets, and image descriptions. Use `DeepSeek: Open Request Dumps Folder` to open the dump location |

README.zh-cn.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ API Key 存储在 VS Code 的 `SecretStorage` 中(macOS 钥匙串 / Windows
104104
| 设置项 | 默认值 | 说明 |
105105
|---|---|---|
106106
| `deepseek-copilot.baseUrl` | `https://api.deepseek.com` | API 端点——可改为自托管或代理部署地址 |
107+
| `deepseek-copilot.requestHeaders` | `{}` | 聊天补全请求的自定义请求头。[配置说明](https://github.com/Vizards/deepseek-v4-for-copilot/blob/main/docs/settings/request-headers.zh.md) |
107108
| `deepseek-copilot.maxTokens` | `0` | 最大输出 Token 数(`0` = 不限制)。可用于成本控制 |
108109
| `deepseek-copilot.modelIdOverrides` | 预填官方 ID 映射 | DeepSeek V4 Flash、Pro 和 Flash Vision Exp 对应的 API 模型 ID。仅在使用模型名不同的兼容第三方 API 时修改 |
109110
| `deepseek-copilot.debugMode` | `minimal` | 诊断模式:`minimal` 仅上报 token 用量,`metadata` 输出隐私安全日志,`verbose` 将完整请求 dump 和 pipeline snapshot 写入扩展 global storage。完整 dump 可能包含敏感提示词文本、工具定义、文件片段和图片描述。使用 `DeepSeek: 打开请求 Dump 目录` 打开 dump 位置 |
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Request Headers
2+
3+
`deepseek-copilot.requestHeaders` adds or overrides headers for chat completion requests sent to `deepseek-copilot.baseUrl`. Its default value is `{}`.
4+
5+
## Configuration
6+
7+
Add header names and string values in the native VS Code Settings editor, or edit `settings.json`.
8+
9+
Example configuration for [OpenCode Go](https://opencode.ai/docs/go/):
10+
11+
```json
12+
{
13+
"deepseek-copilot.baseUrl": "https://opencode.ai/zen/go/v1",
14+
"deepseek-copilot.requestHeaders": {
15+
"User-Agent": "deepseek-copilot",
16+
"x-opencode-session": "${conversationId}"
17+
}
18+
}
19+
```
20+
21+
- Header names are case-insensitive. Configured values override existing headers, including `Authorization` and `Content-Type`.
22+
- The extension adds no custom `User-Agent` by default; you can set one here if needed.
23+
- Header values are stored in VS Code settings.
24+
25+
## Variables
26+
27+
Use `${name}` anywhere in a header value. Each variable is resolved once per provider call and reused for all occurrences and HTTP attempts. Unknown placeholders are passed through unchanged.
28+
29+
| Variable | Value | Fallback order |
30+
|---|---|---|
31+
| `${conversationId}` | Upstream conversation ID | Workspace ID (`workspace-<workspaceId>`) → Copilot request ID (`request-<requestId>`) → generated UUID (`request-<uuid>`) |
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# 自定义请求头
2+
3+
`deepseek-copilot.requestHeaders` 用于为发送到 `deepseek-copilot.baseUrl` 的聊天补全请求添加或覆盖请求头,默认值为 `{}`
4+
5+
## 配置方式
6+
7+
在 VS Code 原生 Settings 编辑器中添加请求头名称和字符串值,或编辑 `settings.json`
8+
9+
[OpenCode Go](https://opencode.ai/docs/zh-cn/go/) 为例:
10+
11+
```json
12+
{
13+
"deepseek-copilot.baseUrl": "https://opencode.ai/zen/go/v1",
14+
"deepseek-copilot.requestHeaders": {
15+
"User-Agent": "deepseek-copilot",
16+
"x-opencode-session": "${conversationId}"
17+
}
18+
}
19+
```
20+
21+
- 请求头名称不区分大小写,配置值会覆盖已有值,包括 `Authorization``Content-Type`
22+
- 扩展默认不额外添加 `User-Agent`,有需要时可在此配置。
23+
- 请求头的值保存在 VS Code 设置中。
24+
25+
## 变量
26+
27+
可以在请求头值的任意位置使用 `${变量名}`。每个变量在同一次 Provider 调用内只解析一次,所有变量替换和 HTTP 请求尝试均复用该值。未知占位符保持原样。
28+
29+
| 变量 | 取值 | 缺失时的兜底顺序 |
30+
|---|---|---|
31+
| `${conversationId}` | 上游提供的对话 ID | 工作区 ID(`workspace-<workspaceId>`)→ Copilot 请求 ID(`request-<requestId>`)→ 新生成的 UUID(`request-<uuid>`|

package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@
127127
"minimum": 0,
128128
"description": "%deepseek-copilot.config.maxTokens.description%"
129129
},
130+
"deepseek-copilot.requestHeaders": {
131+
"type": "object",
132+
"default": {},
133+
"additionalProperties": {
134+
"type": "string"
135+
},
136+
"markdownDescription": "%deepseek-copilot.config.requestHeaders.description%"
137+
},
130138
"deepseek-copilot.experimental.stabilizeToolList": {
131139
"type": "boolean",
132140
"default": false,

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"deepseek-copilot.walkthrough.advancedSettings.description": "Customize providers and model names, configure the vision proxy, enable experimental settings, and more in the extension settings.\n[Open settings](command:deepseek-copilot.openSettings)",
1717
"deepseek-copilot.config.title": "DeepSeek Copilot",
1818
"deepseek-copilot.config.baseUrl.description": "DeepSeek API base URL. Defaults to official DeepSeek API endpoint.",
19+
"deepseek-copilot.config.requestHeaders.description": "Custom headers for chat completions. [Learn more](https://github.com/Vizards/deepseek-v4-for-copilot/blob/main/docs/settings/request-headers.en.md).",
1920
"deepseek-copilot.config.maxTokens.description": "Maximum number of output tokens per request. Set to 0 to use the API default (no limit). Useful for controlling costs.",
2021
"deepseek-copilot.config.experimental.stabilizeToolList.description": "**Experimental**: improve DeepSeek context-cache hit rate by pre-activating available tools.\n- When the enabled tools list changes across turns, this may improve DeepSeek context-cache hit rate.\n- Requests will include more function definitions, so input tokens may increase. Cache-hit input tokens are billed at a lower price, but still count toward usage.\n- This may add internal preflight tool calls to the current Copilot chat history. If you switch to another model in the same conversation, that model provider may reject or mishandle the replayed history. Start a new chat if model switching behaves unexpectedly.\n\nUse [Configure Tools](command:workbench.action.chat.configureTools) to **view and manage** your tool list:\n\n- 64 or fewer enabled tools: usually no need to enable this unless the tool list still changes across turns.\n- More than 128 enabled tools: not recommended. DeepSeek supports at most 128 functions in one `tools` request. Consider disabling tools you rarely use.",
2122
"deepseek-copilot.config.debugMode.description": "Controls what diagnostic information DeepSeek Copilot writes. Token usage is always reported to Copilot regardless of this setting.\n\n- **Minimal** — Token usage only. No diagnostic logs or request dumps.\n- **Metadata** — Privacy-safe diagnostic metadata (request hashes, prefix overlap, tool schema changes). Does not contain prompt text — safe to share in public issue reports. View with [`DeepSeek: Show Logs`](command:deepseek-copilot.showLogs).\n- **Verbose** — Complete request payloads written to disk for local debugging. **Warning: contains sensitive prompt content.** View with [`DeepSeek: Open Request Dumps Folder`](command:deepseek-copilot.openRequestDumpsFolder).",

package.nls.zh-cn.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"deepseek-copilot.walkthrough.advancedSettings.description": "可以在插件设置中自定义提供方与模型名称、自定义视觉代理、开启实验性设置等。\n[打开设置](command:deepseek-copilot.openSettings)",
1717
"deepseek-copilot.config.title": "DeepSeek 助手",
1818
"deepseek-copilot.config.baseUrl.description": "DeepSeek API 基础 URL,默认为官方 DeepSeek API 端点。",
19+
"deepseek-copilot.config.requestHeaders.description": "聊天补全请求的自定义请求头。[了解更多](https://github.com/Vizards/deepseek-v4-for-copilot/blob/main/docs/settings/request-headers.zh.md)。",
1920
"deepseek-copilot.config.maxTokens.description": "每次请求的最大输出 Token 数,设为 0 则不限制,可用于控制成本。",
2021
"deepseek-copilot.config.experimental.stabilizeToolList.description": "**实验性功能**:通过预先激活可用的工具来提升 DeepSeek 上下文缓存命中率。\n- 当已启用工具列表跨轮次变化时,这可能提高 DeepSeek 上下文缓存命中率;\n- 请求中将包含更多函数工具定义,input tokens 可能增加,虽然缓存命中的 input tokens 单价更低,但仍会计入用量;\n- 此设置可能会在当前 Copilot 对话历史中加入内部预检工具调用。在同一对话中切换到其他模型时,部分模型提供方可能无法正确重放这段历史;如果切换模型后请求异常,请新建对话后重试。\n\n 通过 [配置工具](command:workbench.action.chat.configureTools) **查看和管理**工具列表:\n\n- 64 个或更少已启用工具时通常无需开启,除非工具列表仍在跨轮次变化;\n- 超过 128 个已启用工具时不建议开启:DeepSeek 单次 `tools` 请求最多支持 128 个 functions。考虑禁用部分不常用工具。",
2122
"deepseek-copilot.config.debugMode.description": "控制 DeepSeek Copilot 写入的诊断信息量。无论此设置如何,token 用量始终上报给 Copilot。\n\n- **基本** — 仅上报 token 用量,不输出诊断日志或请求 dump。\n- **元数据** — 隐私安全的诊断元数据(请求哈希、前缀重合度、工具定义变更)。不含提示词原文,可安全附在公开 issue 中反馈问题。使用 [`DeepSeek: 显示日志`](command:deepseek-copilot.showLogs) 查看。\n- **详细** — 将完整请求体写入磁盘,供本地调试。**警告:包含敏感的提示词内容。** 使用 [`DeepSeek: 打开请求 Dump 目录`](command:deepseek-copilot.openRequestDumpsFolder) 浏览。",

src/client/core.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class DeepSeekClient {
1818
constructor(
1919
private readonly baseUrl: string,
2020
private readonly apiKey: string,
21+
private readonly requestHeaders: Readonly<Record<string, string>> = {},
2122
) {}
2223

2324
/**
@@ -44,12 +45,17 @@ export class DeepSeekClient {
4445
stream_options: { include_usage: true },
4546
};
4647

48+
const headers = new Headers({
49+
'Content-Type': 'application/json',
50+
Authorization: `Bearer ${this.apiKey}`,
51+
});
52+
for (const [name, value] of Object.entries(this.requestHeaders)) {
53+
headers.set(name, value);
54+
}
55+
4756
const response = await fetch(`${this.baseUrl}/chat/completions`, {
4857
method: 'POST',
49-
headers: {
50-
'Content-Type': 'application/json',
51-
Authorization: `Bearer ${this.apiKey}`,
52-
},
58+
headers,
5359
body: safeStringify(requestBody),
5460
signal: controller.signal,
5561
});

src/config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ export function getBaseUrl(): string {
1212
return config.get<string>('baseUrl') || 'https://api.deepseek.com';
1313
}
1414

15+
export function getRequestHeaders(): Record<string, string> {
16+
const config = vscode.workspace.getConfiguration(CONFIG_SECTION);
17+
return config.get<Record<string, string>>('requestHeaders', {});
18+
}
19+
1520
/**
1621
* Resolve the API model ID to send to the endpoint.
1722
*

0 commit comments

Comments
 (0)