@morlay/session-rdb 0.1.10-alpha.0 → 0.1.10-alpha.3

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 (142) hide show
  1. package/README.md +18 -3
  2. package/dist/artifact.d.mts +118 -2
  3. package/dist/artifact.mjs +5 -3
  4. package/dist/{log-TYgd8Xkr.d.mts → backend-BKtJ5sO5.d.mts} +183 -284
  5. package/dist/backend-rdb-BDCntVDy.mjs +1341 -0
  6. package/dist/branch-CG1PUlO6.mjs +833 -0
  7. package/dist/deletion-SSX7IqU8.mjs +35 -0
  8. package/dist/deletion.d.mts +1 -1
  9. package/dist/deletion.mjs +2 -2
  10. package/dist/export-CfJQjQfr.mjs +123 -0
  11. package/dist/export.d.mts +1 -1
  12. package/dist/export.mjs +31 -55
  13. package/dist/import.d.mts +1 -1
  14. package/dist/import.mjs +31 -76
  15. package/dist/index-CUD2ZpTA.d.mts +71 -0
  16. package/dist/index.d.mts +20 -2
  17. package/dist/index.mjs +1561 -4
  18. package/dist/open-YoyD_kah.mjs +561 -0
  19. package/dist/organize.d.mts +9 -0
  20. package/dist/organize.mjs +30 -0
  21. package/dist/route-DpfY0zq-.mjs +114 -0
  22. package/dist/storage.d.mts +41 -48
  23. package/dist/storage.mjs +3 -1
  24. package/dist/testing.d.mts +9 -1
  25. package/dist/testing.mjs +25 -4
  26. package/dist/usage-row-BQQM-_t6.mjs +36 -0
  27. package/dist/usage.d.mts +1 -1
  28. package/dist/usage.mjs +7 -40
  29. package/dist/write-guard-CYrY58GM.mjs +174 -0
  30. package/package.json +32 -36
  31. package/src/artifact.ts +4 -1
  32. package/src/backend-rdb.ts +331 -0
  33. package/src/backend.ts +32 -15
  34. package/src/{branch.ts → branch/index.ts} +109 -110
  35. package/src/branch/port.ts +62 -0
  36. package/src/branch/semantics.ts +69 -0
  37. package/src/db/open.ts +180 -0
  38. package/src/db/stats.ts +449 -0
  39. package/src/deletion-error.ts +17 -0
  40. package/src/deletion.ts +19 -72
  41. package/src/entities/index.ts +16 -1
  42. package/src/entities/v3/event-usage.ts +3 -3
  43. package/src/entities/v3/events.ts +3 -3
  44. package/src/entities/v3/index.ts +4 -16
  45. package/src/entities/v3/persistence-state.ts +3 -3
  46. package/src/entities/v3/schema-meta.ts +3 -3
  47. package/src/entities/v3/session-counts.ts +3 -3
  48. package/src/entities/v3/session-events.ts +3 -3
  49. package/src/entities/v3/session-projcache-rows.ts +3 -3
  50. package/src/entities/v3/session-usage.ts +3 -3
  51. package/src/entities/v3/sessions.ts +3 -3
  52. package/src/entities/v3/storage-records.ts +17 -0
  53. package/src/entities/v3/storage-units.ts +3 -3
  54. package/src/{schema.ts → event-shape.ts} +0 -46
  55. package/src/export.ts +32 -78
  56. package/src/handles.ts +349 -0
  57. package/src/http/route.ts +178 -0
  58. package/src/import-storages.ts +5 -2
  59. package/src/import.ts +63 -125
  60. package/src/index.ts +15 -1666
  61. package/src/legacy.ts +3 -1
  62. package/src/live-routing.ts +205 -0
  63. package/src/log/export.ts +84 -0
  64. package/src/{log.ts → log/repair.ts} +1 -268
  65. package/src/log/rows.ts +107 -0
  66. package/src/log/usage-row.ts +64 -0
  67. package/src/migrations.ts +196 -0
  68. package/src/organize.ts +38 -0
  69. package/src/read-path.ts +190 -0
  70. package/src/routes.ts +2 -1
  71. package/src/rows.ts +25 -77
  72. package/src/session-ops.ts +444 -0
  73. package/src/session-store.ts +675 -0
  74. package/src/stats-fold.ts +44 -0
  75. package/src/storage-takeover/index.ts +2 -5
  76. package/src/storage-takeover/legacy-domain-migration.ts +118 -0
  77. package/src/storage-takeover/projection-cache.ts +122 -71
  78. package/src/storage-takeover/read-model.ts +189 -0
  79. package/src/storage-takeover/repository.ts +236 -442
  80. package/src/storage-takeover/storage-backend.ts +44 -159
  81. package/src/storage-takeover/types.ts +45 -19
  82. package/src/storage-takeover/workspace-documents.ts +65 -0
  83. package/src/storage.ts +4 -2
  84. package/src/testing.ts +21 -1
  85. package/src/usage.ts +11 -65
  86. package/src/version.ts +13 -0
  87. package/src/write-path.ts +286 -0
  88. package/dist/branch-CoPCRKer.mjs +0 -401
  89. package/dist/deletion-CWl89TIR.mjs +0 -2249
  90. package/dist/gc.d.mts +0 -4
  91. package/dist/gc.mjs +0 -48
  92. package/dist/log-CcWy46VE.mjs +0 -558
  93. package/dist/routes-hZjTcX_R.mjs +0 -9
  94. package/dist/sqlite-BNRd1aqR.mjs +0 -1778
  95. package/drizzle/postgres/20260908072805_v2_initial/migration.sql +0 -58
  96. package/drizzle/postgres/20260908072805_v2_initial/snapshot.json +0 -686
  97. package/drizzle/postgres/20260908072806_v3_drop_original_seq/migration.sql +0 -1
  98. package/drizzle/postgres/20260908072806_v3_drop_original_seq/snapshot.json +0 -673
  99. package/drizzle/postgres/20260910120001_v3_storage_tables/migration.sql +0 -65
  100. package/drizzle/postgres/20260910120001_v3_storage_tables/snapshot.json +0 -1183
  101. package/drizzle/postgres/20260910130001_v3_session_title_backfill/migration.sql +0 -10
  102. package/drizzle/postgres/20260910130001_v3_session_title_backfill/snapshot.json +0 -1183
  103. package/drizzle/postgres/20260918120000_v3_event_usage/migration.sql +0 -14
  104. package/drizzle/postgres/20260918120000_v3_event_usage/snapshot.json +0 -1309
  105. package/drizzle/postgres/20260921075900_v3_agent_preset/migration.sql +0 -1
  106. package/drizzle/postgres/20260922090001_v3_pinned_seq/migration.sql +0 -2
  107. package/drizzle/postgres/20260922093001_v3_last_event_at/migration.sql +0 -10
  108. package/drizzle/postgres/20260923120000_v3_usage_materialized/migration.sql +0 -48
  109. package/drizzle/postgres/20261008103001_v3_schedule_tasks/migration.sql +0 -11
  110. package/drizzle/sqlite/20260908072751_v2_initial/migration.sql +0 -53
  111. package/drizzle/sqlite/20260908072751_v2_initial/snapshot.json +0 -492
  112. package/drizzle/sqlite/20260908072752_v3_drop_original_seq/migration.sql +0 -6
  113. package/drizzle/sqlite/20260908072752_v3_drop_original_seq/snapshot.json +0 -513
  114. package/drizzle/sqlite/20260910120000_v3_storage_tables/migration.sql +0 -66
  115. package/drizzle/sqlite/20260910120000_v3_storage_tables/snapshot.json +0 -905
  116. package/drizzle/sqlite/20260910130000_v3_session_title_backfill/migration.sql +0 -13
  117. package/drizzle/sqlite/20260910130000_v3_session_title_backfill/snapshot.json +0 -905
  118. package/drizzle/sqlite/20260918120000_v3_event_usage/migration.sql +0 -14
  119. package/drizzle/sqlite/20260918120000_v3_event_usage/snapshot.json +0 -1031
  120. package/drizzle/sqlite/20260921075855_v3_agent_preset/migration.sql +0 -7
  121. package/drizzle/sqlite/20260921075855_v3_agent_preset/snapshot.json +0 -1041
  122. package/drizzle/sqlite/20260922090000_v3_pinned_seq/migration.sql +0 -4
  123. package/drizzle/sqlite/20260922093000_v3_last_event_at/migration.sql +0 -13
  124. package/drizzle/sqlite/20260923120000_v3_usage_materialized/migration.sql +0 -48
  125. package/drizzle/sqlite/20261008103000_v3_schedule_tasks/migration.sql +0 -14
  126. package/src/adapters/index.ts +0 -12
  127. package/src/adapters/to-postgres.ts +0 -93
  128. package/src/adapters/to-sqlite.ts +0 -83
  129. package/src/adapters/types.ts +0 -44
  130. package/src/drizzle/postgres-v2.ts +0 -10
  131. package/src/drizzle/postgres-v3.ts +0 -18
  132. package/src/drizzle/sqlite-v2.ts +0 -9
  133. package/src/drizzle/sqlite-v3.ts +0 -18
  134. package/src/entities/v2/index.ts +0 -20
  135. package/src/entities/v2/session-events.ts +0 -10
  136. package/src/entities/v3/schedule-tasks.ts +0 -16
  137. package/src/entities/v3/workspace-sessions.ts +0 -19
  138. package/src/entities/v3/workspace-state.ts +0 -12
  139. package/src/entities/v3/workspaces.ts +0 -14
  140. package/src/gc.ts +0 -77
  141. package/src/postgres.ts +0 -1015
  142. package/src/sqlite.ts +0 -1096
