@morlay/session-rdb 0.0.20 → 0.0.21-alpha.0

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 (69) hide show
  1. package/README.md +59 -31
  2. package/dist/artifact.d.mts +25 -65
  3. package/dist/artifact.mjs +2 -2
  4. package/dist/{schema-BkQN5GyT.d.mts → backend-DpdtxYpz.d.mts} +346 -93
  5. package/dist/{branch-Co6xlbi0.mjs → branch-5JzX9rUq.mjs} +163 -52
  6. package/dist/deletion.d.mts +7 -0
  7. package/dist/deletion.mjs +2 -0
  8. package/dist/dist-vIVO6bA-.mjs +1524 -0
  9. package/dist/import.d.mts +4 -4
  10. package/dist/import.mjs +28 -11
  11. package/dist/index.d.mts +2 -3
  12. package/dist/index.mjs +4 -1631
  13. package/dist/{log-DO69NQnn.mjs → log-CnYct2Dv.mjs} +37 -82
  14. package/dist/{sqlite-DYExtbLo.mjs → sqlite-fpvm5Dzs.mjs} +205 -75
  15. package/dist/src-CWTWV7vx.mjs +1904 -0
  16. package/dist/storage.d.mts +14 -5
  17. package/dist/storage.mjs +2 -2
  18. package/dist/testing.d.mts +1 -26
  19. package/dist/testing.mjs +10503 -9614
  20. package/drizzle/postgres/20260918120000_v3_event_usage/migration.sql +14 -0
  21. package/drizzle/postgres/20260918120000_v3_event_usage/snapshot.json +1309 -0
  22. package/drizzle/sqlite/20260918120000_v3_event_usage/migration.sql +14 -0
  23. package/drizzle/sqlite/20260918120000_v3_event_usage/snapshot.json +1031 -0
  24. package/package.json +28 -29
  25. package/src/adapters/to-postgres.ts +1 -3
  26. package/src/adapters/to-sqlite.ts +0 -2
  27. package/src/adapters/types.ts +0 -3
  28. package/src/artifact.ts +0 -2
  29. package/src/backend.ts +31 -2
  30. package/src/branch.ts +223 -135
  31. package/src/deletion.ts +87 -0
  32. package/src/drizzle/postgres-v2.ts +0 -1
  33. package/src/drizzle/postgres-v3.ts +0 -1
  34. package/src/drizzle/sqlite-v2.ts +0 -1
  35. package/src/drizzle/sqlite-v3.ts +0 -1
  36. package/src/entities/v2/session-events.ts +0 -1
  37. package/src/entities/v3/event-usage.ts +25 -0
  38. package/src/entities/v3/events.ts +1 -3
  39. package/src/entities/v3/index.ts +4 -0
  40. package/src/entities/v3/session-events.ts +1 -2
  41. package/src/entities/v3/session-projcache-rows.ts +0 -8
  42. package/src/entities/v3/sessions.ts +3 -3
  43. package/src/entities/v3/storage-units.ts +0 -1
  44. package/src/entities/v3/workspace-sessions.ts +0 -5
  45. package/src/entities/v3/workspace-state.ts +0 -6
  46. package/src/entities/v3/workspaces.ts +0 -5
  47. package/src/export.ts +103 -0
  48. package/src/gc.ts +76 -0
  49. package/src/import-storages.ts +4 -37
  50. package/src/import.ts +54 -31
  51. package/src/index.ts +150 -114
  52. package/src/legacy.ts +4 -42
  53. package/src/log.ts +63 -106
  54. package/src/postgres.ts +249 -22
  55. package/src/schema.ts +6 -6
  56. package/src/session-query.ts +0 -4
  57. package/src/sqlite.ts +231 -55
  58. package/src/storage-takeover/index.ts +2 -28
  59. package/src/storage-takeover/projection-cache.ts +30 -134
  60. package/src/storage-takeover/repository.ts +20 -59
  61. package/src/storage-takeover/storage-backend.ts +3 -33
  62. package/src/storage-takeover/types.ts +14 -56
  63. package/src/storage.ts +0 -2
  64. package/src/testing/contract.ts +19 -50
  65. package/src/testing/coordinator-contract.ts +10 -25
  66. package/src/testing.ts +1 -4
  67. package/src/usage.ts +191 -0
  68. package/dist/index-D55G9n4k.d.mts +0 -271
  69. package/dist/magic-string.es-BgJoa-3K.mjs +0 -1017
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morlay/session-rdb",
3
- "version": "0.0.20",
3
+ "version": "0.0.21-alpha.0",
4
4
  "description": "RDB durable session backend for DeepSeek Harness: implements both session-persistence and session-branch (rewind / retry / fork) providers.",
