@morlay/session-rdb 0.0.20 → 0.0.21-alpha.1
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 +59 -31
- package/dist/artifact.d.mts +25 -65
- package/dist/artifact.mjs +2 -2
- package/dist/{schema-BkQN5GyT.d.mts → backend-DpdtxYpz.d.mts} +346 -93
- package/dist/{branch-Co6xlbi0.mjs → branch-5JzX9rUq.mjs} +163 -52
- package/dist/deletion.d.mts +7 -0
- package/dist/deletion.mjs +2 -0
- package/dist/dist-vIVO6bA-.mjs +1524 -0
- package/dist/import.d.mts +4 -4
- package/dist/import.mjs +28 -11
- package/dist/index.d.mts +2 -3
- package/dist/index.mjs +4 -1631
- package/dist/{log-DO69NQnn.mjs → log-CnYct2Dv.mjs} +37 -82
- package/dist/{sqlite-DYExtbLo.mjs → sqlite-fpvm5Dzs.mjs} +205 -75
- package/dist/src-CWTWV7vx.mjs +1904 -0
- package/dist/storage.d.mts +14 -5
- package/dist/storage.mjs +2 -2
- package/dist/testing.d.mts +1 -26
- package/dist/testing.mjs +10503 -9614
- package/drizzle/postgres/20260918120000_v3_event_usage/migration.sql +14 -0
- package/drizzle/postgres/20260918120000_v3_event_usage/snapshot.json +1309 -0
- package/drizzle/sqlite/20260918120000_v3_event_usage/migration.sql +14 -0
- package/drizzle/sqlite/20260918120000_v3_event_usage/snapshot.json +1031 -0
- package/package.json +28 -29
- package/src/adapters/to-postgres.ts +1 -3
- package/src/adapters/to-sqlite.ts +0 -2
- package/src/adapters/types.ts +0 -3
- package/src/artifact.ts +0 -2
- package/src/backend.ts +31 -2
- package/src/branch.ts +223 -135
- package/src/deletion.ts +87 -0
- package/src/drizzle/postgres-v2.ts +0 -1
- package/src/drizzle/postgres-v3.ts +0 -1
- package/src/drizzle/sqlite-v2.ts +0 -1
- package/src/drizzle/sqlite-v3.ts +0 -1
- package/src/entities/v2/session-events.ts +0 -1
- package/src/entities/v3/event-usage.ts +25 -0
- package/src/entities/v3/events.ts +1 -3
- package/src/entities/v3/index.ts +4 -0
- package/src/entities/v3/session-events.ts +1 -2
- package/src/entities/v3/session-projcache-rows.ts +0 -8
- package/src/entities/v3/sessions.ts +3 -3
- package/src/entities/v3/storage-units.ts +0 -1
- package/src/entities/v3/workspace-sessions.ts +0 -5
- package/src/entities/v3/workspace-state.ts +0 -6
- package/src/entities/v3/workspaces.ts +0 -5
- package/src/export.ts +103 -0
- package/src/gc.ts +76 -0
- package/src/import-storages.ts +4 -37
- package/src/import.ts +54 -31
- package/src/index.ts +150 -114
- package/src/legacy.ts +4 -42
- package/src/log.ts +63 -106
- package/src/postgres.ts +249 -22
- package/src/schema.ts +6 -6
- package/src/session-query.ts +0 -4
- package/src/sqlite.ts +231 -55
- package/src/storage-takeover/index.ts +2 -28
- package/src/storage-takeover/projection-cache.ts +30 -134
- package/src/storage-takeover/repository.ts +20 -59
- package/src/storage-takeover/storage-backend.ts +3 -33
- package/src/storage-takeover/types.ts +14 -56
- package/src/storage.ts +0 -2
- package/src/testing/contract.ts +19 -50
- package/src/testing/coordinator-contract.ts +10 -25
- package/src/testing.ts +1 -4
- package/src/usage.ts +191 -0
- package/dist/index-D55G9n4k.d.mts +0 -271
- package/dist/magic-string.es-BgJoa-3K.mjs +0 -1017
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { SessionSeq } from "@deepseek-ai/dsh-session";
|
|
2
2
|
import { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
|
|
3
3
|
//#region src/log.ts
|
|
4
|
-
/**
|
|
5
|
-
* 把桥接行列里的 replace surfaceOp 归一到当前字段名。
|
|
6
|
-
*
|
|
7
|
-
* v2 时代落库的 JSON 用 `start`/`end`,当前格式用 `startSeq`/`endSeq`;
|
|
8
|
-
* 混合世代回退路径直接采用存储行,必须在此归一,否则上游 v3 surface 校验
|
|
9
|
-
* 以「invalid replace surfaceOp」拒绝整个会话。非 replace 形状原样返回,
|
|
10
|
-
* 由读取视图修复决定降级。
|
|
11
|
-
*/
|
|
12
4
|
function normalizeSurfaceOp(value) {
|
|
13
5
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return value;
|
|
14
6
|
const record = value;
|
|
@@ -88,18 +80,6 @@ const SURFACE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
88
80
|
"tool/result"
|
|
89
81
|
]);
|
|
90
82
|
const METERING_EVENT_TYPES = /* @__PURE__ */ new Set(["compaction/summary", "compaction/prune"]);
|
|
91
|
-
/**
|
|
92
|
-
* 读取时重计算 replace 的 sourceEventSeqs(sourceEventSeqs 不落库)。
|
|
93
|
-
*
|
|
94
|
-
* 优先采用紧邻 metering 事件(compaction/summary | compaction/prune)的
|
|
95
|
-
* shadowedSeqs:它是压缩事务落库的**权威被遮蔽节点列表**(range 只是首尾
|
|
96
|
-
* 边界对,压缩竞态下可能漏掉并发落地的节点——range 数值扫描会漏掉这些
|
|
97
|
-
* 节点,使上游 assertProvenance 报 missing)。shadowedSeqs 已由 rowToEvent
|
|
98
|
-
* 重映射到稠密坐标,与 replace 的 surfaceOp range 同空间。
|
|
99
|
-
*
|
|
100
|
-
* 无紧邻 metering 事件时回退到 range 数值扫描(历史数据 / 非压缩 replace,
|
|
101
|
-
* 如 tool-result pruner 的旧样式),保证既有行为不变。
|
|
102
|
-
*/
|
|
103
83
|
function recomputeReplaceProvenance(events) {
|
|
104
84
|
for (let i = 0; i < events.length; i++) {
|
|
105
85
|
const raw = events[i];
|
|
@@ -222,14 +202,6 @@ function findSurfaceRepairs(events) {
|
|
|
222
202
|
clampEnd
|
|
223
203
|
};
|
|
224
204
|
}
|
|
225
|
-
/**
|
|
226
|
-
* 夹取一个 end 落在旧坐标空间的 replace 的结尾。
|
|
227
|
-
*
|
|
228
|
-
* 仅当 replace 紧邻一个 metering 事件且其 `shadowedSeqs` 是权威数量时成立;
|
|
229
|
-
* 夹取点是从 `start` 起的第 `shadowedSeqs.length` 个当前 surface 节点(不足
|
|
230
|
-
* 则取当前 surface 末尾)。无法夹取(start 也不在当前 surface)时返回
|
|
231
|
-
* `undefined`,由调用方降级为 append。
|
|
232
|
-
*/
|
|
233
205
|
function clampReplaceEnd(events, index, nodes, startIdx) {
|
|
234
206
|
const metering = index > 0 ? events[index - 1] : void 0;
|
|
235
207
|
if (metering === void 0 || !METERING_EVENT_TYPES.has(metering.type)) return void 0;
|
|
@@ -255,11 +227,6 @@ function repairSurfaceOps(events) {
|
|
|
255
227
|
else if (repairs.clearSurfaceOp.has(event.seq)) delete raw.surfaceOp;
|
|
256
228
|
}
|
|
257
229
|
}
|
|
258
|
-
/**
|
|
259
|
-
* 读取时补全 assistant 结算字段:旧写入器不落库 `stream`(v2 才把流式记录
|
|
260
|
-
* 嵌入消息),读回时缺失即补空数组——上游 seed 校验要求 turn/step/stream
|
|
261
|
-
* 三者齐备,缺失会让整个会话加载失败。
|
|
262
|
-
*/
|
|
263
230
|
function repairAssistantSettlement(events) {
|
|
264
231
|
for (const event of events) {
|
|
265
232
|
if (event.type !== "assistant/message" && event.type !== "assistant/attempt") continue;
|
|
@@ -267,13 +234,6 @@ function repairAssistantSettlement(events) {
|
|
|
267
234
|
if (!Array.isArray(data["stream"])) data["stream"] = [];
|
|
268
235
|
}
|
|
269
236
|
}
|
|
270
|
-
/**
|
|
271
|
-
* 读取时把旧格式 `request/header` 归一为当前格式:v3 起 system prompt 由
|
|
272
|
-
* surface 上的 `system/message` 承载,header 必须省略 `system`,空 `tools` /
|
|
273
|
-
* `adapterDefaults` 也必须省略(上游 v3 事件校验 fail loud)。混合世代回退
|
|
274
|
-
* 视图直接采用存储行,不归一会让整个会话加载失败。system prompt 因此不再
|
|
275
|
-
* 进入模型请求;会话下次运行由 v3 的 system/message 机制重建。
|
|
276
|
-
*/
|
|
277
237
|
function repairRequestHeaders(events) {
|
|
278
238
|
for (const event of events) {
|
|
279
239
|
if (event.type !== "request/header") continue;
|
|
@@ -286,17 +246,6 @@ function repairRequestHeaders(events) {
|
|
|
286
246
|
if (typeof defaults === "object" && defaults !== null && !Array.isArray(defaults) && Object.keys(defaults).length === 0) delete record["adapterDefaults"];
|
|
287
247
|
}
|
|
288
248
|
}
|
|
289
|
-
/**
|
|
290
|
-
* 把紧邻 replace 的 metering 事件的 `shadowedRange` / `shadowedSeqs` 对齐到
|
|
291
|
-
* replace 最终的稠密 range。
|
|
292
|
-
*
|
|
293
|
-
* 旧写入器重编号事件后,metering 与 replace 一起落在旧坐标空间:二者数值
|
|
294
|
-
* 相等但与当前 surface 无关。夹取(或 range 本身已落在稠密空间而 metering
|
|
295
|
-
* 仍是旧值)后二者不再相等,而上游 token-meter 契约要求紧邻的 metering
|
|
296
|
-
* range 与 replace range 完全一致(否则报 no adjacent shadow price)。range
|
|
297
|
-
* 已一致时不改写——当前写入器保证一致,shadowedSeqs 的额外并发节点因此
|
|
298
|
-
* 原样保留。
|
|
299
|
-
*/
|
|
300
249
|
function syncMeteringRanges(events) {
|
|
301
250
|
for (let i = 1; i < events.length; i++) {
|
|
302
251
|
const metering = events[i - 1];
|
|
@@ -317,7 +266,6 @@ const PTC_EVENT_RENAMES = {
|
|
|
317
266
|
"tool/code-dispatch-start": "tool/ptc-dispatch-start",
|
|
318
267
|
"tool/code-dispatch": "tool/ptc-dispatch"
|
|
319
268
|
};
|
|
320
|
-
/** 把消息的 `tools-code-mode` 插件来源改写为 `tools-ptc`(非该来源原样返回)。 */
|
|
321
269
|
function renamePtcMessageSource(message) {
|
|
322
270
|
if (typeof message !== "object" || message === null || Array.isArray(message)) return message;
|
|
323
271
|
const record = message;
|
|
@@ -333,15 +281,6 @@ function renamePtcMessageSource(message) {
|
|
|
333
281
|
}
|
|
334
282
|
};
|
|
335
283
|
}
|
|
336
|
-
/**
|
|
337
|
-
* 读取时把 v2 时代的 PTC 词汇归一为当前词汇。
|
|
338
|
-
*
|
|
339
|
-
* 上游 v2→v3 迁移把 `tool/code-dispatch(-start)` 改名为
|
|
340
|
-
* `tool/ptc-dispatch(-start)`、把 `tools-code-mode` 插件来源改名为 `tools-ptc`、
|
|
341
|
-
* 把 agent preset 值 `code` 改名为 `ptc`。混合世代回退视图直接采用存储行,
|
|
342
|
-
* 不重命名会被上游 v3 校验以「unknown event type」拒绝整个会话。词汇改写
|
|
343
|
-
* 与上游迁移链的 renamePtcEvent 对齐。
|
|
344
|
-
*/
|
|
345
284
|
function renameLegacyPtcEvents(events) {
|
|
346
285
|
for (let index = 0; index < events.length; index++) {
|
|
347
286
|
const event = events[index];
|
|
@@ -388,11 +327,6 @@ function renameLegacyPtcEvents(events) {
|
|
|
388
327
|
}
|
|
389
328
|
}
|
|
390
329
|
}
|
|
391
|
-
/**
|
|
392
|
-
* 读取视图修复总入口:形状补全(结算字段 / request header)→ PTC 词汇归一
|
|
393
|
-
* → surface 语义修复 → metering 对齐 → provenance 重算 → 孤儿 inbox splice
|
|
394
|
-
* 改写。全部只作用于内存视图,不落库。
|
|
395
|
-
*/
|
|
396
330
|
function repairReadView(events) {
|
|
397
331
|
repairAssistantSettlement(events);
|
|
398
332
|
repairRequestHeaders(events);
|
|
@@ -402,14 +336,6 @@ function repairReadView(events) {
|
|
|
402
336
|
recomputeReplaceProvenance(events);
|
|
403
337
|
repairOrphanInboxSplices(events);
|
|
404
338
|
}
|
|
405
|
-
/**
|
|
406
|
-
* 定位无法从空状态增量重放的 agent/inbox/spliced 事件(孤儿操作)。
|
|
407
|
-
*
|
|
408
|
-
* 上游 Inbox 每次构造都从会话起点重放全部 inbox splice,失败即拒绝整个
|
|
409
|
-
* 会话(resume / 编辑重放不可用)。rewind 截断历史轮次后若残留 splice 引用
|
|
410
|
-
* 已被截断的排队消息(插入被删、消费保留,或反之),重放时越界或重复——
|
|
411
|
-
* 无法独立重放。
|
|
412
|
-
*/
|
|
413
339
|
function orphanInboxSpliceSeqs(events) {
|
|
414
340
|
const inbox = {
|
|
415
341
|
"next-turn": [],
|
|
@@ -455,7 +381,6 @@ function orphanInboxSpliceSeqs(events) {
|
|
|
455
381
|
}
|
|
456
382
|
return orphan;
|
|
457
383
|
}
|
|
458
|
-
/** 内存修复:把孤儿 inbox splice 改写为 no-op(调用方负责持久化)。 */
|
|
459
384
|
function repairOrphanInboxSplices(events) {
|
|
460
385
|
const orphan = orphanInboxSpliceSeqs(events);
|
|
461
386
|
if (orphan.size === 0) return;
|
|
@@ -513,12 +438,6 @@ function toJsonlArtifact(meta, inheritedEventCount, events) {
|
|
|
513
438
|
for (const event of events) lines.push(JSON.stringify(sessionFormatCatalog.encodeCurrentEvent(event)));
|
|
514
439
|
return lines.join("\n");
|
|
515
440
|
}
|
|
516
|
-
/**
|
|
517
|
-
* 事件行 JSON → `session/title` 的标题文本。存储层写路径保证 `f_data` 是完整
|
|
518
|
-
* 事件 JSON;形状不符(或损坏)按「无标题」处理——标题是派生显示数据。
|
|
519
|
-
* @param data - `t_events.f_data` 原文。
|
|
520
|
-
* @returns 标题文本,或 `undefined`。
|
|
521
|
-
*/
|
|
522
441
|
function titleOfEventData(data) {
|
|
523
442
|
try {
|
|
524
443
|
const value = JSON.parse(data);
|
|
@@ -528,5 +447,41 @@ function titleOfEventData(data) {
|
|
|
528
447
|
return;
|
|
529
448
|
}
|
|
530
449
|
}
|
|
450
|
+
function numericField(value) {
|
|
451
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
|
|
452
|
+
}
|
|
453
|
+
function textField(value) {
|
|
454
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* 一条事件行的用量(只有带 `usage` 的 `assistant/message` 才有):写路径据此记录
|
|
458
|
+
* `t_event_usage`,统计因此不必逐行解析 JSON。两种 `f_data` 结构(带信封 / 老格式)都认。
|
|
459
|
+
* @param event - 待写入的事件行。
|
|
460
|
+
* @returns 用量行,或该事件没有用量时的 undefined。
|
|
461
|
+
*/
|
|
462
|
+
function usageRowOf(event) {
|
|
463
|
+
if (event.fType !== "assistant/message") return void 0;
|
|
464
|
+
let parsed;
|
|
465
|
+
try {
|
|
466
|
+
parsed = JSON.parse(event.fData);
|
|
467
|
+
} catch {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
const envelope = parsed["data"] ?? parsed;
|
|
471
|
+
const usage = envelope["usage"];
|
|
472
|
+
if (typeof usage !== "object" || usage === null) return void 0;
|
|
473
|
+
const source = envelope["message"]?.source;
|
|
474
|
+
return {
|
|
475
|
+
fEventId: event.fEventId,
|
|
476
|
+
fCreatedAt: event.fCreatedAt,
|
|
477
|
+
fProvider: textField(source?.["provider"]),
|
|
478
|
+
fModel: textField(source?.["model"]),
|
|
479
|
+
fInputTokens: numericField(usage["inputTokens"]),
|
|
480
|
+
fOutputTokens: numericField(usage["outputTokens"]),
|
|
481
|
+
fCacheReadTokens: numericField(usage["cacheReadTokens"]),
|
|
482
|
+
fReasoningTokens: numericField(usage["reasoningTokens"]),
|
|
483
|
+
fTotalTokens: numericField(usage["totalTokens"])
|
|
484
|
+
};
|
|
485
|
+
}
|
|
531
486
|
//#endregion
|
|
532
|
-
export { toJsonlArtifact as _, repairAssistantSettlement as a, repairRequestHeaders as c, rowToMeta as d, scanRows as f, titleOfEventData as g, syncMeteringRanges as h, renameLegacyPtcEvents as i, repairSurfaceOps as l, sessionInsertRow as m, orphanInboxSpliceSeqs as n, repairOrphanInboxSplices as o, sessionConflictRow as p, recomputeReplaceProvenance as r, repairReadView as s, findSurfaceRepairs as t, rowToEvent as u };
|
|
487
|
+
export { toJsonlArtifact as _, repairAssistantSettlement as a, repairRequestHeaders as c, rowToMeta as d, scanRows as f, titleOfEventData as g, syncMeteringRanges as h, renameLegacyPtcEvents as i, repairSurfaceOps as l, sessionInsertRow as m, orphanInboxSpliceSeqs as n, repairOrphanInboxSplices as o, sessionConflictRow as p, recomputeReplaceProvenance as r, repairReadView as s, findSurfaceRepairs as t, rowToEvent as u, usageRowOf as v };
|