@cortexkit/pi-magic-context 0.21.6 → 0.21.7
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.js +885 -337
- package/dist/subagent-entry.js +251 -73
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8163,10 +8163,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8163
8163
|
replacer = null;
|
|
8164
8164
|
indent = EMPTY;
|
|
8165
8165
|
};
|
|
8166
|
-
var
|
|
8166
|
+
var join10 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
8167
8167
|
var join_content = (inside, value, gap) => {
|
|
8168
8168
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
8169
|
-
return
|
|
8169
|
+
return join10(comment, inside, gap);
|
|
8170
8170
|
};
|
|
8171
8171
|
var stringify_string = (holder, key, value) => {
|
|
8172
8172
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -8188,13 +8188,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8188
8188
|
if (i !== 0) {
|
|
8189
8189
|
inside += COMMA;
|
|
8190
8190
|
}
|
|
8191
|
-
const before =
|
|
8191
|
+
const before = join10(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
8192
8192
|
inside += before || LF + deeper_gap;
|
|
8193
8193
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
8194
8194
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
8195
8195
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
8196
8196
|
}
|
|
8197
|
-
inside +=
|
|
8197
|
+
inside += join10(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
8198
8198
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
8199
8199
|
};
|
|
8200
8200
|
var object_stringify = (value, gap) => {
|
|
@@ -8215,13 +8215,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8215
8215
|
inside += COMMA;
|
|
8216
8216
|
}
|
|
8217
8217
|
first = false;
|
|
8218
|
-
const before =
|
|
8218
|
+
const before = join10(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
8219
8219
|
inside += before || LF + deeper_gap;
|
|
8220
8220
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
8221
8221
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
8222
8222
|
};
|
|
8223
8223
|
keys.forEach(iteratee);
|
|
8224
|
-
inside +=
|
|
8224
|
+
inside += join10(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
8225
8225
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
8226
8226
|
};
|
|
8227
8227
|
function stringify(key, holder, gap) {
|
|
@@ -8343,7 +8343,57 @@ var init_rpc_notifications = __esm(() => {
|
|
|
8343
8343
|
|
|
8344
8344
|
// src/index.ts
|
|
8345
8345
|
import { createRequire as createRequire4 } from "node:module";
|
|
8346
|
-
import { join as
|
|
8346
|
+
import { join as join20 } from "node:path";
|
|
8347
|
+
|
|
8348
|
+
// ../plugin/src/config/agent-disable.ts
|
|
8349
|
+
function isDreamerRunnable(config) {
|
|
8350
|
+
return !!config.dreamer && config.dreamer.disable !== true;
|
|
8351
|
+
}
|
|
8352
|
+
function clonePlainObject(value) {
|
|
8353
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
8354
|
+
return;
|
|
8355
|
+
}
|
|
8356
|
+
return { ...value };
|
|
8357
|
+
}
|
|
8358
|
+
function migrateLegacyEnabledForAgent(args) {
|
|
8359
|
+
const agent = clonePlainObject(args.patched[args.agentName]);
|
|
8360
|
+
if (!agent || !("enabled" in agent))
|
|
8361
|
+
return;
|
|
8362
|
+
const enabled = agent.enabled;
|
|
8363
|
+
const disable = agent.disable;
|
|
8364
|
+
delete agent.enabled;
|
|
8365
|
+
if (args.agentName === "historian") {
|
|
8366
|
+
args.warnings.push('Removed invalid "historian.enabled" in-memory (run doctor to persist).');
|
|
8367
|
+
args.patched.historian = agent;
|
|
8368
|
+
return;
|
|
8369
|
+
}
|
|
8370
|
+
if (args.agentName === "dreamer") {
|
|
8371
|
+
if (disable !== true && enabled === false) {
|
|
8372
|
+
agent.disable = true;
|
|
8373
|
+
args.warnings.push('Migrated "dreamer.enabled=false" → "dreamer.disable=true" in-memory (run doctor to persist). This now also disables manual /ctx-dream; for manual-only remove disable and set schedule="".');
|
|
8374
|
+
}
|
|
8375
|
+
args.patched.dreamer = agent;
|
|
8376
|
+
return;
|
|
8377
|
+
}
|
|
8378
|
+
if (disable !== true && enabled === false) {
|
|
8379
|
+
agent.disable = true;
|
|
8380
|
+
args.warnings.push('Migrated "sidekick.enabled=false" → "sidekick.disable=true" in-memory (run doctor to persist).');
|
|
8381
|
+
}
|
|
8382
|
+
args.patched.sidekick = agent;
|
|
8383
|
+
}
|
|
8384
|
+
function migrateLegacyAgentEnabledInMemory(rawConfig, warnings) {
|
|
8385
|
+
const shouldPatch = ["dreamer", "sidekick", "historian"].some((key) => {
|
|
8386
|
+
const agent = rawConfig[key];
|
|
8387
|
+
return typeof agent === "object" && agent !== null && !Array.isArray(agent) && "enabled" in agent;
|
|
8388
|
+
});
|
|
8389
|
+
if (!shouldPatch)
|
|
8390
|
+
return rawConfig;
|
|
8391
|
+
const patched = { ...rawConfig };
|
|
8392
|
+
migrateLegacyEnabledForAgent({ patched, agentName: "dreamer", warnings });
|
|
8393
|
+
migrateLegacyEnabledForAgent({ patched, agentName: "sidekick", warnings });
|
|
8394
|
+
migrateLegacyEnabledForAgent({ patched, agentName: "historian", warnings });
|
|
8395
|
+
return patched;
|
|
8396
|
+
}
|
|
8347
8397
|
|
|
8348
8398
|
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
8349
8399
|
import { execSync } from "node:child_process";
|
|
@@ -141830,6 +141880,40 @@ function parseReportedLimit(message) {
|
|
|
141830
141880
|
}
|
|
141831
141881
|
return;
|
|
141832
141882
|
}
|
|
141883
|
+
// ../plugin/src/features/magic-context/compartment-lease.ts
|
|
141884
|
+
var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
141885
|
+
var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
|
|
141886
|
+
function acquireCompartmentLease(db, sessionId, holderId) {
|
|
141887
|
+
const acquiredAt = Date.now();
|
|
141888
|
+
const expiresAt = acquiredAt + COMPARTMENT_LEASE_TTL_MS;
|
|
141889
|
+
const result = db.prepare(`INSERT INTO compartment_state_lease (session_id, holder_id, acquired_at, expires_at)
|
|
141890
|
+
VALUES (?, ?, ?, ?)
|
|
141891
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
141892
|
+
holder_id = excluded.holder_id,
|
|
141893
|
+
acquired_at = excluded.acquired_at,
|
|
141894
|
+
expires_at = excluded.expires_at
|
|
141895
|
+
WHERE compartment_state_lease.holder_id = excluded.holder_id
|
|
141896
|
+
OR compartment_state_lease.expires_at <= ?`).run(sessionId, holderId, acquiredAt, expiresAt, acquiredAt);
|
|
141897
|
+
if (result.changes !== 1) {
|
|
141898
|
+
return null;
|
|
141899
|
+
}
|
|
141900
|
+
return { sessionId, holderId, acquiredAt, expiresAt };
|
|
141901
|
+
}
|
|
141902
|
+
function renewCompartmentLease(db, sessionId, holderId) {
|
|
141903
|
+
const now = Date.now();
|
|
141904
|
+
const expiresAt = now + COMPARTMENT_LEASE_TTL_MS;
|
|
141905
|
+
const result = db.prepare(`UPDATE compartment_state_lease
|
|
141906
|
+
SET expires_at = ?, acquired_at = ?
|
|
141907
|
+
WHERE session_id = ? AND holder_id = ? AND expires_at > ?`).run(expiresAt, now, sessionId, holderId, now);
|
|
141908
|
+
return result.changes === 1;
|
|
141909
|
+
}
|
|
141910
|
+
function releaseCompartmentLease(db, sessionId, holderId) {
|
|
141911
|
+
db.prepare("DELETE FROM compartment_state_lease WHERE session_id = ? AND holder_id = ?").run(sessionId, holderId);
|
|
141912
|
+
}
|
|
141913
|
+
function isCompartmentLeaseHeld(db, sessionId, holderId) {
|
|
141914
|
+
const row = db.prepare("SELECT 1 FROM compartment_state_lease WHERE session_id = ? AND holder_id = ? AND expires_at > ?").get(sessionId, holderId, Date.now());
|
|
141915
|
+
return row != null;
|
|
141916
|
+
}
|
|
141833
141917
|
|
|
141834
141918
|
// ../plugin/src/features/magic-context/compartment-storage.ts
|
|
141835
141919
|
var insertCompartmentStatements = new WeakMap;
|
|
@@ -141940,6 +142024,38 @@ function replaceAllCompartmentState(db, sessionId, compartments, facts) {
|
|
|
141940
142024
|
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
141941
142025
|
})();
|
|
141942
142026
|
}
|
|
142027
|
+
function replaceAllCompartmentStateAndBumpDepth(db, holderId, sessionId, compartments, facts, depthStartOrdinal, depthEndOrdinal) {
|
|
142028
|
+
const now = Date.now();
|
|
142029
|
+
db.exec("BEGIN IMMEDIATE");
|
|
142030
|
+
let finished = false;
|
|
142031
|
+
try {
|
|
142032
|
+
if (!isCompartmentLeaseHeld(db, sessionId, holderId)) {
|
|
142033
|
+
db.exec("ROLLBACK");
|
|
142034
|
+
finished = true;
|
|
142035
|
+
return false;
|
|
142036
|
+
}
|
|
142037
|
+
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
142038
|
+
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
142039
|
+
insertCompartmentRows(db, sessionId, compartments, now);
|
|
142040
|
+
insertFactRows(db, sessionId, facts, now);
|
|
142041
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
142042
|
+
if (depthEndOrdinal >= depthStartOrdinal) {
|
|
142043
|
+
const stmt = getIncrementDepthStatement(db);
|
|
142044
|
+
for (let ordinal = depthStartOrdinal;ordinal <= depthEndOrdinal; ordinal += 1) {
|
|
142045
|
+
stmt.run(sessionId, ordinal, getHarness());
|
|
142046
|
+
}
|
|
142047
|
+
}
|
|
142048
|
+
db.exec("COMMIT");
|
|
142049
|
+
finished = true;
|
|
142050
|
+
return true;
|
|
142051
|
+
} finally {
|
|
142052
|
+
if (!finished) {
|
|
142053
|
+
try {
|
|
142054
|
+
db.exec("ROLLBACK");
|
|
142055
|
+
} catch {}
|
|
142056
|
+
}
|
|
142057
|
+
}
|
|
142058
|
+
}
|
|
141943
142059
|
function buildCompartmentBlock(compartments, facts, memoryBlock, dateRanges) {
|
|
141944
142060
|
const lines = [];
|
|
141945
142061
|
if (memoryBlock) {
|
|
@@ -142007,12 +142123,37 @@ function getRecompStaging(db, sessionId) {
|
|
|
142007
142123
|
lastEndMessage: lastEnd
|
|
142008
142124
|
};
|
|
142009
142125
|
}
|
|
142010
|
-
function promoteRecompStaging(db, sessionId) {
|
|
142126
|
+
function promoteRecompStaging(db, sessionId, holderId) {
|
|
142011
142127
|
const now = Date.now();
|
|
142012
|
-
|
|
142128
|
+
if (!holderId) {
|
|
142129
|
+
return db.transaction(() => {
|
|
142130
|
+
const staging = getRecompStaging(db, sessionId);
|
|
142131
|
+
if (!staging || staging.compartments.length === 0)
|
|
142132
|
+
return null;
|
|
142133
|
+
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
142134
|
+
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
142135
|
+
insertCompartmentRows(db, sessionId, staging.compartments, now);
|
|
142136
|
+
insertFactRows(db, sessionId, staging.facts, now);
|
|
142137
|
+
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
142138
|
+
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
142139
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
142140
|
+
return { compartments: staging.compartments, facts: staging.facts };
|
|
142141
|
+
})();
|
|
142142
|
+
}
|
|
142143
|
+
db.exec("BEGIN IMMEDIATE");
|
|
142144
|
+
let finished = false;
|
|
142145
|
+
try {
|
|
142146
|
+
if (!isCompartmentLeaseHeld(db, sessionId, holderId)) {
|
|
142147
|
+
db.exec("ROLLBACK");
|
|
142148
|
+
finished = true;
|
|
142149
|
+
return null;
|
|
142150
|
+
}
|
|
142013
142151
|
const staging = getRecompStaging(db, sessionId);
|
|
142014
|
-
if (!staging || staging.compartments.length === 0)
|
|
142152
|
+
if (!staging || staging.compartments.length === 0) {
|
|
142153
|
+
db.exec("ROLLBACK");
|
|
142154
|
+
finished = true;
|
|
142015
142155
|
return null;
|
|
142156
|
+
}
|
|
142016
142157
|
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
142017
142158
|
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
142018
142159
|
insertCompartmentRows(db, sessionId, staging.compartments, now);
|
|
@@ -142020,8 +142161,16 @@ function promoteRecompStaging(db, sessionId) {
|
|
|
142020
142161
|
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
142021
142162
|
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
142022
142163
|
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
142164
|
+
db.exec("COMMIT");
|
|
142165
|
+
finished = true;
|
|
142023
142166
|
return { compartments: staging.compartments, facts: staging.facts };
|
|
142024
|
-
}
|
|
142167
|
+
} finally {
|
|
142168
|
+
if (!finished) {
|
|
142169
|
+
try {
|
|
142170
|
+
db.exec("ROLLBACK");
|
|
142171
|
+
} catch {}
|
|
142172
|
+
}
|
|
142173
|
+
}
|
|
142025
142174
|
}
|
|
142026
142175
|
function invalidateAllMemoryBlockCaches(db) {
|
|
142027
142176
|
try {
|
|
@@ -142669,6 +142818,22 @@ var MIGRATIONS = [
|
|
|
142669
142818
|
db.exec("ALTER TABLE session_meta ADD COLUMN pending_pi_compaction_marker_state TEXT");
|
|
142670
142819
|
}
|
|
142671
142820
|
}
|
|
142821
|
+
},
|
|
142822
|
+
{
|
|
142823
|
+
version: 19,
|
|
142824
|
+
description: "Add compartment state lease table",
|
|
142825
|
+
up: (db) => {
|
|
142826
|
+
db.exec(`
|
|
142827
|
+
CREATE TABLE IF NOT EXISTS compartment_state_lease (
|
|
142828
|
+
session_id TEXT PRIMARY KEY NOT NULL,
|
|
142829
|
+
holder_id TEXT NOT NULL,
|
|
142830
|
+
acquired_at INTEGER NOT NULL,
|
|
142831
|
+
expires_at INTEGER NOT NULL
|
|
142832
|
+
);
|
|
142833
|
+
CREATE INDEX IF NOT EXISTS idx_compartment_state_lease_expires
|
|
142834
|
+
ON compartment_state_lease(expires_at);
|
|
142835
|
+
`);
|
|
142836
|
+
}
|
|
142672
142837
|
}
|
|
142673
142838
|
];
|
|
142674
142839
|
function ensureMigrationsTable(db) {
|
|
@@ -143124,6 +143289,15 @@ function initializeDatabase(db) {
|
|
|
143124
143289
|
);
|
|
143125
143290
|
CREATE INDEX IF NOT EXISTS idx_compartments_session ON compartments(session_id);
|
|
143126
143291
|
|
|
143292
|
+
CREATE TABLE IF NOT EXISTS compartment_state_lease (
|
|
143293
|
+
session_id TEXT PRIMARY KEY NOT NULL,
|
|
143294
|
+
holder_id TEXT NOT NULL,
|
|
143295
|
+
acquired_at INTEGER NOT NULL,
|
|
143296
|
+
expires_at INTEGER NOT NULL
|
|
143297
|
+
);
|
|
143298
|
+
CREATE INDEX IF NOT EXISTS idx_compartment_state_lease_expires
|
|
143299
|
+
ON compartment_state_lease(expires_at);
|
|
143300
|
+
|
|
143127
143301
|
CREATE TABLE IF NOT EXISTS compression_depth (
|
|
143128
143302
|
session_id TEXT NOT NULL,
|
|
143129
143303
|
message_ordinal INTEGER NOT NULL,
|
|
@@ -144046,6 +144220,7 @@ function getPendingPiCompactionMarkerState(db, sessionId) {
|
|
|
144046
144220
|
return parsed;
|
|
144047
144221
|
}
|
|
144048
144222
|
} catch {}
|
|
144223
|
+
db.prepare("UPDATE session_meta SET pending_pi_compaction_marker_state = NULL WHERE session_id = ? AND pending_pi_compaction_marker_state = ?").run(sessionId, raw);
|
|
144049
144224
|
return null;
|
|
144050
144225
|
}
|
|
144051
144226
|
function setPendingPiCompactionMarkerState(db, sessionId, state) {
|
|
@@ -145266,10 +145441,98 @@ function isTodoItem(value) {
|
|
|
145266
145441
|
return typeof todo.content === "string" && typeof todo.status === "string" && (todo.priority === undefined || typeof todo.priority === "string");
|
|
145267
145442
|
}
|
|
145268
145443
|
|
|
145444
|
+
// ../plugin/src/shared/announcement.ts
|
|
145445
|
+
init_data_path();
|
|
145446
|
+
import * as fs2 from "node:fs";
|
|
145447
|
+
import * as path5 from "node:path";
|
|
145448
|
+
var ANNOUNCEMENT_VERSION = "0.21.7";
|
|
145449
|
+
var ANNOUNCEMENT_FEATURES = [
|
|
145450
|
+
"Pi parity sweep: 44 audit findings fixed, including a critical SHIP-BLOCKER where /ctx-flush did not drain the pending Pi compaction queue.",
|
|
145451
|
+
"Pi historian recovery fix: empty/no-op historian returns now clear emergency recovery so sessions cannot loop forever at 95%.",
|
|
145452
|
+
"trimPiMessagesToBoundary now sweeps non-contiguous tool-result orphans, fixing provider 400s after compaction in long Pi sessions.",
|
|
145453
|
+
"Hidden subagent tool isolation: historian, dreamer, and sidekick can no longer spawn subagents or run unsafe tools.",
|
|
145454
|
+
"TUI sidebar and /ctx-status header now show execute threshold inline: '47.5% / 65%' on the left, '475K / 1.0M' on the right.",
|
|
145455
|
+
"doctor --issue now caps GitHub issue bodies at ~60KB with a dedicated 'Recent errors' section so reports stay submittable."
|
|
145456
|
+
];
|
|
145457
|
+
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
|
|
145458
|
+
var STATE_FILENAME = "last_announced_version";
|
|
145459
|
+
function getStateFilePath() {
|
|
145460
|
+
return path5.join(getMagicContextStorageDir(), STATE_FILENAME);
|
|
145461
|
+
}
|
|
145462
|
+
function readLastAnnouncedVersion() {
|
|
145463
|
+
try {
|
|
145464
|
+
const file = getStateFilePath();
|
|
145465
|
+
if (!fs2.existsSync(file))
|
|
145466
|
+
return "";
|
|
145467
|
+
return fs2.readFileSync(file, "utf-8").trim();
|
|
145468
|
+
} catch {
|
|
145469
|
+
return "";
|
|
145470
|
+
}
|
|
145471
|
+
}
|
|
145472
|
+
function markAnnouncementSeen(version) {
|
|
145473
|
+
if (!version)
|
|
145474
|
+
return;
|
|
145475
|
+
try {
|
|
145476
|
+
const dir = getMagicContextStorageDir();
|
|
145477
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
145478
|
+
fs2.writeFileSync(getStateFilePath(), version);
|
|
145479
|
+
} catch {}
|
|
145480
|
+
}
|
|
145481
|
+
function shouldShowAnnouncement() {
|
|
145482
|
+
if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0)
|
|
145483
|
+
return false;
|
|
145484
|
+
return readLastAnnouncedVersion() !== ANNOUNCEMENT_VERSION;
|
|
145485
|
+
}
|
|
145486
|
+
|
|
145269
145487
|
// src/index.ts
|
|
145270
145488
|
init_data_path();
|
|
145271
145489
|
init_logger();
|
|
145272
145490
|
|
|
145491
|
+
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
145492
|
+
function resolveFallbackChain(agentName, userFallbacks) {
|
|
145493
|
+
const userList = normalizeUserFallbacks(userFallbacks);
|
|
145494
|
+
if (userList.length > 0) {
|
|
145495
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
145496
|
+
}
|
|
145497
|
+
const builtin = getAgentFallbackModels(agentName);
|
|
145498
|
+
if (!builtin || builtin.length === 0)
|
|
145499
|
+
return [];
|
|
145500
|
+
return dedupe(builtin.filter(isValidModelSpec));
|
|
145501
|
+
}
|
|
145502
|
+
function normalizeUserFallbacks(userFallbacks) {
|
|
145503
|
+
if (!userFallbacks)
|
|
145504
|
+
return [];
|
|
145505
|
+
if (typeof userFallbacks === "string") {
|
|
145506
|
+
const trimmed = userFallbacks.trim();
|
|
145507
|
+
return trimmed ? [trimmed] : [];
|
|
145508
|
+
}
|
|
145509
|
+
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
145510
|
+
}
|
|
145511
|
+
function isValidModelSpec(spec) {
|
|
145512
|
+
const slash = spec.indexOf("/");
|
|
145513
|
+
return slash > 0 && slash < spec.length - 1;
|
|
145514
|
+
}
|
|
145515
|
+
function dedupe(list) {
|
|
145516
|
+
const seen = new Set;
|
|
145517
|
+
const out = [];
|
|
145518
|
+
for (const item of list) {
|
|
145519
|
+
if (seen.has(item))
|
|
145520
|
+
continue;
|
|
145521
|
+
seen.add(item);
|
|
145522
|
+
out.push(item);
|
|
145523
|
+
}
|
|
145524
|
+
return out;
|
|
145525
|
+
}
|
|
145526
|
+
function parseProviderModel(spec) {
|
|
145527
|
+
const slash = spec.indexOf("/");
|
|
145528
|
+
if (slash < 1 || slash >= spec.length - 1)
|
|
145529
|
+
return null;
|
|
145530
|
+
return {
|
|
145531
|
+
providerID: spec.slice(0, slash).trim(),
|
|
145532
|
+
modelID: spec.slice(slash + 1).trim()
|
|
145533
|
+
};
|
|
145534
|
+
}
|
|
145535
|
+
|
|
145273
145536
|
// ../plugin/src/features/magic-context/sidekick/core.ts
|
|
145274
145537
|
var SIDEKICK_SYSTEM_PROMPT = `You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.
|
|
145275
145538
|
|
|
@@ -145295,17 +145558,17 @@ init_logger();
|
|
|
145295
145558
|
|
|
145296
145559
|
// src/subagent-runner.ts
|
|
145297
145560
|
import * as childProcess from "node:child_process";
|
|
145298
|
-
import { existsSync as
|
|
145561
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
145299
145562
|
import { createRequire as createRequire3 } from "node:module";
|
|
145300
|
-
import { dirname as dirname3, join as
|
|
145563
|
+
import { dirname as dirname3, join as join9, resolve as resolvePath } from "node:path";
|
|
145301
145564
|
import { createInterface } from "node:readline";
|
|
145302
145565
|
import { fileURLToPath } from "node:url";
|
|
145303
145566
|
function resolveBundledPiCli() {
|
|
145304
145567
|
try {
|
|
145305
145568
|
const require_ = createRequire3(import.meta.url);
|
|
145306
145569
|
const pkgJson = require_.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
145307
|
-
const cliPath =
|
|
145308
|
-
if (
|
|
145570
|
+
const cliPath = join9(dirname3(pkgJson), "dist/cli.js");
|
|
145571
|
+
if (existsSync7(cliPath))
|
|
145309
145572
|
return cliPath;
|
|
145310
145573
|
return null;
|
|
145311
145574
|
} catch {
|
|
@@ -145316,7 +145579,7 @@ function resolveSubagentEntryPath() {
|
|
|
145316
145579
|
try {
|
|
145317
145580
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
145318
145581
|
const candidate = resolvePath(here, "subagent-entry.js");
|
|
145319
|
-
if (
|
|
145582
|
+
if (existsSync7(candidate))
|
|
145320
145583
|
return candidate;
|
|
145321
145584
|
return;
|
|
145322
145585
|
} catch {
|
|
@@ -145348,6 +145611,27 @@ class PiSubagentRunner {
|
|
|
145348
145611
|
this.spawnImpl = options.spawnImpl ?? childProcess.spawn;
|
|
145349
145612
|
}
|
|
145350
145613
|
async run(options) {
|
|
145614
|
+
const models = [options.model, ...options.fallbackModels ?? []].filter((model) => typeof model === "string" && model.length > 0);
|
|
145615
|
+
const attempts = models.length > 0 ? models : [undefined];
|
|
145616
|
+
let lastResult = null;
|
|
145617
|
+
for (let index = 0;index < attempts.length; index += 1) {
|
|
145618
|
+
const model = attempts[index];
|
|
145619
|
+
const attemptOptions = {
|
|
145620
|
+
...options,
|
|
145621
|
+
model,
|
|
145622
|
+
fallbackModels: undefined
|
|
145623
|
+
};
|
|
145624
|
+
const result = await this.runOnce(attemptOptions);
|
|
145625
|
+
if (result.ok)
|
|
145626
|
+
return result;
|
|
145627
|
+
lastResult = result;
|
|
145628
|
+
if (index >= attempts.length - 1 || !isFallbackEligible(result.reason)) {
|
|
145629
|
+
return result;
|
|
145630
|
+
}
|
|
145631
|
+
}
|
|
145632
|
+
return lastResult ?? this.runOnce({ ...options, fallbackModels: undefined });
|
|
145633
|
+
}
|
|
145634
|
+
async runOnce(options) {
|
|
145351
145635
|
const startTime = Date.now();
|
|
145352
145636
|
if (options.signal?.aborted) {
|
|
145353
145637
|
return {
|
|
@@ -145484,7 +145768,7 @@ class PiSubagentRunner {
|
|
|
145484
145768
|
const m = e.message;
|
|
145485
145769
|
if (m.role === "assistant") {
|
|
145486
145770
|
const hasToolCall = Array.isArray(m.content) && m.content.some((c) => typeof c === "object" && c !== null && c.type === "toolCall");
|
|
145487
|
-
const isTerminalStopReason = typeof m.stopReason === "string" && (m.stopReason === "stop" || m.stopReason === "length" || m.stopReason === "
|
|
145771
|
+
const isTerminalStopReason = typeof m.stopReason === "string" && (m.stopReason === "stop" || m.stopReason === "length" || m.stopReason === "aborted");
|
|
145488
145772
|
if (isTerminalStopReason && !hasToolCall) {
|
|
145489
145773
|
sawAgentEnd = true;
|
|
145490
145774
|
const result = extractFinalAssistant(accumulatedMessages);
|
|
@@ -145506,6 +145790,10 @@ class PiSubagentRunner {
|
|
|
145506
145790
|
}
|
|
145507
145791
|
if (sawAgentEnd && !drainTimerStarted) {
|
|
145508
145792
|
drainTimerStarted = true;
|
|
145793
|
+
if (timeoutHandle) {
|
|
145794
|
+
clearTimeout(timeoutHandle);
|
|
145795
|
+
timeoutHandle = undefined;
|
|
145796
|
+
}
|
|
145509
145797
|
drainTimerHandle = setTimeout(() => {
|
|
145510
145798
|
if (settled)
|
|
145511
145799
|
return;
|
|
@@ -145588,6 +145876,20 @@ class PiSubagentRunner {
|
|
|
145588
145876
|
});
|
|
145589
145877
|
return;
|
|
145590
145878
|
}
|
|
145879
|
+
if (code !== 0 || signal !== null) {
|
|
145880
|
+
settle({
|
|
145881
|
+
ok: false,
|
|
145882
|
+
reason: "non_zero_exit",
|
|
145883
|
+
error: `pi exited (code=${code}, signal=${signal}) after terminal assistant event. stderr: ${stderr.slice(0, 500) || "(empty)"}`,
|
|
145884
|
+
durationMs: Date.now() - startTime,
|
|
145885
|
+
meta: {
|
|
145886
|
+
stderr: stderr.length > 0 ? stderr : undefined,
|
|
145887
|
+
exitCode: code,
|
|
145888
|
+
signal
|
|
145889
|
+
}
|
|
145890
|
+
});
|
|
145891
|
+
return;
|
|
145892
|
+
}
|
|
145591
145893
|
if (finalStopReason === "error" || finalStopReason === "aborted" || finalStopReason === "length") {
|
|
145592
145894
|
settle({
|
|
145593
145895
|
ok: false,
|
|
@@ -145649,6 +145951,9 @@ class PiSubagentRunner {
|
|
|
145649
145951
|
});
|
|
145650
145952
|
}
|
|
145651
145953
|
}
|
|
145954
|
+
function isFallbackEligible(reason) {
|
|
145955
|
+
return reason === "model_failed" || reason === "truncated" || reason === "non_zero_exit" || reason === "no_assistant";
|
|
145956
|
+
}
|
|
145652
145957
|
function buildArgs(options) {
|
|
145653
145958
|
const args = [
|
|
145654
145959
|
"--print",
|
|
@@ -145659,7 +145964,8 @@ function buildArgs(options) {
|
|
|
145659
145964
|
"--no-skills",
|
|
145660
145965
|
"--no-prompt-templates"
|
|
145661
145966
|
];
|
|
145662
|
-
|
|
145967
|
+
const shouldLoadSubagentExtension = SUBAGENT_ENTRY_PATH && (options.agent === "sidekick" || DREAMER_ACTION_AGENTS.has(options.agent));
|
|
145968
|
+
if (shouldLoadSubagentExtension) {
|
|
145663
145969
|
args.push("--extension", SUBAGENT_ENTRY_PATH);
|
|
145664
145970
|
if (DREAMER_ACTION_AGENTS.has(options.agent)) {
|
|
145665
145971
|
args.push("--magic-context-dreamer-actions");
|
|
@@ -145668,11 +145974,8 @@ function buildArgs(options) {
|
|
|
145668
145974
|
if (options.systemPrompt && options.systemPrompt.length > 0) {
|
|
145669
145975
|
args.push("--system-prompt", options.systemPrompt);
|
|
145670
145976
|
}
|
|
145671
|
-
|
|
145672
|
-
|
|
145673
|
-
args.push("--models", models.join(","));
|
|
145674
|
-
} else if (models.length === 1) {
|
|
145675
|
-
args.push("--model", models[0]);
|
|
145977
|
+
if (typeof options.model === "string" && options.model.length > 0) {
|
|
145978
|
+
args.push("--model", options.model);
|
|
145676
145979
|
}
|
|
145677
145980
|
if (options.thinkingLevel) {
|
|
145678
145981
|
args.push("--thinking", options.thinkingLevel);
|
|
@@ -145762,6 +146065,7 @@ function registerCtxAugCommand(pi, config) {
|
|
|
145762
146065
|
systemPrompt: config.systemPrompt ?? SIDEKICK_SYSTEM_PROMPT,
|
|
145763
146066
|
userMessage: prompt,
|
|
145764
146067
|
model: config.model,
|
|
146068
|
+
fallbackModels: config.fallbackModels,
|
|
145765
146069
|
timeoutMs: config.timeoutMs ?? 30000,
|
|
145766
146070
|
cwd: ctx.cwd,
|
|
145767
146071
|
signal: ctx.signal,
|
|
@@ -145972,61 +146276,14 @@ function clearStaleEntries(db, maxAgeMs) {
|
|
|
145972
146276
|
// src/commands/ctx-dream.ts
|
|
145973
146277
|
init_logger();
|
|
145974
146278
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
145975
|
-
import { existsSync as
|
|
145976
|
-
import { join as
|
|
146279
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
146280
|
+
import { join as join12 } from "node:path";
|
|
145977
146281
|
|
|
145978
146282
|
// ../plugin/src/shared/index.ts
|
|
145979
146283
|
init_logger();
|
|
145980
146284
|
|
|
145981
146285
|
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
145982
146286
|
init_logger();
|
|
145983
|
-
|
|
145984
|
-
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
145985
|
-
function resolveFallbackChain(agentName, userFallbacks) {
|
|
145986
|
-
const userList = normalizeUserFallbacks(userFallbacks);
|
|
145987
|
-
if (userList.length > 0) {
|
|
145988
|
-
return dedupe(userList.filter(isValidModelSpec));
|
|
145989
|
-
}
|
|
145990
|
-
const builtin = getAgentFallbackModels(agentName);
|
|
145991
|
-
if (!builtin || builtin.length === 0)
|
|
145992
|
-
return [];
|
|
145993
|
-
return dedupe(builtin.filter(isValidModelSpec));
|
|
145994
|
-
}
|
|
145995
|
-
function normalizeUserFallbacks(userFallbacks) {
|
|
145996
|
-
if (!userFallbacks)
|
|
145997
|
-
return [];
|
|
145998
|
-
if (typeof userFallbacks === "string") {
|
|
145999
|
-
const trimmed = userFallbacks.trim();
|
|
146000
|
-
return trimmed ? [trimmed] : [];
|
|
146001
|
-
}
|
|
146002
|
-
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
146003
|
-
}
|
|
146004
|
-
function isValidModelSpec(spec) {
|
|
146005
|
-
const slash = spec.indexOf("/");
|
|
146006
|
-
return slash > 0 && slash < spec.length - 1;
|
|
146007
|
-
}
|
|
146008
|
-
function dedupe(list) {
|
|
146009
|
-
const seen = new Set;
|
|
146010
|
-
const out = [];
|
|
146011
|
-
for (const item of list) {
|
|
146012
|
-
if (seen.has(item))
|
|
146013
|
-
continue;
|
|
146014
|
-
seen.add(item);
|
|
146015
|
-
out.push(item);
|
|
146016
|
-
}
|
|
146017
|
-
return out;
|
|
146018
|
-
}
|
|
146019
|
-
function parseProviderModel(spec) {
|
|
146020
|
-
const slash = spec.indexOf("/");
|
|
146021
|
-
if (slash < 1 || slash >= spec.length - 1)
|
|
146022
|
-
return null;
|
|
146023
|
-
return {
|
|
146024
|
-
providerID: spec.slice(0, slash).trim(),
|
|
146025
|
-
modelID: spec.slice(slash + 1).trim()
|
|
146026
|
-
};
|
|
146027
|
-
}
|
|
146028
|
-
|
|
146029
|
-
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
146030
146287
|
function extractMessage(error) {
|
|
146031
146288
|
if (typeof error === "string")
|
|
146032
146289
|
return error;
|
|
@@ -146267,20 +146524,20 @@ init_logger();
|
|
|
146267
146524
|
await init_sqlite();
|
|
146268
146525
|
|
|
146269
146526
|
// ../plugin/src/features/magic-context/key-files/identify-key-files.ts
|
|
146270
|
-
import { readFileSync as
|
|
146271
|
-
import { join as
|
|
146527
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
146528
|
+
import { join as join11 } from "node:path";
|
|
146272
146529
|
init_logger();
|
|
146273
146530
|
|
|
146274
146531
|
// ../plugin/src/features/magic-context/key-files/aft-availability.ts
|
|
146275
146532
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
146276
|
-
import { existsSync as
|
|
146533
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
146277
146534
|
import { homedir as homedir3 } from "node:os";
|
|
146278
|
-
import { join as
|
|
146535
|
+
import { join as join10 } from "node:path";
|
|
146279
146536
|
var overrideAvailability = null;
|
|
146280
|
-
function parseConfig(
|
|
146281
|
-
if (!
|
|
146537
|
+
function parseConfig(path6) {
|
|
146538
|
+
if (!existsSync8(path6))
|
|
146282
146539
|
return null;
|
|
146283
|
-
return import_comment_json.parse(
|
|
146540
|
+
return import_comment_json.parse(readFileSync4(path6, "utf-8"));
|
|
146284
146541
|
}
|
|
146285
146542
|
function entryMatchesAft(entry) {
|
|
146286
146543
|
const value = Array.isArray(entry) ? entry[0] : entry;
|
|
@@ -146302,15 +146559,15 @@ function hasAftAtKeys(value, keys) {
|
|
|
146302
146559
|
function getAftAvailability() {
|
|
146303
146560
|
const home = process.env.HOME || homedir3();
|
|
146304
146561
|
const opencodePaths = [
|
|
146305
|
-
|
|
146306
|
-
|
|
146562
|
+
join10(home, ".config", "opencode", "opencode.jsonc"),
|
|
146563
|
+
join10(home, ".config", "opencode", "opencode.json")
|
|
146307
146564
|
];
|
|
146308
|
-
const piPaths = [
|
|
146565
|
+
const piPaths = [join10(home, ".pi", "agent", "settings.json")];
|
|
146309
146566
|
const checkedPaths = [...opencodePaths, ...piPaths];
|
|
146310
146567
|
let opencode = false;
|
|
146311
|
-
for (const
|
|
146568
|
+
for (const path6 of opencodePaths) {
|
|
146312
146569
|
try {
|
|
146313
|
-
const config = parseConfig(
|
|
146570
|
+
const config = parseConfig(path6);
|
|
146314
146571
|
if (hasAftAtKeys(config, ["plugin", "plugins", "mcp", "mcp_servers"])) {
|
|
146315
146572
|
opencode = true;
|
|
146316
146573
|
break;
|
|
@@ -146318,9 +146575,9 @@ function getAftAvailability() {
|
|
|
146318
146575
|
} catch {}
|
|
146319
146576
|
}
|
|
146320
146577
|
let pi = false;
|
|
146321
|
-
for (const
|
|
146578
|
+
for (const path6 of piPaths) {
|
|
146322
146579
|
try {
|
|
146323
|
-
const config = parseConfig(
|
|
146580
|
+
const config = parseConfig(path6);
|
|
146324
146581
|
if (hasAftAtKeys(config, ["packages", "extensions"])) {
|
|
146325
146582
|
pi = true;
|
|
146326
146583
|
break;
|
|
@@ -146769,7 +147026,7 @@ async function runKeyFilesTask(args) {
|
|
|
146769
147026
|
if (row.staleReason !== null || row.generationConfigHash !== configHash)
|
|
146770
147027
|
return false;
|
|
146771
147028
|
try {
|
|
146772
|
-
return sha256(
|
|
147029
|
+
return sha256(readFileSync5(join11(projectPath, row.path))) === row.contentHash;
|
|
146773
147030
|
} catch {
|
|
146774
147031
|
return false;
|
|
146775
147032
|
}
|
|
@@ -147693,6 +147950,17 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
147693
147950
|
}
|
|
147694
147951
|
|
|
147695
147952
|
// ../plugin/src/features/magic-context/user-memory/storage-user-memory.ts
|
|
147953
|
+
function insertUserMemoryCandidates(db, candidates) {
|
|
147954
|
+
if (candidates.length === 0)
|
|
147955
|
+
return;
|
|
147956
|
+
const now = Date.now();
|
|
147957
|
+
const stmt = db.prepare("INSERT INTO user_memory_candidates (content, session_id, source_compartment_start, source_compartment_end, created_at) VALUES (?, ?, ?, ?, ?)");
|
|
147958
|
+
db.transaction(() => {
|
|
147959
|
+
for (const c of candidates) {
|
|
147960
|
+
stmt.run(c.content, c.sessionId, c.sourceCompartmentStart ?? null, c.sourceCompartmentEnd ?? null, now);
|
|
147961
|
+
}
|
|
147962
|
+
})();
|
|
147963
|
+
}
|
|
147696
147964
|
function getUserMemoryCandidates(db) {
|
|
147697
147965
|
const rows = db.prepare("SELECT id, content, session_id, source_compartment_start, source_compartment_end, created_at FROM user_memory_candidates ORDER BY created_at ASC").all();
|
|
147698
147966
|
return rows.map((r) => ({
|
|
@@ -147966,11 +148234,11 @@ function logWithStackHead(message, stackHead) {
|
|
|
147966
148234
|
log(message, stackHead ? { stackHead } : undefined);
|
|
147967
148235
|
}
|
|
147968
148236
|
function getOpenCodeDbPath2() {
|
|
147969
|
-
return
|
|
148237
|
+
return join12(getDataDir(), "opencode", "opencode.db");
|
|
147970
148238
|
}
|
|
147971
148239
|
function openOpenCodeDb() {
|
|
147972
148240
|
const dbPath = getOpenCodeDbPath2();
|
|
147973
|
-
if (!
|
|
148241
|
+
if (!existsSync9(dbPath)) {
|
|
147974
148242
|
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
147975
148243
|
return null;
|
|
147976
148244
|
}
|
|
@@ -148101,8 +148369,8 @@ async function runDream(args) {
|
|
|
148101
148369
|
try {
|
|
148102
148370
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
148103
148371
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
148104
|
-
architecture:
|
|
148105
|
-
structure:
|
|
148372
|
+
architecture: existsSync9(join12(docsDir, "ARCHITECTURE.md")),
|
|
148373
|
+
structure: existsSync9(join12(docsDir, "STRUCTURE.md"))
|
|
148106
148374
|
} : undefined;
|
|
148107
148375
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
148108
148376
|
id: um.id,
|
|
@@ -149518,10 +149786,10 @@ function mergeDefs(...defs) {
|
|
|
149518
149786
|
function cloneDef(schema) {
|
|
149519
149787
|
return mergeDefs(schema._zod.def);
|
|
149520
149788
|
}
|
|
149521
|
-
function getElementAtPath(obj,
|
|
149522
|
-
if (!
|
|
149789
|
+
function getElementAtPath(obj, path6) {
|
|
149790
|
+
if (!path6)
|
|
149523
149791
|
return obj;
|
|
149524
|
-
return
|
|
149792
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
149525
149793
|
}
|
|
149526
149794
|
function promiseAllObject(promisesObj) {
|
|
149527
149795
|
const keys = Object.keys(promisesObj);
|
|
@@ -149929,11 +150197,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
149929
150197
|
}
|
|
149930
150198
|
return false;
|
|
149931
150199
|
}
|
|
149932
|
-
function prefixIssues(
|
|
150200
|
+
function prefixIssues(path6, issues) {
|
|
149933
150201
|
return issues.map((iss) => {
|
|
149934
150202
|
var _a2;
|
|
149935
150203
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
149936
|
-
iss.path.unshift(
|
|
150204
|
+
iss.path.unshift(path6);
|
|
149937
150205
|
return iss;
|
|
149938
150206
|
});
|
|
149939
150207
|
}
|
|
@@ -150080,16 +150348,16 @@ function flattenError(error, mapper = (issue2) => issue2.message) {
|
|
|
150080
150348
|
}
|
|
150081
150349
|
function formatError(error, mapper = (issue2) => issue2.message) {
|
|
150082
150350
|
const fieldErrors = { _errors: [] };
|
|
150083
|
-
const processError = (error2,
|
|
150351
|
+
const processError = (error2, path6 = []) => {
|
|
150084
150352
|
for (const issue2 of error2.issues) {
|
|
150085
150353
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
150086
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
150354
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
150087
150355
|
} else if (issue2.code === "invalid_key") {
|
|
150088
|
-
processError({ issues: issue2.issues }, [...
|
|
150356
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150089
150357
|
} else if (issue2.code === "invalid_element") {
|
|
150090
|
-
processError({ issues: issue2.issues }, [...
|
|
150358
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150091
150359
|
} else {
|
|
150092
|
-
const fullpath = [...
|
|
150360
|
+
const fullpath = [...path6, ...issue2.path];
|
|
150093
150361
|
if (fullpath.length === 0) {
|
|
150094
150362
|
fieldErrors._errors.push(mapper(issue2));
|
|
150095
150363
|
} else {
|
|
@@ -150116,17 +150384,17 @@ function formatError(error, mapper = (issue2) => issue2.message) {
|
|
|
150116
150384
|
}
|
|
150117
150385
|
function treeifyError(error, mapper = (issue2) => issue2.message) {
|
|
150118
150386
|
const result = { errors: [] };
|
|
150119
|
-
const processError = (error2,
|
|
150387
|
+
const processError = (error2, path6 = []) => {
|
|
150120
150388
|
var _a2, _b;
|
|
150121
150389
|
for (const issue2 of error2.issues) {
|
|
150122
150390
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
150123
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
150391
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
150124
150392
|
} else if (issue2.code === "invalid_key") {
|
|
150125
|
-
processError({ issues: issue2.issues }, [...
|
|
150393
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150126
150394
|
} else if (issue2.code === "invalid_element") {
|
|
150127
|
-
processError({ issues: issue2.issues }, [...
|
|
150395
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150128
150396
|
} else {
|
|
150129
|
-
const fullpath = [...
|
|
150397
|
+
const fullpath = [...path6, ...issue2.path];
|
|
150130
150398
|
if (fullpath.length === 0) {
|
|
150131
150399
|
result.errors.push(mapper(issue2));
|
|
150132
150400
|
continue;
|
|
@@ -150158,8 +150426,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
|
|
|
150158
150426
|
}
|
|
150159
150427
|
function toDotPath(_path) {
|
|
150160
150428
|
const segs = [];
|
|
150161
|
-
const
|
|
150162
|
-
for (const seg of
|
|
150429
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
150430
|
+
for (const seg of path6) {
|
|
150163
150431
|
if (typeof seg === "number")
|
|
150164
150432
|
segs.push(`[${seg}]`);
|
|
150165
150433
|
else if (typeof seg === "symbol")
|
|
@@ -162618,13 +162886,13 @@ function resolveRef(ref, ctx) {
|
|
|
162618
162886
|
if (!ref.startsWith("#")) {
|
|
162619
162887
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
162620
162888
|
}
|
|
162621
|
-
const
|
|
162622
|
-
if (
|
|
162889
|
+
const path6 = ref.slice(1).split("/").filter(Boolean);
|
|
162890
|
+
if (path6.length === 0) {
|
|
162623
162891
|
return ctx.rootSchema;
|
|
162624
162892
|
}
|
|
162625
162893
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
162626
|
-
if (
|
|
162627
|
-
const key =
|
|
162894
|
+
if (path6[0] === defsKey) {
|
|
162895
|
+
const key = path6[1];
|
|
162628
162896
|
if (!key || !ctx.defs[key]) {
|
|
162629
162897
|
throw new Error(`Reference not found: ${ref}`);
|
|
162630
162898
|
}
|
|
@@ -163093,7 +163361,6 @@ var DEFAULT_DREAMER_TASKS = [
|
|
|
163093
163361
|
];
|
|
163094
163362
|
var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional();
|
|
163095
163363
|
var DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.object({
|
|
163096
|
-
enabled: exports_external.boolean().default(false),
|
|
163097
163364
|
schedule: exports_external.string().default("02:00-06:00"),
|
|
163098
163365
|
max_runtime_minutes: exports_external.number().min(10).default(120),
|
|
163099
163366
|
tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS),
|
|
@@ -163111,7 +163378,6 @@ var DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.objec
|
|
|
163111
163378
|
thinking_level: PiThinkingLevelSchema
|
|
163112
163379
|
}));
|
|
163113
163380
|
var SidekickConfigSchema = AgentOverrideConfigSchema.extend({
|
|
163114
|
-
enabled: exports_external.boolean().default(false),
|
|
163115
163381
|
timeout_ms: exports_external.number().default(30000),
|
|
163116
163382
|
system_prompt: exports_external.string().optional(),
|
|
163117
163383
|
thinking_level: PiThinkingLevelSchema
|
|
@@ -163295,9 +163561,9 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
163295
163561
|
}
|
|
163296
163562
|
|
|
163297
163563
|
// ../plugin/src/features/magic-context/memory/embedding-local.ts
|
|
163298
|
-
import { mkdirSync as
|
|
163564
|
+
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
163299
163565
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
163300
|
-
import { dirname as dirname4, join as
|
|
163566
|
+
import { dirname as dirname4, join as join13 } from "node:path";
|
|
163301
163567
|
import { pathToFileURL } from "node:url";
|
|
163302
163568
|
init_data_path();
|
|
163303
163569
|
init_logger();
|
|
@@ -163364,7 +163630,7 @@ async function injectWasmOrtForElectron() {
|
|
|
163364
163630
|
const { createRequire: createRequireFn } = await import("node:module");
|
|
163365
163631
|
const requireFn = createRequireFn(import.meta.url);
|
|
163366
163632
|
const pkgPath = requireFn.resolve("onnxruntime-web/package.json");
|
|
163367
|
-
const distDir =
|
|
163633
|
+
const distDir = join13(dirname4(pkgPath), "dist");
|
|
163368
163634
|
const wasmPathsPrefix = `${pathToFileURL(distDir).href}/`;
|
|
163369
163635
|
if (ortWeb.env?.wasm) {
|
|
163370
163636
|
ortWeb.env.wasm.wasmPaths = wasmPathsPrefix;
|
|
@@ -163475,15 +163741,15 @@ class LocalEmbeddingProvider {
|
|
|
163475
163741
|
if (LogLevel && "ERROR" in LogLevel) {
|
|
163476
163742
|
env.logLevel = LogLevel.ERROR;
|
|
163477
163743
|
}
|
|
163478
|
-
const modelCacheDir =
|
|
163744
|
+
const modelCacheDir = join13(getMagicContextStorageDir(), "models");
|
|
163479
163745
|
try {
|
|
163480
|
-
|
|
163746
|
+
mkdirSync5(modelCacheDir, { recursive: true });
|
|
163481
163747
|
env.cacheDir = modelCacheDir;
|
|
163482
163748
|
} catch {
|
|
163483
163749
|
log("[magic-context] could not create model cache dir, using library default");
|
|
163484
163750
|
}
|
|
163485
163751
|
const createPipeline = transformersModule.pipeline;
|
|
163486
|
-
const lockPath =
|
|
163752
|
+
const lockPath = join13(modelCacheDir, ".load.lock");
|
|
163487
163753
|
const releaseLock = await acquireModelLoadLock(lockPath);
|
|
163488
163754
|
const stopHeartbeat = startLockHeartbeat(lockPath);
|
|
163489
163755
|
try {
|
|
@@ -164651,7 +164917,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
164651
164917
|
const db = openDatabase();
|
|
164652
164918
|
await args.ensureRegistered(args.directory, db);
|
|
164653
164919
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
164654
|
-
const dreamingEnabled = Boolean(args.dreamerConfig
|
|
164920
|
+
const dreamingEnabled = Boolean(args.dreamerConfig && args.dreamerConfig.disable !== true && args.dreamerConfig.schedule?.trim());
|
|
164655
164921
|
const embeddingSweepEnabled = snapshot?.enabled ?? false;
|
|
164656
164922
|
const commitIndexingEnabled = snapshot?.gitCommitEnabled ?? false;
|
|
164657
164923
|
if (!dreamingEnabled && !embeddingSweepEnabled && !commitIndexingEnabled) {
|
|
@@ -164707,7 +164973,7 @@ function runTick(origin) {
|
|
|
164707
164973
|
})();
|
|
164708
164974
|
}
|
|
164709
164975
|
async function sweepProject(reg, origin, db = openDatabase(), gitCommitEnabled = getProjectEmbeddingSnapshot(reg.projectIdentity)?.gitCommitEnabled === true) {
|
|
164710
|
-
const dreamingEnabled = Boolean(reg.dreamerConfig
|
|
164976
|
+
const dreamingEnabled = Boolean(reg.dreamerConfig && reg.dreamerConfig.disable !== true && reg.dreamerConfig.schedule?.trim());
|
|
164711
164977
|
if (gitCommitEnabled && reg.gitCommitIndexing) {
|
|
164712
164978
|
await sweepGitCommits({
|
|
164713
164979
|
directory: reg.directory,
|
|
@@ -164835,12 +165101,12 @@ function handleUntrustedLoad(db, projectIdentity, directory, detailed) {
|
|
|
164835
165101
|
}
|
|
164836
165102
|
|
|
164837
165103
|
// src/config/index.ts
|
|
164838
|
-
import { existsSync as
|
|
165104
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
|
|
164839
165105
|
import { homedir as homedir5 } from "node:os";
|
|
164840
|
-
import { join as
|
|
165106
|
+
import { join as join14 } from "node:path";
|
|
164841
165107
|
|
|
164842
165108
|
// ../plugin/src/config/variable.ts
|
|
164843
|
-
import { existsSync as
|
|
165109
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6 } from "node:fs";
|
|
164844
165110
|
import { homedir as homedir4 } from "node:os";
|
|
164845
165111
|
import { dirname as dirname5, isAbsolute, resolve as resolve3 } from "node:path";
|
|
164846
165112
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
@@ -164898,13 +165164,13 @@ function substituteConfigVariables(input) {
|
|
|
164898
165164
|
} else if (!isAbsolute(filePath)) {
|
|
164899
165165
|
filePath = resolve3(configDir, filePath);
|
|
164900
165166
|
}
|
|
164901
|
-
if (!
|
|
165167
|
+
if (!existsSync10(filePath)) {
|
|
164902
165168
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
164903
165169
|
continue;
|
|
164904
165170
|
}
|
|
164905
165171
|
let contents;
|
|
164906
165172
|
try {
|
|
164907
|
-
contents =
|
|
165173
|
+
contents = readFileSync6(filePath, "utf-8").trim();
|
|
164908
165174
|
} catch (error51) {
|
|
164909
165175
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
164910
165176
|
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
@@ -164920,39 +165186,39 @@ function substituteConfigVariables(input) {
|
|
|
164920
165186
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
164921
165187
|
var CONFIG_FILE_NAME = "magic-context";
|
|
164922
165188
|
function getProjectConfigPaths(cwd) {
|
|
164923
|
-
const basePath =
|
|
165189
|
+
const basePath = join14(cwd, ".pi", CONFIG_FILE_NAME);
|
|
164924
165190
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
164925
165191
|
}
|
|
164926
165192
|
function getUserConfigPaths() {
|
|
164927
165193
|
const home = process.env.HOME ?? homedir5();
|
|
164928
|
-
const basePath =
|
|
165194
|
+
const basePath = join14(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
164929
165195
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
164930
165196
|
}
|
|
164931
165197
|
function resolveFirstExisting(paths) {
|
|
164932
|
-
return paths.find((
|
|
165198
|
+
return paths.find((path6) => existsSync11(path6));
|
|
164933
165199
|
}
|
|
164934
|
-
function loadConfigFile(
|
|
165200
|
+
function loadConfigFile(path6, scope) {
|
|
164935
165201
|
try {
|
|
164936
|
-
const rawText =
|
|
165202
|
+
const rawText = readFileSync7(path6, "utf-8");
|
|
164937
165203
|
const substituted = substituteConfigVariables({
|
|
164938
165204
|
text: rawText,
|
|
164939
|
-
configPath:
|
|
165205
|
+
configPath: path6
|
|
164940
165206
|
});
|
|
164941
165207
|
return {
|
|
164942
|
-
path:
|
|
165208
|
+
path: path6,
|
|
164943
165209
|
scope,
|
|
164944
165210
|
config: import_comment_json2.parse(substituted.text),
|
|
164945
|
-
warnings: substituted.warnings.map((warning) => `${
|
|
165211
|
+
warnings: substituted.warnings.map((warning) => `${path6}: ${warning}`),
|
|
164946
165212
|
loadOutcome: substituted.warnings.length > 0 ? "substitution-failure" : "ok"
|
|
164947
165213
|
};
|
|
164948
165214
|
} catch (error51) {
|
|
164949
165215
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
164950
165216
|
return {
|
|
164951
|
-
path:
|
|
165217
|
+
path: path6,
|
|
164952
165218
|
scope,
|
|
164953
165219
|
config: {},
|
|
164954
165220
|
warnings: [
|
|
164955
|
-
`${
|
|
165221
|
+
`${path6}: failed to load config: ${message}; using defaults for this file.`
|
|
164956
165222
|
],
|
|
164957
165223
|
loadOutcome: typeof error51.code === "string" ? "project-file-io-error" : "project-file-parse-error"
|
|
164958
165224
|
};
|
|
@@ -164990,9 +165256,11 @@ function mergeRawConfigs(base, override) {
|
|
|
164990
165256
|
return merged;
|
|
164991
165257
|
}
|
|
164992
165258
|
function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
164993
|
-
const
|
|
165259
|
+
const preMigrationWarnings = [];
|
|
165260
|
+
const migrated = migrateLegacyAgentEnabledInMemory(rawConfig, preMigrationWarnings);
|
|
165261
|
+
const parsed = MagicContextConfigSchema.safeParse(migrated);
|
|
164994
165262
|
if (parsed.success) {
|
|
164995
|
-
return { config: parsed.data, warnings:
|
|
165263
|
+
return { config: parsed.data, warnings: preMigrationWarnings };
|
|
164996
165264
|
}
|
|
164997
165265
|
const defaults = MagicContextConfigSchema.parse({});
|
|
164998
165266
|
const errorPaths = new Set;
|
|
@@ -165002,8 +165270,8 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
165002
165270
|
errorPaths.add(String(topKey));
|
|
165003
165271
|
}
|
|
165004
165272
|
}
|
|
165005
|
-
const patched = { ...
|
|
165006
|
-
const warnings = [];
|
|
165273
|
+
const patched = { ...migrated };
|
|
165274
|
+
const warnings = [...preMigrationWarnings];
|
|
165007
165275
|
for (const key of errorPaths) {
|
|
165008
165276
|
recoveredTopLevelKeys.push(key);
|
|
165009
165277
|
const isAgentConfig = key === "historian" || key === "dreamer" || key === "sidekick";
|
|
@@ -165077,9 +165345,9 @@ function bindSubstitutionFailures(loaded) {
|
|
|
165077
165345
|
}
|
|
165078
165346
|
const emptyPaths = collectEmptyStringPaths(loaded.config);
|
|
165079
165347
|
return loaded.warnings.map((message) => {
|
|
165080
|
-
const matchedPath = emptyPaths.find((
|
|
165081
|
-
const tail =
|
|
165082
|
-
return message.includes(
|
|
165348
|
+
const matchedPath = emptyPaths.find((path6) => {
|
|
165349
|
+
const tail = path6.split(".").at(-1) ?? path6;
|
|
165350
|
+
return message.includes(path6) || message.toLowerCase().includes(tail.toLowerCase());
|
|
165083
165351
|
});
|
|
165084
165352
|
return {
|
|
165085
165353
|
keyPath: matchedPath ?? "<unknown>",
|
|
@@ -165175,7 +165443,7 @@ var sessionCounter = 0;
|
|
|
165175
165443
|
var piSubagentRunnerFactory = () => new PiSubagentRunner;
|
|
165176
165444
|
var startDreamScheduleTimerFn = startDreamScheduleTimer;
|
|
165177
165445
|
function registerPiDreamerProject(opts) {
|
|
165178
|
-
if (
|
|
165446
|
+
if (opts.config.disable === true) {
|
|
165179
165447
|
return;
|
|
165180
165448
|
}
|
|
165181
165449
|
const existing = registeredProjects2.get(opts.projectIdentity);
|
|
@@ -165410,7 +165678,7 @@ function registerCtxDreamCommand(pi, deps) {
|
|
|
165410
165678
|
if (deps.dreamerEnabled === false) {
|
|
165411
165679
|
sendCtxStatusMessage(pi, {
|
|
165412
165680
|
title: "/ctx-dream",
|
|
165413
|
-
text: "## /ctx-dream\n\nDreamer is
|
|
165681
|
+
text: "## /ctx-dream\n\nDreamer is disabled for this project (`dreamer.disable=true`).",
|
|
165414
165682
|
level: "info"
|
|
165415
165683
|
}, {
|
|
165416
165684
|
projectDir: project.projectDir,
|
|
@@ -165456,6 +165724,8 @@ function registerCtxDreamCommand(pi, deps) {
|
|
|
165456
165724
|
let summary;
|
|
165457
165725
|
if (!result) {
|
|
165458
165726
|
summary = "Dream queued, but another worker is already processing the queue.";
|
|
165727
|
+
} else if (result.tasks.length === 0) {
|
|
165728
|
+
summary = "Dreamer is configured, but no dream tasks are enabled for this project.";
|
|
165459
165729
|
} else {
|
|
165460
165730
|
const taskLines = result.tasks.map((task) => {
|
|
165461
165731
|
const status = task.error ? `error: ${task.error}` : "ok";
|
|
@@ -167787,7 +168057,7 @@ function stripNestedSystemReminders(text) {
|
|
|
167787
168057
|
return result;
|
|
167788
168058
|
}
|
|
167789
168059
|
function extractUserPromptText(message) {
|
|
167790
|
-
return stripNestedSystemReminders(collectUserPromptParts(message)).replace(
|
|
168060
|
+
return stripNestedSystemReminders(collectUserPromptParts(message)).replace(/<!--[\s\S]*?-->/g, "").replace(/<ctx-search-hint>[\s\S]*?<\/ctx-search-hint>/g, "").replace(/<ctx-search-auto>[\s\S]*?<\/ctx-search-auto>/g, "").replace(/<instruction[^>]*>[\s\S]*?<\/instruction>/g, "").replace(/<sidekick-augmentation>[\s\S]*?<\/sidekick-augmentation>/g, "").replace(/<\/?[a-zA-Z][^<>]*>/g, "").replace(/§\d+§\s*/g, "").replace(/[ \t]+\n/g, `
|
|
167791
168061
|
`).replace(/\n{3,}/g, `
|
|
167792
168062
|
|
|
167793
168063
|
`).trim();
|
|
@@ -167958,18 +168228,28 @@ function applyDeferredPiCompactionMarker(deps, sessionId, pending) {
|
|
|
167958
168228
|
return { kind: "stale-skip", reason: "target-superseded" };
|
|
167959
168229
|
}
|
|
167960
168230
|
const branchEntries = deps.readBranchEntries();
|
|
167961
|
-
|
|
168231
|
+
const pendingFirstKeptIndex = findEntryIndex(branchEntries, pending.firstKeptEntryId);
|
|
168232
|
+
if (pendingFirstKeptIndex < 0) {
|
|
167962
168233
|
return { kind: "stale-skip", reason: "entry-removed" };
|
|
167963
168234
|
}
|
|
167964
168235
|
const latestFirstKept = findLatestCompactionFirstKept(branchEntries);
|
|
167965
|
-
if (latestFirstKept
|
|
167966
|
-
|
|
168236
|
+
if (latestFirstKept !== null) {
|
|
168237
|
+
const latestFirstKeptIndex = findEntryIndex(branchEntries, latestFirstKept);
|
|
168238
|
+
if (latestFirstKeptIndex >= pendingFirstKeptIndex) {
|
|
168239
|
+
return { kind: "already-current" };
|
|
168240
|
+
}
|
|
167967
168241
|
}
|
|
167968
|
-
deps.appendCompaction(pending.summary, pending.firstKeptEntryId, pending.tokensBefore, {
|
|
168242
|
+
const compactionId = deps.appendCompaction(pending.summary, pending.firstKeptEntryId, pending.tokensBefore, {
|
|
167969
168243
|
source: "magic-context",
|
|
167970
168244
|
lastCompactedOrdinal: pending.ordinal
|
|
167971
168245
|
}, true);
|
|
167972
|
-
|
|
168246
|
+
if (typeof compactionId !== "string" || compactionId.length === 0) {
|
|
168247
|
+
return {
|
|
168248
|
+
kind: "retryable-failure",
|
|
168249
|
+
error: new Error("Pi appendCompaction returned no compaction id")
|
|
168250
|
+
};
|
|
168251
|
+
}
|
|
168252
|
+
sessionLog(sessionId, `Pi compaction-marker drain: applied compactionId=${compactionId} firstKept=${pending.firstKeptEntryId} endMessageId=${pending.endMessageId} ordinal=${pending.ordinal} tokensBefore=${pending.tokensBefore}`);
|
|
167973
168253
|
return { kind: "applied", firstKeptEntryId: pending.firstKeptEntryId };
|
|
167974
168254
|
} catch (err) {
|
|
167975
168255
|
const error51 = err instanceof Error ? err : new Error(String(err));
|
|
@@ -167995,6 +168275,9 @@ function getEntryId(entry) {
|
|
|
167995
168275
|
const id = entry.id;
|
|
167996
168276
|
return typeof id === "string" ? id : null;
|
|
167997
168277
|
}
|
|
168278
|
+
function findEntryIndex(branchEntries, entryId) {
|
|
168279
|
+
return branchEntries.findIndex((entry) => getEntryId(entry) === entryId);
|
|
168280
|
+
}
|
|
167998
168281
|
|
|
167999
168282
|
// src/detect-recent-commit.ts
|
|
168000
168283
|
var COMMIT_LOOKBACK = 5;
|
|
@@ -168347,36 +168630,70 @@ function trimPiMessagesToBoundary(piMessages, entryIds, cutoffMessageId) {
|
|
|
168347
168630
|
}
|
|
168348
168631
|
if (cutoffIndex < 0)
|
|
168349
168632
|
return 0;
|
|
168350
|
-
const
|
|
168351
|
-
for (let i = 0;i <= cutoffIndex; i++)
|
|
168352
|
-
|
|
168353
|
-
|
|
168354
|
-
|
|
168355
|
-
|
|
168356
|
-
|
|
168357
|
-
|
|
168358
|
-
for (const
|
|
168359
|
-
|
|
168360
|
-
|
|
168633
|
+
const remove = new Set;
|
|
168634
|
+
for (let i = 0;i <= cutoffIndex; i++)
|
|
168635
|
+
remove.add(i);
|
|
168636
|
+
let changed = true;
|
|
168637
|
+
while (changed) {
|
|
168638
|
+
changed = false;
|
|
168639
|
+
const removedCallIds = new Set;
|
|
168640
|
+
const removedResultIds = new Set;
|
|
168641
|
+
for (const index of remove) {
|
|
168642
|
+
const msg = piMessages[index];
|
|
168643
|
+
if (!msg)
|
|
168644
|
+
continue;
|
|
168645
|
+
if (msg.role === "assistant") {
|
|
168646
|
+
for (const callId of getPiToolCallIds(msg))
|
|
168647
|
+
removedCallIds.add(callId);
|
|
168648
|
+
} else if (msg.role === "toolResult") {
|
|
168649
|
+
const callId = getPiToolResultCallId(msg);
|
|
168650
|
+
if (callId)
|
|
168651
|
+
removedResultIds.add(callId);
|
|
168361
168652
|
}
|
|
168362
168653
|
}
|
|
168363
|
-
|
|
168364
|
-
|
|
168365
|
-
|
|
168366
|
-
while (i < piMessages.length) {
|
|
168654
|
+
for (let i = 0;i < piMessages.length; i++) {
|
|
168655
|
+
if (remove.has(i))
|
|
168656
|
+
continue;
|
|
168367
168657
|
const msg = piMessages[i];
|
|
168368
|
-
if (msg
|
|
168369
|
-
|
|
168370
|
-
|
|
168371
|
-
|
|
168372
|
-
|
|
168658
|
+
if (!msg)
|
|
168659
|
+
continue;
|
|
168660
|
+
if (msg.role === "toolResult") {
|
|
168661
|
+
const callId = getPiToolResultCallId(msg);
|
|
168662
|
+
if (callId && removedCallIds.has(callId)) {
|
|
168663
|
+
remove.add(i);
|
|
168664
|
+
changed = true;
|
|
168665
|
+
}
|
|
168666
|
+
continue;
|
|
168667
|
+
}
|
|
168668
|
+
if (msg.role === "assistant") {
|
|
168669
|
+
const callIds = getPiToolCallIds(msg);
|
|
168670
|
+
if (callIds.some((callId) => removedResultIds.has(callId))) {
|
|
168671
|
+
remove.add(i);
|
|
168672
|
+
changed = true;
|
|
168673
|
+
}
|
|
168373
168674
|
}
|
|
168374
168675
|
}
|
|
168375
168676
|
}
|
|
168376
|
-
const
|
|
168377
|
-
piMessages.
|
|
168677
|
+
const kept = piMessages.filter((_, index) => !remove.has(index));
|
|
168678
|
+
const removed = piMessages.length - kept.length;
|
|
168679
|
+
piMessages.splice(0, piMessages.length, ...kept);
|
|
168378
168680
|
return removed;
|
|
168379
168681
|
}
|
|
168682
|
+
function getPiToolCallIds(message) {
|
|
168683
|
+
if (!Array.isArray(message.content))
|
|
168684
|
+
return [];
|
|
168685
|
+
const ids = [];
|
|
168686
|
+
for (const part of message.content) {
|
|
168687
|
+
if (part && typeof part === "object" && part.type === "toolCall" && typeof part.id === "string") {
|
|
168688
|
+
ids.push(part.id);
|
|
168689
|
+
}
|
|
168690
|
+
}
|
|
168691
|
+
return ids;
|
|
168692
|
+
}
|
|
168693
|
+
function getPiToolResultCallId(message) {
|
|
168694
|
+
const callId = message.toolCallId;
|
|
168695
|
+
return typeof callId === "string" && callId.length > 0 ? callId : null;
|
|
168696
|
+
}
|
|
168380
168697
|
function injectHistoryBlockIntoFirstUserMessage(piMessages, historyBlock) {
|
|
168381
168698
|
for (let i = 0;i < piMessages.length; i++) {
|
|
168382
168699
|
const msg = piMessages[i];
|
|
@@ -168468,6 +168785,7 @@ ${prepared.block}
|
|
|
168468
168785
|
// src/note-visibility-pi.ts
|
|
168469
168786
|
var NOTE_TOOL_NAME = "ctx_note";
|
|
168470
168787
|
var READ_ACTION = "read";
|
|
168788
|
+
var WHOLE_MESSAGE_PLACEHOLDER_TEXT = "[dropped]";
|
|
168471
168789
|
function hasVisibleNoteReadCallPi(messages) {
|
|
168472
168790
|
for (let i = messages.length - 1;i >= 0; i--) {
|
|
168473
168791
|
const raw = messages[i];
|
|
@@ -168479,6 +168797,8 @@ function hasVisibleNoteReadCallPi(messages) {
|
|
|
168479
168797
|
if (!Array.isArray(msg.content))
|
|
168480
168798
|
continue;
|
|
168481
168799
|
for (const part of msg.content) {
|
|
168800
|
+
if (isSentinelPart(part))
|
|
168801
|
+
continue;
|
|
168482
168802
|
if (!part || typeof part !== "object")
|
|
168483
168803
|
continue;
|
|
168484
168804
|
const p = part;
|
|
@@ -168496,6 +168816,12 @@ function hasVisibleNoteReadCallPi(messages) {
|
|
|
168496
168816
|
}
|
|
168497
168817
|
return false;
|
|
168498
168818
|
}
|
|
168819
|
+
function isSentinelPart(part) {
|
|
168820
|
+
if (!part || typeof part !== "object")
|
|
168821
|
+
return false;
|
|
168822
|
+
const p = part;
|
|
168823
|
+
return p.type === "text" && typeof p.text === "string" && (p.text === "" || p.text === WHOLE_MESSAGE_PLACEHOLDER_TEXT);
|
|
168824
|
+
}
|
|
168499
168825
|
|
|
168500
168826
|
// src/nudge-injector.ts
|
|
168501
168827
|
var INSTRUCTION_NAME_PATTERN = /<instruction\s+name="([^"]+)">/;
|
|
@@ -169060,6 +169386,8 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169060
169386
|
sessionLog(sessionId, `compressor: history block ~${totalTokens} tokens within budget ${historyBudgetTokens}, skipping`);
|
|
169061
169387
|
return false;
|
|
169062
169388
|
}
|
|
169389
|
+
const overage = totalTokens - historyBudgetTokens;
|
|
169390
|
+
sessionLog(sessionId, `compressor: history block ~${totalTokens} tokens exceeds budget ${historyBudgetTokens} by ~${overage} tokens`);
|
|
169063
169391
|
const lastEndMessage = compartments[compartments.length - 1]?.endMessage ?? 0;
|
|
169064
169392
|
const floor = Math.max(1, Math.ceil(lastEndMessage / minCompartmentRatio));
|
|
169065
169393
|
const floorHeadroom = compartments.length - floor;
|
|
@@ -169068,6 +169396,17 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169068
169396
|
return false;
|
|
169069
169397
|
}
|
|
169070
169398
|
const scored = scoreCompartments(db, sessionId, compartments);
|
|
169399
|
+
const depthHistogram = new Map;
|
|
169400
|
+
for (const scoredCompartment of scored) {
|
|
169401
|
+
const bucket = Math.round(scoredCompartment.averageDepth);
|
|
169402
|
+
depthHistogram.set(bucket, (depthHistogram.get(bucket) ?? 0) + 1);
|
|
169403
|
+
}
|
|
169404
|
+
const histText = [...depthHistogram.entries()].sort((a, b) => a[0] - b[0]).map(([depth, count]) => `d${depth}=${count}`).join(" ");
|
|
169405
|
+
const histKey = `${scored.length}|${histText}`;
|
|
169406
|
+
if (lastDepthHistogramBySession.get(sessionId) !== histKey) {
|
|
169407
|
+
lastDepthHistogramBySession.set(sessionId, histKey);
|
|
169408
|
+
sessionLog(sessionId, `compressor: depth histogram (${scored.length} total) ${histText}`);
|
|
169409
|
+
}
|
|
169071
169410
|
const band = selectPiCompressionBand(scored, {
|
|
169072
169411
|
maxPickable: maxCompartmentsPerPass,
|
|
169073
169412
|
maxMergeDepth,
|
|
@@ -169086,7 +169425,7 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169086
169425
|
const outputDepth = Math.min(5, Math.max(1, Math.round(avgDepth) + 1));
|
|
169087
169426
|
const mergeRatio = COMPRESSOR_MERGE_RATIO_BY_DEPTH[outputDepth] ?? 2;
|
|
169088
169427
|
const outputCount = mergeRatio > 0 ? Math.max(1, Math.ceil(band.length / mergeRatio)) : 1;
|
|
169089
|
-
sessionLog(sessionId, `compressor: picked ${band.length}
|
|
169428
|
+
sessionLog(sessionId, `compressor: scored ${compartments.length}, picked ${band.length} contiguous (${selectedCompartments[0]?.startMessage}-${selectedCompartments[selectedCompartments.length - 1]?.endMessage}, ~${selectedTokens} tokens), avg_depth=${avgDepth.toFixed(1)} → output_depth=${outputDepth} (ratio=${mergeRatio}, target=${outputCount} compartments)`);
|
|
169090
169429
|
if (outputDepth === 5) {
|
|
169091
169430
|
const compressed = selectedCompartments.map((c) => ({
|
|
169092
169431
|
startMessage: c.startMessage,
|
|
@@ -169106,7 +169445,8 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169106
169445
|
originalStart: selectedCompartments[0]?.startMessage ?? 0,
|
|
169107
169446
|
originalEnd: selectedCompartments[selectedCompartments.length - 1]?.endMessage ?? 0,
|
|
169108
169447
|
facts,
|
|
169109
|
-
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${compressed.length})
|
|
169448
|
+
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${compressed.length})`,
|
|
169449
|
+
holderId: deps.compartmentLeaseHolderId
|
|
169110
169450
|
});
|
|
169111
169451
|
if (ok2)
|
|
169112
169452
|
onPublished?.();
|
|
@@ -169137,7 +169477,8 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169137
169477
|
originalStart: selectedCompartments[0]?.startMessage ?? 0,
|
|
169138
169478
|
originalEnd: selectedCompartments[selectedCompartments.length - 1]?.endMessage ?? 0,
|
|
169139
169479
|
facts,
|
|
169140
|
-
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})
|
|
169480
|
+
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})`,
|
|
169481
|
+
holderId: deps.compartmentLeaseHolderId
|
|
169141
169482
|
});
|
|
169142
169483
|
if (ok)
|
|
169143
169484
|
onPublished?.();
|
|
@@ -169246,12 +169587,20 @@ function finalizeCompression(args) {
|
|
|
169246
169587
|
sequence: leading.length + compressed.length + i
|
|
169247
169588
|
}))
|
|
169248
169589
|
];
|
|
169249
|
-
|
|
169250
|
-
|
|
169590
|
+
const published = args.holderId ? replaceAllCompartmentStateAndBumpDepth(db, args.holderId, sessionId, allCompartments, args.facts, originalStart, originalEnd) : (() => {
|
|
169591
|
+
replaceAllCompartmentState(db, sessionId, allCompartments, args.facts);
|
|
169592
|
+
incrementCompressionDepth(db, sessionId, originalStart, originalEnd);
|
|
169593
|
+
return true;
|
|
169594
|
+
})();
|
|
169595
|
+
if (!published) {
|
|
169596
|
+
sessionLog(sessionId, "compressor: publish skipped because compartment lease is no longer held");
|
|
169597
|
+
return false;
|
|
169598
|
+
}
|
|
169251
169599
|
sessionLog(sessionId, `compressor: completed ${args.logLabel}`);
|
|
169252
169600
|
return true;
|
|
169253
169601
|
}
|
|
169254
169602
|
var lastCompressorRunBySession = new Map;
|
|
169603
|
+
var lastDepthHistogramBySession = new Map;
|
|
169255
169604
|
function isPiCompressorOnCooldown(sessionId, cooldownMs) {
|
|
169256
169605
|
const last = lastCompressorRunBySession.get(sessionId);
|
|
169257
169606
|
return last !== undefined && Date.now() - last < cooldownMs;
|
|
@@ -169261,6 +169610,7 @@ function markPiCompressorRun(sessionId) {
|
|
|
169261
169610
|
}
|
|
169262
169611
|
function clearPiCompressorState(sessionId) {
|
|
169263
169612
|
lastCompressorRunBySession.delete(sessionId);
|
|
169613
|
+
lastDepthHistogramBySession.delete(sessionId);
|
|
169264
169614
|
}
|
|
169265
169615
|
|
|
169266
169616
|
// ../plugin/src/hooks/magic-context/compartment-runner-drop-queue.ts
|
|
@@ -169491,27 +169841,27 @@ function getReducedRecompTokenBudget(currentBudget) {
|
|
|
169491
169841
|
|
|
169492
169842
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
169493
169843
|
init_data_path();
|
|
169494
|
-
import { mkdirSync as
|
|
169495
|
-
import { join as
|
|
169844
|
+
import { mkdirSync as mkdirSync6, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
169845
|
+
import { join as join15 } from "node:path";
|
|
169496
169846
|
var HISTORIAN_STATE_INLINE_THRESHOLD = 30000;
|
|
169497
169847
|
function maybeWriteHistorianStateFile(sessionId, existingState, directory) {
|
|
169498
169848
|
if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
|
|
169499
169849
|
return;
|
|
169500
169850
|
try {
|
|
169501
169851
|
const dir = getProjectMagicContextHistorianDir(directory);
|
|
169502
|
-
|
|
169503
|
-
const
|
|
169504
|
-
|
|
169505
|
-
return
|
|
169852
|
+
mkdirSync6(dir, { recursive: true });
|
|
169853
|
+
const path6 = join15(dir, `state-${sessionId}-${Date.now()}.xml`);
|
|
169854
|
+
writeFileSync3(path6, existingState, "utf8");
|
|
169855
|
+
return path6;
|
|
169506
169856
|
} catch {
|
|
169507
169857
|
return;
|
|
169508
169858
|
}
|
|
169509
169859
|
}
|
|
169510
|
-
function cleanupHistorianStateFile(
|
|
169511
|
-
if (!
|
|
169860
|
+
function cleanupHistorianStateFile(path6) {
|
|
169861
|
+
if (!path6)
|
|
169512
169862
|
return;
|
|
169513
169863
|
try {
|
|
169514
|
-
unlinkSync(
|
|
169864
|
+
unlinkSync(path6);
|
|
169515
169865
|
} catch {}
|
|
169516
169866
|
}
|
|
169517
169867
|
|
|
@@ -169628,7 +169978,7 @@ function convertEntriesToRawMessages(entries) {
|
|
|
169628
169978
|
if (pendingToolParts.length > 0) {
|
|
169629
169979
|
result.push({
|
|
169630
169980
|
ordinal: nextOrdinal++,
|
|
169631
|
-
id: pendingFirstRealId
|
|
169981
|
+
id: `synth-user-${pendingFirstRealId}`,
|
|
169632
169982
|
role: "user",
|
|
169633
169983
|
parts: pendingToolParts
|
|
169634
169984
|
});
|
|
@@ -169653,7 +170003,7 @@ function convertEntriesToRawMessages(entries) {
|
|
|
169653
170003
|
if (pendingToolParts.length > 0) {
|
|
169654
170004
|
result.push({
|
|
169655
170005
|
ordinal: nextOrdinal,
|
|
169656
|
-
id: pendingFirstRealId
|
|
170006
|
+
id: `synth-user-${pendingFirstRealId}`,
|
|
169657
170007
|
role: "user",
|
|
169658
170008
|
parts: pendingToolParts
|
|
169659
170009
|
});
|
|
@@ -169776,6 +170126,7 @@ async function runPiHistorian(deps) {
|
|
|
169776
170126
|
memoryEnabled,
|
|
169777
170127
|
autoPromote,
|
|
169778
170128
|
onPublished,
|
|
170129
|
+
compartmentLeaseHolderId,
|
|
169779
170130
|
readBranchEntries,
|
|
169780
170131
|
notifyIssue
|
|
169781
170132
|
} = deps;
|
|
@@ -169802,23 +170153,27 @@ async function runPiHistorian(deps) {
|
|
|
169802
170153
|
const existingValidationError = validateStoredCompartments(priorCompartments);
|
|
169803
170154
|
if (existingValidationError) {
|
|
169804
170155
|
sessionLog(sessionId, `historian failure: source=existing-validation reason="${existingValidationError}"`);
|
|
170156
|
+
incrementHistorianFailure(db, sessionId, existingValidationError);
|
|
169805
170157
|
await notify(`Historian skipped: existing stored compartments are invalid: ${existingValidationError}`);
|
|
169806
170158
|
return;
|
|
169807
170159
|
}
|
|
169808
170160
|
const offset = priorCompartments.length > 0 ? priorCompartments[priorCompartments.length - 1].endMessage + 1 : 1;
|
|
169809
170161
|
const protectedTailStart = getProtectedTailStartOrdinal(sessionId);
|
|
169810
170162
|
if (protectedTailStart <= offset) {
|
|
169811
|
-
sessionLog(sessionId, `historian
|
|
170163
|
+
sessionLog(sessionId, `historian no-op: protectedTailStart=${protectedTailStart} <= offset=${offset} — nothing to compact`);
|
|
170164
|
+
clearEmergencyRecovery(db, sessionId);
|
|
169812
170165
|
return;
|
|
169813
170166
|
}
|
|
169814
170167
|
const chunk = readSessionChunk(sessionId, historianChunkTokens, offset, protectedTailStart);
|
|
169815
170168
|
if (!chunk.text || chunk.messageCount === 0) {
|
|
169816
|
-
sessionLog(sessionId, `historian
|
|
170169
|
+
sessionLog(sessionId, `historian no-op: chunk empty after filtering (messageCount=${chunk.messageCount}, textLen=${chunk.text?.length ?? 0}) range=${offset}-${protectedTailStart - 1}`);
|
|
170170
|
+
clearEmergencyRecovery(db, sessionId);
|
|
169817
170171
|
return;
|
|
169818
170172
|
}
|
|
169819
170173
|
const chunkCoverageError = validateChunkCoverage(chunk);
|
|
169820
170174
|
if (chunkCoverageError) {
|
|
169821
170175
|
sessionLog(sessionId, `historian failure: source=chunk-coverage reason="${chunkCoverageError}" chunkRange=${chunk.startIndex}-${chunk.endIndex}`);
|
|
170176
|
+
incrementHistorianFailure(db, sessionId, chunkCoverageError);
|
|
169822
170177
|
await notify(`Historian skipped: raw chunk could not be safely chunked: ${chunkCoverageError}`);
|
|
169823
170178
|
return;
|
|
169824
170179
|
}
|
|
@@ -169923,7 +170278,6 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169923
170278
|
systemPrompt: HISTORIAN_EDITOR_SYSTEM_PROMPT,
|
|
169924
170279
|
userMessage: buildHistorianEditorPrompt(draftAssistantText),
|
|
169925
170280
|
model: historianModel,
|
|
169926
|
-
fallbackModels,
|
|
169927
170281
|
timeoutMs: historianTimeoutMs,
|
|
169928
170282
|
cwd: directory,
|
|
169929
170283
|
thinkingLevel,
|
|
@@ -169961,10 +170315,30 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169961
170315
|
sessionLog(sessionId, `historian: native compaction queue lookup failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
169962
170316
|
}
|
|
169963
170317
|
}
|
|
169964
|
-
|
|
170318
|
+
if (!compartmentLeaseHolderId) {
|
|
170319
|
+
sessionLog(sessionId, "historian publish skipped: missing compartment lease holder");
|
|
170320
|
+
return;
|
|
170321
|
+
}
|
|
170322
|
+
let published = false;
|
|
170323
|
+
db.exec("BEGIN IMMEDIATE");
|
|
170324
|
+
try {
|
|
170325
|
+
if (!isCompartmentLeaseHeld(db, sessionId, compartmentLeaseHolderId)) {
|
|
170326
|
+
db.exec("ROLLBACK");
|
|
170327
|
+
sessionLog(sessionId, "historian publish skipped: compartment lease no longer held");
|
|
170328
|
+
return;
|
|
170329
|
+
}
|
|
169965
170330
|
appendCompartments(db, sessionId, newCompartments);
|
|
169966
170331
|
replaceSessionFacts(db, sessionId, validatedPass.facts ?? []);
|
|
169967
170332
|
clearHistorianFailureState(db, sessionId);
|
|
170333
|
+
clearEmergencyRecovery(db, sessionId);
|
|
170334
|
+
if (validatedPass.userObservations?.length) {
|
|
170335
|
+
insertUserMemoryCandidates(db, validatedPass.userObservations.map((obs) => ({
|
|
170336
|
+
content: obs,
|
|
170337
|
+
sessionId,
|
|
170338
|
+
sourceCompartmentStart: newCompartments[0]?.startMessage,
|
|
170339
|
+
sourceCompartmentEnd: lastNewEnd
|
|
170340
|
+
})));
|
|
170341
|
+
}
|
|
169968
170342
|
if (firstKeptEntryId && lastNewEndMessageId) {
|
|
169969
170343
|
setPendingPiCompactionMarkerState(db, sessionId, {
|
|
169970
170344
|
firstKeptEntryId,
|
|
@@ -169975,13 +170349,24 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169975
170349
|
publishedAt: Date.now()
|
|
169976
170350
|
});
|
|
169977
170351
|
}
|
|
169978
|
-
|
|
170352
|
+
db.exec("COMMIT");
|
|
170353
|
+
published = true;
|
|
170354
|
+
} finally {
|
|
170355
|
+
if (!published) {
|
|
170356
|
+
try {
|
|
170357
|
+
db.exec("ROLLBACK");
|
|
170358
|
+
} catch {}
|
|
170359
|
+
}
|
|
170360
|
+
}
|
|
169979
170361
|
onNoteTrigger(db, sessionId, "historian_complete");
|
|
169980
170362
|
onPublished?.();
|
|
169981
170363
|
if (memoryEnabled !== false && autoPromote !== false) {
|
|
169982
170364
|
promoteSessionFactsToMemory(db, sessionId, projectPath, validatedPass.facts ?? []);
|
|
169983
170365
|
}
|
|
169984
170366
|
queueDropsForCompartmentalizedMessages(db, sessionId, lastNewEnd);
|
|
170367
|
+
if (validatedPass.userObservations?.length) {
|
|
170368
|
+
sessionLog(sessionId, `stored ${validatedPass.userObservations.length} user memory candidate(s)`);
|
|
170369
|
+
}
|
|
169985
170370
|
sessionLog(sessionId, `historian: published ${newCompartments.length} compartment(s), ${validatedPass.facts?.length ?? 0} fact(s) covering messages ${chunk.startIndex}-${lastNewEnd}`);
|
|
169986
170371
|
completedSuccessfully = true;
|
|
169987
170372
|
});
|
|
@@ -170453,8 +170838,8 @@ function stripPiDroppedPlaceholderMessages(args) {
|
|
|
170453
170838
|
|
|
170454
170839
|
// src/system-prompt.ts
|
|
170455
170840
|
import { createHash as createHash8 } from "node:crypto";
|
|
170456
|
-
import { existsSync as
|
|
170457
|
-
import { join as
|
|
170841
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
|
|
170842
|
+
import { join as join17 } from "node:path";
|
|
170458
170843
|
|
|
170459
170844
|
// ../plugin/src/agents/magic-context-prompt.ts
|
|
170460
170845
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
@@ -170544,16 +170929,16 @@ Prefer many small targeted operations over one large blanket operation. Compress
|
|
|
170544
170929
|
}
|
|
170545
170930
|
|
|
170546
170931
|
// ../plugin/src/hooks/magic-context/key-files-block.ts
|
|
170547
|
-
import { readFileSync as
|
|
170548
|
-
import { join as
|
|
170932
|
+
import { readFileSync as readFileSync8, realpathSync as realpathSync3 } from "node:fs";
|
|
170933
|
+
import { join as join16, sep as sep2 } from "node:path";
|
|
170549
170934
|
init_logger();
|
|
170550
170935
|
var cachedKeyFilesBySession = new Map;
|
|
170551
170936
|
var staleUpdates = new Map;
|
|
170552
170937
|
function staleKey(update) {
|
|
170553
170938
|
return `${update.projectPath}\x00${update.path}\x00${update.generatedAtWitness}\x00${update.staleReason}`;
|
|
170554
170939
|
}
|
|
170555
|
-
function queueStaleUpdate(projectPath,
|
|
170556
|
-
const update = { projectPath, path:
|
|
170940
|
+
function queueStaleUpdate(projectPath, path6, generatedAtWitness, staleReason) {
|
|
170941
|
+
const update = { projectPath, path: path6, generatedAtWitness, staleReason };
|
|
170557
170942
|
staleUpdates.set(staleKey(update), update);
|
|
170558
170943
|
}
|
|
170559
170944
|
function flushStaleUpdates(db) {
|
|
@@ -170598,13 +170983,13 @@ function buildKeyFilesBlock(db, projectPath, config2 = { enabled: true, tokenBud
|
|
|
170598
170983
|
let nextStale = null;
|
|
170599
170984
|
let observed = false;
|
|
170600
170985
|
try {
|
|
170601
|
-
const absPath =
|
|
170986
|
+
const absPath = join16(projectPath, row.path);
|
|
170602
170987
|
const real = realpathSync3(absPath);
|
|
170603
170988
|
if (!isUnderProject(projectPath, real)) {
|
|
170604
170989
|
nextStale = "missing";
|
|
170605
170990
|
observed = true;
|
|
170606
170991
|
} else {
|
|
170607
|
-
const diskHash = sha256(
|
|
170992
|
+
const diskHash = sha256(readFileSync8(real));
|
|
170608
170993
|
if (diskHash !== row.contentHash)
|
|
170609
170994
|
nextStale = "content_drift";
|
|
170610
170995
|
observed = true;
|
|
@@ -170681,10 +171066,10 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
170681
171066
|
function readProjectDocs(directory) {
|
|
170682
171067
|
const sections = [];
|
|
170683
171068
|
for (const filename of DOC_FILES) {
|
|
170684
|
-
const filePath =
|
|
171069
|
+
const filePath = join17(directory, filename);
|
|
170685
171070
|
try {
|
|
170686
|
-
if (
|
|
170687
|
-
const content =
|
|
171071
|
+
if (existsSync12(filePath)) {
|
|
171072
|
+
const content = readFileSync9(filePath, "utf-8").trim();
|
|
170688
171073
|
if (content.length > 0) {
|
|
170689
171074
|
sections.push(`<${filename}>
|
|
170690
171075
|
${escapeXmlContent(content)}
|
|
@@ -171438,6 +171823,16 @@ var recentReduceBySession = new Map;
|
|
|
171438
171823
|
var liveModelBySession = new Map;
|
|
171439
171824
|
var toolUsageSinceUserTurn = new Map;
|
|
171440
171825
|
var latestUserMessageBySession = new Map;
|
|
171826
|
+
var RECENT_REDUCE_TTL_MS = 5 * 60 * 1000;
|
|
171827
|
+
function hasRecentPiCtxReduceExecution(sessionId) {
|
|
171828
|
+
const recordedAt = recentReduceBySession.get(sessionId);
|
|
171829
|
+
if (recordedAt === undefined)
|
|
171830
|
+
return false;
|
|
171831
|
+
if (Date.now() - recordedAt <= RECENT_REDUCE_TTL_MS)
|
|
171832
|
+
return true;
|
|
171833
|
+
recentReduceBySession.delete(sessionId);
|
|
171834
|
+
return false;
|
|
171835
|
+
}
|
|
171441
171836
|
function logTransformTiming(sessionId, stage, start, extra) {
|
|
171442
171837
|
const elapsed = (performance.now() - start).toFixed(1);
|
|
171443
171838
|
const suffix = extra ? ` ${extra}` : "";
|
|
@@ -171527,7 +171922,7 @@ function recordPiToolExecution(sessionId) {
|
|
|
171527
171922
|
function onPiNewUserMessage(args) {
|
|
171528
171923
|
const sessionMeta = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
171529
171924
|
const turnUsage = toolUsageSinceUserTurn.get(args.sessionId);
|
|
171530
|
-
const agentAlreadyReduced =
|
|
171925
|
+
const agentAlreadyReduced = hasRecentPiCtxReduceExecution(args.sessionId);
|
|
171531
171926
|
if (!sessionMeta.isSubagent && !agentAlreadyReduced && getPersistedStickyTurnReminder(args.db, args.sessionId) === null && turnUsage !== undefined && turnUsage >= TOOL_HEAVY_TURN_REMINDER_THRESHOLD) {
|
|
171532
171927
|
setPersistedStickyTurnReminder(args.db, args.sessionId, TOOL_HEAVY_TURN_REMINDER_TEXT);
|
|
171533
171928
|
}
|
|
@@ -171648,7 +172043,8 @@ function collectMessageEntryIdsByRef(ctx, messages, sessionId, preloadedBranchEn
|
|
|
171648
172043
|
continue;
|
|
171649
172044
|
}
|
|
171650
172045
|
const fingerprint = piMessageEntryFingerprint(msg);
|
|
171651
|
-
const
|
|
172046
|
+
const fingerprintBucket = fingerprint ? entryIdsByFingerprint.get(fingerprint) : undefined;
|
|
172047
|
+
const fingerprintId = fingerprintBucket?.length === 1 && !consumedFingerprintIds.has(fingerprintBucket[0]) ? fingerprintBucket[0] : undefined;
|
|
171652
172048
|
if (typeof fingerprintId === "string") {
|
|
171653
172049
|
consumedFingerprintIds.add(fingerprintId);
|
|
171654
172050
|
result[i] = fingerprintId;
|
|
@@ -171784,8 +172180,10 @@ function registerPiContextHandler(pi, options) {
|
|
|
171784
172180
|
});
|
|
171785
172181
|
clearHistorianFailureState(options.db, sessionId);
|
|
171786
172182
|
clearPersistedReasoningWatermark(options.db, sessionId);
|
|
171787
|
-
|
|
171788
|
-
|
|
172183
|
+
if (modelChanged) {
|
|
172184
|
+
clearDetectedContextLimit(options.db, sessionId);
|
|
172185
|
+
clearEmergencyRecovery(options.db, sessionId);
|
|
172186
|
+
}
|
|
171789
172187
|
sessionMetaForUsage.lastContextPercentage = 0;
|
|
171790
172188
|
sessionMetaForUsage.lastInputTokens = 0;
|
|
171791
172189
|
sessionMetaForUsage.observedSafeInputTokens = 0;
|
|
@@ -171855,6 +172253,10 @@ function registerPiContextHandler(pi, options) {
|
|
|
171855
172253
|
setDeferredExecutePendingIfAbsent(options.db, sessionId, flagPayload);
|
|
171856
172254
|
}
|
|
171857
172255
|
schedulerDecision = midTurnAdjustedSchedulerDecision;
|
|
172256
|
+
const deferredExecutePending = peekDeferredExecutePending(options.db, sessionId);
|
|
172257
|
+
if (deferredExecutePending !== null && schedulerDecision === "defer" && !midTurn) {
|
|
172258
|
+
schedulerDecision = "execute";
|
|
172259
|
+
}
|
|
171858
172260
|
sessionLog(sessionId, `[boundary-exec] base=${schedulerDecisionEarly} bypass=${bypassReason} midTurn=${midTurn} effective=${midTurnAdjustedSchedulerDecision} sideEffect=${sideEffect}`);
|
|
171859
172261
|
const forceMaterialization = usagePercentage >= FORCE_MATERIALIZATION_PERCENTAGE;
|
|
171860
172262
|
const isEmergency = usagePercentage >= EMERGENCY_BLOCK_PERCENTAGE;
|
|
@@ -171933,7 +172335,7 @@ function registerPiContextHandler(pi, options) {
|
|
|
171933
172335
|
db: options.db,
|
|
171934
172336
|
messages: outputMessages,
|
|
171935
172337
|
entryIds: entryIds ?? null,
|
|
171936
|
-
hasRecentReduceCall:
|
|
172338
|
+
hasRecentReduceCall: hasRecentPiCtxReduceExecution(sessionId),
|
|
171937
172339
|
isCacheBustingPass: cacheBustingPass
|
|
171938
172340
|
});
|
|
171939
172341
|
} catch (err) {
|
|
@@ -171960,8 +172362,7 @@ function registerPiContextHandler(pi, options) {
|
|
|
171960
172362
|
db: options.db,
|
|
171961
172363
|
messages: outputMessages,
|
|
171962
172364
|
projectIdentity,
|
|
171963
|
-
entryIds: strictEntryIds
|
|
171964
|
-
isCacheBusting
|
|
172365
|
+
entryIds: strictEntryIds
|
|
171965
172366
|
});
|
|
171966
172367
|
} catch (err) {
|
|
171967
172368
|
sessionLog(sessionId, `note nudges failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -172084,6 +172485,13 @@ function resolveHistoryBudgetTokensForPi(args) {
|
|
|
172084
172485
|
contextLimit: derivedLimit
|
|
172085
172486
|
}) / 100) * historyBudgetPercentage);
|
|
172086
172487
|
}
|
|
172488
|
+
function startPiCompartmentLeaseRenewal(db, sessionId, holderId) {
|
|
172489
|
+
return setInterval(() => {
|
|
172490
|
+
if (!renewCompartmentLease(db, sessionId, holderId)) {
|
|
172491
|
+
sessionLog(sessionId, "compartment lease renewal failed; publish will be skipped if holder is stale");
|
|
172492
|
+
}
|
|
172493
|
+
}, COMPARTMENT_LEASE_RENEWAL_MS);
|
|
172494
|
+
}
|
|
172087
172495
|
function maybeFireCompressor(args) {
|
|
172088
172496
|
const { ctx, sessionId, db, historian } = args;
|
|
172089
172497
|
const compressor = historian.compressor;
|
|
@@ -172109,30 +172517,46 @@ function maybeFireCompressor(args) {
|
|
|
172109
172517
|
});
|
|
172110
172518
|
if (!historyBudgetTokens || historyBudgetTokens <= 0)
|
|
172111
172519
|
return;
|
|
172112
|
-
const
|
|
172113
|
-
|
|
172114
|
-
sessionId,
|
|
172115
|
-
|
|
172116
|
-
|
|
172117
|
-
|
|
172118
|
-
fallbackModels: historian.fallbackModels,
|
|
172119
|
-
historyBudgetTokens,
|
|
172120
|
-
historianTimeoutMs: historian.timeoutMs,
|
|
172121
|
-
thinkingLevel: historian.thinkingLevel,
|
|
172122
|
-
minCompartmentRatio: compressor.minCompartmentRatio,
|
|
172123
|
-
maxMergeDepth: compressor.maxMergeDepth,
|
|
172124
|
-
maxCompartmentsPerPass: compressor.maxCompartmentsPerPass,
|
|
172125
|
-
graceCompartments: compressor.graceCompartments,
|
|
172126
|
-
onPublished: () => {
|
|
172127
|
-
if (!isContextHandlerSessionActive(sessionId)) {
|
|
172128
|
-
sessionLog(sessionId, "compressor publication ignored: session was cleared");
|
|
172129
|
-
return;
|
|
172130
|
-
}
|
|
172131
|
-
signalPiDeferredHistoryRefresh(sessionId);
|
|
172132
|
-
signalPiDeferredMaterialization(sessionId);
|
|
172133
|
-
historian.onStatusChange?.(ctx, sessionId);
|
|
172520
|
+
const holderId = crypto2.randomUUID();
|
|
172521
|
+
const runPromise = (async () => {
|
|
172522
|
+
const lease2 = acquireCompartmentLease(db, sessionId, holderId);
|
|
172523
|
+
if (!lease2) {
|
|
172524
|
+
sessionLog(sessionId, "compressor skipped: compartment lease held by another process");
|
|
172525
|
+
return false;
|
|
172134
172526
|
}
|
|
172135
|
-
|
|
172527
|
+
const renewal = startPiCompartmentLeaseRenewal(db, sessionId, holderId);
|
|
172528
|
+
try {
|
|
172529
|
+
return await runPiCompressionPassIfNeeded({
|
|
172530
|
+
db,
|
|
172531
|
+
sessionId,
|
|
172532
|
+
directory: ctx.cwd,
|
|
172533
|
+
runner: historian.runner,
|
|
172534
|
+
historianModel: historian.model,
|
|
172535
|
+
fallbackModels: historian.fallbackModels,
|
|
172536
|
+
historyBudgetTokens,
|
|
172537
|
+
historianTimeoutMs: historian.timeoutMs,
|
|
172538
|
+
thinkingLevel: historian.thinkingLevel,
|
|
172539
|
+
minCompartmentRatio: compressor.minCompartmentRatio,
|
|
172540
|
+
maxMergeDepth: compressor.maxMergeDepth,
|
|
172541
|
+
maxCompartmentsPerPass: compressor.maxCompartmentsPerPass,
|
|
172542
|
+
graceCompartments: compressor.graceCompartments,
|
|
172543
|
+
compartmentLeaseHolderId: holderId,
|
|
172544
|
+
onPublished: () => {
|
|
172545
|
+
const sessionStillActive = isContextHandlerSessionActive(sessionId);
|
|
172546
|
+
signalPiDeferredHistoryRefresh(sessionId);
|
|
172547
|
+
signalPiDeferredMaterialization(sessionId);
|
|
172548
|
+
if (sessionStillActive) {
|
|
172549
|
+
historian.onStatusChange?.(ctx, sessionId);
|
|
172550
|
+
} else {
|
|
172551
|
+
sessionLog(sessionId, "compressor publication recorded after session clear; status callback skipped");
|
|
172552
|
+
}
|
|
172553
|
+
}
|
|
172554
|
+
});
|
|
172555
|
+
} finally {
|
|
172556
|
+
clearInterval(renewal);
|
|
172557
|
+
releaseCompartmentLease(db, sessionId, holderId);
|
|
172558
|
+
}
|
|
172559
|
+
})().then((didPublish) => {
|
|
172136
172560
|
if (didPublish === true) {
|
|
172137
172561
|
markPiCompressorRun(sessionId);
|
|
172138
172562
|
}
|
|
@@ -172170,37 +172594,53 @@ function sendPiIgnoredNotification(ctx, message) {
|
|
|
172170
172594
|
}
|
|
172171
172595
|
function spawnPiHistorianRun(args) {
|
|
172172
172596
|
const { ctx, sessionId, db, historian, provider: provider2, unregister } = args;
|
|
172173
|
-
const
|
|
172174
|
-
|
|
172175
|
-
sessionId,
|
|
172176
|
-
|
|
172177
|
-
|
|
172178
|
-
|
|
172179
|
-
readBranchEntries: resolvePiReadBranchEntries(ctx),
|
|
172180
|
-
runner: historian.runner,
|
|
172181
|
-
historianModel: historian.model,
|
|
172182
|
-
fallbackModels: historian.fallbackModels,
|
|
172183
|
-
historianChunkTokens: historian.historianChunkTokens,
|
|
172184
|
-
historianTimeoutMs: historian.timeoutMs,
|
|
172185
|
-
twoPass: historian.twoPass,
|
|
172186
|
-
thinkingLevel: historian.thinkingLevel,
|
|
172187
|
-
memoryEnabled: historian.memoryEnabled,
|
|
172188
|
-
autoPromote: historian.autoPromote,
|
|
172189
|
-
onPublished: () => {
|
|
172190
|
-
if (!isContextHandlerSessionActive(sessionId)) {
|
|
172191
|
-
sessionLog(sessionId, "historian publication ignored: session was cleared");
|
|
172192
|
-
return;
|
|
172193
|
-
}
|
|
172194
|
-
try {
|
|
172195
|
-
clearEmergencyRecovery(db, sessionId);
|
|
172196
|
-
} catch (err) {
|
|
172197
|
-
sessionLog(sessionId, `historian: clearEmergencyRecovery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
172198
|
-
}
|
|
172199
|
-
signalPiDeferredHistoryRefresh(sessionId);
|
|
172200
|
-
signalPiDeferredMaterialization(sessionId);
|
|
172201
|
-
historian.onStatusChange?.(ctx, sessionId);
|
|
172597
|
+
const holderId = crypto2.randomUUID();
|
|
172598
|
+
const runPromise = (async () => {
|
|
172599
|
+
const lease2 = acquireCompartmentLease(db, sessionId, holderId);
|
|
172600
|
+
if (!lease2) {
|
|
172601
|
+
sessionLog(sessionId, "historian skipped: compartment lease held by another process");
|
|
172602
|
+
return;
|
|
172202
172603
|
}
|
|
172203
|
-
|
|
172604
|
+
const renewal = startPiCompartmentLeaseRenewal(db, sessionId, holderId);
|
|
172605
|
+
try {
|
|
172606
|
+
await runPiHistorian({
|
|
172607
|
+
db,
|
|
172608
|
+
sessionId,
|
|
172609
|
+
directory: ctx.cwd,
|
|
172610
|
+
provider: provider2,
|
|
172611
|
+
appendCompaction: resolvePiAppendCompaction(ctx),
|
|
172612
|
+
readBranchEntries: resolvePiReadBranchEntries(ctx),
|
|
172613
|
+
runner: historian.runner,
|
|
172614
|
+
historianModel: historian.model,
|
|
172615
|
+
fallbackModels: historian.fallbackModels,
|
|
172616
|
+
historianChunkTokens: historian.historianChunkTokens,
|
|
172617
|
+
historianTimeoutMs: historian.timeoutMs,
|
|
172618
|
+
twoPass: historian.twoPass,
|
|
172619
|
+
thinkingLevel: historian.thinkingLevel,
|
|
172620
|
+
memoryEnabled: historian.memoryEnabled,
|
|
172621
|
+
autoPromote: historian.autoPromote,
|
|
172622
|
+
compartmentLeaseHolderId: holderId,
|
|
172623
|
+
onPublished: () => {
|
|
172624
|
+
const sessionStillActive = isContextHandlerSessionActive(sessionId);
|
|
172625
|
+
try {
|
|
172626
|
+
clearEmergencyRecovery(db, sessionId);
|
|
172627
|
+
} catch (err) {
|
|
172628
|
+
sessionLog(sessionId, `historian: clearEmergencyRecovery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
172629
|
+
}
|
|
172630
|
+
signalPiDeferredHistoryRefresh(sessionId);
|
|
172631
|
+
signalPiDeferredMaterialization(sessionId);
|
|
172632
|
+
if (sessionStillActive) {
|
|
172633
|
+
historian.onStatusChange?.(ctx, sessionId);
|
|
172634
|
+
} else {
|
|
172635
|
+
sessionLog(sessionId, "historian publication recorded after session clear; status callback skipped");
|
|
172636
|
+
}
|
|
172637
|
+
}
|
|
172638
|
+
});
|
|
172639
|
+
} finally {
|
|
172640
|
+
clearInterval(renewal);
|
|
172641
|
+
releaseCompartmentLease(db, sessionId, holderId);
|
|
172642
|
+
}
|
|
172643
|
+
})().finally(() => {
|
|
172204
172644
|
inFlightHistorian.delete(sessionId);
|
|
172205
172645
|
unregister();
|
|
172206
172646
|
if (isContextHandlerSessionActive(sessionId)) {
|
|
@@ -172221,12 +172661,11 @@ function resolvePiReadBranchEntries(ctx) {
|
|
|
172221
172661
|
if (typeof sm?.getBranch !== "function")
|
|
172222
172662
|
return;
|
|
172223
172663
|
return () => {
|
|
172224
|
-
|
|
172225
|
-
|
|
172226
|
-
|
|
172227
|
-
} catch {
|
|
172228
|
-
return [];
|
|
172664
|
+
const entries = sm.getBranch?.call(sm);
|
|
172665
|
+
if (!Array.isArray(entries)) {
|
|
172666
|
+
throw new Error("Pi sessionManager.getBranch() did not return an array");
|
|
172229
172667
|
}
|
|
172668
|
+
return entries;
|
|
172230
172669
|
};
|
|
172231
172670
|
}
|
|
172232
172671
|
function maybeFireHistorian(args) {
|
|
@@ -172328,6 +172767,7 @@ Historian previously failed ${failureState.failureCount} time(s), so magic-conte
|
|
|
172328
172767
|
async function runPipeline(args) {
|
|
172329
172768
|
let executedWorkThisPass = false;
|
|
172330
172769
|
let historyWasConsumedThisPass = false;
|
|
172770
|
+
let materializationSatisfiedThisPass = false;
|
|
172331
172771
|
let suppressDeferredHistoryDrain = false;
|
|
172332
172772
|
let casLost = false;
|
|
172333
172773
|
const deferredHistoryWasPendingAtPassStart = deferredHistoryRefreshSessions.has(args.sessionId);
|
|
@@ -172349,7 +172789,7 @@ async function runPipeline(args) {
|
|
|
172349
172789
|
return findLatestUserMessageIdPi(args.messages, ids)?.messageId ?? null;
|
|
172350
172790
|
})();
|
|
172351
172791
|
const alreadyRanHeuristicsThisTurn = currentTurnId !== null && lastHeuristicsTurnIdBySession.get(args.sessionId) === currentTurnId;
|
|
172352
|
-
const shouldRunHeuristics = args.heuristics !== undefined && (args.forceMaterialization === true || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
|
|
172792
|
+
const shouldRunHeuristics = args.heuristics !== undefined && (args.forceMaterialization === true || hasPendingMaterialization(args.sessionId) || deferredMaterializationSessions.has(args.sessionId) || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
|
|
172353
172793
|
const tTag = performance.now();
|
|
172354
172794
|
const { targets } = tagTranscript(args.sessionId, transcript, args.tagger, args.db, {
|
|
172355
172795
|
skipPrefixInjection: !args.ctxReduceEnabled
|
|
@@ -172372,22 +172812,26 @@ async function runPipeline(args) {
|
|
|
172372
172812
|
const hasPendingMaterializeSignal = hasPendingMaterialization(args.sessionId);
|
|
172373
172813
|
const deferredMaterializationWasPending = deferredMaterializationSessions.has(args.sessionId);
|
|
172374
172814
|
const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
|
|
172815
|
+
const deferredExecuteWasPending = peekDeferredExecutePending(args.db, args.sessionId) !== null;
|
|
172375
172816
|
const pendingOps = getPendingOps(args.db, args.sessionId);
|
|
172376
|
-
const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal;
|
|
172817
|
+
const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || deferredExecuteWasPending;
|
|
172377
172818
|
const canConsumeDeferredLate = baseShouldApplyPendingOps || shouldRunHeuristics;
|
|
172378
172819
|
const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
|
|
172379
172820
|
const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
|
|
172380
172821
|
const shouldApplyPendingOps = baseShouldApplyPendingOps || deferredMaterialize;
|
|
172381
172822
|
if (shouldApplyPendingOps) {
|
|
172382
|
-
const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
172823
|
+
const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredExecuteWasPending ? "deferred_boundary_execute" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
172383
172824
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
172384
172825
|
try {
|
|
172385
172826
|
const tApplyPending = performance.now();
|
|
172386
172827
|
applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, pendingOps);
|
|
172387
172828
|
logTransformTiming(args.sessionId, "applyPendingOperations", tApplyPending);
|
|
172388
172829
|
executedWorkThisPass = true;
|
|
172830
|
+
materializationSatisfiedThisPass = true;
|
|
172389
172831
|
if (hasPendingMaterializeSignal) {
|
|
172390
|
-
|
|
172832
|
+
if (args.heuristics === undefined) {
|
|
172833
|
+
consumePendingMaterialization(args.sessionId);
|
|
172834
|
+
}
|
|
172391
172835
|
}
|
|
172392
172836
|
if (deferredMaterialize) {
|
|
172393
172837
|
consumeDeferredMaterialization(args.sessionId);
|
|
@@ -172467,6 +172911,9 @@ async function runPipeline(args) {
|
|
|
172467
172911
|
}, activeTags);
|
|
172468
172912
|
heuristicsExecuted = true;
|
|
172469
172913
|
executedWorkThisPass = true;
|
|
172914
|
+
if (hasPendingMaterializeSignal) {
|
|
172915
|
+
consumePendingMaterialization(args.sessionId);
|
|
172916
|
+
}
|
|
172470
172917
|
if (currentTurnId !== null) {
|
|
172471
172918
|
lastHeuristicsTurnIdBySession.set(args.sessionId, currentTurnId);
|
|
172472
172919
|
}
|
|
@@ -172501,7 +172948,9 @@ async function runPipeline(args) {
|
|
|
172501
172948
|
}
|
|
172502
172949
|
logTransformTiming(args.sessionId, "clearOldReasoning", tClearReasoning);
|
|
172503
172950
|
logTransformTiming(args.sessionId, "watermarkCleanup", tClearReasoning);
|
|
172504
|
-
|
|
172951
|
+
if (combinedWatermark > prevWatermark || clearOutcome.cleared > 0 || stripOutcome.stripped > 0) {
|
|
172952
|
+
executedWorkThisPass = true;
|
|
172953
|
+
}
|
|
172505
172954
|
} catch (err) {
|
|
172506
172955
|
sessionLog(args.sessionId, `reasoning clearing failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
172507
172956
|
}
|
|
@@ -172531,7 +172980,7 @@ async function runPipeline(args) {
|
|
|
172531
172980
|
messages: args.messages,
|
|
172532
172981
|
isCacheBusting: args.isCacheBusting
|
|
172533
172982
|
});
|
|
172534
|
-
const deferredHistoryDrainEligible = historyWasConsumedThisPass && deferredHistoryWasPendingAtPassStart && !suppressDeferredHistoryDrain && !casLost;
|
|
172983
|
+
const deferredHistoryDrainEligible = historyWasConsumedThisPass && materializationSatisfiedThisPass && (deferredHistoryWasPendingAtPassStart || hasPendingMaterializeSignal) && !suppressDeferredHistoryDrain && !casLost;
|
|
172535
172984
|
if (deferredHistoryDrainEligible) {
|
|
172536
172985
|
try {
|
|
172537
172986
|
const pending = getPendingPiCompactionMarkerState(args.db, args.sessionId);
|
|
@@ -172621,7 +173070,7 @@ function applyStickyTurnReminder(args) {
|
|
|
172621
173070
|
const messageIdByIndex = buildPiMessageIdByIndex(args.messages, args.entryIds);
|
|
172622
173071
|
if (reminder.messageId) {
|
|
172623
173072
|
const reinjected = appendReminderToUserMessageByIdPi(args.messages, messageIdByIndex, reminder.messageId, reminder.text);
|
|
172624
|
-
if (!reinjected && args.isCacheBustingPass && args.entryIds !== null) {
|
|
173073
|
+
if (!reinjected && args.isCacheBustingPass && args.entryIds !== null && !args.entryIds.includes(undefined) && !args.entryIds.includes(reminder.messageId)) {
|
|
172625
173074
|
clearPersistedStickyTurnReminder(args.db, args.sessionId);
|
|
172626
173075
|
}
|
|
172627
173076
|
return args.messages;
|
|
@@ -172638,14 +173087,15 @@ function applyStickyTurnReminder(args) {
|
|
|
172638
173087
|
return args.messages;
|
|
172639
173088
|
}
|
|
172640
173089
|
function applyNoteNudges(args) {
|
|
172641
|
-
const { sessionId, db, messages, projectIdentity, entryIds
|
|
173090
|
+
const { sessionId, db, messages, projectIdentity, entryIds } = args;
|
|
172642
173091
|
const messageIdByIndex = buildPiMessageIdByIndex(messages, entryIds);
|
|
173092
|
+
const replayMessageIdByIndex = buildPiMessageIdByIndex(messages, entryIds, true);
|
|
172643
173093
|
for (const anchor of getNoteNudgeAnchors(db, sessionId)) {
|
|
172644
|
-
appendReminderToUserMessageByIdPi(messages,
|
|
173094
|
+
appendReminderToUserMessageByIdPi(messages, replayMessageIdByIndex, anchor.messageId, anchor.text);
|
|
172645
173095
|
}
|
|
172646
173096
|
for (const decision of getAutoSearchHintDecisions(db, sessionId)) {
|
|
172647
173097
|
if (decision.decision === "hint") {
|
|
172648
|
-
appendReminderToUserMessageByIdPi(messages,
|
|
173098
|
+
appendReminderToUserMessageByIdPi(messages, replayMessageIdByIndex, decision.messageId, decision.text);
|
|
172649
173099
|
}
|
|
172650
173100
|
}
|
|
172651
173101
|
const latestUser = findLatestUserMessageIdPi(messages, messageIdByIndex);
|
|
@@ -172661,14 +173111,18 @@ function applyNoteNudges(args) {
|
|
|
172661
173111
|
|
|
172662
173112
|
<instruction name="deferred_notes">${deferredNoteText}</instruction>`;
|
|
172663
173113
|
const anchoredId = latestUser?.messageId ?? null;
|
|
173114
|
+
if (!anchoredId) {
|
|
173115
|
+
sessionLog(sessionId, "Pi note-nudge: latest user message has no resolved SessionEntry id; deferring delivery to next pass");
|
|
173116
|
+
return messages;
|
|
173117
|
+
}
|
|
172664
173118
|
const outcome = markNoteNudgeDelivered(db, sessionId, noteInstruction, anchoredId);
|
|
172665
|
-
if (latestUser &&
|
|
173119
|
+
if (latestUser && outcome.ok) {
|
|
172666
173120
|
appendReminderToPiUserMessage(messages[latestUser.index], noteInstruction);
|
|
172667
|
-
} else if (
|
|
173121
|
+
} else if (!outcome.ok) {
|
|
172668
173122
|
sessionLog(sessionId, `Pi note-nudge delivery skipped wire append: ${outcome.kind}`);
|
|
172669
173123
|
}
|
|
172670
173124
|
}
|
|
172671
|
-
if (
|
|
173125
|
+
if (entryIds !== null && !entryIds.includes(undefined)) {
|
|
172672
173126
|
const visibleIds = new Set(entryIds.filter((id) => typeof id === "string"));
|
|
172673
173127
|
pruneNoteNudgeAnchors(db, sessionId, visibleIds);
|
|
172674
173128
|
pruneAutoSearchHintDecisions(db, sessionId, visibleIds);
|
|
@@ -172700,7 +173154,7 @@ function hasMeaningfulUserTextPi(message) {
|
|
|
172700
173154
|
}
|
|
172701
173155
|
return false;
|
|
172702
173156
|
}
|
|
172703
|
-
function buildPiMessageIdByIndex(messages, entryIds) {
|
|
173157
|
+
function buildPiMessageIdByIndex(messages, entryIds, includeMessageIdFallback = false) {
|
|
172704
173158
|
const ids = new Map;
|
|
172705
173159
|
for (let index = 0;index < messages.length; index += 1) {
|
|
172706
173160
|
const entryId = entryIds?.[index];
|
|
@@ -172708,9 +173162,11 @@ function buildPiMessageIdByIndex(messages, entryIds) {
|
|
|
172708
173162
|
ids.set(index, entryId);
|
|
172709
173163
|
continue;
|
|
172710
173164
|
}
|
|
172711
|
-
|
|
172712
|
-
|
|
172713
|
-
|
|
173165
|
+
if (includeMessageIdFallback) {
|
|
173166
|
+
const messageId = messages[index]?.id;
|
|
173167
|
+
if (typeof messageId === "string") {
|
|
173168
|
+
ids.set(index, messageId);
|
|
173169
|
+
}
|
|
172714
173170
|
}
|
|
172715
173171
|
}
|
|
172716
173172
|
return ids;
|
|
@@ -172841,7 +173297,7 @@ init_logger();
|
|
|
172841
173297
|
init_data_path();
|
|
172842
173298
|
init_logger();
|
|
172843
173299
|
await init_sqlite();
|
|
172844
|
-
import { join as
|
|
173300
|
+
import { join as join18 } from "node:path";
|
|
172845
173301
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
172846
173302
|
function randomBase62(length) {
|
|
172847
173303
|
const chars = [];
|
|
@@ -172862,7 +173318,7 @@ function generatePartId(timestampMs, counter = 0n) {
|
|
|
172862
173318
|
return generateId("prt", timestampMs, counter);
|
|
172863
173319
|
}
|
|
172864
173320
|
function getOpenCodeDbPath3() {
|
|
172865
|
-
return
|
|
173321
|
+
return join18(getDataDir(), "opencode", "opencode.db");
|
|
172866
173322
|
}
|
|
172867
173323
|
var cachedWriteDb = null;
|
|
172868
173324
|
var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
@@ -173031,7 +173487,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
173031
173487
|
// ../plugin/src/hooks/magic-context/compartment-runner-compressor.ts
|
|
173032
173488
|
init_logger();
|
|
173033
173489
|
var HISTORIAN_AGENT2 = "historian";
|
|
173034
|
-
var
|
|
173490
|
+
var lastDepthHistogramBySession2 = new Map;
|
|
173035
173491
|
function cavemanLevelForDepth2(outputDepth) {
|
|
173036
173492
|
if (outputDepth <= 1)
|
|
173037
173493
|
return null;
|
|
@@ -173045,6 +173501,10 @@ function cavemanLevelForDepth2(outputDepth) {
|
|
|
173045
173501
|
}
|
|
173046
173502
|
async function runCompressionPassIfNeeded(deps) {
|
|
173047
173503
|
const { db, sessionId, historyBudgetTokens } = deps;
|
|
173504
|
+
if (deps.historianRunnable === false) {
|
|
173505
|
+
sessionLog(sessionId, "compressor: skipped because historian.disable=true");
|
|
173506
|
+
return false;
|
|
173507
|
+
}
|
|
173048
173508
|
const minCompartmentRatio = deps.minCompartmentRatio ?? DEFAULT_COMPRESSOR_MIN_COMPARTMENT_RATIO;
|
|
173049
173509
|
const maxMergeDepth = deps.maxMergeDepth ?? DEFAULT_COMPRESSOR_MAX_MERGE_DEPTH;
|
|
173050
173510
|
const compartments = getCompartments(db, sessionId);
|
|
@@ -173084,8 +173544,8 @@ ${c.content}
|
|
|
173084
173544
|
}
|
|
173085
173545
|
const histText = [...depthHistogram.entries()].sort((a, b) => a[0] - b[0]).map(([d, n]) => `d${d}=${n}`).join(" ");
|
|
173086
173546
|
const histKey = `${scored.length}|${histText}`;
|
|
173087
|
-
if (
|
|
173088
|
-
|
|
173547
|
+
if (lastDepthHistogramBySession2.get(sessionId) !== histKey) {
|
|
173548
|
+
lastDepthHistogramBySession2.set(sessionId, histKey);
|
|
173089
173549
|
sessionLog(sessionId, `compressor: depth histogram (${scored.length} total) ${histText}`);
|
|
173090
173550
|
}
|
|
173091
173551
|
const floorHeadroom = compartments.length - floor;
|
|
@@ -173131,7 +173591,8 @@ ${c.content}
|
|
|
173131
173591
|
originalStart: selectedCompartments[0].startMessage,
|
|
173132
173592
|
originalEnd: selectedCompartments[selectedCompartments.length - 1].endMessage,
|
|
173133
173593
|
facts,
|
|
173134
|
-
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${selectedCompartments.length})
|
|
173594
|
+
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${selectedCompartments.length})`,
|
|
173595
|
+
holderId: deps.compartmentLeaseHolderId
|
|
173135
173596
|
});
|
|
173136
173597
|
}
|
|
173137
173598
|
try {
|
|
@@ -173161,7 +173622,8 @@ ${c.content}
|
|
|
173161
173622
|
originalStart: selectedCompartments[0].startMessage,
|
|
173162
173623
|
originalEnd: selectedCompartments[selectedCompartments.length - 1].endMessage,
|
|
173163
173624
|
facts,
|
|
173164
|
-
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})
|
|
173625
|
+
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})`,
|
|
173626
|
+
holderId: deps.compartmentLeaseHolderId
|
|
173165
173627
|
});
|
|
173166
173628
|
} catch (error51) {
|
|
173167
173629
|
sessionLog(sessionId, "compressor: unexpected error:", getErrorMessage(error51));
|
|
@@ -173286,7 +173748,8 @@ function finalizeCompression2(args) {
|
|
|
173286
173748
|
originalStart,
|
|
173287
173749
|
originalEnd,
|
|
173288
173750
|
facts,
|
|
173289
|
-
logLabel
|
|
173751
|
+
logLabel,
|
|
173752
|
+
holderId
|
|
173290
173753
|
} = args;
|
|
173291
173754
|
const compressedStart = compressed[0].startMessage;
|
|
173292
173755
|
const compressedEnd = compressed[compressed.length - 1].endMessage;
|
|
@@ -173337,8 +173800,16 @@ function finalizeCompression2(args) {
|
|
|
173337
173800
|
content: c.content
|
|
173338
173801
|
}))
|
|
173339
173802
|
];
|
|
173340
|
-
|
|
173341
|
-
|
|
173803
|
+
const factInputs = facts.map((f) => ({ category: f.category, content: f.content }));
|
|
173804
|
+
const published = holderId ? replaceAllCompartmentStateAndBumpDepth(db, holderId, sessionId, allCompartments, factInputs, originalStart, originalEnd) : (() => {
|
|
173805
|
+
replaceAllCompartmentState(db, sessionId, allCompartments, factInputs);
|
|
173806
|
+
incrementCompressionDepth(db, sessionId, originalStart, originalEnd);
|
|
173807
|
+
return true;
|
|
173808
|
+
})();
|
|
173809
|
+
if (!published) {
|
|
173810
|
+
sessionLog(sessionId, "compressor: publish skipped because compartment lease is no longer held");
|
|
173811
|
+
return false;
|
|
173812
|
+
}
|
|
173342
173813
|
sessionLog(sessionId, `compressor: completed ${logLabel}`);
|
|
173343
173814
|
return true;
|
|
173344
173815
|
}
|
|
@@ -173419,8 +173890,8 @@ async function runCompressorPass2(args) {
|
|
|
173419
173890
|
}
|
|
173420
173891
|
|
|
173421
173892
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
173422
|
-
import { mkdirSync as
|
|
173423
|
-
import { join as
|
|
173893
|
+
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
173894
|
+
import { join as join19 } from "node:path";
|
|
173424
173895
|
init_data_path();
|
|
173425
173896
|
function historianResponseDumpDir(directory) {
|
|
173426
173897
|
return getProjectMagicContextHistorianDir(directory);
|
|
@@ -173671,11 +174142,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
173671
174142
|
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
173672
174143
|
try {
|
|
173673
174144
|
const dumpDir = historianResponseDumpDir(directory);
|
|
173674
|
-
|
|
174145
|
+
mkdirSync7(dumpDir, { recursive: true });
|
|
173675
174146
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
173676
174147
|
const safeLabel = sanitizeDumpName(label);
|
|
173677
|
-
const dumpPath =
|
|
173678
|
-
|
|
174148
|
+
const dumpPath = join19(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
174149
|
+
writeFileSync4(dumpPath, text, "utf8");
|
|
173679
174150
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
173680
174151
|
label,
|
|
173681
174152
|
dumpPath
|
|
@@ -173856,6 +174327,12 @@ async function executePartialRecompInternal(deps, range) {
|
|
|
173856
174327
|
getNotificationParams
|
|
173857
174328
|
} = deps;
|
|
173858
174329
|
const notifParams = () => getNotificationParams?.() ?? {};
|
|
174330
|
+
const holderId = deps.compartmentLeaseHolderId;
|
|
174331
|
+
if (!holderId) {
|
|
174332
|
+
return `## Magic Recomp — Failed
|
|
174333
|
+
|
|
174334
|
+
Could not acquire the compartment-state lease for this session.`;
|
|
174335
|
+
}
|
|
173859
174336
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
173860
174337
|
try {
|
|
173861
174338
|
let promoteFinal = function() {
|
|
@@ -173892,7 +174369,7 @@ async function executePartialRecompInternal(deps, range) {
|
|
|
173892
174369
|
return null;
|
|
173893
174370
|
}
|
|
173894
174371
|
saveRecompStagingPass(db, sessionId, passCount + 1, merged, currentFacts);
|
|
173895
|
-
const promoted = promoteRecompStaging(db, sessionId);
|
|
174372
|
+
const promoted = promoteRecompStaging(db, sessionId, holderId);
|
|
173896
174373
|
if (!promoted) {
|
|
173897
174374
|
log("[magic-context] partial recomp promote returned null");
|
|
173898
174375
|
return null;
|
|
@@ -174100,6 +174577,7 @@ Staging preserved for resume on next attempt.`;
|
|
|
174100
174577
|
}
|
|
174101
174578
|
|
|
174102
174579
|
// ../plugin/src/hooks/magic-context/compartment-runner-recomp.ts
|
|
174580
|
+
init_logger();
|
|
174103
174581
|
async function executeContextRecompInternal(deps) {
|
|
174104
174582
|
const {
|
|
174105
174583
|
client,
|
|
@@ -174111,6 +174589,12 @@ async function executeContextRecompInternal(deps) {
|
|
|
174111
174589
|
getNotificationParams
|
|
174112
174590
|
} = deps;
|
|
174113
174591
|
const notifParams = () => getNotificationParams?.() ?? {};
|
|
174592
|
+
const holderId = deps.compartmentLeaseHolderId;
|
|
174593
|
+
if (!holderId) {
|
|
174594
|
+
return `## Magic Recomp — Skipped
|
|
174595
|
+
|
|
174596
|
+
Could not acquire the compartment-state lease for this session.`;
|
|
174597
|
+
}
|
|
174114
174598
|
let currentStateFilePath;
|
|
174115
174599
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
174116
174600
|
try {
|
|
@@ -174147,7 +174631,7 @@ Found ${existingStaging.compartments.length} staged compartment(s) from ${existi
|
|
|
174147
174631
|
if (mergedError)
|
|
174148
174632
|
return null;
|
|
174149
174633
|
saveRecompStagingPass(db, sessionId, passCount, candidateCompartments, candidateFacts);
|
|
174150
|
-
const promoted2 = promoteRecompStaging(db, sessionId);
|
|
174634
|
+
const promoted2 = promoteRecompStaging(db, sessionId, holderId);
|
|
174151
174635
|
if (!promoted2)
|
|
174152
174636
|
return null;
|
|
174153
174637
|
clearCompressionDepth(db, sessionId);
|
|
@@ -174298,10 +174782,12 @@ Recomp completed ${passCount} pass${passCount === 1 ? "" : "es"} but produced an
|
|
|
174298
174782
|
Nothing was written.`;
|
|
174299
174783
|
}
|
|
174300
174784
|
saveRecompStagingPass(db, sessionId, passCount, candidateCompartments, candidateFacts);
|
|
174301
|
-
const promoted = promoteRecompStaging(db, sessionId);
|
|
174785
|
+
const promoted = promoteRecompStaging(db, sessionId, holderId);
|
|
174302
174786
|
if (!promoted) {
|
|
174303
|
-
|
|
174304
|
-
|
|
174787
|
+
sessionLog(sessionId, "recomp publish skipped: compartment lease no longer held");
|
|
174788
|
+
return `## Magic Recomp — Skipped
|
|
174789
|
+
|
|
174790
|
+
Another process acquired the compartment-state lease before recomp could publish. No state was written.`;
|
|
174305
174791
|
}
|
|
174306
174792
|
clearCompressionDepth(db, sessionId);
|
|
174307
174793
|
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
@@ -174370,12 +174856,32 @@ function withPublishedCallback(deps) {
|
|
|
174370
174856
|
}
|
|
174371
174857
|
};
|
|
174372
174858
|
}
|
|
174373
|
-
|
|
174859
|
+
function startLeaseRenewal(deps, holderId) {
|
|
174860
|
+
return setInterval(() => {
|
|
174861
|
+
if (!renewCompartmentLease(deps.db, deps.sessionId, holderId)) {
|
|
174862
|
+
sessionLog(deps.sessionId, "compartment lease renewal failed; publish will be skipped if holder is stale");
|
|
174863
|
+
}
|
|
174864
|
+
}, COMPARTMENT_LEASE_RENEWAL_MS);
|
|
174865
|
+
}
|
|
174866
|
+
async function executeContextRecompWithResult(deps, options = {}) {
|
|
174374
174867
|
const { sessionId } = deps;
|
|
174375
174868
|
if (activeRuns.has(sessionId)) {
|
|
174376
|
-
return
|
|
174869
|
+
return {
|
|
174870
|
+
message: "## Magic Recomp\n\nHistorian is already running for this session. Wait for it to finish, then try `/ctx-recomp` again.",
|
|
174871
|
+
published: false
|
|
174872
|
+
};
|
|
174873
|
+
}
|
|
174874
|
+
const holderId = crypto.randomUUID();
|
|
174875
|
+
const lease2 = acquireCompartmentLease(deps.db, sessionId, holderId);
|
|
174876
|
+
if (!lease2) {
|
|
174877
|
+
sessionLog(sessionId, "recomp skipped: compartment lease held by another process");
|
|
174878
|
+
return {
|
|
174879
|
+
message: "## Magic Recomp\n\nAnother process is already mutating compartment state for this session. Wait for it to finish, then try `/ctx-recomp` again.",
|
|
174880
|
+
published: false
|
|
174881
|
+
};
|
|
174377
174882
|
}
|
|
174378
|
-
const
|
|
174883
|
+
const renewal = startLeaseRenewal(deps, holderId);
|
|
174884
|
+
const runnerDeps = withPublishedCallback({ ...deps, compartmentLeaseHolderId: holderId });
|
|
174379
174885
|
const promise2 = options.range ? executePartialRecompInternal(runnerDeps, options.range) : executeContextRecompInternal(runnerDeps);
|
|
174380
174886
|
const wrappedPromise = promise2.then(() => {
|
|
174381
174887
|
return;
|
|
@@ -174384,8 +174890,14 @@ async function executeContextRecomp(deps, options = {}) {
|
|
|
174384
174890
|
});
|
|
174385
174891
|
activeRuns.set(sessionId, { promise: wrappedPromise, published: false });
|
|
174386
174892
|
try {
|
|
174387
|
-
|
|
174893
|
+
const message = await promise2;
|
|
174894
|
+
return {
|
|
174895
|
+
message,
|
|
174896
|
+
published: activeRuns.get(sessionId)?.published === true
|
|
174897
|
+
};
|
|
174388
174898
|
} finally {
|
|
174899
|
+
clearInterval(renewal);
|
|
174900
|
+
releaseCompartmentLease(deps.db, sessionId, holderId);
|
|
174389
174901
|
if (activeRuns.get(sessionId)?.promise === wrappedPromise) {
|
|
174390
174902
|
activeRuns.delete(sessionId);
|
|
174391
174903
|
}
|
|
@@ -174558,7 +175070,7 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
174558
175070
|
projectIdentity: ctx.cwd
|
|
174559
175071
|
});
|
|
174560
175072
|
try {
|
|
174561
|
-
const result = await
|
|
175073
|
+
const result = await executeContextRecompWithResult({
|
|
174562
175074
|
client: createPiRecompClient({
|
|
174563
175075
|
runner: deps.runner,
|
|
174564
175076
|
model: deps.historianModel,
|
|
@@ -174584,9 +175096,12 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
174584
175096
|
}, parsed.kind === "partial" ? { range: parsed.range } : {});
|
|
174585
175097
|
sendCtxStatusMessage(pi, {
|
|
174586
175098
|
title: "/ctx-recomp",
|
|
174587
|
-
text: result,
|
|
174588
|
-
level: inferLevel(result)
|
|
175099
|
+
text: result.message,
|
|
175100
|
+
level: inferLevel(result.message)
|
|
174589
175101
|
});
|
|
175102
|
+
if (!result.published) {
|
|
175103
|
+
return;
|
|
175104
|
+
}
|
|
174590
175105
|
queueAndApplyPiRecompMarker({ db: deps.db, sessionId, ctx });
|
|
174591
175106
|
signalPiHistoryRefresh(sessionId);
|
|
174592
175107
|
signalPiPendingMaterialization(sessionId);
|
|
@@ -174780,8 +175295,8 @@ function createPiRecompClient(args) {
|
|
|
174780
175295
|
function readPathId(input) {
|
|
174781
175296
|
if (typeof input !== "object" || input === null)
|
|
174782
175297
|
return "";
|
|
174783
|
-
const
|
|
174784
|
-
return typeof
|
|
175298
|
+
const path6 = input.path;
|
|
175299
|
+
return typeof path6?.id === "string" ? path6.id : "";
|
|
174785
175300
|
}
|
|
174786
175301
|
function readBody(input) {
|
|
174787
175302
|
if (typeof input !== "object" || input === null)
|
|
@@ -174932,10 +175447,20 @@ import {
|
|
|
174932
175447
|
truncateToWidth,
|
|
174933
175448
|
visibleWidth
|
|
174934
175449
|
} from "@earendil-works/pi-tui";
|
|
175450
|
+
|
|
175451
|
+
// ../plugin/src/shared/format-threshold.ts
|
|
175452
|
+
function formatThresholdPercent(value) {
|
|
175453
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
175454
|
+
return "—";
|
|
175455
|
+
const rounded = Math.round(value);
|
|
175456
|
+
if (Math.abs(value - rounded) < 0.05)
|
|
175457
|
+
return String(rounded);
|
|
175458
|
+
return value.toFixed(1);
|
|
175459
|
+
}
|
|
174935
175460
|
// package.json
|
|
174936
175461
|
var package_default = {
|
|
174937
175462
|
name: "@cortexkit/pi-magic-context",
|
|
174938
|
-
version: "0.21.
|
|
175463
|
+
version: "0.21.7",
|
|
174939
175464
|
type: "module",
|
|
174940
175465
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
174941
175466
|
main: "dist/index.js",
|
|
@@ -175099,7 +175624,7 @@ function renderInner(s, theme, innerWidth) {
|
|
|
175099
175624
|
lines.push(theme.fg("muted", "Tags"));
|
|
175100
175625
|
lines.push(`Active ${s.activeTags} (~${formatBytes(s.activeBytes)}) · Dropped ${s.droppedTags} · Total ${s.totalTags}`);
|
|
175101
175626
|
lines.push(theme.fg("muted", "Rolling Nudges / Context"));
|
|
175102
|
-
lines.push(`Execute threshold ${s.executeThreshold}% · Anchor ${fmt2(s.lastNudgeTokens)} tok · Interval ${fmt2(s.nudgeInterval)} tok · Next ${fmt2(s.nextNudgeAfter)} tok`);
|
|
175627
|
+
lines.push(`Execute threshold ${formatThresholdPercent(s.executeThreshold)}% · Anchor ${fmt2(s.lastNudgeTokens)} tok · Interval ${fmt2(s.nudgeInterval)} tok · Next ${fmt2(s.nextNudgeAfter)} tok`);
|
|
175103
175628
|
lines.push(`Protected tags ${s.protectedTagCount} · Subagent ${s.isSubagent ? "yes" : "no"} · History block ~${fmt2(s.historyBlockTokens)} tok${s.compressionBudget ? ` · Budget ~${fmt2(s.compressionBudget)} tok (${s.compressionUsage} used)` : ""}`);
|
|
175104
175629
|
if (s.lastTransformError)
|
|
175105
175630
|
lines.push(theme.fg("error", `⚠ ${s.lastTransformError}`));
|
|
@@ -175447,7 +175972,7 @@ function buildStatusDetails(deps, sessionId) {
|
|
|
175447
175972
|
status: ["pending", "ready"]
|
|
175448
175973
|
}).length,
|
|
175449
175974
|
dreamer: {
|
|
175450
|
-
enabled: deps.dreamer?.
|
|
175975
|
+
enabled: deps.dreamer?.runnable === true,
|
|
175451
175976
|
schedule: deps.dreamer?.schedule ?? null,
|
|
175452
175977
|
lastRunAt: readNumberState(deps.db, `last_dream_at:${deps.projectIdentity}`)
|
|
175453
175978
|
},
|
|
@@ -180661,7 +181186,7 @@ var PLUGIN_VERSION = (() => {
|
|
|
180661
181186
|
setHarness("pi");
|
|
180662
181187
|
function resolveSidekickFromConfig(config2) {
|
|
180663
181188
|
const sidekick = config2.sidekick;
|
|
180664
|
-
if (!sidekick
|
|
181189
|
+
if (!sidekick || sidekick.disable === true)
|
|
180665
181190
|
return;
|
|
180666
181191
|
const model = sidekick.model?.trim();
|
|
180667
181192
|
if (!model || model.length === 0)
|
|
@@ -180670,18 +181195,20 @@ function resolveSidekickFromConfig(config2) {
|
|
|
180670
181195
|
model,
|
|
180671
181196
|
systemPrompt: sidekick.system_prompt,
|
|
180672
181197
|
timeoutMs: sidekick.timeout_ms,
|
|
180673
|
-
thinking_level: sidekick.thinking_level
|
|
181198
|
+
thinking_level: sidekick.thinking_level,
|
|
181199
|
+
fallbackModels: resolveFallbackChain("sidekick", sidekick.fallback_models)
|
|
180674
181200
|
};
|
|
180675
181201
|
}
|
|
180676
181202
|
function resolveHistorianFromConfig(config2) {
|
|
180677
181203
|
const historian = config2.historian;
|
|
181204
|
+
if (historian?.disable === true)
|
|
181205
|
+
return;
|
|
180678
181206
|
const model = historian?.model?.trim();
|
|
180679
181207
|
if (!model || model.length === 0)
|
|
180680
181208
|
return;
|
|
180681
181209
|
const historianContextLimit = resolveHistorianContextLimit(model);
|
|
180682
181210
|
const historianChunkTokens = deriveHistorianChunkTokens(historianContextLimit);
|
|
180683
|
-
const
|
|
180684
|
-
const fallbackModels = typeof fbRaw === "string" ? [fbRaw] : fbRaw;
|
|
181211
|
+
const fallbackModels = resolveFallbackChain("historian", historian?.fallback_models);
|
|
180685
181212
|
return {
|
|
180686
181213
|
runner: new PiSubagentRunner,
|
|
180687
181214
|
model,
|
|
@@ -180730,11 +181257,11 @@ function resolveAutoSearchFromConfig(config2) {
|
|
|
180730
181257
|
};
|
|
180731
181258
|
}
|
|
180732
181259
|
function resolveDreamerFromConfig(config2) {
|
|
180733
|
-
return config2.dreamer;
|
|
181260
|
+
return config2.dreamer?.disable === true ? undefined : config2.dreamer;
|
|
180734
181261
|
}
|
|
180735
181262
|
async function src_default2(pi) {
|
|
180736
181263
|
const storageDir = getMagicContextStorageDir();
|
|
180737
|
-
const dbPath =
|
|
181264
|
+
const dbPath = join20(storageDir, "context.db");
|
|
180738
181265
|
let db;
|
|
180739
181266
|
try {
|
|
180740
181267
|
db = openDatabase();
|
|
@@ -180750,6 +181277,7 @@ async function src_default2(pi) {
|
|
|
180750
181277
|
const pendingPiMarkerSessions = getSessionsWithPendingPiMarker(db);
|
|
180751
181278
|
for (const sid of pendingPiMarkerSessions) {
|
|
180752
181279
|
signalPiDeferredHistoryRefresh(sid);
|
|
181280
|
+
signalPiPendingMaterialization(sid);
|
|
180753
181281
|
}
|
|
180754
181282
|
if (pendingPiMarkerSessions.length > 0) {
|
|
180755
181283
|
log(`${PREFIX2} rehydrated ${pendingPiMarkerSessions.length} Pi deferred compaction marker session(s)`);
|
|
@@ -180781,7 +181309,7 @@ async function src_default2(pi) {
|
|
|
180781
181309
|
allowDreamerActions: false,
|
|
180782
181310
|
ctxReduceEnabled: config2.ctx_reduce_enabled === true,
|
|
180783
181311
|
protectedTags: config2.protected_tags ?? 20,
|
|
180784
|
-
dreamerEnabled: config2
|
|
181312
|
+
dreamerEnabled: isDreamerRunnable(config2)
|
|
180785
181313
|
});
|
|
180786
181314
|
info(`registered tools: ctx_search, ctx_memory, ctx_note, ctx_expand${config2.ctx_reduce_enabled === true ? ", ctx_reduce" : ""}`);
|
|
180787
181315
|
const historianConfig = resolveHistorianFromConfig(config2);
|
|
@@ -180825,7 +181353,7 @@ async function src_default2(pi) {
|
|
|
180825
181353
|
info(autoSearchConfig.enabled ? `registered auto-search hint (threshold=${autoSearchConfig.scoreThreshold}, minChars=${autoSearchConfig.minPromptChars})` : "registered auto-search hint: DISABLED (experimental.auto_search.enabled=false)");
|
|
180826
181354
|
const sidekickConfig = resolveSidekickFromConfig(config2);
|
|
180827
181355
|
registerCtxAugCommand(pi, sidekickConfig);
|
|
180828
|
-
info(sidekickConfig ? `registered /ctx-aug (sidekick model=${sidekickConfig.model})` : "registered /ctx-aug (sidekick disabled — set sidekick.
|
|
181356
|
+
info(sidekickConfig ? `registered /ctx-aug (sidekick model=${sidekickConfig.model})` : "registered /ctx-aug (sidekick disabled — set sidekick.disable=false and sidekick.model in config)");
|
|
180829
181357
|
registerCtxStatusCommand(pi, {
|
|
180830
181358
|
db,
|
|
180831
181359
|
projectIdentity,
|
|
@@ -180837,7 +181365,7 @@ async function src_default2(pi) {
|
|
|
180837
181365
|
commitClusterTrigger: config2.commit_cluster_trigger,
|
|
180838
181366
|
executeThresholdTokens: config2.execute_threshold_tokens,
|
|
180839
181367
|
dreamer: {
|
|
180840
|
-
|
|
181368
|
+
runnable: isDreamerRunnable(config2),
|
|
180841
181369
|
schedule: config2.dreamer?.schedule
|
|
180842
181370
|
}
|
|
180843
181371
|
});
|
|
@@ -180863,7 +181391,7 @@ async function src_default2(pi) {
|
|
|
180863
181391
|
projectDir,
|
|
180864
181392
|
projectIdentity,
|
|
180865
181393
|
resolveProject: resolveCurrentProject,
|
|
180866
|
-
dreamerEnabled: config2
|
|
181394
|
+
dreamerEnabled: isDreamerRunnable(config2),
|
|
180867
181395
|
onProjectSeen: (identity) => seenDreamerProjectIdentities.add(identity)
|
|
180868
181396
|
});
|
|
180869
181397
|
info("registered /ctx-dream");
|
|
@@ -180879,11 +181407,28 @@ async function src_default2(pi) {
|
|
|
180879
181407
|
gitCommitIndexing: config2.experimental.git_commit_indexing,
|
|
180880
181408
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|
|
180881
181409
|
});
|
|
180882
|
-
info(
|
|
181410
|
+
info(`registered dreamer (schedule=${dreamerConfig.schedule || "manual-only"}, tasks=[${dreamerConfig.tasks.join(",")}])`);
|
|
180883
181411
|
} else {
|
|
180884
|
-
info("registered dreamer: DISABLED (no dreamer config)");
|
|
181412
|
+
info(isDreamerRunnable(config2) ? "registered dreamer: DISABLED (no dreamer config)" : "registered dreamer: DISABLED (dreamer.disable=true or no dreamer config)");
|
|
180885
181413
|
}
|
|
180886
181414
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
181415
|
+
try {
|
|
181416
|
+
if (ctx.hasUI && shouldShowAnnouncement()) {
|
|
181417
|
+
const featureText = ANNOUNCEMENT_FEATURES.map((line) => ` • ${line}`).join(`
|
|
181418
|
+
`);
|
|
181419
|
+
const sections = [
|
|
181420
|
+
`✨ Magic Context v${ANNOUNCEMENT_VERSION} — what's new:`,
|
|
181421
|
+
"",
|
|
181422
|
+
featureText
|
|
181423
|
+
];
|
|
181424
|
+
if (ANNOUNCEMENT_FOOTER && ANNOUNCEMENT_FOOTER.trim().length > 0) {
|
|
181425
|
+
sections.push("", ANNOUNCEMENT_FOOTER);
|
|
181426
|
+
}
|
|
181427
|
+
ctx.ui.notify(sections.join(`
|
|
181428
|
+
`), "info");
|
|
181429
|
+
markAnnouncementSeen(ANNOUNCEMENT_VERSION);
|
|
181430
|
+
}
|
|
181431
|
+
} catch {}
|
|
180887
181432
|
try {
|
|
180888
181433
|
const currentProject = resolveCurrentProject(ctx);
|
|
180889
181434
|
seenDreamerProjectIdentities.add(currentProject.projectIdentity);
|
|
@@ -180915,16 +181460,16 @@ async function src_default2(pi) {
|
|
|
180915
181460
|
cwd: currentProject.projectDir,
|
|
180916
181461
|
sessionId,
|
|
180917
181462
|
memoryEnabled: config2.memory.enabled,
|
|
180918
|
-
injectDocs: config2.dreamer?.inject_docs ?? true,
|
|
181463
|
+
injectDocs: isDreamerRunnable(config2) && (config2.dreamer?.inject_docs ?? true),
|
|
180919
181464
|
includeGuidance: true,
|
|
180920
181465
|
protectedTags: config2.protected_tags,
|
|
180921
181466
|
ctxReduceEnabled: config2.ctx_reduce_enabled,
|
|
180922
|
-
dreamerEnabled: config2
|
|
181467
|
+
dreamerEnabled: isDreamerRunnable(config2),
|
|
180923
181468
|
dropToolStructure: config2.drop_tool_structure,
|
|
180924
181469
|
temporalAwarenessEnabled: config2.experimental?.temporal_awareness ?? false,
|
|
180925
181470
|
cavemanTextCompressionEnabled: config2.ctx_reduce_enabled === false && config2.experimental?.caveman_text_compression?.enabled === true,
|
|
180926
|
-
userMemoriesEnabled:
|
|
180927
|
-
pinKeyFilesEnabled:
|
|
181471
|
+
userMemoriesEnabled: config2.dreamer?.user_memories?.enabled ?? false,
|
|
181472
|
+
pinKeyFilesEnabled: config2.dreamer?.pin_key_files?.enabled ?? false,
|
|
180928
181473
|
pinKeyFilesTokenBudget: config2.dreamer?.pin_key_files?.token_budget ?? 1e4,
|
|
180929
181474
|
isCacheBusting,
|
|
180930
181475
|
existingSystemPrompt: event.systemPrompt
|
|
@@ -181063,7 +181608,7 @@ ${block}` : event.systemPrompt;
|
|
|
181063
181608
|
continue;
|
|
181064
181609
|
if (typeof b.name !== "string")
|
|
181065
181610
|
continue;
|
|
181066
|
-
if (
|
|
181611
|
+
if (b.name !== "todowrite") {
|
|
181067
181612
|
continue;
|
|
181068
181613
|
}
|
|
181069
181614
|
const args = b.arguments;
|
|
@@ -181149,6 +181694,9 @@ ${block}` : event.systemPrompt;
|
|
|
181149
181694
|
});
|
|
181150
181695
|
}
|
|
181151
181696
|
export {
|
|
181697
|
+
resolveSidekickFromConfig,
|
|
181698
|
+
resolveHistorianFromConfig,
|
|
181699
|
+
resolveDreamerFromConfig,
|
|
181152
181700
|
persistPiPressureFromMessageEnd,
|
|
181153
181701
|
persistPiMessageEndModelMeta,
|
|
181154
181702
|
src_default2 as default
|