@morlay/session-rdb 0.0.15 → 0.0.16-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 (65) hide show
  1. package/README.md +11 -13
  2. package/dist/artifact.d.mts +6 -16
  3. package/dist/artifact.mjs +3 -3
  4. package/dist/{import-DFed8DBt.mjs → import-CKrzjXVB.mjs} +73 -83
  5. package/dist/import.d.mts +2 -3
  6. package/dist/import.mjs +2 -2
  7. package/dist/index-CgGDHQSK.d.mts +225 -0
  8. package/dist/index.d.mts +3 -3
  9. package/dist/index.mjs +694 -169
  10. package/dist/log-DTJsxMud.mjs +314 -0
  11. package/dist/{schema-CFXZURX7.d.mts → schema-COK7-wRV.d.mts} +3 -15
  12. package/dist/sqlite-DCy4VTD8.mjs +698 -0
  13. package/dist/storage.d.mts +2 -7
  14. package/dist/storage.mjs +2 -3
  15. package/dist/testing.d.mts +30 -1
  16. package/dist/testing.mjs +676 -1991
  17. package/drizzle/postgres/20260908072805_v2_initial/migration.sql +58 -0
  18. package/drizzle/postgres/20260908072805_v2_initial/snapshot.json +686 -0
  19. package/drizzle/postgres/20260908072806_v3_drop_original_seq/migration.sql +1 -0
  20. package/drizzle/postgres/20260908072806_v3_drop_original_seq/snapshot.json +673 -0
  21. package/drizzle/sqlite/20260908072751_v2_initial/migration.sql +53 -0
  22. package/drizzle/sqlite/20260908072751_v2_initial/snapshot.json +492 -0
  23. package/drizzle/sqlite/20260908072752_v3_drop_original_seq/migration.sql +6 -0
  24. package/drizzle/sqlite/20260908072752_v3_drop_original_seq/snapshot.json +513 -0
  25. package/package.json +17 -12
  26. package/src/adapters/index.ts +10 -2
  27. package/src/adapters/to-postgres.ts +19 -15
  28. package/src/adapters/to-sqlite.ts +20 -14
  29. package/src/{entities → adapters}/types.ts +7 -8
  30. package/src/backend.ts +0 -7
  31. package/src/branch.ts +29 -110
  32. package/src/drizzle/postgres-v2.ts +11 -0
  33. package/src/drizzle/postgres-v3.ts +11 -0
  34. package/src/drizzle/sqlite-v2.ts +10 -0
  35. package/src/drizzle/sqlite-v3.ts +11 -0
  36. package/src/entities/index.ts +2 -30
  37. package/src/entities/v2/index.ts +20 -0
  38. package/src/entities/v2/session-events.ts +11 -0
  39. package/src/entities/v3/events.ts +27 -0
  40. package/src/entities/v3/index.ts +27 -0
  41. package/src/entities/v3/persistence-state.ts +10 -0
  42. package/src/entities/v3/schema-meta.ts +9 -0
  43. package/src/entities/v3/session-events.ts +26 -0
  44. package/src/entities/v3/sessions.ts +20 -0
  45. package/src/import.ts +65 -57
  46. package/src/index.ts +868 -223
  47. package/src/invariant.ts +0 -2
  48. package/src/legacy.ts +67 -0
  49. package/src/log.ts +41 -87
  50. package/src/postgres.ts +75 -93
  51. package/src/schema.ts +3 -14
  52. package/src/sqlite.ts +59 -46
  53. package/src/testing/contract.ts +460 -375
  54. package/src/testing/coordinator-contract.ts +108 -1374
  55. package/src/testing.ts +1 -6
  56. package/dist/index-uUvn6gYp.d.mts +0 -111
  57. package/dist/schema-vwzwEXNE.mjs +0 -878
  58. package/dist/sqlite-CG_Qcx5C.mjs +0 -356
  59. package/src/adapters/ddl.ts +0 -77
  60. package/src/entities/events.ts +0 -27
  61. package/src/entities/persistence-state.ts +0 -10
  62. package/src/entities/schema-meta.ts +0 -9
  63. package/src/entities/session-events.ts +0 -29
  64. package/src/entities/sessions.ts +0 -20
  65. package/src/migrate.ts +0 -137
