@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.
- package/README.md +11 -13
- package/dist/artifact.d.mts +6 -16
- package/dist/artifact.mjs +3 -3
- package/dist/{import-DFed8DBt.mjs → import-CKrzjXVB.mjs} +73 -83
- package/dist/import.d.mts +2 -3
- package/dist/import.mjs +2 -2
- package/dist/index-CgGDHQSK.d.mts +225 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +694 -169
- package/dist/log-DTJsxMud.mjs +314 -0
- package/dist/{schema-CFXZURX7.d.mts → schema-COK7-wRV.d.mts} +3 -15
- package/dist/sqlite-DCy4VTD8.mjs +698 -0
- package/dist/storage.d.mts +2 -7
- package/dist/storage.mjs +2 -3
- package/dist/testing.d.mts +30 -1
- package/dist/testing.mjs +676 -1991
- package/drizzle/postgres/20260908072805_v2_initial/migration.sql +58 -0
- package/drizzle/postgres/20260908072805_v2_initial/snapshot.json +686 -0
- package/drizzle/postgres/20260908072806_v3_drop_original_seq/migration.sql +1 -0
- package/drizzle/postgres/20260908072806_v3_drop_original_seq/snapshot.json +673 -0
- package/drizzle/sqlite/20260908072751_v2_initial/migration.sql +53 -0
- package/drizzle/sqlite/20260908072751_v2_initial/snapshot.json +492 -0
- package/drizzle/sqlite/20260908072752_v3_drop_original_seq/migration.sql +6 -0
- package/drizzle/sqlite/20260908072752_v3_drop_original_seq/snapshot.json +513 -0
- package/package.json +17 -12
- package/src/adapters/index.ts +10 -2
- package/src/adapters/to-postgres.ts +19 -15
- package/src/adapters/to-sqlite.ts +20 -14
- package/src/{entities → adapters}/types.ts +7 -8
- package/src/backend.ts +0 -7
- package/src/branch.ts +29 -110
- package/src/drizzle/postgres-v2.ts +11 -0
- package/src/drizzle/postgres-v3.ts +11 -0
- package/src/drizzle/sqlite-v2.ts +10 -0
- package/src/drizzle/sqlite-v3.ts +11 -0
- package/src/entities/index.ts +2 -30
- package/src/entities/v2/index.ts +20 -0
- package/src/entities/v2/session-events.ts +11 -0
- package/src/entities/v3/events.ts +27 -0
- package/src/entities/v3/index.ts +27 -0
- package/src/entities/v3/persistence-state.ts +10 -0
- package/src/entities/v3/schema-meta.ts +9 -0
- package/src/entities/v3/session-events.ts +26 -0
- package/src/entities/v3/sessions.ts +20 -0
- package/src/import.ts +65 -57
- package/src/index.ts +868 -223
- package/src/invariant.ts +0 -2
- package/src/legacy.ts +67 -0
- package/src/log.ts +41 -87
- package/src/postgres.ts +75 -93
- package/src/schema.ts +3 -14
- package/src/sqlite.ts +59 -46
- package/src/testing/contract.ts +460 -375
- package/src/testing/coordinator-contract.ts +108 -1374
- package/src/testing.ts +1 -6
- package/dist/index-uUvn6gYp.d.mts +0 -111
- package/dist/schema-vwzwEXNE.mjs +0 -878
- package/dist/sqlite-CG_Qcx5C.mjs +0 -356
- package/src/adapters/ddl.ts +0 -77
- package/src/entities/events.ts +0 -27
- package/src/entities/persistence-state.ts +0 -10
- package/src/entities/schema-meta.ts +0 -9
- package/src/entities/session-events.ts +0 -29
- package/src/entities/sessions.ts +0 -20
- package/src/migrate.ts +0 -137
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
|
|
2
|
+
//#region src/log.ts
|
|
3
|
+
function rowToMeta(row) {
|
|
4
|
+
if (!Number.isSafeInteger(row.fCreatedAt) || row.fCreatedAt < 0) throw new Error("stored session createdAt must be a non-negative safe integer");
|
|
5
|
+
return {
|
|
6
|
+
version: row.fVersion,
|
|
7
|
+
id: row.fSessionId,
|
|
8
|
+
createdAt: row.fCreatedAt,
|
|
9
|
+
...row.fCwd !== null ? { cwd: row.fCwd } : {},
|
|
10
|
+
...row.fParentSession !== null ? { parentSession: row.fParentSession } : {},
|
|
11
|
+
isSeeded: row.fSeedLength !== null,
|
|
12
|
+
...row.fOrigin !== null ? { origin: row.fOrigin } : {},
|
|
13
|
+
...row.fDelegationDepth === null ? {} : { delegationDepth: row.fDelegationDepth }
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function sessionInsertRow(storage, incarnation) {
|
|
17
|
+
const meta = storage.meta;
|
|
18
|
+
return {
|
|
19
|
+
fSessionId: meta.id,
|
|
20
|
+
fHeadEventId: "",
|
|
21
|
+
fHeadSequence: -1,
|
|
22
|
+
fVersion: meta.version,
|
|
23
|
+
fCreatedAt: meta.createdAt,
|
|
24
|
+
fCwd: meta.cwd ?? null,
|
|
25
|
+
fParentSession: meta.parentSession ?? null,
|
|
26
|
+
fSeedLength: meta.isSeeded ? storage.inheritedEventCount : null,
|
|
27
|
+
fOrigin: meta.origin ?? null,
|
|
28
|
+
fDelegationDepth: meta.delegationDepth ?? null,
|
|
29
|
+
fIncarnation: incarnation,
|
|
30
|
+
fRevision: 0
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function sessionConflictRow(storage) {
|
|
34
|
+
const meta = storage.meta;
|
|
35
|
+
return {
|
|
36
|
+
fVersion: meta.version,
|
|
37
|
+
fCreatedAt: meta.createdAt,
|
|
38
|
+
fCwd: meta.cwd ?? null,
|
|
39
|
+
fParentSession: meta.parentSession ?? null,
|
|
40
|
+
fSeedLength: meta.isSeeded ? storage.inheritedEventCount : null,
|
|
41
|
+
fOrigin: meta.origin ?? null,
|
|
42
|
+
fDelegationDepth: meta.delegationDepth ?? null
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function rowToEvent(row) {
|
|
46
|
+
const surfaceOp = row.fSurfaceOp !== null ? JSON.parse(row.fSurfaceOp) : void 0;
|
|
47
|
+
const record = JSON.parse(row.fData);
|
|
48
|
+
if (typeof record === "object" && record !== null && !Array.isArray(record) && typeof record["type"] === "string" && typeof record["seq"] === "number" && typeof record["time"] === "number" && "data" in record) return {
|
|
49
|
+
...record,
|
|
50
|
+
seq: row.fSequence,
|
|
51
|
+
time: row.fCreatedAt,
|
|
52
|
+
...surfaceOp === void 0 ? {} : { surfaceOp }
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
type: row.fType,
|
|
56
|
+
seq: row.fSequence,
|
|
57
|
+
time: row.fCreatedAt,
|
|
58
|
+
data: record,
|
|
59
|
+
...surfaceOp === void 0 ? {} : { surfaceOp }
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const SURFACE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
63
|
+
"user/message",
|
|
64
|
+
"assistant/message",
|
|
65
|
+
"tool/result"
|
|
66
|
+
]);
|
|
67
|
+
const METERING_EVENT_TYPES = /* @__PURE__ */ new Set(["compaction/summary", "compaction/prune"]);
|
|
68
|
+
/**
|
|
69
|
+
* 读取时重计算 replace 的 sourceEventSeqs(sourceEventSeqs 不落库)。
|
|
70
|
+
*
|
|
71
|
+
* 优先采用紧邻 metering 事件(compaction/summary | compaction/prune)的
|
|
72
|
+
* shadowedSeqs:它是压缩事务落库的**权威被遮蔽节点列表**(range 只是首尾
|
|
73
|
+
* 边界对,压缩竞态下可能漏掉并发落地的节点——range 数值扫描会漏掉这些
|
|
74
|
+
* 节点,使上游 assertProvenance 报 missing)。shadowedSeqs 已由 rowToEvent
|
|
75
|
+
* 重映射到稠密坐标,与 replace 的 surfaceOp range 同空间。
|
|
76
|
+
*
|
|
77
|
+
* 无紧邻 metering 事件时回退到 range 数值扫描(历史数据 / 非压缩 replace,
|
|
78
|
+
* 如 tool-result pruner 的旧样式),保证既有行为不变。
|
|
79
|
+
*/
|
|
80
|
+
function recomputeReplaceProvenance(events) {
|
|
81
|
+
for (let i = 0; i < events.length; i++) {
|
|
82
|
+
const raw = events[i];
|
|
83
|
+
const op = raw.surfaceOp;
|
|
84
|
+
if (typeof op !== "object" || op === null || op.op !== "replace") continue;
|
|
85
|
+
const { start, end } = op;
|
|
86
|
+
const metering = i > 0 ? events[i - 1] : void 0;
|
|
87
|
+
const meteringData = metering !== void 0 && METERING_EVENT_TYPES.has(metering.type) ? metering.data : void 0;
|
|
88
|
+
if (meteringData?.shadowedSeqs !== void 0) {
|
|
89
|
+
raw.sourceEventSeqs = meteringData.shadowedSeqs;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const refs = [];
|
|
93
|
+
for (const candidate of events) if (candidate.seq >= start && candidate.seq <= end && SURFACE_EVENT_TYPES.has(candidate.type)) refs.push(candidate.seq);
|
|
94
|
+
raw.sourceEventSeqs = refs;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function isEventSeqLike(value) {
|
|
98
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0);
|
|
99
|
+
}
|
|
100
|
+
function isDeepEqualJson(a, b) {
|
|
101
|
+
if (a === b) return true;
|
|
102
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
103
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
104
|
+
return a.every((item, i) => isDeepEqualJson(item, b[i]));
|
|
105
|
+
}
|
|
106
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
107
|
+
const aKeys = Object.keys(a);
|
|
108
|
+
const bRecord = b;
|
|
109
|
+
if (aKeys.length !== Object.keys(bRecord).length) return false;
|
|
110
|
+
return aKeys.every((key) => Object.hasOwn(bRecord, key) && isDeepEqualJson(a[key], bRecord[key]));
|
|
111
|
+
}
|
|
112
|
+
function toolResultRewriteContentOnly(original, replacement) {
|
|
113
|
+
const originalData = original.data;
|
|
114
|
+
const replacementData = replacement.data;
|
|
115
|
+
const originalMessage = originalData["message"];
|
|
116
|
+
const replacementMessage = replacementData["message"];
|
|
117
|
+
const originalContent = Array.isArray(originalMessage?.content) ? originalMessage.content : void 0;
|
|
118
|
+
const replacementContent = Array.isArray(replacementMessage?.content) ? replacementMessage.content : void 0;
|
|
119
|
+
if (originalContent === void 0 || replacementContent === void 0) return false;
|
|
120
|
+
return isDeepEqualJson({
|
|
121
|
+
...originalData,
|
|
122
|
+
message: {
|
|
123
|
+
...originalMessage,
|
|
124
|
+
content: [{
|
|
125
|
+
...originalContent[0],
|
|
126
|
+
content: null
|
|
127
|
+
}]
|
|
128
|
+
}
|
|
129
|
+
}, {
|
|
130
|
+
...replacementData,
|
|
131
|
+
message: {
|
|
132
|
+
...replacementMessage,
|
|
133
|
+
content: [{
|
|
134
|
+
...replacementContent[0],
|
|
135
|
+
content: null
|
|
136
|
+
}]
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function findSurfaceRepairs(events) {
|
|
141
|
+
const nodes = [];
|
|
142
|
+
const degradeToAppend = /* @__PURE__ */ new Set();
|
|
143
|
+
const addAppendMarker = /* @__PURE__ */ new Set();
|
|
144
|
+
const clearSurfaceOp = /* @__PURE__ */ new Set();
|
|
145
|
+
for (const event of events) {
|
|
146
|
+
const op = event.surfaceOp;
|
|
147
|
+
if (op === void 0) {
|
|
148
|
+
if (SURFACE_EVENT_TYPES.has(event.type)) {
|
|
149
|
+
addAppendMarker.add(event.seq);
|
|
150
|
+
nodes.push(event.seq);
|
|
151
|
+
}
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (op === "append") {
|
|
155
|
+
if (SURFACE_EVENT_TYPES.has(event.type)) nodes.push(event.seq);
|
|
156
|
+
else clearSurfaceOp.add(event.seq);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (!SURFACE_EVENT_TYPES.has(event.type)) {
|
|
160
|
+
clearSurfaceOp.add(event.seq);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const replace = typeof op === "object" && op !== null && !Array.isArray(op) ? op : void 0;
|
|
164
|
+
const start = replace?.["start"];
|
|
165
|
+
const end = replace?.["end"];
|
|
166
|
+
const shapeOk = replace !== void 0 && replace["op"] === "replace" && isEventSeqLike(start) && isEventSeqLike(end);
|
|
167
|
+
const startIdx = shapeOk ? nodes.indexOf(start) : -1;
|
|
168
|
+
const endIdx = shapeOk ? nodes.indexOf(end) : -1;
|
|
169
|
+
const rangeOk = shapeOk && startIdx !== -1 && endIdx !== -1 && startIdx <= endIdx;
|
|
170
|
+
let rewriteOk = true;
|
|
171
|
+
if (rangeOk && event.type === "tool/result") {
|
|
172
|
+
const shadowed = nodes.slice(startIdx, endIdx + 1);
|
|
173
|
+
if (shadowed.length !== 1) rewriteOk = false;
|
|
174
|
+
else {
|
|
175
|
+
const original = events[shadowed[0]];
|
|
176
|
+
rewriteOk = original?.type === "tool/result" && toolResultRewriteContentOnly(original, event);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (!rangeOk || !rewriteOk) {
|
|
180
|
+
degradeToAppend.add(event.seq);
|
|
181
|
+
nodes.push(event.seq);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
nodes.splice(startIdx, endIdx - startIdx + 1, event.seq);
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
degradeToAppend,
|
|
188
|
+
addAppendMarker,
|
|
189
|
+
clearSurfaceOp
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function repairSurfaceOps(events) {
|
|
193
|
+
const repairs = findSurfaceRepairs(events);
|
|
194
|
+
if (repairs.degradeToAppend.size === 0 && repairs.addAppendMarker.size === 0 && repairs.clearSurfaceOp.size === 0) return;
|
|
195
|
+
for (const event of events) {
|
|
196
|
+
const raw = event;
|
|
197
|
+
if (repairs.degradeToAppend.has(event.seq)) raw.surfaceOp = "append";
|
|
198
|
+
else if (repairs.addAppendMarker.has(event.seq)) raw.surfaceOp = "append";
|
|
199
|
+
else if (repairs.clearSurfaceOp.has(event.seq)) delete raw.surfaceOp;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* 定位无法从空状态增量重放的 agent/inbox/spliced 事件(孤儿操作)。
|
|
204
|
+
*
|
|
205
|
+
* 上游 Inbox 每次构造都从会话起点重放全部 inbox splice,失败即拒绝整个
|
|
206
|
+
* 会话(resume / 编辑重放不可用)。rewind 截断历史轮次后若残留 splice 引用
|
|
207
|
+
* 已被截断的排队消息(插入被删、消费保留,或反之),重放时越界或重复——
|
|
208
|
+
* 无法独立重放。
|
|
209
|
+
*/
|
|
210
|
+
function orphanInboxSpliceSeqs(events) {
|
|
211
|
+
const inbox = {
|
|
212
|
+
"next-turn": [],
|
|
213
|
+
"next-step": []
|
|
214
|
+
};
|
|
215
|
+
const orphan = /* @__PURE__ */ new Set();
|
|
216
|
+
for (const raw of events) {
|
|
217
|
+
const event = raw;
|
|
218
|
+
if (event.type !== "agent/inbox/spliced") continue;
|
|
219
|
+
const { target, start, removedCount, inserted } = event.data;
|
|
220
|
+
const list = typeof target === "string" ? inbox[target] : void 0;
|
|
221
|
+
if (list === void 0) {
|
|
222
|
+
orphan.add(event.seq);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const removed = removedCount ?? 0;
|
|
226
|
+
const parsedInserted = (inserted ?? []).map((m) => ({ id: typeof m.id === "string" ? m.id : "" }));
|
|
227
|
+
if (!Number.isSafeInteger(start) || start < 0 || start > list.length || !Number.isSafeInteger(removed) || removed < 0 || start + removed > list.length) {
|
|
228
|
+
orphan.add(event.seq);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
const candidate = [
|
|
232
|
+
...list.slice(0, start),
|
|
233
|
+
...parsedInserted,
|
|
234
|
+
...list.slice(start + removed)
|
|
235
|
+
];
|
|
236
|
+
const other = (target === "next-turn" ? inbox["next-step"] : inbox["next-turn"]) ?? [];
|
|
237
|
+
const seen = /* @__PURE__ */ new Set();
|
|
238
|
+
let dup = false;
|
|
239
|
+
for (const m of [...candidate, ...other]) {
|
|
240
|
+
if (m.id === "") continue;
|
|
241
|
+
if (seen.has(m.id)) {
|
|
242
|
+
dup = true;
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
seen.add(m.id);
|
|
246
|
+
}
|
|
247
|
+
if (dup) {
|
|
248
|
+
orphan.add(event.seq);
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
list.splice(start, removed, ...parsedInserted);
|
|
252
|
+
}
|
|
253
|
+
return orphan;
|
|
254
|
+
}
|
|
255
|
+
/** 内存修复:把孤儿 inbox splice 改写为 no-op(调用方负责持久化)。 */
|
|
256
|
+
function repairOrphanInboxSplices(events) {
|
|
257
|
+
const orphan = orphanInboxSpliceSeqs(events);
|
|
258
|
+
if (orphan.size === 0) return;
|
|
259
|
+
for (const event of events) {
|
|
260
|
+
if (!orphan.has(event.seq)) continue;
|
|
261
|
+
const target = event.data.target;
|
|
262
|
+
event.data = {
|
|
263
|
+
...typeof target === "string" ? { target } : { target: "next-turn" },
|
|
264
|
+
start: 0,
|
|
265
|
+
removedCount: 0,
|
|
266
|
+
inserted: []
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function scanRows(rows, base = 0) {
|
|
271
|
+
const parsed = rows.map((row) => {
|
|
272
|
+
try {
|
|
273
|
+
return {
|
|
274
|
+
ok: true,
|
|
275
|
+
event: rowToEvent(row)
|
|
276
|
+
};
|
|
277
|
+
} catch {
|
|
278
|
+
return { ok: false };
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
let lastTurnEnd = -1;
|
|
282
|
+
for (let i = parsed.length - 1; i >= 0; i--) if (parsed[i]?.ok && rows[i]?.fType === "turn/end") {
|
|
283
|
+
lastTurnEnd = i;
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
const preserved = [];
|
|
287
|
+
for (let i = 0; i < rows.length; i++) {
|
|
288
|
+
const p = parsed[i];
|
|
289
|
+
if (!p?.ok || p.event === void 0) {
|
|
290
|
+
if (i <= lastTurnEnd) throw new Error(`corrupt session log: unparsable committed event at seq ${rows[i]?.fSequence}`);
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
if (p.event.seq !== base + i) {
|
|
294
|
+
if (i <= lastTurnEnd) throw new Error(`corrupt session log: seq gap in committed region (expected ${base + i}, got ${p.event.seq})`);
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
preserved.push(p.event);
|
|
298
|
+
}
|
|
299
|
+
return preserved.length < rows.length ? {
|
|
300
|
+
preserved,
|
|
301
|
+
tornFrom: base + preserved.length
|
|
302
|
+
} : { preserved };
|
|
303
|
+
}
|
|
304
|
+
function toJsonlArtifact(meta, inheritedEventCount, events) {
|
|
305
|
+
const header = sessionFormatCatalog.encodeCurrentHeader({
|
|
306
|
+
...meta,
|
|
307
|
+
delegationDepth: meta.delegationDepth ?? 0
|
|
308
|
+
}, inheritedEventCount);
|
|
309
|
+
const lines = [JSON.stringify(header)];
|
|
310
|
+
for (const event of events) lines.push(JSON.stringify(sessionFormatCatalog.encodeCurrentEvent(event)));
|
|
311
|
+
return lines.join("\n");
|
|
312
|
+
}
|
|
313
|
+
//#endregion
|
|
314
|
+
export { repairSurfaceOps as a, scanRows as c, toJsonlArtifact as d, repairOrphanInboxSplices as i, sessionConflictRow as l, orphanInboxSpliceSeqs as n, rowToEvent as o, recomputeReplaceProvenance as r, rowToMeta as s, findSurfaceRepairs as t, sessionInsertRow as u };
|
|
@@ -30,7 +30,6 @@ interface EventInsert {
|
|
|
30
30
|
interface EventRow {
|
|
31
31
|
fEventId: string;
|
|
32
32
|
fSequence: number;
|
|
33
|
-
fOriginalSeq: number;
|
|
34
33
|
fType: string;
|
|
35
34
|
fKind: string;
|
|
36
35
|
fRole: string;
|
|
@@ -50,7 +49,6 @@ interface BackendTx {
|
|
|
50
49
|
fSessionId: SessionId;
|
|
51
50
|
fEventId: string;
|
|
52
51
|
fSequence: number;
|
|
53
|
-
fOriginalSeq: number;
|
|
54
52
|
fSurfaceOp: string | null;
|
|
55
53
|
}>): Promise<void>;
|
|
56
54
|
updateHead(id: SessionId, headEventId: string, headSequence: number): Promise<void>;
|
|
@@ -60,20 +58,12 @@ interface BackendTx {
|
|
|
60
58
|
fEventId: string;
|
|
61
59
|
fSequence: number;
|
|
62
60
|
} | undefined>;
|
|
63
|
-
getLastBridge(id: SessionId): Promise<{
|
|
64
|
-
fEventId: string;
|
|
65
|
-
fSequence: number;
|
|
66
|
-
} | undefined>;
|
|
67
61
|
}
|
|
68
62
|
interface Backend {
|
|
69
63
|
readonly kind: "sqlite" | "postgres";
|
|
70
64
|
readonly storeIdentity: string;
|
|
71
65
|
open(): Promise<void>;
|
|
72
66
|
getSession(id: SessionId): Promise<SessionRow | undefined>;
|
|
73
|
-
getSeqMapRows(id: SessionId): Promise<Array<{
|
|
74
|
-
fSequence: number;
|
|
75
|
-
fOriginalSeq: number;
|
|
76
|
-
}>>;
|
|
77
67
|
getEventRows(id: SessionId, fromSequence?: number): Promise<EventRow[]>;
|
|
78
68
|
listSessions(): Promise<SessionRow[]>;
|
|
79
69
|
transaction<T>(fn: (tx: BackendTx) => Promise<T>): Promise<T>;
|
|
@@ -88,18 +78,16 @@ declare class WriteGuard {
|
|
|
88
78
|
}
|
|
89
79
|
//#endregion
|
|
90
80
|
//#region src/schema.d.ts
|
|
91
|
-
declare const SCHEMA_VERSION =
|
|
81
|
+
declare const SCHEMA_VERSION = 3;
|
|
92
82
|
declare const SESSION_PERSISTENCE_SQLITE_APPLICATION_ID = 1146308688;
|
|
93
|
-
declare const EPHEMERAL_EVENT_TYPES: readonly ["assistant/chunk"];
|
|
94
83
|
declare const EVENT_ENCODING = "json";
|
|
95
84
|
declare const tPersistenceState: any;
|
|
85
|
+
declare const tSchemaMeta: any;
|
|
96
86
|
declare const tSessions: any;
|
|
97
87
|
declare const tEvents: any;
|
|
98
88
|
declare const tSessionEvents: any;
|
|
99
89
|
type JournalMode = "wal" | "delete" | "truncate" | "persist";
|
|
100
90
|
declare const DEFAULT_BUSY_TIMEOUT_MS = 5000;
|
|
101
|
-
declare function isEphemeralType(type: string): boolean;
|
|
102
|
-
declare function isPersistedEvent(event: SessionEvent): boolean;
|
|
103
91
|
type EventKind = "message" | "thinking" | "turn" | "tool" | "request" | "config" | "audit" | "lifecycle" | "inbox" | "compaction" | "llm" | "subagent" | "team" | "workflow" | "goal" | "schedule" | "todo" | "web";
|
|
104
92
|
type EventRole = "user" | "assistant" | "tool";
|
|
105
93
|
declare function eventKind(event: {
|
|
@@ -113,4 +101,4 @@ declare function eventDimensions(event: SessionEvent): {
|
|
|
113
101
|
actionId: string;
|
|
114
102
|
};
|
|
115
103
|
//#endregion
|
|
116
|
-
export {
|
|
104
|
+
export { BackendTx as _, JournalMode as a, eventDimensions as c, tPersistenceState as d, tSchemaMeta as f, Backend as g, WriteGuard as h, EventRole as i, eventKind as l, tSessions as m, EVENT_ENCODING as n, SCHEMA_VERSION as o, tSessionEvents as p, EventKind as r, SESSION_PERSISTENCE_SQLITE_APPLICATION_ID as s, DEFAULT_BUSY_TIMEOUT_MS as t, tEvents as u, EventRow as v, SessionRow as y };
|