@morlay/session-rdb 0.0.21-alpha.7 → 0.0.21-alpha.8
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 +17 -10
- package/dist/artifact.d.mts +2 -101
- package/dist/artifact.mjs +2 -2
- package/dist/{branch-BjUR6wfe.mjs → branch-7eOh_tbO.mjs} +3 -3
- package/dist/deletion.d.mts +1 -1
- package/dist/deletion.mjs +1 -1
- package/dist/import.d.mts +1 -1
- package/dist/import.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +3 -3
- package/dist/{backend-E0bmTXpz.d.mts → log-BbleqD1M.d.mts} +171 -24
- package/dist/{log-qCNkDjh5.mjs → log-DTcvsMz7.mjs} +189 -12
- package/dist/{sqlite-zcXVyMxr.mjs → sqlite-ChM_sHAG.mjs} +320 -259
- package/dist/{src-B9X8BKyh.mjs → src-BWqePRA7.mjs} +290 -162
- package/dist/storage.d.mts +20 -7
- package/dist/storage.mjs +2 -2
- package/dist/testing.d.mts +1 -1
- package/dist/testing.mjs +1 -1
- package/drizzle/postgres/20260923120000_v3_usage_materialized/migration.sql +48 -0
- package/drizzle/sqlite/20260923120000_v3_usage_materialized/migration.sql +48 -0
- package/package.json +20 -20
- package/src/backend.ts +41 -17
- package/src/branch.ts +4 -4
- package/src/drizzle/postgres-v3.ts +2 -0
- package/src/drizzle/sqlite-v3.ts +2 -0
- package/src/entities/v3/event-usage.ts +8 -1
- package/src/entities/v3/index.ts +8 -0
- package/src/entities/v3/session-counts.ts +23 -0
- package/src/entities/v3/session-usage.ts +29 -0
- package/src/index.ts +109 -43
- package/src/log.ts +58 -17
- package/src/postgres.ts +248 -149
- package/src/rows.ts +2 -1
- package/src/schema.ts +4 -0
- package/src/sqlite.ts +263 -124
- package/src/storage-takeover/repository.ts +1 -4
- package/src/usage.ts +10 -6
package/README.md
CHANGED
|
@@ -80,10 +80,10 @@ web 模式经 `POST /api/session.delete`(body `{ sessionId }`)暴露,状
|
|
|
80
80
|
|
|
81
81
|
## 会话列表(两条路)
|
|
82
82
|
|
|
83
|
-
| 用途
|
|
84
|
-
|
|
|
85
|
-
| 官方 UI(上游 `ui
|
|
86
|
-
| 我们自己的管理面
|
|
83
|
+
| 用途 | 接缝 | 内容 |
|
|
84
|
+
| ---------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
85
|
+
| 官方 UI(上游 `ui-*`) | `session/list` → `ctx.sessionQuery.listSessions`(本包接管,**默认排除已归档**) | 未归档的可见语料,标题走投影(`projections.title`) |
|
|
86
|
+
| 我们自己的管理面 | `POST /api/session.rows`(本包路由) | **完整语料(含归档)** + 标题 + 最后活动时间 + 工作区归属,**搜索 / 子代理过滤 / 分页都在后端** |
|
|
87
87
|
|
|
88
88
|
排除归档是本部署的策略:归档是「收起来」的会话,不该混进日常列表与搜索。管理动作(取消归档 / 删除 /
|
|
89
89
|
导入)需要完整集合,所以另给一条自有路由,两条路不混。决策与取舍见
|
|
@@ -118,13 +118,20 @@ subagent 会话**(`origin = 'subagent'`、父不在表里;有 open handle /
|
|
|
118
118
|
## 用量统计
|
|
119
119
|
|
|
120
120
|
`POST /api/session.usage` 一次回报三份数据:`totals`(含 `subagent` / `human` 拆分)、按
|
|
121
|
-
天 × provider/model × subagent
|
|
121
|
+
天 × provider/model × subagent 的桶、按会话的行(活动计数:轮次 / 步骤 / 用户输入 / 工具调用)。
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
统计读侧只读三张**可销毁重建的派生表**,读侧维度(会话 / 模型 / 本地日 / 是否被引用 / 是否子代理)
|
|
124
|
+
全部在写入时物化,查询不做 `EXISTS`、也不回连事件表:
|
|
125
|
+
|
|
126
|
+
- `t_event_usage`——一条 `assistant/message` 事件行一行(去重口径的总量与「天 × 模型」桶读它);
|
|
127
|
+
- `t_session_usage`——会话 × 本地日 × 模型的 token 汇总(按会话的行读它,含 fork 继承前缀);
|
|
128
|
+
- `t_session_counts`——会话 × 本地日的四项活动计数。
|
|
129
|
+
|
|
130
|
+
写入时在事务内落用量行、事务后**旁路累加**两张汇总表;rewind / fork / 删除会话之后按会话重算并全量重算
|
|
131
|
+
引用标记;表为空(首次 / 迁移后 / 手动清空)在打开库时全量回填——迁移对这三张表先删后建。真实库实测
|
|
132
|
+
单次统计从 **1.6s → ~140ms → ~30ms**(口径不变,旧口径逐项交叉核对一致),升级后首次打开付一次回填
|
|
133
|
+
(2.4s / 3.09 万用量行,此后不再发生)。口径与取舍见
|
|
134
|
+
[ADR-统计衍生表物化归属与汇总](.agents/adrs/20260923-统计衍生表物化归属与汇总.md)。
|
|
128
135
|
|
|
129
136
|
## 查询接管(`ctx.sessionQuery`)
|
|
130
137
|
|
package/dist/artifact.d.mts
CHANGED
|
@@ -1,102 +1,3 @@
|
|
|
1
|
-
import { i as
|
|
1
|
+
import { C as usageRowOf, S as toJsonlArtifact, _ as sealOwnEvents, a as normalizeToCurrentShape, b as syncMeteringRanges, c as renameLegacyPtcEvents, d as repairReadView, f as repairRequestHeaders, g as scanRows, h as rowToMeta, i as needsShapeAdoption, l as repairAssistantSettlement, m as rowToEvent, n as OWN_EVENT_TYPES, o as orphanInboxSpliceSeqs, p as repairSurfaceOps, r as findSurfaceRepairs, s as recomputeReplaceProvenance, t as EventUsageRow, u as repairOrphanInboxSplices, v as sessionConflictRow, x as titleOfEventData, y as sessionInsertRow } from "./log-BbleqD1M.mjs";
|
|
2
2
|
import { SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, parseImportZip, parseJsonlArtifact, persistImport, registerSessionImport } from "./import.mjs";
|
|
3
|
-
|
|
4
|
-
import { SessionEvent, SessionHeader } from "@deepseek-ai/dsh-session";
|
|
5
|
-
//#region src/log.d.ts
|
|
6
|
-
declare function rowToMeta(row: SessionRow): SessionHeader;
|
|
7
|
-
declare function sessionInsertRow(storage: SessionStorageMetadata, incarnation: string): {
|
|
8
|
-
fSessionId: string;
|
|
9
|
-
fHeadEventId: string;
|
|
10
|
-
fHeadSequence: number;
|
|
11
|
-
fVersion: number;
|
|
12
|
-
fCreatedAt: number;
|
|
13
|
-
fCwd: string | null;
|
|
14
|
-
fParentSession: string | null;
|
|
15
|
-
fSeedLength: number | null;
|
|
16
|
-
fOrigin: string | null;
|
|
17
|
-
fDelegationDepth: number | null;
|
|
18
|
-
fAgentPreset: string | null;
|
|
19
|
-
fIncarnation: string;
|
|
20
|
-
fRevision: number;
|
|
21
|
-
};
|
|
22
|
-
declare function sessionConflictRow(storage: SessionStorageMetadata): {
|
|
23
|
-
fVersion: number;
|
|
24
|
-
fCreatedAt: number;
|
|
25
|
-
fCwd: string | null;
|
|
26
|
-
fParentSession: string | null;
|
|
27
|
-
fSeedLength: number | null;
|
|
28
|
-
fOrigin: string | null;
|
|
29
|
-
fDelegationDepth: number | null;
|
|
30
|
-
fAgentPreset: string | null;
|
|
31
|
-
};
|
|
32
|
-
declare function rowToEvent(row: EventRow): SessionEvent;
|
|
33
|
-
declare function recomputeReplaceProvenance(events: SessionEvent[]): void;
|
|
34
|
-
declare function findSurfaceRepairs(events: readonly SessionEvent[]): {
|
|
35
|
-
degradeToAppend: Set<number>;
|
|
36
|
-
addAppendMarker: Set<number>;
|
|
37
|
-
clearSurfaceOp: Set<number>;
|
|
38
|
-
clampEnd: Map<number, number>;
|
|
39
|
-
};
|
|
40
|
-
declare function repairSurfaceOps(events: SessionEvent[]): void;
|
|
41
|
-
declare function repairAssistantSettlement(events: SessionEvent[]): void;
|
|
42
|
-
declare function repairRequestHeaders(events: SessionEvent[]): void;
|
|
43
|
-
declare function syncMeteringRanges(events: SessionEvent[]): void;
|
|
44
|
-
declare function renameLegacyPtcEvents(events: SessionEvent[]): void;
|
|
45
|
-
/**
|
|
46
|
-
* 把**旧代(v3 及更早)的消息形状**归一到当前格式(v4):迁移链(严格)拒绝那些形状时,读路径仍要
|
|
47
|
-
* 能把它们读出来——只动字段与标记,不改坐标、不改内容。
|
|
48
|
-
*
|
|
49
|
-
* 三件事:
|
|
50
|
-
* - `system/message` 的 source:`{ kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }` → `{ kind: 'system-prompt' }`
|
|
51
|
-
* (v4 起 system 消息只认这个 kind);
|
|
52
|
-
* - `tool/result` 的消息:v3 是 user 角色、结果块包在 `content[0]`;v4 是 `role: 'tool'` + 顶层
|
|
53
|
-
* `toolCallId` + `content` 就是结果块;
|
|
54
|
-
* - 本仓库自己写过、上游已删除的事件类型(见 `LEGACY_OWN_EVENT_TYPES`)标 `ignorable: true`——v4 的
|
|
55
|
-
* 校验对未知类型只接受可忽略信封。
|
|
56
|
-
*
|
|
57
|
-
* 只认这张白名单:**其它未知类型保持 fail loud**(那是「数据来自更新的 harness」的信号,不能吞掉)。
|
|
58
|
-
*/
|
|
59
|
-
declare function normalizeToCurrentShape(events: SessionEvent[]): void;
|
|
60
|
-
/**
|
|
61
|
-
* 本仓库写过、后来连同机制一起删除的事件类型:读的时候标 `ignorable: true` 让校验跳过它们。
|
|
62
|
-
* 新增历史类型时登记到这里——**不要**用「所有未知类型」代替(那会掩盖更新版本的未知事件)。
|
|
63
|
-
*/
|
|
64
|
-
declare const LEGACY_OWN_EVENT_TYPES: ReadonlySet<string>;
|
|
65
|
-
/** 行里是否还带着旧代消息形状(`session-branch/version` 这类自造事件也算)——写路径曾把回退视图的结果
|
|
66
|
-
* 以当前版本号落库,所以**版本号不可信**,读之前要按内容判一次。 */
|
|
67
|
-
declare function hasLegacyShape(events: readonly SessionEvent[]): boolean;
|
|
68
|
-
declare function repairReadView(events: SessionEvent[]): void;
|
|
69
|
-
declare function orphanInboxSpliceSeqs(events: readonly SessionEvent[]): Set<number>;
|
|
70
|
-
declare function repairOrphanInboxSplices(events: SessionEvent[]): void;
|
|
71
|
-
declare function scanRows(rows: readonly EventRow[], base?: number): {
|
|
72
|
-
preserved: SessionEvent[];
|
|
73
|
-
tornFrom?: number;
|
|
74
|
-
};
|
|
75
|
-
declare function toJsonlArtifact(meta: SessionHeader, inheritedEventCount: number, events: readonly SessionEvent[]): string;
|
|
76
|
-
declare function titleOfEventData(data: string): string | undefined;
|
|
77
|
-
/** 用量行的列(`t_event_usage`)。 */
|
|
78
|
-
interface EventUsageRow {
|
|
79
|
-
fEventId: string;
|
|
80
|
-
fCreatedAt: number;
|
|
81
|
-
fProvider: string | null;
|
|
82
|
-
fModel: string | null;
|
|
83
|
-
fInputTokens: number;
|
|
84
|
-
fOutputTokens: number;
|
|
85
|
-
fCacheReadTokens: number;
|
|
86
|
-
fReasoningTokens: number;
|
|
87
|
-
fTotalTokens: number;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* 一条事件行的用量(只有带 `usage` 的 `assistant/message` 才有):写路径据此记录
|
|
91
|
-
* `t_event_usage`,统计因此不必逐行解析 JSON。两种 `f_data` 结构(带信封 / 老格式)都认。
|
|
92
|
-
* @param event - 待写入的事件行。
|
|
93
|
-
* @returns 用量行,或该事件没有用量时的 undefined。
|
|
94
|
-
*/
|
|
95
|
-
declare function usageRowOf(event: {
|
|
96
|
-
fEventId: string;
|
|
97
|
-
fCreatedAt: number;
|
|
98
|
-
fType: string;
|
|
99
|
-
fData: string;
|
|
100
|
-
}): EventUsageRow | undefined;
|
|
101
|
-
//#endregion
|
|
102
|
-
export { EventUsageRow, LEGACY_OWN_EVENT_TYPES, SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, findSurfaceRepairs, hasLegacyShape, normalizeToCurrentShape, orphanInboxSpliceSeqs, parseImportZip, parseJsonlArtifact, persistImport, recomputeReplaceProvenance, registerSessionImport, renameLegacyPtcEvents, repairAssistantSettlement, repairOrphanInboxSplices, repairReadView, repairRequestHeaders, repairSurfaceOps, rowToEvent, rowToMeta, scanRows, sessionConflictRow, sessionInsertRow, syncMeteringRanges, titleOfEventData, toJsonlArtifact, usageRowOf };
|
|
3
|
+
export { EventUsageRow, OWN_EVENT_TYPES, SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, findSurfaceRepairs, needsShapeAdoption, normalizeToCurrentShape, orphanInboxSpliceSeqs, parseImportZip, parseJsonlArtifact, persistImport, recomputeReplaceProvenance, registerSessionImport, renameLegacyPtcEvents, repairAssistantSettlement, repairOrphanInboxSplices, repairReadView, repairRequestHeaders, repairSurfaceOps, rowToEvent, rowToMeta, scanRows, sealOwnEvents, sessionConflictRow, sessionInsertRow, syncMeteringRanges, titleOfEventData, toJsonlArtifact, usageRowOf };
|
package/dist/artifact.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { S as usageRowOf, _ as sessionConflictRow, a as orphanInboxSpliceSeqs, b as titleOfEventData, c as repairAssistantSettlement, d as repairRequestHeaders, f as repairSurfaceOps, g as sealOwnEvents, h as scanRows, i as normalizeToCurrentShape, l as repairOrphanInboxSplices, m as rowToMeta, n as findSurfaceRepairs, o as recomputeReplaceProvenance, p as rowToEvent, r as needsShapeAdoption, s as renameLegacyPtcEvents, t as OWN_EVENT_TYPES, u as repairReadView, v as sessionInsertRow, x as toJsonlArtifact, y as syncMeteringRanges } from "./log-DTcvsMz7.mjs";
|
|
2
2
|
import { SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, parseImportZip, parseJsonlArtifact, persistImport, registerSessionImport } from "./import.mjs";
|
|
3
|
-
export {
|
|
3
|
+
export { OWN_EVENT_TYPES, SESSION_IMPORT_PATH, SESSION_LOG_ARTIFACT_FILENAME, findSurfaceRepairs, needsShapeAdoption, normalizeToCurrentShape, orphanInboxSpliceSeqs, parseImportZip, parseJsonlArtifact, persistImport, recomputeReplaceProvenance, registerSessionImport, renameLegacyPtcEvents, repairAssistantSettlement, repairOrphanInboxSplices, repairReadView, repairRequestHeaders, repairSurfaceOps, rowToEvent, rowToMeta, scanRows, sealOwnEvents, sessionConflictRow, sessionInsertRow, syncMeteringRanges, titleOfEventData, toJsonlArtifact, usageRowOf };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as repairRequestHeaders, h as scanRows, i as normalizeToCurrentShape, m as rowToMeta } from "./log-
|
|
1
|
+
import { d as repairRequestHeaders, h as scanRows, i as normalizeToCurrentShape, m as rowToMeta } from "./log-DTcvsMz7.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { SESSION_FORMAT_VERSION, SessionLogOffset } from "@deepseek-ai/dsh-session";
|
|
4
4
|
import { createSessionFormatCatalogWithChildren } from "@deepseek-ai/dsh-session-format-catalog";
|
|
@@ -217,7 +217,7 @@ var SessionBranchRdbProvider = class {
|
|
|
217
217
|
internals.dropReuseEventIds(childId);
|
|
218
218
|
throw error;
|
|
219
219
|
}
|
|
220
|
-
await this.persistence.
|
|
220
|
+
await this.persistence.rebuildSessionStats(childId);
|
|
221
221
|
return childId;
|
|
222
222
|
}
|
|
223
223
|
async rewind(id, toBoundary, signal) {
|
|
@@ -290,7 +290,7 @@ var SessionBranchRdbProvider = class {
|
|
|
290
290
|
headSeq: keepLength - 1,
|
|
291
291
|
snapshotEvents: () => []
|
|
292
292
|
});
|
|
293
|
-
await this.persistence.
|
|
293
|
+
await this.persistence.rebuildSessionStats(id);
|
|
294
294
|
return {
|
|
295
295
|
header: rowToMeta(row),
|
|
296
296
|
revision: await internals.readStoredRevision(id)
|
package/dist/deletion.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { L as SessionPersistenceRdb } from "./log-BbleqD1M.mjs";
|
|
2
2
|
import { Context } from "@deepseek-ai/cordis";
|
|
3
3
|
//#region src/deletion.d.ts
|
|
4
4
|
declare const SESSION_DELETE_PATH = "/api/session.delete";
|
package/dist/deletion.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as registerSessionDeletion, i as SESSION_DELETE_PATH } from "./src-
|
|
1
|
+
import { a as registerSessionDeletion, i as SESSION_DELETE_PATH } from "./src-BWqePRA7.mjs";
|
|
2
2
|
export { SESSION_DELETE_PATH, registerSessionDeletion };
|
package/dist/import.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { L as SessionPersistenceRdb } from "./log-BbleqD1M.mjs";
|
|
2
2
|
import { SessionStorageMetadata } from "@deepseek-ai/dsh-session-persistence";
|
|
3
3
|
import { Session, SessionEvent, SessionId } from "@deepseek-ai/dsh-session";
|
|
4
4
|
import { Context } from "@deepseek-ai/cordis";
|
package/dist/import.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as replaceLiveSessionLog, l as restoreCatalog } from "./branch-
|
|
1
|
+
import { i as replaceLiveSessionLog, l as restoreCatalog } from "./branch-7eOh_tbO.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { SESSION_FORMAT_VERSION, SessionLogOffset } from "@deepseek-ai/dsh-session";
|
|
4
4
|
import { parseSessionFormatLogFilename } from "@deepseek-ai/dsh-session-format";
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as SessionBranchRdbProvider, F as SessionDeletionError, G as SessionRowsValue, I as SessionDeletionErrorCode, L as SessionPersistenceRdb, N as Config, P as ProjectionCacheOptions, R as SessionPersistenceRdbInternals, U as SESSION_ROWS_PATH, V as locateTurnEnd, W as SessionRowsItem, Z as SCHEMA_VERSION, z as SessionBranchRdb } from "./log-BbleqD1M.mjs";
|
|
2
2
|
export { Config, ProjectionCacheOptions, SCHEMA_VERSION, SESSION_ROWS_PATH, SessionBranchRdb, SessionBranchRdbProvider, SessionDeletionError, SessionDeletionErrorCode, SessionPersistenceRdb, SessionPersistenceRdb as default, SessionPersistenceRdbInternals, type SessionRowsItem, type SessionRowsValue, locateTurnEnd };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as SessionPersistenceRdb, r as SESSION_ROWS_PATH, t as SessionDeletionError } from "./src-
|
|
3
|
-
import { n as SessionBranchRdbProvider, r as locateTurnEnd, t as SessionBranchRdb } from "./branch-
|
|
1
|
+
import { o as SCHEMA_VERSION } from "./sqlite-ChM_sHAG.mjs";
|
|
2
|
+
import { n as SessionPersistenceRdb, r as SESSION_ROWS_PATH, t as SessionDeletionError } from "./src-BWqePRA7.mjs";
|
|
3
|
+
import { n as SessionBranchRdbProvider, r as locateTurnEnd, t as SessionBranchRdb } from "./branch-7eOh_tbO.mjs";
|
|
4
4
|
export { SCHEMA_VERSION, SESSION_ROWS_PATH, SessionBranchRdb, SessionBranchRdbProvider, SessionDeletionError, SessionPersistenceRdb, SessionPersistenceRdb as default, locateTurnEnd };
|
|
@@ -3478,6 +3478,8 @@ declare const tWorkspaceSessions: any;
|
|
|
3478
3478
|
declare const tWorkspaceState: any;
|
|
3479
3479
|
declare const tSessionProjcacheRows: any;
|
|
3480
3480
|
declare const tEventUsage: any;
|
|
3481
|
+
declare const tSessionUsage: any;
|
|
3482
|
+
declare const tSessionCounts: any;
|
|
3481
3483
|
type JournalMode = "wal" | "delete" | "truncate" | "persist";
|
|
3482
3484
|
declare const DEFAULT_BUSY_TIMEOUT_MS = 5000;
|
|
3483
3485
|
type EventKind = "message" | "thinking" | "turn" | "tool" | "request" | "config" | "audit" | "lifecycle" | "inbox" | "compaction" | "llm" | "subagent" | "team" | "workflow" | "goal" | "schedule" | "todo" | "web";
|
|
@@ -3740,14 +3742,18 @@ declare class SessionPersistenceRdb extends SessionPersistence {
|
|
|
3740
3742
|
migrated: boolean;
|
|
3741
3743
|
} | undefined>;
|
|
3742
3744
|
/**
|
|
3743
|
-
*
|
|
3744
|
-
*
|
|
3745
|
+
* 统计衍生表的**旁路累加**:不在写事务里、失败只 warn——两张会话汇总表都是可销毁重建的
|
|
3746
|
+
* 派生表,丢几次累加不影响可用性(需要时用 `rebuildSessionStats` 重算)。
|
|
3747
|
+
* token 走写路径已折好的用量行,活动计数走本批事件类型。
|
|
3745
3748
|
*/
|
|
3746
|
-
private
|
|
3747
|
-
/**
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3749
|
+
private recordSessionStats;
|
|
3750
|
+
/**
|
|
3751
|
+
* 重算一个会话的统计(rewind / fork 之后;best-effort,同 `recordSessionStats`):
|
|
3752
|
+
* 两张汇总表按会话重算,用量行的引用标记全量重算(引用可能跨会话消失)。
|
|
3753
|
+
*/
|
|
3754
|
+
rebuildSessionStats(id: SessionId): Promise<void>;
|
|
3755
|
+
/** 会话删除时清掉它的汇总行,并重算用量行的引用标记(被删会话引用的行要立刻退出统计)。 */
|
|
3756
|
+
private dropSessionStats;
|
|
3751
3757
|
private rewriteMigratedLog;
|
|
3752
3758
|
listSnapshots(signal?: AbortSignal): Promise<Array<SessionPersistenceSnapshot & {
|
|
3753
3759
|
inheritedEventCount: number;
|
|
@@ -3870,7 +3876,11 @@ interface BackendTx {
|
|
|
3870
3876
|
getSeedLength(id: SessionId): Promise<number | null>;
|
|
3871
3877
|
updateSeedLength(id: SessionId, seedLength: number): Promise<void>;
|
|
3872
3878
|
refreshTitle(id: SessionId): Promise<void>;
|
|
3873
|
-
|
|
3879
|
+
/**
|
|
3880
|
+
* 插入事件行与它们的用量行(`usageRows` 由写路径一次折好,读侧维度已物化在行上)。
|
|
3881
|
+
* 这一批事件与桥接行同事务,提交即「被引用」。
|
|
3882
|
+
*/
|
|
3883
|
+
insertEvents(events: EventInsert[], usageRows: readonly EventUsageRow[]): Promise<void>;
|
|
3874
3884
|
insertBridges(rows: Array<{
|
|
3875
3885
|
fSessionId: SessionId;
|
|
3876
3886
|
fEventId: string;
|
|
@@ -3922,11 +3932,15 @@ interface SessionListRowsPage {
|
|
|
3922
3932
|
/** 过滤后的总数(分页前的),前端据此算页数。 */
|
|
3923
3933
|
total: number;
|
|
3924
3934
|
}
|
|
3925
|
-
/** 活动计数的一个桶:本地日 +
|
|
3926
|
-
interface
|
|
3935
|
+
/** 活动计数的一个桶:本地日 + 四项计数(轮次 / 步骤 / 用户输入 / 工具调用)。 */
|
|
3936
|
+
interface SessionCountBucket extends UsageActivityTotals {
|
|
3927
3937
|
day: string;
|
|
3928
|
-
|
|
3929
|
-
|
|
3938
|
+
}
|
|
3939
|
+
/** 用量累加的一个桶:本地日 + 模型归属 + 五个 token 列。 */
|
|
3940
|
+
interface SessionUsageBucket extends UsageTokenTotals {
|
|
3941
|
+
day: string;
|
|
3942
|
+
provider: string | null;
|
|
3943
|
+
model: string | null;
|
|
3930
3944
|
}
|
|
3931
3945
|
interface Backend {
|
|
3932
3946
|
readonly kind: "sqlite" | "postgres";
|
|
@@ -3944,30 +3958,163 @@ interface Backend {
|
|
|
3944
3958
|
/** 父会话已不存在(或没有父)的 subagent 会话:父被删后它们成了孤儿。 */
|
|
3945
3959
|
listOrphanSubagentSessions(): Promise<SessionId[]>;
|
|
3946
3960
|
/**
|
|
3947
|
-
*
|
|
3948
|
-
*
|
|
3949
|
-
* @param sinceMs -
|
|
3961
|
+
* 用量统计的原始聚合:读三张派生统计表(`t_event_usage` + 两张会话汇总表),
|
|
3962
|
+
* 给出总量 / subagent 拆分、按天×模型的桶与按会话的行(事件行去重、排除孤儿)。
|
|
3963
|
+
* @param sinceMs - 只算该时刻(含)之后的用量;省略即全量。会话汇总表按本地日过滤,
|
|
3964
|
+
* 与毫秒过滤等价的前提是调用方把起点对齐到本地零点(见 `resolveUsageSince`)。
|
|
3950
3965
|
*/
|
|
3951
3966
|
usageReport(sinceMs?: number): Promise<UsageAggregate>;
|
|
3952
3967
|
/** 管理面的会话行列表:完整语料(含归档)+ 标题 + 最后活动时间,按活动倒序分页。 */
|
|
3953
3968
|
listSessionRows(query?: SessionListRowsQuery): Promise<SessionListRowsPage>;
|
|
3954
3969
|
/**
|
|
3955
|
-
*
|
|
3956
|
-
* 每个 (会话, 本地日,
|
|
3970
|
+
* token 用量**旁路累加**(派生表 `t_session_usage`,不参与写事务、失败可丢——表可销毁重建):
|
|
3971
|
+
* 每个 (会话, 本地日, 模型) 记一行累加。
|
|
3972
|
+
* @param id - 会话 id。
|
|
3973
|
+
* @param buckets - 本批要累加的 (day, provider, model, tokens)。
|
|
3974
|
+
*/
|
|
3975
|
+
incrementSessionUsage(id: SessionId, buckets: readonly SessionUsageBucket[]): Promise<void>;
|
|
3976
|
+
/**
|
|
3977
|
+
* 活动计数**旁路累加**(派生表 `t_session_counts`,同上):每个 (会话, 本地日) 累加四项计数。
|
|
3957
3978
|
* @param id - 会话 id。
|
|
3958
|
-
* @param buckets - 本批要累加的 (day,
|
|
3979
|
+
* @param buckets - 本批要累加的 (day, turns, steps, userInputs, toolCalls)。
|
|
3959
3980
|
*/
|
|
3960
|
-
|
|
3981
|
+
incrementSessionCounts(id: SessionId, buckets: readonly SessionCountBucket[]): Promise<void>;
|
|
3961
3982
|
/**
|
|
3962
|
-
*
|
|
3983
|
+
* 按会话从事件表重算两张会话汇总表(rewind / fork 之后调用):先删该会话的行再重算。
|
|
3963
3984
|
* @param id - 会话 id。
|
|
3964
3985
|
*/
|
|
3965
|
-
|
|
3966
|
-
/**
|
|
3967
|
-
|
|
3986
|
+
rebuildSessionStats(id: SessionId): Promise<void>;
|
|
3987
|
+
/**
|
|
3988
|
+
* 全量重算 `t_event_usage` 的引用标记(`f_referenced` / `f_subagent`):rewind / fork / 会话删除之后调用。
|
|
3989
|
+
* 引用可能跨会话消失(截断、删除),只按本会话判定不够,故这里是全量。
|
|
3990
|
+
*/
|
|
3991
|
+
refreshEventUsageFlags(): Promise<void>;
|
|
3992
|
+
/** 删掉一个会话的汇总行(会话删除时;外键 CASCADE 之外再显式清一次)。 */
|
|
3993
|
+
deleteSessionStats(id: SessionId): Promise<void>;
|
|
3968
3994
|
/** 回收空间与统计(含 VACUUM);不得在事务内执行。 */
|
|
3969
3995
|
vacuum(): Promise<void>;
|
|
3970
3996
|
close(): Promise<void>;
|
|
3971
3997
|
}
|
|
3972
3998
|
//#endregion
|
|
3973
|
-
|
|
3999
|
+
//#region src/log.d.ts
|
|
4000
|
+
declare function rowToMeta(row: SessionRow): SessionHeader;
|
|
4001
|
+
declare function sessionInsertRow(storage: SessionStorageMetadata, incarnation: string): {
|
|
4002
|
+
fSessionId: string;
|
|
4003
|
+
fHeadEventId: string;
|
|
4004
|
+
fHeadSequence: number;
|
|
4005
|
+
fVersion: number;
|
|
4006
|
+
fCreatedAt: number;
|
|
4007
|
+
fCwd: string | null;
|
|
4008
|
+
fParentSession: string | null;
|
|
4009
|
+
fSeedLength: number | null;
|
|
4010
|
+
fOrigin: string | null;
|
|
4011
|
+
fDelegationDepth: number | null;
|
|
4012
|
+
fAgentPreset: string | null;
|
|
4013
|
+
fIncarnation: string;
|
|
4014
|
+
fRevision: number;
|
|
4015
|
+
};
|
|
4016
|
+
declare function sessionConflictRow(storage: SessionStorageMetadata): {
|
|
4017
|
+
fVersion: number;
|
|
4018
|
+
fCreatedAt: number;
|
|
4019
|
+
fCwd: string | null;
|
|
4020
|
+
fParentSession: string | null;
|
|
4021
|
+
fSeedLength: number | null;
|
|
4022
|
+
fOrigin: string | null;
|
|
4023
|
+
fDelegationDepth: number | null;
|
|
4024
|
+
fAgentPreset: string | null;
|
|
4025
|
+
};
|
|
4026
|
+
declare function rowToEvent(row: EventRow): SessionEvent;
|
|
4027
|
+
declare function recomputeReplaceProvenance(events: SessionEvent[]): void;
|
|
4028
|
+
declare function findSurfaceRepairs(events: readonly SessionEvent[]): {
|
|
4029
|
+
degradeToAppend: Set<number>;
|
|
4030
|
+
addAppendMarker: Set<number>;
|
|
4031
|
+
clearSurfaceOp: Set<number>;
|
|
4032
|
+
clampEnd: Map<number, number>;
|
|
4033
|
+
};
|
|
4034
|
+
declare function repairSurfaceOps(events: SessionEvent[]): void;
|
|
4035
|
+
declare function repairAssistantSettlement(events: SessionEvent[]): void;
|
|
4036
|
+
declare function repairRequestHeaders(events: SessionEvent[]): void;
|
|
4037
|
+
declare function syncMeteringRanges(events: SessionEvent[]): void;
|
|
4038
|
+
declare function renameLegacyPtcEvents(events: SessionEvent[]): void;
|
|
4039
|
+
/**
|
|
4040
|
+
* 把**旧代(v3 及更早)的消息形状**归一到当前格式(v4):迁移链(严格)拒绝那些形状时,读路径仍要
|
|
4041
|
+
* 能把它们读出来——只动字段与标记,不改坐标、不改内容。
|
|
4042
|
+
*
|
|
4043
|
+
* 三件事:
|
|
4044
|
+
* - `system/message` 的 source:`{ kind: 'plugin', plugin: '@deepseek-ai/dsh-system-prompt' }` → `{ kind: 'system-prompt' }`
|
|
4045
|
+
* (v4 起 system 消息只认这个 kind);
|
|
4046
|
+
* - `tool/result` 的消息:v3 是 user 角色、结果块包在 `content[0]`;v4 是 `role: 'tool'` + 顶层
|
|
4047
|
+
* `toolCallId` + `content` 就是结果块;
|
|
4048
|
+
* - **本仓库自造、上游不认识的事件类型**(见 `OWN_EVENT_TYPES`:历史遗留的与我们当前在写的)标
|
|
4049
|
+
* `ignorable: true`——v4 的校验对未知类型只接受可忽略信封。
|
|
4050
|
+
*
|
|
4051
|
+
* 只认这张白名单:**其它未知类型保持 fail loud**(那是「数据来自更新的 harness」的信号,不能吞掉)。
|
|
4052
|
+
*/
|
|
4053
|
+
declare function normalizeToCurrentShape(events: SessionEvent[]): void;
|
|
4054
|
+
/**
|
|
4055
|
+
* 落库前给**本仓库自造的事件类型**补上 `ignorable: true` 信封。
|
|
4056
|
+
*
|
|
4057
|
+
* 上游的持久化校验(`validateStoredEvents`)只放行「已知类型」或「带可忽略信封的未知类型」,我们的类型
|
|
4058
|
+
* 按构造就在已知表之外——不补的话连**写入**都会被拒(`appendBatch` 里那道校验)。上游 `Session.append`
|
|
4059
|
+
* 没有承载这个信封的口子(第三个参数只服务 surface 事件),所以这一笔由持久化层补:canonical log 里的
|
|
4060
|
+
* 形状不变,落库的那一份带上信封。
|
|
4061
|
+
* @param events - 即将落库的批次(`materializeAppendBatch` 的 JSON 快照副本,可写)。
|
|
4062
|
+
*/
|
|
4063
|
+
declare function sealOwnEvents(events: readonly SessionEvent[]): void;
|
|
4064
|
+
/**
|
|
4065
|
+
* 本仓库自造、上游不认识的事件类型:读的时候标 `ignorable: true`,v4 的持久化校验才肯跳过它们
|
|
4066
|
+
* (`validateStoredEvents` 只放行「已知类型」或「带可忽略信封的未知类型」)。
|
|
4067
|
+
*
|
|
4068
|
+
* 两类都在这张表里:
|
|
4069
|
+
* - **历史遗留**:写过、后来连同机制一起删除的(`session-branch/version`);
|
|
4070
|
+
* - **当前在写**:本仓库的插件自己声明的事件类型(`session-mode/selected`)——上游的
|
|
4071
|
+
* `KNOWN_SESSION_EVENT_TYPES` 由上游仓库的声明生成,外部插件的事件按构造就在它之外。
|
|
4072
|
+
*
|
|
4073
|
+
* 新增自造事件类型时**必须**登记到这里,否则读路径 fail loud(真回归:`session-mode/selected` 漏登记,
|
|
4074
|
+
* 会话打不开)。**不要**用「所有未知类型」代替(那会掩盖更新版本的未知事件——那种必须拒读)。
|
|
4075
|
+
*/
|
|
4076
|
+
declare const OWN_EVENT_TYPES: ReadonlySet<string>;
|
|
4077
|
+
/** 这批事件是否需要按当前形状归一(旧代消息形状,或尚未标 `ignorable` 的自造事件类型)——写路径曾把回退
|
|
4078
|
+
* 视图的结果以当前版本号落库,所以**版本号不可信**,读之前要按内容判一次。 */
|
|
4079
|
+
declare function needsShapeAdoption(events: readonly SessionEvent[]): boolean;
|
|
4080
|
+
declare function repairReadView(events: SessionEvent[]): void;
|
|
4081
|
+
declare function orphanInboxSpliceSeqs(events: readonly SessionEvent[]): Set<number>;
|
|
4082
|
+
declare function repairOrphanInboxSplices(events: SessionEvent[]): void;
|
|
4083
|
+
declare function scanRows(rows: readonly EventRow[], base?: number): {
|
|
4084
|
+
preserved: SessionEvent[];
|
|
4085
|
+
tornFrom?: number;
|
|
4086
|
+
};
|
|
4087
|
+
declare function toJsonlArtifact(meta: SessionHeader, inheritedEventCount: number, events: readonly SessionEvent[]): string;
|
|
4088
|
+
declare function titleOfEventData(data: string): string | undefined;
|
|
4089
|
+
/** 用量行的列(`t_event_usage`):读侧维度(本地日与两个归属标记)在写入时一起物化。 */
|
|
4090
|
+
interface EventUsageRow {
|
|
4091
|
+
fEventId: string;
|
|
4092
|
+
fCreatedAt: number;
|
|
4093
|
+
fDay: string;
|
|
4094
|
+
fProvider: string | null;
|
|
4095
|
+
fModel: string | null;
|
|
4096
|
+
fReferenced: number;
|
|
4097
|
+
fSubagent: number;
|
|
4098
|
+
fInputTokens: number;
|
|
4099
|
+
fOutputTokens: number;
|
|
4100
|
+
fCacheReadTokens: number;
|
|
4101
|
+
fReasoningTokens: number;
|
|
4102
|
+
fTotalTokens: number;
|
|
4103
|
+
}
|
|
4104
|
+
/**
|
|
4105
|
+
* 一条事件行的用量(只有带 `usage` 的 `assistant/message` 才有):写路径据此记录
|
|
4106
|
+
* `t_event_usage`,统计因此不必逐行解析 JSON。两种 `f_data` 结构(带信封 / 老格式)都认。
|
|
4107
|
+
* 读侧维度一起物化:本地日由事件时间算,`f_referenced` 直接 1(这一批事件行与桥接行同事务,
|
|
4108
|
+
* 提交即被引用),`f_subagent` 取写入它的会话是否子代理。
|
|
4109
|
+
* @param event - 待写入的事件行。
|
|
4110
|
+
* @param subagent - 写入它的会话是否 `origin === 'subagent'`。
|
|
4111
|
+
* @returns 用量行,或该事件没有用量时的 undefined。
|
|
4112
|
+
*/
|
|
4113
|
+
declare function usageRowOf(event: {
|
|
4114
|
+
fEventId: string;
|
|
4115
|
+
fCreatedAt: number;
|
|
4116
|
+
fType: string;
|
|
4117
|
+
fData: string;
|
|
4118
|
+
}, subagent: boolean): EventUsageRow | undefined;
|
|
4119
|
+
//#endregion
|
|
4120
|
+
export { eventDimensions as $, SessionRow as A, SessionBranchRdbProvider as B, usageRowOf as C, SessionCountBucket as D, EventRow as E, SessionDeletionError as F, SessionRowsValue as G, truncateLiveSession as H, SessionDeletionErrorCode as I, EventKind as J, DEFAULT_BUSY_TIMEOUT_MS as K, SessionPersistenceRdb as L, UsageAggregate as M, Config$1 as N, SessionListRowsPage as O, ProjectionCacheOptions as P, SESSION_PERSISTENCE_SQLITE_APPLICATION_ID as Q, SessionPersistenceRdbInternals as R, toJsonlArtifact as S, BackendTx as T, SESSION_ROWS_PATH as U, locateTurnEnd as V, SessionRowsItem as W, JournalMode as X, EventRole as Y, SCHEMA_VERSION as Z, sealOwnEvents as _, normalizeToCurrentShape as a, tSessionCounts as at, syncMeteringRanges as b, renameLegacyPtcEvents as c, tSessionUsage as ct, repairReadView as d, tWorkspaceSessions as dt, eventKind as et, repairRequestHeaders as f, tWorkspaceState as ft, scanRows as g, rowToMeta as h, StorageRepository as ht, needsShapeAdoption as i, tSchemaMeta as it, SessionUsageBucket as j, SessionListRowsQuery as k, repairAssistantSettlement as l, tSessions as lt, rowToEvent as m, WriteGuard as mt, OWN_EVENT_TYPES as n, tEvents as nt, orphanInboxSpliceSeqs as o, tSessionEvents as ot, repairSurfaceOps as p, tWorkspaces as pt, EVENT_ENCODING as q, findSurfaceRepairs as r, tPersistenceState as rt, recomputeReplaceProvenance as s, tSessionProjcacheRows as st, EventUsageRow as t, tEventUsage as tt, repairOrphanInboxSplices as u, tStorageUnits as ut, sessionConflictRow as v, Backend as w, titleOfEventData as x, sessionInsertRow as y, SessionBranchRdb as z };
|