@yfwu2020/dsh-selection-explain 0.10.3 → 0.10.5

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.
Files changed (119) hide show
  1. package/README.md +13 -11
  2. package/cordis.patch.yml +1 -1
  3. package/lib/client.js +10694 -12424
  4. package/lib/client.js.map +7 -0
  5. package/lib/config-values.js +55 -0
  6. package/lib/config-values.js.map +1 -0
  7. package/lib/host/analyze.js +795 -0
  8. package/lib/host/analyze.js.map +1 -0
  9. package/lib/host/config.js +81 -0
  10. package/lib/host/config.js.map +1 -0
  11. package/lib/host/constants.js +25 -0
  12. package/lib/host/constants.js.map +1 -0
  13. package/lib/host/context.js +237 -0
  14. package/lib/host/context.js.map +1 -0
  15. package/lib/host/design-skill.js +42 -0
  16. package/lib/host/design-skill.js.map +1 -0
  17. package/lib/host/effort.js +239 -0
  18. package/lib/host/effort.js.map +1 -0
  19. package/lib/host/filters.js +132 -0
  20. package/lib/host/filters.js.map +1 -0
  21. package/lib/host/history-store.js +404 -0
  22. package/lib/host/history-store.js.map +1 -0
  23. package/lib/host/http.js +46 -0
  24. package/lib/host/http.js.map +1 -0
  25. package/lib/host/messages.js +14 -0
  26. package/lib/host/messages.js.map +1 -0
  27. package/lib/host/mic.js +246 -0
  28. package/lib/host/mic.js.map +1 -0
  29. package/lib/host/models.js +246 -0
  30. package/lib/host/models.js.map +1 -0
  31. package/lib/host/plugin.js +41 -0
  32. package/lib/host/plugin.js.map +1 -0
  33. package/lib/host/promote.js +219 -0
  34. package/lib/host/promote.js.map +1 -0
  35. package/lib/host/routes.js +237 -0
  36. package/lib/host/routes.js.map +1 -0
  37. package/lib/host/sessions.js +181 -0
  38. package/lib/host/sessions.js.map +1 -0
  39. package/lib/host/settings-store.js +140 -0
  40. package/lib/host/settings-store.js.map +1 -0
  41. package/lib/host/speech.js +320 -0
  42. package/lib/host/speech.js.map +1 -0
  43. package/lib/host/tools.js +179 -0
  44. package/lib/host/tools.js.map +1 -0
  45. package/lib/host/types.js +2 -0
  46. package/lib/host/types.js.map +1 -0
  47. package/lib/index.js +10 -3691
  48. package/lib/index.js.map +1 -1
  49. package/lib/prompts.js +1 -1
  50. package/lib/settings.js +17 -27
  51. package/lib/settings.js.map +1 -1
  52. package/lib/types/config-values.d.ts +175 -0
  53. package/lib/types/host/analyze.d.ts +10 -0
  54. package/lib/types/host/config.d.ts +147 -0
  55. package/lib/types/host/constants.d.ts +24 -0
  56. package/lib/types/host/context.d.ts +41 -0
  57. package/lib/types/host/design-skill.d.ts +1 -0
  58. package/lib/types/host/effort.d.ts +61 -0
  59. package/lib/types/host/filters.d.ts +20 -0
  60. package/lib/types/host/history-store.d.ts +13 -0
  61. package/lib/types/host/http.d.ts +8 -0
  62. package/lib/types/host/messages.d.ts +13 -0
  63. package/lib/types/host/mic.d.ts +17 -0
  64. package/lib/types/host/models.d.ts +57 -0
  65. package/lib/types/host/plugin.d.ts +3 -0
  66. package/lib/types/host/promote.d.ts +9 -0
  67. package/lib/types/host/routes.d.ts +14 -0
  68. package/lib/types/host/sessions.d.ts +14 -0
  69. package/lib/types/host/settings-store.d.ts +8 -0
  70. package/lib/types/host/speech.d.ts +23 -0
  71. package/lib/types/host/tools.d.ts +39 -0
  72. package/lib/types/host/types.d.ts +89 -0
  73. package/lib/types/index.d.ts +12 -441
  74. package/lib/types/prompts.d.ts +1 -1
  75. package/lib/types/settings.d.ts +1 -1
  76. package/package.json +31 -21
  77. package/assets/code.png +0 -0
  78. package/assets/detail.png +0 -0
  79. package/assets/quotes.png +0 -0
  80. package/assets/stage1.png +0 -0
  81. package/assets/stage2.png +0 -0
  82. package/assets/translation.png +0 -0
  83. package/assets/voice-card-light.png +0 -0
  84. package/assets/voice-inserted.png +0 -0
  85. package/assets/voice-settings.png +0 -0
  86. package/assets/voice.png +0 -0
  87. package/assets/web.png +0 -0
  88. package/scripts/build-demo-pages.mjs +0 -350
  89. package/scripts/build-vcard-lab.mjs +0 -834
  90. package/scripts/build.sh +0 -147
  91. package/scripts/crop-png.mjs +0 -142
  92. package/scripts/dump-prompt.mjs +0 -143
  93. package/scripts/fixtures/fake-mic-probe.sh +0 -9
  94. package/scripts/gen-star-path.mjs +0 -71
  95. package/scripts/measure-cost.mjs +0 -251
  96. package/scripts/smoke-bridge.mjs +0 -365
  97. package/scripts/smoke-panel.mjs +0 -1903
  98. package/scripts/smoke-voice.mjs +0 -774
  99. package/scripts/test-bridge.mjs +0 -412
  100. package/scripts/test-client.mjs +0 -6175
  101. package/scripts/test-effort-map.mjs +0 -129
  102. package/scripts/test-effort-retry.mjs +0 -109
  103. package/scripts/test-escape-focus.mjs +0 -101
  104. package/scripts/test-filters.mjs +0 -146
  105. package/scripts/test-format.mjs +0 -93
  106. package/scripts/test-guard.mjs +0 -48
  107. package/scripts/test-mic-idle.mjs +0 -158
  108. package/scripts/test-model-follow.mjs +0 -193
  109. package/scripts/test-prompt.mjs +0 -193
  110. package/scripts/test-route-cache.mjs +0 -138
  111. package/scripts/test-settings-behavior.mjs +0 -188
  112. package/scripts/test-settings-host.mjs +0 -48
  113. package/scripts/test-settings.mjs +0 -329
  114. package/scripts/test-speech.mjs +0 -220
  115. package/scripts/test-transcript.mjs +0 -151
  116. package/src/client/index.js +0 -12580
  117. package/src/index.ts +0 -4179
  118. package/src/prompts.ts +0 -144
  119. package/src/settings.ts +0 -313
