@yfwu2020/dsh-selection-explain 0.10.4 → 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -11
- package/cordis.patch.yml +1 -1
- package/lib/client.js +10698 -12424
- package/lib/client.js.map +7 -0
- package/lib/config-values.js +55 -0
- package/lib/config-values.js.map +1 -0
- package/lib/host/analyze.js +795 -0
- package/lib/host/analyze.js.map +1 -0
- package/lib/host/config.js +81 -0
- package/lib/host/config.js.map +1 -0
- package/lib/host/constants.js +25 -0
- package/lib/host/constants.js.map +1 -0
- package/lib/host/context.js +237 -0
- package/lib/host/context.js.map +1 -0
- package/lib/host/design-skill.js +42 -0
- package/lib/host/design-skill.js.map +1 -0
- package/lib/host/effort.js +239 -0
- package/lib/host/effort.js.map +1 -0
- package/lib/host/filters.js +132 -0
- package/lib/host/filters.js.map +1 -0
- package/lib/host/history-store.js +404 -0
- package/lib/host/history-store.js.map +1 -0
- package/lib/host/http.js +46 -0
- package/lib/host/http.js.map +1 -0
- package/lib/host/messages.js +14 -0
- package/lib/host/messages.js.map +1 -0
- package/lib/host/mic.js +246 -0
- package/lib/host/mic.js.map +1 -0
- package/lib/host/models.js +246 -0
- package/lib/host/models.js.map +1 -0
- package/lib/host/plugin.js +41 -0
- package/lib/host/plugin.js.map +1 -0
- package/lib/host/promote.js +219 -0
- package/lib/host/promote.js.map +1 -0
- package/lib/host/routes.js +237 -0
- package/lib/host/routes.js.map +1 -0
- package/lib/host/sessions.js +181 -0
- package/lib/host/sessions.js.map +1 -0
- package/lib/host/settings-store.js +140 -0
- package/lib/host/settings-store.js.map +1 -0
- package/lib/host/speech.js +320 -0
- package/lib/host/speech.js.map +1 -0
- package/lib/host/tools.js +179 -0
- package/lib/host/tools.js.map +1 -0
- package/lib/host/types.js +2 -0
- package/lib/host/types.js.map +1 -0
- package/lib/index.js +10 -3765
- package/lib/index.js.map +1 -1
- package/lib/prompts.js +1 -1
- package/lib/settings.js +17 -27
- package/lib/settings.js.map +1 -1
- package/lib/types/config-values.d.ts +175 -0
- package/lib/types/host/analyze.d.ts +10 -0
- package/lib/types/host/config.d.ts +147 -0
- package/lib/types/host/constants.d.ts +24 -0
- package/lib/types/host/context.d.ts +41 -0
- package/lib/types/host/design-skill.d.ts +1 -0
- package/lib/types/host/effort.d.ts +61 -0
- package/lib/types/host/filters.d.ts +20 -0
- package/lib/types/host/history-store.d.ts +13 -0
- package/lib/types/host/http.d.ts +8 -0
- package/lib/types/host/messages.d.ts +13 -0
- package/lib/types/host/mic.d.ts +17 -0
- package/lib/types/host/models.d.ts +57 -0
- package/lib/types/host/plugin.d.ts +3 -0
- package/lib/types/host/promote.d.ts +9 -0
- package/lib/types/host/routes.d.ts +14 -0
- package/lib/types/host/sessions.d.ts +14 -0
- package/lib/types/host/settings-store.d.ts +8 -0
- package/lib/types/host/speech.d.ts +23 -0
- package/lib/types/host/tools.d.ts +39 -0
- package/lib/types/host/types.d.ts +89 -0
- package/lib/types/index.d.ts +12 -441
- package/lib/types/prompts.d.ts +1 -1
- package/lib/types/settings.d.ts +1 -1
- package/package.json +31 -21
- package/assets/code.png +0 -0
- package/assets/detail.png +0 -0
- package/assets/quotes.png +0 -0
- package/assets/stage1.png +0 -0
- package/assets/stage2.png +0 -0
- package/assets/translation.png +0 -0
- package/assets/voice-card-light.png +0 -0
- package/assets/voice-inserted.png +0 -0
- package/assets/voice-settings.png +0 -0
- package/assets/voice.png +0 -0
- package/assets/web.png +0 -0
- package/scripts/build-demo-pages.mjs +0 -350
- package/scripts/build-vcard-lab.mjs +0 -834
- package/scripts/build.sh +0 -147
- package/scripts/crop-png.mjs +0 -142
- package/scripts/dump-prompt.mjs +0 -143
- package/scripts/fixtures/fake-mic-probe.sh +0 -9
- package/scripts/gen-star-path.mjs +0 -71
- package/scripts/measure-cost.mjs +0 -251
- package/scripts/smoke-bridge.mjs +0 -365
- package/scripts/smoke-panel.mjs +0 -1903
- package/scripts/smoke-voice.mjs +0 -774
- package/scripts/test-bridge.mjs +0 -412
- package/scripts/test-client.mjs +0 -6175
- package/scripts/test-effort-map.mjs +0 -129
- package/scripts/test-effort-retry.mjs +0 -109
- package/scripts/test-escape-focus.mjs +0 -101
- package/scripts/test-filters.mjs +0 -146
- package/scripts/test-format.mjs +0 -93
- package/scripts/test-guard.mjs +0 -48
- package/scripts/test-mic-build.mjs +0 -146
- package/scripts/test-mic-idle.mjs +0 -158
- package/scripts/test-model-follow.mjs +0 -193
- package/scripts/test-prompt.mjs +0 -193
- package/scripts/test-route-cache.mjs +0 -138
- package/scripts/test-settings-behavior.mjs +0 -188
- package/scripts/test-settings-host.mjs +0 -48
- package/scripts/test-settings.mjs +0 -329
- package/scripts/test-speech.mjs +0 -220
- package/scripts/test-transcript.mjs +0 -151
- package/src/client/index.js +0 -12580
- package/src/index.ts +0 -4254
- package/src/prompts.ts +0 -144
- package/src/settings.ts +0 -313
package/lib/host/mic.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { spawnSync, spawn } from 'node:child_process';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { existsSync, readFileSync, mkdirSync, chmodSync } from 'node:fs';
|
|
6
|
+
import { createHash } from 'node:crypto';
|
|
7
|
+
import { createInterface } from 'node:readline';
|
|
8
|
+
/** 最新一次探针状态(进程集合变了才更新)。 */
|
|
9
|
+
const micState = {
|
|
10
|
+
available: false,
|
|
11
|
+
capturing: false,
|
|
12
|
+
processes: [],
|
|
13
|
+
/** 不可用时的原因(not-macos / probe-missing / probe-failed / probe-exited)。 */
|
|
14
|
+
reason: '',
|
|
15
|
+
};
|
|
16
|
+
let micChild = null;
|
|
17
|
+
/** 只尝试启动一次:失败就认(避免每个请求都去 spawn 一遍)。 */
|
|
18
|
+
let micStarted = false;
|
|
19
|
+
/** 最近一次有人来问探针的时间(用来判断"没人看了")。 */
|
|
20
|
+
let micLastUse = 0;
|
|
21
|
+
/** "没人看就停"的检查定时器。 */
|
|
22
|
+
let micIdleTimer = null;
|
|
23
|
+
/**
|
|
24
|
+
* 没人来问之后,探针还留多久(毫秒)。
|
|
25
|
+
*
|
|
26
|
+
* 为什么不立刻停:页面在"点一下别处"时会瞬间停轮询,立刻杀进程会变成反复 spawn/kill。
|
|
27
|
+
* 留一段空转把这种抖动吸收掉;划词期间页面每 200ms 来问一次,探针自然不会到期。
|
|
28
|
+
*
|
|
29
|
+
* 为什么是 60 秒:让探针"热着"—— 你划词、看两眼、再划下一段,中间往往隔几十秒;
|
|
30
|
+
* 探针还在的话,第二次划词是**零启动开销**(冷启动要 ~80ms 才出第一行)。
|
|
31
|
+
* 代价是没人用之后进程多留一会儿,而它常驻只占 ~0.8% 单核,值。
|
|
32
|
+
* 实际停止发生在超时后的下一次检查,所以真实寿命是 60~65 秒(见 MIC_IDLE_CHECK_MS)。
|
|
33
|
+
*/
|
|
34
|
+
const MIC_IDLE_MS = Number(process.env.DSH_SEL_MIC_IDLE_MS || 60000);
|
|
35
|
+
/** 空转检查的间隔(毫秒)。 */
|
|
36
|
+
const MIC_IDLE_CHECK_MS = Number(process.env.DSH_SEL_MIC_CHECK_MS || 5000);
|
|
37
|
+
/**
|
|
38
|
+
* 探针的采样间隔(毫秒)—— 决定它多久发现"麦克风被打开了"。
|
|
39
|
+
*
|
|
40
|
+
* 为什么是 125:实测常驻成本极低(250ms → 0.6% 单核,150ms → 0.7%),
|
|
41
|
+
* 而"按 Fn 到卡片弹出"的延迟里它是主要两项之一(另一项是页面轮询)。
|
|
42
|
+
* 调快一倍的代价约 0.1% 单核,换来发现延迟减半 —— 值。
|
|
43
|
+
* 原生探针会把区间夹在 50~5000ms 之间(见 native/mic-probe.c)。
|
|
44
|
+
*/
|
|
45
|
+
const MIC_WATCH_MS = Number(process.env.DSH_SEL_MIC_WATCH_MS || 125);
|
|
46
|
+
/** 探针二进制:随包构建出来的那个(与编译产物 lib/index.js 同级;测试可注入假的)。 */
|
|
47
|
+
const MIC_PROBE = fileURLToPath(new URL('../native/mic-probe', import.meta.url));
|
|
48
|
+
/** 探针源码:发布包里**一定有它**(`files` 含 native/),二进制则不一定(见下)。 */
|
|
49
|
+
const MIC_PROBE_SRC = fileURLToPath(new URL('../../native/mic-probe.c', import.meta.url));
|
|
50
|
+
/** 解析结果缓存:'' = 解析过了但没有可用探针(reason 说明为什么)。 */
|
|
51
|
+
let micProbeResolved = null;
|
|
52
|
+
let micProbeReason = '';
|
|
53
|
+
/** 插件自己的数据目录(历史 / 记忆 / 就地编译出来的探针都放这儿)。 */
|
|
54
|
+
function pluginDataDir() {
|
|
55
|
+
return join(process.env.DSH_HOME ?? join(homedir(), '.dsh'), 'selection-explain');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 找到探针二进制 —— 找不到就**现场编一份**。
|
|
59
|
+
*
|
|
60
|
+
* 为什么必须运行时编译:CI 跑在 ubuntu 上,`build.sh` 里的原生探针那一步会被跳过
|
|
61
|
+
* (日志原话:"跳过原生探针(非 macOS 或没有 clang)"),于是 npm / Release 装下来的包里
|
|
62
|
+
* **只有 `native/mic-probe.c` 源码、没有 `lib/native/mic-probe`** —— macOS 用户装上就是
|
|
63
|
+
* `probe-missing`,豆包开麦永远不弹卡(2026-10-11 用户在另一台 Mac 上实测到的就是这个)。
|
|
64
|
+
*
|
|
65
|
+
* 顺序:环境变量覆盖(测试用)→ 随包构建的 → 数据目录里按**源码 hash** 缓存的那份
|
|
66
|
+
* (没有就 clang 编一次;源码改了就自然重建)→ 都没有则如实报原因。
|
|
67
|
+
* 编译失败不算致命:其余功能一律不受影响(和"没装识别服务"一个待遇)。
|
|
68
|
+
*/
|
|
69
|
+
function resolveMicProbe() {
|
|
70
|
+
if (micProbeResolved !== null)
|
|
71
|
+
return micProbeResolved;
|
|
72
|
+
const override = process.env.DSH_SEL_MIC_PROBE;
|
|
73
|
+
if (override) {
|
|
74
|
+
micProbeResolved = existsSync(override) ? override : '';
|
|
75
|
+
if (!micProbeResolved)
|
|
76
|
+
micProbeReason = 'probe-missing';
|
|
77
|
+
return micProbeResolved;
|
|
78
|
+
}
|
|
79
|
+
if (existsSync(MIC_PROBE)) {
|
|
80
|
+
micProbeResolved = MIC_PROBE;
|
|
81
|
+
return micProbeResolved;
|
|
82
|
+
}
|
|
83
|
+
if (!existsSync(MIC_PROBE_SRC)) {
|
|
84
|
+
micProbeResolved = '';
|
|
85
|
+
micProbeReason = 'probe-missing';
|
|
86
|
+
return micProbeResolved;
|
|
87
|
+
}
|
|
88
|
+
let tag = 'v1';
|
|
89
|
+
try {
|
|
90
|
+
tag = createHash('sha1').update(readFileSync(MIC_PROBE_SRC)).digest('hex').slice(0, 8);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
/* 读不了源码就按固定名缓存 */
|
|
94
|
+
}
|
|
95
|
+
const built = join(pluginDataDir(), `mic-probe-${tag}`);
|
|
96
|
+
if (existsSync(built)) {
|
|
97
|
+
micProbeResolved = built;
|
|
98
|
+
return micProbeResolved;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
mkdirSync(pluginDataDir(), { recursive: true });
|
|
102
|
+
const result = spawnSync('clang', ['-O2', '-framework', 'CoreAudio', '-framework', 'CoreFoundation', MIC_PROBE_SRC, '-o', built], { timeout: 60_000 });
|
|
103
|
+
if (result.status === 0 && existsSync(built)) {
|
|
104
|
+
try {
|
|
105
|
+
chmodSync(built, 0o755);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
/* 权限位设不上也还能试跑 */
|
|
109
|
+
}
|
|
110
|
+
micProbeResolved = built;
|
|
111
|
+
return micProbeResolved;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
/* 下面统一给失败原因 */
|
|
116
|
+
}
|
|
117
|
+
micProbeResolved = '';
|
|
118
|
+
micProbeReason = 'probe-build-failed';
|
|
119
|
+
return micProbeResolved;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 懒启动探针(第一次有人来问才 spawn)。
|
|
123
|
+
*
|
|
124
|
+
* 为什么不加载就启动:插件装着的绝大多数时间没人划词,没必要常驻一个每秒读几次
|
|
125
|
+
* CoreAudio 的进程。第一次 GET /mic 时才起。
|
|
126
|
+
* 起过之后**也不是一直留着**:见 armMicIdleCheck —— 没人来问就停,下次再起。
|
|
127
|
+
*/
|
|
128
|
+
function ensureMicProbe() {
|
|
129
|
+
if (micStarted)
|
|
130
|
+
return;
|
|
131
|
+
micStarted = true;
|
|
132
|
+
if (process.platform !== 'darwin') {
|
|
133
|
+
micState.reason = 'not-macos';
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const probe = resolveMicProbe();
|
|
137
|
+
if (!probe) {
|
|
138
|
+
micState.reason = micProbeReason || 'probe-missing';
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const child = spawn(probe, ['--watch', String(MIC_WATCH_MS)], {
|
|
143
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
144
|
+
});
|
|
145
|
+
micChild = child;
|
|
146
|
+
micState.available = true;
|
|
147
|
+
micState.reason = '';
|
|
148
|
+
if (child.stdout) {
|
|
149
|
+
const lines = createInterface({ input: child.stdout });
|
|
150
|
+
lines.on('line', (line) => {
|
|
151
|
+
try {
|
|
152
|
+
const parsed = JSON.parse(line);
|
|
153
|
+
micState.capturing = !!parsed.capturing;
|
|
154
|
+
micState.processes = Array.isArray(parsed.processes) ? parsed.processes : [];
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// 半行 / 坏行:丢掉,下一行会覆盖(探针每行都是完整状态)
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
child.on('error', () => {
|
|
162
|
+
micChild = null;
|
|
163
|
+
micState.available = false;
|
|
164
|
+
micState.capturing = false;
|
|
165
|
+
micState.processes = [];
|
|
166
|
+
micState.reason = 'probe-failed';
|
|
167
|
+
});
|
|
168
|
+
child.on('exit', () => {
|
|
169
|
+
micChild = null;
|
|
170
|
+
micState.available = false;
|
|
171
|
+
micState.capturing = false;
|
|
172
|
+
micState.processes = [];
|
|
173
|
+
micState.reason = 'probe-exited';
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
micChild = null;
|
|
178
|
+
micState.available = false;
|
|
179
|
+
micState.reason = 'probe-failed';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 排一次"没人看就停"的检查(幂等)。
|
|
184
|
+
*
|
|
185
|
+
* 页面的轮询只在"有选区 / 卡片开着"时跑,探针跟着它的节奏走就够了 ——
|
|
186
|
+
* 划词即启动,选区消失后再空转 MIC_IDLE_MS 就停,下次划词再起。
|
|
187
|
+
*/
|
|
188
|
+
function armMicIdleCheck() {
|
|
189
|
+
if (micIdleTimer)
|
|
190
|
+
return;
|
|
191
|
+
micIdleTimer = setInterval(() => {
|
|
192
|
+
if (Date.now() - micLastUse < MIC_IDLE_MS)
|
|
193
|
+
return;
|
|
194
|
+
stopMicProbe();
|
|
195
|
+
}, MIC_IDLE_CHECK_MS);
|
|
196
|
+
if (typeof micIdleTimer.unref === 'function')
|
|
197
|
+
micIdleTimer.unref();
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* 停掉探针(没人看了 / 插件卸载)。**下次有人来问会重新启动**。
|
|
201
|
+
*
|
|
202
|
+
* 注意 available 要跟着回落到 false:探针都停了,再报"正在录"就是过期数据 ——
|
|
203
|
+
* 客户端看到 !available 会停掉轮询(不假装),这正是我们要的。
|
|
204
|
+
*/
|
|
205
|
+
export function stopMicProbe() {
|
|
206
|
+
if (micIdleTimer) {
|
|
207
|
+
clearInterval(micIdleTimer);
|
|
208
|
+
micIdleTimer = null;
|
|
209
|
+
}
|
|
210
|
+
// 允许下次重新启动(与"启动失败就认"不同:那是 spawn 失败,不该每个请求都重试)
|
|
211
|
+
micStarted = false;
|
|
212
|
+
micState.available = false;
|
|
213
|
+
micState.capturing = false;
|
|
214
|
+
micState.processes = [];
|
|
215
|
+
micState.reason = 'idle';
|
|
216
|
+
const child = micChild;
|
|
217
|
+
micChild = null;
|
|
218
|
+
if (!child)
|
|
219
|
+
return;
|
|
220
|
+
try {
|
|
221
|
+
child.kill();
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// 已经退了:无所谓
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* GET /selection-explain/api/mic
|
|
229
|
+
* → { ok, available, capturing, processes:[{pid,bundleId,name}], reason }
|
|
230
|
+
*
|
|
231
|
+
* 客户端只关心 `capturing` 和某个进程的 bundleId 是不是目标输入法;
|
|
232
|
+
* 一次把所有占用者给全,是因为"同时在录的还有别的 App"很常见(会议软件、录音工具),
|
|
233
|
+
* 只报第一个会让特性在那种情况下静默失效。
|
|
234
|
+
*/
|
|
235
|
+
export const handleMic = (req, res) => {
|
|
236
|
+
// 每次有人来问都续一次命:只要页面在轮询,探针就不会到期
|
|
237
|
+
micLastUse = Date.now();
|
|
238
|
+
ensureMicProbe();
|
|
239
|
+
armMicIdleCheck();
|
|
240
|
+
res.writeHead(200, {
|
|
241
|
+
'content-type': 'application/json; charset=utf-8',
|
|
242
|
+
'cache-control': 'no-store',
|
|
243
|
+
});
|
|
244
|
+
res.end(JSON.stringify({ ok: true, ...micState }));
|
|
245
|
+
};
|
|
246
|
+
//# sourceMappingURL=mic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mic.js","sourceRoot":"","sources":["../../src/host/mic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { name } from './constants.js';
|
|
5
|
+
import { pickNextEffort, effortMapOf } from './effort.js';
|
|
6
|
+
/** Owns models state for one plugin instance. */
|
|
7
|
+
export function createModels(ctx, config) {
|
|
8
|
+
/** 兜底路由:第一次真实 LLM 调用后捕获。 */
|
|
9
|
+
let captured = null;
|
|
10
|
+
ctx.on('llm/stream', (options, next) => {
|
|
11
|
+
captured = { provider: options.provider, model: options.model };
|
|
12
|
+
return next();
|
|
13
|
+
});
|
|
14
|
+
let modelCache = { at: 0, items: [] };
|
|
15
|
+
/** 哪些 provider/model 在 "关" 档会把思考写进正文(实测过一次就记住,之后自动改用「低」)。 */
|
|
16
|
+
const leakyOnOff = new Set();
|
|
17
|
+
/**
|
|
18
|
+
* 哪些 provider/model **根本不接受 "关" 档**(上游直接 400 invalid_request_error)。
|
|
19
|
+
*
|
|
20
|
+
* 和 leakyOnOff 分开记:那个是"能发但会泄漏",这个是"发了就报错"。
|
|
21
|
+
* 记下来之后不再发 off,直接改用 low —— 这是"最接近关"的可接受档位。
|
|
22
|
+
* 不记的话每次划词都要先失败一轮再重试:用户看到一次报错闪动 + 多一个来回的时延。
|
|
23
|
+
*/
|
|
24
|
+
const noOffRoutes = new Set();
|
|
25
|
+
const leakyFile = () => join(process.env.DSH_HOME ?? join(homedir(), '.dsh'), 'selection-explain', 'leaky-off.json');
|
|
26
|
+
let leakyLoaded = false;
|
|
27
|
+
/** 载入"关档会泄漏思考"的模型清单(跨重启保留;文件坏了就当空)。 */
|
|
28
|
+
async function loadLeaky() {
|
|
29
|
+
if (leakyLoaded)
|
|
30
|
+
return;
|
|
31
|
+
leakyLoaded = true;
|
|
32
|
+
try {
|
|
33
|
+
const raw = await readFile(leakyFile(), 'utf8');
|
|
34
|
+
const parsed = JSON.parse(raw);
|
|
35
|
+
let dropped = 0;
|
|
36
|
+
const accept = (item, into) => {
|
|
37
|
+
if (typeof item !== 'string' || !item)
|
|
38
|
+
return;
|
|
39
|
+
// 落盘文件是**跨重启的经验**,但也可能被测试夹具写脏(实测有 p1/m-strong):
|
|
40
|
+
// provider 不存在的条目直接丢掉,并顺手把文件写回干净版。
|
|
41
|
+
if (!isRealProvider(item.split('/')[0] ?? '')) {
|
|
42
|
+
dropped += 1;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
into.add(item);
|
|
46
|
+
};
|
|
47
|
+
if (Array.isArray(parsed?.routes))
|
|
48
|
+
for (const item of parsed.routes)
|
|
49
|
+
accept(item, leakyOnOff);
|
|
50
|
+
if (Array.isArray(parsed?.noOff))
|
|
51
|
+
for (const item of parsed.noOff)
|
|
52
|
+
accept(item, noOffRoutes);
|
|
53
|
+
if (dropped > 0)
|
|
54
|
+
saveLeaky();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* 没有这个文件是常态 */
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function saveLeaky() {
|
|
61
|
+
const body = JSON.stringify({ version: 1, routes: Array.from(leakyOnOff), noOff: Array.from(noOffRoutes) }, null, 0);
|
|
62
|
+
void writeFile(leakyFile(), body, 'utf8').catch((error) => {
|
|
63
|
+
ctx.logger?.warn?.(`[${name}] 泄漏清单写盘失败:${String(error?.message ?? error)}`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 这条 route 的 provider 是不是**这台机器上真有的**。
|
|
68
|
+
*
|
|
69
|
+
* 为什么落盘前要查一下:这两个集合会写进 `~/.dsh/selection-explain/leaky-off.json`,
|
|
70
|
+
* 而请求体里的 provider 是可以伪造的(`resolveRoute` 在清单没加载出来时只做形状校验)。
|
|
71
|
+
* 实测踩过:`test-client.mjs` 的夹具 provider `p1` 被写进了用户真实的落盘文件
|
|
72
|
+
* (`p1/m-strong`、`p1/m-fast`)—— 之后再也没人清掉它。
|
|
73
|
+
* 宁可不记(顶多多撞一次上游,反正有重试),也不要往用户的文件里写不存在的东西。
|
|
74
|
+
*/
|
|
75
|
+
function isRealProvider(provider) {
|
|
76
|
+
if (!provider)
|
|
77
|
+
return false;
|
|
78
|
+
try {
|
|
79
|
+
const llm = ctx.get('llm');
|
|
80
|
+
const list = llm?.listProviders?.() ?? [];
|
|
81
|
+
return list.some((item) => String(item?.id ?? '') === provider);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** 记住一个"关档会泄漏"的模型(内存 + 落盘)。 */
|
|
88
|
+
function markLeaky(route) {
|
|
89
|
+
if (leakyOnOff.has(route))
|
|
90
|
+
return;
|
|
91
|
+
if (!isRealProvider(route.split('/')[0] ?? ''))
|
|
92
|
+
return;
|
|
93
|
+
leakyOnOff.add(route);
|
|
94
|
+
if (leakyLoaded)
|
|
95
|
+
saveLeaky();
|
|
96
|
+
}
|
|
97
|
+
/** 记住一个"不接受关档"的模型(内存 + 落盘):下次直接改用 low,不再先撞一次。 */
|
|
98
|
+
function markNoOff(route) {
|
|
99
|
+
if (noOffRoutes.has(route))
|
|
100
|
+
return;
|
|
101
|
+
if (!isRealProvider(route.split('/')[0] ?? ''))
|
|
102
|
+
return;
|
|
103
|
+
noOffRoutes.add(route);
|
|
104
|
+
if (leakyLoaded)
|
|
105
|
+
saveLeaky();
|
|
106
|
+
}
|
|
107
|
+
/** 档位阶梯与判据都在模块层(纯函数,可单测):这里只把清单数据喂给它。 */
|
|
108
|
+
function nextEffortFor(route, rejected, tried) {
|
|
109
|
+
const item = modelCache.items.find((entry) => `${entry.provider}/${entry.model}` === route);
|
|
110
|
+
return pickNextEffort((item?.efforts ?? []).map((effort) => effort.id), item?.defaultEffort, rejected, tried);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 规范档位(设置页那四格)→ 这个 route **这次真要发**的档位('' = 不带 reasoningEffort)。
|
|
114
|
+
*
|
|
115
|
+
* 每次请求都按**当前模型的声明**现算(不缓存映射结果、不落盘):用户换模型、DSH 升级换
|
|
116
|
+
* adapter 之后立刻跟着变。清单里查不到(还没加载过 / 那次调用失败)就原样发规范值 ——
|
|
117
|
+
* 与改动前一致,被拒时由换档重试兜;同时后台预热一次清单,下一次请求就能映射上。
|
|
118
|
+
* 模型明确不支持推理(hasReasoning === false)时不发档位:发了 dsh-llm 必拒。
|
|
119
|
+
*/
|
|
120
|
+
function effortForRoute(route, canonical) {
|
|
121
|
+
const item = modelCache.items.find((entry) => `${entry.provider}/${entry.model}` === route);
|
|
122
|
+
if (!item) {
|
|
123
|
+
warmModelCache();
|
|
124
|
+
return canonical;
|
|
125
|
+
}
|
|
126
|
+
if (item.hasReasoning === false)
|
|
127
|
+
return '';
|
|
128
|
+
const mapped = item.effortMap?.[canonical];
|
|
129
|
+
return mapped === undefined || mapped === '' ? canonical : mapped;
|
|
130
|
+
}
|
|
131
|
+
/** 清单预热:只在"真要用却还没读到"时拉一次,60 秒内不重复拉(失败也不打转)。 */
|
|
132
|
+
let modelWarmAt = 0;
|
|
133
|
+
function warmModelCache() {
|
|
134
|
+
if (modelCache.items.length > 0)
|
|
135
|
+
return;
|
|
136
|
+
if (Date.now() - modelWarmAt < MODEL_CACHE_MS)
|
|
137
|
+
return;
|
|
138
|
+
modelWarmAt = Date.now();
|
|
139
|
+
void listModelChoices(false).catch(() => undefined);
|
|
140
|
+
}
|
|
141
|
+
const MODEL_CACHE_MS = 60_000;
|
|
142
|
+
async function listModelChoices(force = false) {
|
|
143
|
+
if (!force && modelCache.items.length > 0 && Date.now() - modelCache.at < MODEL_CACHE_MS)
|
|
144
|
+
return modelCache.items;
|
|
145
|
+
const llm = ctx.get('llm');
|
|
146
|
+
const items = [];
|
|
147
|
+
const providers = llm?.listProviders?.() ?? [];
|
|
148
|
+
for (const provider of providers) {
|
|
149
|
+
if (!provider?.id || typeof llm?.listModels !== 'function')
|
|
150
|
+
continue;
|
|
151
|
+
let models = [];
|
|
152
|
+
try {
|
|
153
|
+
models = (await llm.listModels(provider.id)) ?? [];
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
models = [];
|
|
157
|
+
}
|
|
158
|
+
for (const model of models) {
|
|
159
|
+
if (!model?.id)
|
|
160
|
+
continue;
|
|
161
|
+
let efforts = [];
|
|
162
|
+
let defaultEffort = null;
|
|
163
|
+
// null = 没读到(调用失败 / 拿不到信息);true/false = 明确支持 / 不支持
|
|
164
|
+
let hasReasoning = null;
|
|
165
|
+
try {
|
|
166
|
+
let info = null;
|
|
167
|
+
if (typeof llm.resolveModelInfo === 'function') {
|
|
168
|
+
info = (await llm.resolveModelInfo(provider.id, model.id));
|
|
169
|
+
}
|
|
170
|
+
else if (typeof llm.resolveModel === 'function') {
|
|
171
|
+
info = (await llm.resolveModel(provider.id, model.id));
|
|
172
|
+
}
|
|
173
|
+
if (info) {
|
|
174
|
+
const list = info.reasoning?.efforts ?? [];
|
|
175
|
+
efforts = list
|
|
176
|
+
.filter((item) => typeof item?.id === 'string' && item.id.length > 0)
|
|
177
|
+
.map((item) => ({ id: String(item.id), name: String(item.name ?? item.id) }));
|
|
178
|
+
defaultEffort = typeof info.reasoning?.defaultEffort === 'string' ? info.reasoning.defaultEffort : null;
|
|
179
|
+
// 声明了 reasoning 但档位列表为空 → 发任何档位 dsh-llm 都会拒(它自己也不接受空表)
|
|
180
|
+
hasReasoning = efforts.length > 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
efforts = [];
|
|
185
|
+
}
|
|
186
|
+
items.push({
|
|
187
|
+
provider: provider.id,
|
|
188
|
+
providerName: String(provider.name ?? provider.id),
|
|
189
|
+
model: model.id,
|
|
190
|
+
name: String(model.name ?? model.id),
|
|
191
|
+
efforts,
|
|
192
|
+
defaultEffort,
|
|
193
|
+
hasReasoning,
|
|
194
|
+
effortMap: effortMapOf(efforts),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (items.length > 0)
|
|
199
|
+
modelCache = { at: Date.now(), items };
|
|
200
|
+
return items;
|
|
201
|
+
}
|
|
202
|
+
/** 请求里带 provider+model 时优先用它(并按清单校验;清单还没加载出来就只做形状校验)。 */
|
|
203
|
+
const resolveRoute = (override,
|
|
204
|
+
/**
|
|
205
|
+
* **当前会话**自己的模型选择(见 sessionModelOf)。
|
|
206
|
+
*
|
|
207
|
+
* 为什么要有它:会话是各自选模型的(每个 Agent 一份 model-selection),
|
|
208
|
+
* 而 `agentDefaultModel.currentSelection()` 是**全局默认**、与会话无关。
|
|
209
|
+
* 以前只用后者,于是"跟随主会话"其实跟的是"全局默认"——
|
|
210
|
+
* 两个会话用不同模型时,插件对两个会话都用同一个默认模型,跟谁都对不上。
|
|
211
|
+
*
|
|
212
|
+
* 优先级:显式 override(小窗胶囊选的)→ 插件配置(设置页选的)→ **本会话的模型** → 全局默认 → 第一个可用。
|
|
213
|
+
* 会话没记过选择(新会话、或日志里没有 model/selection)时自然落回全局默认,行为与以前一致。
|
|
214
|
+
*/
|
|
215
|
+
sessionModel,
|
|
216
|
+
/**
|
|
217
|
+
* 这一轮是不是**追问**。
|
|
218
|
+
*
|
|
219
|
+
* 三个阶段沿用同一模型;旧 chatProvider/chatModel 仅保留配置兼容,不再参与路由。
|
|
220
|
+
*/
|
|
221
|
+
chat) => {
|
|
222
|
+
if (override?.provider && override?.model) {
|
|
223
|
+
const wanted = { provider: override.provider, model: override.model };
|
|
224
|
+
const known = modelCache.items.some((item) => item.provider === wanted.provider && item.model === wanted.model);
|
|
225
|
+
if (known || modelCache.items.length === 0)
|
|
226
|
+
return wanted;
|
|
227
|
+
}
|
|
228
|
+
if (config.provider && config.model)
|
|
229
|
+
return { provider: config.provider, model: config.model };
|
|
230
|
+
if (sessionModel?.provider && sessionModel?.model) {
|
|
231
|
+
return { provider: sessionModel.provider, model: sessionModel.model };
|
|
232
|
+
}
|
|
233
|
+
const service = ctx.get('agentDefaultModel');
|
|
234
|
+
const selection = service?.currentSelection?.();
|
|
235
|
+
if (selection?.provider && selection?.model) {
|
|
236
|
+
return { provider: selection.provider, model: selection.model };
|
|
237
|
+
}
|
|
238
|
+
const llm = ctx.get('llm');
|
|
239
|
+
const first = llm?.listProviders?.()?.find((item) => (item.models?.length ?? 0) > 0);
|
|
240
|
+
if (first?.id && first.models?.[0]?.id)
|
|
241
|
+
return { provider: first.id, model: first.models[0].id };
|
|
242
|
+
return captured;
|
|
243
|
+
};
|
|
244
|
+
return { resolveRoute, loadLeaky, leakyOnOff, noOffRoutes, effortForRoute, nextEffortFor, markNoOff, markLeaky, listModelChoices, get modelCache() { return modelCache; }, MODEL_CACHE_MS };
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/host/models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { API_PREFIX, name } from './constants.js';
|
|
2
|
+
import { handleMic, stopMicProbe } from './mic.js';
|
|
3
|
+
import { resolveConfig } from './config.js';
|
|
4
|
+
import { createSpeech } from './speech.js';
|
|
5
|
+
import { createSettingsStore } from './settings-store.js';
|
|
6
|
+
import { createModels } from './models.js';
|
|
7
|
+
import { createAnalyze } from './analyze.js';
|
|
8
|
+
import { createSessions } from './sessions.js';
|
|
9
|
+
import { createHistoryStore } from './history-store.js';
|
|
10
|
+
import { createRoutes } from './routes.js';
|
|
11
|
+
import { createPromote } from './promote.js';
|
|
12
|
+
export function apply(ctx, rawConfig) {
|
|
13
|
+
const config = resolveConfig(rawConfig);
|
|
14
|
+
const speech = createSpeech(ctx, config);
|
|
15
|
+
const settingsStore = createSettingsStore(ctx, config);
|
|
16
|
+
const models = createModels(ctx, config);
|
|
17
|
+
const sessions = createSessions(ctx, config);
|
|
18
|
+
const historyStore = createHistoryStore(ctx, config, models, settingsStore);
|
|
19
|
+
const routes = createRoutes(ctx, config, historyStore, sessions, models, settingsStore);
|
|
20
|
+
const promote = createPromote(ctx, config, sessions, historyStore);
|
|
21
|
+
const analyze = createAnalyze(ctx, config, models, sessions, historyStore);
|
|
22
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/analyze`, handler: analyze.handleAnalyze }), `${name}: analyze route`);
|
|
23
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/settings`, handler: settingsStore.handleSettings }), `${name}: settings route`);
|
|
24
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/route`, handler: routes.handleRoute }), `${name}: route route`);
|
|
25
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/ping`, handler: routes.handlePing }), `${name}: ping route`);
|
|
26
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/history`, handler: historyStore.handleHistory }), `${name}: history route`);
|
|
27
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/panel`, handler: historyStore.handlePanelSize }), `${name}: panel box route`);
|
|
28
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/pill`, handler: historyStore.handlePillPos }), `${name}: pill position route`);
|
|
29
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/mic`, handler: handleMic }), `${name}: mic presence route`);
|
|
30
|
+
// 探针是懒启动的(第一次有人问才起),但**卸载时要收干净**:
|
|
31
|
+
// 否则插件热重载几次就会留下一串没人管的 mic-probe 进程。
|
|
32
|
+
ctx.effect(() => () => stopMicProbe(), `${name}: mic probe process`);
|
|
33
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/models`, handler: routes.handleModels }), `${name}: models route`);
|
|
34
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/promote`, handler: promote.handlePromote }), `${name}: promote route`);
|
|
35
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/quote-context`, handler: routes.handleQuoteContext }), `${name}: quote-context route`);
|
|
36
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/speech`, handler: speech.handleSpeech }), `${name}: speech catalog route`);
|
|
37
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/speech/transcribe`, handler: speech.handleSpeechTranscribe }), `${name}: speech transcribe route`);
|
|
38
|
+
ctx.effect(() => ctx.webServer.register({ kind: 'exact', path: `${API_PREFIX}/speech/prepare`, handler: speech.handleSpeechPrepare }), `${name}: speech prepare route`);
|
|
39
|
+
ctx.logger?.info?.(`[${name}] 划词解读路由就绪:${API_PREFIX}/analyze`);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/host/plugin.ts"],"names":[],"mappings":"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"}
|