5
5
  "keywords": [
6
6
  "branch",
@@ -14,7 +14,7 @@
14
14
  "license": "MIT",
15
15
  "repository": {
16
16
  "type": "git",
17
- "url": "https://github.com/morlay/session-rdb.git"
17
+ "url": "https://github.com/morlay/dsh-plugin.git"
18
18
  },
19
19
  "files": [
20
20
  "dist",
@@ -27,42 +27,46 @@
27
27
  "exports": {
28
28
  ".": "./dist/index.mjs",
29
29
  "./artifact": "./dist/artifact.mjs",
30
+ "./deletion": "./dist/deletion.mjs",
31
+ "./export": "./dist/export.mjs",
32
+ "./gc": "./dist/gc.mjs",
30
33
  "./import": "./dist/import.mjs",
31
34
  "./invariant": "./dist/invariant.mjs",
32
35
  "./storage": "./dist/storage.mjs",
33
36
  "./testing": "./dist/testing.mjs",
37
+ "./usage": "./dist/usage.mjs",
34
38
  "./package.json": "./package.json",
35
39
  "./cordis.patch.yml": "./cordis.patch.yml"
36
40
  },
37
41
  "dependencies": {
38
- "@morlay/session-branch": "^0.0.8",
42
+ "@morlay/session-branch": "^0.0.9-alpha.0",
39
43
  "drizzle-orm": "^1.0.0-rc.5-ab785fc",
40
44
  "fflate": "^0.8.2",
41
45
  "pg": "^8.23.0"
42
46
  },
43
47
  "devDependencies": {
44
- "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.2",
45
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2",
46
- "@deepseek-ai/dsh-session-turn-outline": "^0.1.5-rc.2",
47
- "@deepseek-ai/dsh-storage": "^0.1.5-rc.2",
48
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
49
- "@deepseek-ai/dsh-token-meter": "^0.1.5-rc.2",
50
- "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2",
48
+ "@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
49
+ "@deepseek-ai/dsh-session-projection-cache": "^0.1.6-alpha.2",
50
+ "@deepseek-ai/dsh-session-turn-outline": "^0.1.6-alpha.2",
51
+ "@deepseek-ai/dsh-storage": "^0.1.6-alpha.2",
52
+ "@deepseek-ai/dsh-storage-domain": "^0.1.6-alpha.2",
53
+ "@deepseek-ai/dsh-token-meter": "^0.1.6-alpha.2",
54
+ "@deepseek-ai/dsh-workspace": "^0.1.6-alpha.2",
51
55
  "@types/pg": "^8.23.1",
52
56
  "drizzle-kit": "1.0.0-rc.5-ab785fc"
53
57
  },
54
58
  "peerDependencies": {
55
59
  "@deepseek-ai/cordis": "^4.0.2",
56
- "@deepseek-ai/dsh-invariants": "^0.1.5-rc.2",
57
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
58
- "@deepseek-ai/dsh-scope": "^0.1.5-rc.2",
59
- "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
60
- "@deepseek-ai/dsh-session-format": "^0.1.5-rc.2",
61
- "@deepseek-ai/dsh-session-format-catalog": "^0.1.5-rc.2",
62
- "@deepseek-ai/dsh-session-persistence": "^0.1.5-rc.2",
63
- "@deepseek-ai/dsh-session-query": "^0.1.5-rc.2",
64
- "@deepseek-ai/dsh-settings": "^0.1.5-rc.2",
65
- "@deepseek-ai/dsh-storage": "^0.1.5-rc.2",
60
+ "@deepseek-ai/dsh-invariants": "^0.1.6-alpha.2",
61
+ "@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
62
+ "@deepseek-ai/dsh-scope": "^0.1.6-alpha.2",
63
+ "@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
64
+ "@deepseek-ai/dsh-session-format": "^0.1.6-alpha.2",
65
+ "@deepseek-ai/dsh-session-format-catalog": "^0.1.6-alpha.2",
66
+ "@deepseek-ai/dsh-session-persistence": "^0.1.6-alpha.2",
67
+ "@deepseek-ai/dsh-session-query": "^0.1.6-alpha.2",
68
+ "@deepseek-ai/dsh-settings": "^0.1.6-alpha.2",
69
+ "@deepseek-ai/dsh-storage": "^0.1.6-alpha.2",
66
70
  "@deepseek-ai/schemastery": "^3.18.2"
67
71
  },
68
72
  "dsh": {
@@ -72,16 +76,11 @@
72
76
  },
73
77
  "inlinedDependencies": {
74
78
  "@jridgewell/sourcemap-codec": "1.6.0",
75
- "@vitest/expect": "4.1.11",
76
- "@vitest/pretty-format": "4.1.11",
77
- "@vitest/runner": "4.1.11",
78
- "@vitest/snapshot": "4.1.11",
79
- "@vitest/spy": "4.1.11",
80
- "@vitest/utils": "4.1.11",
81
79
  "chai": "6.2.2",
82
- "magic-string": "0.30.21",
83
- "tinyrainbow": "3.1.1",
84
- "vitest": "4.1.11",
80
+ "expect-type": "1.4.0",
81
+ "magic-string": "1.4.1",
82
+ "tinybench": "6.1.4",
83
+ "vitest": "5.0.0",
85
84
  "zod": "4.6.5"
86
85
  },
87
86
  "scripts": {
@@ -18,7 +18,6 @@ import { toProperty, type ColumnDef, type TableDef } from "./types.ts";
18
18
  type TableRegistry = Record<string, AnyPgTable>;
19
19
 
20
20
  function buildColumn(name: string, c: ColumnDef, tables: TableRegistry): AnyPgColumnBuilder {
21
- // 具体 builder 类型与 AnyPgColumnBuilder 在方法层面不兼容,构建阶段用宽松类型。
22
21
  let col: any;
23
22
  switch (c.type) {
24
23
  case "text": {
@@ -58,8 +57,7 @@ export function toPostgresSchema(
58
57
  schemaName = "public",
59
58
  ): Record<string, AnyPgTable> {
60
59
  const tables: TableRegistry = {};
61
- // `pgSchema(name).table` 使表对象携带 schema 限定(查询/DDL 显式引用,
62
- // 不依赖 search_path);public 与无 schema 行为一致。
60
+
63
61
  const table = schemaName === "public" ? pgTable : pgSchema(schemaName).table;
64
62
  for (const def of defs) {
65
63
  const columns: Record<string, AnyPgColumnBuilder> = {};
@@ -15,8 +15,6 @@ import { toProperty, type ColumnDef, type TableDef } from "./types.ts";
15
15
  type TableRegistry = Record<string, AnySQLiteTable>;
16
16
 
17
17
  function buildColumn(name: string, c: ColumnDef, tables: TableRegistry): SQLiteColumnBuilder {
18
- // 具体 builder 类型与基类在方法层面不兼容(泛型逆变),构建阶段用宽松
19
- // 类型合并,返回时收窄为基类;查询类型安全由手写行接口兜底。
20
18
  let col: any;
21
19
  switch (c.type) {
22
20
  case "text": {
@@ -1,5 +1,3 @@
1
- /** drizzle util 层:方言无关的表结构描述(entities 与 adapters 共用)。 */
2
-
3
1
  export type ColumnTypeName = "serial" | "integer" | "bigint" | "text";
4
2
 
5
3
  export type DeleteAction = "cascade" | "set null" | "restrict" | "no action";
@@ -33,7 +31,6 @@ export interface IndexDef {
33
31
  columns: string[];
34
32
  }
35
33
 
36
- /** 表结构描述:columns / checks / uniques / indexes 以 Record 键为名,天然唯一。 */
37
34
  export interface TableDef {
38
35
  name: string;
39
36
  columns: Record<string, ColumnDef>;
package/src/artifact.ts CHANGED
@@ -1,4 +1,2 @@
1
- // 日志 / artifact 格式层:会话日志行处理(scanRows / rowToEvent / 修复)与
2
- // 导入导出 artifact 解析(jsonl / zip)。文件物理分开,经本入口聚合导出。
3
1
  export * from "./log.ts";
4
2
  export * from "./import.ts";
package/src/backend.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { SessionId } from "@deepseek-ai/dsh-session";
2
2
  import type { SessionStorageMetadata } from "@deepseek-ai/dsh-session-persistence";
3
3
  import type { StorageRepository } from "./storage-takeover/types.ts";
4
+ import type { UsageAggregate } from "./usage.ts";
4
5
 
5
6
  export interface SessionRow {
6
7
  fSessionId: string;
@@ -18,6 +19,8 @@ export interface SessionRow {
18
19
  fIncarnation: string;
19
20
 
20
21
  fRevision: number;
22
+
23
+ fArchivedAt: number | null;
21
24
  }
22
25
 
23
26
  export interface EventInsert {
@@ -64,7 +67,6 @@ export interface BackendTx {
64
67
 
65
68
  updateSeedLength(id: SessionId, seedLength: number): Promise<void>;
66
69
 
67
- /** 从事件表重算会话标题(最后一条 `session/title`)并写回会话行。 */
68
70
  refreshTitle(id: SessionId): Promise<void>;
69
71
 
70
72
  insertEvents(events: EventInsert[]): Promise<void>;
@@ -88,6 +90,11 @@ export interface BackendTx {
88
90
  id: SessionId,
89
91
  sequence: number,
90
92
  ): Promise<{ fEventId: string; fSequence: number } | undefined>;
93
+
94
+ deleteSession(id: SessionId): Promise<void>;
95
+
96
+ /** 批量删除整条会话:桥接行、workspace 归属行、投影行与会话行。 */
97
+ deleteSessions(ids: SessionId[]): Promise<number>;
91
98
  }
92
99
 
93
100
  export interface Backend {
@@ -95,7 +102,6 @@ export interface Backend {
95
102
 
96
103
  readonly storeIdentity: string;
97
104
 
98
- /** storages 接管表(workspace 域与投影 checkpoint)的访问层:与事件日志同介质。 */
99
105
  readonly storage: StorageRepository;
100
106
 
101
107
  open(): Promise<void>;
@@ -104,9 +110,32 @@ export interface Backend {
104
110
 
105
111
  getEventRows(id: SessionId, fromSequence?: number): Promise<EventRow[]>;
106
112
 
113
+ getEventTypeAt(id: SessionId, sequence: number): Promise<string | undefined>;
114
+
115
+ getEventTypesBefore(
116
+ id: SessionId,
117
+ beforeSequence: number,
118
+ limit: number,
119
+ ): Promise<Array<Pick<EventRow, "fSequence" | "fType">>>;
120
+
107
121
  listSessions(): Promise<SessionRow[]>;
108
122
 
109
123
  transaction<T>(fn: (tx: BackendTx) => Promise<T>): Promise<T>;
110
124
 
125
+ /** 删除已无桥接行引用的事件行(孤儿),返回删除行数。 */
126
+ collectOrphans(): Promise<number>;
127
+
128
+ /** 父会话已不存在(或没有父)的 subagent 会话:父被删后它们成了孤儿。 */
129
+ listOrphanSubagentSessions(): Promise<SessionId[]>;
130
+
131
+ /**
132
+ * 用量统计的原始聚合:按天×模型×subagent 的桶与按会话的行(事件行去重、排除孤儿)。
133
+ * @param sinceMs - 只算该时刻(含)之后的事件行;省略即全量。
134
+ */
135
+ usageReport(sinceMs?: number): Promise<UsageAggregate>;
136
+
137
+ /** 回收空间与统计(含 VACUUM);不得在事务内执行。 */
138
+ vacuum(): Promise<void>;
139
+
111
140
  close(): Promise<void>;
112
141
  }