ds4-context-core 0.1.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/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/artifacts/artifact-manager.d.ts +58 -0
- package/dist/artifacts/artifact-manager.d.ts.map +1 -0
- package/dist/artifacts/artifact-manager.js +445 -0
- package/dist/artifacts/artifact-manager.js.map +1 -0
- package/dist/artifacts/artifact-store.d.ts +33 -0
- package/dist/artifacts/artifact-store.d.ts.map +1 -0
- package/dist/artifacts/artifact-store.js +116 -0
- package/dist/artifacts/artifact-store.js.map +1 -0
- package/dist/compaction/compaction-record.d.ts +74 -0
- package/dist/compaction/compaction-record.d.ts.map +1 -0
- package/dist/compaction/compaction-record.js +113 -0
- package/dist/compaction/compaction-record.js.map +1 -0
- package/dist/compaction/summary-contract.d.ts +68 -0
- package/dist/compaction/summary-contract.d.ts.map +1 -0
- package/dist/compaction/summary-contract.js +315 -0
- package/dist/compaction/summary-contract.js.map +1 -0
- package/dist/compaction/summary-graph.d.ts +48 -0
- package/dist/compaction/summary-graph.d.ts.map +1 -0
- package/dist/compaction/summary-graph.js +123 -0
- package/dist/compaction/summary-graph.js.map +1 -0
- package/dist/config/config-loader.d.ts +18 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +305 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/config.d.ts +113 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +89 -0
- package/dist/config/config.js.map +1 -0
- package/dist/continuation/native-continuation.d.ts +107 -0
- package/dist/continuation/native-continuation.d.ts.map +1 -0
- package/dist/continuation/native-continuation.js +374 -0
- package/dist/continuation/native-continuation.js.map +1 -0
- package/dist/core/budget-manager.d.ts +26 -0
- package/dist/core/budget-manager.d.ts.map +1 -0
- package/dist/core/budget-manager.js +42 -0
- package/dist/core/budget-manager.js.map +1 -0
- package/dist/core/canonical-message.d.ts +69 -0
- package/dist/core/canonical-message.d.ts.map +1 -0
- package/dist/core/canonical-message.js +2 -0
- package/dist/core/canonical-message.js.map +1 -0
- package/dist/core/model-awareness.d.ts +59 -0
- package/dist/core/model-awareness.d.ts.map +1 -0
- package/dist/core/model-awareness.js +177 -0
- package/dist/core/model-awareness.js.map +1 -0
- package/dist/core/model-profile.d.ts +27 -0
- package/dist/core/model-profile.d.ts.map +1 -0
- package/dist/core/model-profile.js +29 -0
- package/dist/core/model-profile.js.map +1 -0
- package/dist/core/token-estimator.d.ts +4 -0
- package/dist/core/token-estimator.d.ts.map +1 -0
- package/dist/core/token-estimator.js +64 -0
- package/dist/core/token-estimator.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest/context-manifest.d.ts +163 -0
- package/dist/manifest/context-manifest.d.ts.map +1 -0
- package/dist/manifest/context-manifest.js +2 -0
- package/dist/manifest/context-manifest.js.map +1 -0
- package/dist/manifest/observer.d.ts +63 -0
- package/dist/manifest/observer.d.ts.map +1 -0
- package/dist/manifest/observer.js +150 -0
- package/dist/manifest/observer.js.map +1 -0
- package/dist/memory/memory-manager.d.ts +112 -0
- package/dist/memory/memory-manager.d.ts.map +1 -0
- package/dist/memory/memory-manager.js +499 -0
- package/dist/memory/memory-manager.js.map +1 -0
- package/dist/memory/memory-types.d.ts +126 -0
- package/dist/memory/memory-types.d.ts.map +1 -0
- package/dist/memory/memory-types.js +73 -0
- package/dist/memory/memory-types.js.map +1 -0
- package/dist/persistence/migrations.d.ts +17 -0
- package/dist/persistence/migrations.d.ts.map +1 -0
- package/dist/persistence/migrations.js +588 -0
- package/dist/persistence/migrations.js.map +1 -0
- package/dist/persistence/repositories/artifact-repository.d.ts +50 -0
- package/dist/persistence/repositories/artifact-repository.d.ts.map +1 -0
- package/dist/persistence/repositories/artifact-repository.js +186 -0
- package/dist/persistence/repositories/artifact-repository.js.map +1 -0
- package/dist/persistence/repositories/context-manifest-repository.d.ts +19 -0
- package/dist/persistence/repositories/context-manifest-repository.d.ts.map +1 -0
- package/dist/persistence/repositories/context-manifest-repository.js +144 -0
- package/dist/persistence/repositories/context-manifest-repository.js.map +1 -0
- package/dist/persistence/repositories/memory-repository.d.ts +33 -0
- package/dist/persistence/repositories/memory-repository.d.ts.map +1 -0
- package/dist/persistence/repositories/memory-repository.js +429 -0
- package/dist/persistence/repositories/memory-repository.js.map +1 -0
- package/dist/persistence/repositories/project-knowledge-repository.d.ts +65 -0
- package/dist/persistence/repositories/project-knowledge-repository.d.ts.map +1 -0
- package/dist/persistence/repositories/project-knowledge-repository.js +248 -0
- package/dist/persistence/repositories/project-knowledge-repository.js.map +1 -0
- package/dist/persistence/repositories/session-index-repository.d.ts +81 -0
- package/dist/persistence/repositories/session-index-repository.d.ts.map +1 -0
- package/dist/persistence/repositories/session-index-repository.js +220 -0
- package/dist/persistence/repositories/session-index-repository.js.map +1 -0
- package/dist/persistence/repositories/summary-repository.d.ts +16 -0
- package/dist/persistence/repositories/summary-repository.d.ts.map +1 -0
- package/dist/persistence/repositories/summary-repository.js +242 -0
- package/dist/persistence/repositories/summary-repository.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +45 -0
- package/dist/persistence/sqlite.d.ts.map +1 -0
- package/dist/persistence/sqlite.js +137 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/planner/atomic-groups.d.ts +15 -0
- package/dist/planner/atomic-groups.d.ts.map +1 -0
- package/dist/planner/atomic-groups.js +177 -0
- package/dist/planner/atomic-groups.js.map +1 -0
- package/dist/planner/context-planner.d.ts +49 -0
- package/dist/planner/context-planner.d.ts.map +1 -0
- package/dist/planner/context-planner.js +367 -0
- package/dist/planner/context-planner.js.map +1 -0
- package/dist/privacy/privacy-policy.d.ts +58 -0
- package/dist/privacy/privacy-policy.d.ts.map +1 -0
- package/dist/privacy/privacy-policy.js +412 -0
- package/dist/privacy/privacy-policy.js.map +1 -0
- package/dist/project/file-indexer.d.ts +32 -0
- package/dist/project/file-indexer.d.ts.map +1 -0
- package/dist/project/file-indexer.js +374 -0
- package/dist/project/file-indexer.js.map +1 -0
- package/dist/project/git-state.d.ts +12 -0
- package/dist/project/git-state.d.ts.map +1 -0
- package/dist/project/git-state.js +109 -0
- package/dist/project/git-state.js.map +1 -0
- package/dist/project/project-knowledge.d.ts +63 -0
- package/dist/project/project-knowledge.d.ts.map +1 -0
- package/dist/project/project-knowledge.js +332 -0
- package/dist/project/project-knowledge.js.map +1 -0
- package/dist/retrieval/retrieval-engine.d.ts +55 -0
- package/dist/retrieval/retrieval-engine.d.ts.map +1 -0
- package/dist/retrieval/retrieval-engine.js +290 -0
- package/dist/retrieval/retrieval-engine.js.map +1 -0
- package/dist/retrieval/task-descriptor.d.ts +17 -0
- package/dist/retrieval/task-descriptor.d.ts.map +1 -0
- package/dist/retrieval/task-descriptor.js +107 -0
- package/dist/retrieval/task-descriptor.js.map +1 -0
- package/dist/shared/hash.d.ts +2 -0
- package/dist/shared/hash.d.ts.map +1 -0
- package/dist/shared/hash.js +5 -0
- package/dist/shared/hash.js.map +1 -0
- package/dist/shared/logging.d.ts +27 -0
- package/dist/shared/logging.d.ts.map +1 -0
- package/dist/shared/logging.js +83 -0
- package/dist/shared/logging.js.map +1 -0
- package/dist/shared/stable-json.d.ts +2 -0
- package/dist/shared/stable-json.d.ts.map +1 -0
- package/dist/shared/stable-json.js +38 -0
- package/dist/shared/stable-json.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { isPrivacyClassification } from "../privacy/privacy-policy.js";
|
|
2
|
+
export const MEMORY_CUSTOM_ENTRY_TYPE = "ds4-context-memory-v1";
|
|
3
|
+
export const PIN_CUSTOM_ENTRY_TYPE = "ds4-context-pin-v1";
|
|
4
|
+
export const MEMORY_MUTATION_SCHEMA_VERSION = 1;
|
|
5
|
+
function isRecord(value) {
|
|
6
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
function validBase(value) {
|
|
9
|
+
return value.schemaVersion === MEMORY_MUTATION_SCHEMA_VERSION
|
|
10
|
+
&& typeof value.mutationId === "string"
|
|
11
|
+
&& value.mutationId.length > 0
|
|
12
|
+
&& typeof value.createdAt === "number"
|
|
13
|
+
&& Number.isFinite(value.createdAt);
|
|
14
|
+
}
|
|
15
|
+
function validNewMemory(value) {
|
|
16
|
+
if (!isRecord(value))
|
|
17
|
+
return false;
|
|
18
|
+
return typeof value.id === "string"
|
|
19
|
+
&& (value.scope === "session" || value.scope === "project")
|
|
20
|
+
&& typeof value.claim === "string"
|
|
21
|
+
&& typeof value.createdAt === "number"
|
|
22
|
+
&& Array.isArray(value.sourceEntryIds)
|
|
23
|
+
&& value.sourceEntryIds.every((entryId) => typeof entryId === "string")
|
|
24
|
+
&& (value.projectPath === undefined || typeof value.projectPath === "string")
|
|
25
|
+
&& (value.key === undefined || typeof value.key === "string")
|
|
26
|
+
&& (value.classification === undefined || isPrivacyClassification(value.classification));
|
|
27
|
+
}
|
|
28
|
+
function validNewPin(value) {
|
|
29
|
+
if (!isRecord(value))
|
|
30
|
+
return false;
|
|
31
|
+
return typeof value.id === "string"
|
|
32
|
+
&& (value.scope === "session" || value.scope === "branch" || value.scope === "project")
|
|
33
|
+
&& typeof value.content === "string"
|
|
34
|
+
&& typeof value.createdAt === "number"
|
|
35
|
+
&& (value.projectPath === undefined || typeof value.projectPath === "string")
|
|
36
|
+
&& (value.branchLeafId === undefined || typeof value.branchLeafId === "string")
|
|
37
|
+
&& (value.classification === undefined || isPrivacyClassification(value.classification))
|
|
38
|
+
&& (value.sourceEntryId === undefined || typeof value.sourceEntryId === "string")
|
|
39
|
+
&& (value.sourceFile === undefined || typeof value.sourceFile === "string");
|
|
40
|
+
}
|
|
41
|
+
export function parseMemoryMutation(value) {
|
|
42
|
+
if (!isRecord(value) || !validBase(value))
|
|
43
|
+
return undefined;
|
|
44
|
+
if (value.operation === "add" && validNewMemory(value.item))
|
|
45
|
+
return value;
|
|
46
|
+
if (value.operation === "supersede" && typeof value.previousId === "string" && validNewMemory(value.item)) {
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
if (value.operation === "status"
|
|
50
|
+
&& typeof value.memoryId === "string"
|
|
51
|
+
&& (value.status === "invalid" || value.status === "expired")
|
|
52
|
+
&& (value.reason === undefined || typeof value.reason === "string")) {
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
export function parsePinMutation(value) {
|
|
58
|
+
if (!isRecord(value) || !validBase(value))
|
|
59
|
+
return undefined;
|
|
60
|
+
if (value.operation === "add" && validNewPin(value.item))
|
|
61
|
+
return value;
|
|
62
|
+
if (value.operation === "supersede" && typeof value.previousId === "string" && validNewPin(value.item)) {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
if (value.operation === "status"
|
|
66
|
+
&& typeof value.pinId === "string"
|
|
67
|
+
&& value.status === "deleted"
|
|
68
|
+
&& (value.reason === undefined || typeof value.reason === "string")) {
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=memory-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-types.js","sourceRoot":"","sources":["../../src/memory/memory-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
2
|
+
export interface Migration {
|
|
3
|
+
version: number;
|
|
4
|
+
name: string;
|
|
5
|
+
sql: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AppliedMigration {
|
|
8
|
+
version: number;
|
|
9
|
+
name: string;
|
|
10
|
+
checksum: string;
|
|
11
|
+
appliedAt: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const MIGRATIONS: readonly Migration[];
|
|
14
|
+
export declare const CURRENT_SCHEMA_VERSION: number;
|
|
15
|
+
export declare function listAppliedMigrations(database: DatabaseSync): AppliedMigration[];
|
|
16
|
+
export declare function applyMigrations(database: DatabaseSync, now?: number): AppliedMigration[];
|
|
17
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/persistence/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAohB1C,CAAC;AAEF,eAAO,MAAM,sBAAsB,QAAkC,CAAC;AAatE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAWhF;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,SAAa,GAAG,gBAAgB,EAAE,CAyC5F"}
|
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
import { sha256 } from "../shared/hash.js";
|
|
2
|
+
export const MIGRATIONS = [
|
|
3
|
+
{
|
|
4
|
+
version: 1,
|
|
5
|
+
name: "initial-derived-store",
|
|
6
|
+
sql: `
|
|
7
|
+
CREATE TABLE sessions (
|
|
8
|
+
session_id TEXT PRIMARY KEY,
|
|
9
|
+
session_file TEXT NOT NULL,
|
|
10
|
+
project_path TEXT,
|
|
11
|
+
indexed_at INTEGER NOT NULL
|
|
12
|
+
) STRICT;
|
|
13
|
+
|
|
14
|
+
CREATE TABLE entries (
|
|
15
|
+
entry_id TEXT PRIMARY KEY,
|
|
16
|
+
session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
17
|
+
parent_id TEXT,
|
|
18
|
+
entry_type TEXT NOT NULL,
|
|
19
|
+
role TEXT,
|
|
20
|
+
created_at INTEGER,
|
|
21
|
+
content_hash TEXT NOT NULL,
|
|
22
|
+
searchable_text TEXT,
|
|
23
|
+
token_estimate INTEGER,
|
|
24
|
+
indexed_at INTEGER NOT NULL
|
|
25
|
+
) STRICT;
|
|
26
|
+
CREATE INDEX entries_session_parent_idx ON entries(session_id, parent_id);
|
|
27
|
+
CREATE INDEX entries_session_created_idx ON entries(session_id, created_at);
|
|
28
|
+
CREATE INDEX entries_content_hash_idx ON entries(content_hash);
|
|
29
|
+
|
|
30
|
+
CREATE VIRTUAL TABLE entries_fts USING fts5(
|
|
31
|
+
searchable_text,
|
|
32
|
+
entry_id UNINDEXED,
|
|
33
|
+
session_id UNINDEXED,
|
|
34
|
+
tokenize = 'unicode61 remove_diacritics 2'
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE TABLE summaries (
|
|
38
|
+
summary_id TEXT PRIMARY KEY,
|
|
39
|
+
session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
40
|
+
summary_kind TEXT NOT NULL,
|
|
41
|
+
content TEXT NOT NULL,
|
|
42
|
+
source_hash TEXT NOT NULL,
|
|
43
|
+
created_at INTEGER NOT NULL,
|
|
44
|
+
validation_status TEXT NOT NULL,
|
|
45
|
+
provider TEXT,
|
|
46
|
+
model TEXT
|
|
47
|
+
) STRICT;
|
|
48
|
+
CREATE INDEX summaries_session_created_idx ON summaries(session_id, created_at);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE summary_sources (
|
|
51
|
+
summary_id TEXT NOT NULL REFERENCES summaries(summary_id) ON DELETE CASCADE,
|
|
52
|
+
entry_id TEXT NOT NULL REFERENCES entries(entry_id) ON DELETE CASCADE,
|
|
53
|
+
PRIMARY KEY(summary_id, entry_id)
|
|
54
|
+
) WITHOUT ROWID, STRICT;
|
|
55
|
+
|
|
56
|
+
CREATE TABLE summary_edges (
|
|
57
|
+
parent_summary_id TEXT NOT NULL REFERENCES summaries(summary_id) ON DELETE CASCADE,
|
|
58
|
+
child_summary_id TEXT NOT NULL REFERENCES summaries(summary_id) ON DELETE CASCADE,
|
|
59
|
+
PRIMARY KEY(parent_summary_id, child_summary_id),
|
|
60
|
+
CHECK(parent_summary_id <> child_summary_id)
|
|
61
|
+
) WITHOUT ROWID, STRICT;
|
|
62
|
+
|
|
63
|
+
CREATE TABLE memory_items (
|
|
64
|
+
memory_id TEXT PRIMARY KEY,
|
|
65
|
+
scope TEXT NOT NULL,
|
|
66
|
+
session_id TEXT REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
67
|
+
project_path TEXT,
|
|
68
|
+
claim TEXT NOT NULL,
|
|
69
|
+
status TEXT NOT NULL,
|
|
70
|
+
created_at INTEGER NOT NULL,
|
|
71
|
+
superseded_by TEXT REFERENCES memory_items(memory_id),
|
|
72
|
+
CHECK(scope IN ('session', 'project')),
|
|
73
|
+
CHECK(status IN ('active', 'superseded', 'invalid', 'expired'))
|
|
74
|
+
) STRICT;
|
|
75
|
+
|
|
76
|
+
CREATE TABLE memory_sources (
|
|
77
|
+
memory_id TEXT NOT NULL REFERENCES memory_items(memory_id) ON DELETE CASCADE,
|
|
78
|
+
entry_id TEXT NOT NULL REFERENCES entries(entry_id) ON DELETE CASCADE,
|
|
79
|
+
PRIMARY KEY(memory_id, entry_id)
|
|
80
|
+
) WITHOUT ROWID, STRICT;
|
|
81
|
+
|
|
82
|
+
CREATE VIRTUAL TABLE memory_fts USING fts5(
|
|
83
|
+
claim,
|
|
84
|
+
memory_id UNINDEXED,
|
|
85
|
+
tokenize = 'unicode61 remove_diacritics 2'
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
CREATE TABLE pins (
|
|
89
|
+
pin_id TEXT PRIMARY KEY,
|
|
90
|
+
scope TEXT NOT NULL,
|
|
91
|
+
session_id TEXT REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
92
|
+
project_path TEXT,
|
|
93
|
+
content TEXT NOT NULL,
|
|
94
|
+
source_entry_id TEXT REFERENCES entries(entry_id) ON DELETE SET NULL,
|
|
95
|
+
source_file TEXT,
|
|
96
|
+
status TEXT NOT NULL,
|
|
97
|
+
created_at INTEGER NOT NULL,
|
|
98
|
+
CHECK(scope IN ('session', 'branch', 'project')),
|
|
99
|
+
CHECK(status IN ('active', 'superseded', 'deleted'))
|
|
100
|
+
) STRICT;
|
|
101
|
+
|
|
102
|
+
CREATE TABLE context_manifests (
|
|
103
|
+
manifest_id TEXT PRIMARY KEY,
|
|
104
|
+
session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
105
|
+
created_at INTEGER NOT NULL,
|
|
106
|
+
provider TEXT NOT NULL,
|
|
107
|
+
model TEXT NOT NULL,
|
|
108
|
+
estimated_tokens INTEGER,
|
|
109
|
+
actual_tokens INTEGER,
|
|
110
|
+
prompt_hash TEXT,
|
|
111
|
+
policy_version TEXT NOT NULL,
|
|
112
|
+
planner_version TEXT NOT NULL,
|
|
113
|
+
manifest_json TEXT NOT NULL
|
|
114
|
+
) STRICT;
|
|
115
|
+
CREATE INDEX context_manifests_session_created_idx
|
|
116
|
+
ON context_manifests(session_id, created_at DESC);
|
|
117
|
+
|
|
118
|
+
CREATE TABLE artifacts (
|
|
119
|
+
artifact_id TEXT PRIMARY KEY,
|
|
120
|
+
sha256 TEXT NOT NULL UNIQUE,
|
|
121
|
+
file_path TEXT NOT NULL,
|
|
122
|
+
mime_type TEXT,
|
|
123
|
+
size_bytes INTEGER NOT NULL,
|
|
124
|
+
created_at INTEGER NOT NULL,
|
|
125
|
+
source_entry_id TEXT REFERENCES entries(entry_id) ON DELETE SET NULL
|
|
126
|
+
) STRICT;
|
|
127
|
+
|
|
128
|
+
CREATE TABLE token_calibration (
|
|
129
|
+
calibration_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
130
|
+
provider TEXT NOT NULL,
|
|
131
|
+
model TEXT NOT NULL,
|
|
132
|
+
estimated INTEGER NOT NULL,
|
|
133
|
+
actual INTEGER NOT NULL,
|
|
134
|
+
ratio REAL NOT NULL,
|
|
135
|
+
created_at INTEGER NOT NULL
|
|
136
|
+
) STRICT;
|
|
137
|
+
CREATE INDEX token_calibration_model_created_idx
|
|
138
|
+
ON token_calibration(provider, model, created_at DESC);
|
|
139
|
+
`,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
version: 2,
|
|
143
|
+
name: "session-index-checkpoints-and-scoped-entry-keys",
|
|
144
|
+
sql: `
|
|
145
|
+
CREATE TABLE entries_v2 (
|
|
146
|
+
entry_key TEXT PRIMARY KEY,
|
|
147
|
+
entry_id TEXT NOT NULL,
|
|
148
|
+
session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
149
|
+
parent_id TEXT,
|
|
150
|
+
entry_type TEXT NOT NULL,
|
|
151
|
+
role TEXT,
|
|
152
|
+
created_at INTEGER,
|
|
153
|
+
content_hash TEXT NOT NULL,
|
|
154
|
+
searchable_text TEXT,
|
|
155
|
+
token_estimate INTEGER,
|
|
156
|
+
indexed_at INTEGER NOT NULL,
|
|
157
|
+
UNIQUE(session_id, entry_id)
|
|
158
|
+
) STRICT;
|
|
159
|
+
INSERT INTO entries_v2(
|
|
160
|
+
entry_key, entry_id, session_id, parent_id, entry_type, role,
|
|
161
|
+
created_at, content_hash, searchable_text, token_estimate, indexed_at
|
|
162
|
+
)
|
|
163
|
+
SELECT
|
|
164
|
+
session_id || ':' || entry_id, entry_id, session_id, parent_id, entry_type, role,
|
|
165
|
+
created_at, content_hash, searchable_text, token_estimate, indexed_at
|
|
166
|
+
FROM entries;
|
|
167
|
+
|
|
168
|
+
CREATE TABLE summary_sources_v2 (
|
|
169
|
+
summary_id TEXT NOT NULL REFERENCES summaries(summary_id) ON DELETE CASCADE,
|
|
170
|
+
entry_key TEXT NOT NULL REFERENCES entries_v2(entry_key) ON DELETE CASCADE,
|
|
171
|
+
PRIMARY KEY(summary_id, entry_key)
|
|
172
|
+
) WITHOUT ROWID, STRICT;
|
|
173
|
+
INSERT INTO summary_sources_v2(summary_id, entry_key)
|
|
174
|
+
SELECT source.summary_id, entry.session_id || ':' || source.entry_id
|
|
175
|
+
FROM summary_sources AS source
|
|
176
|
+
JOIN entries AS entry ON entry.entry_id = source.entry_id;
|
|
177
|
+
|
|
178
|
+
CREATE TABLE memory_sources_v2 (
|
|
179
|
+
memory_id TEXT NOT NULL REFERENCES memory_items(memory_id) ON DELETE CASCADE,
|
|
180
|
+
entry_key TEXT NOT NULL REFERENCES entries_v2(entry_key) ON DELETE CASCADE,
|
|
181
|
+
PRIMARY KEY(memory_id, entry_key)
|
|
182
|
+
) WITHOUT ROWID, STRICT;
|
|
183
|
+
INSERT INTO memory_sources_v2(memory_id, entry_key)
|
|
184
|
+
SELECT source.memory_id, entry.session_id || ':' || source.entry_id
|
|
185
|
+
FROM memory_sources AS source
|
|
186
|
+
JOIN entries AS entry ON entry.entry_id = source.entry_id;
|
|
187
|
+
|
|
188
|
+
CREATE TABLE pins_v2 (
|
|
189
|
+
pin_id TEXT PRIMARY KEY,
|
|
190
|
+
scope TEXT NOT NULL,
|
|
191
|
+
session_id TEXT REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
192
|
+
project_path TEXT,
|
|
193
|
+
content TEXT NOT NULL,
|
|
194
|
+
source_entry_key TEXT REFERENCES entries_v2(entry_key) ON DELETE SET NULL,
|
|
195
|
+
source_entry_id TEXT,
|
|
196
|
+
source_file TEXT,
|
|
197
|
+
status TEXT NOT NULL,
|
|
198
|
+
created_at INTEGER NOT NULL,
|
|
199
|
+
CHECK(scope IN ('session', 'branch', 'project')),
|
|
200
|
+
CHECK(status IN ('active', 'superseded', 'deleted'))
|
|
201
|
+
) STRICT;
|
|
202
|
+
INSERT INTO pins_v2(
|
|
203
|
+
pin_id, scope, session_id, project_path, content, source_entry_key,
|
|
204
|
+
source_entry_id, source_file, status, created_at
|
|
205
|
+
)
|
|
206
|
+
SELECT
|
|
207
|
+
pin.pin_id, pin.scope, pin.session_id, pin.project_path, pin.content,
|
|
208
|
+
(SELECT entry.session_id || ':' || entry.entry_id FROM entries AS entry
|
|
209
|
+
WHERE entry.entry_id = pin.source_entry_id LIMIT 1),
|
|
210
|
+
pin.source_entry_id, pin.source_file, pin.status, pin.created_at
|
|
211
|
+
FROM pins AS pin;
|
|
212
|
+
|
|
213
|
+
CREATE TABLE artifacts_v2 (
|
|
214
|
+
artifact_id TEXT PRIMARY KEY,
|
|
215
|
+
sha256 TEXT NOT NULL UNIQUE,
|
|
216
|
+
file_path TEXT NOT NULL,
|
|
217
|
+
mime_type TEXT,
|
|
218
|
+
size_bytes INTEGER NOT NULL,
|
|
219
|
+
created_at INTEGER NOT NULL,
|
|
220
|
+
source_entry_key TEXT REFERENCES entries_v2(entry_key) ON DELETE SET NULL,
|
|
221
|
+
source_entry_id TEXT
|
|
222
|
+
) STRICT;
|
|
223
|
+
INSERT INTO artifacts_v2(
|
|
224
|
+
artifact_id, sha256, file_path, mime_type, size_bytes, created_at,
|
|
225
|
+
source_entry_key, source_entry_id
|
|
226
|
+
)
|
|
227
|
+
SELECT
|
|
228
|
+
artifact.artifact_id, artifact.sha256, artifact.file_path, artifact.mime_type,
|
|
229
|
+
artifact.size_bytes, artifact.created_at,
|
|
230
|
+
(SELECT entry.session_id || ':' || entry.entry_id FROM entries AS entry
|
|
231
|
+
WHERE entry.entry_id = artifact.source_entry_id LIMIT 1),
|
|
232
|
+
artifact.source_entry_id
|
|
233
|
+
FROM artifacts AS artifact;
|
|
234
|
+
|
|
235
|
+
DROP TABLE summary_sources;
|
|
236
|
+
DROP TABLE memory_sources;
|
|
237
|
+
DROP TABLE pins;
|
|
238
|
+
DROP TABLE artifacts;
|
|
239
|
+
DROP TABLE entries_fts;
|
|
240
|
+
DROP TABLE entries;
|
|
241
|
+
|
|
242
|
+
ALTER TABLE entries_v2 RENAME TO entries;
|
|
243
|
+
ALTER TABLE summary_sources_v2 RENAME TO summary_sources;
|
|
244
|
+
ALTER TABLE memory_sources_v2 RENAME TO memory_sources;
|
|
245
|
+
ALTER TABLE pins_v2 RENAME TO pins;
|
|
246
|
+
ALTER TABLE artifacts_v2 RENAME TO artifacts;
|
|
247
|
+
|
|
248
|
+
CREATE INDEX entries_session_parent_idx ON entries(session_id, parent_id);
|
|
249
|
+
CREATE INDEX entries_session_created_idx ON entries(session_id, created_at);
|
|
250
|
+
CREATE INDEX entries_content_hash_idx ON entries(content_hash);
|
|
251
|
+
CREATE VIRTUAL TABLE entries_fts USING fts5(
|
|
252
|
+
searchable_text,
|
|
253
|
+
entry_key UNINDEXED,
|
|
254
|
+
entry_id UNINDEXED,
|
|
255
|
+
session_id UNINDEXED,
|
|
256
|
+
tokenize = 'unicode61 remove_diacritics 2'
|
|
257
|
+
);
|
|
258
|
+
INSERT INTO entries_fts(searchable_text, entry_key, entry_id, session_id)
|
|
259
|
+
SELECT COALESCE(searchable_text, ''), entry_key, entry_id, session_id FROM entries;
|
|
260
|
+
|
|
261
|
+
CREATE TABLE session_index_state (
|
|
262
|
+
session_id TEXT PRIMARY KEY REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
263
|
+
session_file TEXT NOT NULL,
|
|
264
|
+
header_hash TEXT NOT NULL,
|
|
265
|
+
file_size INTEGER NOT NULL,
|
|
266
|
+
file_mtime_ms REAL NOT NULL,
|
|
267
|
+
checkpoint_offset INTEGER NOT NULL,
|
|
268
|
+
checkpoint_line_start INTEGER NOT NULL,
|
|
269
|
+
checkpoint_hash TEXT,
|
|
270
|
+
indexed_entries INTEGER NOT NULL,
|
|
271
|
+
malformed_lines INTEGER NOT NULL,
|
|
272
|
+
indexed_at INTEGER NOT NULL
|
|
273
|
+
) STRICT;
|
|
274
|
+
`,
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
version: 3,
|
|
278
|
+
name: "bounded-checkpoint-fingerprint",
|
|
279
|
+
sql: `
|
|
280
|
+
ALTER TABLE session_index_state
|
|
281
|
+
RENAME COLUMN checkpoint_line_start TO checkpoint_hash_start;
|
|
282
|
+
`,
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
version: 4,
|
|
286
|
+
name: "observer-context-manifest-columns",
|
|
287
|
+
sql: `
|
|
288
|
+
ALTER TABLE context_manifests ADD COLUMN branch_leaf_id TEXT;
|
|
289
|
+
ALTER TABLE context_manifests ADD COLUMN context_window INTEGER;
|
|
290
|
+
ALTER TABLE context_manifests ADD COLUMN output_reserve INTEGER;
|
|
291
|
+
ALTER TABLE context_manifests ADD COLUMN hard_input_limit INTEGER;
|
|
292
|
+
ALTER TABLE context_manifests ADD COLUMN target_input_tokens INTEGER;
|
|
293
|
+
ALTER TABLE context_manifests ADD COLUMN pi_reported_tokens INTEGER;
|
|
294
|
+
CREATE INDEX context_manifests_prompt_hash_idx
|
|
295
|
+
ON context_manifests(prompt_hash);
|
|
296
|
+
`,
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
version: 5,
|
|
300
|
+
name: "compaction-summary-lifecycle",
|
|
301
|
+
sql: `
|
|
302
|
+
ALTER TABLE summaries ADD COLUMN first_kept_entry_id TEXT;
|
|
303
|
+
ALTER TABLE summaries ADD COLUMN tokens_before INTEGER;
|
|
304
|
+
ALTER TABLE summaries ADD COLUMN compaction_reason TEXT;
|
|
305
|
+
ALTER TABLE summaries ADD COLUMN lifecycle_status TEXT NOT NULL DEFAULT 'committed'
|
|
306
|
+
CHECK(lifecycle_status IN ('prepared', 'committed', 'failed'));
|
|
307
|
+
ALTER TABLE summaries ADD COLUMN pi_compaction_entry_id TEXT;
|
|
308
|
+
ALTER TABLE summaries ADD COLUMN metadata_json TEXT NOT NULL DEFAULT '{}';
|
|
309
|
+
CREATE INDEX summaries_session_lifecycle_idx
|
|
310
|
+
ON summaries(session_id, lifecycle_status, created_at DESC);
|
|
311
|
+
CREATE UNIQUE INDEX summaries_pi_compaction_entry_idx
|
|
312
|
+
ON summaries(session_id, pi_compaction_entry_id)
|
|
313
|
+
WHERE pi_compaction_entry_id IS NOT NULL;
|
|
314
|
+
`,
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
version: 6,
|
|
318
|
+
name: "hierarchical-summary-graph",
|
|
319
|
+
sql: `
|
|
320
|
+
ALTER TABLE summaries ADD COLUMN graph_level INTEGER NOT NULL DEFAULT 0
|
|
321
|
+
CHECK(graph_level >= 0);
|
|
322
|
+
ALTER TABLE summary_edges ADD COLUMN child_order INTEGER NOT NULL DEFAULT 0
|
|
323
|
+
CHECK(child_order >= 0);
|
|
324
|
+
CREATE INDEX summaries_session_kind_level_idx
|
|
325
|
+
ON summaries(session_id, summary_kind, graph_level, created_at DESC);
|
|
326
|
+
CREATE INDEX summary_edges_child_idx
|
|
327
|
+
ON summary_edges(child_summary_id, parent_summary_id);
|
|
328
|
+
`,
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
version: 7,
|
|
332
|
+
name: "project-knowledge-index",
|
|
333
|
+
sql: `
|
|
334
|
+
CREATE TABLE project_states (
|
|
335
|
+
project_path TEXT PRIMARY KEY,
|
|
336
|
+
git_root TEXT,
|
|
337
|
+
git_branch TEXT,
|
|
338
|
+
git_head TEXT,
|
|
339
|
+
dirty INTEGER NOT NULL CHECK(dirty IN (0, 1)),
|
|
340
|
+
changed_files_json TEXT NOT NULL,
|
|
341
|
+
indexed_at INTEGER NOT NULL
|
|
342
|
+
) STRICT;
|
|
343
|
+
|
|
344
|
+
CREATE TABLE project_files (
|
|
345
|
+
project_path TEXT NOT NULL REFERENCES project_states(project_path) ON DELETE CASCADE,
|
|
346
|
+
file_path TEXT NOT NULL,
|
|
347
|
+
content_hash TEXT NOT NULL,
|
|
348
|
+
size_bytes INTEGER NOT NULL CHECK(size_bytes >= 0),
|
|
349
|
+
mtime_ms REAL NOT NULL,
|
|
350
|
+
language TEXT,
|
|
351
|
+
git_commit TEXT,
|
|
352
|
+
modified INTEGER NOT NULL CHECK(modified IN (0, 1)),
|
|
353
|
+
tracked INTEGER NOT NULL CHECK(tracked IN (0, 1)),
|
|
354
|
+
status TEXT NOT NULL CHECK(status IN ('current', 'deleted')),
|
|
355
|
+
indexed_at INTEGER NOT NULL,
|
|
356
|
+
PRIMARY KEY(project_path, file_path)
|
|
357
|
+
) WITHOUT ROWID, STRICT;
|
|
358
|
+
CREATE INDEX project_files_hash_idx ON project_files(project_path, content_hash);
|
|
359
|
+
CREATE INDEX project_files_status_idx ON project_files(project_path, status, file_path);
|
|
360
|
+
|
|
361
|
+
CREATE TABLE project_snippets (
|
|
362
|
+
snippet_id TEXT PRIMARY KEY,
|
|
363
|
+
project_path TEXT NOT NULL,
|
|
364
|
+
file_path TEXT NOT NULL,
|
|
365
|
+
file_hash TEXT NOT NULL,
|
|
366
|
+
start_line INTEGER NOT NULL CHECK(start_line > 0),
|
|
367
|
+
end_line INTEGER NOT NULL CHECK(end_line >= start_line),
|
|
368
|
+
content TEXT NOT NULL,
|
|
369
|
+
symbols TEXT NOT NULL,
|
|
370
|
+
token_estimate INTEGER NOT NULL CHECK(token_estimate >= 0),
|
|
371
|
+
stale INTEGER NOT NULL CHECK(stale IN (0, 1)),
|
|
372
|
+
indexed_at INTEGER NOT NULL,
|
|
373
|
+
FOREIGN KEY(project_path, file_path)
|
|
374
|
+
REFERENCES project_files(project_path, file_path) ON DELETE CASCADE
|
|
375
|
+
) STRICT;
|
|
376
|
+
CREATE INDEX project_snippets_file_idx
|
|
377
|
+
ON project_snippets(project_path, file_path, stale, start_line);
|
|
378
|
+
CREATE INDEX project_snippets_hash_idx
|
|
379
|
+
ON project_snippets(project_path, file_hash, stale);
|
|
380
|
+
|
|
381
|
+
CREATE VIRTUAL TABLE project_snippets_fts USING fts5(
|
|
382
|
+
content,
|
|
383
|
+
file_path,
|
|
384
|
+
symbols,
|
|
385
|
+
snippet_id UNINDEXED,
|
|
386
|
+
project_path UNINDEXED,
|
|
387
|
+
tokenize = 'unicode61 remove_diacritics 2'
|
|
388
|
+
);
|
|
389
|
+
`,
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
version: 8,
|
|
393
|
+
name: "content-addressed-artifact-store",
|
|
394
|
+
sql: `
|
|
395
|
+
CREATE TABLE artifact_objects (
|
|
396
|
+
sha256 TEXT PRIMARY KEY CHECK(length(sha256) = 64),
|
|
397
|
+
file_path TEXT NOT NULL UNIQUE,
|
|
398
|
+
mime_type TEXT NOT NULL,
|
|
399
|
+
size_bytes INTEGER NOT NULL CHECK(size_bytes >= 0),
|
|
400
|
+
created_at INTEGER NOT NULL,
|
|
401
|
+
last_verified_at INTEGER,
|
|
402
|
+
status TEXT NOT NULL CHECK(status IN ('available', 'missing', 'corrupt'))
|
|
403
|
+
) STRICT;
|
|
404
|
+
INSERT OR IGNORE INTO artifact_objects(
|
|
405
|
+
sha256, file_path, mime_type, size_bytes, created_at, status
|
|
406
|
+
)
|
|
407
|
+
SELECT sha256, file_path, COALESCE(mime_type, 'application/octet-stream'),
|
|
408
|
+
size_bytes, created_at, 'available'
|
|
409
|
+
FROM artifacts;
|
|
410
|
+
|
|
411
|
+
CREATE TABLE artifacts_v3 (
|
|
412
|
+
artifact_id TEXT PRIMARY KEY,
|
|
413
|
+
sha256 TEXT NOT NULL REFERENCES artifact_objects(sha256) ON DELETE RESTRICT,
|
|
414
|
+
source_session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
415
|
+
source_entry_key TEXT NOT NULL REFERENCES entries(entry_key) ON DELETE CASCADE,
|
|
416
|
+
source_entry_id TEXT NOT NULL,
|
|
417
|
+
source_tool_call_id TEXT NOT NULL,
|
|
418
|
+
source_tool_name TEXT NOT NULL,
|
|
419
|
+
is_error INTEGER NOT NULL CHECK(is_error IN (0, 1)),
|
|
420
|
+
original_chars INTEGER NOT NULL CHECK(original_chars >= 0),
|
|
421
|
+
original_tokens INTEGER NOT NULL CHECK(original_tokens >= 0),
|
|
422
|
+
condensed_chars INTEGER NOT NULL CHECK(condensed_chars >= 0),
|
|
423
|
+
condensed_tokens INTEGER NOT NULL CHECK(condensed_tokens >= 0),
|
|
424
|
+
created_at INTEGER NOT NULL,
|
|
425
|
+
metadata_json TEXT NOT NULL,
|
|
426
|
+
UNIQUE(source_session_id, source_entry_id, source_tool_call_id, sha256)
|
|
427
|
+
) STRICT;
|
|
428
|
+
INSERT OR IGNORE INTO artifacts_v3(
|
|
429
|
+
artifact_id, sha256, source_session_id, source_entry_key, source_entry_id,
|
|
430
|
+
source_tool_call_id, source_tool_name, is_error, original_chars,
|
|
431
|
+
original_tokens, condensed_chars, condensed_tokens, created_at, metadata_json
|
|
432
|
+
)
|
|
433
|
+
SELECT
|
|
434
|
+
artifact.artifact_id, artifact.sha256, entry.session_id,
|
|
435
|
+
artifact.source_entry_key, artifact.source_entry_id,
|
|
436
|
+
'legacy', 'unknown', 0, artifact.size_bytes, 0, 0, 0,
|
|
437
|
+
artifact.created_at, '{}'
|
|
438
|
+
FROM artifacts AS artifact
|
|
439
|
+
JOIN entries AS entry ON entry.entry_key = artifact.source_entry_key
|
|
440
|
+
WHERE artifact.source_entry_key IS NOT NULL AND artifact.source_entry_id IS NOT NULL;
|
|
441
|
+
|
|
442
|
+
DROP TABLE artifacts;
|
|
443
|
+
ALTER TABLE artifacts_v3 RENAME TO artifacts;
|
|
444
|
+
CREATE INDEX artifacts_session_created_idx
|
|
445
|
+
ON artifacts(source_session_id, created_at DESC);
|
|
446
|
+
CREATE INDEX artifacts_source_entry_idx
|
|
447
|
+
ON artifacts(source_session_id, source_entry_id);
|
|
448
|
+
CREATE INDEX artifacts_sha_idx ON artifacts(sha256);
|
|
449
|
+
`,
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
version: 9,
|
|
453
|
+
name: "event-sourced-memory-and-pins",
|
|
454
|
+
sql: `
|
|
455
|
+
ALTER TABLE memory_items ADD COLUMN memory_key TEXT;
|
|
456
|
+
ALTER TABLE memory_items ADD COLUMN origin_session_id TEXT
|
|
457
|
+
REFERENCES sessions(session_id) ON DELETE CASCADE;
|
|
458
|
+
ALTER TABLE memory_items ADD COLUMN updated_at INTEGER NOT NULL DEFAULT 0;
|
|
459
|
+
ALTER TABLE memory_items ADD COLUMN status_reason TEXT;
|
|
460
|
+
ALTER TABLE memory_items ADD COLUMN metadata_json TEXT NOT NULL DEFAULT '{}';
|
|
461
|
+
CREATE INDEX memory_items_scope_status_idx
|
|
462
|
+
ON memory_items(scope, session_id, project_path, status, created_at DESC);
|
|
463
|
+
CREATE UNIQUE INDEX memory_items_active_key_idx
|
|
464
|
+
ON memory_items(
|
|
465
|
+
scope,
|
|
466
|
+
COALESCE(session_id, ''),
|
|
467
|
+
COALESCE(project_path, ''),
|
|
468
|
+
memory_key
|
|
469
|
+
)
|
|
470
|
+
WHERE status = 'active' AND memory_key IS NOT NULL;
|
|
471
|
+
|
|
472
|
+
ALTER TABLE pins ADD COLUMN branch_leaf_id TEXT;
|
|
473
|
+
ALTER TABLE pins ADD COLUMN superseded_by TEXT REFERENCES pins(pin_id);
|
|
474
|
+
ALTER TABLE pins ADD COLUMN updated_at INTEGER NOT NULL DEFAULT 0;
|
|
475
|
+
ALTER TABLE pins ADD COLUMN status_reason TEXT;
|
|
476
|
+
ALTER TABLE pins ADD COLUMN metadata_json TEXT NOT NULL DEFAULT '{}';
|
|
477
|
+
CREATE INDEX pins_scope_status_idx
|
|
478
|
+
ON pins(scope, session_id, project_path, status, created_at DESC);
|
|
479
|
+
CREATE INDEX pins_branch_leaf_idx
|
|
480
|
+
ON pins(session_id, branch_leaf_id, status);
|
|
481
|
+
|
|
482
|
+
CREATE TABLE memory_mutations (
|
|
483
|
+
mutation_key TEXT PRIMARY KEY REFERENCES entries(entry_key) ON DELETE CASCADE,
|
|
484
|
+
mutation_id TEXT NOT NULL,
|
|
485
|
+
session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
486
|
+
created_at INTEGER NOT NULL,
|
|
487
|
+
entry_order INTEGER NOT NULL CHECK(entry_order >= 0),
|
|
488
|
+
payload_json TEXT NOT NULL
|
|
489
|
+
) STRICT;
|
|
490
|
+
CREATE INDEX memory_mutations_session_created_idx
|
|
491
|
+
ON memory_mutations(session_id, created_at, mutation_id);
|
|
492
|
+
|
|
493
|
+
CREATE TABLE pin_mutations (
|
|
494
|
+
mutation_key TEXT PRIMARY KEY REFERENCES entries(entry_key) ON DELETE CASCADE,
|
|
495
|
+
mutation_id TEXT NOT NULL,
|
|
496
|
+
session_id TEXT NOT NULL REFERENCES sessions(session_id) ON DELETE CASCADE,
|
|
497
|
+
created_at INTEGER NOT NULL,
|
|
498
|
+
entry_order INTEGER NOT NULL CHECK(entry_order >= 0),
|
|
499
|
+
payload_json TEXT NOT NULL
|
|
500
|
+
) STRICT;
|
|
501
|
+
CREATE INDEX pin_mutations_session_created_idx
|
|
502
|
+
ON pin_mutations(session_id, created_at, mutation_id);
|
|
503
|
+
`,
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
version: 10,
|
|
507
|
+
name: "model-calibration-and-provider-cache-metrics",
|
|
508
|
+
sql: `
|
|
509
|
+
ALTER TABLE context_manifests ADD COLUMN input_tokens INTEGER
|
|
510
|
+
CHECK(input_tokens IS NULL OR input_tokens >= 0);
|
|
511
|
+
ALTER TABLE context_manifests ADD COLUMN cache_read_tokens INTEGER
|
|
512
|
+
CHECK(cache_read_tokens IS NULL OR cache_read_tokens >= 0);
|
|
513
|
+
ALTER TABLE context_manifests ADD COLUMN cache_write_tokens INTEGER
|
|
514
|
+
CHECK(cache_write_tokens IS NULL OR cache_write_tokens >= 0);
|
|
515
|
+
|
|
516
|
+
ALTER TABLE token_calibration ADD COLUMN manifest_id TEXT
|
|
517
|
+
REFERENCES context_manifests(manifest_id) ON DELETE CASCADE;
|
|
518
|
+
ALTER TABLE token_calibration ADD COLUMN estimator_version TEXT NOT NULL DEFAULT 'chars-v1';
|
|
519
|
+
ALTER TABLE token_calibration ADD COLUMN input_tokens INTEGER
|
|
520
|
+
CHECK(input_tokens IS NULL OR input_tokens >= 0);
|
|
521
|
+
ALTER TABLE token_calibration ADD COLUMN cache_read_tokens INTEGER
|
|
522
|
+
CHECK(cache_read_tokens IS NULL OR cache_read_tokens >= 0);
|
|
523
|
+
ALTER TABLE token_calibration ADD COLUMN cache_write_tokens INTEGER
|
|
524
|
+
CHECK(cache_write_tokens IS NULL OR cache_write_tokens >= 0);
|
|
525
|
+
UPDATE token_calibration
|
|
526
|
+
SET input_tokens = actual, cache_read_tokens = 0, cache_write_tokens = 0
|
|
527
|
+
WHERE input_tokens IS NULL;
|
|
528
|
+
CREATE UNIQUE INDEX token_calibration_manifest_idx
|
|
529
|
+
ON token_calibration(manifest_id) WHERE manifest_id IS NOT NULL;
|
|
530
|
+
CREATE INDEX token_calibration_model_estimator_created_idx
|
|
531
|
+
ON token_calibration(provider, model, estimator_version, created_at DESC);
|
|
532
|
+
`,
|
|
533
|
+
},
|
|
534
|
+
];
|
|
535
|
+
export const CURRENT_SCHEMA_VERSION = MIGRATIONS.at(-1)?.version ?? 0;
|
|
536
|
+
function migrationChecksum(migration) {
|
|
537
|
+
return sha256(`${migration.version}\n${migration.name}\n${migration.sql}`);
|
|
538
|
+
}
|
|
539
|
+
export function listAppliedMigrations(database) {
|
|
540
|
+
const rows = database
|
|
541
|
+
.prepare("SELECT version, name, checksum, applied_at FROM schema_migrations ORDER BY version")
|
|
542
|
+
.all();
|
|
543
|
+
return rows.map((row) => ({
|
|
544
|
+
version: row.version,
|
|
545
|
+
name: row.name,
|
|
546
|
+
checksum: row.checksum,
|
|
547
|
+
appliedAt: row.applied_at,
|
|
548
|
+
}));
|
|
549
|
+
}
|
|
550
|
+
export function applyMigrations(database, now = Date.now()) {
|
|
551
|
+
database.exec(`
|
|
552
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
553
|
+
version INTEGER PRIMARY KEY,
|
|
554
|
+
name TEXT NOT NULL,
|
|
555
|
+
checksum TEXT NOT NULL,
|
|
556
|
+
applied_at INTEGER NOT NULL
|
|
557
|
+
) STRICT;
|
|
558
|
+
`);
|
|
559
|
+
const applied = new Map(listAppliedMigrations(database).map((migration) => [migration.version, migration]));
|
|
560
|
+
for (const existing of applied.values()) {
|
|
561
|
+
const known = MIGRATIONS.find((migration) => migration.version === existing.version);
|
|
562
|
+
if (!known) {
|
|
563
|
+
throw new Error(`Database schema version ${existing.version} is newer than this extension supports`);
|
|
564
|
+
}
|
|
565
|
+
if (existing.checksum !== migrationChecksum(known)) {
|
|
566
|
+
throw new Error(`Migration checksum mismatch for version ${existing.version}`);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
const insert = database.prepare("INSERT INTO schema_migrations(version, name, checksum, applied_at) VALUES (?, ?, ?, ?)");
|
|
570
|
+
for (const migration of MIGRATIONS) {
|
|
571
|
+
if (applied.has(migration.version))
|
|
572
|
+
continue;
|
|
573
|
+
database.exec("BEGIN IMMEDIATE");
|
|
574
|
+
try {
|
|
575
|
+
database.exec(migration.sql);
|
|
576
|
+
insert.run(migration.version, migration.name, migrationChecksum(migration), now);
|
|
577
|
+
database.exec(`PRAGMA user_version = ${migration.version}`);
|
|
578
|
+
database.exec("COMMIT");
|
|
579
|
+
}
|
|
580
|
+
catch (error) {
|
|
581
|
+
if (database.isTransaction)
|
|
582
|
+
database.exec("ROLLBACK");
|
|
583
|
+
throw error;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return listAppliedMigrations(database);
|
|
587
|
+
}
|
|
588
|
+
//# sourceMappingURL=migrations.js.map
|