@deepseek-ai/dsh-session-persistence-jsonl 0.0.1-rc.2 → 0.0.1-rc.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.
- package/README.i18n.yaml +1 -1
- package/README.zh.md +10 -10
- package/lib/index.js +2 -2
- package/lib/types/index.d.ts +2 -2
- package/package.json +10 -10
package/README.i18n.yaml
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/session/session-persistence-jsonl/README.md
|
|
5
5
|
README.md: 4cff3215cdb083d2fdb7c4a8f1b60e8c4028ba84
|
|
6
|
-
README.zh.md:
|
|
6
|
+
README.zh.md: 38b41cb9f7fa0f144923feced06152a185254c0a
|
package/README.zh.md
CHANGED
|
@@ -14,9 +14,9 @@ JSONL 持久会话存储后端:`SessionPersistence` 的一个具体实现(`d
|
|
|
14
14
|
session.jsonl # only with compression: 'none'
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
- 第一个逻辑行是不可变的 `SessionHeader`,标记为 `{ type: 'session', version, id, cwd?, createdAt, parentSession?, seedLength?, origin?, delegationDepth, agentPreset? }`。`delegationDepth` 在磁盘上必需,顶层会话为 `0`;缺失或无效值会拒绝日志。`agentPreset`
|
|
18
|
-
- 存储记录是原样 `SessionEvent` JSON,或在 `packChunks` 已启用且连续段符合条件时写入的**打包分片行**(`text-chunks` / `reasoning-chunks` / `tool-call-chunks`;像 header 的 `session` 一样不带斜杠,因此行 tag 不会与事件类型混淆):一行保存至少 3 个连续同 block `assistant/chunk` delta 事件,`seq0`/`time0`
|
|
19
|
-
- 项目目录保留规范化 cwd
|
|
17
|
+
- 第一个逻辑行是不可变的 `SessionHeader`,标记为 `{ type: 'session', version, id, cwd?, createdAt, parentSession?, seedLength?, origin?, delegationDepth, agentPreset? }`。`delegationDepth` 在磁盘上必需,顶层会话为 `0`;缺失或无效值会拒绝日志。`agentPreset` 必须持久化,因为它决定了被恢复会话的工具与提示词——恢复成另一套组装,就会回放模型已无法据以行动的历史。后续每个逻辑行是一条存储记录;`assistant/chunk` 事件绝不丢弃,且 `seq` 在解码日志中保持连续(`events[i].seq === i`)。
|
|
18
|
+
- 存储记录是原样 `SessionEvent` JSON,或在 `packChunks` 已启用且连续段符合条件时写入的**打包分片行**(`text-chunks` / `reasoning-chunks` / `tool-call-chunks`;像 header 的 `session` 一样不带斜杠,因此行 tag 不会与事件类型混淆):一行保存至少 3 个连续同 block `assistant/chunk` delta 事件,`seq0`/`time0` 和各成员的 `dt` 间隔精确重建每个成员的 `seq`/`time`。无损 codec 位于 `@deepseek-ai/dsh-session`(`packChunkRuns`/`decodeStorageRecord`),并使用精确形态 allowlist:任何未识别内容原样存储。读取与布局无关:`load` 始终解码行,因此打包、非打包和混合文件加载结果一致。
|
|
19
|
+
- 项目目录保留规范化 cwd 的可读形式,便于导航,并限制在文件系统组件上限内。分隔符替换和截断刻意有损,因此规范化相同的 cwd 字符串共享项目目录;会话 id 仍选择不同会话目录。在不区分大小写的文件系统上,只有文件系统规范化将两种写法解析到同一 transcript(文本记录)时,身份验证才接受备选路径写法。配置根仍由部署控制:可以是项目本地、共享、临时或集中式。[项目会话目录决策](../../../.agents/notes/implemented/architecture/2026-07-24-project-session-directories.md) 记录这项取舍。
|
|
20
20
|
- 会话 id 是未验证的带品牌类型的字符串,因此在使用前单射转义为一个安全路径段(无遍历、无冲突)。结果目录保留给其他会话自有产物;发现只读取固定 transcript 文件名。
|
|
21
21
|
|
|
22
22
|
## 配置
|
|
@@ -24,7 +24,7 @@ JSONL 持久会话存储后端:`SessionPersistence` 的一个具体实现(`d
|
|
|
24
24
|
| 键 | 类型 | 说明 |
|
|
25
25
|
|---|---|---|
|
|
26
26
|
| `root` | `string`(必需) | 所有会话文件的根目录。**无默认值**:`process.cwd()` 默认值会随进程 cwd 变更(bash 调用、子进程)而分散文件。现有根必须是可读目录;缺失根在第一次实体化时创建。 |
|
|
27
|
-
| `packChunks` | `boolean`(默认 `true`) | 将符合条件的 delta
|
|
27
|
+
| `packChunks` | `boolean`(默认 `true`) | 将符合条件的 delta 分片连续段写为打包行(在真实编程会话上测得逻辑日志约小 60%)。设为 `false` 可用于每事件一行诊断;无论该写入侧开关如何,都能读取打包行。 |
|
|
28
28
|
| `compression` | `'zstd' \| 'none'` | 默认 `'zstd'`;`'none'` 保留换行分隔 UTF-8 文本。 |
|
|
29
29
|
| `preparedSessionCacheSize` | 正整数(默认 `5`) | 冷历史检查后保留、供恢复复用的未发布会话数量上限。 |
|
|
30
30
|
| `writeBatchMaxDelayMs` | 正整数(默认 `200`) | 空闲的活动事件队列收到待写入事件后开启的固定合并窗口。后续事件不会重置窗口;flush 与 teardown 会绕过它。该值不限制事件循环、串行化操作或后端延迟。最大值为 Node 计时器上限 `2_147_483_647` ms。 |
|
|
@@ -43,9 +43,9 @@ JSONL 持久会话存储后端:`SessionPersistence` 的一个具体实现(`d
|
|
|
43
43
|
- **延迟实体化。**`create(meta)` 不写入;第一次 `append` 将编码 header 和第一批写入临时文件并执行 `fsync`。POSIX 通过硬链接无覆盖发布,并对父目录 `fsync`。Windows 通过 `MoveFileExW(..., MOVEFILE_WRITE_THROUGH)` 无覆盖发布,并通过同一 write-through pattern 创建缺失目录。已创建但从未 append 的会话不留下磁盘内容,不在 `list` 中。
|
|
44
44
|
- **仅追加。** 已 flush 事件绝不重写。后续原始批次 append 行;压缩批次 append 一个 frame。两条路径都执行 `fsync`,并在捕获到写入或同步失败时回滚到之前字节长度。
|
|
45
45
|
- **崩溃恢复:保留有效尾部工作。**`load` 验证每个完整压缩 frame,并扫描解压 JSONL。最后 frame 结构不完整时,读取器保留其完整解码记录,从 frame 开头截断,并使用共享[持久化约定](../../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.md) 需要的合成工具、步骤和轮次 closer 重新编码这些记录。原始 mode 从第一个不完整行截断。已经存在却没有完整 header frame 的压缩工件、完整 frame 中的 checksum/解压失败,或位于最后已提交的 `turn/end` 处或之前的缺陷都属于损坏,会被拒绝。
|
|
46
|
-
-
|
|
47
|
-
- **连续 seq。**`append` 拒绝第一个 `seq`
|
|
48
|
-
- **轻量修订。**`listSnapshots(signal?)` 使用 device、inode、size 和纳秒时间戳标识日志,避免解析完整日志;该标识会在 append、修复、替换或存储变更后改变。完整前缀读取要求读取字节前后的身份一致,`readStoredRevision()` 使用同一身份校验保留的 preparation
|
|
46
|
+
- **非修改式检查。**`inspect()` 返回不可变、平衡的逻辑视图,并可在内存中合成恢复 closer,但不会截断不完整尾部或更改轻量修订。
|
|
47
|
+
- **连续 seq。**`append` 拒绝第一个 `seq` 不继续已存储日志的批次,并拒绝无法 JSON 序列化的 `event.data`,同时命名违规事件类型。
|
|
48
|
+
- **轻量修订。**`listSnapshots(signal?)` 使用 device、inode、size 和纳秒时间戳标识日志,避免解析完整日志;该标识会在 append、修复、替换或存储变更后改变。完整前缀读取要求读取字节前后的身份一致,`readStoredRevision()` 使用同一身份校验保留的 preparation,而不加载日志。快照列表通过产物发现原样转发该信号,并在每个 `stat` 前后检查取消;由于文件系统 `stat` 不可中断,取消会等待活动调用完成,然后在不启动另一次调用的情况下拒绝。
|
|
49
49
|
|
|
50
50
|
## 写入路径
|
|
51
51
|
|
|
@@ -57,7 +57,7 @@ JSONL 持久会话存储后端:`SessionPersistence` 的一个具体实现(`d
|
|
|
57
57
|
|
|
58
58
|
#### 模型看到的内容
|
|
59
59
|
|
|
60
|
-
JSONL
|
|
60
|
+
JSONL 存储不会向当前请求提供提示词或 schema。加载会恢复已存储的表层历史,并保留之前的请求 header 用于重建;新 loop 组合当前 envelope。恢复会用 `TOOL_NOT_STARTED` 平衡没有已持久化调用的 assistant 请求;已持久化调用无结果时则变为 `TOOL_OUTCOME_UNKNOWN`,它要求模型只重试只读或幂等工作,并验证可能的副作用或询问用户。原始 `assistant/chunk` 记录不会重复生成消息。
|
|
61
61
|
|
|
62
62
|
#### Token 影响
|
|
63
63
|
|
|
@@ -69,9 +69,9 @@ JSONL 存储不修改实时请求前缀。只有重建历史、当前 envelope
|
|
|
69
69
|
|
|
70
70
|
## 已知限制与暂缓事项
|
|
71
71
|
|
|
72
|
-
- **只加载已配置编码和当前 `SESSION_FORMAT_VERSION
|
|
72
|
+
- **只加载已配置编码和当前 `SESSION_FORMAT_VERSION`(v0)**:更改压缩需要独立/全新根,或选择遗留原始 mode;预发布格式没有迁移。
|
|
73
73
|
- **平铺文件存储布局不加载**:加载前使用独立根,或将预发布产物移入项目/会话目录布局。
|
|
74
74
|
- **压缩文件不能直接按行读取**:使用后端加载;或在写入新根前选择 `compression: 'none'`,以便外部行 reader 使用。
|
|
75
75
|
- **不删除会话文件**:日志在 `root` 下累积,直到外部移除(seam 无删除接口)。
|
|
76
|
-
-
|
|
76
|
+
- **每会话一个活动 writer**:append 和修复只在所属后端实例内协调。在所有者完成完全停稳的 dispose 前,其他后端实例或进程不得写入同一会话;初始同 id 发布仍通过 POSIX 无覆盖硬链接或 Windows 无替换 write-through rename 保持冲突安全。
|
|
77
77
|
- **POSIX 实体化需要硬链接支持**:第一次 append 使用 `link()`,使同 id 竞态失败,而不覆盖已提交日志;Windows 使用无替换 write-through rename。
|
package/lib/index.js
CHANGED
|
@@ -763,7 +763,7 @@ function isENOENT(error) {
|
|
|
763
763
|
* listeners. Its torn-tail marker carries the byte offset and any events
|
|
764
764
|
* recovered from an incomplete final Zstandard frame.
|
|
765
765
|
*/
|
|
766
|
-
var
|
|
766
|
+
var JsonlSessionPersistence = class extends SessionPersistence {
|
|
767
767
|
config;
|
|
768
768
|
supportsRawArtifacts = true;
|
|
769
769
|
static inject = ["sessions"];
|
|
@@ -1458,4 +1458,4 @@ var SessionPersistenceJsonl = class extends SessionPersistence {
|
|
|
1458
1458
|
}
|
|
1459
1459
|
};
|
|
1460
1460
|
//#endregion
|
|
1461
|
-
export { JsonlCompressionSchema,
|
|
1461
|
+
export { JsonlCompressionSchema, JsonlSessionPersistence, JsonlSessionPersistence as default };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ interface JsonlTornMarker {
|
|
|
49
49
|
* listeners. Its torn-tail marker carries the byte offset and any events
|
|
50
50
|
* recovered from an incomplete final Zstandard frame.
|
|
51
51
|
*/
|
|
52
|
-
export declare class
|
|
52
|
+
export declare class JsonlSessionPersistence extends SessionPersistence implements PersistenceBackend<JsonlTornMarker> {
|
|
53
53
|
config: Config;
|
|
54
54
|
readonly supportsRawArtifacts = true;
|
|
55
55
|
static inject: string[];
|
|
@@ -183,5 +183,5 @@ export declare class SessionPersistenceJsonl extends SessionPersistence implemen
|
|
|
183
183
|
private exists;
|
|
184
184
|
private assertLogParentAllowsAbsence;
|
|
185
185
|
}
|
|
186
|
-
export default
|
|
186
|
+
export default JsonlSessionPersistence;
|
|
187
187
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-session-persistence-jsonl",
|
|
3
3
|
"description": "JSONL durable session persistence backend for the DeepSeek Harness",
|
|
4
|
-
"version": "0.0.1-rc.
|
|
4
|
+
"version": "0.0.1-rc.5",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "restricted"
|
|
7
7
|
},
|
|
@@ -32,19 +32,19 @@
|
|
|
32
32
|
],
|
|
33
33
|
"license": "BSD-3-Clause",
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@deepseek-ai/dsh-
|
|
36
|
-
"@deepseek-ai/dsh-session-persistence": "^0.0.1-rc.
|
|
37
|
-
"@deepseek-ai/
|
|
38
|
-
"@deepseek-ai/
|
|
35
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.5",
|
|
36
|
+
"@deepseek-ai/dsh-session-persistence": "^0.0.1-rc.5",
|
|
37
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.5",
|
|
38
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.4"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"koffi": "^3.1.0",
|
|
42
|
-
"@deepseek-ai/schemastery": "^3.18.1-rc.
|
|
42
|
+
"@deepseek-ai/schemastery": "^3.18.1-rc.4"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.
|
|
46
|
-
"@deepseek-ai/dsh-session": "^0.0.1-rc.
|
|
47
|
-
"@deepseek-ai/dsh-session-persistence": "^0.0.1-rc.
|
|
48
|
-
"@deepseek-ai/cordis": "^4.0.1-rc.
|
|
45
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.5",
|
|
46
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.5",
|
|
47
|
+
"@deepseek-ai/dsh-session-persistence": "^0.0.1-rc.5",
|
|
48
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.4"
|
|
49
49
|
}
|
|
50
50
|
}
|