@stardustlc/dsh-dream 0.3.2 → 0.3.4
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.en.md +7 -1
- package/README.md +7 -1
- package/lib/sessions.js +17 -13
- package/lib/tools.js +10 -4
- package/package.json +3 -3
package/README.en.md
CHANGED
|
@@ -4,13 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
# dsh-dream
|
|
6
6
|
|
|
7
|
+
## 0.3.4 update (2026-09-28)
|
|
8
|
+
|
|
9
|
+
Fixes [#2](https://github.com/STARDUSTLC666/dsh-dream/issues/2): digests now render human excerpts, assistant responses and tool names, skip truly empty sessions, and mask metadata as well as the body. Supports Harness v4 session files while excluding reasoning blocks and injected context from human excerpts.
|
|
10
|
+
|
|
7
11
|
> **An agent that dreams**: session replay (dream material) → reflection (interpretation) → dream journal (memory consolidation).
|
|
8
12
|
|
|
9
13
|
Humans consolidate memories by replaying the day during sleep — dsh-dream gives DeepSeek Harness agents the same ability. It reads your historical sessions (the official multi-frame zstd session logs, parsed with zero dependencies), distills dream material, lets the agent reflect, and writes permanent dream journal entries that can be recalled later.
|
|
10
14
|
|
|
11
15
|
## Compatibility
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
Verified with Harness `0.1.7-rc.2` built from official sources and Node `24.16.0` on 2026-09-28, retaining the local tool-scheduler fix: 64 tests pass, and all 18 plugins register together. Host checks read the current session format and validate rendered content. Standard-mode browser testing recovered human text, assistant responses and tool names from isolated sessions. Uses the `cordis.patch.yml` + `dsh.bundle.patch` bundle model. Node requirement: 22.19 or later within 22.x, or 24 or later.
|
|
18
|
+
|
|
19
|
+
Reads v0/v1/v2/v3/v4 plaintext JSONL and multi-frame zstd, legacy packed chunks and embedded streams. Only the newest canonical file is selected per session. PTC child calls retain tool names without double counting; system prompts, reasoning, tool arguments and result bodies are excluded.
|
|
14
20
|
|
|
15
21
|
Default data directories follow `DSH_HOME`: `sessions` for session logs and `.dsh-dream` for the journal. Without `DSH_HOME`, the base is `~/.dsh`. Explicit `sessionsRoot` and `journalDir` settings take precedence.
|
|
16
22
|
|
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
# dsh-dream
|
|
4
4
|
|
|
5
|
+
## 0.3.4 更新(2026-09-28)
|
|
6
|
+
|
|
7
|
+
修复 [#2](https://github.com/STARDUSTLC666/dsh-dream/issues/2):摘要现在实际输出用户原话、助手回应和工具足迹;跳过真正空会话,标题与正文一并脱敏。支持新版 Harness 的 v4 会话文件,并过滤推理内容与自动注入的上下文,避免当作用户原话。
|
|
8
|
+
|
|
5
9
|
> **会做梦的 agent**:会话回放(梦原料)→ 反思(解梦)→ 梦境日记(记忆巩固)。
|
|
6
10
|
|
|
7
11
|
   
|
|
@@ -10,7 +14,9 @@
|
|
|
10
14
|
|
|
11
15
|
## 兼容性
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
已在官方源码构建的 Harness `0.1.7-rc.2`、Node `24.16.0` 上验证(2026-09-28,保留本地工具调度器修复):64 项测试通过;18 个插件共同注册,宿主实际读取当前格式会话并检查最终渲染内容。浏览器标准模式已读到隔离会话的原话、回应与工具足迹。采用 `cordis.patch.yml` + `dsh.bundle.patch` 组合包模型。Node 要求:22.19 及以上的 22.x,或 24 及以上。
|
|
18
|
+
|
|
19
|
+
支持 v0/v1/v2/v3/v4 的普通 JSONL 与多帧 zstd、旧 packed-chunk 行及内嵌 stream;升级留下多代文件时只读取每个会话的最新规范文件。PTC 子工具调用保留工具名且不重复计数,不提取系统提示、推理、工具参数或结果正文。
|
|
14
20
|
|
|
15
21
|
默认从 `DSH_HOME/sessions` 读取会话、在 `DSH_HOME/.dsh-dream` 保存日记;未设置 `DSH_HOME` 时使用 `~/.dsh`。配置中的 `sessionsRoot`、`journalDir` 始终优先。
|
|
16
22
|
|
package/lib/sessions.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DSH 会话日志读取:兼容 v0/v1/v2 的 JSONL 与多帧 zstd。
|
|
2
|
+
* DSH 会话日志读取:兼容 v0/v1/v2/v3/v4 的 JSONL 与多帧 zstd。
|
|
3
3
|
* 首个逻辑行是会话头({ type: 'session', ... }),其后每行一条存储记录({ type, seq, time, data })。
|
|
4
4
|
* 本模块只读不写;损坏帧/行一律容错跳过。
|
|
5
5
|
*
|
|
@@ -37,20 +37,15 @@ function blockText(value) {
|
|
|
37
37
|
return value;
|
|
38
38
|
if (Array.isArray(value)) {
|
|
39
39
|
return value
|
|
40
|
-
.map(
|
|
41
|
-
if (typeof item === 'string')
|
|
42
|
-
return item;
|
|
43
|
-
if (typeof item === 'object' && item !== null) {
|
|
44
|
-
const rec = item;
|
|
45
|
-
return typeof rec.text === 'string' ? rec.text : '';
|
|
46
|
-
}
|
|
47
|
-
return '';
|
|
48
|
-
})
|
|
40
|
+
.map(blockText)
|
|
49
41
|
.filter((text) => text !== '')
|
|
50
42
|
.join('');
|
|
51
43
|
}
|
|
52
44
|
if (typeof value === 'object' && value !== null) {
|
|
53
45
|
const rec = value;
|
|
46
|
+
// Assistant content can contain reasoning beside visible text (including v4).
|
|
47
|
+
if (typeof rec.type === 'string' && rec.type !== 'text')
|
|
48
|
+
return '';
|
|
54
49
|
for (const key of ['text', 'content']) {
|
|
55
50
|
const inner = blockText(rec[key]);
|
|
56
51
|
if (inner !== '')
|
|
@@ -88,12 +83,14 @@ export function digestSessionFile(filePath, maxUserMessages) {
|
|
|
88
83
|
if (lines.length === 0)
|
|
89
84
|
return null;
|
|
90
85
|
let header = null;
|
|
86
|
+
let formatVersion = 0;
|
|
91
87
|
try {
|
|
92
88
|
const first = JSON.parse(lines[0]);
|
|
93
89
|
if (first.type !== 'session')
|
|
94
90
|
return null;
|
|
95
|
-
if (first.version !== undefined && ![0, 1, 2].includes(first.version))
|
|
91
|
+
if (first.version !== undefined && ![0, 1, 2, 3, 4].includes(first.version))
|
|
96
92
|
return null;
|
|
93
|
+
formatVersion = typeof first.version === 'number' ? first.version : 0;
|
|
97
94
|
header = {
|
|
98
95
|
id: String(first.id ?? ''),
|
|
99
96
|
createdAt: typeof first.createdAt === 'number' ? first.createdAt : 0,
|
|
@@ -156,7 +153,7 @@ export function digestSessionFile(filePath, maxUserMessages) {
|
|
|
156
153
|
const time = typeof rec.time === 'number' ? rec.time : typeof rec.time0 === 'number' ? rec.time0 : null;
|
|
157
154
|
if (time !== null && (digest.endedAt === null || time > digest.endedAt))
|
|
158
155
|
digest.endedAt = time;
|
|
159
|
-
// v2 把流式片段内嵌进 message/attempt;v0 的独立打包行继续兼容。
|
|
156
|
+
// v2/v3/v4 把流式片段内嵌进 message/attempt;v0 的独立打包行继续兼容。
|
|
160
157
|
if ((type === 'assistant/message' || type === 'assistant/attempt') && typeof data === 'object' && data !== null) {
|
|
161
158
|
const stream = data.stream;
|
|
162
159
|
if (Array.isArray(stream))
|
|
@@ -170,6 +167,12 @@ export function digestSessionFile(filePath, maxUserMessages) {
|
|
|
170
167
|
digest.turns++;
|
|
171
168
|
}
|
|
172
169
|
else if (type === 'user/message') {
|
|
170
|
+
if (formatVersion >= 4 && typeof data === 'object' && data !== null) {
|
|
171
|
+
const source = data.source;
|
|
172
|
+
// User-role injections are context, not the human's original words.
|
|
173
|
+
if (typeof source === 'object' && source !== null && source.kind !== 'user')
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
173
176
|
const msg = textOf(data);
|
|
174
177
|
if (msg !== '' && digest.userMessages.length < maxUserMessages * 2)
|
|
175
178
|
digest.userMessages.push(msg);
|
|
@@ -182,7 +185,8 @@ export function digestSessionFile(filePath, maxUserMessages) {
|
|
|
182
185
|
digest.assistantTail.shift();
|
|
183
186
|
}
|
|
184
187
|
}
|
|
185
|
-
else if (type === 'tool/call') {
|
|
188
|
+
else if (type === 'tool/call' || type === 'tool/code-dispatch-start' || type === 'tool/ptc-dispatch-start') {
|
|
189
|
+
// PTC 子调用只记录开始事件,避免与完成事件重复计算;不提取参数或结果正文。
|
|
186
190
|
if (typeof data === 'object' && data !== null)
|
|
187
191
|
appendToolName(data.name);
|
|
188
192
|
}
|
package/lib/tools.js
CHANGED
|
@@ -67,6 +67,9 @@ export function buildDreamTools(config) {
|
|
|
67
67
|
for (const item of sessions) {
|
|
68
68
|
const s = asRecord(item);
|
|
69
69
|
lines.push('- ' + (s.title !== '' ? s.title : '(无标题)') + ':' + s.turns + ' 轮,目录 ' + s.cwd);
|
|
70
|
+
// execute already masks secrets and applies the full/brief character budget.
|
|
71
|
+
if (typeof s.digestText === 'string' && s.digestText !== '')
|
|
72
|
+
lines.push(s.digestText);
|
|
70
73
|
}
|
|
71
74
|
return [{ type: 'text', text: lines.join('\n') }];
|
|
72
75
|
},
|
|
@@ -87,17 +90,20 @@ export function buildDreamTools(config) {
|
|
|
87
90
|
continue;
|
|
88
91
|
if (digest.origin === 'subagent')
|
|
89
92
|
continue;
|
|
93
|
+
if (digest.turns === 0 && digest.userMessages.length === 0 && digest.assistantTail.length === 0
|
|
94
|
+
&& digest.toolCalls.length === 0 && digest.streamTail.trim() === '')
|
|
95
|
+
continue;
|
|
90
96
|
sessions.push({
|
|
91
97
|
id: digest.id,
|
|
92
|
-
title: digest.title,
|
|
98
|
+
title: mask(digest.title),
|
|
93
99
|
createdAt: digest.createdAt,
|
|
94
100
|
endedAt: digest.endedAt,
|
|
95
|
-
cwd: digest.cwd,
|
|
101
|
+
cwd: mask(digest.cwd),
|
|
96
102
|
turns: digest.turns,
|
|
97
|
-
agentPreset: digest.agentPreset,
|
|
103
|
+
agentPreset: mask(digest.agentPreset),
|
|
98
104
|
userMessages: digest.userMessages.map((msg) => clip(mask(msg), 400)),
|
|
99
105
|
assistantTail: digest.assistantTail.map((msg) => clip(mask(msg), 600)),
|
|
100
|
-
toolCalls: [...new Set(digest.toolCalls)],
|
|
106
|
+
toolCalls: [...new Set(digest.toolCalls)].map(mask),
|
|
101
107
|
digestText: clip(mask(buildDigestText(digest)), mode === 'brief' ? 400 : cfg.maxCharsPerSession),
|
|
102
108
|
});
|
|
103
109
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stardustlc/dsh-dream",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "DSH
|
|
3
|
+
"version": "0.3.4",
|
|
4
|
+
"description": "DSH 做梦插件:会话间隙回放近期对话、反思写入梦境日记,并把高频教训幂等桥接进 AGENTS.md;默认隐私脱敏,零运行时依赖。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
],
|
|
44
44
|
"license": "MIT",
|
|
45
45
|
"engines": {
|
|
46
|
-
"node": "
|
|
46
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {},
|
|
49
49
|
"devDependencies": {
|