@alanzhao/dsh-memory-lite 0.1.1 → 0.2.1
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 +9 -4
- package/cordis.patch.yml +1 -1
- package/lib/catalog.js +2 -1
- package/lib/catalog.js.map +1 -1
- package/lib/client.js +114 -42
- package/lib/config.d.ts +6 -2
- package/lib/config.js +16 -2
- package/lib/config.js.map +1 -1
- package/lib/extract/index.d.ts +7 -1
- package/lib/extract/index.js +11 -3
- package/lib/extract/index.js.map +1 -1
- package/lib/extract/window.d.ts +17 -3
- package/lib/extract/window.js +29 -4
- package/lib/extract/window.js.map +1 -1
- package/lib/index.js +140 -6
- package/lib/index.js.map +1 -1
- package/lib/memory-store.d.ts +26 -2
- package/lib/memory-store.js +42 -2
- package/lib/memory-store.js.map +1 -1
- package/lib/peer.d.ts +7 -0
- package/lib/peer.js +9 -0
- package/lib/peer.js.map +1 -1
- package/package.json +28 -15
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ Design: [《Light Memory for DSH 设计方案》](https://github.com/deepseek-ai
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
+
> **Requires dsh ≥ 0.1.5.** v0.2.0 migrated the plugin RPC channels to the `/api` shared Fetch-route registry (`connection.fetch.register`); `connection.rpc.handle` is unusable for third-party plugins since 0.1.3-alpha.2 (official issue #5926, unfixed on master).
|
|
12
|
+
|
|
11
13
|
Install into a profile and add it to that profile's bundle list:
|
|
12
14
|
|
|
13
15
|
```sh
|
|
@@ -19,7 +21,7 @@ or, for a local checkout, add a linked dependency and bundle:
|
|
|
19
21
|
```jsonc
|
|
20
22
|
// $DSH_HOME/profiles/web/package.json
|
|
21
23
|
{
|
|
22
|
-
"dependencies": { "@alanzhao/dsh-memory-lite": "^0.
|
|
24
|
+
"dependencies": { "@alanzhao/dsh-memory-lite": "^0.2.0" },
|
|
23
25
|
"dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@alanzhao/dsh-memory-lite"] } }
|
|
24
26
|
}
|
|
25
27
|
```
|
|
@@ -34,12 +36,14 @@ The plugin row in `cordis.patch.yml` carries **no configuration** (mount only);
|
|
|
34
36
|
|
|
35
37
|
```yaml
|
|
36
38
|
- id: memory-lite
|
|
37
|
-
name: @alanzhao/dsh-memory-lite
|
|
39
|
+
name: "@alanzhao/dsh-memory-lite"
|
|
38
40
|
# config: # optional deployment defaults; settings override
|
|
39
41
|
# root: '~/.agent-memory'
|
|
40
42
|
# defaultPeer: dsh-web
|
|
41
43
|
# extraction:
|
|
42
44
|
# mode: incremental
|
|
45
|
+
# windowTurns: 50
|
|
46
|
+
# messageScope: [user, assistant] # count/feed only conversation turns
|
|
43
47
|
# turnStoppingTrigger: false
|
|
44
48
|
# flushTrigger: false
|
|
45
49
|
# sharing:
|
|
@@ -85,11 +89,12 @@ Each memory file uses `## Current` / `## History` / `## Related` sections; updat
|
|
|
85
89
|
|
|
86
90
|
- **L0 catalog injection** (`agent/pre-step` waterfall, copied from `@deepseek-ai/dsh-tool-skill`): the peer's `_index.md` is rendered into one durable `user/message` with a typed `memory-catalog` source and re-published when the index changes or compaction moves it off the visible surface. A fresh empty index publishes nothing (unless sharing mounts are enabled — then only the `## shared` hint is published). Subagent sessions get no catalog.
|
|
87
91
|
- **Peer isolation**: each session's cwd derives its peer name (sanitized basename + short hash); cwd-less sessions fall back to `defaultPeer`.
|
|
92
|
+
- **Peer display names**: Chinese and other non-ASCII workspace directories collapse to hash-suffixed ASCII names (e.g. `workspace-aad65ea5`). The plugin records a human-readable `.peer-meta.json` (`displayName`, e.g. 健康分析) per peer the first time a session with that cwd is seen; the sharing settings list shows `健康分析 (workspace-aad65ea5)`.
|
|
88
93
|
- **Path safety**: every file access goes through a containment boundary — relative paths only, `..` / absolute / symlink escapes rejected at the executor.
|
|
89
|
-
- **Implicit extraction** (Phase 2): once `windowTurns` (default
|
|
94
|
+
- **Implicit extraction** (Phase 2): once `windowTurns` (default 50) new in-scope conversation messages accumulate — or after `idleTimeoutMin` (default 30 min) of idle — a background run feeds the new window to the LLM and applies a create/merge/update/skip decision (dedup against existing memories), then advances a per-session checkpoint and rolling digest. Turn-boundary and flush triggers are shipped but disabled by config (cost); subagent sessions are never extracted. Only `messageScope` event kinds count toward the trigger and enter the window (default `['user','assistant']`; raw tool results excluded — their output adds token cost and noise while the assistant message already carries the interpretation). Audit trails live in `peers/{peer}/sessions/`.
|
|
90
95
|
- **Cross-peer sharing** (Phase 3): `sharing.mounts` expose another peer's memories read-only at `shared/<name>/...`; `search_memory` covers shared mounts and results keep the `shared/<name>` prefix. Shared entries stay out of the local catalog.
|
|
91
96
|
- **Concurrent writes**: all mutations run through a serial queue with atomic tmp+rename replacement.
|
|
92
|
-
- **Header status indicator** (browser half, `lib/client.js`): a compact "memory-lite" capsule in the session-header utilities row, left of the built-in "
|
|
97
|
+
- **Header status indicator** (browser half, `lib/client.js`): a compact "memory-lite" capsule in the session-header utilities row, left of the built-in "open workspace" split button (order -20 vs the button's -10). The dot polls the `/api/memory-status/snapshot` RPC channel every 10s — green (last extraction run ok), red (last run failed or the plugin is unreachable), gray (extraction mode off / explicit_only). No data yet is green.
|
|
93
98
|
|
|
94
99
|
## Model Experience
|
|
95
100
|
|
package/cordis.patch.yml
CHANGED
package/lib/catalog.js
CHANGED
|
@@ -86,7 +86,8 @@ export function readCatalogEntries(source) {
|
|
|
86
86
|
*/
|
|
87
87
|
export function catalogHistory(agent) {
|
|
88
88
|
const visible = new Set(agent.session.surface.nodes);
|
|
89
|
-
const
|
|
89
|
+
const sessionAny = agent.session;
|
|
90
|
+
const events = sessionAny.snapshotEvents !== undefined ? sessionAny.snapshotEvents() : (sessionAny.events ?? []);
|
|
90
91
|
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
91
92
|
// The loop bound proves the read-only event view contains this index.
|
|
92
93
|
const event = events[index];
|
package/lib/catalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
package/lib/client.js
CHANGED
|
@@ -59,7 +59,7 @@ window.__ModuleLoader__.load({
|
|
|
59
59
|
|
|
60
60
|
const tick = useCallback(async () => {
|
|
61
61
|
try {
|
|
62
|
-
const result = await connection.rpc.call('/
|
|
62
|
+
const result = await connection.rpc.call('/api', 'memory-status/snapshot', {});
|
|
63
63
|
if (result && result.ok && result.value) {
|
|
64
64
|
setSnap(result.value);
|
|
65
65
|
setDown(false);
|
|
@@ -136,7 +136,8 @@ window.__ModuleLoader__.load({
|
|
|
136
136
|
{ path: ['extraction', 'turnDebounceMs'], type: 'number', group: 'extraction', sub: '触发方式', label: '回合防抖(毫秒)', hint: '回合边界提取的防抖窗口;0 = 无防抖,每次都触发' },
|
|
137
137
|
// ---- 提取内容 ----
|
|
138
138
|
{ path: ['extraction', 'maxMessages'], type: 'number', group: 'extraction', sub: '提取内容', label: '单次消息上限', hint: '单次提取喂给 LLM 的最大消息数;0 = 窗口为空,不提取(等效禁用)' },
|
|
139
|
-
{ path: ['extraction', '
|
|
139
|
+
{ path: ['extraction', 'messageScope'], type: 'multicheck', group: 'extraction', sub: '提取内容', label: '计入窗口的消息类型', options: [['user', '用户消息'], ['assistant', '助手消息'], ['tool_result', '工具结果原文']], hint: '勾选的类型计入触发计数并进入提取窗口;工具结果默认排除(助手消息已含解读,原文只增成本与噪声)。保存即时生效。' },
|
|
140
|
+
{ path: ['extraction', 'toolResultMaxBytes'], type: 'number', group: 'extraction', sub: '提取内容', label: '工具结果截断(字节)', hint: '仅当上方勾选“工具结果原文”时生效:每条 tool_result 喂给 LLM 前的截断字节;0 = 工具内容全部丢弃' },
|
|
140
141
|
{ path: ['extraction', 'includeDigest'], type: 'toggle', group: 'extraction', sub: '提取内容', label: '携带会话摘要', hint: '提取时携带滚动会话 digest' },
|
|
141
142
|
{ path: ['extraction', 'dedup'], type: 'toggle', group: 'extraction', sub: '提取内容', label: '去重检索', hint: '提取前 grep 已有记忆做去重/矛盾判断' },
|
|
142
143
|
// ---- 提取模型 ----
|
|
@@ -171,6 +172,7 @@ window.__ModuleLoader__.load({
|
|
|
171
172
|
'extraction.windowTurns': 20,
|
|
172
173
|
'extraction.idleTimeoutMin': 30,
|
|
173
174
|
'extraction.maxMessages': 20,
|
|
175
|
+
'extraction.messageScope': ['user', 'assistant'],
|
|
174
176
|
'extraction.toolResultMaxBytes': 2048,
|
|
175
177
|
'extraction.includeDigest': true,
|
|
176
178
|
'extraction.dedup': true,
|
|
@@ -215,29 +217,34 @@ window.__ModuleLoader__.load({
|
|
|
215
217
|
// - effortOptionsFor(route): efforts of the selected model, prefixed with the
|
|
216
218
|
// '跟随全局默认' empty option (the model's defaultEffort when absent).
|
|
217
219
|
function useModelOptions(connection, agentDefaultScope) {
|
|
218
|
-
const [catalog, setCatalog] = useState(null); // { groups: [{id,name,models:[{id,name
|
|
220
|
+
const [catalog, setCatalog] = useState(null); // { groups: [{id,name,models:[{id,name}]}] }
|
|
221
|
+
const [efforts, setEfforts] = useState(null); // { efforts: [], defaultEffort } for the selected route
|
|
222
|
+
const [effortRoute, setEffortRoute] = useState('');
|
|
219
223
|
const [failed, setFailed] = useState(false);
|
|
220
224
|
const [, force] = useState(0);
|
|
221
225
|
|
|
226
|
+
// Model catalog now comes from our own /memory-models RPC (rc.1 removed
|
|
227
|
+
// the browser connection.api.llm.models aggregate; the host rebuilds the
|
|
228
|
+
// same shape from ctx.llm over the plugin channel).
|
|
222
229
|
useEffect(() => {
|
|
223
230
|
let alive = true;
|
|
224
231
|
const load = async () => {
|
|
225
232
|
try {
|
|
226
|
-
const res = await connection.api
|
|
233
|
+
const res = await connection.rpc.call('/api', 'memory-models/snapshot', {});
|
|
227
234
|
if (!alive) return;
|
|
228
|
-
if (res && res.
|
|
229
|
-
setCatalog(res.
|
|
235
|
+
if (res && res.ok && res.value) {
|
|
236
|
+
setCatalog(res.value);
|
|
230
237
|
setFailed(false);
|
|
231
|
-
if (!res.
|
|
232
|
-
console.warn('[memory-lite]
|
|
238
|
+
if (!res.value.groups || res.value.groups.length === 0) {
|
|
239
|
+
console.warn('[memory-lite] /memory-models returned empty groups', res.value);
|
|
233
240
|
}
|
|
234
241
|
} else {
|
|
235
|
-
console.warn('[memory-lite]
|
|
242
|
+
console.warn('[memory-lite] /memory-models non-ok:', res);
|
|
236
243
|
setFailed(true);
|
|
237
244
|
}
|
|
238
245
|
} catch (err) {
|
|
239
246
|
if (alive) {
|
|
240
|
-
console.error('[memory-lite]
|
|
247
|
+
console.error('[memory-lite] /memory-models failed:', err);
|
|
241
248
|
setFailed(true);
|
|
242
249
|
}
|
|
243
250
|
}
|
|
@@ -246,6 +253,32 @@ window.__ModuleLoader__.load({
|
|
|
246
253
|
return () => { alive = false; };
|
|
247
254
|
}, [connection]);
|
|
248
255
|
|
|
256
|
+
// Reasoning efforts are resolved lazily per selected route through
|
|
257
|
+
// /memory-model-efforts (host resolveModelInfo), not embedded in the
|
|
258
|
+
// catalog (that would be N host calls per mount).
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
if (!connection || effortRoute === '') { setEfforts(null); return; }
|
|
261
|
+
let alive = true;
|
|
262
|
+
const load = async () => {
|
|
263
|
+
try {
|
|
264
|
+
const res = await connection.rpc.call('/api', 'memory-model-efforts/snapshot', { route: effortRoute });
|
|
265
|
+
if (!alive) return;
|
|
266
|
+
if (res && res.ok && res.value) {
|
|
267
|
+
setEfforts(res.value);
|
|
268
|
+
} else {
|
|
269
|
+
setEfforts({ efforts: [], defaultEffort: undefined });
|
|
270
|
+
}
|
|
271
|
+
} catch (err) {
|
|
272
|
+
if (alive) {
|
|
273
|
+
console.error('[memory-lite] /memory-model-efforts failed:', err);
|
|
274
|
+
setEfforts({ efforts: [], defaultEffort: undefined });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
void load();
|
|
279
|
+
return () => { alive = false; };
|
|
280
|
+
}, [connection, effortRoute]);
|
|
281
|
+
|
|
249
282
|
useEffect(() => {
|
|
250
283
|
if (!agentDefaultScope) return undefined;
|
|
251
284
|
return agentDefaultScope.subscribe(() => { force((n) => n + 1); });
|
|
@@ -271,26 +304,24 @@ window.__ModuleLoader__.load({
|
|
|
271
304
|
}
|
|
272
305
|
}
|
|
273
306
|
|
|
274
|
-
// For one selected route,
|
|
307
|
+
// For one selected route, expose its reasoning efforts. The efforts
|
|
308
|
+
// were fetched lazily (see the effortRoute effect above) the last time
|
|
309
|
+
// the route changed; selecting a route re-triggers that fetch.
|
|
310
|
+
// Selected route drives the lazy efforts fetch (see the effortRoute
|
|
311
|
+
// effect above). effortOptionsFor renders from the fetched efforts;
|
|
312
|
+
// while the fetch is in flight only the default option shows.
|
|
313
|
+
const selectRoute = (route) => { setEffortRoute(route || ''); };
|
|
275
314
|
const effortOptionsFor = (route) => {
|
|
276
315
|
const opts = [['', '跟随全局默认']];
|
|
277
|
-
if (!
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const mid = route.slice(slash + 1);
|
|
282
|
-
const group = (catalog.groups || []).find((g) => g.id === gid);
|
|
283
|
-
const model = group && (group.models || []).find((m) => m.id === mid);
|
|
284
|
-
const reasoning = model && model.reasoning;
|
|
285
|
-
if (reasoning && reasoning.efforts && reasoning.efforts.length > 0) {
|
|
286
|
-
for (const eff of reasoning.efforts) {
|
|
287
|
-
opts.push([eff.id, eff.name + (eff.description ? '(' + eff.description + ')' : '')]);
|
|
288
|
-
}
|
|
316
|
+
if (!route || route === '' || route !== effortRoute) return opts;
|
|
317
|
+
const list = (efforts && efforts.efforts) || [];
|
|
318
|
+
for (const eff of list) {
|
|
319
|
+
opts.push([eff.id, eff.name + (eff.description ? '(' + eff.description + ')' : '')]);
|
|
289
320
|
}
|
|
290
321
|
return opts;
|
|
291
322
|
};
|
|
292
323
|
|
|
293
|
-
return { routeOptions, effortOptionsFor, failed };
|
|
324
|
+
return { routeOptions, effortOptionsFor, selectRoute, failed };
|
|
294
325
|
}
|
|
295
326
|
|
|
296
327
|
/* ---- 共享挂载 peer 列表 (16.9 补: 勾选式编辑) ---- */
|
|
@@ -298,19 +329,22 @@ window.__ModuleLoader__.load({
|
|
|
298
329
|
/* mount, plus the currently configured mounts. The settings page renders */
|
|
299
330
|
/* one checkbox per peer; toggling changes the mounts list saved on Save. */
|
|
300
331
|
function usePeerList(connection) {
|
|
301
|
-
const [peers, setPeers] = useState([]);
|
|
302
|
-
const [
|
|
332
|
+
const [peers, setPeers] = useState([]); // string[] storage names
|
|
333
|
+
const [display, setDisplay] = useState({}); // { storageName: displayName }
|
|
334
|
+
const [mounts, setMounts] = useState([]); // {name, peer, subpath, readonly}[]
|
|
303
335
|
const [failed, setFailed] = useState(false);
|
|
304
336
|
useEffect(() => {
|
|
305
337
|
let alive = true;
|
|
306
338
|
const load = async () => {
|
|
307
339
|
try {
|
|
308
|
-
const res = await connection.rpc.call('/
|
|
340
|
+
const res = await connection.rpc.call('/api', 'memory-peers/snapshot', {});
|
|
309
341
|
if (!alive) return;
|
|
310
342
|
// rpc.call resolves to { ok, value } directly (StatusDot pattern),
|
|
311
343
|
// not a { result: ... } wrapper.
|
|
312
344
|
if (res && res.ok && res.value) {
|
|
313
|
-
|
|
345
|
+
const list = (res.value.peers || []).map(p => ({ name: p.name, displayName: p.displayName || p.name }));
|
|
346
|
+
setPeers(list.map(p => p.name));
|
|
347
|
+
setDisplay(Object.fromEntries(list.map(p => [p.name, p.displayName])));
|
|
314
348
|
setMounts(res.value.mounts || []);
|
|
315
349
|
setFailed(false);
|
|
316
350
|
} else {
|
|
@@ -327,7 +361,7 @@ window.__ModuleLoader__.load({
|
|
|
327
361
|
void load();
|
|
328
362
|
return () => { alive = false; };
|
|
329
363
|
}, [connection]);
|
|
330
|
-
return { peers, mounts, failed };
|
|
364
|
+
return { peers, display, mounts, failed };
|
|
331
365
|
}
|
|
332
366
|
|
|
333
367
|
function FieldRow({ spec, value, draft, onChange, modelOptions }) {
|
|
@@ -356,8 +390,10 @@ window.__ModuleLoader__.load({
|
|
|
356
390
|
// Effort dropdown: options for the currently-selected route (draft or
|
|
357
391
|
// stored), falling back to the global default's effort when route unset.
|
|
358
392
|
let options;
|
|
393
|
+
let isRoute = false;
|
|
359
394
|
if (spec.dynamic === 'route') {
|
|
360
395
|
options = modelOptions ? modelOptions.routeOptions : [];
|
|
396
|
+
isRoute = true;
|
|
361
397
|
} else {
|
|
362
398
|
const routeKey = 'extraction.llm.route';
|
|
363
399
|
const routeVal = draft[routeKey] !== undefined ? draft[routeKey] : value;
|
|
@@ -365,11 +401,38 @@ window.__ModuleLoader__.load({
|
|
|
365
401
|
}
|
|
366
402
|
control = jsx('select', {
|
|
367
403
|
value: String(shown ?? ''),
|
|
368
|
-
onChange: (e) => {
|
|
404
|
+
onChange: (e) => {
|
|
405
|
+
const next = e.target.value;
|
|
406
|
+
// Selecting a model route re-targets the lazy efforts fetch.
|
|
407
|
+
if (isRoute && modelOptions && modelOptions.selectRoute) modelOptions.selectRoute(next);
|
|
408
|
+
onChange(key, next);
|
|
409
|
+
},
|
|
369
410
|
style: inputStyle,
|
|
370
411
|
children: (options || []).map(([optValue, optLabel]) =>
|
|
371
412
|
jsx('option', { value: optValue, children: optLabel, key: optValue })),
|
|
372
413
|
});
|
|
414
|
+
} else if (spec.type === 'multicheck') {
|
|
415
|
+
// Array-of-enum picker: one checkbox per allowed option; the saved
|
|
416
|
+
// value is the array of checked options in spec.options order.
|
|
417
|
+
const current = Array.isArray(shown) ? shown : [];
|
|
418
|
+
const order = (spec.options || []).map(o => o[0]);
|
|
419
|
+
const toggleOpt = (opt, on) => {
|
|
420
|
+
const next = new Set(current);
|
|
421
|
+
if (on) next.add(opt); else next.delete(opt);
|
|
422
|
+
onChange(key, order.filter(o => next.has(o)));
|
|
423
|
+
};
|
|
424
|
+
control = jsx('div', { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children:
|
|
425
|
+
(spec.options || []).map(([optValue, optLabel]) =>
|
|
426
|
+
jsx('label', { key: optValue, style: { display: 'flex', alignItems: 'center', gap: 6, fontSize: 13, color: 'var(--dsw-alias-label-primary)', cursor: 'pointer' }, children: [
|
|
427
|
+
jsx('input', {
|
|
428
|
+
type: 'checkbox',
|
|
429
|
+
checked: current.includes(optValue),
|
|
430
|
+
onChange: (e) => { toggleOpt(optValue, e.target.checked); },
|
|
431
|
+
style: { width: 14, height: 14, accentColor: 'var(--dsw-alias-state-business-primary)' },
|
|
432
|
+
}),
|
|
433
|
+
optLabel,
|
|
434
|
+
]})),
|
|
435
|
+
});
|
|
373
436
|
} else {
|
|
374
437
|
control = jsx('input', {
|
|
375
438
|
type: 'text',
|
|
@@ -451,19 +514,25 @@ window.__ModuleLoader__.load({
|
|
|
451
514
|
ops.push({ op: 'set', path: ['sharing', 'mounts'], value: peers.map(peer => ({ name: peer, peer, subpath: '', readonly: true })) });
|
|
452
515
|
}
|
|
453
516
|
if (ops.length === 0) { setSaving(false); return; }
|
|
517
|
+
// dsh-settings >= 0.1.2: the bound scope owns writes (scope.mutate);
|
|
518
|
+
// legacy hosts wrote through connection.api.settings.mutate. Prefer
|
|
519
|
+
// the scope method when present (it fences its own revision).
|
|
454
520
|
const revision = scope.getSnapshot().revision;
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
521
|
+
if (typeof scope.mutate === 'function') {
|
|
522
|
+
await scope.mutate(ops, revision === undefined ? undefined : revision);
|
|
523
|
+
} else if (connection && connection.api && connection.api.settings) {
|
|
524
|
+
const response = await connection.api.settings.mutate({
|
|
525
|
+
ns: NS,
|
|
526
|
+
ops,
|
|
527
|
+
...(revision === undefined ? {} : { expectedRevision: revision }),
|
|
528
|
+
});
|
|
529
|
+
if (!response.result.ok) throw new Error('settings mutate failed');
|
|
462
530
|
} else {
|
|
463
|
-
|
|
464
|
-
setMountDraft(null);
|
|
465
|
-
setSaved(true);
|
|
531
|
+
throw new Error('no settings write channel available');
|
|
466
532
|
}
|
|
533
|
+
setDraft({});
|
|
534
|
+
setMountDraft(null);
|
|
535
|
+
setSaved(true);
|
|
467
536
|
} catch {
|
|
468
537
|
setFailed(true);
|
|
469
538
|
} finally {
|
|
@@ -550,6 +619,7 @@ window.__ModuleLoader__.load({
|
|
|
550
619
|
// Sharing mounts: checkbox per peer. Checked peers are shared (readonly).
|
|
551
620
|
const configuredMounts = (value && value.sharing && value.sharing.mounts) || [];
|
|
552
621
|
const checkedPeers = new Set(configuredMounts.map(m => m.peer));
|
|
622
|
+
const peerDisplay = peerList.display || {};
|
|
553
623
|
const shownPeers = (peerList.peers || []).length > 0 ? peerList.peers : Object.keys(checkedPeers);
|
|
554
624
|
const mountCheckboxValue = (peer) => mountDraft !== null ? mountDraft.has(peer) : checkedPeers.has(peer);
|
|
555
625
|
const toggleMount = (peer, on) => {
|
|
@@ -580,7 +650,7 @@ window.__ModuleLoader__.load({
|
|
|
580
650
|
onChange: (e) => { toggleMount(peer, e.target.checked); },
|
|
581
651
|
style: { width: 16, height: 16, accentColor: 'var(--dsw-alias-state-business-primary)' },
|
|
582
652
|
}),
|
|
583
|
-
jsx('span', { style: { fontFamily: 'var(--ds-font-family-code)', color: 'var(--dsw-alias-label-primary)' }, children: peer }),
|
|
653
|
+
jsx('span', { style: { fontFamily: 'var(--ds-font-family-code)', color: 'var(--dsw-alias-label-primary)' }, children: peerDisplay[peer] && peerDisplay[peer] !== peer ? peerDisplay[peer] + ' (' + peer + ')' : peer }),
|
|
584
654
|
on ? jsx('span', { style: { fontSize: 11, color: 'var(--dsw-alias-label-tertiary)' }, children: '(已共享)' }) : null,
|
|
585
655
|
],
|
|
586
656
|
});
|
|
@@ -605,7 +675,9 @@ window.__ModuleLoader__.load({
|
|
|
605
675
|
{
|
|
606
676
|
name: 'conversation.session.header.utilities',
|
|
607
677
|
id: 'memory-lite-status',
|
|
608
|
-
|
|
678
|
+
// -20 < open-in-app (-10): the status pill sits left of the
|
|
679
|
+
// workspace open-in-app split button (Finder/VSCode/Xcode).
|
|
680
|
+
order: -20,
|
|
609
681
|
inject: () => ({ connection, scope }),
|
|
610
682
|
},
|
|
611
683
|
StatusDot,
|
package/lib/config.d.ts
CHANGED
|
@@ -73,13 +73,17 @@ export interface ExtractionLlmConfig {
|
|
|
73
73
|
export interface ExtractionConfig {
|
|
74
74
|
/** incremental | explicit_only | off. Defaults to incremental. */
|
|
75
75
|
mode: 'incremental' | 'explicit_only' | 'off';
|
|
76
|
-
/** New
|
|
76
|
+
/** New in-scope conversation messages >= this count triggers an extraction. Defaults to 50. */
|
|
77
77
|
windowTurns: number;
|
|
78
78
|
/** Idle minutes before the remaining window is extracted. Defaults to 30. */
|
|
79
79
|
idleTimeoutMin: number;
|
|
80
80
|
/** Max messages fed to the extraction LLM per run. Defaults to 20. */
|
|
81
81
|
maxMessages: number;
|
|
82
|
-
/** Which event kinds count and feed the window
|
|
82
|
+
/** Which event kinds count toward windowTurns and feed the extraction window.
|
|
83
|
+
* 'user' = real user messages (injections never count), 'assistant' = assistant
|
|
84
|
+
* messages, 'tool_result' = raw tool results. Tool results are excluded by
|
|
85
|
+
* default: their raw output adds token cost and noise while the assistant
|
|
86
|
+
* message already carries the interpretation. Defaults to ['user','assistant']. */
|
|
83
87
|
messageScope: ('user' | 'assistant' | 'tool_result')[];
|
|
84
88
|
/** Per tool/result content truncation before feeding the LLM. Defaults to 2048. */
|
|
85
89
|
toolResultMaxBytes: number;
|
package/lib/config.js
CHANGED
|
@@ -68,6 +68,20 @@ export const Config = z.object({
|
|
|
68
68
|
headerOrder: z.number(),
|
|
69
69
|
}),
|
|
70
70
|
});
|
|
71
|
+
/** Validate and normalize extraction.messageScope. Invalid entries throw; an
|
|
72
|
+
* absent value yields the default (conversation only, no raw tool results). */
|
|
73
|
+
function normalizeMessageScope(scope) {
|
|
74
|
+
if (scope === undefined || scope.length === 0)
|
|
75
|
+
return ['user', 'assistant'];
|
|
76
|
+
const valid = new Set(['user', 'assistant', 'tool_result']);
|
|
77
|
+
for (const entry of scope) {
|
|
78
|
+
if (!valid.has(entry)) {
|
|
79
|
+
throw new Error('dsh-memory-lite: extraction.messageScope entries must be user | assistant | tool_result, got ' + JSON.stringify(entry));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Drop duplicates while preserving order.
|
|
83
|
+
return [...new Set(scope)];
|
|
84
|
+
}
|
|
71
85
|
/** Normalize and default a raw configuration; throws on invalid values. */
|
|
72
86
|
export function resolveConfig(config = {}) {
|
|
73
87
|
const root = resolve(expandHomePath(config.root ?? DEFAULT_MEMORY_ROOT));
|
|
@@ -89,10 +103,10 @@ export function resolveConfig(config = {}) {
|
|
|
89
103
|
}
|
|
90
104
|
const extraction = {
|
|
91
105
|
mode: config.extraction?.mode ?? 'incremental',
|
|
92
|
-
windowTurns: config.extraction?.windowTurns ??
|
|
106
|
+
windowTurns: config.extraction?.windowTurns ?? 50,
|
|
93
107
|
idleTimeoutMin: config.extraction?.idleTimeoutMin ?? 30,
|
|
94
108
|
maxMessages: config.extraction?.maxMessages ?? 20,
|
|
95
|
-
messageScope: config.extraction?.messageScope
|
|
109
|
+
messageScope: normalizeMessageScope(config.extraction?.messageScope),
|
|
96
110
|
toolResultMaxBytes: config.extraction?.toolResultMaxBytes ?? 2048,
|
|
97
111
|
includeDigest: config.extraction?.includeDigest ?? true,
|
|
98
112
|
dedup: config.extraction?.dedup ?? true,
|
package/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,CAAC,MAAM,0BAA0B,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D,gEAAgE;AAChE,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAA;AACpD,2DAA2D;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAA;AACrC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAA;AAC5C,mHAAmH;AACnH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/lib/extract/index.d.ts
CHANGED
|
@@ -29,7 +29,13 @@ export interface ExtractionSessionLike {
|
|
|
29
29
|
readonly cwd?: string;
|
|
30
30
|
readonly origin?: 'subagent';
|
|
31
31
|
};
|
|
32
|
-
|
|
32
|
+
/** dsh-session <= 0.1.1 exposed the full log as `events`; >= 0.1.2 uses snapshotEvents(). */
|
|
33
|
+
readonly events?: readonly {
|
|
34
|
+
readonly type: string;
|
|
35
|
+
readonly seq: number;
|
|
36
|
+
readonly data: unknown;
|
|
37
|
+
}[];
|
|
38
|
+
snapshotEvents?(fromSeq?: number, toSeqExclusive?: number): readonly {
|
|
33
39
|
readonly type: string;
|
|
34
40
|
readonly seq: number;
|
|
35
41
|
readonly data: unknown;
|
package/lib/extract/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { BlockAssembler, createUserMessage, ReasoningEffortId } from '@deepseek-
|
|
|
12
12
|
import { peerForHeader } from '../peer.js';
|
|
13
13
|
import { MEMORY_CATEGORIES } from '../types.js';
|
|
14
14
|
import { slugify, summaryOf } from '../memory-store.js';
|
|
15
|
-
import { isSurfaceType, selectWindow, renderEventText } from './window.js';
|
|
15
|
+
import { isSurfaceType, inScope, selectWindow, renderEventText } from './window.js';
|
|
16
16
|
import { shouldExtractIdle, shouldExtractTurn, shouldExtractWindow } from './triggers.js';
|
|
17
17
|
import { parseDecision } from './decision.js';
|
|
18
18
|
import { digestApproxTokens, rollDigest } from './digest.js';
|
|
@@ -27,6 +27,12 @@ const MAX_GREP_HITS = 8;
|
|
|
27
27
|
// the repair path on ~85% of runs. 4096 leaves room for both reasoning and the
|
|
28
28
|
// JSON decision body.
|
|
29
29
|
const EXTRACTION_MAX_TOKENS = 4096;
|
|
30
|
+
/** Read a session's full event log across dsh-session versions (events vs snapshotEvents). */
|
|
31
|
+
function sessionEvents(session) {
|
|
32
|
+
if (session.snapshotEvents !== undefined)
|
|
33
|
+
return session.snapshotEvents();
|
|
34
|
+
return session.events ?? [];
|
|
35
|
+
}
|
|
30
36
|
/** Register the extraction channel for the lifetime of `ctx`. */
|
|
31
37
|
export function applyExtraction(ctx, deps, tracker) {
|
|
32
38
|
const ext = () => deps.config().extraction;
|
|
@@ -71,6 +77,8 @@ export function applyExtraction(ctx, deps, tracker) {
|
|
|
71
77
|
return;
|
|
72
78
|
if (!isSurfaceType(event.type))
|
|
73
79
|
return;
|
|
80
|
+
if (!inScope(event.type, ext().messageScope))
|
|
81
|
+
return;
|
|
74
82
|
const state = stateOf(session);
|
|
75
83
|
state.pending += 1;
|
|
76
84
|
resetIdle(session, state);
|
|
@@ -146,8 +154,8 @@ export async function extractOnce(session, state, ctx, deps, signal, tracker) {
|
|
|
146
154
|
state.checkpoint = parseCheckpoint(raw);
|
|
147
155
|
}
|
|
148
156
|
const fromSeq = state.checkpoint.checkpoint.seq;
|
|
149
|
-
const events = session
|
|
150
|
-
const windowEvents = selectWindow(events, fromSeq, ext.maxMessages);
|
|
157
|
+
const events = sessionEvents(session);
|
|
158
|
+
const windowEvents = selectWindow(events, fromSeq, ext.maxMessages, ext.messageScope);
|
|
151
159
|
if (windowEvents.length === 0)
|
|
152
160
|
return;
|
|
153
161
|
const windowStart = windowEvents[0].seq;
|