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,242 @@
|
|
|
1
|
+
import { parseDs4CompactionDetails, } from "../../compaction/compaction-record.js";
|
|
2
|
+
const SELECT_SUMMARY = `
|
|
3
|
+
SELECT summary_id, session_id, summary_kind, content, source_hash, created_at,
|
|
4
|
+
validation_status, provider, model, first_kept_entry_id, tokens_before,
|
|
5
|
+
compaction_reason, lifecycle_status, pi_compaction_entry_id, metadata_json,
|
|
6
|
+
graph_level
|
|
7
|
+
FROM summaries
|
|
8
|
+
`;
|
|
9
|
+
function parseKind(value) {
|
|
10
|
+
if (!["segment", "aggregate", "task-state", "branch"].includes(value)) {
|
|
11
|
+
throw new Error(`Unsupported summary kind in database: ${value}`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function rowToRecord(database, row) {
|
|
16
|
+
const parsed = JSON.parse(row.metadata_json);
|
|
17
|
+
const metadata = parseDs4CompactionDetails({
|
|
18
|
+
readFiles: [],
|
|
19
|
+
modifiedFiles: [],
|
|
20
|
+
ds4ContextEngine: parsed,
|
|
21
|
+
})?.ds4ContextEngine;
|
|
22
|
+
if (!metadata)
|
|
23
|
+
throw new Error(`Summary ${row.summary_id} contains invalid DS4 metadata`);
|
|
24
|
+
if (metadata.summaryId !== row.summary_id
|
|
25
|
+
|| metadata.summaryKind !== row.summary_kind
|
|
26
|
+
|| metadata.sourceHash !== row.source_hash
|
|
27
|
+
|| metadata.graphLevel !== row.graph_level) {
|
|
28
|
+
throw new Error(`Summary ${row.summary_id} metadata does not match graph columns`);
|
|
29
|
+
}
|
|
30
|
+
const sourceRows = database.prepare(`
|
|
31
|
+
SELECT entry.entry_id
|
|
32
|
+
FROM summary_sources AS source
|
|
33
|
+
JOIN entries AS entry ON entry.entry_key = source.entry_key
|
|
34
|
+
WHERE source.summary_id = ?
|
|
35
|
+
ORDER BY entry.created_at, entry.entry_id
|
|
36
|
+
`).all(row.summary_id);
|
|
37
|
+
const childRows = database.prepare(`
|
|
38
|
+
SELECT child_summary_id
|
|
39
|
+
FROM summary_edges
|
|
40
|
+
WHERE parent_summary_id = ?
|
|
41
|
+
ORDER BY child_order, child_summary_id
|
|
42
|
+
`).all(row.summary_id);
|
|
43
|
+
const sourceEntryIds = sourceRows.map((source) => source.entry_id);
|
|
44
|
+
const childSummaryIds = childRows.map((child) => child.child_summary_id);
|
|
45
|
+
const sorted = (values) => [...values].sort((left, right) => left.localeCompare(right));
|
|
46
|
+
if (JSON.stringify(sorted(sourceEntryIds)) !== JSON.stringify(sorted(metadata.sourceEntryIds))) {
|
|
47
|
+
throw new Error(`Summary ${row.summary_id} source links do not match metadata`);
|
|
48
|
+
}
|
|
49
|
+
if (JSON.stringify(childSummaryIds) !== JSON.stringify(metadata.childSummaryIds)) {
|
|
50
|
+
throw new Error(`Summary ${row.summary_id} child order does not match metadata`);
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
id: row.summary_id,
|
|
54
|
+
sessionId: row.session_id,
|
|
55
|
+
kind: parseKind(row.summary_kind),
|
|
56
|
+
content: row.content,
|
|
57
|
+
sourceHash: row.source_hash,
|
|
58
|
+
sourceEntryIds,
|
|
59
|
+
childSummaryIds,
|
|
60
|
+
graphLevel: row.graph_level,
|
|
61
|
+
createdAt: row.created_at,
|
|
62
|
+
validationStatus: metadata.validationStatus,
|
|
63
|
+
...(row.provider ? { provider: row.provider } : {}),
|
|
64
|
+
...(row.model ? { model: row.model } : {}),
|
|
65
|
+
firstKeptEntryId: row.first_kept_entry_id ?? metadata.firstKeptEntryId,
|
|
66
|
+
tokensBefore: row.tokens_before ?? metadata.tokensBefore,
|
|
67
|
+
reason: metadata.reason,
|
|
68
|
+
lifecycleStatus: row.lifecycle_status,
|
|
69
|
+
...(row.pi_compaction_entry_id ? { piCompactionEntryId: row.pi_compaction_entry_id } : {}),
|
|
70
|
+
metadata,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function assertImmutable(database, record) {
|
|
74
|
+
const existing = database.prepare(`
|
|
75
|
+
SELECT session_id, summary_kind, content, source_hash, created_at, graph_level
|
|
76
|
+
FROM summaries WHERE summary_id = ?
|
|
77
|
+
`).get(record.id);
|
|
78
|
+
if (!existing)
|
|
79
|
+
return;
|
|
80
|
+
if (existing.session_id !== record.sessionId
|
|
81
|
+
|| existing.summary_kind !== record.kind
|
|
82
|
+
|| existing.content !== record.content
|
|
83
|
+
|| existing.source_hash !== record.sourceHash
|
|
84
|
+
|| existing.created_at !== record.createdAt
|
|
85
|
+
|| existing.graph_level !== record.graphLevel) {
|
|
86
|
+
throw new Error(`Summary node is immutable and conflicts with existing node: ${record.id}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export class SummaryRepository {
|
|
90
|
+
database;
|
|
91
|
+
constructor(database) {
|
|
92
|
+
this.database = database;
|
|
93
|
+
}
|
|
94
|
+
save(record) {
|
|
95
|
+
this.saveGraph([record]);
|
|
96
|
+
}
|
|
97
|
+
saveGraph(records) {
|
|
98
|
+
if (records.length === 0)
|
|
99
|
+
return;
|
|
100
|
+
const ids = new Set();
|
|
101
|
+
for (const record of records) {
|
|
102
|
+
if (ids.has(record.id))
|
|
103
|
+
throw new Error(`Duplicate summary node in graph batch: ${record.id}`);
|
|
104
|
+
ids.add(record.id);
|
|
105
|
+
}
|
|
106
|
+
this.database.exec("BEGIN IMMEDIATE");
|
|
107
|
+
try {
|
|
108
|
+
for (const record of records) {
|
|
109
|
+
assertImmutable(this.database, record);
|
|
110
|
+
this.database.prepare(`
|
|
111
|
+
INSERT INTO summaries(
|
|
112
|
+
summary_id, session_id, summary_kind, content, source_hash, created_at,
|
|
113
|
+
validation_status, provider, model, first_kept_entry_id, tokens_before,
|
|
114
|
+
compaction_reason, lifecycle_status, pi_compaction_entry_id, metadata_json,
|
|
115
|
+
graph_level
|
|
116
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
117
|
+
ON CONFLICT(summary_id) DO UPDATE SET
|
|
118
|
+
validation_status = excluded.validation_status,
|
|
119
|
+
provider = excluded.provider,
|
|
120
|
+
model = excluded.model,
|
|
121
|
+
first_kept_entry_id = excluded.first_kept_entry_id,
|
|
122
|
+
tokens_before = excluded.tokens_before,
|
|
123
|
+
compaction_reason = excluded.compaction_reason,
|
|
124
|
+
lifecycle_status = CASE
|
|
125
|
+
WHEN excluded.lifecycle_status = 'committed' THEN 'committed'
|
|
126
|
+
WHEN summaries.lifecycle_status = 'committed' THEN 'committed'
|
|
127
|
+
ELSE excluded.lifecycle_status
|
|
128
|
+
END,
|
|
129
|
+
pi_compaction_entry_id = COALESCE(excluded.pi_compaction_entry_id, summaries.pi_compaction_entry_id),
|
|
130
|
+
metadata_json = excluded.metadata_json,
|
|
131
|
+
graph_level = excluded.graph_level
|
|
132
|
+
`).run(record.id, record.sessionId, record.kind, record.content, record.sourceHash, record.createdAt, record.validationStatus, record.provider ?? null, record.model ?? null, record.firstKeptEntryId, record.tokensBefore, record.reason, record.lifecycleStatus, record.piCompactionEntryId ?? null, JSON.stringify(record.metadata), record.graphLevel);
|
|
133
|
+
}
|
|
134
|
+
for (const record of records) {
|
|
135
|
+
this.database.prepare("DELETE FROM summary_sources WHERE summary_id = ?").run(record.id);
|
|
136
|
+
this.database.prepare("DELETE FROM summary_edges WHERE parent_summary_id = ?").run(record.id);
|
|
137
|
+
}
|
|
138
|
+
const insertSource = this.database.prepare(`
|
|
139
|
+
INSERT INTO summary_sources(summary_id, entry_key)
|
|
140
|
+
SELECT ?, entry_key FROM entries WHERE session_id = ? AND entry_id = ?
|
|
141
|
+
`);
|
|
142
|
+
const childLookup = this.database.prepare(`
|
|
143
|
+
SELECT session_id, graph_level FROM summaries WHERE summary_id = ?
|
|
144
|
+
`);
|
|
145
|
+
const insertEdge = this.database.prepare(`
|
|
146
|
+
INSERT INTO summary_edges(parent_summary_id, child_summary_id, child_order)
|
|
147
|
+
VALUES (?, ?, ?)
|
|
148
|
+
`);
|
|
149
|
+
for (const record of records) {
|
|
150
|
+
for (const entryId of new Set(record.sourceEntryIds)) {
|
|
151
|
+
const result = insertSource.run(record.id, record.sessionId, entryId);
|
|
152
|
+
if (result.changes !== 1) {
|
|
153
|
+
throw new Error(`Summary source entry is not indexed: ${record.sessionId}:${entryId}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const children = [...new Set(record.childSummaryIds)];
|
|
157
|
+
for (const [order, childId] of children.entries()) {
|
|
158
|
+
if (childId === record.id)
|
|
159
|
+
throw new Error(`Summary node cannot reference itself: ${record.id}`);
|
|
160
|
+
const child = childLookup.get(childId);
|
|
161
|
+
if (!child || child.session_id !== record.sessionId) {
|
|
162
|
+
throw new Error(`Summary child is missing from the same session: ${record.sessionId}:${childId}`);
|
|
163
|
+
}
|
|
164
|
+
if (child.graph_level >= record.graphLevel) {
|
|
165
|
+
throw new Error(`Summary child level must be lower than parent: ${childId} -> ${record.id}`);
|
|
166
|
+
}
|
|
167
|
+
const cycle = this.database.prepare(`
|
|
168
|
+
WITH RECURSIVE descendants(summary_id) AS (
|
|
169
|
+
SELECT child_summary_id FROM summary_edges WHERE parent_summary_id = ?
|
|
170
|
+
UNION
|
|
171
|
+
SELECT edge.child_summary_id
|
|
172
|
+
FROM summary_edges AS edge
|
|
173
|
+
JOIN descendants AS child ON edge.parent_summary_id = child.summary_id
|
|
174
|
+
)
|
|
175
|
+
SELECT 1 AS found FROM descendants WHERE summary_id = ? LIMIT 1
|
|
176
|
+
`).get(childId, record.id);
|
|
177
|
+
if (cycle)
|
|
178
|
+
throw new Error(`Summary edge would create a cycle: ${record.id} -> ${childId}`);
|
|
179
|
+
insertEdge.run(record.id, childId, order);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
this.database.exec("COMMIT");
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
if (this.database.isTransaction)
|
|
186
|
+
this.database.exec("ROLLBACK");
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
markCommitted(summaryId, piCompactionEntryId) {
|
|
191
|
+
const result = this.database.prepare(`
|
|
192
|
+
UPDATE summaries
|
|
193
|
+
SET lifecycle_status = 'committed',
|
|
194
|
+
pi_compaction_entry_id = COALESCE(?, pi_compaction_entry_id)
|
|
195
|
+
WHERE summary_id = ?
|
|
196
|
+
`).run(piCompactionEntryId ?? null, summaryId);
|
|
197
|
+
return result.changes === 1;
|
|
198
|
+
}
|
|
199
|
+
markFailed(summaryId) {
|
|
200
|
+
const result = this.database.prepare(`
|
|
201
|
+
UPDATE summaries SET lifecycle_status = 'failed'
|
|
202
|
+
WHERE summary_id = ? AND lifecycle_status = 'prepared'
|
|
203
|
+
`).run(summaryId);
|
|
204
|
+
return result.changes === 1;
|
|
205
|
+
}
|
|
206
|
+
markFailedMany(summaryIds) {
|
|
207
|
+
let changed = 0;
|
|
208
|
+
for (const summaryId of new Set(summaryIds))
|
|
209
|
+
changed += this.markFailed(summaryId) ? 1 : 0;
|
|
210
|
+
return changed;
|
|
211
|
+
}
|
|
212
|
+
failPreparedForSession(sessionId) {
|
|
213
|
+
const result = this.database.prepare(`
|
|
214
|
+
UPDATE summaries SET lifecycle_status = 'failed'
|
|
215
|
+
WHERE session_id = ? AND lifecycle_status = 'prepared'
|
|
216
|
+
`).run(sessionId);
|
|
217
|
+
return Number(result.changes);
|
|
218
|
+
}
|
|
219
|
+
getById(summaryId) {
|
|
220
|
+
const row = this.database.prepare(`${SELECT_SUMMARY} WHERE summary_id = ? AND metadata_json <> '{}'`)
|
|
221
|
+
.get(summaryId);
|
|
222
|
+
return row ? rowToRecord(this.database, row) : undefined;
|
|
223
|
+
}
|
|
224
|
+
getLatest(sessionId) {
|
|
225
|
+
const row = this.database.prepare(`
|
|
226
|
+
${SELECT_SUMMARY}
|
|
227
|
+
WHERE session_id = ? AND metadata_json <> '{}'
|
|
228
|
+
ORDER BY created_at DESC, graph_level DESC, rowid DESC
|
|
229
|
+
LIMIT 1
|
|
230
|
+
`).get(sessionId);
|
|
231
|
+
return row ? rowToRecord(this.database, row) : undefined;
|
|
232
|
+
}
|
|
233
|
+
listBySession(sessionId) {
|
|
234
|
+
const rows = this.database.prepare(`
|
|
235
|
+
${SELECT_SUMMARY}
|
|
236
|
+
WHERE session_id = ? AND metadata_json <> '{}'
|
|
237
|
+
ORDER BY created_at, graph_level, rowid
|
|
238
|
+
`).all(sessionId);
|
|
239
|
+
return rows.map((row) => rowToRecord(this.database, row));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=summary-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary-repository.js","sourceRoot":"","sources":["../../../src/persistence/repositories/summary-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Logger } from "../shared/logging.ts";
|
|
2
|
+
import { type AppliedMigration } from "./migrations.ts";
|
|
3
|
+
import { ArtifactRepository } from "./repositories/artifact-repository.ts";
|
|
4
|
+
import { ContextManifestRepository } from "./repositories/context-manifest-repository.ts";
|
|
5
|
+
import { MemoryRepository } from "./repositories/memory-repository.ts";
|
|
6
|
+
import { ProjectKnowledgeRepository } from "./repositories/project-knowledge-repository.ts";
|
|
7
|
+
import { SessionIndexRepository, type SessionIdentity, type SessionIndexStats } from "./repositories/session-index-repository.ts";
|
|
8
|
+
import { SummaryRepository } from "./repositories/summary-repository.ts";
|
|
9
|
+
export type SessionRecord = SessionIdentity;
|
|
10
|
+
export type { SessionIndexStats } from "./repositories/session-index-repository.ts";
|
|
11
|
+
export interface DatabaseHealth {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
quickCheck: string;
|
|
14
|
+
journalMode: string;
|
|
15
|
+
foreignKeys: boolean;
|
|
16
|
+
schemaVersion: number;
|
|
17
|
+
appliedMigrations: number;
|
|
18
|
+
}
|
|
19
|
+
export interface OpenDatabaseOptions {
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
now?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare class ContextDatabase {
|
|
24
|
+
readonly path: string;
|
|
25
|
+
private readonly database;
|
|
26
|
+
private readonly logger;
|
|
27
|
+
readonly schemaVersion: number;
|
|
28
|
+
readonly migrations: readonly AppliedMigration[];
|
|
29
|
+
readonly sessionIndex: SessionIndexRepository;
|
|
30
|
+
readonly artifacts: ArtifactRepository;
|
|
31
|
+
readonly manifests: ContextManifestRepository;
|
|
32
|
+
readonly memory: MemoryRepository;
|
|
33
|
+
readonly summaries: SummaryRepository;
|
|
34
|
+
readonly projectKnowledge: ProjectKnowledgeRepository;
|
|
35
|
+
private closed;
|
|
36
|
+
private constructor();
|
|
37
|
+
static open(path: string, options?: OpenDatabaseOptions): ContextDatabase;
|
|
38
|
+
upsertSession(record: SessionIdentity): void;
|
|
39
|
+
getSessionStats(sessionId: string): SessionIndexStats;
|
|
40
|
+
listTables(): string[];
|
|
41
|
+
health(): DatabaseHealth;
|
|
42
|
+
close(): void;
|
|
43
|
+
private assertOpen;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAA2C,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,+CAA+C,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EACL,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAEpF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAoBD,qBAAa,eAAe;IAYxB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAbzB,QAAQ,CAAC,aAAa,SAA0B;IAChD,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,0BAA0B,CAAC;IACtD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;IAeP,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,eAAe;IAwC7E,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAK5C,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB;IAKrD,UAAU,IAAI,MAAM,EAAE;IAUtB,MAAM,IAAI,cAAc;IAiBxB,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { chmodSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { DatabaseSync } from "node:sqlite";
|
|
4
|
+
import { silentLogger } from "../shared/logging.js";
|
|
5
|
+
import { applyMigrations, CURRENT_SCHEMA_VERSION } from "./migrations.js";
|
|
6
|
+
import { ArtifactRepository } from "./repositories/artifact-repository.js";
|
|
7
|
+
import { ContextManifestRepository } from "./repositories/context-manifest-repository.js";
|
|
8
|
+
import { MemoryRepository } from "./repositories/memory-repository.js";
|
|
9
|
+
import { ProjectKnowledgeRepository } from "./repositories/project-knowledge-repository.js";
|
|
10
|
+
import { SessionIndexRepository, } from "./repositories/session-index-repository.js";
|
|
11
|
+
import { SummaryRepository } from "./repositories/summary-repository.js";
|
|
12
|
+
function firstColumn(row) {
|
|
13
|
+
if (!row || typeof row !== "object")
|
|
14
|
+
throw new Error("SQLite PRAGMA returned no row");
|
|
15
|
+
const value = Object.values(row)[0];
|
|
16
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
17
|
+
throw new Error("SQLite PRAGMA returned an unexpected value");
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function bestEffortChmod(path, mode) {
|
|
22
|
+
try {
|
|
23
|
+
chmodSync(path, mode);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const code = error && typeof error === "object" && "code" in error ? String(error.code) : "";
|
|
27
|
+
if (code !== "ENOSYS" && code !== "EPERM" && code !== "EINVAL")
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class ContextDatabase {
|
|
32
|
+
path;
|
|
33
|
+
database;
|
|
34
|
+
logger;
|
|
35
|
+
schemaVersion = CURRENT_SCHEMA_VERSION;
|
|
36
|
+
migrations;
|
|
37
|
+
sessionIndex;
|
|
38
|
+
artifacts;
|
|
39
|
+
manifests;
|
|
40
|
+
memory;
|
|
41
|
+
summaries;
|
|
42
|
+
projectKnowledge;
|
|
43
|
+
closed = false;
|
|
44
|
+
constructor(path, database, logger, migrations) {
|
|
45
|
+
this.path = path;
|
|
46
|
+
this.database = database;
|
|
47
|
+
this.logger = logger;
|
|
48
|
+
this.migrations = migrations;
|
|
49
|
+
this.sessionIndex = new SessionIndexRepository(database);
|
|
50
|
+
this.artifacts = new ArtifactRepository(database);
|
|
51
|
+
this.manifests = new ContextManifestRepository(database);
|
|
52
|
+
this.memory = new MemoryRepository(database);
|
|
53
|
+
this.summaries = new SummaryRepository(database);
|
|
54
|
+
this.projectKnowledge = new ProjectKnowledgeRepository(database);
|
|
55
|
+
}
|
|
56
|
+
static open(path, options = {}) {
|
|
57
|
+
const logger = options.logger ?? silentLogger;
|
|
58
|
+
const memory = path === ":memory:";
|
|
59
|
+
if (!memory) {
|
|
60
|
+
const directory = dirname(path);
|
|
61
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
62
|
+
bestEffortChmod(directory, 0o700);
|
|
63
|
+
}
|
|
64
|
+
const database = new DatabaseSync(path, {
|
|
65
|
+
enableForeignKeyConstraints: true,
|
|
66
|
+
enableDoubleQuotedStringLiterals: false,
|
|
67
|
+
allowExtension: false,
|
|
68
|
+
timeout: 5000,
|
|
69
|
+
});
|
|
70
|
+
try {
|
|
71
|
+
database.exec("PRAGMA foreign_keys = ON");
|
|
72
|
+
database.exec("PRAGMA busy_timeout = 5000");
|
|
73
|
+
database.exec("PRAGMA synchronous = NORMAL");
|
|
74
|
+
database.exec("PRAGMA trusted_schema = OFF");
|
|
75
|
+
database.exec("PRAGMA secure_delete = FAST");
|
|
76
|
+
if (!memory)
|
|
77
|
+
database.exec("PRAGMA journal_mode = WAL");
|
|
78
|
+
const migrations = applyMigrations(database, options.now);
|
|
79
|
+
if (!memory)
|
|
80
|
+
bestEffortChmod(path, 0o600);
|
|
81
|
+
logger.info("database.opened", {
|
|
82
|
+
databasePath: path,
|
|
83
|
+
schemaVersion: CURRENT_SCHEMA_VERSION,
|
|
84
|
+
migrations: migrations.length,
|
|
85
|
+
});
|
|
86
|
+
return new ContextDatabase(path, database, logger, migrations);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
database.close();
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
upsertSession(record) {
|
|
94
|
+
this.assertOpen();
|
|
95
|
+
this.sessionIndex.upsertSession(record);
|
|
96
|
+
}
|
|
97
|
+
getSessionStats(sessionId) {
|
|
98
|
+
this.assertOpen();
|
|
99
|
+
return this.sessionIndex.getStats(sessionId);
|
|
100
|
+
}
|
|
101
|
+
listTables() {
|
|
102
|
+
this.assertOpen();
|
|
103
|
+
const rows = this.database.prepare(`
|
|
104
|
+
SELECT name FROM sqlite_schema
|
|
105
|
+
WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
|
|
106
|
+
ORDER BY name
|
|
107
|
+
`).all();
|
|
108
|
+
return rows.map((row) => row.name);
|
|
109
|
+
}
|
|
110
|
+
health() {
|
|
111
|
+
this.assertOpen();
|
|
112
|
+
const quickCheck = String(firstColumn(this.database.prepare("PRAGMA quick_check").get()));
|
|
113
|
+
const journalMode = String(firstColumn(this.database.prepare("PRAGMA journal_mode").get()));
|
|
114
|
+
const foreignKeys = Number(firstColumn(this.database.prepare("PRAGMA foreign_keys").get())) === 1;
|
|
115
|
+
const schemaVersion = Number(firstColumn(this.database.prepare("PRAGMA user_version").get()));
|
|
116
|
+
return {
|
|
117
|
+
ok: quickCheck === "ok" && foreignKeys && schemaVersion === CURRENT_SCHEMA_VERSION,
|
|
118
|
+
quickCheck,
|
|
119
|
+
journalMode,
|
|
120
|
+
foreignKeys,
|
|
121
|
+
schemaVersion,
|
|
122
|
+
appliedMigrations: this.migrations.length,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
close() {
|
|
126
|
+
if (this.closed)
|
|
127
|
+
return;
|
|
128
|
+
this.closed = true;
|
|
129
|
+
this.database.close();
|
|
130
|
+
this.logger.info("database.closed", { databasePath: this.path });
|
|
131
|
+
}
|
|
132
|
+
assertOpen() {
|
|
133
|
+
if (this.closed)
|
|
134
|
+
throw new Error("Context database is closed");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type AtomicGroupKind = "turn" | "summary" | "prefix";
|
|
2
|
+
export interface AtomicMessageGroup {
|
|
3
|
+
id: string;
|
|
4
|
+
kind: AtomicGroupKind;
|
|
5
|
+
messageIndices: number[];
|
|
6
|
+
startIndex: number;
|
|
7
|
+
endIndex: number;
|
|
8
|
+
estimatedTokens: number;
|
|
9
|
+
containsToolExchange: boolean;
|
|
10
|
+
reason: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function messageRole(message: unknown): string | undefined;
|
|
13
|
+
export declare function buildAtomicGroups(messages: readonly unknown[]): AtomicMessageGroup[];
|
|
14
|
+
export declare function validateAtomicSelection(messages: readonly unknown[], selectedIndices: ReadonlySet<number>): string[];
|
|
15
|
+
//# sourceMappingURL=atomic-groups.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-groups.d.ts","sourceRoot":"","sources":["../../src/planner/atomic-groups.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB;AAgBD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGhE;AA0ED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,kBAAkB,EAAE,CA+EpF;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,GACnC,MAAM,EAAE,CAyBV"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { estimateMessageTokens } from "../core/token-estimator.js";
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
export function messageRole(message) {
|
|
6
|
+
if (!isRecord(message))
|
|
7
|
+
return undefined;
|
|
8
|
+
return typeof message.role === "string" ? message.role : undefined;
|
|
9
|
+
}
|
|
10
|
+
function isSummaryMessage(message) {
|
|
11
|
+
const role = messageRole(message);
|
|
12
|
+
return role === "compactionSummary" || role === "branchSummary";
|
|
13
|
+
}
|
|
14
|
+
function toolRelations(messages) {
|
|
15
|
+
const calls = new Map();
|
|
16
|
+
const results = new Map();
|
|
17
|
+
for (let index = 0; index < messages.length; index++) {
|
|
18
|
+
const message = messages[index];
|
|
19
|
+
if (!isRecord(message))
|
|
20
|
+
continue;
|
|
21
|
+
if (message.role === "assistant" && Array.isArray(message.content)) {
|
|
22
|
+
for (const block of message.content) {
|
|
23
|
+
if (!isRecord(block) || block.type !== "toolCall" || typeof block.id !== "string")
|
|
24
|
+
continue;
|
|
25
|
+
calls.set(block.id, index);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (message.role === "toolResult" && typeof message.toolCallId === "string") {
|
|
29
|
+
const indices = results.get(message.toolCallId) ?? [];
|
|
30
|
+
indices.push(index);
|
|
31
|
+
results.set(message.toolCallId, indices);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { calls, results };
|
|
35
|
+
}
|
|
36
|
+
function initialGroups(messages) {
|
|
37
|
+
const groups = [];
|
|
38
|
+
let activeTurn;
|
|
39
|
+
let activePrefix;
|
|
40
|
+
for (let index = 0; index < messages.length; index++) {
|
|
41
|
+
const message = messages[index];
|
|
42
|
+
if (isSummaryMessage(message)) {
|
|
43
|
+
groups.push({ kind: "summary", messageIndices: [index] });
|
|
44
|
+
activeTurn = undefined;
|
|
45
|
+
activePrefix = undefined;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (messageRole(message) === "user") {
|
|
49
|
+
activeTurn = { kind: "turn", messageIndices: [index] };
|
|
50
|
+
groups.push(activeTurn);
|
|
51
|
+
activePrefix = undefined;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (activeTurn) {
|
|
55
|
+
activeTurn.messageIndices.push(index);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (!activePrefix) {
|
|
59
|
+
activePrefix = { kind: "prefix", messageIndices: [] };
|
|
60
|
+
groups.push(activePrefix);
|
|
61
|
+
}
|
|
62
|
+
activePrefix.messageIndices.push(index);
|
|
63
|
+
}
|
|
64
|
+
return groups;
|
|
65
|
+
}
|
|
66
|
+
function mergedKind(groups, members) {
|
|
67
|
+
if (members.some((index) => groups[index]?.kind === "turn"))
|
|
68
|
+
return "turn";
|
|
69
|
+
if (members.every((index) => groups[index]?.kind === "summary"))
|
|
70
|
+
return "summary";
|
|
71
|
+
return "prefix";
|
|
72
|
+
}
|
|
73
|
+
export function buildAtomicGroups(messages) {
|
|
74
|
+
const drafts = initialGroups(messages);
|
|
75
|
+
if (drafts.length === 0)
|
|
76
|
+
return [];
|
|
77
|
+
const parents = drafts.map((_, index) => index);
|
|
78
|
+
const messageGroups = new Map();
|
|
79
|
+
drafts.forEach((group, groupIndex) => {
|
|
80
|
+
for (const messageIndex of group.messageIndices)
|
|
81
|
+
messageGroups.set(messageIndex, groupIndex);
|
|
82
|
+
});
|
|
83
|
+
const find = (index) => {
|
|
84
|
+
let root = index;
|
|
85
|
+
while (parents[root] !== root)
|
|
86
|
+
root = parents[root] ?? root;
|
|
87
|
+
while (parents[index] !== index) {
|
|
88
|
+
const parent = parents[index] ?? index;
|
|
89
|
+
parents[index] = root;
|
|
90
|
+
index = parent;
|
|
91
|
+
}
|
|
92
|
+
return root;
|
|
93
|
+
};
|
|
94
|
+
const union = (left, right) => {
|
|
95
|
+
const leftRoot = find(left);
|
|
96
|
+
const rightRoot = find(right);
|
|
97
|
+
if (leftRoot !== rightRoot)
|
|
98
|
+
parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
|
|
99
|
+
};
|
|
100
|
+
const relations = toolRelations(messages);
|
|
101
|
+
for (const [toolCallId, resultIndices] of relations.results) {
|
|
102
|
+
const callIndex = relations.calls.get(toolCallId);
|
|
103
|
+
if (callIndex === undefined)
|
|
104
|
+
continue;
|
|
105
|
+
const callGroup = messageGroups.get(callIndex);
|
|
106
|
+
if (callGroup === undefined)
|
|
107
|
+
continue;
|
|
108
|
+
for (const resultIndex of resultIndices) {
|
|
109
|
+
const resultGroup = messageGroups.get(resultIndex);
|
|
110
|
+
if (resultGroup !== undefined)
|
|
111
|
+
union(callGroup, resultGroup);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const merged = new Map();
|
|
115
|
+
drafts.forEach((group, groupIndex) => {
|
|
116
|
+
const root = find(groupIndex);
|
|
117
|
+
const aggregate = merged.get(root) ?? { draftIndices: [], messageIndices: [] };
|
|
118
|
+
aggregate.draftIndices.push(groupIndex);
|
|
119
|
+
aggregate.messageIndices.push(...group.messageIndices);
|
|
120
|
+
merged.set(root, aggregate);
|
|
121
|
+
});
|
|
122
|
+
return [...merged.values()]
|
|
123
|
+
.map((aggregate) => {
|
|
124
|
+
const messageIndices = [...aggregate.messageIndices].sort((left, right) => left - right);
|
|
125
|
+
const startIndex = messageIndices[0] ?? 0;
|
|
126
|
+
const endIndex = messageIndices.at(-1) ?? startIndex;
|
|
127
|
+
const selected = new Set(messageIndices);
|
|
128
|
+
const containsToolExchange = [...relations.results].some(([id, resultIndices]) => {
|
|
129
|
+
const callIndex = relations.calls.get(id);
|
|
130
|
+
return callIndex !== undefined && selected.has(callIndex) && resultIndices.some((index) => selected.has(index));
|
|
131
|
+
});
|
|
132
|
+
const kind = mergedKind(drafts, aggregate.draftIndices);
|
|
133
|
+
return {
|
|
134
|
+
id: `group:${startIndex}-${endIndex}`,
|
|
135
|
+
kind,
|
|
136
|
+
messageIndices,
|
|
137
|
+
startIndex,
|
|
138
|
+
endIndex,
|
|
139
|
+
estimatedTokens: messageIndices.reduce((total, index) => total + estimateMessageTokens(messages[index]), 0),
|
|
140
|
+
containsToolExchange,
|
|
141
|
+
reason: containsToolExchange
|
|
142
|
+
? "Atomic conversation turn containing a complete tool call/result batch"
|
|
143
|
+
: kind === "turn"
|
|
144
|
+
? "Conversation turn boundary"
|
|
145
|
+
: kind === "summary"
|
|
146
|
+
? "Active Pi summary message"
|
|
147
|
+
: "Messages preceding the first user turn",
|
|
148
|
+
};
|
|
149
|
+
})
|
|
150
|
+
.sort((left, right) => left.startIndex - right.startIndex);
|
|
151
|
+
}
|
|
152
|
+
export function validateAtomicSelection(messages, selectedIndices) {
|
|
153
|
+
const relations = toolRelations(messages);
|
|
154
|
+
const errors = [];
|
|
155
|
+
for (const [toolCallId, callIndex] of relations.calls) {
|
|
156
|
+
if (!selectedIndices.has(callIndex))
|
|
157
|
+
continue;
|
|
158
|
+
const resultIndices = relations.results.get(toolCallId) ?? [];
|
|
159
|
+
if (resultIndices.length === 0) {
|
|
160
|
+
errors.push(`selected tool call ${toolCallId} has no result`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (resultIndices.some((index) => !selectedIndices.has(index))) {
|
|
164
|
+
errors.push(`selected tool call ${toolCallId} is missing one or more results`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (const [toolCallId, resultIndices] of relations.results) {
|
|
168
|
+
if (!resultIndices.some((index) => selectedIndices.has(index)))
|
|
169
|
+
continue;
|
|
170
|
+
const callIndex = relations.calls.get(toolCallId);
|
|
171
|
+
if (callIndex === undefined || !selectedIndices.has(callIndex)) {
|
|
172
|
+
errors.push(`selected tool result ${toolCallId} has no selected call`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return [...new Set(errors)];
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=atomic-groups.js.map
|