@cortexkit/pi-magic-context 0.42.1 → 0.42.3
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/{index-pknkkpnp.js → index-xw7qmpmt.js} +833 -33
- package/dist/index.js +418 -143
- package/dist/subagent-entry.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -174,6 +174,7 @@ import {
|
|
|
174
174
|
escapeXmlContent,
|
|
175
175
|
getModuleNoteEvaluationBridge,
|
|
176
176
|
getContextStoreUuid,
|
|
177
|
+
drainMirrorPages,
|
|
177
178
|
parseCompartmentOutput,
|
|
178
179
|
resolveWorkspaceShareCategories,
|
|
179
180
|
resolveWorkspaceIdentitySet,
|
|
@@ -463,7 +464,7 @@ import {
|
|
|
463
464
|
registerTodoStateLifecycle,
|
|
464
465
|
syncCtxMemoryToolEnabled,
|
|
465
466
|
registerMagicContextTools
|
|
466
|
-
} from "./index-
|
|
467
|
+
} from "./index-xw7qmpmt.js";
|
|
467
468
|
import {
|
|
468
469
|
pushNotification2
|
|
469
470
|
} from "./index-b3eqj1g6.js";
|
|
@@ -2414,14 +2415,25 @@ function countActiveMemories(db, projectPath) {
|
|
|
2414
2415
|
const row = db.prepare("SELECT COUNT(*) AS cnt FROM memories WHERE project_path = ? AND status IN ('active','permanent')").get(projectPath);
|
|
2415
2416
|
return row?.cnt ?? 0;
|
|
2416
2417
|
}
|
|
2418
|
+
function countLiveMemories(db, projectPath, options = {}) {
|
|
2419
|
+
const unclassified = options.unclassifiedOnly && hasMemoryClassifiedAtColumn(db);
|
|
2420
|
+
const row = db.prepare(`SELECT COUNT(*) AS cnt
|
|
2421
|
+
FROM memories
|
|
2422
|
+
WHERE project_path = ?
|
|
2423
|
+
AND status IN ('active','permanent')
|
|
2424
|
+
AND (expires_at IS NULL OR expires_at > ?)
|
|
2425
|
+
${unclassified ? "AND classified_at IS NULL" : ""}`).get(projectPath, Date.now());
|
|
2426
|
+
return row?.cnt ?? 0;
|
|
2427
|
+
}
|
|
2417
2428
|
function countUnmappedActiveMemories(db, projectPath) {
|
|
2418
2429
|
const row = db.prepare(`SELECT COUNT(*) AS cnt
|
|
2419
2430
|
FROM memories m
|
|
2420
2431
|
WHERE m.project_path = ?
|
|
2421
2432
|
AND m.status IN ('active','permanent')
|
|
2433
|
+
AND (m.expires_at IS NULL OR m.expires_at > ?)
|
|
2422
2434
|
AND NOT EXISTS (
|
|
2423
2435
|
SELECT 1 FROM memory_verifications v WHERE v.memory_id = m.id
|
|
2424
|
-
)`).get(projectPath);
|
|
2436
|
+
)`).get(projectPath, Date.now());
|
|
2425
2437
|
return row?.cnt ?? 0;
|
|
2426
2438
|
}
|
|
2427
2439
|
function countCompartmentsSince(db, projectPath, since) {
|
|
@@ -2441,7 +2453,8 @@ function countMappedMemories(db, projectPath) {
|
|
|
2441
2453
|
JOIN memory_verifications v ON v.memory_id = m.id
|
|
2442
2454
|
WHERE m.project_path = ?
|
|
2443
2455
|
AND m.status IN ('active','permanent')
|
|
2444
|
-
AND
|
|
2456
|
+
AND (m.expires_at IS NULL OR m.expires_at > ?)
|
|
2457
|
+
AND v.file_path <> ''`).get(projectPath, Date.now());
|
|
2445
2458
|
return row?.cnt ?? 0;
|
|
2446
2459
|
}
|
|
2447
2460
|
function countUnverifiedMappedMemories(db, projectPath) {
|
|
@@ -2450,8 +2463,9 @@ function countUnverifiedMappedMemories(db, projectPath) {
|
|
|
2450
2463
|
JOIN memory_verifications v ON v.memory_id = m.id
|
|
2451
2464
|
WHERE m.project_path = ?
|
|
2452
2465
|
AND m.status IN ('active','permanent')
|
|
2466
|
+
AND (m.expires_at IS NULL OR m.expires_at > ?)
|
|
2453
2467
|
AND v.file_path <> ''
|
|
2454
|
-
AND v.verified_at = 0`).get(projectPath);
|
|
2468
|
+
AND v.verified_at = 0`).get(projectPath, Date.now());
|
|
2455
2469
|
return row?.cnt ?? 0;
|
|
2456
2470
|
}
|
|
2457
2471
|
function countBroadCycleCandidates(db, projectPath, cycleStartAt) {
|
|
@@ -2459,22 +2473,24 @@ function countBroadCycleCandidates(db, projectPath, cycleStartAt) {
|
|
|
2459
2473
|
FROM memories m
|
|
2460
2474
|
WHERE m.project_path = ?
|
|
2461
2475
|
AND m.status IN ('active','permanent')
|
|
2476
|
+
AND (m.expires_at IS NULL OR m.expires_at > ?)
|
|
2462
2477
|
AND (
|
|
2463
2478
|
SELECT MAX(v.verified_at)
|
|
2464
2479
|
FROM memory_verifications v
|
|
2465
2480
|
WHERE v.memory_id = m.id
|
|
2466
2481
|
AND v.file_path <> ''
|
|
2467
|
-
) < ?`).get(projectPath, cycleStartAt);
|
|
2482
|
+
) < ?`).get(projectPath, Date.now(), cycleStartAt);
|
|
2468
2483
|
return row?.cnt ?? 0;
|
|
2469
2484
|
}
|
|
2470
2485
|
function countCueCandidates(db, projectPath) {
|
|
2471
2486
|
if (!hasMuralCueColumns(db))
|
|
2472
|
-
return
|
|
2487
|
+
return countLiveMemories(db, projectPath);
|
|
2473
2488
|
const row = db.prepare(`SELECT COUNT(*) AS cnt
|
|
2474
2489
|
FROM memories
|
|
2475
2490
|
WHERE project_path = ?
|
|
2476
2491
|
AND status IN ('active','permanent')
|
|
2477
|
-
AND (
|
|
2492
|
+
AND (expires_at IS NULL OR expires_at > ?)
|
|
2493
|
+
AND (mural_cue IS NULL OR mural_cue_hash IS NULL OR updated_at > mural_cue_at)`).get(projectPath, Date.now());
|
|
2478
2494
|
return row?.cnt ?? 0;
|
|
2479
2495
|
}
|
|
2480
2496
|
function countStalePrimers(db, projectPath) {
|
|
@@ -2486,16 +2502,6 @@ function countStalePrimers(db, projectPath) {
|
|
|
2486
2502
|
OR last_observed_at > answer_refreshed_at)`).get(projectPath);
|
|
2487
2503
|
return row?.cnt ?? 0;
|
|
2488
2504
|
}
|
|
2489
|
-
function countUnclassifiedActiveMemories(db, projectPath) {
|
|
2490
|
-
if (!hasMemoryClassifiedAtColumn(db))
|
|
2491
|
-
return countActiveMemories(db, projectPath);
|
|
2492
|
-
const row = db.prepare(`SELECT COUNT(*) AS cnt
|
|
2493
|
-
FROM memories
|
|
2494
|
-
WHERE project_path = ?
|
|
2495
|
-
AND status IN ('active','permanent')
|
|
2496
|
-
AND classified_at IS NULL`).get(projectPath);
|
|
2497
|
-
return row?.cnt ?? 0;
|
|
2498
|
-
}
|
|
2499
2505
|
function countPendingSmartNotes(db, projectPath) {
|
|
2500
2506
|
const row = db.prepare("SELECT COUNT(*) AS cnt FROM notes WHERE project_path = ? AND type = 'smart' AND status = 'pending'").get(projectPath);
|
|
2501
2507
|
return row?.cnt ?? 0;
|
|
@@ -2511,7 +2517,7 @@ function countActivePrimers(db, projectPath) {
|
|
|
2511
2517
|
function getDreamTaskBacklog(db, projectPath, task, options = {}) {
|
|
2512
2518
|
switch (task) {
|
|
2513
2519
|
case "map-memories": {
|
|
2514
|
-
const total =
|
|
2520
|
+
const total = countLiveMemories(db, projectPath);
|
|
2515
2521
|
return { pending: countUnmappedActiveMemories(db, projectPath), total };
|
|
2516
2522
|
}
|
|
2517
2523
|
case "verify": {
|
|
@@ -2527,16 +2533,19 @@ function getDreamTaskBacklog(db, projectPath, task, options = {}) {
|
|
|
2527
2533
|
return { pending, total };
|
|
2528
2534
|
}
|
|
2529
2535
|
case "curate": {
|
|
2530
|
-
const total =
|
|
2536
|
+
const total = countLiveMemories(db, projectPath);
|
|
2531
2537
|
return { pending: total, total };
|
|
2532
2538
|
}
|
|
2533
2539
|
case "compress-cues": {
|
|
2534
|
-
const total =
|
|
2540
|
+
const total = countLiveMemories(db, projectPath);
|
|
2535
2541
|
return { pending: countCueCandidates(db, projectPath), total };
|
|
2536
2542
|
}
|
|
2537
2543
|
case "classify-memories": {
|
|
2538
|
-
const total =
|
|
2539
|
-
return {
|
|
2544
|
+
const total = countLiveMemories(db, projectPath);
|
|
2545
|
+
return {
|
|
2546
|
+
pending: countLiveMemories(db, projectPath, { unclassifiedOnly: true }),
|
|
2547
|
+
total
|
|
2548
|
+
};
|
|
2540
2549
|
}
|
|
2541
2550
|
case "retrospective": {
|
|
2542
2551
|
const pending = countProjectSessionsSince(db, projectPath, options.retrospectiveWatermarkMs ?? null);
|
|
@@ -2581,15 +2590,15 @@ function evaluateTaskGate(task, ctx) {
|
|
|
2581
2590
|
case "map-memories":
|
|
2582
2591
|
return countUnmappedActiveMemories(db, project) > 0;
|
|
2583
2592
|
case "verify":
|
|
2584
|
-
return
|
|
2593
|
+
return countLiveMemories(db, project) > 0;
|
|
2585
2594
|
case "verify-broad":
|
|
2586
|
-
return getTaskScheduleState(db, project, "verify-broad")?.lastBroadRunAt != null ||
|
|
2595
|
+
return getTaskScheduleState(db, project, "verify-broad")?.lastBroadRunAt != null || countLiveMemories(db, project) > 0;
|
|
2587
2596
|
case "curate":
|
|
2588
2597
|
return countActiveMemories(db, project) > 0;
|
|
2589
2598
|
case "compress-cues":
|
|
2590
|
-
return
|
|
2599
|
+
return countLiveMemories(db, project) > 0;
|
|
2591
2600
|
case "classify-memories":
|
|
2592
|
-
return
|
|
2601
|
+
return countLiveMemories(db, project) > 0;
|
|
2593
2602
|
case "retrospective":
|
|
2594
2603
|
return countProjectSessionsSince(db, project, ctx.retrospectiveWatermarkMs ?? null) > 0;
|
|
2595
2604
|
case "maintain-docs":
|
|
@@ -7049,6 +7058,116 @@ Output exactly JSON: {"met": false}`;
|
|
|
7049
7058
|
}
|
|
7050
7059
|
}
|
|
7051
7060
|
|
|
7061
|
+
// ../plugin/src/features/magic-context/dreamer/expire-memories.ts
|
|
7062
|
+
var MODULE_ARCHIVE_BATCH_SIZE = 100;
|
|
7063
|
+
var EXPIRED_ARCHIVE_REASON = "expired";
|
|
7064
|
+
function getExpiredActiveMemoryIds(db, projectIdentity, now = Date.now()) {
|
|
7065
|
+
const rows = db.prepare(`SELECT id
|
|
7066
|
+
FROM memories
|
|
7067
|
+
WHERE project_path = ?
|
|
7068
|
+
AND status = 'active'
|
|
7069
|
+
AND expires_at IS NOT NULL
|
|
7070
|
+
AND expires_at <= ?
|
|
7071
|
+
ORDER BY id`).all(projectIdentity, now);
|
|
7072
|
+
return rows.map((row) => row.id);
|
|
7073
|
+
}
|
|
7074
|
+
function assertSuccessfulModuleArchive(response) {
|
|
7075
|
+
const result = response && typeof response === "object" && "result" in response ? response.result : response;
|
|
7076
|
+
if (result && typeof result === "object") {
|
|
7077
|
+
const record = result;
|
|
7078
|
+
if (record.ok === false || record.error) {
|
|
7079
|
+
throw new Error("module rejected expired-memory archive");
|
|
7080
|
+
}
|
|
7081
|
+
}
|
|
7082
|
+
}
|
|
7083
|
+
async function archiveExpiredThroughModule(args) {
|
|
7084
|
+
if (!args.moduleRoute.moduleClient.mirrorPull) {
|
|
7085
|
+
throw new DreamerModuleFailureError("mirror.pull expired archive", new Error("Rust dreamer client omitted the memory mirror route"));
|
|
7086
|
+
}
|
|
7087
|
+
for (let offset = 0;offset < args.expiredContextIds.length; offset += MODULE_ARCHIVE_BATCH_SIZE) {
|
|
7088
|
+
if (!leaseOwnershipMatches(args.db, args.holderId, args.leaseAcquisition.generation, args.leaseKey)) {
|
|
7089
|
+
throw new Error("Dream lease lost before expired-memory archive");
|
|
7090
|
+
}
|
|
7091
|
+
const contextBatch = args.expiredContextIds.slice(offset, offset + MODULE_ARCHIVE_BATCH_SIZE);
|
|
7092
|
+
const identities = getModuleMemoryIdentities(args.db, args.projectIdentity, contextBatch);
|
|
7093
|
+
if (identities.size !== contextBatch.length) {
|
|
7094
|
+
throw new DreamerModuleFailureError("ctx_memory expired archive", new Error("expired memory is missing its module mirror identity"));
|
|
7095
|
+
}
|
|
7096
|
+
const moduleBatch = contextBatch.map((id) => {
|
|
7097
|
+
const identity = identities.get(id);
|
|
7098
|
+
if (!identity)
|
|
7099
|
+
throw new Error(`missing module identity for expired memory ${id}`);
|
|
7100
|
+
return identity.moduleId;
|
|
7101
|
+
});
|
|
7102
|
+
try {
|
|
7103
|
+
const response = await args.moduleRoute.moduleClient.call({
|
|
7104
|
+
sessionId: args.moduleRoute.moduleSessionId,
|
|
7105
|
+
projectRoot: args.moduleRoute.moduleProjectRoot,
|
|
7106
|
+
method: "ctx_memory",
|
|
7107
|
+
body: {
|
|
7108
|
+
name: "ctx_memory",
|
|
7109
|
+
arguments: {
|
|
7110
|
+
action: "archive",
|
|
7111
|
+
memory_project: args.projectIdentity,
|
|
7112
|
+
ids: moduleBatch,
|
|
7113
|
+
reason: EXPIRED_ARCHIVE_REASON,
|
|
7114
|
+
command_id: `${args.moduleRoute.moduleCommandId}:expire:${offset / MODULE_ARCHIVE_BATCH_SIZE}`
|
|
7115
|
+
}
|
|
7116
|
+
}
|
|
7117
|
+
});
|
|
7118
|
+
assertSuccessfulModuleArchive(response);
|
|
7119
|
+
} catch (error) {
|
|
7120
|
+
throw new DreamerModuleFailureError("ctx_memory expired archive", error);
|
|
7121
|
+
}
|
|
7122
|
+
}
|
|
7123
|
+
const mirrorPull = args.moduleRoute.moduleClient.mirrorPull;
|
|
7124
|
+
const drained = await drainMirrorPages({
|
|
7125
|
+
db: args.db,
|
|
7126
|
+
module: {
|
|
7127
|
+
mirrorPull: (request) => mirrorPull({ ...request, projectRoot: args.moduleRoute.moduleProjectRoot })
|
|
7128
|
+
},
|
|
7129
|
+
domain: "memories",
|
|
7130
|
+
limit: 1000
|
|
7131
|
+
});
|
|
7132
|
+
if (!drained.complete) {
|
|
7133
|
+
throw new DreamerModuleFailureError("mirror.pull expired archive", new Error("memory mirror did not reach the module cursor"));
|
|
7134
|
+
}
|
|
7135
|
+
if (!leaseOwnershipMatches(args.db, args.holderId, args.leaseAcquisition.generation, args.leaseKey)) {
|
|
7136
|
+
throw new Error("Dream lease lost during expired-memory archive");
|
|
7137
|
+
}
|
|
7138
|
+
return args.expiredContextIds.length;
|
|
7139
|
+
}
|
|
7140
|
+
async function archiveExpiredMemories(args) {
|
|
7141
|
+
const expiredContextIds = getExpiredActiveMemoryIds(args.db, args.projectIdentity, args.now);
|
|
7142
|
+
if (expiredContextIds.length === 0) {
|
|
7143
|
+
if (!leaseOwnershipMatches(args.db, args.holderId, args.leaseAcquisition.generation, args.leaseKey)) {
|
|
7144
|
+
throw new Error("Dream lease lost before expired-memory probe");
|
|
7145
|
+
}
|
|
7146
|
+
return 0;
|
|
7147
|
+
}
|
|
7148
|
+
if (args.moduleRoute) {
|
|
7149
|
+
return archiveExpiredThroughModule({
|
|
7150
|
+
...args,
|
|
7151
|
+
expiredContextIds,
|
|
7152
|
+
moduleRoute: args.moduleRoute
|
|
7153
|
+
});
|
|
7154
|
+
}
|
|
7155
|
+
const selectedIds = new Set(expiredContextIds);
|
|
7156
|
+
return runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
|
|
7157
|
+
const stillExpired = getExpiredActiveMemoryIds(args.db, args.projectIdentity, args.now).filter((id) => selectedIds.has(id));
|
|
7158
|
+
for (const id of stillExpired) {
|
|
7159
|
+
archiveMemory(args.db, id, EXPIRED_ARCHIVE_REASON);
|
|
7160
|
+
queueMemoryMutation(args.db, {
|
|
7161
|
+
projectPath: args.projectIdentity,
|
|
7162
|
+
mutationType: "archive",
|
|
7163
|
+
targetMemoryId: id,
|
|
7164
|
+
queuedAt: args.now
|
|
7165
|
+
});
|
|
7166
|
+
}
|
|
7167
|
+
return stillExpired.length;
|
|
7168
|
+
});
|
|
7169
|
+
}
|
|
7170
|
+
|
|
7052
7171
|
// ../plugin/src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
|
|
7053
7172
|
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
7054
7173
|
import { join as join2 } from "node:path";
|
|
@@ -8521,7 +8640,7 @@ function normalizeOpenCodeRows(db, sessionId, rows) {
|
|
|
8521
8640
|
const placeholders = messageIds.map(() => "?").join(", ");
|
|
8522
8641
|
const partRows = db.prepare(`SELECT message_id, data
|
|
8523
8642
|
FROM part
|
|
8524
|
-
WHERE session_id = ?
|
|
8643
|
+
WHERE +session_id = ?
|
|
8525
8644
|
AND likelihood(message_id IN (${placeholders}), 0.000001)
|
|
8526
8645
|
ORDER BY time_created ASC, id ASC`).all(sessionId, ...messageIds);
|
|
8527
8646
|
const partsByMessageId = new Map;
|
|
@@ -9388,6 +9507,9 @@ function inspectCurateMemoryOperations(messages) {
|
|
|
9388
9507
|
}
|
|
9389
9508
|
return summary;
|
|
9390
9509
|
}
|
|
9510
|
+
function formatExpiredArchiveProgress(count) {
|
|
9511
|
+
return `curate: archived ${count} expired ${count === 1 ? "memory" : "memories"}`;
|
|
9512
|
+
}
|
|
9391
9513
|
function formatCurateMemoryOperations(actions) {
|
|
9392
9514
|
const actionCounts = new Map;
|
|
9393
9515
|
for (const action of actions)
|
|
@@ -9438,7 +9560,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9438
9560
|
};
|
|
9439
9561
|
const parent = await resolveParentSessionId();
|
|
9440
9562
|
let moduleRoute;
|
|
9441
|
-
if (config.task === "map-memories" || config.task === "compress-cues" || config.task === "classify-memories" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
|
|
9563
|
+
if (config.task === "curate" || config.task === "map-memories" || config.task === "compress-cues" || config.task === "classify-memories" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
|
|
9442
9564
|
try {
|
|
9443
9565
|
moduleRoute = await resolveDreamerModuleRoute({
|
|
9444
9566
|
db,
|
|
@@ -9767,7 +9889,9 @@ function createDreamTaskExecutor(deps) {
|
|
|
9767
9889
|
parent,
|
|
9768
9890
|
recordRun,
|
|
9769
9891
|
computeMemoryDelta,
|
|
9770
|
-
reportProgress
|
|
9892
|
+
reportProgress,
|
|
9893
|
+
leaseAcquisition,
|
|
9894
|
+
moduleRoute
|
|
9771
9895
|
});
|
|
9772
9896
|
} catch (error) {
|
|
9773
9897
|
const { transient, brief } = classifyFailure(error);
|
|
@@ -10068,17 +10192,6 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
10068
10192
|
architecture: existsSync5(`${docsDir}/ARCHITECTURE.md`),
|
|
10069
10193
|
structure: existsSync5(`${docsDir}/STRUCTURE.md`)
|
|
10070
10194
|
} : undefined;
|
|
10071
|
-
let curateMemories;
|
|
10072
|
-
if (task === "curate") {
|
|
10073
|
-
curateMemories = loadActiveMemoryPromptMemories(db, projectIdentity);
|
|
10074
|
-
log(`[dreamer] curate pool: in_scope=${curateMemories.length}`);
|
|
10075
|
-
}
|
|
10076
|
-
const taskPrompt = buildDreamTaskPrompt(task, {
|
|
10077
|
-
projectPath: projectIdentity,
|
|
10078
|
-
lastDreamAt: lastRunAt ? String(lastRunAt) : null,
|
|
10079
|
-
existingDocs,
|
|
10080
|
-
curate: curateMemories ? { memories: curateMemories } : undefined
|
|
10081
|
-
});
|
|
10082
10195
|
const abortController = new AbortController;
|
|
10083
10196
|
let leaseLost = false;
|
|
10084
10197
|
const heartbeat = startLeaseHeartbeat(db, holderId, leaseKey, () => {
|
|
@@ -10087,7 +10200,37 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
10087
10200
|
}, ctx.leaseAcquisition);
|
|
10088
10201
|
let childSessionId = null;
|
|
10089
10202
|
let promptSettled = false;
|
|
10203
|
+
let expiredArchived = 0;
|
|
10090
10204
|
try {
|
|
10205
|
+
let curateMemories;
|
|
10206
|
+
if (task === "curate") {
|
|
10207
|
+
expiredArchived = await archiveExpiredMemories({
|
|
10208
|
+
db,
|
|
10209
|
+
projectIdentity,
|
|
10210
|
+
holderId,
|
|
10211
|
+
leaseKey,
|
|
10212
|
+
leaseAcquisition: helpers.leaseAcquisition,
|
|
10213
|
+
moduleRoute: helpers.moduleRoute
|
|
10214
|
+
});
|
|
10215
|
+
if (leaseLost)
|
|
10216
|
+
throw new Error("Dream lease lost during expired-memory archive");
|
|
10217
|
+
curateMemories = loadActiveMemoryPromptMemories(db, projectIdentity);
|
|
10218
|
+
log(`[dreamer] curate pool: in_scope=${curateMemories.length} expired_archived=${expiredArchived}`);
|
|
10219
|
+
if (curateMemories.length === 0 && expiredArchived > 0) {
|
|
10220
|
+
const progress = formatExpiredArchiveProgress(expiredArchived);
|
|
10221
|
+
helpers.recordRun("completed", null, {
|
|
10222
|
+
memoryChanges: helpers.computeMemoryDelta(memoryBefore),
|
|
10223
|
+
progress
|
|
10224
|
+
});
|
|
10225
|
+
return { status: "completed", detail: progress };
|
|
10226
|
+
}
|
|
10227
|
+
}
|
|
10228
|
+
const taskPrompt = buildDreamTaskPrompt(task, {
|
|
10229
|
+
projectPath: projectIdentity,
|
|
10230
|
+
lastDreamAt: lastRunAt ? String(lastRunAt) : null,
|
|
10231
|
+
existingDocs,
|
|
10232
|
+
curate: curateMemories ? { memories: curateMemories } : undefined
|
|
10233
|
+
});
|
|
10091
10234
|
const createResponse = await createChildSessionWithFence({
|
|
10092
10235
|
client: deps.client,
|
|
10093
10236
|
db,
|
|
@@ -10179,6 +10322,7 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
10179
10322
|
}
|
|
10180
10323
|
const curateOutput = task === "curate" ? run.validated : undefined;
|
|
10181
10324
|
const progress = [
|
|
10325
|
+
expiredArchived > 0 ? formatExpiredArchiveProgress(expiredArchived) : null,
|
|
10182
10326
|
curateOutput && curateOutput.memoryOperations.completedActions.length > 0 ? formatCurateMemoryOperations(curateOutput.memoryOperations.completedActions) : null,
|
|
10183
10327
|
curateRefused > 0 ? `curate: refused ${curateRefused} unsafe mutation(s)` : null
|
|
10184
10328
|
].filter((value) => Boolean(value)).join("; ");
|
|
@@ -14210,78 +14354,93 @@ function buildReplacementContent(tagId) {
|
|
|
14210
14354
|
}
|
|
14211
14355
|
function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set) {
|
|
14212
14356
|
let didMutateMessage = false;
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
|
|
14230
|
-
|
|
14231
|
-
|
|
14232
|
-
|
|
14233
|
-
const target = targets.get(pendingOp.tagId);
|
|
14234
|
-
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
14235
|
-
if (synthetic) {
|
|
14236
|
-
if (!isToolTag || target?.canDrop?.() !== true)
|
|
14357
|
+
let admitted = false;
|
|
14358
|
+
let startedAt = 0;
|
|
14359
|
+
try {
|
|
14360
|
+
db.transaction(() => {
|
|
14361
|
+
admitted = true;
|
|
14362
|
+
startedAt = performance.now();
|
|
14363
|
+
const tags = preloadedTags ?? getTagsBySession(db, sessionId);
|
|
14364
|
+
const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
|
|
14365
|
+
const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
|
|
14366
|
+
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
14367
|
+
const opsToApply = [
|
|
14368
|
+
...pendingOps.map((op) => ({ op, synthetic: false })),
|
|
14369
|
+
...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
|
|
14370
|
+
];
|
|
14371
|
+
const skeletonWindow = new Set(tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW));
|
|
14372
|
+
for (const { op: pendingOp, synthetic } of opsToApply) {
|
|
14373
|
+
const tagStatus = tagStatusById.get(pendingOp.tagId);
|
|
14374
|
+
if (tagStatus === "compacted" || tagStatus === "dropped") {
|
|
14375
|
+
if (!synthetic)
|
|
14376
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
14237
14377
|
continue;
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14242
|
-
|
|
14243
|
-
|
|
14244
|
-
|
|
14245
|
-
|
|
14246
|
-
didMutateMessage = true;
|
|
14247
|
-
updateTagDropMode(db, sessionId, pendingOp.tagId, "edit_marker");
|
|
14248
|
-
shouldPersistDrop = true;
|
|
14249
|
-
} else if (skeletonWindow.has(pendingOp.tagId)) {
|
|
14250
|
-
const truncResult = target?.truncate?.() ?? "absent";
|
|
14251
|
-
if (truncResult === "incomplete" || synthetic && truncResult !== "truncated") {
|
|
14378
|
+
}
|
|
14379
|
+
if (protectedTagIds.has(pendingOp.tagId)) {
|
|
14380
|
+
continue;
|
|
14381
|
+
}
|
|
14382
|
+
const target = targets.get(pendingOp.tagId);
|
|
14383
|
+
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
14384
|
+
if (synthetic) {
|
|
14385
|
+
if (!isToolTag || target?.canDrop?.() !== true)
|
|
14252
14386
|
continue;
|
|
14253
|
-
|
|
14254
|
-
|
|
14387
|
+
}
|
|
14388
|
+
let shouldPersistDrop = false;
|
|
14389
|
+
if (isToolTag) {
|
|
14390
|
+
if (editMarkerTagIds.has(pendingOp.tagId)) {
|
|
14391
|
+
const markResult = target?.editMarker?.() ?? "absent";
|
|
14392
|
+
if (markResult === "incomplete" || markResult === "absent") {
|
|
14393
|
+
continue;
|
|
14394
|
+
}
|
|
14255
14395
|
didMutateMessage = true;
|
|
14396
|
+
updateTagDropMode(db, sessionId, pendingOp.tagId, "edit_marker");
|
|
14397
|
+
shouldPersistDrop = true;
|
|
14398
|
+
} else if (skeletonWindow.has(pendingOp.tagId)) {
|
|
14399
|
+
const truncResult = target?.truncate?.() ?? "absent";
|
|
14400
|
+
if (truncResult === "incomplete" || synthetic && truncResult !== "truncated") {
|
|
14401
|
+
continue;
|
|
14402
|
+
}
|
|
14403
|
+
if (truncResult === "truncated") {
|
|
14404
|
+
didMutateMessage = true;
|
|
14405
|
+
}
|
|
14406
|
+
updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
|
|
14407
|
+
shouldPersistDrop = true;
|
|
14408
|
+
} else {
|
|
14409
|
+
const dropResult = target?.drop?.() ?? "absent";
|
|
14410
|
+
if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
|
|
14411
|
+
continue;
|
|
14412
|
+
}
|
|
14413
|
+
if (dropResult === "removed") {
|
|
14414
|
+
didMutateMessage = true;
|
|
14415
|
+
}
|
|
14416
|
+
updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
|
|
14417
|
+
shouldPersistDrop = true;
|
|
14256
14418
|
}
|
|
14257
|
-
|
|
14258
|
-
|
|
14259
|
-
|
|
14260
|
-
const dropResult = target?.drop?.() ?? "absent";
|
|
14261
|
-
if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
|
|
14262
|
-
continue;
|
|
14263
|
-
}
|
|
14264
|
-
if (dropResult === "removed") {
|
|
14419
|
+
} else if (target) {
|
|
14420
|
+
const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
|
|
14421
|
+
if (changed)
|
|
14265
14422
|
didMutateMessage = true;
|
|
14266
|
-
|
|
14267
|
-
|
|
14423
|
+
shouldPersistDrop = true;
|
|
14424
|
+
} else if (!synthetic) {
|
|
14268
14425
|
shouldPersistDrop = true;
|
|
14269
14426
|
}
|
|
14270
|
-
|
|
14271
|
-
|
|
14272
|
-
|
|
14273
|
-
|
|
14274
|
-
|
|
14275
|
-
} else if (!synthetic) {
|
|
14276
|
-
shouldPersistDrop = true;
|
|
14427
|
+
if (!shouldPersistDrop)
|
|
14428
|
+
continue;
|
|
14429
|
+
updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
|
|
14430
|
+
if (!synthetic)
|
|
14431
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
14277
14432
|
}
|
|
14278
|
-
|
|
14279
|
-
|
|
14280
|
-
|
|
14281
|
-
|
|
14282
|
-
|
|
14433
|
+
}).immediate();
|
|
14434
|
+
} catch (error) {
|
|
14435
|
+
if (!admitted && /database (?:table )?is locked|sqlite_(busy|locked)/i.test(String(error))) {
|
|
14436
|
+
sessionLog(sessionId, "pending operations write admission busy; retaining prior bytes for retry");
|
|
14437
|
+
return false;
|
|
14283
14438
|
}
|
|
14284
|
-
|
|
14439
|
+
throw error;
|
|
14440
|
+
} finally {
|
|
14441
|
+
if (admitted)
|
|
14442
|
+
logSlowWriteTransaction("apply_pending_operations", startedAt);
|
|
14443
|
+
}
|
|
14285
14444
|
return didMutateMessage;
|
|
14286
14445
|
}
|
|
14287
14446
|
function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
|
|
@@ -16456,11 +16615,16 @@ function buildAggregateTarget(tagId, occurrences, requiresToolArcSkeleton) {
|
|
|
16456
16615
|
const complete = occurrences.some((occ) => occ.kind === "tool_use") && occurrences.some((occ) => occ.kind === "tool_result");
|
|
16457
16616
|
if (!complete)
|
|
16458
16617
|
return "incomplete";
|
|
16459
|
-
if (!requiresToolArcSkeleton
|
|
16460
|
-
|
|
16461
|
-
|
|
16462
|
-
|
|
16463
|
-
|
|
16618
|
+
if (!requiresToolArcSkeleton) {
|
|
16619
|
+
const authorization = occurrences.map((occ) => occ.part.canRemove?.());
|
|
16620
|
+
if (authorization.includes("defer"))
|
|
16621
|
+
return "incomplete";
|
|
16622
|
+
if (occurrences.every((occ, index) => occ.part.remove && authorization[index] !== false)) {
|
|
16623
|
+
let removed = false;
|
|
16624
|
+
for (const occ of occurrences)
|
|
16625
|
+
removed = occ.part.remove?.() || removed;
|
|
16626
|
+
return removed ? "removed" : "absent";
|
|
16627
|
+
}
|
|
16464
16628
|
}
|
|
16465
16629
|
const sentinel = `[dropped §${tagId}§]`;
|
|
16466
16630
|
let any = false;
|
|
@@ -21104,7 +21268,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
|
|
|
21104
21268
|
emergencyDroppedTools++;
|
|
21105
21269
|
}
|
|
21106
21270
|
}
|
|
21107
|
-
})();
|
|
21271
|
+
}).immediate();
|
|
21108
21272
|
sessionLog(sessionId, `emergency tiered drop: ${plan.reason}`);
|
|
21109
21273
|
} else {
|
|
21110
21274
|
sessionLog(sessionId, `emergency tiered drop skipped: ${plan.reason}`);
|
|
@@ -21133,7 +21297,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
|
|
|
21133
21297
|
droppedStaleReduceCalls++;
|
|
21134
21298
|
}
|
|
21135
21299
|
}
|
|
21136
|
-
})();
|
|
21300
|
+
}).immediate();
|
|
21137
21301
|
}
|
|
21138
21302
|
if (routine) {
|
|
21139
21303
|
db.transaction(() => {
|
|
@@ -21170,7 +21334,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
|
|
|
21170
21334
|
}
|
|
21171
21335
|
}
|
|
21172
21336
|
}
|
|
21173
|
-
})();
|
|
21337
|
+
}).immediate();
|
|
21174
21338
|
}
|
|
21175
21339
|
const toolFingerprints = routine ? buildPiToolFingerprints(piMessages, resolveStableId) : new Map;
|
|
21176
21340
|
if (toolFingerprints.size > 0) {
|
|
@@ -21208,7 +21372,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config, pre
|
|
|
21208
21372
|
}
|
|
21209
21373
|
}
|
|
21210
21374
|
}
|
|
21211
|
-
})();
|
|
21375
|
+
}).immediate();
|
|
21212
21376
|
}
|
|
21213
21377
|
if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0 || droppedStaleReduceCalls > 0) {
|
|
21214
21378
|
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale ctx_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
@@ -23544,6 +23708,23 @@ function applyNativeReasoningReplayPi(args, saved) {
|
|
|
23544
23708
|
args.messages[index] = message;
|
|
23545
23709
|
return nextIds.size;
|
|
23546
23710
|
}
|
|
23711
|
+
function authorizePiToolRemoval(args) {
|
|
23712
|
+
if (!args.saved)
|
|
23713
|
+
return false;
|
|
23714
|
+
if (args.saved.get(args.callId) === NATIVE_TOOL_REMOVAL_MARKER)
|
|
23715
|
+
return true;
|
|
23716
|
+
if (!args.canApply)
|
|
23717
|
+
return false;
|
|
23718
|
+
try {
|
|
23719
|
+
saveNativeToolInputs(args.db, args.sessionId, new Map([[args.callId, NATIVE_TOOL_REMOVAL_MARKER]]));
|
|
23720
|
+
args.saved.set(args.callId, NATIVE_TOOL_REMOVAL_MARKER);
|
|
23721
|
+
return true;
|
|
23722
|
+
} catch (error) {
|
|
23723
|
+
sessionLog(args.sessionId, `tool arc removal persistence failed; retaining pair: ${String(error)}`);
|
|
23724
|
+
const priorDrop = args.db.prepare("SELECT 1 FROM tags WHERE session_id = ? AND type = 'tool' AND message_id = ? AND status = 'dropped' LIMIT 1").get(args.sessionId, args.callId);
|
|
23725
|
+
return priorDrop ? false : "defer";
|
|
23726
|
+
}
|
|
23727
|
+
}
|
|
23547
23728
|
|
|
23548
23729
|
// src/note-visibility-pi.ts
|
|
23549
23730
|
var NOTE_TOOL_NAME = "ctx_note";
|
|
@@ -23703,13 +23884,38 @@ function parsePersistedLkgSlot(row) {
|
|
|
23703
23884
|
const jsonPrefix = record.json_prefix;
|
|
23704
23885
|
const lastInputMessageId = record.last_input_message_id;
|
|
23705
23886
|
const capturedAt = record.captured_at;
|
|
23706
|
-
|
|
23887
|
+
let inputIdsRaw = record.input_id_seq;
|
|
23888
|
+
let piOutputEntryIds;
|
|
23889
|
+
if (typeof inputIdsRaw === "string") {
|
|
23890
|
+
try {
|
|
23891
|
+
const metadata = JSON.parse(inputIdsRaw);
|
|
23892
|
+
if (metadata && !Array.isArray(metadata) && metadata.version === 1 && Array.isArray(metadata.piOutputEntryIds)) {
|
|
23893
|
+
if (!metadata.piOutputEntryIds.every((id) => id === null || typeof id === "string" && id.length > 0))
|
|
23894
|
+
return;
|
|
23895
|
+
piOutputEntryIds = metadata.piOutputEntryIds;
|
|
23896
|
+
inputIdsRaw = JSON.stringify(metadata.inputIds);
|
|
23897
|
+
}
|
|
23898
|
+
} catch {
|
|
23899
|
+
return;
|
|
23900
|
+
}
|
|
23901
|
+
}
|
|
23902
|
+
const inputIdSeq = parseStringArray(inputIdsRaw);
|
|
23707
23903
|
const inputContentDigests = parseStringArray(record.input_content_digests);
|
|
23708
23904
|
const modelKey = parseNullableString(record.model_key);
|
|
23709
23905
|
const providerKey = parseNullableString(record.provider_key);
|
|
23710
23906
|
if (typeof jsonPrefix !== "string" || typeof lastInputMessageId !== "string" || lastInputMessageId.length === 0 || typeof capturedAt !== "number" || !Number.isFinite(capturedAt) || inputIdSeq === null || inputContentDigests === null || inputContentDigests.length !== inputIdSeq.length || modelKey === undefined || providerKey === undefined) {
|
|
23711
23907
|
return;
|
|
23712
23908
|
}
|
|
23909
|
+
if (piOutputEntryIds) {
|
|
23910
|
+
try {
|
|
23911
|
+
const output = JSON.parse(jsonPrefix);
|
|
23912
|
+
const inputs = new Set(inputIdSeq);
|
|
23913
|
+
if (!Array.isArray(output) || output.length !== piOutputEntryIds.length || piOutputEntryIds.some((id) => id !== null && !inputs.has(id)))
|
|
23914
|
+
return;
|
|
23915
|
+
} catch {
|
|
23916
|
+
return;
|
|
23917
|
+
}
|
|
23918
|
+
}
|
|
23713
23919
|
let inputContentSignatures;
|
|
23714
23920
|
if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
|
|
23715
23921
|
const parsed = parseStringArray(record.input_content_signatures);
|
|
@@ -23728,6 +23934,8 @@ function parsePersistedLkgSlot(row) {
|
|
|
23728
23934
|
};
|
|
23729
23935
|
if (inputContentSignatures)
|
|
23730
23936
|
slot.inputContentSignatures = inputContentSignatures;
|
|
23937
|
+
if (piOutputEntryIds)
|
|
23938
|
+
slot.piOutputEntryIds = piOutputEntryIds;
|
|
23731
23939
|
const rowVersion = parseNullableInteger(record.row_version);
|
|
23732
23940
|
if (rowVersion !== undefined)
|
|
23733
23941
|
slot.rowVersion = rowVersion;
|
|
@@ -23753,7 +23961,11 @@ function saveLkgSlotToDb(db, sessionId, slot) {
|
|
|
23753
23961
|
provider_key = excluded.provider_key,
|
|
23754
23962
|
captured_at = excluded.captured_at,
|
|
23755
23963
|
row_version = excluded.row_version,
|
|
23756
|
-
capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.
|
|
23964
|
+
capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.piOutputEntryIds ? {
|
|
23965
|
+
version: 1,
|
|
23966
|
+
inputIds: slot.inputIdSeq,
|
|
23967
|
+
piOutputEntryIds: slot.piOutputEntryIds
|
|
23968
|
+
} : slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
|
|
23757
23969
|
return true;
|
|
23758
23970
|
} catch (error) {
|
|
23759
23971
|
sessionLog(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
|
|
@@ -23812,7 +24024,8 @@ function registerLkgPersistence(backend) {
|
|
|
23812
24024
|
}
|
|
23813
24025
|
function slotBytes(slot) {
|
|
23814
24026
|
const digestBytes = slot.inputContentDigests.reduce((total, digest) => total + 2 * digest.length, 0);
|
|
23815
|
-
|
|
24027
|
+
const ownershipBytes = slot.piOutputEntryIds?.reduce((total, id) => total + (id?.length ?? 0) * 2 + 8, 0) ?? 0;
|
|
24028
|
+
return 2 * slot.jsonPrefix.length + digestBytes + ownershipBytes + LKG_METADATA_BYTES;
|
|
23816
24029
|
}
|
|
23817
24030
|
var LKG_SNAPSHOT_ARRAY = Symbol("array");
|
|
23818
24031
|
var LKG_SNAPSHOT_OBJECT = Symbol("object");
|
|
@@ -23973,6 +24186,7 @@ function captureSlot(sessionId, slot) {
|
|
|
23973
24186
|
const entry = {
|
|
23974
24187
|
slot: {
|
|
23975
24188
|
...slot,
|
|
24189
|
+
...slot.piOutputEntryIds ? { piOutputEntryIds: [...slot.piOutputEntryIds] } : {},
|
|
23976
24190
|
inputIdSeq: [...slot.inputIdSeq],
|
|
23977
24191
|
inputContentDigests: [...slot.inputContentDigests],
|
|
23978
24192
|
inputContentSignatures: slot.inputContentSignatures ? [...slot.inputContentSignatures] : undefined
|
|
@@ -24011,6 +24225,7 @@ function installHydratedSlot(sessionId, slot) {
|
|
|
24011
24225
|
const entry = {
|
|
24012
24226
|
slot: {
|
|
24013
24227
|
...slot,
|
|
24228
|
+
...slot.piOutputEntryIds ? { piOutputEntryIds: [...slot.piOutputEntryIds] } : {},
|
|
24014
24229
|
inputIdSeq: [...slot.inputIdSeq],
|
|
24015
24230
|
inputContentDigests: [...slot.inputContentDigests],
|
|
24016
24231
|
inputContentSignatures: slot.inputContentSignatures ? [...slot.inputContentSignatures] : undefined
|
|
@@ -24043,6 +24258,7 @@ function hydrateSlotFromPersistence(sessionId) {
|
|
|
24043
24258
|
function copySlotForRead(slot) {
|
|
24044
24259
|
return {
|
|
24045
24260
|
...slot,
|
|
24261
|
+
...slot.piOutputEntryIds ? { piOutputEntryIds: [...slot.piOutputEntryIds] } : {},
|
|
24046
24262
|
inputIdSeq: [...slot.inputIdSeq],
|
|
24047
24263
|
inputContentDigests: [...slot.inputContentDigests],
|
|
24048
24264
|
inputContentSignatures: slot.inputContentSignatures ? [...slot.inputContentSignatures] : undefined
|
|
@@ -24521,16 +24737,13 @@ function snapshotInputs(messages, entryIds) {
|
|
|
24521
24737
|
}
|
|
24522
24738
|
const inputs = [];
|
|
24523
24739
|
const seen = new Set;
|
|
24524
|
-
for (let index =
|
|
24525
|
-
const id = entryIds[index];
|
|
24526
|
-
if (typeof id !== "string" || id.length === 0) {
|
|
24527
|
-
return { inputs: [], failure: "lkg_entry_id_gap" };
|
|
24528
|
-
}
|
|
24529
|
-
if (seen.has(id))
|
|
24530
|
-
return { inputs: [], failure: "lkg_duplicate_entry_id" };
|
|
24740
|
+
for (let index = 0;index < entryIds.length; index += 1) {
|
|
24531
24741
|
const fields = lkgContentFields(messages[index]);
|
|
24532
24742
|
if (!fields)
|
|
24533
24743
|
return { inputs: [], failure: "lkg_content_snapshot_failed" };
|
|
24744
|
+
const id = entryIds[index] || `pi-lkg-unmapped:${lkgContentDigestFromFields(fields)}`;
|
|
24745
|
+
if (seen.has(id))
|
|
24746
|
+
return { inputs: [], failure: "lkg_duplicate_entry_id" };
|
|
24534
24747
|
seen.add(id);
|
|
24535
24748
|
inputs.push({ id, messageIndex: index, fields });
|
|
24536
24749
|
}
|
|
@@ -24626,6 +24839,29 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
|
|
|
24626
24839
|
if (snapshot.replayAnchorInputIndex === null || snapshot.pristineTail === null) {
|
|
24627
24840
|
return { ok: false, reason: "lkg_miss" };
|
|
24628
24841
|
}
|
|
24842
|
+
const slot = getSlot(snapshot.sessionId);
|
|
24843
|
+
const start = slot?.inputIdSeq.indexOf(snapshot.inputs[0]?.id ?? "") ?? -1;
|
|
24844
|
+
if (slot && start > 0) {
|
|
24845
|
+
const ownership = slot.piOutputEntryIds;
|
|
24846
|
+
if (!ownership)
|
|
24847
|
+
return { ok: false, reason: "lkg_output_mapping_unavailable" };
|
|
24848
|
+
if (slot.modelKey !== snapshot.modelKey || slot.providerKey !== snapshot.providerKey)
|
|
24849
|
+
return { ok: false, reason: "lkg_model_mismatch" };
|
|
24850
|
+
const surviving = snapshot.inputs.slice(0, snapshot.replayAnchorInputIndex + 1);
|
|
24851
|
+
if (surviving.length !== slot.inputIdSeq.length - start || surviving.some((input, index) => input.id !== slot.inputIdSeq[start + index]))
|
|
24852
|
+
return { ok: false, reason: "lkg_invalidated_reshape" };
|
|
24853
|
+
if (surviving.some((input, index) => lkgContentDigestFromFields(input.fields) !== slot.inputContentDigests[start + index]))
|
|
24854
|
+
return { ok: false, reason: "lkg_content_mismatch" };
|
|
24855
|
+
const removed = new Set(slot.inputIdSeq.slice(0, start));
|
|
24856
|
+
const prefix = JSON.parse(slot.jsonPrefix);
|
|
24857
|
+
return {
|
|
24858
|
+
ok: true,
|
|
24859
|
+
messages: [
|
|
24860
|
+
...prefix.filter((_, index) => ownership[index] === null || !removed.has(ownership[index] ?? "")),
|
|
24861
|
+
...snapshot.pristineTail
|
|
24862
|
+
]
|
|
24863
|
+
};
|
|
24864
|
+
}
|
|
24629
24865
|
const entry = {
|
|
24630
24866
|
pristineTail: snapshot.pristineTail,
|
|
24631
24867
|
entryInputIds: snapshot.inputs.map((input) => input.id),
|
|
@@ -24662,6 +24898,22 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
|
|
|
24662
24898
|
return;
|
|
24663
24899
|
}
|
|
24664
24900
|
const state = stateFor(snapshot.sessionId);
|
|
24901
|
+
const idsByDigest = new Map;
|
|
24902
|
+
if (!args.outputEntryIds)
|
|
24903
|
+
for (const input of snapshot.inputs) {
|
|
24904
|
+
const digest = lkgContentDigestFromFields(input.fields);
|
|
24905
|
+
idsByDigest.set(digest, idsByDigest.has(digest) ? undefined : input.id);
|
|
24906
|
+
}
|
|
24907
|
+
const inferredIds = args.outputEntryIds ?? args.outputMessages.map((message) => {
|
|
24908
|
+
const fields = lkgContentFields(message);
|
|
24909
|
+
if (!fields)
|
|
24910
|
+
return;
|
|
24911
|
+
const digest = lkgContentDigestFromFields(fields);
|
|
24912
|
+
return idsByDigest.get(digest);
|
|
24913
|
+
});
|
|
24914
|
+
const outputIds = args.outputEntryIds ?? inferredIds;
|
|
24915
|
+
const inputIds = new Set(snapshot.inputs.map((input) => input.id));
|
|
24916
|
+
const ownership = outputIds.length === args.outputMessages.length && outputIds.every((id) => id === null || typeof id === "string" && inputIds.has(id)) ? [...outputIds] : undefined;
|
|
24665
24917
|
state.captureSequence += 1;
|
|
24666
24918
|
const plan = {
|
|
24667
24919
|
sessionId: snapshot.sessionId,
|
|
@@ -24702,6 +24954,7 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
|
|
|
24702
24954
|
reusedPrefix = incremental.reusedPrefix;
|
|
24703
24955
|
const slot = {
|
|
24704
24956
|
jsonPrefix: plan.jsonPrefix,
|
|
24957
|
+
piOutputEntryIds: ownership,
|
|
24705
24958
|
inputIdSeq,
|
|
24706
24959
|
inputContentDigests: incremental.digests,
|
|
24707
24960
|
inputContentSignatures,
|
|
@@ -24749,6 +25002,24 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
|
|
|
24749
25002
|
};
|
|
24750
25003
|
return { beginPass, replay, captureAppliedPass };
|
|
24751
25004
|
}
|
|
25005
|
+
function resolvePiLkgOutputEntryIds(messages, syntheticLeadingCount, entryId) {
|
|
25006
|
+
const ids = messages.map((message, index) => index < syntheticLeadingCount ? null : isRecord(message) ? entryId(message) : undefined);
|
|
25007
|
+
const syntheticOwners = new Map;
|
|
25008
|
+
for (let index = 0;index < messages.length; index++) {
|
|
25009
|
+
const message = messages[index];
|
|
25010
|
+
const owner = ids[index];
|
|
25011
|
+
if (typeof owner !== "string" || !isRecord(message) || message.role !== "assistant" || !Array.isArray(message.content))
|
|
25012
|
+
continue;
|
|
25013
|
+
for (const part of message.content) {
|
|
25014
|
+
if (isRecord(part) && part.type === "toolCall" && part.syntheticTodoMarker === true && typeof part.id === "string")
|
|
25015
|
+
syntheticOwners.set(part.id, syntheticOwners.has(part.id) ? undefined : owner);
|
|
25016
|
+
}
|
|
25017
|
+
}
|
|
25018
|
+
return ids.map((id, index) => {
|
|
25019
|
+
const message = messages[index];
|
|
25020
|
+
return id === undefined && isRecord(message) && message.role === "toolResult" && message.syntheticTodoMarker === true && typeof message.toolCallId === "string" ? syntheticOwners.get(message.toolCallId) : id;
|
|
25021
|
+
});
|
|
25022
|
+
}
|
|
24752
25023
|
|
|
24753
25024
|
// src/pi-pressure.ts
|
|
24754
25025
|
function extractAssistantUsage(message) {
|
|
@@ -26593,7 +26864,9 @@ function createPiAssistantPart(working, messageIndex, partIndex, markDirty) {
|
|
|
26593
26864
|
canRemove() {
|
|
26594
26865
|
const message = working[messageIndex];
|
|
26595
26866
|
const part = message.content[partIndex];
|
|
26596
|
-
|
|
26867
|
+
if (part?.type !== "toolCall" || !canRemoveNativeToolCall(message, part.id))
|
|
26868
|
+
return false;
|
|
26869
|
+
return toolRemovalAuthorization.get(working)?.(part.id) ?? true;
|
|
26597
26870
|
},
|
|
26598
26871
|
remove() {
|
|
26599
26872
|
return markToolRemoval(working, messageIndex, partIndex);
|
|
@@ -27627,6 +27900,9 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
27627
27900
|
modelKey: lkgModelKey,
|
|
27628
27901
|
providerKey: lkgProviderKey
|
|
27629
27902
|
});
|
|
27903
|
+
const lkgInputIdByRef = new Map;
|
|
27904
|
+
for (const input of lkgPassSnapshot.inputs)
|
|
27905
|
+
lkgInputIdByRef.set(event.messages[input.messageIndex], input.id);
|
|
27630
27906
|
const thinkingBindingRecoveryApplied = applyPiThinkingBindingRecovery({
|
|
27631
27907
|
db: options.db,
|
|
27632
27908
|
sessionId,
|
|
@@ -27935,6 +28211,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
27935
28211
|
projectDirectory,
|
|
27936
28212
|
sessionMeta,
|
|
27937
28213
|
messages: event.messages,
|
|
28214
|
+
lkgEntryIds: event.messages.map((message) => lkgInputIdByRef.get(message)),
|
|
27938
28215
|
smartDrops: options.smartDrops === true,
|
|
27939
28216
|
protectedTags: options.protectedTags ?? 20,
|
|
27940
28217
|
protectedTokens: options.protectedTokens,
|
|
@@ -28214,6 +28491,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
28214
28491
|
lkgCoordinator.captureAppliedPass({
|
|
28215
28492
|
snapshot: lkgPassSnapshot,
|
|
28216
28493
|
outputMessages,
|
|
28494
|
+
outputEntryIds: resolvePiLkgOutputEntryIds(outputMessages, result.syntheticLeadingCount, (message) => result.postCommitEntryIdByRef.get(message) ?? result.lkgEntryIdByRef.get(message)),
|
|
28217
28495
|
cacheBusting: result.bustedThisPass
|
|
28218
28496
|
});
|
|
28219
28497
|
}
|
|
@@ -28774,7 +29052,8 @@ async function runCompactionOffPipeline(args) {
|
|
|
28774
29052
|
protectedTagNumbers: new Set,
|
|
28775
29053
|
pendingDropTagNumbers: new Set
|
|
28776
29054
|
},
|
|
28777
|
-
postCommitEntryIdByRef: new Map
|
|
29055
|
+
postCommitEntryIdByRef: new Map,
|
|
29056
|
+
lkgEntryIdByRef: new Map
|
|
28778
29057
|
};
|
|
28779
29058
|
}
|
|
28780
29059
|
async function runPipeline(args) {
|
|
@@ -28816,22 +29095,13 @@ async function runPipeline(args) {
|
|
|
28816
29095
|
const tTranscriptBuild = performance.now();
|
|
28817
29096
|
const transcript = createPiTranscript(args.messages, args.sessionId, args.entryIds, {
|
|
28818
29097
|
preserveReasoningToolArcs: args.reasoningClearing?.preserveReasoningToolArcs,
|
|
28819
|
-
authorizeToolRemoval: (callId) => {
|
|
28820
|
-
|
|
28821
|
-
|
|
28822
|
-
|
|
28823
|
-
|
|
28824
|
-
|
|
28825
|
-
|
|
28826
|
-
try {
|
|
28827
|
-
saveNativeToolInputs(args.db, args.sessionId, new Map([[callId, NATIVE_TOOL_REMOVAL_MARKER]]));
|
|
28828
|
-
nativeRemovalInputs.set(callId, NATIVE_TOOL_REMOVAL_MARKER);
|
|
28829
|
-
return true;
|
|
28830
|
-
} catch (error) {
|
|
28831
|
-
sessionLog(args.sessionId, `tool arc removal persistence failed; retaining pair: ${String(error)}`);
|
|
28832
|
-
return false;
|
|
28833
|
-
}
|
|
28834
|
-
}
|
|
29098
|
+
authorizeToolRemoval: (callId) => authorizePiToolRemoval({
|
|
29099
|
+
db: args.db,
|
|
29100
|
+
sessionId: args.sessionId,
|
|
29101
|
+
callId,
|
|
29102
|
+
saved: nativeRemovalInputs,
|
|
29103
|
+
canApply: isCacheBustingPass
|
|
29104
|
+
})
|
|
28835
29105
|
});
|
|
28836
29106
|
logTransformTiming(args.sessionId, "transcriptBuild", tTranscriptBuild);
|
|
28837
29107
|
const workingMessages = transcript.getWorkingMessages();
|
|
@@ -29377,6 +29647,7 @@ async function runPipeline(args) {
|
|
|
29377
29647
|
const tPostCommitStableIdMaps = performance.now();
|
|
29378
29648
|
const postCommitStableIdByRef = new Map;
|
|
29379
29649
|
const postCommitEntryIdByRef = new Map;
|
|
29650
|
+
const lkgEntryIdByRef = new Map;
|
|
29380
29651
|
for (let i = 0;i < args.messages.length; i++) {
|
|
29381
29652
|
const m = args.messages[i];
|
|
29382
29653
|
if (!m || typeof m !== "object")
|
|
@@ -29384,6 +29655,9 @@ async function runPipeline(args) {
|
|
|
29384
29655
|
const id = resolvePiStableId(m, i, args.entryIds, args.entryIdByRef ?? undefined);
|
|
29385
29656
|
if (id)
|
|
29386
29657
|
postCommitStableIdByRef.set(m, id);
|
|
29658
|
+
const lkgId = args.lkgEntryIds?.[i];
|
|
29659
|
+
if (lkgId)
|
|
29660
|
+
lkgEntryIdByRef.set(m, lkgId);
|
|
29387
29661
|
const realId = args.entryIds?.[i];
|
|
29388
29662
|
if (typeof realId === "string" && realId.length > 0) {
|
|
29389
29663
|
postCommitEntryIdByRef.set(m, realId);
|
|
@@ -29548,7 +29822,8 @@ async function runPipeline(args) {
|
|
|
29548
29822
|
reasoningWatermark: args.sessionMeta.clearedReasoningThroughTag ?? 0,
|
|
29549
29823
|
activeTags,
|
|
29550
29824
|
channelBaselineSnapshot,
|
|
29551
|
-
postCommitEntryIdByRef
|
|
29825
|
+
postCommitEntryIdByRef,
|
|
29826
|
+
lkgEntryIdByRef
|
|
29552
29827
|
};
|
|
29553
29828
|
}
|
|
29554
29829
|
var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
@@ -32364,7 +32639,7 @@ function formatTailHygiene(status) {
|
|
|
32364
32639
|
// package.json
|
|
32365
32640
|
var package_default = {
|
|
32366
32641
|
name: "@cortexkit/pi-magic-context",
|
|
32367
|
-
version: "0.42.
|
|
32642
|
+
version: "0.42.3",
|
|
32368
32643
|
type: "module",
|
|
32369
32644
|
description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
|
|
32370
32645
|
main: "dist/index.js",
|
|
@@ -32395,7 +32670,7 @@ var package_default = {
|
|
|
32395
32670
|
build: "tsc -p ../retina-local-fs/tsconfig.build.json && rm -f dist/index.js dist/subagent-entry.js dist/historian-calibration-extension.js dist/transformers-web.js dist/transformers-node-wasm.js dist/*-*.js && bun build ../plugin/src/features/magic-context/memory/transformers-web-entry.ts --outfile dist/transformers-web.js --target browser --format esm --external onnxruntime-web && bun ../plugin/scripts/build-transformers-node-wasm.ts dist && bun build src/index.ts src/subagent-entry.ts src/historian-calibration-extension.ts --outdir dist --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external onnxruntime-node --external onnxruntime-web --external sharp --external node:sqlite",
|
|
32396
32671
|
"build:e2e-argv": "bun build src/subagent-runner.ts --outfile ../../tests/docker/.generated/subagent-runner-e2e.mjs --target node --format esm --external node:sqlite",
|
|
32397
32672
|
typecheck: "tsc -p ../retina-local-fs/tsconfig.build.json && tsc --noEmit",
|
|
32398
|
-
test: "bun install --frozen-lockfile && bun test",
|
|
32673
|
+
test: "bun install --frozen-lockfile && bun test --parallel --timeout 30000",
|
|
32399
32674
|
lint: "biome check src",
|
|
32400
32675
|
"lint:fix": "biome check --write src",
|
|
32401
32676
|
format: "biome format --write src",
|