@cortexkit/pi-magic-context 0.49.20 → 0.49.22
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/dist/auto-search-worker.js +6 -6
- package/dist/chunk-embedding-write-worker.js +9 -9
- package/dist/{compaction-marker-candidates-fnm47jat.js → compaction-marker-candidates-p1kqkqhq.js} +2 -2
- package/dist/compaction-marker-candidates-worker.js +2 -2
- package/dist/{compartment-chunk-embedding-81qesfjs.js → compartment-chunk-embedding-y01m95c2.js} +5 -5
- package/dist/{embedding-backfill-56e871c6.js → embedding-backfill-2vh6m3bg.js} +11 -11
- package/dist/embedding-worker-process.js +1 -1
- package/dist/embedding-worker.js +4 -4
- package/dist/{index-dzem6gn9.js → index-29nw7n1r.js} +1 -1
- package/dist/{index-jt0g3hn0.js → index-2bx7ge3x.js} +60 -18
- package/dist/{index-hws5f0z9.js → index-2qtx0q6h.js} +213 -4
- package/dist/{index-5vgt1zeh.js → index-3c3ztwgc.js} +2 -2
- package/dist/{index-rgfb753z.js → index-579m1751.js} +2 -2
- package/dist/{index-kqb3d8bs.js → index-5j6vwg4z.js} +148 -11
- package/dist/{index-6kb2xpw7.js → index-6wdwv3a6.js} +1 -1
- package/dist/{index-rfyvax95.js → index-at6py2k3.js} +1 -1
- package/dist/{index-bxmf4dhr.js → index-ccanzg8p.js} +2367 -1243
- package/dist/{index-mtvvhcw4.js → index-dbgg6hsf.js} +24 -10
- package/dist/{index-af9t637y.js → index-ftvm2acc.js} +121 -38
- package/dist/{index-zhwwp8zz.js → index-gqjxy2p7.js} +14 -4
- package/dist/{index-jxjr7kz9.js → index-gwxaz0z5.js} +2 -4
- package/dist/{index-p63nwn5v.js → index-hxp6q5f8.js} +1 -1
- package/dist/{index-qerzchrs.js → index-j3pz3a1b.js} +1 -1
- package/dist/{index-bttctq07.js → index-n8e5e9fp.js} +6 -3
- package/dist/{index-b8am7tns.js → index-pe5gz5c4.js} +4 -4
- package/dist/{index-tb3d9trm.js → index-st4gwt64.js} +1 -1
- package/dist/{index-5n5zxs8e.js → index-vx6f7wff.js} +2 -2
- package/dist/{index-v2epyzbm.js → index-w1twp2kp.js} +9 -7
- package/dist/{index-vdy273xw.js → index-wgmhk91m.js} +10 -4
- package/dist/{index-e19qtjj0.js → index-wqpjhx1p.js} +35 -4
- package/dist/index.js +239 -209
- package/dist/{message-fts-rowid-map-bpexnsdj.js → message-fts-rowid-map-59y476bk.js} +3 -3
- package/dist/{message-index-mvag9crh.js → message-index-3snxf11x.js} +9 -9
- package/dist/{message-index-bounded-d4r3weh0.js → message-index-bounded-4ngt600v.js} +9 -9
- package/dist/{message-time-backfill-kc10yrcj.js → message-time-backfill-e3r8ddh1.js} +1 -1
- package/dist/migration-worker.js +6 -6
- package/dist/{project-embedding-registry-cfrg952x.js → project-embedding-registry-hfyzs654.js} +10 -10
- package/dist/raw-ordinal-warmup-worker.js +8 -8
- package/dist/{read-session-chunk-7g4zvpd8.js → read-session-chunk-5dmc77q2.js} +5 -5
- package/dist/{read-session-raw-0fsjh10f.js → read-session-raw-yxv2fv34.js} +2 -2
- package/dist/{search-archive-qbhp7e89.js → search-archive-3daj5ttc.js} +6 -6
- package/dist/{search-hp4g3g9v.js → search-jhfh3tsj.js} +17 -17
- package/dist/{sqlite-d67n6dtr.js → sqlite-v89bj0yy.js} +7 -1
- package/dist/{storage-memory-9g882j7a.js → storage-memory-0ndn65fm.js} +2 -2
- package/dist/{storage-tags-m2qcp1g2.js → storage-tags-r48vxthe.js} +2 -2
- package/dist/subagent-entry.js +22 -21
- package/dist/tag-snapshot-worker-pi.js +8 -8
- package/package.json +5 -2
|
@@ -174,6 +174,177 @@ function topLevelCommaSegments(text) {
|
|
|
174
174
|
function getTagIdentityWriteGeneration2() {
|
|
175
175
|
return tagIdentityWriteGeneration;
|
|
176
176
|
}
|
|
177
|
+
var busyTimeoutStates = new WeakMap;
|
|
178
|
+
var BUSY_TIMEOUT_QUERY = /^\s*PRAGMA\s+(?:(?:\w+|"[^"]+"|`[^`]+`|\[[^\]]+\])\s*\.\s*)?(?:busy_timeout|"busy_timeout"|`busy_timeout`|\[busy_timeout\])\s*;?\s*$/i;
|
|
179
|
+
var BUSY_TIMEOUT_SETTER = /^\s*PRAGMA\s+(?:(?:\w+|"[^"]+"|`[^`]+`|\[[^\]]+\])\s*\.\s*)?(?:busy_timeout|"busy_timeout"|`busy_timeout`|\[busy_timeout\])\s*(?==|\()/i;
|
|
180
|
+
function literalBusyTimeout(sql) {
|
|
181
|
+
const head = BUSY_TIMEOUT_SETTER.exec(sql);
|
|
182
|
+
if (!head)
|
|
183
|
+
return;
|
|
184
|
+
const match = /^(?:=\s*|\(\s*)(?:'(-?\d+)'|"(-?\d+)"|(-?\d+))\s*\)?\s*;?\s*$/.exec(sql.slice(head[0].length));
|
|
185
|
+
if (!match)
|
|
186
|
+
return;
|
|
187
|
+
const value = Number(match[1] ?? match[2] ?? match[3]);
|
|
188
|
+
return value < 0 ? 0 : value <= 2147483647 ? value : undefined;
|
|
189
|
+
}
|
|
190
|
+
function busyTimeoutStatements(sql) {
|
|
191
|
+
const statements = [];
|
|
192
|
+
let statement = "";
|
|
193
|
+
let quote = "";
|
|
194
|
+
for (let i = 0;i < sql.length; i++) {
|
|
195
|
+
const char = sql[i];
|
|
196
|
+
if (quote) {
|
|
197
|
+
statement += char;
|
|
198
|
+
if (char === quote) {
|
|
199
|
+
if (sql[i + 1] === quote)
|
|
200
|
+
statement += sql[++i];
|
|
201
|
+
else
|
|
202
|
+
quote = "";
|
|
203
|
+
}
|
|
204
|
+
} else if (char === "'" || char === '"' || char === "`" || char === "[") {
|
|
205
|
+
quote = char === "[" ? "]" : char;
|
|
206
|
+
statement += char;
|
|
207
|
+
} else if (char === "-" && sql[i + 1] === "-") {
|
|
208
|
+
while (i + 1 < sql.length && sql[i + 1] !== `
|
|
209
|
+
`)
|
|
210
|
+
i++;
|
|
211
|
+
statement += " ";
|
|
212
|
+
} else if (char === "/" && sql[i + 1] === "*") {
|
|
213
|
+
i += 2;
|
|
214
|
+
while (i < sql.length && !(sql[i] === "*" && sql[i + 1] === "/"))
|
|
215
|
+
i++;
|
|
216
|
+
i++;
|
|
217
|
+
statement += " ";
|
|
218
|
+
} else if (char === ";") {
|
|
219
|
+
statements.push(statement);
|
|
220
|
+
statement = "";
|
|
221
|
+
} else
|
|
222
|
+
statement += char;
|
|
223
|
+
}
|
|
224
|
+
statements.push(statement);
|
|
225
|
+
return statements.filter((part) => part.trim().length > 0);
|
|
226
|
+
}
|
|
227
|
+
function installNativeDeadlineRouting(db) {
|
|
228
|
+
const rawExec = db.exec.bind(db);
|
|
229
|
+
const rawPrepare = db.prepare.bind(db);
|
|
230
|
+
const readTimeout = () => {
|
|
231
|
+
const statement = rawPrepare("PRAGMA busy_timeout");
|
|
232
|
+
try {
|
|
233
|
+
return Object.values(statement.get())[0];
|
|
234
|
+
} finally {
|
|
235
|
+
statement.finalize?.();
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const timeoutState = { current: readTimeout() };
|
|
239
|
+
busyTimeoutStates.set(db, timeoutState);
|
|
240
|
+
const setBusyTimeout = (timeout) => {
|
|
241
|
+
rawExec(`PRAGMA busy_timeout=${timeout}`);
|
|
242
|
+
timeoutState.current = timeout;
|
|
243
|
+
};
|
|
244
|
+
const withinDeadline = (operation) => {
|
|
245
|
+
const deadline = nativeWaitScope?.getStore();
|
|
246
|
+
if (!deadline?.active || !deadline.remainingMs)
|
|
247
|
+
return operation();
|
|
248
|
+
const remaining = deadline.remainingMs();
|
|
249
|
+
if (remaining === Infinity)
|
|
250
|
+
return operation();
|
|
251
|
+
const previous = timeoutState.current;
|
|
252
|
+
const timeout = Math.min(previous, Math.max(0, Math.floor(remaining)));
|
|
253
|
+
if (timeout === previous)
|
|
254
|
+
return operation();
|
|
255
|
+
setBusyTimeout(timeout);
|
|
256
|
+
try {
|
|
257
|
+
return operation();
|
|
258
|
+
} finally {
|
|
259
|
+
setBusyTimeout(previous);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
Object.defineProperty(db, "exec", {
|
|
263
|
+
configurable: true,
|
|
264
|
+
writable: true,
|
|
265
|
+
value: (sql) => {
|
|
266
|
+
const parts = /\bbusy_timeout\b/i.test(sql) ? busyTimeoutStatements(sql) : [];
|
|
267
|
+
if (parts.length === 1 && BUSY_TIMEOUT_QUERY.test(parts[0]))
|
|
268
|
+
return rawExec(sql);
|
|
269
|
+
const singleSetter = parts.length === 1 && BUSY_TIMEOUT_SETTER.test(parts[0]);
|
|
270
|
+
const setting = singleSetter ? literalBusyTimeout(parts[0]) : undefined;
|
|
271
|
+
if (singleSetter) {
|
|
272
|
+
const result = rawExec(sql);
|
|
273
|
+
timeoutState.current = setting ?? readTimeout();
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
if (!/\bbusy_timeout\b/i.test(sql))
|
|
277
|
+
return withinDeadline(() => rawExec(sql));
|
|
278
|
+
const setters = parts.filter((part) => BUSY_TIMEOUT_SETTER.test(part));
|
|
279
|
+
return withinDeadline(() => {
|
|
280
|
+
try {
|
|
281
|
+
const result = rawExec(sql);
|
|
282
|
+
if (setters.length)
|
|
283
|
+
timeoutState.current = literalBusyTimeout(setters[setters.length - 1]) ?? readTimeout();
|
|
284
|
+
return result;
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (setters.length)
|
|
287
|
+
timeoutState.current = readTimeout();
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
const nativePrepare = (sql) => BUSY_TIMEOUT_QUERY.test(sql) || BUSY_TIMEOUT_SETTER.test(sql) ? rawPrepare(sql) : withinDeadline(() => rawPrepare(sql));
|
|
294
|
+
Object.defineProperty(db, "prepare", {
|
|
295
|
+
configurable: true,
|
|
296
|
+
writable: true,
|
|
297
|
+
value: (sql) => {
|
|
298
|
+
const statement = nativePrepare(sql);
|
|
299
|
+
const normalized = /\bbusy_timeout\b/i.test(sql) ? busyTimeoutStatements(sql)[0] ?? sql : sql;
|
|
300
|
+
const setting = literalBusyTimeout(normalized);
|
|
301
|
+
const timeoutSetter = BUSY_TIMEOUT_SETTER.test(normalized);
|
|
302
|
+
const timeoutQuery = BUSY_TIMEOUT_QUERY.test(normalized);
|
|
303
|
+
if (timeoutSetter)
|
|
304
|
+
timeoutState.current = setting ?? readTimeout();
|
|
305
|
+
for (const method of ["run", "get", "all", "values"]) {
|
|
306
|
+
const execute = statement[method]?.bind(statement);
|
|
307
|
+
if (!execute)
|
|
308
|
+
continue;
|
|
309
|
+
Object.defineProperty(statement, method, {
|
|
310
|
+
configurable: true,
|
|
311
|
+
value: (...args) => {
|
|
312
|
+
if (timeoutQuery)
|
|
313
|
+
return execute(...args);
|
|
314
|
+
if (!timeoutSetter)
|
|
315
|
+
return withinDeadline(() => execute(...args));
|
|
316
|
+
const result = execute(...args);
|
|
317
|
+
timeoutState.current = readTimeout();
|
|
318
|
+
return result;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (typeof statement.iterate === "function") {
|
|
323
|
+
const iterate = statement.iterate.bind(statement);
|
|
324
|
+
Object.defineProperty(statement, "iterate", {
|
|
325
|
+
configurable: true,
|
|
326
|
+
value: (...args) => {
|
|
327
|
+
const iterator = !timeoutSetter && !timeoutQuery ? withinDeadline(() => iterate(...args)) : iterate(...args);
|
|
328
|
+
const next = iterator.next.bind(iterator);
|
|
329
|
+
if (timeoutSetter)
|
|
330
|
+
timeoutState.current = readTimeout();
|
|
331
|
+
iterator.next = () => {
|
|
332
|
+
if (timeoutQuery)
|
|
333
|
+
return next();
|
|
334
|
+
if (!timeoutSetter)
|
|
335
|
+
return withinDeadline(next);
|
|
336
|
+
const result = next();
|
|
337
|
+
timeoutState.current = readTimeout();
|
|
338
|
+
return result;
|
|
339
|
+
};
|
|
340
|
+
return iterator;
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
return statement;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
}
|
|
177
348
|
function installTransactionRouting(db, readonly) {
|
|
178
349
|
const nativeExec = db.exec.bind(db);
|
|
179
350
|
Object.defineProperty(db, "exec", {
|
|
@@ -311,7 +482,7 @@ function wrapRemainingTagWriteForms(statement) {
|
|
|
311
482
|
});
|
|
312
483
|
}
|
|
313
484
|
}
|
|
314
|
-
function trackSqliteConnection(db, filename, options) {
|
|
485
|
+
function trackSqliteConnection(db, filename, options, turnDeadlines = false) {
|
|
315
486
|
const originalClose = db.close.bind(db);
|
|
316
487
|
const sequence = nextSqliteConnectionSequence++;
|
|
317
488
|
const metadata = {
|
|
@@ -319,6 +490,8 @@ function trackSqliteConnection(db, filename, options) {
|
|
|
319
490
|
filename: typeof filename === "string" ? filename : Buffer.isBuffer(filename) ? "<buffer>" : ":memory:",
|
|
320
491
|
readonly: Boolean(options) && typeof options === "object" && (options.readonly === true || options.readOnly === true)
|
|
321
492
|
};
|
|
493
|
+
if (turnDeadlines)
|
|
494
|
+
installNativeDeadlineRouting(db);
|
|
322
495
|
installTransactionRouting(db, metadata.readonly);
|
|
323
496
|
Object.defineProperty(db, "close", {
|
|
324
497
|
configurable: true,
|
|
@@ -371,6 +544,12 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
371
544
|
return NodeSqliteDatabase;
|
|
372
545
|
}
|
|
373
546
|
var Database2 = TrackedDatabase;
|
|
547
|
+
function createSqliteTurnDatabase2(filename, options) {
|
|
548
|
+
return trackSqliteConnection(new DatabaseImpl(filename, options), filename, options, true);
|
|
549
|
+
}
|
|
550
|
+
function hasSqliteTurnDeadlineRouting2(db) {
|
|
551
|
+
return busyTimeoutStates.has(db);
|
|
552
|
+
}
|
|
374
553
|
function getSqliteDatabasePath2(db) {
|
|
375
554
|
for (const connection of trackedSqliteConnections.values()) {
|
|
376
555
|
if (connection.reference.deref() === db) {
|
|
@@ -390,6 +569,11 @@ function pragmaValue(db, name) {
|
|
|
390
569
|
return row[name] ?? Object.values(row)[0];
|
|
391
570
|
}
|
|
392
571
|
function pragmaNumber(db, name) {
|
|
572
|
+
if (name === "busy_timeout") {
|
|
573
|
+
const state = busyTimeoutStates.get(db);
|
|
574
|
+
if (state)
|
|
575
|
+
return state.current;
|
|
576
|
+
}
|
|
393
577
|
try {
|
|
394
578
|
const value = pragmaValue(db, name);
|
|
395
579
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
@@ -455,11 +639,34 @@ function prepareCachedStatement2(db, sql) {
|
|
|
455
639
|
return ownPreparedStatement(db, db.prepare(sql));
|
|
456
640
|
}
|
|
457
641
|
var privilegeDepth = new WeakMap;
|
|
642
|
+
var nativeWaitScope;
|
|
643
|
+
function releaseNativeWaitLease(lease) {
|
|
644
|
+
lease.active = false;
|
|
645
|
+
lease.remainingMs = undefined;
|
|
646
|
+
}
|
|
647
|
+
function withSqliteTurnDeadline2(remainingMs, operation) {
|
|
648
|
+
const scope = nativeWaitScope ??= new AsyncLocalStorage;
|
|
649
|
+
const lease = { active: true, remainingMs };
|
|
650
|
+
return scope.run(lease, () => {
|
|
651
|
+
try {
|
|
652
|
+
const result = operation();
|
|
653
|
+
if (result && typeof result.then === "function")
|
|
654
|
+
return Promise.resolve(result).finally(releaseNativeWaitLease.bind(null, lease));
|
|
655
|
+
releaseNativeWaitLease(lease);
|
|
656
|
+
return result;
|
|
657
|
+
} catch (error) {
|
|
658
|
+
releaseNativeWaitLease(lease);
|
|
659
|
+
throw error;
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
}
|
|
458
663
|
var transformPassScope = new AsyncLocalStorage;
|
|
459
664
|
var admissionScope = new AsyncLocalStorage;
|
|
460
665
|
var backgroundWriterScope = new AsyncLocalStorage;
|
|
461
666
|
function withSqliteBackgroundWriter2(operation) {
|
|
462
|
-
|
|
667
|
+
if (!nativeWaitScope?.getStore())
|
|
668
|
+
return backgroundWriterScope.run(true, operation);
|
|
669
|
+
return nativeWaitScope.run(undefined, () => backgroundWriterScope.run(true, operation));
|
|
463
670
|
}
|
|
464
671
|
function withSqliteTransformPass2(operation) {
|
|
465
672
|
const existing = transformPassScope.getStore();
|
|
@@ -490,7 +697,9 @@ function withSqliteTransformPass2(operation) {
|
|
|
490
697
|
return typeof reservation === "function" ? run(reservation) : reservation.then(run);
|
|
491
698
|
}
|
|
492
699
|
function withoutSqliteTransformPass2(operation) {
|
|
493
|
-
|
|
700
|
+
if (!nativeWaitScope?.getStore())
|
|
701
|
+
return transformPassScope.run(undefined, operation);
|
|
702
|
+
return nativeWaitScope.run(undefined, () => transformPassScope.run(undefined, operation));
|
|
494
703
|
}
|
|
495
704
|
function guardSqliteTransformPass2(guard) {
|
|
496
705
|
const lease = transformPassScope.getStore();
|
|
@@ -829,4 +1038,4 @@ async function yieldIndexChunk2() {
|
|
|
829
1038
|
await yieldIndexTurn();
|
|
830
1039
|
}
|
|
831
1040
|
|
|
832
|
-
export { inRootAsyncContext2, registerSlowWriteReporter2, registerSqliteDiagnosticSink2, detectSqliteRuntime2, getTagIdentityWriteGeneration2, Database2, getSqliteDatabasePath2, prepareCachedStatement2, withSqliteBackgroundWriter2, withSqliteTransformPass2, withoutSqliteTransformPass2, guardSqliteTransformPass2, assertTransformWrite2, isTransientSqliteError2, beginSqliteWriterAsync2, withAsyncPrivilegedWriter2, withPrivilegedWriter2, indexCoordinationInput2, releaseIndexOwner2, withIndexChunk2, yieldIndexChunk2 };
|
|
1041
|
+
export { inRootAsyncContext2, registerSlowWriteReporter2, registerSqliteDiagnosticSink2, detectSqliteRuntime2, getTagIdentityWriteGeneration2, Database2, createSqliteTurnDatabase2, hasSqliteTurnDeadlineRouting2, getSqliteDatabasePath2, prepareCachedStatement2, withSqliteTurnDeadline2, withSqliteBackgroundWriter2, withSqliteTransformPass2, withoutSqliteTransformPass2, guardSqliteTransformPass2, assertTransformWrite2, isTransientSqliteError2, beginSqliteWriterAsync2, withAsyncPrivilegedWriter2, withPrivilegedWriter2, indexCoordinationInput2, releaseIndexOwner2, withIndexChunk2, yieldIndexChunk2 };
|
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
} from "./index-8976mezv.js";
|
|
17
17
|
import {
|
|
18
18
|
Database2
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-2qtx0q6h.js";
|
|
20
20
|
import {
|
|
21
21
|
normalizeStoredProjectPath,
|
|
22
22
|
storedPathBelongsToIdentity
|
|
23
|
-
} from "./index-
|
|
23
|
+
} from "./index-hxp6q5f8.js";
|
|
24
24
|
import {
|
|
25
25
|
logSlowWriteTransaction
|
|
26
26
|
} from "./index-hqw0rt9k.js";
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
getSqliteDatabasePath2,
|
|
3
3
|
withSqliteBackgroundWriter2,
|
|
4
4
|
withoutSqliteTransformPass2
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-2qtx0q6h.js";
|
|
6
6
|
import {
|
|
7
7
|
runSessionWarmupWorker
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-at6py2k3.js";
|
|
9
9
|
import {
|
|
10
10
|
logSlowWriteTransaction
|
|
11
11
|
} from "./index-hqw0rt9k.js";
|
|
@@ -7,18 +7,136 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
getTagsBySession2,
|
|
9
9
|
getTagsByNumbers2
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-n8e5e9fp.js";
|
|
11
11
|
import {
|
|
12
12
|
inRootAsyncContext2,
|
|
13
|
-
getSqliteDatabasePath2
|
|
14
|
-
|
|
13
|
+
getSqliteDatabasePath2,
|
|
14
|
+
withSqliteTurnDeadline2
|
|
15
|
+
} from "./index-2qtx0q6h.js";
|
|
15
16
|
import {
|
|
16
17
|
createFailClosedBlockingError
|
|
17
|
-
} from "./index-
|
|
18
|
+
} from "./index-dbgg6hsf.js";
|
|
18
19
|
import {
|
|
19
20
|
createWorkerShutdown
|
|
20
21
|
} from "./index-54wmg4rj.js";
|
|
21
22
|
|
|
23
|
+
// src/pi-context-budget.ts
|
|
24
|
+
var PI_CONTEXT_BUDGET = {
|
|
25
|
+
hostDeadlineMs: 30000,
|
|
26
|
+
hostMarginMs: 5000,
|
|
27
|
+
outcomeMs: 25000,
|
|
28
|
+
fallbackObservedMs: 4,
|
|
29
|
+
workMs: 21000,
|
|
30
|
+
writerMs: 16500,
|
|
31
|
+
completionReserveMs: 2000,
|
|
32
|
+
searchMs: 3000
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
class PiContextDeadlineError extends Error {
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class PiContextSupersededError extends Error {
|
|
39
|
+
origin;
|
|
40
|
+
constructor(message, origin = "context ownership") {
|
|
41
|
+
super(message);
|
|
42
|
+
this.origin = origin;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class PiContextBudget {
|
|
47
|
+
startedAt;
|
|
48
|
+
now;
|
|
49
|
+
sideTurn = false;
|
|
50
|
+
stage = "entry";
|
|
51
|
+
recovery = "not attempted";
|
|
52
|
+
abandoned = false;
|
|
53
|
+
completed = false;
|
|
54
|
+
failureReason;
|
|
55
|
+
signal;
|
|
56
|
+
cancelled = false;
|
|
57
|
+
isCancelled(error) {
|
|
58
|
+
return this.cancelled || this.signal?.aborted === true || !this.signal && typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
|
|
59
|
+
}
|
|
60
|
+
cancel() {
|
|
61
|
+
this.cancelled = true;
|
|
62
|
+
this.abandoned = true;
|
|
63
|
+
this.completed = false;
|
|
64
|
+
this.failureReason = undefined;
|
|
65
|
+
}
|
|
66
|
+
assertOwner = () => {};
|
|
67
|
+
constructor(startedAt = performance.now(), now = () => performance.now()) {
|
|
68
|
+
this.startedAt = startedAt;
|
|
69
|
+
this.now = now;
|
|
70
|
+
}
|
|
71
|
+
elapsed() {
|
|
72
|
+
return this.now() - this.startedAt;
|
|
73
|
+
}
|
|
74
|
+
remainingWork = () => {
|
|
75
|
+
return Math.max(0, PI_CONTEXT_BUDGET.workMs - this.elapsed());
|
|
76
|
+
};
|
|
77
|
+
remainingOutcome = () => Math.max(0, PI_CONTEXT_BUDGET.outcomeMs - this.elapsed());
|
|
78
|
+
writerAllowance() {
|
|
79
|
+
return Math.max(0, Math.min(PI_CONTEXT_BUDGET.writerMs, this.remainingWork() - PI_CONTEXT_BUDGET.completionReserveMs));
|
|
80
|
+
}
|
|
81
|
+
hydrationAllowance() {
|
|
82
|
+
return Math.max(0, Math.min(this.remainingWork() - PI_CONTEXT_BUDGET.completionReserveMs, this.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs));
|
|
83
|
+
}
|
|
84
|
+
assertOutcome = () => {
|
|
85
|
+
this.assertOwner();
|
|
86
|
+
this.signal?.throwIfAborted();
|
|
87
|
+
if (this.abandoned || this.elapsed() >= PI_CONTEXT_BUDGET.outcomeMs)
|
|
88
|
+
throw new PiContextDeadlineError(this.diagnostic());
|
|
89
|
+
};
|
|
90
|
+
assert = () => {
|
|
91
|
+
this.assertOutcome();
|
|
92
|
+
if (this.elapsed() >= PI_CONTEXT_BUDGET.workMs)
|
|
93
|
+
throw new PiContextDeadlineError(this.diagnostic());
|
|
94
|
+
};
|
|
95
|
+
assertDecisionPublication = () => {
|
|
96
|
+
this.signal?.throwIfAborted();
|
|
97
|
+
if (!this.completed)
|
|
98
|
+
this.assertOwner();
|
|
99
|
+
if (this.abandoned || !this.completed && this.elapsed() >= PI_CONTEXT_BUDGET.outcomeMs)
|
|
100
|
+
throw new PiContextDeadlineError(this.diagnostic());
|
|
101
|
+
};
|
|
102
|
+
diagnostic() {
|
|
103
|
+
return `stage=${this.stage} elapsed=${Math.round(this.elapsed())}ms recovery=${this.recovery}`;
|
|
104
|
+
}
|
|
105
|
+
waitUntil = async (pending, assert, remaining) => {
|
|
106
|
+
try {
|
|
107
|
+
assert();
|
|
108
|
+
} catch (error) {
|
|
109
|
+
pending.catch(() => {});
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
let timer;
|
|
113
|
+
let onAbort;
|
|
114
|
+
try {
|
|
115
|
+
return await Promise.race([
|
|
116
|
+
pending,
|
|
117
|
+
...this.signal ? [
|
|
118
|
+
new Promise((_, reject) => {
|
|
119
|
+
onAbort = () => reject(this.signal?.reason);
|
|
120
|
+
this.signal?.addEventListener("abort", onAbort, {
|
|
121
|
+
once: true
|
|
122
|
+
});
|
|
123
|
+
})
|
|
124
|
+
] : [],
|
|
125
|
+
new Promise((_, reject) => {
|
|
126
|
+
timer = setTimeout(() => reject(new PiContextDeadlineError(this.diagnostic())), remaining());
|
|
127
|
+
})
|
|
128
|
+
]);
|
|
129
|
+
} finally {
|
|
130
|
+
clearTimeout(timer);
|
|
131
|
+
if (onAbort)
|
|
132
|
+
this.signal?.removeEventListener("abort", onAbort);
|
|
133
|
+
assert();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
wait = (pending) => this.waitUntil(pending, this.assert, () => this.remainingWork());
|
|
137
|
+
waitMandatory = (pending) => this.waitUntil(pending, this.assertOutcome, this.remainingOutcome);
|
|
138
|
+
}
|
|
139
|
+
|
|
22
140
|
// src/tag-snapshot-worker-client-pi.ts
|
|
23
141
|
import { setImmediate as yieldImmediate } from "node:timers/promises";
|
|
24
142
|
import { Worker } from "node:worker_threads";
|
|
@@ -310,6 +428,13 @@ function createPiTagSnapshotReader(db) {
|
|
|
310
428
|
const existing = readers.get(db);
|
|
311
429
|
if (existing)
|
|
312
430
|
return existing;
|
|
431
|
+
const nativeWaiters = new Set;
|
|
432
|
+
const inSnapshotRoot = (operation) => inRootAsyncContext2(() => withSqliteTurnDeadline2(() => {
|
|
433
|
+
let remaining = Infinity;
|
|
434
|
+
for (const waiter of nativeWaiters)
|
|
435
|
+
remaining = Math.min(remaining, waiter());
|
|
436
|
+
return remaining;
|
|
437
|
+
}, operation));
|
|
313
438
|
db.exec(`
|
|
314
439
|
CREATE TEMP TABLE IF NOT EXISTS pi_tag_revision (revision INTEGER NOT NULL);
|
|
315
440
|
INSERT INTO pi_tag_revision SELECT 0 WHERE NOT EXISTS (SELECT 1 FROM pi_tag_revision);
|
|
@@ -403,7 +528,8 @@ function createPiTagSnapshotReader(db) {
|
|
|
403
528
|
const ownFirstAllocation = db.prepare(`SELECT 1 FROM pi_tag_first_allocation allocation
|
|
404
529
|
WHERE session_id = ? AND seen = 1 AND incarnation || ':0' = ?
|
|
405
530
|
AND EXISTS (SELECT 1 FROM pi_tag_watch WHERE session_id = allocation.session_id)
|
|
406
|
-
AND EXISTS (SELECT 1 FROM
|
|
531
|
+
AND EXISTS (SELECT 1 FROM pi_tag_changes WHERE session_id = allocation.session_id)
|
|
532
|
+
AND (? = 'legacy' OR EXISTS (SELECT 1 FROM pi_tag_first_rows WHERE session_id = allocation.session_id))
|
|
407
533
|
AND NOT EXISTS (SELECT 1 FROM pi_tag_first_rows first_row WHERE first_row.session_id = allocation.session_id
|
|
408
534
|
AND NOT EXISTS (SELECT 1 FROM pi_tag_changes change WHERE change.session_id = first_row.session_id AND change.tag_number IS first_row.tag_number))`);
|
|
409
535
|
const managed = new Set;
|
|
@@ -414,6 +540,7 @@ function createPiTagSnapshotReader(db) {
|
|
|
414
540
|
let desiredSession;
|
|
415
541
|
let failedUntil = 0;
|
|
416
542
|
let lastFailure;
|
|
543
|
+
let failedSession;
|
|
417
544
|
const totalRevision = db.prepare("SELECT COALESCE(value, '0') AS revision, value IS NOT NULL AS present FROM (SELECT 1) LEFT JOIN schema_migrations_meta ON key = ?");
|
|
418
545
|
const assertOutsideTransaction = () => {
|
|
419
546
|
const connection = db;
|
|
@@ -458,7 +585,7 @@ function createPiTagSnapshotReader(db) {
|
|
|
458
585
|
if (current?.sessionId === sessionId)
|
|
459
586
|
current.cancel();
|
|
460
587
|
};
|
|
461
|
-
const load = (sessionId) =>
|
|
588
|
+
const load = (sessionId) => inSnapshotRoot(async () => {
|
|
462
589
|
managed.add(sessionId);
|
|
463
590
|
if (ready(sessionId))
|
|
464
591
|
return;
|
|
@@ -472,7 +599,7 @@ function createPiTagSnapshotReader(db) {
|
|
|
472
599
|
throw new PiTagHydrationError("session hydration superseded", "stale");
|
|
473
600
|
return load(sessionId);
|
|
474
601
|
}
|
|
475
|
-
if (performance.now() < failedUntil)
|
|
602
|
+
if (failedSession === sessionId && performance.now() < failedUntil)
|
|
476
603
|
throw lastFailure;
|
|
477
604
|
watch.run(sessionId);
|
|
478
605
|
const token = stamps(sessionId, ++jobId);
|
|
@@ -516,7 +643,7 @@ function createPiTagSnapshotReader(db) {
|
|
|
516
643
|
if (current !== destination || desiredSession !== sessionId || !samePiTagSnapshotToken(token, live) || token.totalRevision !== live.totalRevision || generation.revision !== token.totalRevision || generation.durable !== token.durableVersion)
|
|
517
644
|
throw new PiTagHydrationError("owner generation or lifetime changed", "stale");
|
|
518
645
|
const snapshot = {
|
|
519
|
-
firstAllocationPending:
|
|
646
|
+
firstAllocationPending: live.revisionPresent ? undefined : candidate.tags.length === 0 && !db.prepare("SELECT 1 FROM tags WHERE session_id = ? LIMIT 1").get(sessionId) ? "empty" : "legacy",
|
|
520
647
|
revision: legacyFallbackOnly ? previous.revision : live.localRevision,
|
|
521
648
|
foreignRevision: live.foreignRevision,
|
|
522
649
|
tags: legacyFallbackOnly ? previous.tags : candidate.tags,
|
|
@@ -545,6 +672,7 @@ function createPiTagSnapshotReader(db) {
|
|
|
545
672
|
if (error instanceof PiTagHydrationError && error.code === "stale")
|
|
546
673
|
destination.stale = true;
|
|
547
674
|
if (current === destination && desiredSession === sessionId && token.sessionEpoch === (sessionEpochs.get(sessionId) ?? 0)) {
|
|
675
|
+
failedSession = sessionId;
|
|
548
676
|
lastFailure = error;
|
|
549
677
|
failedUntil = performance.now() + (error instanceof PiTagHydrationError && error.code === "stale" ? 0 : 500);
|
|
550
678
|
}
|
|
@@ -562,6 +690,12 @@ function createPiTagSnapshotReader(db) {
|
|
|
562
690
|
owners.set(db, {
|
|
563
691
|
ready,
|
|
564
692
|
load,
|
|
693
|
+
addNativeWaiter: (remaining) => {
|
|
694
|
+
nativeWaiters.add(remaining);
|
|
695
|
+
return () => {
|
|
696
|
+
nativeWaiters.delete(remaining);
|
|
697
|
+
};
|
|
698
|
+
},
|
|
565
699
|
manage: (sessionId) => managed.add(sessionId),
|
|
566
700
|
cancel
|
|
567
701
|
});
|
|
@@ -578,9 +712,9 @@ function createPiTagSnapshotReader(db) {
|
|
|
578
712
|
];
|
|
579
713
|
const stamp = versionStamp.get(sessionId, sessionId);
|
|
580
714
|
let snapshot = cache.get(sessionId);
|
|
581
|
-
if (snapshot?.firstAllocationPending && snapshot.foreignRevision !== external && snapshot.revision !== local && stamp.durable - snapshot.durableVersion === stamp.own - snapshot.ownVersion && ownFirstAllocation.get(sessionId, external)) {
|
|
715
|
+
if (snapshot?.firstAllocationPending && snapshot.foreignRevision !== external && snapshot.revision !== local && stamp.durable - snapshot.durableVersion === stamp.own - snapshot.ownVersion && ownFirstAllocation.get(sessionId, external, snapshot.firstAllocationPending)) {
|
|
582
716
|
snapshot.foreignRevision = external;
|
|
583
|
-
snapshot.firstAllocationPending =
|
|
717
|
+
snapshot.firstAllocationPending = undefined;
|
|
584
718
|
db.prepare("DELETE FROM pi_tag_first_watch WHERE session_id = ?").run(sessionId);
|
|
585
719
|
db.prepare("DELETE FROM pi_tag_first_rows WHERE session_id = ?").run(sessionId);
|
|
586
720
|
}
|
|
@@ -662,6 +796,7 @@ function createPiTagSnapshotReader(db) {
|
|
|
662
796
|
writable: true,
|
|
663
797
|
value: (...args) => {
|
|
664
798
|
desiredSession = undefined;
|
|
799
|
+
nativeWaiters.clear();
|
|
665
800
|
current?.cancel();
|
|
666
801
|
cache.clear();
|
|
667
802
|
entryReaders.delete(db);
|
|
@@ -885,6 +1020,7 @@ function ensurePiTagSnapshotReady(db, sessionId, budget) {
|
|
|
885
1020
|
if (allowance <= 0)
|
|
886
1021
|
throw new PiTagHydrationError("remaining pass budget exhausted waiting for tag snapshot; turn not sent, retry", "deadline");
|
|
887
1022
|
let timer;
|
|
1023
|
+
const releaseNativeWaiter = owner.addNativeWaiter(() => budget.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs);
|
|
888
1024
|
try {
|
|
889
1025
|
await budget.wait(Promise.race([
|
|
890
1026
|
owner.load(sessionId),
|
|
@@ -901,9 +1037,10 @@ function ensurePiTagSnapshotReady(db, sessionId, budget) {
|
|
|
901
1037
|
throw error;
|
|
902
1038
|
} finally {
|
|
903
1039
|
clearTimeout(timer);
|
|
1040
|
+
releaseNativeWaiter();
|
|
904
1041
|
}
|
|
905
1042
|
}
|
|
906
1043
|
})();
|
|
907
1044
|
}
|
|
908
1045
|
|
|
909
|
-
export { encodePiHydrationOperation, PiTagHydrationError, PI_FALLBACK_ROW_COLUMNS, PI_FALLBACK_ROW_PREDICATE, getPiTagSnapshotView, getPiActiveTagSnapshotView, readPiFallbackTagRows, prewarmPiTagSnapshot, cancelPiTagSnapshotSession, drainPiTagSnapshotSession, assertPiTagSnapshotReady, ensurePiTagSnapshotReady };
|
|
1046
|
+
export { PI_CONTEXT_BUDGET, PiContextDeadlineError, PiContextSupersededError, PiContextBudget, encodePiHydrationOperation, PiTagHydrationError, PI_FALLBACK_ROW_COLUMNS, PI_FALLBACK_ROW_PREDICATE, getPiTagSnapshotView, getPiActiveTagSnapshotView, readPiFallbackTagRows, prewarmPiTagSnapshot, cancelPiTagSnapshotSession, drainPiTagSnapshotSession, assertPiTagSnapshotReady, ensurePiTagSnapshotReady };
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
inRootAsyncContext2,
|
|
9
9
|
getSqliteDatabasePath2
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-2qtx0q6h.js";
|
|
11
11
|
|
|
12
12
|
// ../plugin/src/features/magic-context/compaction-marker-candidates.ts
|
|
13
13
|
import { existsSync, realpathSync } from "node:fs";
|