@@ -0,0 +1,219 @@
1
+ import { sendJson, readBody, BODY_LIMIT } from './http.js';
2
+ import { sessionIdOf } from './context.js';
3
+ import { name, PLUGIN_SOURCE_KIND } from './constants.js';
4
+ /** Owns promote state for one plugin instance. */
5
+ export function createPromote(ctx, config, sessions, historyStore) {
6
+ /**
7
+ * 把划词解读小窗「升格」成正式会话(建在来源会话同一个项目下):
8
+ * ① 建会话 → ② 注入上下文消息(选中文字/所在位置/上下文片段,生产者自有 kind 的 context 消息)
9
+ * → ③ 把首轮解读写成助手消息 → ④ 把追问逐轮写成真实的 user/assistant 历史消息
10
+ * → ⑤ 送一条短开场消息让 agent 接手(这样整段历史才会落盘)。
11
+ * 这样新会话里看到的就是一段真实的多轮对话,而不是一大坨打包文本。
12
+ * live 会话对象拿不到时,退回「打包成一条消息」的老路径,保证升格不会整体失败。
13
+ */
14
+ const handlePromote = async (req, res) => {
15
+ if (req.method !== 'POST') {
16
+ sendJson(res, 405, { error: '只支持 POST' });
17
+ return;
18
+ }
19
+ let body;
20
+ try {
21
+ body = JSON.parse(await readBody(req, BODY_LIMIT));
22
+ }
23
+ catch (error) {
24
+ sendJson(res, 400, { error: `请求体解析失败:${String(error?.message ?? error)}` });
25
+ return;
26
+ }
27
+ const text = typeof body.text === 'string' ? body.text.trim() : '';
28
+ if (!text) {
29
+ sendJson(res, 400, { error: '缺少 text(选中文字)' });
30
+ return;
31
+ }
32
+ const controller = ctx.get('sessionController');
33
+ if (typeof controller?.create !== 'function' || typeof controller?.prompt !== 'function') {
34
+ sendJson(res, 503, { error: '当前部署不支持创建会话(sessionController 不可用)' });
35
+ return;
36
+ }
37
+ const sourceSessionId = sessionIdOf(body);
38
+ const cwd = await sessions.resolveSessionCwd(sourceSessionId);
39
+ // 会话在侧栏里的「项目分组」= workspace 的 sessionIds(按 canonical cwd 索引)。
40
+ // 只传 cwd 不够:还要带上 workspaceId,并在建好后把它挂到该 workspace 上(双保险)。
41
+ const registry = ctx.get('workspaceRegistry');
42
+ let workspaceId;
43
+ if (cwd) {
44
+ try {
45
+ const workspace = await registry?.resolveByPath?.(cwd);
46
+ if (typeof workspace?.id === 'string')
47
+ workspaceId = workspace.id;
48
+ }
49
+ catch (error) {
50
+ ctx.logger?.warn?.(`[${name}] 解析 workspace 失败(${cwd}):${String(error?.message ?? error)}`);
51
+ }
52
+ }
53
+ try {
54
+ // 注意:session.create 的 workspaceId 与 cwd 互斥(同时传会报
55
+ // "session.create accepts workspaceId or cwd, not both")——有 workspace 就只传它
56
+ const created = await controller.create(workspaceId ? { workspaceId } : cwd ? { cwd } : {});
57
+ const newSessionId = typeof created?.sessionId === 'string' ? created.sessionId : '';
58
+ if (!newSessionId) {
59
+ sendJson(res, 500, { error: '创建会话失败:未返回会话 id' });
60
+ return;
61
+ }
62
+ // 兜底:若 cwd 索引还没把它算进该 workspace,显式 attach 一次
63
+ if (workspaceId) {
64
+ try {
65
+ const workspace = registry?.get?.(workspaceId);
66
+ if (workspace && !(workspace.sessionIds ?? []).includes(newSessionId)) {
67
+ await workspace.attachSession?.(newSessionId);
68
+ }
69
+ }
70
+ catch (error) {
71
+ ctx.logger?.warn?.(`[${name}] 挂载会话到 workspace 失败:${String(error?.message ?? error)}`);
72
+ }
73
+ }
74
+ const title = `划词解读:${text.replace(/\s+/g, ' ').slice(0, 24)}`;
75
+ try {
76
+ await controller.rename?.({ sessionId: newSessionId, title });
77
+ }
78
+ catch {
79
+ /* 标题失败不影响升格 */
80
+ }
81
+ const label = historyStore.clampText(body.label, 80) || '页面内容';
82
+ const contextText = historyStore.clampText(body.context, config.maxContextChars) || '(未记录)';
83
+ const translation = historyStore.clampText(body.translation, 8000);
84
+ const detail = historyStore.clampText(body.detail, 12000);
85
+ const turns = (Array.isArray(body.turns) ? body.turns : [])
86
+ .slice(-20)
87
+ .map((turn) => turn)
88
+ .filter((turn) => turn.seed !== true && typeof turn.text === 'string' && turn.text.trim().length > 0)
89
+ .map((turn) => ({ role: turn.role === 'assistant' ? 'assistant' : 'user', text: turn.text.trim() }));
90
+ const live = ctx.get('sessions')?.get?.(newSessionId);
91
+ let seeded = false;
92
+ if (live && typeof live.append === 'function') {
93
+ const stamp = Date.now().toString(36);
94
+ /**
95
+ * 把一轮写进日志:turn/start → step/start → 消息 → step/end → turn/end。
96
+ * ⚠️ 必须带这层骨架:客户端会话视图是按 turn/step 事件给消息定位的,
97
+ * 裸写 user/message、assistant/message 会因为拿不到坐标而不显示成历史对话。
98
+ */
99
+ // 轮号从 1000 起:客户端按「轮号」分组(Map<number>),而新建会话里 agent 的第一轮
100
+ // 一定从 1 开始(phase.turn 初始为 0),所以历史轮必须避开低位号段,
101
+ // 否则历史的 turn 1 会和真实的 turn 1 并成同一组、看起来"历史没进去"。
102
+ // 同时这也是 resume 语义安全的:resume 时 phase.turn = lastTurn + 1 = 1000+N+1,仍不与历史重号。
103
+ let turnNo = 1000;
104
+ const appendTurn = (userEvent, assistantText) => {
105
+ turnNo += 1;
106
+ const turn = turnNo;
107
+ live.append?.('turn/start', { turn });
108
+ live.append?.('step/start', { turn, step: 1 });
109
+ if (userEvent)
110
+ live.append?.('user/message', userEvent, { surfaceOp: 'append' });
111
+ live.append?.('assistant/message', {
112
+ turn,
113
+ step: 1,
114
+ stream: [],
115
+ message: {
116
+ id: `sel-a-${stamp}-${turn}`,
117
+ role: 'assistant',
118
+ source: { kind: 'model', provider: 'dsh-selection-explain', model: '划词解读小窗' },
119
+ content: [{ type: 'text', text: assistantText }],
120
+ },
121
+ }, { surfaceOp: 'append' });
122
+ live.append?.('step/end', { turn, step: 1 });
123
+ live.append?.('turn/end', { turn, reason: { kind: 'completed' } });
124
+ };
125
+ // 第 1 轮:上下文消息(生产者自有的 source.kind + snapshot 呈现)+ 首轮解读
126
+ // ⚠️ kind 必须是 PLUGIN_SOURCE_KIND(`plugin:<插件名>`):会话格式 v4 起不再
127
+ // 接受退役的 `plugin` 包装(`kind: 'plugin'` 加一个 `plugin` 字段),否则整场升格
128
+ // 会死在 "format v4 message requires a producer-owned source kind" 上(见文件头常量注释)。
129
+ const contextBody = [
130
+ `选中文字:${text}`,
131
+ `所在位置:${label}`,
132
+ `来源:划词解读小窗${sourceSessionId ? `(来源会话 ${sourceSessionId})` : ''}`,
133
+ '',
134
+ '选中处的上下文片段:',
135
+ contextText,
136
+ ].join('\n');
137
+ const explanation = ['翻译', translation || '(未记录)', '', '详解', detail || '(未记录)'].join('\n');
138
+ appendTurn({
139
+ id: `sel-ctx-${stamp}`,
140
+ role: 'user',
141
+ source: {
142
+ kind: PLUGIN_SOURCE_KIND,
143
+ form: 'snapshot',
144
+ sections: [
145
+ { name: '划词解读 · 选中文字', text },
146
+ { name: '划词解读 · 所在位置', text: label },
147
+ { name: '划词解读 · 上下文片段', text: contextText },
148
+ ],
149
+ },
150
+ content: [{ type: 'text', text: contextBody }],
151
+ }, explanation);
152
+ // 后续轮:小窗里的追问逐轮写成真实问答
153
+ for (let i = 0; i < turns.length; i += 1) {
154
+ const turn = turns[i];
155
+ if (!turn)
156
+ continue;
157
+ if (turn.role === 'user') {
158
+ appendTurn({
159
+ id: `sel-u-${stamp}-${i}`,
160
+ role: 'user',
161
+ source: { kind: 'user' },
162
+ content: [{ type: 'text', text: turn.text }],
163
+ }, turns[i + 1] && turns[i + 1]?.role === 'assistant' ? (turns[i + 1]?.text ?? '') : '(未记录)');
164
+ i += 1; // 助手回答已随本轮写入
165
+ }
166
+ else {
167
+ // 落单的助手消息(历史里没有对应提问):单独成一轮
168
+ appendTurn(null, turn.text);
169
+ }
170
+ }
171
+ seeded = true;
172
+ }
173
+ // ⑤ 开场消息:让 agent 接手(也是整段历史落盘的触发点)
174
+ const opener = seeded
175
+ ? '(本会话由划词解读小窗升格而来,以上是这段文字的上下文与我们的讨论)请用一句话确认,然后等我继续提问。'
176
+ : [
177
+ '【划词解读 · 升格为会话】',
178
+ '下面这段文字来自一次划词解读小窗;上下文、结论与小窗里的追问一并附上,作为本次会话的既有背景。',
179
+ '',
180
+ '■ 选中文字',
181
+ text,
182
+ '',
183
+ '■ 所在位置',
184
+ label,
185
+ '',
186
+ '■ 选中处的上下文片段',
187
+ contextText,
188
+ '',
189
+ '■ 解读 · 翻译',
190
+ translation || '(未记录)',
191
+ '',
192
+ '■ 解读 · 详解',
193
+ detail || '(未记录)',
194
+ ...(turns.length > 0 ? ['', '■ 小窗里的追问', ...turns.map((t) => `${t.role === 'assistant' ? '答' : '我问'}:${t.text}`)] : []),
195
+ '',
196
+ '以上是背景,请把它作为本次会话的既有上下文;先不需要展开,等我继续提问。',
197
+ ].join('\n');
198
+ const promoteController = new AbortController();
199
+ await controller.prompt({
200
+ requestId: `sel-promote-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
201
+ sessionId: newSessionId,
202
+ mode: 'queue',
203
+ content: [{ type: 'text', text: opener }],
204
+ }, promoteController.signal);
205
+ sendJson(res, 200, {
206
+ ok: true,
207
+ sessionId: newSessionId,
208
+ cwd: cwd ?? null,
209
+ workspaceId: workspaceId ?? null,
210
+ mode: seeded ? 'history' : 'packed',
211
+ });
212
+ }
213
+ catch (error) {
214
+ sendJson(res, 500, { error: `升格失败:${String(error?.message ?? error)}` });
215
+ }
216
+ };
217
+ return { handlePromote };
218
+ }
219
+ //# sourceMappingURL=promote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promote.js","sourceRoot":"","sources":["../../src/host/promote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,237 @@
1
+ import { sendJson, readBody } from './http.js';
2
+ import { quoteContextOf } from './context.js';
3
+ import { webFetchUsable } from './tools.js';
4
+ import { name, API_PREFIX } from './constants.js';
5
+ /** Owns routes state for one plugin instance. */
6
+ export function createRoutes(ctx, config, historyStore, sessions, models, settingsStore) {
7
+ /**
8
+ * 引用上下文:客户端点了「❝ 引用」之后,拿引用文字来换它所在的那一组对话 ± 一组。
9
+ *
10
+ * 为什么走 host 而不是客户端读 DOM:会话正文的**干净文本**只有 host 这边有
11
+ * (`readSurface` 的事件流里工具调用/结果、系统提示、harness 注入全都被 `transcriptOf`
12
+ * 那套规则滤掉过)。客户端 DOM 里读到的会是"渲染后的样子"——思考块、工具卡片、
13
+ * 按钮文案全混在里面。定位不到(引用来自侧边栏网页/文档预览)就返回 matched:false,
14
+ * 客户端退回它自己采的局部上下文。
15
+ */
16
+ const handleQuoteContext = (req, res) => {
17
+ void (async () => {
18
+ if (req.method !== 'POST') {
19
+ sendJson(res, 405, { ok: false, error: '只支持 POST' });
20
+ return;
21
+ }
22
+ const raw = await readBody(req, 200_000);
23
+ let body = {};
24
+ try {
25
+ body = raw ? JSON.parse(raw) : {};
26
+ }
27
+ catch {
28
+ sendJson(res, 400, { ok: false, error: '请求体不是合法 JSON' });
29
+ return;
30
+ }
31
+ const sessionId = typeof body.sessionId === 'string' ? body.sessionId.trim() : '';
32
+ const text = historyStore.clampText(body.text, config.maxSelectionChars);
33
+ if (!sessionId || !text.trim()) {
34
+ sendJson(res, 200, { ok: true, matched: false, context: '', rounds: 0 });
35
+ return;
36
+ }
37
+ const events = await sessions.readSurfaceEvents(sessionId);
38
+ const context = quoteContextOf(events, text, {
39
+ roundsAround: config.quoteContextRounds,
40
+ maxCharsPerTurn: config.quoteContextMaxCharsPerTurn,
41
+ maxChars: config.quoteContextMaxChars,
42
+ });
43
+ sendJson(res, 200, {
44
+ ok: true,
45
+ matched: context.matched,
46
+ context: context.transcript,
47
+ rounds: context.rounds,
48
+ chars: context.transcript.length,
49
+ });
50
+ })().catch((error) => {
51
+ sendJson(res, 500, { ok: false, error: String(error?.message ?? error) });
52
+ });
53
+ };
54
+ /** GET /models:给「模型」菜单用(带每个模型支持的推理等级;60 秒缓存)。 */
55
+ async function handleModels(req, res) {
56
+ await models.loadLeaky(); // 不 await 的话,这条路由在读"关档会泄漏"的清单时文件还没载入(实测报空)
57
+ const url = new URL(req.url ?? '/', 'http://localhost');
58
+ const force = url.searchParams.get('refresh') === '1';
59
+ let items = [];
60
+ let error = '';
61
+ try {
62
+ items = await models.listModelChoices(force);
63
+ }
64
+ catch (thrown) {
65
+ error = String(thrown?.message ?? thrown);
66
+ }
67
+ // 会话级:设置页的「跟随主会话」要显示**当前会话**在用的模型
68
+ let modelsSessionId = '';
69
+ try {
70
+ modelsSessionId = url.searchParams.get('sessionId') ?? '';
71
+ }
72
+ catch {
73
+ /* 解析不了就当没带 */
74
+ }
75
+ const current = models.resolveRoute(undefined, await sessions.sessionModelOf(modelsSessionId));
76
+ sendJson(res, 200, {
77
+ ok: true,
78
+ current,
79
+ cached: Date.now() - models.modelCache.at < models.MODEL_CACHE_MS,
80
+ ...(error ? { error } : {}),
81
+ models: items,
82
+ // 进程内学到的"关档会把思考写进正文"的模型(客户端据此在菜单里标注;重启后由客户端本地记忆兜着)
83
+ leakyOff: Array.from(models.leakyOnOff),
84
+ // 前端按 provider+model 匹配"当前档"
85
+ stages: {
86
+ chat: config.chatReasoningEffort || config.reasoningEffort,
87
+ translation: config.translationReasoningEffort || config.reasoningEffort,
88
+ detail: config.reasoningEffort,
89
+ },
90
+ });
91
+ }
92
+ /**
93
+ * 极轻的"这一轮会用哪个模型"查询。
94
+ *
95
+ * GET /selection-explain/api/route?sessionId=…[&chat=1]
96
+ *
97
+ * 为什么单开一条:设置页要**实时**显示当前会话在用的模型,
98
+ * 而 /models 会去列 provider 与模型(42 个,还要端点发现)、/ping 要枚举工具表并探 DNS ——
99
+ * 两者都不适合按秒轮询。这条只做一次会话模型解析 + 一次 resolveRoute。
100
+ *
101
+ * 也是唯一走 `sessionModelOf(…, true)`(短缓存)的地方:客户端在小窗开着时每 2 秒问一次,
102
+ * 不能每拍都重放一次会话日志(见 sessionModelCache 的注释)。
103
+ */
104
+ const handleRoute = (req, res) => {
105
+ void (async () => {
106
+ await settingsStore.loadSettings();
107
+ let sessionId = '';
108
+ let chat = false;
109
+ try {
110
+ const url = new URL(req.url ?? '/', 'http://localhost');
111
+ sessionId = url.searchParams.get('sessionId') ?? '';
112
+ chat = url.searchParams.get('chat') === '1';
113
+ }
114
+ catch {
115
+ /* 解析不了就当没带 */
116
+ }
117
+ const route = models.resolveRoute(undefined, await sessions.sessionModelOf(sessionId, true), chat);
118
+ sendJson(res, 200, {
119
+ ok: true,
120
+ provider: route?.provider ?? '',
121
+ model: route?.model ?? '',
122
+ // 是不是"跟首轮/次轮同一个":客户端据此把追问下拉显示成「跟随首轮 / 次轮」
123
+ chatFollows: true,
124
+ });
125
+ })().catch((error) => {
126
+ sendJson(res, 500, { ok: false, error: String(error?.message ?? error) });
127
+ });
128
+ };
129
+ const handlePing = (req, res) => {
130
+ const sessionQuery = ctx.get('sessionQuery');
131
+ // 可以带 ?sessionId=xxx:工具是**按会话作用域**注册的,不带 id 只能看到全局视图(里面没有 web_search)
132
+ let pingSessionId = '';
133
+ try {
134
+ pingSessionId = new URL(req.url ?? '/', 'http://localhost').searchParams.get('sessionId') ?? '';
135
+ }
136
+ catch {
137
+ /* 解析不了就当没带 */
138
+ }
139
+ // 小窗能调哪些工具:白名单是配置,实际放行还要看本机能不能抓网页(见下)。
140
+ // 用 async 包一层:探测 DNS 是异步的,出错也要给出结构化响应(和 history 路由同一写法)。
141
+ void (async () => {
142
+ // 先把用户改过的设置套上:下面报的每一条都必须是**当前生效**的值
143
+ await settingsStore.loadSettings();
144
+ const whitelist = config.toolNames
145
+ .split(',')
146
+ .map((item) => item.trim())
147
+ .filter((item) => item.length > 0);
148
+ const agents = ctx.get('agents');
149
+ // 复刻 handleAnalyze 的作用域回退:本会话 agent 取不到就用任一活跃 agent
150
+ let pingAgent = pingSessionId ? agents?.get?.(pingSessionId) : undefined;
151
+ let pingScope = pingAgent ? 'session' : '';
152
+ if (!pingAgent) {
153
+ pingAgent = agents?.list?.()?.[0];
154
+ pingScope = pingAgent ? 'fallback' : 'global';
155
+ }
156
+ let visible = [];
157
+ let visibleError = '';
158
+ let toolInfo = [];
159
+ let toolNames = [];
160
+ let sessionToolCount = 0;
161
+ try {
162
+ // 必须带着 registry 调(`const f = registry.schemas; f(...)` 会把 this 丢掉 → 拿到空表)
163
+ const registry = ctx.get('tools');
164
+ const all = registry?.schemas?.(pingAgent) ?? [];
165
+ sessionToolCount = all.length;
166
+ visible = all.map((schema) => schema.name).filter((toolName) => whitelist.includes(toolName));
167
+ // 诊断用:会话里这几个工具到底是哪个插件提供的(描述前 70 字能认出来)
168
+ toolInfo = all.map((schema) => ({
169
+ name: schema.name,
170
+ desc: String(schema.description ?? '').replace(/\s+/g, ' ').slice(0, 70),
171
+ }));
172
+ toolNames = all.map((schema) => schema.name);
173
+ }
174
+ catch (error) {
175
+ visibleError = String(error?.message ?? error);
176
+ }
177
+ // 本机抓不了网页时 web_fetch 会被摘掉(探针缓存 5 分钟,这里复用同一个)
178
+ let fetchBlocked = '';
179
+ if (whitelist.includes('web_fetch')) {
180
+ const probe = await webFetchUsable();
181
+ if (!probe.usable)
182
+ fetchBlocked = probe.sample;
183
+ }
184
+ sendJson(res, 200, {
185
+ ok: true,
186
+ plugin: name,
187
+ route: models.resolveRoute(undefined, await sessions.sessionModelOf(pingSessionId)),
188
+ reasoningEffort: config.reasoningEffort,
189
+ modelsRoute: `${API_PREFIX}/models`,
190
+ history: { maxEntries: config.historyMaxEntries, file: historyStore.historyFile() },
191
+ // 三档分开报:一眼看出"首轮为什么快、详解为什么慢"
192
+ reasoningEffortByStage: {
193
+ translation: config.translationReasoningEffort,
194
+ detail: config.reasoningEffort,
195
+ chat: config.chatReasoningEffort,
196
+ },
197
+ // 小窗能用哪些工具:whitelist=配置允许,offered=这一轮真会交给模型的
198
+ tools: {
199
+ enabled: config.tools && config.maxToolRounds > 0,
200
+ whitelist,
201
+ offered: visible.filter((toolName) => !(toolName === 'web_fetch' && fetchBlocked)),
202
+ // 文件类工具的读取边界:'' = 会话工作目录,'*' = 不限制
203
+ readRoot: config.toolReadRoot === '*' ? '(不限)' : config.toolReadRoot || '(会话工作目录)',
204
+ visible: visibleError ? '读取工具表失败:' + visibleError : visible.length,
205
+ // 备用联网工具是否启用(没装 free-search 时会补上 web_search)
206
+ fallback: config.fallbackToolNames,
207
+ preferredSearchPresent: visible.includes('advanced_search') || visible.includes('platform_search'),
208
+ toolInfo,
209
+ toolNames,
210
+ // 这个会话一共能看到多少工具(放行的是白名单里那几个,其余一律不可用)
211
+ sessionTools: sessionToolCount,
212
+ scope: pingScope,
213
+ maxRounds: config.maxToolRounds,
214
+ fetchBlocked,
215
+ },
216
+ sessionContext: config.sessionContext && typeof sessionQuery?.readSurface === 'function',
217
+ // 侧边栏 HTML 预览里的划词桥开关:客户端据此决定要不要往预览帧注入桥脚本
218
+ bridgeSidebarPreview: config.bridgeSidebarPreview,
219
+ // 悬浮胶囊的两个偏好:跟着 ping 一起下发,省得客户端为它单开一次请求
220
+ pill: { enabled: config.pillEnabled, idleMs: config.pillIdleMs },
221
+ limits: {
222
+ maxSelectionChars: config.maxSelectionChars,
223
+ maxContextChars: config.maxContextChars,
224
+ sessionContextMaxMessages: config.sessionContextMaxMessages,
225
+ sessionContextFastMessages: config.sessionContextFastMessages,
226
+ sessionContextMaxChars: config.sessionContextMaxChars,
227
+ quoteContextRounds: config.quoteContextRounds,
228
+ quoteContextMaxChars: config.quoteContextMaxChars,
229
+ },
230
+ });
231
+ })().catch((error) => {
232
+ sendJson(res, 500, { ok: false, error: String(error?.message ?? error) });
233
+ });
234
+ };
235
+ return { handleRoute, handlePing, handleModels, handleQuoteContext };
236
+ }
237
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/host/routes.ts"],"names":[],"mappings":"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"}