Skip to content

Commit ecd9d12

Browse files
committed
chore: 升级版本至 0.7.9 并更新变更日志
- 将 `package.json` 版本号改为 0.7.9 - 更新状态栏文本常量,去除旧命令绑定 - 调整相关测试以匹配新实现
1 parent d9db9bc commit ecd9d12

10 files changed

Lines changed: 319 additions & 273 deletions

CHANGELOG.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.7.2] - 2026-04-16
6+
- feat(commitMessageGenerator): 增强风格参考约束与回退格式优先级
7+
58
## [0.7.1] - 2026-04-16
69
- chore: 升级版本至 0.7.1
710

@@ -44,12 +47,4 @@ All notable changes to this project will be documented in this file.
4447

4548
## [0.6.4] - 2026-03-22
4649
- fix(docs): 更新上下文窗口文档与状态栏显示逻辑
47-
- feat: 支持 contextSize 配置并优化上下文窗口处理
48-
49-
## [0.6.2] - 2026-03-19
50-
- fix(provider-pricing): 更新供应商定价数据及资源链接
51-
- fix(#8): 更新 OpenRouter 指标采集流程
52-
- build(workflow): 更新 OpenRouter 指标与套餐抓取流程
53-
- feat(ci): 调整 OpenRouter 模型数据最大缓存天数
54-
- fix(provider-pricing): 更新模型定价数据和爬虫逻辑
55-
- fix(docs): 更新废弃字段 maxInputTokens 和 maxOutputTokens 的描述信息
50+
- feat: 支持 contextSize 配置并优化上下文窗口处理
Lines changed: 62 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,94 @@
1-
# VS Code Copilot Chat Context Window 使用说明
1+
# VS Code Chat Context Window 的值是怎么来的
22

3-
更新时间:2026-03-19
3+
更新时间:2026-04-22
44

55
## 一句话结论
66

7-
`Context Window` 不是一个让你手动编辑“当前上下文内容”的面板,而是一个“当前这轮对话已经塞进了多少上下文”的使用量指示器。真正决定上下文内容的入口,是聊天里的隐式上下文、`#` 引用、`@` 参与者、自定义指令、prompt files、图片、浏览器元素和对话历史。
7+
`Context Window X / Y tokens` 表示:
88

9-
## Context Window 里通常有什么
9+
| 部分 | 含义 | 来源 |
10+
| --- | --- | --- |
11+
| `Y` | 当前所选模型的总上下文窗口 | 由 VS Code 根据所选模型的上下文能力决定 |
12+
| `X` | 当前这轮对话已经占用的上下文 token | 由 VS Code / Copilot 在运行时把当前请求上下文拼装并计数后得到 |
1013

11-
根据 VS Code 官方文档,Copilot Chat 会把下面几类信息拼进当前请求:
14+
这个控件本质上是“上下文占用统计”,不是“完整 prompt 明细列表”。
1215

13-
- 隐式上下文:当前选中的代码、当前文件名;在部分模式下还会自动考虑活动文件。
14-
- 显式上下文:通过 `#` 主动附加的文件、文件夹、符号、`#codebase`、终端输出、网页内容等。
15-
- 参与者与工具:通过 `@` 选择的 chat participant,以及该参与者可用的工具定义。
16-
- 自定义指令:`.github/copilot-instructions.md``*.instructions.md``AGENTS.md`、用户级或组织级 instructions。
17-
- Prompt files:`*.prompt.md`,通常通过 `/你的命令名` 运行。
18-
- 多模态上下文:图片、浏览器元素、集成浏览器页面。
19-
- 会话历史:当前聊天的历史消息,以及历史过长后压缩出来的摘要。
20-
- 输出预留:为了避免本轮回答超限,系统会预留一部分 token 给模型输出。
16+
## `Y` 是怎么得到的
2117

22-
你在悬浮 `Context Window X / Y tokens` 时看到的分类拆分,本质上就是这些来源的占用统计
18+
官方文档只明确说明一件事:`Context Window` 的分母会随着你切换模型而变化,因为不同模型的 context window 不同
2319

24-
## 这东西应该怎么用
20+
对自定义模型提供方,VS Code 公开给扩展的模型容量元数据是:
2521

26-
### 1. 把它当成“上下文预算表”,不是“内容编辑器”
22+
| API 字段 | 含义 |
23+
| --- | --- |
24+
| `maxInputTokens` | 模型最多可接受多少输入 token |
25+
| `maxOutputTokens` | 模型最多可生成多少输出 token |
2726

28-
看见占用上涨,说明你当前这次对话携带的信息在变多。它适合回答两个问题
27+
本仓库里,这两个值的来源链路是
2928

30-
- 现在这轮对话是否已经装了太多无关历史?
31-
- 我还要不要继续往里塞文件、图片、网页,还是应该先压缩/开新会话?
29+
| 步骤 | 本仓库实现 |
30+
| --- | --- |
31+
| 1. 读取模型配置 | `AIModelConfig.maxTokens` 表示模型总上下文窗口,`maxInputTokens` / `maxOutputTokens` 是拆分值,见 [src/providers/baseProvider.ts](../src/providers/baseProvider.ts) |
32+
| 2. 生成对外模型信息 | `toLanguageModelInfo(...)``model.maxInputTokens``model.maxOutputTokens` 暴露给 VS Code,见 [src/providers/lmChatProviderAdapter.ts](../src/providers/lmChatProviderAdapter.ts) |
33+
| 3. VS Code 显示分母 | VS Code 根据当前选中的模型信息显示 `Y` |
3234

33-
不适合的用法是:盯着这个面板猜“为什么模型一定看到了某一段代码”。因为它显示的是预算和分类,不是完整逐项清单
35+
所以,对这个仓库来说,`Y` 最终来自模型配置,再通过扩展注册的 `LanguageModelChatInformation` 传给 VS Code
3436

35-
### 2. 优先用 `#` 精确喂上下文
37+
## `X` 是怎么得到的
3638

37-
如果问题和代码直接相关,优先用精确上下文,而不是一句笼统自然语言让 Agent 自己猜
39+
官方文档说明,`X` 表示“当前已使用的上下文”,会随着对话推进不断增长;hover 时还能看到按类别拆分的占用。官方还能确认这些上下文来源会参与统计
3840

39-
- 单文件问题:直接选中代码,再补一个 `#对应文件`
40-
- 多文件链路问题:`#入口文件 #调用方文件 #相关配置文件`
41-
- 仓库级问题:明确写 `#codebase`
42-
- 终端报错:附加终端输出
43-
- 最新外部文档:直接贴 URL,或者加 `#fetch`
41+
| 来源 | 官方说明 |
42+
| --- | --- |
43+
| 系统与指令层 | system prompt、custom instructions 也属于 context window 的一部分 |
44+
| 隐式上下文 | 活动文件、当前选区、文件名会自动带入 |
45+
| 显式上下文 | `#file``#codebase``#terminalSelection``#fetch`|
46+
| 工作区检索结果 | Copilot 会自动做 workspace indexing、search、read、usages 等检索,再把结果带入 |
47+
| 工具结果 | tool outputs、previous tool results 会进入上下文 |
48+
| 会话历史 | conversation history 会进入上下文 |
49+
| 多模态上下文 | 图片、浏览器元素、页面内容等 |
50+
| 历史压缩结果 | 上下文快满时,VS Code 会自动 compact 旧历史,摘要仍继续占用上下文 |
4451

45-
官方文档还特别提到:附加文件时,能放下就传完整文件;放不下时会退化成文件大纲;大纲还放不下时,这个文件可能根本不会进 prompt。也就是说,“提到了文件名”不等于“完整源码一定进了上下文”。
52+
所以,`X` 不是“当前输入框文本长度”,而是“这次请求最终真正送进模型的上下文总量”。
4653

47-
### 3. 用 `@` 决定“谁来回答”,不要把它和 `#` 混在一起理解
54+
## 这仓库能确认到哪一步
4855

49-
- `#` 是给模型补材料
50-
- `@` 是指定由哪个 participant 处理问题
56+
这点最重要:
5157

52-
例如:
58+
本仓库不会把“当前这轮响应结束后”拿到的真实 `usage` 实时精确写回 VS Code 原生 `Context Window`
5359

54-
- `@vscode 如何开启自动保存`
55-
- `@terminal 当前目录最大的 5 个文件是什么`
60+
并且按 2026-04-22 这次对当前 VS Code 源码链路与本扩展运行日志的核对结果,第三方 `LanguageModelChatProvider.provideTokenCount(...)` 也不会驱动原生 `Context Window` 弹层里的 `X`
5661

57-
如果你问的是仓库代码本身,重点还是先把代码上下文喂准,而不是只切 participant。
62+
能确认的实现如下:
5863

59-
### 4. 稳定规则放 instructions,重复流程放 prompt files
64+
| 位置 | 结论 |
65+
| --- | --- |
66+
| [src/providers/lmChatProviderAdapter.ts](../src/providers/lmChatProviderAdapter.ts) | `provideTokenCount(...)` 不做本地 prompt token 估算;若存在“同模型最近一次已完成请求”的 usage 快照,则返回最近一次 occupied context,否则返回 `0` |
67+
| [src/providers/lmChatProviderAdapter.ts](../src/providers/lmChatProviderAdapter.ts) | `reportUsageToProgress(...)` 会读取响应里的 usage |
68+
| [src/providers/lmChatProviderAdapter.ts](../src/providers/lmChatProviderAdapter.ts) | `updateContextUsageState(...)` 会把 usage 缓存到本仓库自己的 `CodingPlans Context` 状态栏状态里 |
69+
| VS Code 源码 `src/vs/workbench/api/browser/mainThreadLanguageModels.ts` / `src/vs/workbench/api/common/extHostLanguageModels.ts` | `provideTokenCount(...)` 只被桥接到 `computeTokenLength(...)` / `countTokens(...)` 能力;本次未找到原生 `Context Window` UI 消费这条路径的源码 |
6070

61-
如果某些约束每次都要生效,不要每轮聊天重复粘贴,应该落到文件
71+
因此可以明确下结论
6272

63-
- 项目级统一规则:`.github/copilot-instructions.md`
64-
- 目录或语言特定规则:`*.instructions.md`
65-
- 多代理共享规则:`AGENTS.md`
66-
- 可复用工作流:`*.prompt.md`
73+
1. VS Code 原生 `Context Window``X`,不是本仓库把上游 `usage.totalTokens` 原样回填出来的值。
74+
2. 本仓库公开参与原生控件的能力,只有模型元数据和 `provideTokenCount()` 这个估算接口。
75+
3. 现在这里的 `provideTokenCount()` 虽然会优先返回“同模型最近一次已完成请求”的 occupied context,但按当前源码和运行结果,这不会驱动原生 `Context Window` 弹层里的 `X`
76+
4. 因此,原生 `Context Window` 里的 `X` 目前仍应视为 VS Code / Copilot 自己的内部上下文拼装统计结果;对第三方 provider,这个值可能保持 `0`
6777

68-
官方建议也很明确:
78+
## 最终结论
6979

70-
- 全项目共用规范,优先放 `.github/copilot-instructions.md`
71-
- 多代理场景,使用 `AGENTS.md`
72-
- 某类任务反复出现,做成 prompt file,用 `/命令名` 触发
80+
如果你只关心“vscode chat 的 context 窗口中的值是如何得到的”,可以直接记这一句:
7381

74-
这几类文件会直接影响 Copilot Chat 的上下文组成,所以它们比“手动在聊天里反复解释一遍”更稳定。
82+
`Y` 来自当前模型的上下文能力;`X` 来自 VS Code / Copilot 把当前请求要发送的上下文拼起来后做的运行时统计。
83+
在本仓库里,模型容量由扩展提供给 VS Code;但对第三方 provider,当前并不能依靠 `provideTokenCount()` 或上游 `usage` 去驱动原生 `Context Window``X`
7584

76-
### 5. UI / 页面问题,不要只发文字
85+
## 参考
7786

78-
如果问题和前端界面有关,优先附加:
79-
80-
- 截图
81-
- 浏览器元素
82-
- 集成浏览器页面
83-
84-
官方文档支持把集成浏览器里的元素直接加进 Chat,上下文里可以包含 HTML、CSS,必要时还能带图片。对布局问题、样式问题、交互问题,这比“描述页面长什么样”有效得多。
85-
86-
### 6. 当上下文快满时,主动压缩或开新会话
87-
88-
官方文档说明,Context Window 快满时 VS Code 会自动做 compaction,也就是把更早的对话压缩成摘要。
89-
90-
你的可操作手段有两个:
91-
92-
- 输入 `/compact`,必要时补一句压缩重点,例如 `/compact focus on the provider config changes`
93-
- 直接开始新会话
94-
95-
经验上:
96-
97-
- 还在同一个问题链路里,但历史有噪音:用 `/compact`
98-
- 任务已经换题:直接开新会话
99-
100-
## 结合本仓库应该怎么理解
101-
102-
### 1. 本扩展复用的是 VS Code 内置 Context Window
103-
104-
本仓库没有再维护一套独立的原生 Context Agent 展示。用户在聊天框里看到的 `Context Window`、hover 后的 token 拆分、compact 行为,都以 VS Code / Copilot Chat 当前内置实现为准。
105-
106-
### 2. 分母大小依赖模型上下文配置
107-
108-
在这个仓库里,模型上下文参数来自供应商/模型配置。代码里会把总上下文、最大输入、最大输出做归一化处理:
109-
110-
- 当显式提供总上下文和输入/输出上限时,按显式值使用
111-
- 只提供部分字段时,会推导剩余部分
112-
- 没配时,会回退到默认值
113-
114-
因此,如果供应商模型的 `contextSize``maxInputTokens``maxOutputTokens` 配置不准确,Copilot Chat 里看到的 `X / Y tokens` 也可能与真实模型能力不一致。本仓库当前推荐用 `contextSize` 作为描述模型上下文的主字段;`maxInputTokens` / `maxOutputTokens` 仅保留兼容旧配置。运行时会优先使用 `contextSize` 作为总上下文窗口;只有当 `maxInputTokens``maxOutputTokens` 超过它时,才会自动收敛到 `contextSize`
115-
116-
### 2.5 当前不再维护原生 Context Window 分子
117-
118-
本仓库当前不再尝试把上游返回的 `usage` 回填到 VS Code 原生 `Context Window X / Y tokens``X`
119-
120-
原因不是上游没有 usage,而是当前公开的 VS Code Chat / Language Model 扩展 API 没有提供“把 prompt/completion/total/outputBuffer 这类 usage 明细写回原生 Context Window”的公开接口。公开接口要求扩展实现的只有:
121-
122-
- 通过 `LanguageModelChatProvider.provideLanguageModelChatResponse(...)` 回传响应流
123-
- 通过 `LanguageModelChatProvider.provideTokenCount(...)` 返回一个 token 数
124-
125-
`provideTokenCount(...)` 本质上是“对输入做 tokenizer 计数”的接口,不是“上报上一轮真实 usage”的接口。本仓库已经明确停止本地 prompt token 估算和本地 token 计数,因此这里直接返回 `0`,不再继续做上一轮 usage 回填这种妥协方案。
126-
127-
如果上游接口返回了 usage,本仓库会把最近一次已完成请求的真实 usage 展示到状态栏 `CodingPlans Context`,用于查看实际占比和明细。后续若 VS Code 开放了原生 usage/context 写回 API,再恢复这一块,见 [todo/vscode-chat-api-follow-up.md](../todo/vscode-chat-api-follow-up.md)
128-
129-
### 3. 对这个项目最实用的上下文组织方式
130-
131-
处理这个仓库的典型问题时,建议这样喂上下文:
132-
133-
- 改 provider 行为:附加 `#src/providers/...` 和相关配置读取代码
134-
- 改设置项:附加 `#src/config/configStore.ts #package.json #README.md #DEV.md`
135-
- 改文档说明:附加 `#README.md #README_en.md #DEV.md`
136-
- 查某个模型上下文窗口为什么显示不对:附加模型配置 + `#src/providers/baseProvider.ts #src/config/configStore.ts`
137-
138-
不要一上来就无差别 `#codebase`。只有在确实是跨模块机制问题时,才需要整仓上下文。
139-
140-
## 排查建议
141-
142-
如果你怀疑“为什么某条 instructions / prompt 没生效”,官方建议直接看 Chat 诊断信息:
143-
144-
1. 在 Chat 视图里右键
145-
2. 选择 `Diagnostics`
146-
3. 检查已加载的 instruction files、prompt files 和错误信息
147-
148-
这比只盯着 `Context Window` 数字更有效,因为后者只能告诉你“用了多少”,不能告诉你“具体哪份规则没被加载”。
149-
150-
## 官方文档
151-
152-
- VS Code: Manage context for AI
87+
- VS Code 官方:Manage context for AI
15388
https://code.visualstudio.com/docs/copilot/chat/copilot-chat-context
154-
- VS Code: Chat overview
89+
- VS Code 官方:Chat overview
15590
https://code.visualstudio.com/docs/copilot/chat/copilot-chat
156-
- VS Code: Use custom instructions in VS Code
157-
https://code.visualstudio.com/docs/copilot/customization/custom-instructions
158-
- VS Code: Use prompt files in VS Code
159-
https://code.visualstudio.com/docs/copilot/customization/prompt-files
91+
- VS Code 官方:How Copilot understands your workspace
92+
https://code.visualstudio.com/docs/copilot/reference/workspace-context
93+
- VS Code 官方:Language Model Chat Provider API
94+
https://code.visualstudio.com/api/extension-guides/ai/language-model-chat-provider

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "coding-plans-for-copilot",
33
"displayName": "%displayName%",
44
"description": "%description%",
5-
"version": "0.7.2",
5+
"version": "0.7.9",
66
"publisher": "techfetch-dev",
77
"repository": {
88
"type": "git",

src/contextUsageState.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export interface LastContextUsageSnapshot extends NormalizedTokenUsage {
1010
recordedAt: number;
1111
}
1212

13+
const STATUS_BAR_NO_BREAK_SPACE = '\u00A0';
14+
const CONTEXT_STATUS_LABEL = `CodingPlans${STATUS_BAR_NO_BREAK_SPACE}Context`;
15+
1316
export class ContextUsageState implements vscode.Disposable {
1417
private snapshot: LastContextUsageSnapshot | undefined;
1518
private readonly onDidChangeEmitter = new vscode.EventEmitter<LastContextUsageSnapshot | undefined>();
@@ -64,11 +67,11 @@ export class ContextStatusBarController implements vscode.Disposable {
6467

6568
export function buildContextStatusText(snapshot: LastContextUsageSnapshot | undefined): string {
6669
if (!snapshot || snapshot.totalContextWindow <= 0) {
67-
return 'CodingPlans Context --';
70+
return `${CONTEXT_STATUS_LABEL}${STATUS_BAR_NO_BREAK_SPACE}--`;
6871
}
6972

7073
const percentage = Math.min(100, Math.max(0, Math.round((readOccupiedContextTokens(snapshot) / snapshot.totalContextWindow) * 100)));
71-
return `CodingPlans Context ${percentage}%`;
74+
return `${CONTEXT_STATUS_LABEL}${STATUS_BAR_NO_BREAK_SPACE}${percentage}%`;
7275
}
7376

7477
export function buildContextStatusTooltip(snapshot: LastContextUsageSnapshot | undefined): string {

src/extension.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ContextUsageState } from './contextUsageState';
33
import { GenericAIProvider } from './providers/genericProvider';
44
import { LMChatProviderAdapter } from './providers/lmChatProviderAdapter';
55
import { ConfigStore } from './config/configStore';
6-
import { CodingPlanStatusBarController, PlanUsagePollingController, PlanUsageState, showCodingPlanDetails } from './planUsageStatus';
6+
import { CodingPlanStatusBarController, PlanUsagePollingController, PlanUsageState } from './planUsageStatus';
77
import { initI18n, getMessage } from './i18n/i18n';
88
import { getCompactErrorMessage } from './providers/baseProvider';
99
import {
@@ -24,7 +24,6 @@ let providers: Map<string, GenericAIProvider> = new Map();
2424
let refreshModelsCommandInProgress = false;
2525
let languageModelProviderRegistration: vscode.Disposable | undefined;
2626
let reRegisterLanguageModelProviderInProgress = false;
27-
const SHOW_STATUS_DETAILS_COMMAND = 'coding-plans.showStatusDetails';
2827

2928
function shouldShowGenerateCommitMessageCommand(): boolean {
3029
return vscode.workspace
@@ -205,15 +204,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
205204
context.subscriptions.push(contextUsageState);
206205
const planUsageState = new PlanUsageState();
207206
context.subscriptions.push(planUsageState);
208-
context.subscriptions.push(
209-
vscode.commands.registerCommand(SHOW_STATUS_DETAILS_COMMAND, () => {
210-
showCodingPlanDetails(contextUsageState.getSnapshot(), planUsageState.getSnapshot());
211-
})
212-
);
213207
const codingPlanStatusBarController = new CodingPlanStatusBarController(
214208
contextUsageState,
215-
planUsageState,
216-
SHOW_STATUS_DETAILS_COMMAND
209+
planUsageState
217210
);
218211
context.subscriptions.push(codingPlanStatusBarController);
219212
const planUsagePollingController = new PlanUsagePollingController(configStore, planUsageState, contextUsageState);

0 commit comments

Comments
 (0)