@cortexkit/pi-magic-context 0.49.10 → 0.49.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/auto-search-worker.js +4 -4
  2. package/dist/{compaction-marker-candidates-n4dphyz4.js → compaction-marker-candidates-k4tqg4jb.js} +2 -2
  3. package/dist/compaction-marker-candidates-worker.js +1 -1
  4. package/dist/embedding-backfill-14tqcfrn.js +20 -0
  5. package/dist/embedding-worker-process.js +1 -1
  6. package/dist/embedding-worker.js +5 -5
  7. package/dist/historian-calibration-extension.js +1 -1
  8. package/dist/{index-ta0ed2nc.js → index-1k729e4f.js} +15 -15
  9. package/dist/{index-g13fb2sj.js → index-3cnarwf8.js} +4 -4
  10. package/dist/{index-729kkhmf.js → index-46q4e104.js} +1 -1
  11. package/dist/{index-9vzkrnrf.js → index-53xdqb3d.js} +30 -26
  12. package/dist/{index-szh001qb.js → index-6dz2ed1v.js} +2 -2
  13. package/dist/{index-gqxsds3q.js → index-6ex901g3.js} +187 -27
  14. package/dist/{index-h160xxaq.js → index-6hex51s9.js} +8 -8
  15. package/dist/{index-gycf3sp7.js → index-7bqrfyny.js} +46 -2
  16. package/dist/{index-6e3yv1jt.js → index-af9nb5db.js} +243 -135
  17. package/dist/{index-3veejgp8.js → index-apgwdby5.js} +1 -1
  18. package/dist/{index-43zqh10z.js → index-d4dt19md.js} +1 -1
  19. package/dist/{index-fdxzpnbj.js → index-djxc8w8c.js} +1 -1
  20. package/dist/{index-x7426vy4.js → index-ed9d2ded.js} +18 -5
  21. package/dist/{index-kh3jt7t9.js → index-f18ec69t.js} +1 -1
  22. package/dist/{index-qc8e13wc.js → index-f6e8jsrh.js} +140 -17
  23. package/dist/{index-4pxydwvg.js → index-g4jf772p.js} +1 -1
  24. package/dist/{index-ns319t8e.js → index-gykw2zhn.js} +16 -11
  25. package/dist/{index-4vj37yw9.js → index-he9s4qsj.js} +16 -6
  26. package/dist/{index-8yjhda46.js → index-j24916mq.js} +3 -3
  27. package/dist/{index-ttxsmaj5.js → index-jrap43gc.js} +1 -1
  28. package/dist/{index-v26j81w6.js → index-xpsht877.js} +5 -5
  29. package/dist/{index-243wh86p.js → index-z5ftst3e.js} +9 -9
  30. package/dist/{index-rkwh9kce.js → index-zapgkmp7.js} +58 -34
  31. package/dist/index.js +453 -240
  32. package/dist/{logger-qg51hmp7.js → logger-dygt96rn.js} +1 -1
  33. package/dist/{message-index-bounded-y1c88n9a.js → message-index-bounded-ws37m1nt.js} +13 -13
  34. package/dist/{message-index-ejaa9may.js → message-index-dfs6k35a.js} +13 -13
  35. package/dist/{message-time-backfill-q9s88zdv.js → message-time-backfill-r2ar1qvk.js} +2 -2
  36. package/dist/migration-worker.js +9 -9
  37. package/dist/{project-embedding-registry-bxawck58.js → project-embedding-registry-ymvne11v.js} +10 -10
  38. package/dist/raw-ordinal-warmup-worker.js +12 -7
  39. package/dist/{read-session-chunk-4094zemt.js → read-session-chunk-83864b37.js} +8 -8
  40. package/dist/{read-session-raw-hm7ptnrh.js → read-session-raw-azkqjgzg.js} +6 -2
  41. package/dist/{safe-notification-target-62ty6rvp.js → safe-notification-target-2rkvkmw8.js} +2 -2
  42. package/dist/{search-hsr95vex.js → search-85e21wb8.js} +19 -19
  43. package/dist/{storage-tags-zh23ynsh.js → storage-tags-zmf30zqp.js} +6 -4
  44. package/dist/subagent-entry.js +22 -22
  45. package/package.json +1 -1
  46. package/dist/embedding-backfill-chva00z3.js +0 -20
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  getTokenEstimatorFingerprint,
3
3
  estimateTokens
4
- } from "./index-4pxydwvg.js";
4
+ } from "./index-g4jf772p.js";
5
5
  import {
6
6
  getHarness2
7
7
  } from "./index-0h2mkab2.js";
8
8
  import {
9
9
  log2
10
- } from "./index-gycf3sp7.js";
10
+ } from "./index-7bqrfyny.js";
11
11
  import {
12
12
  isSynapseEmbeddingTruncated
13
- } from "./index-szh001qb.js";
13
+ } from "./index-6dz2ed1v.js";
14
14
  import {
15
15
  messageFtsOrdinalRangeIsMapped
16
- } from "./index-fdxzpnbj.js";
16
+ } from "./index-djxc8w8c.js";
17
17
 
18
18
  // ../plugin/src/features/magic-context/compartment-chunk-embedding.ts
19
19
  import { createHash } from "node:crypto";
