@nightpainters/dsh-ling 1.5.1 → 1.5.3
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/ACCESS-DESIGN.md +10 -7
- package/CHANGELOG.md +140 -3
- package/DESIGN.md +162 -18
- package/README.md +66 -32
- package/lib/audit/access-log.js +181 -25
- package/lib/audit/index.js +45 -3
- package/lib/audit/patch-spec.js +1 -1
- package/lib/client.js +1183 -88
- package/lib/host/api.js +716 -83
- package/lib/host/backfill.js +8 -2
- package/lib/host/feedback.js +112 -2
- package/lib/host/freeze.js +52 -1
- package/lib/host/genesis.js +27 -5
- package/lib/host/guard.js +39 -2
- package/lib/host/habit-gen.js +12 -4
- package/lib/host/import-file.js +62 -6
- package/lib/host/import-log.js +80 -2
- package/lib/host/inject.js +49 -12
- package/lib/host/l1.js +11 -4
- package/lib/host/lifecycle.js +13 -2
- package/lib/host/memory.js +425 -33
- package/lib/host/mode-service.js +85 -0
- package/lib/host/mode.js +29 -9
- package/lib/host/persona.js +38 -7
- package/lib/host/retitle.js +6 -0
- package/lib/host/session-line.js +688 -0
- package/lib/host/snapshot.js +48 -7
- package/lib/host/summarizer.js +159 -3
- package/lib/host/surgery.js +600 -0
- package/lib/host/tools.js +12 -1
- package/lib/host/tree-ops.js +1 -1
- package/lib/index.js +22 -29
- package/package.json +51 -4
- package/tools/apply-access-log-patch.mjs +1 -1
package/lib/index.js
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
// Skeleton wiring: settings file, sqlite memory, freeze gate, system-prompt
|
|
3
3
|
// injection, lifecycle listeners, loopback HTTP gateway.
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import { readFileSync
|
|
6
|
-
import { svc, pick, ensureDir, defaultDataDir, utcIso
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { svc, pick, ensureDir, defaultDataDir, utcIso } from './host/util.js';
|
|
7
7
|
import { SettingsFile } from './host/settings-file.js';
|
|
8
8
|
import { MemoryStore } from './host/memory.js';
|
|
9
9
|
import { FreezeGate } from './host/freeze.js';
|
|
10
10
|
import { registerMemorySection } from './host/inject.js';
|
|
11
|
+
import { wireSessionLine } from './host/session-line.js';
|
|
11
12
|
import { wireLifecycle } from './host/lifecycle.js';
|
|
13
|
+
import { registerModeService } from './host/mode-service.js';
|
|
12
14
|
import { registerApi } from './host/api.js';
|
|
13
15
|
import { summarizeDsh } from './host/summarizer.js';
|
|
14
|
-
import {
|
|
16
|
+
import { registerFeedbackListener } from './host/feedback.js';
|
|
15
17
|
import { probeLLM, runDeepPass, DEEP_CFG } from './host/deepsummary.js';
|
|
16
18
|
import { registerLingTools } from './host/tools.js';
|
|
17
19
|
import { registerClockSkill } from './host/clock-skill.js';
|
|
@@ -56,7 +58,14 @@ export function apply(ctx, config = {}) {
|
|
|
56
58
|
|
|
57
59
|
const disposers = [];
|
|
58
60
|
disposers.push(registerMemorySection(ctx, gate, memory, settings));
|
|
61
|
+
// E0「那一行跟着会话走」:只加一个 agent/pre-step 监听(全库目前没有别处用它)。
|
|
62
|
+
// 形态 A —— 只往 `decision.messages` 追加,**不碰** systemPrompt 的 section()/context(),
|
|
63
|
+
// 也绝不调用带 surfaceOp 的 session.append。关掉开关:settings.memory.sessionProgressLine=false。
|
|
64
|
+
disposers.push(wireSessionLine(ctx, memory, settings, cfg.sessionLine || {}));
|
|
59
65
|
disposers.push(wireLifecycle(ctx, gate, memory, settings, cfg));
|
|
66
|
+
// P3-A(2026-09-29):把「给某个会话设模式」暴露成跨插件服务 `dsh-ling/mode` ——
|
|
67
|
+
// 飞书桥建线时用它把新会话钉到生活挡位。软能力:注册失败只记日志,不影响其余功能。
|
|
68
|
+
disposers.push(registerModeService(ctx, { gate, memory, settings }));
|
|
60
69
|
disposers.push(registerApi(ctx, { gate, memory, settings }, cfg));
|
|
61
70
|
// E4 可取证访问日志:只挂两个全局钩子,core 侧补丁留的调用点见 lib/audit/patch-spec.js。
|
|
62
71
|
// 补丁未打时钩子收不到调用 —— 安装器会在启动日志里明确喊出来,不允许静默不记。
|
|
@@ -182,30 +191,19 @@ export function apply(ctx, config = {}) {
|
|
|
182
191
|
}, 8000);
|
|
183
192
|
}
|
|
184
193
|
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
// 反馈成长回路:事件驱动(U7 正解,2026-10-01)。
|
|
195
|
+
// ⚠️ 旧实现是"每 60 秒读一次 `~/.dsh/storages/message_feedback.json`",两处都错:
|
|
196
|
+
// ① 宿主**有推送** —— `dsh-message-feedback\lib\index.js:288` 在冷会话写入 flush 后
|
|
197
|
+
// 发 `feedback/committed`(活会话走 `session/event` 的 feedback 事件);
|
|
198
|
+
// ② 那个 sidecar 在 Web 组合下自 2026/9/11 起**零写入**(该组合只挂 message-feedback,
|
|
199
|
+
// 反馈已改写在会话日志里)⇒ 轮询每 60 秒读同一个死文件,纯空转。
|
|
200
|
+
// 现在:事件到达即处理;`feedbackAuto:false` 可整体关掉。
|
|
201
|
+
if (cfg.feedbackAuto !== false) {
|
|
189
202
|
try {
|
|
190
|
-
|
|
191
|
-
const fileObj = JSON.parse(readFileSync(fbFile, 'utf8'));
|
|
192
|
-
const entries = entriesFromFeedbackFile(fileObj);
|
|
193
|
-
if (!entries.length) return;
|
|
194
|
-
const seen = loadSeen(memory);
|
|
195
|
-
const res = ingestFeedbackEntries(memory, entries, { seen });
|
|
196
|
-
if (res.queued + res.boosted + res.seenAdded > 0) {
|
|
197
|
-
memory.kvSet('feedback.last', JSON.stringify({ at: utcIso(), ...res }));
|
|
198
|
-
}
|
|
203
|
+
disposers.push(registerFeedbackListener(ctx, memory));
|
|
199
204
|
} catch (e) {
|
|
200
|
-
console.debug('[dsh-ling] feedback
|
|
205
|
+
console.debug('[dsh-ling] feedback listener wiring failed', e);
|
|
201
206
|
}
|
|
202
|
-
};
|
|
203
|
-
if (cfg.feedbackAuto !== false) {
|
|
204
|
-
const pollSec = Math.max(20, Number(cfg.feedbackPollSec ?? 60));
|
|
205
|
-
fbTimer = setTimeout(() => {
|
|
206
|
-
pollFeedback();
|
|
207
|
-
fbTimer = setInterval(pollFeedback, pollSec * 1000);
|
|
208
|
-
}, 20000);
|
|
209
207
|
}
|
|
210
208
|
|
|
211
209
|
// LLM 深摘要:启动 12s 先自检探针;通过才挂自动调度(保守上限,可配)
|
|
@@ -232,11 +230,6 @@ export function apply(ctx, config = {}) {
|
|
|
232
230
|
clearInterval(sumTimer);
|
|
233
231
|
sumTimer = null;
|
|
234
232
|
}
|
|
235
|
-
if (fbTimer) {
|
|
236
|
-
clearTimeout(fbTimer);
|
|
237
|
-
clearInterval(fbTimer);
|
|
238
|
-
fbTimer = null;
|
|
239
|
-
}
|
|
240
233
|
if (deepTimer) {
|
|
241
234
|
clearInterval(deepTimer);
|
|
242
235
|
deepTimer = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nightpainters/dsh-ling",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "器灵 · 跑在你自己电脑上的记忆与人格助手插件:三层记忆、从历史里长出来的人格档案、定型锁与自由生长",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
|
-
"test": "node tests/unit.mjs && node tests/access-log.test.mjs && node tests/archive.test.mjs && node tests/autotree.test.mjs && node tests/backfill.test.mjs && node tests/branch.test.mjs && node tests/assistant.test.mjs && node tests/capture.test.mjs && node tests/clock.test.mjs && node tests/clock-skill.test.mjs && node tests/deep.test.mjs && node tests/dswebsum.test.mjs && node tests/export.test.mjs && node tests/feedback.test.mjs && node tests/forget-backfill.test.mjs && node tests/genesis.test.mjs && node tests/guard.test.mjs && node tests/habitgen.test.mjs && node tests/idle.test.mjs && node tests/importfile.test.mjs && node tests/importlog.test.mjs && node tests/l1lines.test.mjs && node tests/memories.test.mjs && node tests/mode.test.mjs && node tests/mustache.test.mjs && node tests/retitle.test.mjs && node tests/rules.test.mjs && node tests/suggest.test.mjs && node tests/summarize.test.mjs && node tests/times.test.mjs && node tests/tone.test.mjs && node tests/tools.test.mjs && node tests/tree.test.mjs && node tests/patch-spec.test.mjs",
|
|
27
|
+
"test": "node tests/unit.mjs && node tests/access-log.test.mjs && node tests/archive.test.mjs && node tests/autotree.test.mjs && node tests/backfill.test.mjs && node tests/branch.test.mjs && node tests/assistant.test.mjs && node tests/capture.test.mjs && node tests/clock.test.mjs && node tests/clock-skill.test.mjs && node tests/deep.test.mjs && node tests/dswebsum.test.mjs && node tests/duty.test.mjs && node tests/export.test.mjs && node tests/feedback.test.mjs && node tests/forget-backfill.test.mjs && node tests/genesis.test.mjs && node tests/guard.test.mjs && node tests/habitgen.test.mjs && node tests/idle.test.mjs && node tests/importfile.test.mjs && node tests/importlog.test.mjs && node tests/l1lines.test.mjs && node tests/memories.test.mjs && node tests/mode.test.mjs && node tests/mode-service.test.mjs && node tests/mustache.test.mjs && node tests/retitle.test.mjs && node tests/rules.test.mjs && node tests/sessionline.test.mjs && node tests/suggest.test.mjs && node tests/summarize.test.mjs && node tests/times.test.mjs && node tests/tone.test.mjs && node tests/tools.test.mjs && node tests/tree.test.mjs && node tests/patch-spec.test.mjs && node tests/bodylimit.test.mjs && node tests/client-batch.test.mjs",
|
|
28
28
|
"check": "node tools/check-install.mjs",
|
|
29
29
|
"check:publish": "node tools/check-publish.mjs"
|
|
30
30
|
},
|
|
@@ -51,16 +51,63 @@
|
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": ">=22.5.0"
|
|
53
53
|
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@deepseek-ai/cordis": ">=4.0.4",
|
|
56
|
+
"@deepseek-ai/dsh-agent-default-model": ">=0.1.7-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-api-session-controller": ">=0.1.7-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-connection": ">=0.1.7-rc.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.7-rc.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-store": ">=0.1.7-rc.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.7-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-host-webserver": ">=0.1.7-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-llm": ">=0.1.7-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-skill": ">=0.1.7-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-system-prompt": ">=0.1.7-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-tools": ">=0.1.7-rc.2"
|
|
67
|
+
},
|
|
68
|
+
"peerDependenciesMeta": {
|
|
69
|
+
"@deepseek-ai/dsh-agent-default-model": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"@deepseek-ai/dsh-api-session-controller": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@deepseek-ai/dsh-client-connection": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@deepseek-ai/dsh-client-locale": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@deepseek-ai/dsh-client-store": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-slots": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"@deepseek-ai/dsh-host-webserver": {
|
|
88
|
+
"optional": true
|
|
89
|
+
},
|
|
90
|
+
"@deepseek-ai/dsh-llm": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"@deepseek-ai/dsh-skill": {
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"@deepseek-ai/dsh-system-prompt": {
|
|
97
|
+
"optional": true
|
|
98
|
+
},
|
|
99
|
+
"@deepseek-ai/dsh-tools": {
|
|
100
|
+
"optional": true
|
|
101
|
+
}
|
|
102
|
+
},
|
|
54
103
|
"dsh": {
|
|
55
104
|
"bundle": {
|
|
56
105
|
"patch": "./cordis.patch.yml"
|
|
57
106
|
},
|
|
58
107
|
"client": {
|
|
59
108
|
"inject": [
|
|
60
|
-
"@deepseek-ai/dsh-client-store",
|
|
61
109
|
"@deepseek-ai/dsh-client-connection",
|
|
62
110
|
"@deepseek-ai/dsh-client-locale",
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-slots",
|
|
64
111
|
"@deepseek-ai/dsh-api-session-controller"
|
|
65
112
|
],
|
|
66
113
|
"platform": "web"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// E4 访问日志 · 核心补丁脚本(幂等 / 可回滚 / 可自检)
|
|
3
3
|
//
|
|
4
4
|
// 背景:`/api` 的 403/401 栅栏在 core 里(dsh-client-connection),插件层看不到 ——
|
|
5
|
-
// 而"谁在什么时候被拦下"
|
|
5
|
+
// 而"谁在什么时候被拦下"恰恰是悬案最缺的那条证据(E4 设计里定下的首选落点)。
|
|
6
6
|
// 解决办法不是把逻辑搬进 core,而是让 core 多一行**可选调用**:
|
|
7
7
|
//
|
|
8
8
|
// globalThis.__dshAccessLogObserve?.(req, res); // E4 access log (dsh-ling patch)
|