Skip to content

Commit 0766d4b

Browse files
authored
feat: acp model select (#1366)
* feat(acp): add session config options * feat(chat): refine acp status bar * fix(acp): cache latest process config * fix(chat): isolate ACP config cache by agent * fix(acp): preserve config state on sync
1 parent ed5ccf4 commit 0766d4b

File tree

34 files changed

+2689
-167
lines changed

34 files changed

+2689
-167
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# ACP Session Config Options 实施计划
2+
3+
## 1. 当前基线
4+
5+
1. ACP 状态栏当前只把 provider/model 锁定为外层 ACP agent。
6+
2. ACP 内部 model/mode 能力部分来自旧 `models/modes`,没有统一配置状态。
7+
3. 新版 SDK `0.16.1` 已支持 `configOptions``config_option_update``session_info_update``usage_update`
8+
9+
## 2. 设计决策
10+
11+
### 2.1 统一配置状态
12+
13+
新增共享类型:
14+
15+
1. `AcpConfigOptionValue`
16+
2. `AcpConfigOption`
17+
3. `AcpConfigState`
18+
19+
主进程通过 `normalizeAcpConfigState()` 统一把两类来源归一为同一结构:
20+
21+
1. `configOptions` 直接映射,标记 `source=configOptions`
22+
2. legacy `models/modes` 合成为伪 config option,标记 `source=legacy`
23+
24+
### 2.2 Warmup / Session 双缓存
25+
26+
1. `AcpProcessHandle` 缓存 process 级 warmup config state
27+
2. `AcpSessionRecord` 缓存 session 级 config state
28+
3. `prepareAcpSession` 在 draft 建立后立即发出 config-ready 事件,让 renderer 无缝从 process cache 切到 session cache
29+
30+
### 2.3 事件策略
31+
32+
新增事件:
33+
34+
1. `ACP_WORKSPACE_EVENTS.SESSION_CONFIG_OPTIONS_READY`
35+
36+
触发时机:
37+
38+
1. process warmup 完成
39+
2. `prepareAcpSession` / `coreStream` 绑定 session 后
40+
3. 收到 `config_option_update`
41+
4. `setSessionConfigOption` / legacy mode/model 写入成功后
42+
43+
### 2.4 Renderer 展示策略
44+
45+
状态栏维持双轨:
46+
47+
1. 非 ACP:继续显示普通模型列表和 generation settings
48+
2. ACP:显示 ACP options 面板,不再清空设置区
49+
50+
排序规则:
51+
52+
1. `model`
53+
2. `thought_level`
54+
3. 其余按 agent 原顺序
55+
56+
读写规则:
57+
58+
1.`draftSessionId` 或活动 ACP session 时,走 session 级读写
59+
2. 仅有 process warmup 数据时,面板只读
60+
61+
UI refinement:
62+
63+
1. ACP 状态栏隐藏 permission mode 入口,右侧只保留 `更多` 与最右侧 `MCP`
64+
2. inline 只展示前 3 个 `select` 类型配置,触发器复用 MCP 风格的 ghost button + popover header
65+
3. `boolean` 与剩余配置统一进入 `更多` 面板,不再 inline 展示
66+
67+
## 3. 分阶段实施
68+
69+
### Phase 1:SDK 与主进程兼容
70+
71+
1. 升级 SDK 到 `0.16.1`
72+
2. 修正 schema import 路径
73+
3. 兼容 `unstable_setSessionModel` / `KillTerminalRequest` 等 SDK 差异
74+
75+
### Phase 2:ACP 配置状态归一
76+
77+
1. 新增 `acpConfigState.ts`
78+
2. `AcpProcessManager` warmup 归一 `configOptions/models/modes`
79+
3. `AcpSessionManager` 建 session 时继承并缓存统一 state
80+
4. `AcpContentMapper` 支持 `config_option_update`
81+
82+
### Phase 3:Presenter 与事件
83+
84+
1. `AcpProvider` 增加 process/session config 读写接口
85+
2. `LLMProviderPresenter``NewAgentPresenter` 暴露代理方法
86+
3. 发出 `SESSION_CONFIG_OPTIONS_READY`
87+
88+
### Phase 4:Renderer 状态栏
89+
90+
1. `NewThreadPage` 透传 ACP draft sessionId
91+
2. `ChatStatusBar` 加入 ACP config 同步、只读控制和更新逻辑
92+
3. trigger 显示 `ACP agent / internal model`
93+
94+
## 4. 测试策略
95+
96+
### 4.1 Main
97+
98+
1. `AcpContentMapper` 覆盖 `config_option_update`
99+
2. `AcpProvider.prepareSession` 发出 config-ready 事件
100+
3. `AcpProvider.setSessionConfigOption` 使用 agent 返回的全量 state 回写缓存
101+
4. `NewAgentPresenter` 覆盖 ACP session config 读写代理
102+
103+
### 4.2 Renderer
104+
105+
1. ACP draft 首屏读取 process warmup config
106+
2. draft sessionId 就绪后切换到 session config
107+
3. 写入 ACP select/boolean option 时调用 session presenter
108+
4. 非 ACP 原有状态栏行为无回归
109+
110+
## 5. 风险与缓解
111+
112+
1. 风险:不同 ACP agent 同时返回 `configOptions` 与 legacy 字段。
113+
缓解:统一以 `configOptions` 为准,legacy 仅在缺失时启用。
114+
115+
2. 风险:renderer 在 draft 早期拿不到 sessionId,导致控件误可写。
116+
缓解:基于 `activeAcpSessionId` 做只读门控。
117+
118+
3. 风险:新 SDK 增加的 session 通知被误判为未处理异常。
119+
缓解:`session_info_update``usage_update` 静默兼容。
120+
121+
## 6. 质量门槛
122+
123+
1. `pnpm run typecheck`
124+
2. `pnpm run format`
125+
3. `pnpm run i18n`
126+
4. `pnpm run lint`
127+
5. 关键 main/renderer 测试通过
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# ACP Session Config Options 规格
2+
3+
## 概述
4+
5+
为 ACP 接入协议级 `session config options`,让 ACP agent 的内部 `model``thought_level``mode`、布尔开关等能力在 DeepChat 状态栏中直接展示和修改。
6+
7+
本次改动同时完成:
8+
9+
1. 升级 `@agentclientprotocol/sdk``0.16.1`
10+
2. ACP 优先走新版 `configOptions`
11+
3.`models/modes` 仅作为兼容兜底
12+
4. 预热阶段拿到的配置立即可展示,不等待首条消息
13+
14+
## 背景与动机
15+
16+
1. 当前 ACP 外层模型选择器只表示“ACP agent”,内部 session model 被固定,用户无法直观看到真实内部模型。
17+
2. 协议已提供 `session config options`,可以统一承载 `model``thought_level``mode` 以及其他 agent 自定义配置。
18+
3. ACP warmup 阶段已经能拿到这些信息,继续延迟到首条消息后再展示会造成首屏空窗。
19+
20+
## 用户故事
21+
22+
### US-1:看到 ACP 内部真实模型
23+
24+
作为用户,我希望状态栏显示 `ACP agent / 内部 model`,这样我能确认当前 ACP session 真正在用哪个模型。
25+
26+
### US-2:在新线程阶段就能看配置
27+
28+
作为用户,我希望 ACP draft 刚建立时就能看到 agent 的可配置项,而不是要先发一条消息。
29+
30+
### US-3:统一修改 ACP session 配置
31+
32+
作为用户,我希望在同一个状态栏面板里修改 ACP 的 `model``thought_level``mode` 和布尔类开关。
33+
34+
## 功能需求
35+
36+
### A. 配置来源与兼容策略
37+
38+
- [ ] ACP 主路径使用协议 `configOptions`
39+
- [ ] 当 agent 未返回 `configOptions` 时,回退到 legacy `models/modes`
40+
- [ ] 若同时返回两套字段,只采用 `configOptions`
41+
42+
### B. 外层 agent 与内层 session model 分离
43+
44+
- [ ] 状态栏外层仍显示 ACP agent
45+
- [ ] ACP 内部 `model` 不写回现有通用 `SessionGenerationSettings`
46+
- [ ] ACP agent 不允许通过普通 `setSessionModel` 切走 provider/model
47+
48+
### C. Warmup 与缓存
49+
50+
- [ ] warmup 的 `newSession/loadSession` 结果要归一为统一 `AcpConfigState`
51+
- [ ] 预热缓存应绑定到 process handle
52+
- [ ] `prepareAcpSession` 建立 draft/session 后立即把缓存灌入 session,并发出 ready 事件
53+
54+
### D. Renderer 状态栏
55+
56+
- [ ] 非 ACP 路径保持现有模型选择和 generation settings 行为
57+
- [ ] ACP 路径改为展示 ACP options 面板
58+
- [ ] `category=model` 作为首要选项,并参与 trigger 文案展示
59+
- [ ] `category=thought_level` 排在 `model` 后,保留 agent 返回的 label/value
60+
- [ ] `category=mode` 与其他 generic 选项保持 agent 顺序
61+
- [ ] draft 无 sessionId 时展示 warmup 数据但控件只读
62+
- [ ] draft sessionId 就绪后切到 session 级读写
63+
64+
### E. 事件与接口
65+
66+
- [ ] 新增 `AcpConfigOption``AcpConfigOptionValue``AcpConfigState`
67+
- [ ] `ILlmProviderPresenter` 增加 ACP process/session config 读写接口
68+
- [ ] `INewAgentPresenter` 增加 ACP session config 读写接口
69+
- [ ] 新增 renderer 事件 `ACP_WORKSPACE_EVENTS.SESSION_CONFIG_OPTIONS_READY`
70+
71+
## 验收标准
72+
73+
- [ ] ACP trigger 可显示 `agentId / internal model`
74+
- [ ] 新线程 ACP draft 能先显示 warmup config
75+
- [ ] draft sessionId 就绪后可切到 session config 并允许写入
76+
- [ ] `config_option_update` 会整组替换当前 config state
77+
- [ ] 旧 ACP agent 只有 `models/modes` 时仍可正常展示和切换
78+
79+
## 非目标
80+
81+
1. 不把 ACP `model/thought_level/mode` 混入通用 provider generation settings。
82+
2. 不重做非 ACP 状态栏 UI。
83+
3. 不在本次把 `systemPrompt/temperature/contextLength/maxTokens` 合并进 ACP options。
84+
85+
## 约束
86+
87+
1. 继续遵循现有 Presenter + EventBus 架构。
88+
2. 所有兼容逻辑集中在 ACP 主进程归一层,不在 renderer 分散判断 legacy 字段。
89+
3. UI 不新增独立 ACP 设置页,先复用状态栏入口。
90+
91+
## 开放问题
92+
93+
无。
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# ACP Session Config Options 任务清单
2+
3+
## T0 规格文档
4+
5+
- [x] 新建 `spec.md`
6+
- [x] 新建 `plan.md`
7+
- [x] 新建 `tasks.md`
8+
9+
## T1 SDK 与共享类型
10+
11+
- [x] 升级 `@agentclientprotocol/sdk``0.16.1`
12+
- [x] 修正 ACP schema import 路径
13+
- [x] 新增 `AcpConfigOptionValue`
14+
- [x] 新增 `AcpConfigOption`
15+
- [x] 新增 `AcpConfigState`
16+
17+
## T2 ACP 主进程归一层
18+
19+
- [x] 新增 `acpConfigState.ts`
20+
- [x] warmup 解析 `configOptions`
21+
- [x] legacy `models/modes` 回退归一
22+
- [x] `config_option_update` 整组替换 session config state
23+
- [x] `session_info_update` / `usage_update` 静默兼容
24+
25+
## T3 Presenter / EventBus
26+
27+
- [x] `AcpProcessHandle` / `AcpSessionRecord` 缓存统一 config state
28+
- [x] 新增 `SESSION_CONFIG_OPTIONS_READY` 事件
29+
- [x] `ILlmProviderPresenter` 增加 ACP process/session config 读写接口
30+
- [x] `INewAgentPresenter` 增加 ACP session config 读写接口
31+
32+
## T4 Renderer 状态栏
33+
34+
- [x] `NewThreadPage` 透传 `acpDraftSessionId`
35+
- [x] `ChatStatusBar` 增加 ACP config 拉取与事件订阅
36+
- [x] ACP trigger 显示 `agent / internal model`
37+
- [x] draft 无 sessionId 时显示 warmup config 且只读
38+
- [x] draft sessionId 就绪后切换到 session 级读写
39+
40+
## T5 测试
41+
42+
- [x] 更新 `acpContentMapper.test.ts`
43+
- [x] 更新 `acpProvider.test.ts`
44+
- [x] 更新 `newAgentPresenter.test.ts`
45+
- [x] 更新 `ChatStatusBar.test.ts`
46+
47+
## T6 质量门禁
48+
49+
- [x] `pnpm run format`
50+
- [x] `pnpm run i18n`
51+
- [x] `pnpm run lint`
52+
- [x] 运行关键测试并记录结果

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"update-shadcn": "node scripts/update-shadcn.js"
6161
},
6262
"dependencies": {
63-
"@agentclientprotocol/sdk": "^0.5.1",
63+
"@agentclientprotocol/sdk": "^0.16.1",
6464
"@anthropic-ai/sdk": "^0.53.0",
6565
"@antv/infographic": "^0.2.7",
6666
"@aws-sdk/client-bedrock": "^3.958.0",
@@ -116,8 +116,6 @@
116116
"@lingual/i18n-check": "0.8.12",
117117
"@mcp-ui/client": "^5.13.3",
118118
"@pinia/colada": "^0.20.0",
119-
"@unovis/ts": "1.6.4",
120-
"@unovis/vue": "1.6.4",
121119
"@tailwindcss/typography": "^0.5.19",
122120
"@tailwindcss/vite": "^4.1.18",
123121
"@tiptap/core": "^2.11.7",
@@ -137,6 +135,8 @@
137135
"@types/node": "^22.19.3",
138136
"@types/xlsx": "^0.0.35",
139137
"@typescript/native-preview": "7.0.0-dev.20260115.1",
138+
"@unovis/ts": "1.6.4",
139+
"@unovis/vue": "1.6.4",
140140
"@vee-validate/zod": "^4.15.1",
141141
"@vitejs/plugin-vue": "^6.0.3",
142142
"@vitest/ui": "^3.2.4",

src/main/events.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ export const WORKSPACE_EVENTS = {
274274
// ACP-specific workspace events
275275
export const ACP_WORKSPACE_EVENTS = {
276276
SESSION_MODES_READY: 'acp-workspace:session-modes-ready', // Session modes available
277-
SESSION_COMMANDS_READY: 'acp-workspace:session-commands-ready' // Session commands available
277+
SESSION_COMMANDS_READY: 'acp-workspace:session-commands-ready', // Session commands available
278+
SESSION_CONFIG_OPTIONS_READY: 'acp-workspace:session-config-options-ready' // Session config options available
278279
}
279280

280281
export const ACP_DEBUG_EVENTS = {

src/main/presenter/agentPresenter/acp/acpCapabilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type * as schema from '@agentclientprotocol/sdk/dist/schema.js'
1+
import type * as schema from '@agentclientprotocol/sdk/dist/schema/index.js'
22

33
export interface AcpCapabilityOptions {
44
enableFs?: boolean

0 commit comments

Comments
 (0)