@@ -106,6 +106,27 @@ function recursiveCharacterSplit(text, options) {
106
106
  // ../plugin/src/features/magic-context/compartment-chunk-embedding.ts
107
107
  var DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS = 512;
108
108
  var CHUNK_WINDOW_SAFETY_RATIO = 0.9;
109
+ var SEARCH_SCOPE_METADATA_FIELDS = [
110
+ "rowId",
111
+ "compartmentId",
112
+ "sessionId",
113
+ "projectPath",
114
+ "harness",
115
+ "windowIndex",
116
+ "windowStart",
117
+ "windowEnd",
118
+ "chunkHash",
119
+ "modelId",
120
+ "dims",
121
+ "createdAt",
122
+ "vectorBytes",
123
+ "compartmentSessionId",
124
+ "title",
125
+ "compartmentStart",
126
+ "compartmentEnd",
127
+ "startTime",
128
+ "endTime"
129
+ ];
109
130
  var MESSAGE_FTS_CHUNK_LOAD_SQL = `SELECT map.message_ordinal AS messageOrdinal, fts.role, fts.content
110
131
  FROM message_fts_rowid_map AS map
111
132
  CROSS JOIN message_history_fts AS fts
@@ -115,7 +136,7 @@ var MESSAGE_FTS_CHUNK_LOAD_SQL = `SELECT map.message_ordinal AS messageOrdinal,
115
136
  AND fts.role IN ('user', 'assistant')
116
137
  ORDER BY map.message_ordinal ASC`;
117
138
  var loadFtsRowsStatements = new WeakMap;
118
- var searchPoolCompartmentStatements = new WeakMap;
139
+ var searchPoolDates = new WeakMap;
119
140
  var existingHashStatements = new WeakMap;
120
141
  var existingHashByProjectStatements = new WeakMap;
121
142
  var deleteByCompartmentStatements = new WeakMap;
@@ -123,14 +144,15 @@ var insertEmbeddingStatements = new WeakMap;
123
144
  var renumberEmbeddingWindowStatements = new WeakMap;
124
145
  var searchRowsStatements = new WeakMap;
125
146
  var searchRowsByModelStatements = new WeakMap;
126
- var datedSearchRowsByModelStatements = new WeakMap;
127
147
  var searchPoolProbeStatements = new WeakMap;
148
+ var pendingSearchPools = new WeakMap;
128
149
  var backfillCandidateStatements = new WeakMap;
129
150
  var shadowBackfillCandidateStatements = new WeakMap;
130
151
  var DECODED_SEARCH_POOL_CACHE_MAX_BYTES = 256 * 1024 * 1024;
131
152
  var decodedSearchPools = new WeakMap;
132
153
  var decodedSearchPoolLru = new Map;
133
154
  var decodedSearchPoolBytes = 0;
155
+ var searchPoolStats = { fullRebuilds: 0, appends: 0, probes: 0, probeMs: 0, probePages: 0 };
134
156
  function getLoadFtsRowsStatement(db) {
135
157
  let stmt = loadFtsRowsStatements.get(db);
136
158
  if (!stmt) {
@@ -188,49 +210,120 @@ function getRenumberEmbeddingWindowStatement(db) {
188
210
  function getSearchPoolProbeStatement(db) {
189
211
  let stmt = searchPoolProbeStatements.get(db);
190
212
  if (!stmt) {
191
- stmt = db.prepare(`SELECT COUNT(*) AS rowCount, MAX(id) AS maxRowId
192
- FROM compartment_chunk_embeddings
193
- WHERE session_id = ? AND project_path = ? AND model_id = ?`);
213
+ stmt = db.prepare(`SELECT e.id AS rowId, e.compartment_id AS compartmentId,
214
+ e.session_id AS sessionId, e.project_path AS projectPath, e.harness AS harness,
215
+ e.window_index AS windowIndex, e.start_ordinal AS windowStart,
216
+ e.end_ordinal AS windowEnd, e.chunk_hash AS chunkHash,
217
+ e.model_id AS modelId, e.dims AS dims, e.created_at AS createdAt,
218
+ length(e.vector) AS vectorBytes,
219
+ c.session_id AS compartmentSessionId, c.title AS title,
220
+ c.start_message AS compartmentStart, c.end_message AS compartmentEnd,
221
+ start_map.message_time_ms AS startTime, end_map.message_time_ms AS endTime
222
+ FROM compartment_chunk_embeddings e
223
+ LEFT JOIN compartments c ON c.id = e.compartment_id
224
+ LEFT JOIN message_fts_rowid_map start_map
225
+ ON start_map.session_id = c.session_id AND start_map.message_ordinal = c.start_message
226
+ LEFT JOIN message_fts_rowid_map end_map
227
+ ON end_map.session_id = c.session_id AND end_map.message_ordinal = c.end_message
228
+ WHERE e.session_id = ? AND e.project_path = ? AND e.model_id = ? AND e.id > ?
229
+ ORDER BY e.id ASC LIMIT 512`);
194
230
  searchPoolProbeStatements.set(db, stmt);
195
231
  }
196
232
  return stmt;
197
233
  }
198
- function getSearchPoolCompartmentStatement(db) {
199
- let stmt = searchPoolCompartmentStatements.get(db);
200
- if (!stmt) {
201
- stmt = db.prepare(`SELECT id, title, start_message AS startOrdinal, end_message AS endOrdinal
202
- FROM compartments
203
- WHERE id IN (
204
- SELECT compartment_id FROM compartment_chunk_embeddings
205
- WHERE session_id = ? AND project_path = ? AND model_id = ?
206
- )`);
207
- searchPoolCompartmentStatements.set(db, stmt);
208
- }
209
- return stmt;
210
- }
211
- function refreshPoolCompartmentFields(db, sessionId, projectPath, modelId, rows) {
212
- const current = new Map;
213
- for (const row of getSearchPoolCompartmentStatement(db).all(sessionId, projectPath, modelId)) {
214
- current.set(row.id, row);
234
+ function sameScopeMetadata(left, right) {
235
+ for (let index = 0;index < SEARCH_SCOPE_METADATA_FIELDS.length; index++) {
236
+ const key = SEARCH_SCOPE_METADATA_FIELDS[index];
237
+ if (left[key] !== right[key])
238
+ return false;
215
239
  }
216
- let missing = false;
217
- for (const row of rows) {
218
- const compartment = current.get(row.compartmentId);
219
- if (!compartment) {
220
- missing = true;
221
- continue;
240
+ return true;
241
+ }
242
+ async function probeSearchScope(db, sessionId, projectPath, modelId, previous) {
243
+ const started = performance.now();
244
+ searchPoolStats.probes++;
245
+ const probe = {
246
+ rowCount: 0,
247
+ maxRowId: 0,
248
+ rowIdSum: 0,
249
+ metadata: previous?.metadata ?? new Map,
250
+ ids: previous?.ids ?? []
251
+ };
252
+ let copied = previous === undefined;
253
+ let oldIndex = 0;
254
+ const writable = () => {
255
+ if (!copied) {
256
+ probe.metadata = new Map(probe.metadata);
257
+ copied = true;
258
+ }
259
+ return probe.metadata;
260
+ };
261
+ await yieldSearchPool();
262
+ for (;; ) {
263
+ const rows = getSearchPoolProbeStatement(db).all(sessionId, projectPath, modelId, probe.maxRowId);
264
+ searchPoolStats.probePages++;
265
+ if (rows.length === 0) {
266
+ if (previous) {
267
+ while (oldIndex < previous.ids.length)
268
+ writable().delete(previous.ids[oldIndex++]);
269
+ }
270
+ if (copied)
271
+ probe.ids = [...probe.metadata.keys()].sort((a, b) => a - b);
272
+ searchPoolStats.probeMs += performance.now() - started;
273
+ return probe;
274
+ }
275
+ for (const row of rows) {
276
+ probe.rowCount++;
277
+ probe.maxRowId = row.rowId;
278
+ probe.rowIdSum += row.rowId;
279
+ if (previous) {
280
+ while (oldIndex < previous.ids.length && previous.ids[oldIndex] < row.rowId) {
281
+ writable().delete(previous.ids[oldIndex++]);
282
+ }
283
+ }
284
+ if (previous && previous.ids[oldIndex] === row.rowId) {
285
+ const old = previous.metadata.get(row.rowId);
286
+ if (!old || !sameScopeMetadata(old, row)) {
287
+ writable().set(row.rowId, row);
288
+ }
289
+ oldIndex++;
290
+ } else
291
+ writable().set(row.rowId, row);
222
292
  }
223
- row.title = compartment.title;
224
- row.startOrdinal = compartment.startOrdinal;
225
- row.endOrdinal = compartment.endOrdinal;
293
+ await yieldSearchPool();
294
+ }
295
+ }
296
+ function sameSearchScope(left, right) {
297
+ return left.rowCount === right.rowCount && left.maxRowId === right.maxRowId && left.rowIdSum === right.rowIdSum && (left.metadata === right.metadata || [...left.metadata].every(([id, value]) => right.metadata.get(id) === value));
298
+ }
299
+ function scopeOnlyAppended(cached, probe) {
300
+ if (probe.rowCount <= cached.rowCount)
301
+ return false;
302
+ let addedCount = 0;
303
+ let addedSum = 0;
304
+ for (const [id, fingerprint] of probe.metadata) {
305
+ if (id > cached.maxRowId) {
306
+ addedCount++;
307
+ addedSum += id;
308
+ } else if (cached.metadata.get(id) !== fingerprint)
309
+ return false;
226
310
  }
227
- return missing ? rows.filter((row) => current.has(row.compartmentId)) : rows;
311
+ return addedCount === probe.rowCount - cached.rowCount && cached.rowIdSum + addedSum === probe.rowIdSum;
312
+ }
313
+ function filterSearchPoolDates(rows, dateRange) {
314
+ if (dateRange === null)
315
+ return rows;
316
+ return rows.filter((row) => {
317
+ const compartment = searchPoolDates.get(row);
318
+ return compartment !== undefined && compartment.startTime !== null && compartment.endTime !== null && compartment.startTime <= dateRange.to && compartment.endTime >= dateRange.from;
319
+ });
228
320
  }
229
321
  function getSearchRowsStatement(db, withModel) {
230
322
  const map = withModel ? searchRowsByModelStatements : searchRowsStatements;
231
323
  let stmt = map.get(db);
232
324
  if (!stmt) {
233
- stmt = db.prepare(`SELECT e.compartment_id AS compartmentId,
325
+ stmt = db.prepare(`SELECT e.id AS rowId, e.compartment_id AS compartmentId,
326
+ start_map.message_time_ms AS startTime, end_map.message_time_ms AS endTime,
234
327
  e.session_id AS sessionId,
235
328
  c.title AS title,
236
329
  c.start_message AS compartmentStart,
@@ -243,48 +336,20 @@ function getSearchRowsStatement(db, withModel) {
243
336
  e.dims AS dims,
244
337
  e.vector AS vector
245
338
  FROM compartment_chunk_embeddings e
246
- JOIN compartments c ON c.id = e.compartment_id
339
+ JOIN compartments c ON c.id = e.compartment_id
340
+ LEFT JOIN message_fts_rowid_map start_map
341
+ ON start_map.session_id = c.session_id AND start_map.message_ordinal = c.start_message
342
+ LEFT JOIN message_fts_rowid_map end_map
343
+ ON end_map.session_id = c.session_id AND end_map.message_ordinal = c.end_message
247
344
  WHERE e.session_id = ?
248
345
  AND e.project_path = ?
249
- ${withModel ? "AND e.model_id = ?" : ""}
250
- ORDER BY e.compartment_id ASC, e.window_index ASC`);
346
+ ${withModel ? "AND e.model_id = ?" : ""}
347
+ AND e.id > ? AND e.id <= ?
348
+ ORDER BY e.id ASC LIMIT 16`);
251
349
  map.set(db, stmt);
252
350
  }
253
351
  return stmt;
254
352
  }
255
- function getDatedSearchRowsByModelStatement(db) {
256
- let statement = datedSearchRowsByModelStatements.get(db);
257
- if (!statement) {
258
- statement = db.prepare(`SELECT e.compartment_id AS compartmentId,
259
- e.session_id AS sessionId,
260
- c.title AS title,
261
- c.start_message AS compartmentStart,
262
- c.end_message AS compartmentEnd,
263
- e.window_index AS windowIndex,
264
- e.start_ordinal AS windowStart,
265
- e.end_ordinal AS windowEnd,
266
- e.chunk_hash AS chunkHash,
267
- e.model_id AS modelId,
268
- e.dims AS dims,
269
- e.vector AS vector
270
- FROM compartment_chunk_embeddings e
271
- JOIN compartments c ON c.id = e.compartment_id
272
- JOIN message_fts_rowid_map AS start_map
273
- ON start_map.session_id = c.session_id
274
- AND start_map.message_ordinal = c.start_message
275
- JOIN message_fts_rowid_map AS end_map
276
- ON end_map.session_id = c.session_id
277
- AND end_map.message_ordinal = c.end_message
278
- WHERE e.session_id = ?
279
- AND e.project_path = ?
280
- AND e.model_id = ?
281
- AND start_map.message_time_ms <= ?
282
- AND end_map.message_time_ms >= ?
283
- ORDER BY e.compartment_id ASC, e.window_index ASC`);
284
- datedSearchRowsByModelStatements.set(db, statement);
285
- }
286
- return statement;
287
- }
288
353
  function getBackfillCandidateStatement(db) {
289
354
  let stmt = backfillCandidateStatements.get(db);
290
355
  if (!stmt) {
@@ -358,22 +423,30 @@ function touchDecodedSearchPoolEntry(entry) {
358
423
  function estimateDecodedSearchPoolBytes(rows) {
359
424
  let bytes = 0;
360
425
  for (const row of rows) {
361
- bytes += row.vector.byteLength + 256 + 2 * (row.sessionId.length + row.title.length + row.chunkHash.length + row.modelId.length);
426
+ bytes += row.vector.byteLength + 384 + 2 * (row.sessionId.length + row.title.length + row.chunkHash.length + row.modelId.length);
362
427
  }
363
428
  return bytes;
364
429
  }
365
- function cacheDecodedSearchPool(pool, key, rowCount, maxRowId, rows) {
430
+ function cacheDecodedSearchPool(pool, key, probe, rows) {
366
431
  const existing = pool.get(key);
367
432
  if (existing)
368
433
  removeDecodedSearchPoolEntry(existing);
369
434
  const entry = {
370
435
  pool,
371
436
  key,
372
- rowCount,
373
- maxRowId,
437
+ ...probe,
374
438
  rows,
375
439
  byteSize: estimateDecodedSearchPoolBytes(rows)
376
440
  };
441
+ entry.byteSize += probe.ids.length * 8;
442
+ for (const metadata of probe.metadata.values()) {
443
+ entry.byteSize += 320;
444
+ for (const key of SEARCH_SCOPE_METADATA_FIELDS) {
445
+ const value = metadata[key];
446
+ if (typeof value === "string")
447
+ entry.byteSize += 2 * value.length;
448
+ }
449
+ }
377
450
  pool.set(key, entry);
378
451
  decodedSearchPoolLru.set(entry, true);
379
452
  decodedSearchPoolBytes += entry.byteSize;
@@ -384,16 +457,6 @@ function cacheDecodedSearchPool(pool, key, rowCount, maxRowId, rows) {
384
457
  removeDecodedSearchPoolEntry(oldest);
385
458
  }
386
459
  }
387
- function invalidateDecodedSearchPools(db, predicate) {
388
- const pool = decodedSearchPools.get(db);
389
- if (!pool)
390
- return;
391
- for (const [key, entry] of [...pool.entries()]) {
392
- const parsed = JSON.parse(key);
393
- if (predicate(parsed))
394
- removeDecodedSearchPoolEntry(entry);
395
- }
396
- }
397
460
  function isFinitePositiveInteger(value) {
398
461
  return typeof value === "number" && Number.isFinite(value) && value > 0;
399
462
  }
@@ -692,58 +755,104 @@ function replaceCompartmentChunkEmbeddings(db, rows, windowSourceKey) {
692
755
  recordChunkWindowSource(db, compartmentId, windowSourceKey, rows.map((row) => [row.window.windowIndex, row.window.chunkHash]));
693
756
  }
694
757
  }).immediate();
695
- invalidateDecodedSearchPools(db, ([sessionId, projectPath, cachedModelId]) => sessionId === rows[0].sessionId && projectPath === rows[0].projectPath && cachedModelId === modelId);
696
758
  }
697
- function loadCompartmentChunkEmbeddingsForSearch(db, sessionId, projectPath, modelId, dateRange = null) {
759
+ var yieldSearchPool = () => new Promise((resolve) => setImmediate(resolve));
760
+ function searchPoolInTransaction(db) {
761
+ const connection = db;
762
+ return connection.inTransaction === true || connection.isTransaction === true;
763
+ }
764
+ async function refreshDecodedSearchPool(db, sessionId, projectPath, modelId) {
765
+ const key = searchPoolKey(sessionId, projectPath, modelId);
766
+ const pool = getDecodedSearchPool(db);
767
+ for (;; ) {
768
+ const inTransaction = searchPoolInTransaction(db);
769
+ const previous = pool.get(key);
770
+ const probe = await probeSearchScope(db, sessionId, projectPath, modelId, previous);
771
+ const rowCount = probe.rowCount;
772
+ const maxRowId = probe.maxRowId;
773
+ const cached = pool.get(key);
774
+ if (!inTransaction && cached && sameSearchScope(cached, probe)) {
775
+ touchDecodedSearchPoolEntry(cached);
776
+ return cached.rows;
777
+ }
778
+ const append = !inTransaction && cached && scopeOnlyAppended(cached, probe);
779
+ if (append)
780
+ searchPoolStats.appends++;
781
+ else
782
+ searchPoolStats.fullRebuilds++;
783
+ let afterId = append ? cached.maxRowId : 0;
784
+ const added = [];
785
+ let appendedCount = 0;
786
+ await yieldSearchPool();
787
+ for (;; ) {
788
+ const rows = getSearchRowsStatement(db, true).all(sessionId, projectPath, modelId, afterId, maxRowId);
789
+ if (rows.length === 0)
790
+ break;
791
+ afterId = rows[rows.length - 1].rowId;
792
+ appendedCount += rows.length;
793
+ for (const row of rows) {
794
+ if (typeof row.compartmentId !== "number" || typeof row.sessionId !== "string" || typeof row.title !== "string" || typeof row.compartmentStart !== "number" || typeof row.compartmentEnd !== "number" || typeof row.windowIndex !== "number" || typeof row.windowStart !== "number" || typeof row.windowEnd !== "number" || typeof row.chunkHash !== "string" || typeof row.modelId !== "string" || typeof row.dims !== "number" || !(row.vector instanceof Uint8Array || row.vector instanceof ArrayBuffer))
795
+ continue;
796
+ added.push({
797
+ compartmentId: row.compartmentId,
798
+ sessionId: row.sessionId,
799
+ title: row.title,
800
+ startOrdinal: row.compartmentStart,
801
+ endOrdinal: row.compartmentEnd,
802
+ windowIndex: row.windowIndex,
803
+ windowStartOrdinal: row.windowStart,
804
+ windowEndOrdinal: row.windowEnd,
805
+ chunkHash: row.chunkHash,
806
+ modelId: row.modelId,
807
+ dims: row.dims,
808
+ vector: toFloat32Array(row.vector)
809
+ });
810
+ searchPoolDates.set(added[added.length - 1], {
811
+ startTime: row.startTime,
812
+ endTime: row.endTime
813
+ });
814
+ }
815
+ await yieldSearchPool();
816
+ }
817
+ const endProbe = await probeSearchScope(db, sessionId, projectPath, modelId, probe);
818
+ if (!sameSearchScope(probe, endProbe) || searchPoolInTransaction(db) !== inTransaction) {
819
+ continue;
820
+ }
821
+ if (append && appendedCount !== rowCount - cached.rowCount) {
822
+ removeDecodedSearchPoolEntry(cached);
823
+ continue;
824
+ }
825
+ const decoded = append ? cached.rows.concat(added) : added;
826
+ decoded.sort((a, b) => a.compartmentId - b.compartmentId || a.windowIndex - b.windowIndex);
827
+ if (!inTransaction)
828
+ cacheDecodedSearchPool(pool, key, probe, decoded);
829
+ return decoded;
830
+ }
831
+ }
832
+ async function loadCompartmentChunkEmbeddingsForSearch(db, sessionId, projectPath, modelId, dateRange = null) {
698
833
  if (!modelId) {
699
834
  throw new Error("loadCompartmentChunkEmbeddingsForSearch requires a current model id");
700
835
  }
701
- if (dateRange !== null) {
702
- const rows = getDatedSearchRowsByModelStatement(db).all(sessionId, projectPath, modelId, dateRange.to, dateRange.from);
703
- return rows.filter((row) => typeof row.compartmentId === "number" && typeof row.sessionId === "string" && typeof row.title === "string" && typeof row.compartmentStart === "number" && typeof row.compartmentEnd === "number" && typeof row.windowIndex === "number" && typeof row.windowStart === "number" && typeof row.windowEnd === "number" && typeof row.chunkHash === "string" && typeof row.modelId === "string" && typeof row.dims === "number" && (row.vector instanceof Uint8Array || row.vector instanceof ArrayBuffer)).map((row) => ({
704
- compartmentId: row.compartmentId,
705
- sessionId: row.sessionId,
706
- title: row.title,
707
- startOrdinal: row.compartmentStart,
708
- endOrdinal: row.compartmentEnd,
709
- windowIndex: row.windowIndex,
710
- windowStartOrdinal: row.windowStart,
711
- windowEndOrdinal: row.windowEnd,
712
- chunkHash: row.chunkHash,
713
- modelId: row.modelId,
714
- dims: row.dims,
715
- vector: toFloat32Array(row.vector)
716
- }));
717
- }
718
836
  const key = searchPoolKey(sessionId, projectPath, modelId);
719
- const pool = getDecodedSearchPool(db);
720
- const probe = getSearchPoolProbeStatement(db).get(sessionId, projectPath, modelId);
721
- const rowCount = typeof probe?.rowCount === "number" ? probe.rowCount : 0;
722
- const maxRowId = typeof probe?.maxRowId === "number" ? probe.maxRowId : 0;
723
- const cached = pool.get(key);
724
- if (cached && cached.rowCount === rowCount && cached.maxRowId === maxRowId) {
725
- touchDecodedSearchPoolEntry(cached);
726
- return refreshPoolCompartmentFields(db, sessionId, projectPath, modelId, cached.rows);
837
+ let pending = pendingSearchPools.get(db);
838
+ if (!pending) {
839
+ pending = new Map;
840
+ pendingSearchPools.set(db, pending);
841
+ }
842
+ for (;; ) {
843
+ while (pending.has(key))
844
+ await pending.get(key);
845
+ const operation = refreshDecodedSearchPool(db, sessionId, projectPath, modelId);
846
+ const completion = operation.then(() => {});
847
+ pending.set(key, completion);
848
+ try {
849
+ const rows = await operation;
850
+ return filterSearchPoolDates(rows, dateRange);
851
+ } finally {
852
+ pending.delete(key);
853
+ completion.catch(() => {});
854
+ }
727
855
  }
728
- if (cached)
729
- removeDecodedSearchPoolEntry(cached);
730
- const rows = getSearchRowsStatement(db, true).all(sessionId, projectPath, modelId);
731
- const decodedRows = rows.filter((row) => typeof row.compartmentId === "number" && typeof row.sessionId === "string" && typeof row.title === "string" && typeof row.compartmentStart === "number" && typeof row.compartmentEnd === "number" && typeof row.windowIndex === "number" && typeof row.windowStart === "number" && typeof row.windowEnd === "number" && typeof row.chunkHash === "string" && typeof row.modelId === "string" && typeof row.dims === "number" && (row.vector instanceof Uint8Array || row.vector instanceof ArrayBuffer)).map((row) => ({
732
- compartmentId: row.compartmentId,
733
- sessionId: row.sessionId,
734
- title: row.title,
735
- startOrdinal: row.compartmentStart,
736
- endOrdinal: row.compartmentEnd,
737
- windowIndex: row.windowIndex,
738
- windowStartOrdinal: row.windowStart,
739
- windowEndOrdinal: row.windowEnd,
740
- chunkHash: row.chunkHash,
741
- modelId: row.modelId,
742
- dims: row.dims,
743
- vector: toFloat32Array(row.vector)
744
- }));
745
- cacheDecodedSearchPool(pool, key, rowCount, maxRowId, decodedRows);
746
- return decodedRows;
747
856
  }
748
857
  function loadUnembeddedShadowChunkCandidates(db, projectPath, primaryModelId, shadowModelId, limit, shadowMaxInputTokens) {
749
858
  const rows = getShadowBackfillCandidateStatement(db).all(projectPath, projectPath, primaryModelId);
@@ -928,7 +1037,6 @@ function renumberOneBasedChunkWindows(db, candidate, projectPath, modelId, windo
928
1037
  recordChunkWindowSource(db, candidate.id, sourceKey, windows.map((window) => [window.windowIndex, window.chunkHash]));
929
1038
  }
930
1039
  }).immediate();
931
- invalidateDecodedSearchPools(db, ([sessionId, cachedProjectPath, cachedModelId]) => sessionId === candidate.sessionId && cachedProjectPath === projectPath && cachedModelId === modelId);
932
1040
  }
933
1041
  function classifyChunkCoverageDefect(db, projectPath, modelId, candidate, maxInputTokens) {
934
1042
  const mappedText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage);
@@ -1057,4 +1165,4 @@ async function countUnembeddedSessionCompartmentsPolite(db, projectPath, session
1057
1165
  return count;
1058
1166
  }
1059
1167
 
1060
- export { CHUNK_WINDOW_SAFETY_RATIO, normalizeCompartmentChunkMaxInputTokens, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, loadCompartmentChunkEmbeddingsForSearch, loadUnembeddedShadowChunkCandidates, loadUnembeddedCompartmentChunkCandidatesPolite, deleteChunkEmbedBackoffForSession, recordChunkEmbedBackoff, chunkWindowSourceKey, loadUnembeddedSessionChunkCandidatesPolite, countSessionCompartmentEmbedCoverage, countSessionCompartmentEmbedCoveragePolite, countUnembeddedSessionCompartmentsPolite };
1168
+ export { DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS, CHUNK_WINDOW_SAFETY_RATIO, normalizeCompartmentChunkMaxInputTokens, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, loadCompartmentChunkEmbeddingsForSearch, loadUnembeddedShadowChunkCandidates, loadUnembeddedCompartmentChunkCandidatesPolite, deleteChunkEmbedBackoffForSession, recordChunkEmbedBackoff, chunkWindowSourceKey, loadUnembeddedSessionChunkCandidatesPolite, countSessionCompartmentEmbedCoverage, countSessionCompartmentEmbedCoveragePolite, countUnembeddedSessionCompartmentsPolite };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  log2
3
- } from "./index-gycf3sp7.js";
3
+ } from "./index-7bqrfyny.js";
4
4
 
5
5
  // ../plugin/src/shared/rpc-utils.ts
6
6
  import { execFile, execFileSync } from "node:child_process";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  log2
3
- } from "./index-gycf3sp7.js";
3
+ } from "./index-7bqrfyny.js";
4
4
 
5
5
  // ../plugin/src/shared/write-transaction-timing.ts
6
6
  var SLOW_WRITE_TRANSACTION_THRESHOLD_MS = 1000;
@@ -4,7 +4,7 @@ import {
4
4
  } from "./index-asrxgdt4.js";
5
5
  import {
6
6
  logSlowWriteTransaction
7
- } from "./index-43zqh10z.js";
7
+ } from "./index-d4dt19md.js";
8
8
 
9
9
  // ../plugin/src/shared/project-directory-key.ts
10
10
  import path from "node:path";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  estimateTokens
3
- } from "./index-4pxydwvg.js";
3
+ } from "./index-g4jf772p.js";
4
4
  import {
5
5
  getHarness2
6
6
  } from "./index-0h2mkab2.js";
7
7
  import {
8
8
  sessionLog2
9
- } from "./index-gycf3sp7.js";
9
+ } from "./index-7bqrfyny.js";
10
10
  import {
11
11
  getTagIdentityWriteGeneration2,
12
12
  getSqliteDatabasePath2
@@ -15,7 +15,7 @@ import {
15
15
  jsonHashSink,
16
16
  tagOrderConstraintIndex,
17
17
  tagIdentityRevisionKey
18
- } from "./index-ttxsmaj5.js";
18
+ } from "./index-jrap43gc.js";
19
19
  import {
20
20
  DEFAULT_PROTECTED_TOOLS,
21
21
  normalizeProtectedToolName,
@@ -2533,6 +2533,19 @@ function insertTag2(db, sessionId, messageId, type, byteSize, tagNumber, reasoni
2533
2533
  function updateTagStatus2(db, sessionId, tagId, status) {
2534
2534
  getUpdateTagStatusStatement(db).run(status, sessionId, tagId);
2535
2535
  }
2536
+ var droppedTagStatements = new WeakMap;
2537
+ function markTagDropped2(db, sessionId, tagId, mode) {
2538
+ if (!mode) {
2539
+ updateTagStatus2(db, sessionId, tagId, "dropped");
2540
+ return;
2541
+ }
2542
+ let statement = droppedTagStatements.get(db);
2543
+ if (!statement) {
2544
+ statement = db.prepare("UPDATE tags SET status = ?, drop_mode = ? WHERE session_id = ? AND tag_number = ?");
2545
+ droppedTagStatements.set(db, statement);
2546
+ }
2547
+ statement.run("dropped", mode, sessionId, tagId);
2548
+ }
2536
2549
  var inertWhitespaceStatements = new WeakMap;
2537
2550
  var inertWhitespaceByNumberStatements = new WeakMap;
2538
2551
  function getInertWhitespaceAssistantTagsByNumbers2(db, sessionId, tagNumbers) {
@@ -3197,7 +3210,7 @@ function getNewestToolTagNumbers2(db, sessionId, limit) {
3197
3210
  let statement = newestToolTagNumberStatements.get(db);
3198
3211
  if (!statement) {
3199
3212
  statement = db.prepare(`SELECT tag_number FROM tags
3200
- WHERE session_id = ? AND type = 'tool'
3213
+ WHERE session_id = ? AND +type = 'tool'
3201
3214
  AND typeof(message_id) = 'text'
3202
3215
  AND typeof(status) = 'text'
3203
3216
  AND typeof(byte_size) IN ('integer', 'real')
@@ -3367,4 +3380,4 @@ function deleteToolTagsByOwner(db, sessionId, ownerMsgId) {
3367
3380
  return getDeleteToolTagsByOwnerStatement(db).all(sessionId, ownerMsgId).length;
3368
3381
  }
3369
3382
 
3370
- export { UNKNOWN_FIT_RATIO, resolveDecisionCalibration, hasMeasuredDecisionCalibration, providerMass, localBudget, calibrationForModelKey, historyLocalBudget, adoptedProtectedToolsPolicy, protectedToolTagNumbers, protectedToolTokenCount, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, rememberCurrentToolOutputCount, currentReclaimableToolOutputCount, isRecord, TEXT_TAG_IDENTITY_MARKER, PI_FALLBACK_PREFIXES_JSON, contentTagOwnerMessageId, TailHygieneJsonMemo, piJsonHash, estimateImageTokensFromDataUrl, estimateToolAttachmentImageTokens, providerVisiblePart, providerVisibleMessage, TODO_STATUSES, TODO_PRIORITIES, TITLE_DONE_STATUSES, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, compareMeasuredTailPrefix, formatTailHygienePrefixMismatch, freezeTailHygieneMeasurement, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, measureEmergencyTag, queuePendingOp, queuePendingDropForUnchangedTag, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, updateTagByteSize2, getRecentTagOwnerMessageIds2, getActiveTagTokenAggregate2, AGE_RECLAIM_MIN_TOKENS2, getOldestActiveUnprotectedToolTags2, getActiveToolTagsForAgeReclaim2, getTriggerTagTokenUpperBound2, getActiveTagTokenTotalsByMessage2, updateTagInputByteSize2, updateTagTokenCount2, getPersistedToolTagAccounting2, getAllStatusTagTokenTotalsFlat2, getReasoningTokenEstimatesByMessage2, tryGetReasoningTokenEstimatesByMessage2, getMaxTagNumberByOwnerMessage2, scanTagOwnerSummary2, scanTagOwnerDelta2, updateTagInputTokenCount2, tagTokenCountIsNull2, backfillTagTokenCounts2, insertTag2, updateTagStatus2, getInertWhitespaceAssistantTagsByNumbers2, updateTagDropMode2, updateCavemanDepth2, updateTagMessageId2, hasPiFallbackMessageTags2, findAdoptableFallbackTags2, adoptFallbackTagMessageId2, foldShrunkPartTags2, hasPiFallbackToolOwnerTags2, findPiFallbackToolOwnerTags2, PiTagIdentityConflictError2, getPiMessageTagCandidates2, findPiTagIdentityConflict2, adoptPiFallbackToolOwnerTag2, adoptPiFallbackMessageTag2, markTagsCompactedByMessageIds2, deleteTagsByMessageId2, getMaxTagNumberBySession2, getTagNumberByMessageId2, getAssignableTagNumberByMessageId2, getMinMessageTagNumberForRawId2, deriveTagLoadFloor2, TAG_SELECT_COLUMNS2, getTagsBySession2, getActiveTagsBySession2, getTagsForPendingOperations2, getTagsByNumbers2, getNewestToolTagNumbers2, getDroppedTagsByNumbers2, getMaxDroppedTagNumber2, getTagById2, getTopNBySize2, getToolTagNumberByOwner2, getNullOwnerToolTag2, adoptNullOwnerToolTag2, getCandidateToolOwners2, pickNearestPriorOwner2 };
3383
+ export { UNKNOWN_FIT_RATIO, resolveDecisionCalibration, hasMeasuredDecisionCalibration, providerMass, localBudget, calibrationForModelKey, historyLocalBudget, adoptedProtectedToolsPolicy, protectedToolTagNumbers, protectedToolTokenCount, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, rememberCurrentToolOutputCount, currentReclaimableToolOutputCount, isRecord, TEXT_TAG_IDENTITY_MARKER, PI_FALLBACK_PREFIXES_JSON, contentTagOwnerMessageId, TailHygieneJsonMemo, piJsonHash, estimateImageTokensFromDataUrl, estimateToolAttachmentImageTokens, providerVisiblePart, providerVisibleMessage, TODO_STATUSES, TODO_PRIORITIES, TITLE_DONE_STATUSES, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, compareMeasuredTailPrefix, formatTailHygienePrefixMismatch, freezeTailHygieneMeasurement, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, measureEmergencyTag, queuePendingOp, queuePendingDropForUnchangedTag, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, updateTagByteSize2, getRecentTagOwnerMessageIds2, getActiveTagTokenAggregate2, AGE_RECLAIM_MIN_TOKENS2, getOldestActiveUnprotectedToolTags2, getActiveToolTagsForAgeReclaim2, getTriggerTagTokenUpperBound2, getActiveTagTokenTotalsByMessage2, updateTagInputByteSize2, updateTagTokenCount2, getPersistedToolTagAccounting2, getAllStatusTagTokenTotalsFlat2, getReasoningTokenEstimatesByMessage2, tryGetReasoningTokenEstimatesByMessage2, getMaxTagNumberByOwnerMessage2, scanTagOwnerSummary2, scanTagOwnerDelta2, updateTagInputTokenCount2, tagTokenCountIsNull2, backfillTagTokenCounts2, insertTag2, updateTagStatus2, markTagDropped2, getInertWhitespaceAssistantTagsByNumbers2, updateTagDropMode2, updateCavemanDepth2, updateTagMessageId2, hasPiFallbackMessageTags2, findAdoptableFallbackTags2, adoptFallbackTagMessageId2, foldShrunkPartTags2, hasPiFallbackToolOwnerTags2, findPiFallbackToolOwnerTags2, PiTagIdentityConflictError2, getPiMessageTagCandidates2, findPiTagIdentityConflict2, adoptPiFallbackToolOwnerTag2, adoptPiFallbackMessageTag2, markTagsCompactedByMessageIds2, deleteTagsByMessageId2, getMaxTagNumberBySession2, getTagNumberByMessageId2, getAssignableTagNumberByMessageId2, getMinMessageTagNumberForRawId2, deriveTagLoadFloor2, TAG_SELECT_COLUMNS2, getTagsBySession2, getActiveTagsBySession2, getTagsForPendingOperations2, getTagsByNumbers2, getNewestToolTagNumbers2, getDroppedTagsByNumbers2, getMaxDroppedTagNumber2, getTagById2, getTopNBySize2, getToolTagNumberByOwner2, getNullOwnerToolTag2, adoptNullOwnerToolTag2, getCandidateToolOwners2, pickNearestPriorOwner2 };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  log2
3
- } from "./index-gycf3sp7.js";
3
+ } from "./index-7bqrfyny.js";
4
4
 
5
5
  // ../plugin/src/shared/safe-notification-target.ts
6
6
  var DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;