package/dist/gc.d.mts DELETED
@@ -1,4 +0,0 @@
1
- import { Ft as SESSION_GC_PATH, et as SessionPersistenceRdb } from "./log-TYgd8Xkr.mjs";
2
- import { Context } from "@deepseek-ai/cordis";
3
- export declare function registerSessionGc(ctx: Context, persistence: SessionPersistenceRdb): void;
4
- export { SESSION_GC_PATH };
package/dist/gc.mjs DELETED
@@ -1,48 +0,0 @@
1
- import { r as SESSION_GC_PATH } from "./routes-hZjTcX_R.mjs";
2
- // src/gc.ts
3
- async function stopRunningAgents(ctx) {
4
- const running = ctx.get("agents")?.list() ?? [];
5
- for (const agent of running) agent.cancel?.({ kind: "user" }, { keepInbox: true });
6
- await Promise.all(running.map((agent) => agent.whenIdle()));
7
- return running.length;
8
- }
9
- function registerSessionGc(ctx, persistence) {
10
- ctx.inject(["webServer", "connection"], (webCtx) => {
11
- const webServer = webCtx.webServer;
12
- const connection = webCtx.get("connection");
13
- return webCtx.effect(() => webServer.register({
14
- kind: "exact",
15
- path: SESSION_GC_PATH,
16
- handler: async (req, res) => {
17
- const rejection = connection.requestRejection(req);
18
- if (rejection !== void 0) {
19
- res.writeHead(rejection);
20
- res.end(rejection === 401 ? "unauthorized" : "forbidden");
21
- return;
22
- }
23
- if (req.method !== "POST") {
24
- res.writeHead(405, { "content-type": "application/json" });
25
- res.end(JSON.stringify({ error: "method not allowed" }));
26
- return;
27
- }
28
- try {
29
- const stoppedAgents = await stopRunningAgents(webCtx);
30
- const orphanSessions = await persistence.collectOrphanSessions();
31
- const orphanEvents = await persistence.collectOrphans();
32
- await persistence.vacuum();
33
- res.writeHead(200, { "content-type": "application/json" });
34
- res.end(JSON.stringify({
35
- orphanSessions,
36
- orphanEvents,
37
- stoppedAgents,
38
- vacuumed: true
39
- }));
40
- } catch (error) {
41
- res.writeHead(500, { "content-type": "application/json" });
42
- res.end(JSON.stringify({ error: error instanceof Error ? error.message : "gc failed" }));
43
- }
44
- }
45
- }), `session-rdb: ${SESSION_GC_PATH} route`);
46
- });
47
- }
48
- export { SESSION_GC_PATH, registerSessionGc };
@@ -1,558 +0,0 @@
1
- import { localDayKey } from "./usage.mjs";
2
- import { SessionSeq } from "@deepseek-ai/dsh-session";
3
- import { sessionFormatCatalog } from "@deepseek-ai/dsh-session-format-catalog";
4
- // src/log.ts
5
- function normalizeSurfaceOp(value) {
6
- if (typeof value !== "object" || value === null || Array.isArray(value)) return value;
7
- const record = value;
8
- if (record["op"] !== "replace") return value;
9
- const startSeq = record["startSeq"] ?? record["start"];
10
- const endSeq = record["endSeq"] ?? record["end"];
11
- if (typeof startSeq !== "number" || typeof endSeq !== "number") return value;
12
- return {
13
- op: "replace",
14
- startSeq: SessionSeq(startSeq),
15
- endSeq: SessionSeq(endSeq)
16
- };
17
- }
18
- function rowToMeta(row) {
19
- if (!Number.isSafeInteger(row.fCreatedAt) || row.fCreatedAt < 0) throw new Error("stored session createdAt must be a non-negative safe integer");
20
- return {
21
- version: row.fVersion,
22
- id: row.fSessionId,
23
- createdAt: row.fCreatedAt,
24
- ...row.fCwd !== null ? { cwd: row.fCwd } : {},
25
- ...row.fParentSession !== null ? { parentSession: row.fParentSession } : {},
26
- isSeeded: row.fSeedLength !== null,
27
- ...row.fOrigin !== null ? { origin: row.fOrigin } : {},
28
- ...row.fDelegationDepth === null ? {} : { delegationDepth: row.fDelegationDepth },
29
- ...row.fAgentPreset === null ? {} : { agentPreset: row.fAgentPreset }
30
- };
31
- }
32
- function sessionInsertRow(storage, incarnation) {
33
- const meta = storage.meta;
34
- return {
35
- fSessionId: meta.id,
36
- fHeadEventId: "",
37
- fHeadSequence: -1,
38
- fVersion: meta.version,
39
- fCreatedAt: meta.createdAt,
40
- fCwd: meta.cwd ?? null,
41
- fParentSession: meta.parentSession ?? null,
42
- fSeedLength: meta.isSeeded ? storage.inheritedEventCount : null,
43
- fOrigin: meta.origin ?? null,
44
- fDelegationDepth: meta.delegationDepth ?? null,
45
- fAgentPreset: meta.agentPreset ?? null,
46
- fIncarnation: incarnation,
47
- fRevision: 0
48
- };
49
- }
50
- function sessionConflictRow(storage) {
51
- const meta = storage.meta;
52
- return {
53
- fVersion: meta.version,
54
- fCreatedAt: meta.createdAt,
55
- fCwd: meta.cwd ?? null,
56
- fParentSession: meta.parentSession ?? null,
57
- fSeedLength: meta.isSeeded ? storage.inheritedEventCount : null,
58
- fOrigin: meta.origin ?? null,
59
- fDelegationDepth: meta.delegationDepth ?? null,
60
- fAgentPreset: meta.agentPreset ?? null
61
- };
62
- }
63
- function rowToEvent(row) {
64
- const surfaceOp = row.fSurfaceOp !== null ? normalizeSurfaceOp(JSON.parse(row.fSurfaceOp)) : void 0;
65
- const record = JSON.parse(row.fData);
66
- if (typeof record === "object" && record !== null && !Array.isArray(record) && typeof record["type"] === "string" && typeof record["seq"] === "number" && typeof record["time"] === "number" && "data" in record) {
67
- const event = record;
68
- event.seq = row.fSequence;
69
- event.time = row.fCreatedAt;
70
- if (surfaceOp !== void 0) event.surfaceOp = surfaceOp;
71
- return event;
72
- }
73
- return {
74
- type: row.fType,
75
- seq: row.fSequence,
76
- time: row.fCreatedAt,
77
- data: record,
78
- ...surfaceOp === void 0 ? {} : { surfaceOp }
79
- };
80
- }
81
- const SURFACE_EVENT_TYPES = /* @__PURE__ */ new Set([
82
- "system/message",
83
- "developer/message",
84
- "user/message",
85
- "assistant/message",
86
- "tool/result"
87
- ]);
88
- const METERING_EVENT_TYPES = /* @__PURE__ */ new Set(["compaction/summary", "compaction/prune"]);
89
- function surfaceSeqIndex(events) {
90
- const seqs = [];
91
- for (const event of events) if (SURFACE_EVENT_TYPES.has(event.type)) seqs.push(event.seq);
92
- return seqs;
93
- }
94
- function surfaceSeqsInRange(seqs, startSeq, endSeq) {
95
- let low = 0;
96
- let high = seqs.length;
97
- while (low < high) {
98
- const mid = low + high >> 1;
99
- if (seqs[mid] < startSeq) low = mid + 1;
100
- else high = mid;
101
- }
102
- const from = low;
103
- high = seqs.length;
104
- while (low < high) {
105
- const mid = low + high >> 1;
106
- if (seqs[mid] <= endSeq) low = mid + 1;
107
- else high = mid;
108
- }
109
- return seqs.slice(from, low);
110
- }
111
- function recomputeReplaceProvenance(events) {
112
- const seqs = surfaceSeqIndex(events);
113
- for (let i = 0; i < events.length; i++) {
114
- const raw = events[i];
115
- const op = raw.surfaceOp;
116
- if (typeof op !== "object" || op === null || op.op !== "replace") continue;
117
- const { startSeq, endSeq } = op;
118
- const metering = i > 0 ? events[i - 1] : void 0;
119
- const meteringData = metering !== void 0 && METERING_EVENT_TYPES.has(metering.type) ? metering.data : void 0;
120
- if (meteringData?.shadowedSeqs !== void 0) {
121
- raw.sourceEventSeqs = meteringData.shadowedSeqs;
122
- continue;
123
- }
124
- raw.sourceEventSeqs = surfaceSeqsInRange(seqs, startSeq, endSeq);
125
- }
126
- }
127
- function isEventSeqLike(value) {
128
- return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0);
129
- }
130
- function isDeepEqualJson(a, b) {
131
- if (a === b) return true;
132
- if (Array.isArray(a) || Array.isArray(b)) {
133
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
134
- return a.every((item, i) => isDeepEqualJson(item, b[i]));
135
- }
136
- if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
137
- const aKeys = Object.keys(a);
138
- const bRecord = b;
139
- if (aKeys.length !== Object.keys(bRecord).length) return false;
140
- return aKeys.every((key) => Object.hasOwn(bRecord, key) && isDeepEqualJson(a[key], bRecord[key]));
141
- }
142
- function toolResultRewriteContentOnly(original, replacement) {
143
- const originalData = original.data;
144
- const replacementData = replacement.data;
145
- const originalMessage = originalData["message"];
146
- const replacementMessage = replacementData["message"];
147
- if (!Array.isArray(originalMessage?.content) || !Array.isArray(replacementMessage?.content)) return false;
148
- const rest = (data, message) => ({
149
- ...data,
150
- message: {
151
- ...message,
152
- content: null
153
- }
154
- });
155
- return isDeepEqualJson(rest(originalData, originalMessage), rest(replacementData, replacementMessage));
156
- }
157
- function findSurfaceRepairs(events) {
158
- const nodes = [];
159
- const degradeToAppend = /* @__PURE__ */ new Set();
160
- const addAppendMarker = /* @__PURE__ */ new Set();
161
- const clearSurfaceOp = /* @__PURE__ */ new Set();
162
- const clampEnd = /* @__PURE__ */ new Map();
163
- for (let index = 0; index < events.length; index++) {
164
- const event = events[index];
165
- const op = event.surfaceOp;
166
- if (op === void 0) {
167
- if (SURFACE_EVENT_TYPES.has(event.type)) {
168
- addAppendMarker.add(event.seq);
169
- nodes.push(event.seq);
170
- }
171
- continue;
172
- }
173
- if (op === "append") {
174
- if (SURFACE_EVENT_TYPES.has(event.type)) nodes.push(event.seq);
175
- else clearSurfaceOp.add(event.seq);
176
- continue;
177
- }
178
- if (!SURFACE_EVENT_TYPES.has(event.type)) {
179
- clearSurfaceOp.add(event.seq);
180
- continue;
181
- }
182
- const replace = typeof op === "object" && op !== null && !Array.isArray(op) ? op : void 0;
183
- const start = replace?.["startSeq"];
184
- const end = replace?.["endSeq"];
185
- const shapeOk = replace !== void 0 && replace["op"] === "replace" && isEventSeqLike(start) && isEventSeqLike(end);
186
- const startIdx = shapeOk ? nodes.indexOf(start) : -1;
187
- let endIdx = shapeOk ? nodes.indexOf(end) : -1;
188
- let clamped;
189
- if (shapeOk && startIdx !== -1 && endIdx === -1) {
190
- clamped = clampReplaceEnd(events, index, nodes, startIdx);
191
- if (clamped !== void 0) endIdx = nodes.indexOf(clamped);
192
- }
193
- const rangeOk = shapeOk && startIdx !== -1 && endIdx !== -1 && startIdx <= endIdx;
194
- const provenanceOk = event.type !== "assistant/message";
195
- let rewriteOk = true;
196
- if (rangeOk && event.type === "tool/result") {
197
- const shadowed = nodes.slice(startIdx, endIdx + 1);
198
- if (shadowed.length !== 1) rewriteOk = false;
199
- else {
200
- const original = events[shadowed[0]];
201
- rewriteOk = original?.type === "tool/result" && toolResultRewriteContentOnly(original, event);
202
- }
203
- }
204
- if (!rangeOk || !rewriteOk || !provenanceOk) {
205
- degradeToAppend.add(event.seq);
206
- nodes.push(event.seq);
207
- continue;
208
- }
209
- if (clamped !== void 0) clampEnd.set(event.seq, clamped);
210
- nodes.splice(startIdx, endIdx - startIdx + 1, event.seq);
211
- }
212
- return {
213
- degradeToAppend,
214
- addAppendMarker,
215
- clearSurfaceOp,
216
- clampEnd
217
- };
218
- }
219
- function clampReplaceEnd(events, index, nodes, startIdx) {
220
- const metering = index > 0 ? events[index - 1] : void 0;
221
- if (metering === void 0 || !METERING_EVENT_TYPES.has(metering.type)) return void 0;
222
- const shadowedSeqs = metering.data.shadowedSeqs;
223
- if (!Array.isArray(shadowedSeqs) || shadowedSeqs.length === 0) return void 0;
224
- return nodes[Math.min(startIdx + shadowedSeqs.length - 1, nodes.length - 1)];
225
- }
226
- function repairSurfaceOps(events) {
227
- const repairs = findSurfaceRepairs(events);
228
- if (repairs.degradeToAppend.size === 0 && repairs.addAppendMarker.size === 0 && repairs.clearSurfaceOp.size === 0 && repairs.clampEnd.size === 0) return;
229
- for (const event of events) {
230
- const raw = event;
231
- const clamped = repairs.clampEnd.get(event.seq);
232
- if (repairs.degradeToAppend.has(event.seq)) raw.surfaceOp = "append";
233
- else if (clamped !== void 0) {
234
- const op = raw.surfaceOp;
235
- raw.surfaceOp = {
236
- op: "replace",
237
- startSeq: SessionSeq(op.startSeq),
238
- endSeq: SessionSeq(clamped)
239
- };
240
- } else if (repairs.addAppendMarker.has(event.seq)) raw.surfaceOp = "append";
241
- else if (repairs.clearSurfaceOp.has(event.seq)) delete raw.surfaceOp;
242
- }
243
- }
244
- function repairAssistantSettlement(events) {
245
- for (const event of events) {
246
- if (event.type !== "assistant/message" && event.type !== "assistant/attempt") continue;
247
- const data = event.data;
248
- if (!Array.isArray(data["stream"])) data["stream"] = [];
249
- }
250
- }
251
- function repairRequestHeaders(events) {
252
- for (const event of events) {
253
- if (event.type !== "request/header") continue;
254
- const header = event.data["header"];
255
- if (typeof header !== "object" || header === null || Array.isArray(header)) continue;
256
- const record = header;
257
- delete record["system"];
258
- if (Array.isArray(record["tools"]) && record["tools"].length === 0) delete record["tools"];
259
- const defaults = record["adapterDefaults"];
260
- if (typeof defaults === "object" && defaults !== null && !Array.isArray(defaults) && Object.keys(defaults).length === 0) delete record["adapterDefaults"];
261
- }
262
- }
263
- function syncMeteringRanges(events) {
264
- const seqs = surfaceSeqIndex(events);
265
- for (let i = 1; i < events.length; i++) {
266
- const metering = events[i - 1];
267
- if (!METERING_EVENT_TYPES.has(metering.type)) continue;
268
- const op = events[i].surfaceOp;
269
- if (typeof op !== "object" || op === null || op.op !== "replace") continue;
270
- const { startSeq, endSeq } = op;
271
- const data = metering.data;
272
- if (data.shadowedRange?.start === startSeq && data.shadowedRange.end === endSeq) continue;
273
- data.shadowedRange = {
274
- start: startSeq,
275
- end: endSeq
276
- };
277
- data.shadowedSeqs = surfaceSeqsInRange(seqs, startSeq, endSeq);
278
- }
279
- }
280
- const PTC_EVENT_RENAMES = {
281
- "tool/code-dispatch-start": "tool/ptc-dispatch-start",
282
- "tool/code-dispatch": "tool/ptc-dispatch"
283
- };
284
- function renamePtcMessageSource(message) {
285
- if (typeof message !== "object" || message === null || Array.isArray(message)) return message;
286
- const record = message;
287
- const source = record["source"];
288
- if (typeof source !== "object" || source === null || Array.isArray(source)) return message;
289
- const sourceRecord = source;
290
- if (sourceRecord["kind"] !== "plugin" || sourceRecord["plugin"] !== "tools-code-mode") return message;
291
- return {
292
- ...record,
293
- source: {
294
- ...sourceRecord,
295
- plugin: "tools-ptc"
296
- }
297
- };
298
- }
299
- function renameLegacyPtcEvents(events) {
300
- for (let index = 0; index < events.length; index++) {
301
- const event = events[index];
302
- const renamedType = PTC_EVENT_RENAMES[event.type];
303
- if (renamedType !== void 0) {
304
- events[index] = {
305
- ...event,
306
- type: renamedType
307
- };
308
- continue;
309
- }
310
- if (event.type === "agent-preset/selected") {
311
- const data = event.data;
312
- if (data["agentPreset"] === "code") events[index] = {
313
- ...event,
314
- data: {
315
- ...data,
316
- agentPreset: "ptc"
317
- }
318
- };
319
- continue;
320
- }
321
- if (event.type === "user/message") {
322
- const renamed = renamePtcMessageSource(event.data);
323
- if (renamed !== event.data) events[index] = {
324
- ...event,
325
- data: renamed
326
- };
327
- continue;
328
- }
329
- if (event.type === "agent/inbox/spliced" || event.type === "session/title-llm-request") {
330
- const data = event.data;
331
- const key = event.type === "agent/inbox/spliced" ? "inserted" : "messages";
332
- const list = data[key];
333
- if (!Array.isArray(list)) continue;
334
- const renamed = list.map(renamePtcMessageSource);
335
- if (renamed.some((message, position) => message !== list[position])) events[index] = {
336
- ...event,
337
- data: {
338
- ...data,
339
- [key]: renamed
340
- }
341
- };
342
- }
343
- }
344
- }
345
- function normalizeToCurrentShape(events) {
346
- for (const event of events) {
347
- const type = event.type;
348
- if (OWN_EVENT_TYPES.has(type)) {
349
- event.ignorable = true;
350
- continue;
351
- }
352
- if (type === "system/message") {
353
- const message = event.data["message"];
354
- liftSystemMessageSource(message);
355
- continue;
356
- }
357
- if (type === "tool/result") {
358
- const message = event.data["message"];
359
- liftToolResultMessage(message);
360
- }
361
- }
362
- }
363
- function liftSystemMessageSource(message) {
364
- if (typeof message !== "object" || message === null) return;
365
- const record = message;
366
- const source = record["source"];
367
- if (typeof source !== "object" || source === null) return;
368
- if (source["kind"] !== "plugin") return;
369
- record["source"] = { kind: "system-prompt" };
370
- }
371
- function liftToolResultMessage(message) {
372
- if (typeof message !== "object" || message === null) return;
373
- const record = message;
374
- if (record["role"] === "tool" && typeof record["toolCallId"] === "string") return;
375
- const source = record["source"];
376
- const block = Array.isArray(record["content"]) ? record["content"][0] : void 0;
377
- if (typeof block !== "object" || block === null) return;
378
- const lifted = block;
379
- const callId = lifted["toolCallId"] ?? source?.["callId"];
380
- if (typeof callId !== "string") return;
381
- record["role"] = "tool";
382
- record["toolCallId"] = callId;
383
- record["content"] = Array.isArray(lifted["content"]) ? lifted["content"] : [];
384
- if (typeof lifted["isError"] === "boolean") record["isError"] = lifted["isError"];
385
- record["source"] = {
386
- kind: "tool",
387
- callId
388
- };
389
- }
390
- function sealOwnEvents(events) {
391
- for (const event of events) if (OWN_EVENT_TYPES.has(event.type)) event.ignorable = true;
392
- }
393
- const OWN_EVENT_TYPES = /* @__PURE__ */ new Set(["session-branch/version", "session-mode/selected"]);
394
- function needsShapeAdoption(events) {
395
- for (const event of events) {
396
- const type = event.type;
397
- if (OWN_EVENT_TYPES.has(type)) return true;
398
- if (type === "system/message") {
399
- if ((event.data["message"]?.["source"])?.["kind"] === "plugin") return true;
400
- continue;
401
- }
402
- if (type === "tool/result") {
403
- const message = event.data["message"];
404
- if (message !== void 0 && message["role"] !== "tool") return true;
405
- }
406
- }
407
- return false;
408
- }
409
- function repairReadView(events) {
410
- repairAssistantSettlement(events);
411
- repairRequestHeaders(events);
412
- renameLegacyPtcEvents(events);
413
- repairSurfaceOps(events);
414
- syncMeteringRanges(events);
415
- recomputeReplaceProvenance(events);
416
- repairOrphanInboxSplices(events);
417
- }
418
- function orphanInboxSpliceSeqs(events) {
419
- const inbox = {
420
- "next-turn": [],
421
- "next-step": []
422
- };
423
- const orphan = /* @__PURE__ */ new Set();
424
- for (const raw of events) {
425
- const event = raw;
426
- if (event.type !== "agent/inbox/spliced") continue;
427
- const { target, start, removedCount, inserted } = event.data;
428
- const list = typeof target === "string" ? inbox[target] : void 0;
429
- if (list === void 0) {
430
- orphan.add(event.seq);
431
- continue;
432
- }
433
- const removed = removedCount ?? 0;
434
- const parsedInserted = (inserted ?? []).map((m) => ({ id: typeof m.id === "string" ? m.id : "" }));
435
- if (!Number.isSafeInteger(start) || start < 0 || start > list.length || !Number.isSafeInteger(removed) || removed < 0 || start + removed > list.length) {
436
- orphan.add(event.seq);
437
- continue;
438
- }
439
- const candidate = [
440
- ...list.slice(0, start),
441
- ...parsedInserted,
442
- ...list.slice(start + removed)
443
- ];
444
- const other = (target === "next-turn" ? inbox["next-step"] : inbox["next-turn"]) ?? [];
445
- const seen = /* @__PURE__ */ new Set();
446
- let dup = false;
447
- for (const m of [...candidate, ...other]) {
448
- if (m.id === "") continue;
449
- if (seen.has(m.id)) {
450
- dup = true;
451
- break;
452
- }
453
- seen.add(m.id);
454
- }
455
- if (dup) {
456
- orphan.add(event.seq);
457
- continue;
458
- }
459
- list.splice(start, removed, ...parsedInserted);
460
- }
461
- return orphan;
462
- }
463
- function repairOrphanInboxSplices(events) {
464
- const orphan = orphanInboxSpliceSeqs(events);
465
- if (orphan.size === 0) return;
466
- for (const event of events) {
467
- if (!orphan.has(event.seq)) continue;
468
- const target = event.data.target;
469
- event.data = {
470
- ...typeof target === "string" ? { target } : { target: "next-turn" },
471
- start: 0,
472
- removedCount: 0,
473
- inserted: []
474
- };
475
- }
476
- }
477
- function scanRows(rows, base = 0) {
478
- let lastTurnEnd = -1;
479
- for (let i = rows.length - 1; i >= 0; i--) {
480
- if (rows[i]?.fType !== "turn/end") continue;
481
- try {
482
- rowToEvent(rows[i]);
483
- lastTurnEnd = i;
484
- break;
485
- } catch {}
486
- }
487
- const preserved = [];
488
- for (let i = 0; i < rows.length; i++) {
489
- let event;
490
- try {
491
- event = rowToEvent(rows[i]);
492
- } catch {
493
- if (i <= lastTurnEnd) throw new Error(`corrupt session log: unparsable committed event at seq ${rows[i]?.fSequence}`);
494
- break;
495
- }
496
- if (event.seq !== base + i) {
497
- if (i <= lastTurnEnd) throw new Error(`corrupt session log: seq gap in committed region (expected ${base + i}, got ${event.seq})`);
498
- break;
499
- }
500
- preserved.push(event);
501
- }
502
- return preserved.length < rows.length ? {
503
- preserved,
504
- tornFrom: base + preserved.length
505
- } : { preserved };
506
- }
507
- function toJsonlArtifact(meta, inheritedEventCount, events) {
508
- const header = sessionFormatCatalog.encodeCurrentHeader({
509
- ...meta,
510
- delegationDepth: meta.delegationDepth ?? 0
511
- }, inheritedEventCount);
512
- const lines = [JSON.stringify(header)];
513
- for (const event of events) lines.push(JSON.stringify(sessionFormatCatalog.encodeCurrentEvent(event)));
514
- return lines.join("\n");
515
- }
516
- function titleOfEventData(data) {
517
- try {
518
- const value = JSON.parse(data);
519
- const title = value.data?.title ?? value.title;
520
- return typeof title === "string" ? title : void 0;
521
- } catch {
522
- return;
523
- }
524
- }
525
- function numericField(value) {
526
- return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
527
- }
528
- function textField(value) {
529
- return typeof value === "string" && value !== "" ? value : null;
530
- }
531
- function usageRowOf(event, subagent) {
532
- if (event.fType !== "assistant/message") return void 0;
533
- let parsed;
534
- try {
535
- parsed = JSON.parse(event.fData);
536
- } catch {
537
- return;
538
- }
539
- const envelope = parsed["data"] ?? parsed;
540
- const usage = envelope["usage"];
541
- if (typeof usage !== "object" || usage === null) return void 0;
542
- const source = envelope["message"]?.source;
543
- return {
544
- fEventId: event.fEventId,
545
- fCreatedAt: event.fCreatedAt,
546
- fDay: localDayKey(event.fCreatedAt),
547
- fProvider: textField(source?.["provider"]),
548
- fModel: textField(source?.["model"]),
549
- fReferenced: 1,
550
- fSubagent: subagent ? 1 : 0,
551
- fInputTokens: numericField(usage["inputTokens"]),
552
- fOutputTokens: numericField(usage["outputTokens"]),
553
- fCacheReadTokens: numericField(usage["cacheReadTokens"]),
554
- fReasoningTokens: numericField(usage["reasoningTokens"]),
555
- fTotalTokens: numericField(usage["totalTokens"])
556
- };
557
- }
558
- export { usageRowOf as S, sessionConflictRow as _, orphanInboxSpliceSeqs as a, titleOfEventData as b, repairAssistantSettlement as c, repairRequestHeaders as d, repairSurfaceOps as f, sealOwnEvents as g, scanRows as h, normalizeToCurrentShape as i, repairOrphanInboxSplices as l, rowToMeta as m, findSurfaceRepairs as n, recomputeReplaceProvenance as o, rowToEvent as p, needsShapeAdoption as r, renameLegacyPtcEvents as s, OWN_EVENT_TYPES as t, repairReadView as u, sessionInsertRow as v, toJsonlArtifact as x, syncMeteringRanges as y };
@@ -1,9 +0,0 @@
1
- // src/routes.ts
2
- const MORLAY_SESSION_API_PREFIX = "/api/morlay/v1/session";
3
- const SESSION_ROWS_PATH = `${MORLAY_SESSION_API_PREFIX}/rows`;
4
- const SESSION_EXPORT_PATH = `${MORLAY_SESSION_API_PREFIX}/export`;
5
- const SESSION_IMPORT_PATH = `${MORLAY_SESSION_API_PREFIX}/import`;
6
- const SESSION_DELETE_PATH = `${MORLAY_SESSION_API_PREFIX}/delete`;
7
- const SESSION_GC_PATH = `${MORLAY_SESSION_API_PREFIX}/gc`;
8
- const SESSION_USAGE_PATH = `${MORLAY_SESSION_API_PREFIX}/usage`;
9
- export { SESSION_ROWS_PATH as a, SESSION_IMPORT_PATH as i, SESSION_EXPORT_PATH as n, SESSION_USAGE_PATH as o, SESSION_GC_PATH as r, SESSION_DELETE_PATH as t };