@@ -1,878 +0,0 @@
1
- import { SessionSeq, encodeSeqRanges, packChunkRuns } from "@deepseek-ai/dsh-session";
2
- import { sql } from "drizzle-orm";
3
- import { check, index, integer, sqliteTable, text, unique } from "drizzle-orm/sqlite-core";
4
- import { bigint, check as check$1, index as index$1, integer as integer$1, pgSchema, pgTable, serial, text as text$1, unique as unique$1 } from "drizzle-orm/pg-core";
5
- //#region src/log.ts
6
- function rowToMeta(row) {
7
- if (!Number.isSafeInteger(row.fCreatedAt) || row.fCreatedAt < 0) throw new Error("stored session createdAt must be a non-negative safe integer");
8
- return {
9
- version: row.fVersion,
10
- id: row.fSessionId,
11
- createdAt: row.fCreatedAt,
12
- ...row.fCwd !== null ? { cwd: row.fCwd } : {},
13
- ...row.fParentSession !== null ? { parentSession: row.fParentSession } : {},
14
- isSeeded: row.fSeedLength !== null,
15
- ...row.fOrigin !== null ? { origin: row.fOrigin } : {},
16
- ...row.fDelegationDepth === null ? {} : { delegationDepth: row.fDelegationDepth }
17
- };
18
- }
19
- function sessionInsertRow(storage, incarnation) {
20
- const meta = storage.meta;
21
- return {
22
- fSessionId: meta.id,
23
- fHeadEventId: "",
24
- fHeadSequence: -1,
25
- fVersion: meta.version,
26
- fCreatedAt: meta.createdAt,
27
- fCwd: meta.cwd ?? null,
28
- fParentSession: meta.parentSession ?? null,
29
- fSeedLength: meta.isSeeded ? storage.inheritedEventCount : null,
30
- fOrigin: meta.origin ?? null,
31
- fDelegationDepth: meta.delegationDepth ?? null,
32
- fIncarnation: incarnation,
33
- fRevision: 0
34
- };
35
- }
36
- function sessionConflictRow(storage) {
37
- const meta = storage.meta;
38
- return {
39
- fVersion: meta.version,
40
- fCreatedAt: meta.createdAt,
41
- fCwd: meta.cwd ?? null,
42
- fParentSession: meta.parentSession ?? null,
43
- fSeedLength: meta.isSeeded ? storage.inheritedEventCount : null,
44
- fOrigin: meta.origin ?? null,
45
- fDelegationDepth: meta.delegationDepth ?? null
46
- };
47
- }
48
- function remapSurfaceOp(op, remap) {
49
- if (op === "append") return op;
50
- return {
51
- op: "replace",
52
- start: SessionSeq(remap(op.start)),
53
- end: SessionSeq(remap(op.end))
54
- };
55
- }
56
- function remapShadowedRange(range, remap) {
57
- return {
58
- start: remap(range.start),
59
- end: remap(range.end)
60
- };
61
- }
62
- function remapShadowedSeqs(seqs, seqMap) {
63
- return seqs.flatMap((seq) => {
64
- const dense = seqMap.get(seq);
65
- return dense === void 0 ? [] : [dense];
66
- });
67
- }
68
- function rowToEvent(row, seqMap) {
69
- const remap = (seq) => seqMap.get(seq) ?? seq;
70
- const surfaceOp = row.fSurfaceOp !== null ? remapSurfaceOp(JSON.parse(row.fSurfaceOp), remap) : void 0;
71
- const data = JSON.parse(row.fData);
72
- if (row.fType === "compaction/summary" || row.fType === "compaction/prune") {
73
- const metering = data;
74
- if (metering.shadowedRange !== void 0) metering.shadowedRange = remapShadowedRange(metering.shadowedRange, remap);
75
- if (metering.shadowedSeqs !== void 0) metering.shadowedSeqs = remapShadowedSeqs(metering.shadowedSeqs, seqMap);
76
- }
77
- return {
78
- type: row.fType,
79
- seq: row.fSequence,
80
- time: row.fCreatedAt,
81
- data,
82
- ...surfaceOp === void 0 ? {} : { surfaceOp }
83
- };
84
- }
85
- function buildSeqMap(rows) {
86
- const map = /* @__PURE__ */ new Map();
87
- for (const row of rows) if (!map.has(row.fOriginalSeq)) map.set(row.fOriginalSeq, row.fSequence);
88
- return map;
89
- }
90
- const SURFACE_EVENT_TYPES = /* @__PURE__ */ new Set([
91
- "user/message",
92
- "assistant/message",
93
- "tool/result"
94
- ]);
95
- const METERING_EVENT_TYPES = /* @__PURE__ */ new Set(["compaction/summary", "compaction/prune"]);
96
- /**
97
- * 读取时重计算 replace 的 sourceEventSeqs(sourceEventSeqs 不落库)。
98
- *
99
- * 优先采用紧邻 metering 事件(compaction/summary | compaction/prune)的
100
- * shadowedSeqs:它是压缩事务落库的**权威被遮蔽节点列表**(range 只是首尾
101
- * 边界对,压缩竞态下可能漏掉并发落地的节点——range 数值扫描会漏掉这些
102
- * 节点,使上游 assertProvenance 报 missing)。shadowedSeqs 已由 rowToEvent
103
- * 重映射到稠密坐标,与 replace 的 surfaceOp range 同空间。
104
- *
105
- * 无紧邻 metering 事件时回退到 range 数值扫描(历史数据 / 非压缩 replace,
106
- * 如 tool-result pruner 的旧样式),保证既有行为不变。
107
- */
108
- function recomputeReplaceProvenance(events) {
109
- for (let i = 0; i < events.length; i++) {
110
- const raw = events[i];
111
- const op = raw.surfaceOp;
112
- if (typeof op !== "object" || op === null || op.op !== "replace") continue;
113
- const { start, end } = op;
114
- const metering = i > 0 ? events[i - 1] : void 0;
115
- const meteringData = metering !== void 0 && METERING_EVENT_TYPES.has(metering.type) ? metering.data : void 0;
116
- if (meteringData?.shadowedSeqs !== void 0) {
117
- raw.sourceEventSeqs = meteringData.shadowedSeqs;
118
- continue;
119
- }
120
- const refs = [];
121
- for (const candidate of events) if (candidate.seq >= start && candidate.seq <= end && SURFACE_EVENT_TYPES.has(candidate.type)) refs.push(candidate.seq);
122
- raw.sourceEventSeqs = refs;
123
- }
124
- }
125
- function isEventSeqLike(value) {
126
- return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0);
127
- }
128
- function isDeepEqualJson(a, b) {
129
- if (a === b) return true;
130
- if (Array.isArray(a) || Array.isArray(b)) {
131
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
132
- return a.every((item, i) => isDeepEqualJson(item, b[i]));
133
- }
134
- if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
135
- const aKeys = Object.keys(a);
136
- const bRecord = b;
137
- if (aKeys.length !== Object.keys(bRecord).length) return false;
138
- return aKeys.every((key) => Object.hasOwn(bRecord, key) && isDeepEqualJson(a[key], bRecord[key]));
139
- }
140
- function toolResultRewriteContentOnly(original, replacement) {
141
- const originalData = original.data;
142
- const replacementData = replacement.data;
143
- const originalMessage = originalData["message"];
144
- const replacementMessage = replacementData["message"];
145
- const originalContent = Array.isArray(originalMessage?.content) ? originalMessage.content : void 0;
146
- const replacementContent = Array.isArray(replacementMessage?.content) ? replacementMessage.content : void 0;
147
- if (originalContent === void 0 || replacementContent === void 0) return false;
148
- return isDeepEqualJson({
149
- ...originalData,
150
- message: {
151
- ...originalMessage,
152
- content: [{
153
- ...originalContent[0],
154
- content: null
155
- }]
156
- }
157
- }, {
158
- ...replacementData,
159
- message: {
160
- ...replacementMessage,
161
- content: [{
162
- ...replacementContent[0],
163
- content: null
164
- }]
165
- }
166
- });
167
- }
168
- function findSurfaceRepairs(events) {
169
- const nodes = [];
170
- const degradeToAppend = /* @__PURE__ */ new Set();
171
- const addAppendMarker = /* @__PURE__ */ new Set();
172
- const clearSurfaceOp = /* @__PURE__ */ new Set();
173
- for (const event of events) {
174
- const op = event.surfaceOp;
175
- if (op === void 0) {
176
- if (SURFACE_EVENT_TYPES.has(event.type)) {
177
- addAppendMarker.add(event.seq);
178
- nodes.push(event.seq);
179
- }
180
- continue;
181
- }
182
- if (op === "append") {
183
- if (SURFACE_EVENT_TYPES.has(event.type)) nodes.push(event.seq);
184
- else clearSurfaceOp.add(event.seq);
185
- continue;
186
- }
187
- if (!SURFACE_EVENT_TYPES.has(event.type)) {
188
- clearSurfaceOp.add(event.seq);
189
- continue;
190
- }
191
- const replace = typeof op === "object" && op !== null && !Array.isArray(op) ? op : void 0;
192
- const start = replace?.["start"];
193
- const end = replace?.["end"];
194
- const shapeOk = replace !== void 0 && replace["op"] === "replace" && isEventSeqLike(start) && isEventSeqLike(end);
195
- const startIdx = shapeOk ? nodes.indexOf(start) : -1;
196
- const endIdx = shapeOk ? nodes.indexOf(end) : -1;
197
- const rangeOk = shapeOk && startIdx !== -1 && endIdx !== -1 && startIdx <= endIdx;
198
- let rewriteOk = true;
199
- if (rangeOk && event.type === "tool/result") {
200
- const shadowed = nodes.slice(startIdx, endIdx + 1);
201
- if (shadowed.length !== 1) rewriteOk = false;
202
- else {
203
- const original = events[shadowed[0]];
204
- rewriteOk = original?.type === "tool/result" && toolResultRewriteContentOnly(original, event);
205
- }
206
- }
207
- if (!rangeOk || !rewriteOk) {
208
- degradeToAppend.add(event.seq);
209
- nodes.push(event.seq);
210
- continue;
211
- }
212
- nodes.splice(startIdx, endIdx - startIdx + 1, event.seq);
213
- }
214
- return {
215
- degradeToAppend,
216
- addAppendMarker,
217
- clearSurfaceOp
218
- };
219
- }
220
- function repairSurfaceOps(events) {
221
- const repairs = findSurfaceRepairs(events);
222
- if (repairs.degradeToAppend.size === 0 && repairs.addAppendMarker.size === 0 && repairs.clearSurfaceOp.size === 0) return;
223
- for (const event of events) {
224
- const raw = event;
225
- if (repairs.degradeToAppend.has(event.seq)) raw.surfaceOp = "append";
226
- else if (repairs.addAppendMarker.has(event.seq)) raw.surfaceOp = "append";
227
- else if (repairs.clearSurfaceOp.has(event.seq)) delete raw.surfaceOp;
228
- }
229
- }
230
- /**
231
- * 定位无法从空状态增量重放的 agent/inbox/spliced 事件(孤儿操作)。
232
- *
233
- * 上游 Inbox 每次构造都从会话起点重放全部 inbox splice,失败即拒绝整个
234
- * 会话(resume / 编辑重放不可用)。rewind 截断历史轮次后若残留 splice 引用
235
- * 已被截断的排队消息(插入被删、消费保留,或反之),重放时越界或重复——
236
- * 无法独立重放。
237
- */
238
- function orphanInboxSpliceSeqs(events) {
239
- const inbox = {
240
- "next-turn": [],
241
- "next-step": []
242
- };
243
- const orphan = /* @__PURE__ */ new Set();
244
- for (const raw of events) {
245
- const event = raw;
246
- if (event.type !== "agent/inbox/spliced") continue;
247
- const { target, start, removedCount, inserted } = event.data;
248
- const list = typeof target === "string" ? inbox[target] : void 0;
249
- if (list === void 0) {
250
- orphan.add(event.seq);
251
- continue;
252
- }
253
- const removed = removedCount ?? 0;
254
- const parsedInserted = (inserted ?? []).map((m) => ({ id: typeof m.id === "string" ? m.id : "" }));
255
- if (!Number.isSafeInteger(start) || start < 0 || start > list.length || !Number.isSafeInteger(removed) || removed < 0 || start + removed > list.length) {
256
- orphan.add(event.seq);
257
- continue;
258
- }
259
- const candidate = [
260
- ...list.slice(0, start),
261
- ...parsedInserted,
262
- ...list.slice(start + removed)
263
- ];
264
- const other = (target === "next-turn" ? inbox["next-step"] : inbox["next-turn"]) ?? [];
265
- const seen = /* @__PURE__ */ new Set();
266
- let dup = false;
267
- for (const m of [...candidate, ...other]) {
268
- if (m.id === "") continue;
269
- if (seen.has(m.id)) {
270
- dup = true;
271
- break;
272
- }
273
- seen.add(m.id);
274
- }
275
- if (dup) {
276
- orphan.add(event.seq);
277
- continue;
278
- }
279
- list.splice(start, removed, ...parsedInserted);
280
- }
281
- return orphan;
282
- }
283
- /** 内存修复:把孤儿 inbox splice 改写为 no-op(调用方负责持久化)。 */
284
- function repairOrphanInboxSplices(events) {
285
- const orphan = orphanInboxSpliceSeqs(events);
286
- if (orphan.size === 0) return;
287
- for (const event of events) {
288
- if (!orphan.has(event.seq)) continue;
289
- const target = event.data.target;
290
- event.data = {
291
- ...typeof target === "string" ? { target } : { target: "next-turn" },
292
- start: 0,
293
- removedCount: 0,
294
- inserted: []
295
- };
296
- }
297
- }
298
- function scanRows(rows, base = 0, seqMap = /* @__PURE__ */ new Map()) {
299
- const parsed = rows.map((row) => {
300
- try {
301
- return {
302
- ok: true,
303
- event: rowToEvent(row, seqMap)
304
- };
305
- } catch {
306
- return { ok: false };
307
- }
308
- });
309
- let lastTurnEnd = -1;
310
- for (let i = parsed.length - 1; i >= 0; i--) if (parsed[i]?.ok && rows[i]?.fType === "turn/end") {
311
- lastTurnEnd = i;
312
- break;
313
- }
314
- const preserved = [];
315
- for (let i = 0; i < rows.length; i++) {
316
- const p = parsed[i];
317
- if (!p?.ok || p.event === void 0) {
318
- if (i <= lastTurnEnd) throw new Error(`corrupt session log: unparsable committed event at seq ${rows[i]?.fSequence}`);
319
- break;
320
- }
321
- if (p.event.seq !== base + i) {
322
- if (i <= lastTurnEnd) throw new Error(`corrupt session log: seq gap in committed region (expected ${base + i}, got ${p.event.seq})`);
323
- break;
324
- }
325
- preserved.push(p.event);
326
- }
327
- return preserved.length < rows.length ? {
328
- preserved,
329
- tornFrom: base + preserved.length
330
- } : { preserved };
331
- }
332
- function toStorageRecord(record) {
333
- const withSeqs = record;
334
- if (withSeqs.sourceEventSeqs === void 0) return record;
335
- return {
336
- ...record,
337
- sourceEventSeqs: encodeSeqRanges(withSeqs.sourceEventSeqs)
338
- };
339
- }
340
- function toJsonlArtifact(meta, inheritedEventCount, events) {
341
- const header = {
342
- type: "session",
343
- version: meta.version,
344
- id: meta.id,
345
- createdAt: meta.createdAt,
346
- ...meta.cwd === void 0 ? {} : { cwd: meta.cwd },
347
- ...meta.parentSession === void 0 ? {} : { parentSession: meta.parentSession },
348
- ...meta.isSeeded ? { seedLength: inheritedEventCount } : {},
349
- ...meta.origin === void 0 ? {} : { origin: meta.origin },
350
- delegationDepth: meta.delegationDepth ?? 0,
351
- ...meta.agentPreset === void 0 ? {} : { agentPreset: meta.agentPreset }
352
- };
353
- const lines = [JSON.stringify(header)];
354
- for (const record of packChunkRuns(events)) lines.push(JSON.stringify(toStorageRecord(record)));
355
- return lines.join("\n");
356
- }
357
- //#endregion
358
- //#region src/entities/types.ts
359
- function toProperty(name) {
360
- return name.replace(/_([a-z])/g, (_match, char) => char.toUpperCase());
361
- }
362
- //#endregion
363
- //#region src/adapters/to-sqlite.ts
364
- function buildColumn$1(c, tables) {
365
- let col;
366
- switch (c.type) {
367
- case "text":
368
- col = text(c.name);
369
- break;
370
- case "serial":
371
- col = integer(c.name).primaryKey({ autoIncrement: true });
372
- break;
373
- case "integer":
374
- case "bigint": {
375
- const built = integer(c.name);
376
- col = c.primaryKey ? built.primaryKey() : built;
377
- break;
378
- }
379
- }
380
- if (c.notNull) col = col.notNull();
381
- if (c.default !== void 0) col = col.default(c.default);
382
- if (c.unique) col = col.unique();
383
- if (c.references) {
384
- const { table, column, onDelete } = c.references;
385
- col = col.references(() => tables[table][toProperty(column)], { onDelete });
386
- }
387
- return col;
388
- }
389
- function toSqliteSchema(defs) {
390
- const tables = {};
391
- for (const def of defs) {
392
- const columns = {};
393
- for (const c of def.columns) columns[toProperty(c.name)] = buildColumn$1(c, tables);
394
- const extra = (self) => [
395
- ...(def.checks ?? []).map((c) => check(c.name, sql.raw(c.expression))),
396
- ...(def.uniques ?? []).map((u) => unique(u.name).on(...u.columns.map((name) => self[toProperty(name)]))),
397
- ...(def.indexes ?? []).map((i) => index(i.name).on(...i.columns.map((name) => self[toProperty(name)])))
398
- ];
399
- tables[def.name] = sqliteTable(def.name, columns, extra);
400
- }
401
- return tables;
402
- }
403
- //#endregion
404
- //#region src/adapters/to-postgres.ts
405
- function buildColumn(c, tables) {
406
- let col;
407
- switch (c.type) {
408
- case "text":
409
- col = text$1(c.name);
410
- break;
411
- case "serial":
412
- col = serial(c.name).primaryKey();
413
- break;
414
- case "integer": {
415
- const built = integer$1(c.name);
416
- col = c.primaryKey ? built.primaryKey() : built;
417
- break;
418
- }
419
- case "bigint": {
420
- const built = bigint(c.name, { mode: "number" });
421
- col = c.primaryKey ? built.primaryKey() : built;
422
- break;
423
- }
424
- }
425
- if (c.notNull) col = col.notNull();
426
- if (c.default !== void 0) col = col.default(c.default);
427
- if (c.unique) col = col.unique();
428
- if (c.references) {
429
- const { table, column, onDelete } = c.references;
430
- col = col.references(() => tables[table][toProperty(column)], { onDelete });
431
- }
432
- return col;
433
- }
434
- function toPostgresSchema(defs, schemaName = "public") {
435
- const tables = {};
436
- const table = schemaName === "public" ? pgTable : pgSchema(schemaName).table;
437
- for (const def of defs) {
438
- const columns = {};
439
- for (const c of def.columns) columns[toProperty(c.name)] = buildColumn(c, tables);
440
- const extra = (self) => [
441
- ...(def.checks ?? []).map((c) => check$1(c.name, sql.raw(c.expression))),
442
- ...(def.uniques ?? []).map((u) => unique$1(u.name).on(...u.columns.map((name) => self[toProperty(name)]))),
443
- ...(def.indexes ?? []).map((i) => index$1(i.name).on(...i.columns.map((name) => self[toProperty(name)])))
444
- ];
445
- tables[def.name] = table(def.name, columns, extra);
446
- }
447
- return tables;
448
- }
449
- //#endregion
450
- //#region src/entities/persistence-state.ts
451
- const persistenceState = {
452
- name: "t_persistence_state",
453
- columns: [{
454
- name: "f_singleton",
455
- type: "integer",
456
- primaryKey: true
457
- }, {
458
- name: "f_store_id",
459
- type: "text",
460
- notNull: true
461
- }],
462
- checks: [{
463
- name: "ck_persistence_state_singleton",
464
- expression: "f_singleton = 1"
465
- }]
466
- };
467
- //#endregion
468
- //#region src/entities/schema-meta.ts
469
- const schemaMeta = {
470
- name: "t_schema_meta",
471
- columns: [{
472
- name: "f_key",
473
- type: "text",
474
- primaryKey: true
475
- }, {
476
- name: "f_value",
477
- type: "text",
478
- notNull: true
479
- }]
480
- };
481
- //#endregion
482
- //#region src/entities/sessions.ts
483
- const sessions = {
484
- name: "t_sessions",
485
- columns: [
486
- {
487
- name: "f_id",
488
- type: "serial",
489
- primaryKey: true
490
- },
491
- {
492
- name: "f_session_id",
493
- type: "text",
494
- notNull: true,
495
- unique: true
496
- },
497
- {
498
- name: "f_head_event_id",
499
- type: "text",
500
- notNull: true,
501
- default: ""
502
- },
503
- {
504
- name: "f_head_sequence",
505
- type: "integer",
506
- notNull: true,
507
- default: -1
508
- },
509
- {
510
- name: "f_version",
511
- type: "integer",
512
- notNull: true
513
- },
514
- {
515
- name: "f_created_at",
516
- type: "bigint",
517
- notNull: true
518
- },
519
- {
520
- name: "f_cwd",
521
- type: "text"
522
- },
523
- {
524
- name: "f_parent_session",
525
- type: "text"
526
- },
527
- {
528
- name: "f_seed_length",
529
- type: "integer"
530
- },
531
- {
532
- name: "f_origin",
533
- type: "text"
534
- },
535
- {
536
- name: "f_delegation_depth",
537
- type: "integer"
538
- },
539
- {
540
- name: "f_incarnation",
541
- type: "text",
542
- notNull: true
543
- },
544
- {
545
- name: "f_revision",
546
- type: "integer",
547
- notNull: true
548
- }
549
- ]
550
- };
551
- //#endregion
552
- //#region src/entities/events.ts
553
- const events = {
554
- name: "t_events",
555
- columns: [
556
- {
557
- name: "f_id",
558
- type: "serial",
559
- primaryKey: true
560
- },
561
- {
562
- name: "f_event_id",
563
- type: "text",
564
- notNull: true,
565
- unique: true
566
- },
567
- {
568
- name: "f_parent_id",
569
- type: "text",
570
- notNull: true,
571
- default: ""
572
- },
573
- {
574
- name: "f_type",
575
- type: "text",
576
- notNull: true,
577
- default: ""
578
- },
579
- {
580
- name: "f_kind",
581
- type: "text",
582
- notNull: true,
583
- default: ""
584
- },
585
- {
586
- name: "f_role",
587
- type: "text",
588
- notNull: true,
589
- default: ""
590
- },
591
- {
592
- name: "f_name",
593
- type: "text",
594
- notNull: true,
595
- default: ""
596
- },
597
- {
598
- name: "f_action_id",
599
- type: "text",
600
- notNull: true,
601
- default: ""
602
- },
603
- {
604
- name: "f_encoding",
605
- type: "text",
606
- notNull: true,
607
- default: ""
608
- },
609
- {
610
- name: "f_data",
611
- type: "text",
612
- notNull: true
613
- },
614
- {
615
- name: "f_created_at",
616
- type: "bigint",
617
- notNull: true,
618
- default: 0
619
- }
620
- ],
621
- indexes: [
622
- {
623
- name: "idx_events_kind",
624
- columns: ["f_kind"]
625
- },
626
- {
627
- name: "idx_events_role",
628
- columns: ["f_role"]
629
- },
630
- {
631
- name: "idx_events_name",
632
- columns: ["f_name"]
633
- },
634
- {
635
- name: "idx_events_action_id",
636
- columns: ["f_action_id"]
637
- }
638
- ]
639
- };
640
- //#endregion
641
- //#region src/entities/session-events.ts
642
- const sessionEvents = {
643
- name: "t_session_events",
644
- columns: [
645
- {
646
- name: "f_id",
647
- type: "serial",
648
- primaryKey: true
649
- },
650
- {
651
- name: "f_session_id",
652
- type: "text",
653
- notNull: true,
654
- references: {
655
- table: "t_sessions",
656
- column: "f_session_id",
657
- onDelete: "cascade"
658
- }
659
- },
660
- {
661
- name: "f_event_id",
662
- type: "text",
663
- notNull: true,
664
- references: {
665
- table: "t_events",
666
- column: "f_event_id",
667
- onDelete: "cascade"
668
- }
669
- },
670
- {
671
- name: "f_sequence",
672
- type: "integer",
673
- notNull: true
674
- },
675
- {
676
- name: "f_original_seq",
677
- type: "integer",
678
- notNull: true
679
- },
680
- {
681
- name: "f_surface_op",
682
- type: "text"
683
- }
684
- ],
685
- uniques: [{
686
- name: "uq_session_events_session_sequence",
687
- columns: ["f_session_id", "f_sequence"]
688
- }],
689
- indexes: [{
690
- name: "idx_session_events_event_id",
691
- columns: ["f_event_id"]
692
- }]
693
- };
694
- //#endregion
695
- //#region src/entities/index.ts
696
- const sqliteTableDefs = [
697
- persistenceState,
698
- sessions,
699
- events,
700
- sessionEvents
701
- ];
702
- const postgresTableDefs = [
703
- persistenceState,
704
- schemaMeta,
705
- sessions,
706
- events,
707
- sessionEvents
708
- ];
709
- //#endregion
710
- //#region src/schema.ts
711
- const SCHEMA_VERSION = 2;
712
- const SESSION_PERSISTENCE_SQLITE_APPLICATION_ID = 1146308688;
713
- const EPHEMERAL_EVENT_TYPES = ["assistant/chunk"];
714
- const EVENT_ENCODING = "json";
715
- const sqliteTables = toSqliteSchema(sqliteTableDefs);
716
- const tPersistenceState = sqliteTables["t_persistence_state"];
717
- const tSessions = sqliteTables["t_sessions"];
718
- const tEvents = sqliteTables["t_events"];
719
- const tSessionEvents = sqliteTables["t_session_events"];
720
- const DEFAULT_BUSY_TIMEOUT_MS = 5e3;
721
- function isEphemeralType(type) {
722
- return EPHEMERAL_EVENT_TYPES.includes(type);
723
- }
724
- function isPersistedEvent(event) {
725
- return !isEphemeralType(event.type) && event.ignorable !== true;
726
- }
727
- function eventKind(event) {
728
- switch (event.type) {
729
- case "user/message": return "message";
730
- case "assistant/message":
731
- if ((event.data.message?.content)?.some((block) => block?.type === "reasoning")) return "thinking";
732
- return "message";
733
- case "turn/start":
734
- case "turn/end":
735
- case "step/start":
736
- case "step/end":
737
- case "session/end-seed": return "turn";
738
- case "tool/call":
739
- case "tool/result":
740
- case "tool/code-dispatch-start":
741
- case "tool/code-dispatch": return "tool";
742
- case "request/header":
743
- case "request/context": return "request";
744
- case "model/selection":
745
- case "permission/preset":
746
- case "approval/policy":
747
- case "sandbox/mode":
748
- case "plan/mode":
749
- case "agent-preset/selected": return "config";
750
- case "approval/asked":
751
- case "approval/decided":
752
- case "command/run":
753
- case "command/done":
754
- case "hook/invoked":
755
- case "hook/result":
756
- case "feedback/record": return "audit";
757
- case "session/title":
758
- case "session/title-llm-request":
759
- case "session-log-deepseek/delivery-accepted": return "lifecycle";
760
- case "agent/inbox/spliced": return "inbox";
761
- case "compaction/start":
762
- case "compaction/end":
763
- case "compaction/summary":
764
- case "compaction/prune": return "compaction";
765
- case "llm/retry":
766
- case "llm/retry-started": return "llm";
767
- case "subagent/descriptor":
768
- case "subagent/model-selection-policy": return "subagent";
769
- case "team/member":
770
- case "team/task":
771
- case "team/message/queued":
772
- case "team/message/delivered": return "team";
773
- case "tool-workflow/run-start":
774
- case "tool-workflow/run-end":
775
- case "tool-workflow/agent-start":
776
- case "tool-workflow/agent-end": return "workflow";
777
- case "goal/change": return "goal";
778
- case "schedule/change": return "schedule";
779
- case "todo/write": return "todo";
780
- case "web/deepseek-search-llm-request": return "web";
781
- default: return "";
782
- }
783
- }
784
- function eventDimensions(event) {
785
- const kind = eventKind(event);
786
- const type = event.type;
787
- const data = event.data;
788
- switch (type) {
789
- case "user/message": return {
790
- kind,
791
- role: "user",
792
- name: "",
793
- actionId: ""
794
- };
795
- case "assistant/message": return {
796
- kind,
797
- role: "assistant",
798
- name: "",
799
- actionId: ""
800
- };
801
- case "tool/result": return {
802
- kind,
803
- role: "tool",
804
- name: "",
805
- actionId: data["message"]?.content?.[0]?.toolCallId ?? ""
806
- };
807
- case "tool/call": return {
808
- kind,
809
- role: "",
810
- name: typeof data["name"] === "string" ? data["name"] : "",
811
- actionId: typeof data["callId"] === "string" ? data["callId"] : ""
812
- };
813
- case "tool/code-dispatch-start":
814
- case "tool/code-dispatch": return {
815
- kind,
816
- role: "",
817
- name: "",
818
- actionId: typeof data["subCallId"] === "string" ? data["subCallId"] : ""
819
- };
820
- case "command/run":
821
- case "command/done": return {
822
- kind,
823
- role: "",
824
- name: type === "command/run" && typeof data["name"] === "string" ? data["name"] : "",
825
- actionId: typeof data["commandId"] === "string" ? data["commandId"] : ""
826
- };
827
- case "approval/asked":
828
- case "approval/decided": return {
829
- kind,
830
- role: "",
831
- name: "",
832
- actionId: typeof data["id"] === "string" ? data["id"] : ""
833
- };
834
- case "hook/invoked":
835
- case "hook/result": return {
836
- kind,
837
- role: "",
838
- name: "",
839
- actionId: typeof data["handlerId"] === "string" ? data["handlerId"] : ""
840
- };
841
- case "llm/retry":
842
- case "llm/retry-started": return {
843
- kind,
844
- role: "",
845
- name: "",
846
- actionId: typeof data["retryId"] === "string" ? data["retryId"] : ""
847
- };
848
- case "tool-workflow/run-start":
849
- case "tool-workflow/run-end":
850
- case "tool-workflow/agent-start":
851
- case "tool-workflow/agent-end": return {
852
- kind,
853
- role: "",
854
- name: "",
855
- actionId: typeof data["runId"] === "string" ? data["runId"] : ""
856
- };
857
- case "todo/write": return {
858
- kind,
859
- role: "",
860
- name: "todos",
861
- actionId: ""
862
- };
863
- case "subagent/descriptor": return {
864
- kind,
865
- role: "",
866
- name: typeof data["label"] === "string" ? data["label"] : "",
867
- actionId: ""
868
- };
869
- default: return {
870
- kind,
871
- role: "",
872
- name: "",
873
- actionId: ""
874
- };
875
- }
876
- }
877
- //#endregion
878
- export { sessionInsertRow as A, remapSurfaceOp as C, rowToMeta as D, rowToEvent as E, scanRows as O, remapShadowedSeqs as S, repairSurfaceOps as T, buildSeqMap as _, SESSION_PERSISTENCE_SQLITE_APPLICATION_ID as a, recomputeReplaceProvenance as b, isEphemeralType as c, tPersistenceState as d, tSessionEvents as f, toPostgresSchema as g, sqliteTableDefs as h, SCHEMA_VERSION as i, toJsonlArtifact as j, sessionConflictRow as k, isPersistedEvent as l, postgresTableDefs as m, EPHEMERAL_EVENT_TYPES as n, eventDimensions as o, tSessions as p, EVENT_ENCODING as r, eventKind as s, DEFAULT_BUSY_TIMEOUT_MS as t, tEvents as u, findSurfaceRepairs as v, repairOrphanInboxSplices as w, remapShadowedRange as x, orphanInboxSpliceSeqs as y };