@cortexkit/pi-magic-context 0.22.1 → 0.22.2
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 +491 -370
- package/dist/subagent-entry.js +331 -91
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -86,9 +86,6 @@ function getMagicContextStorageDir() {
|
|
|
86
86
|
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
87
87
|
return path2.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
88
88
|
}
|
|
89
|
-
function getCacheDir() {
|
|
90
|
-
return process.env.XDG_CACHE_HOME ?? path2.join(os.homedir(), ".cache");
|
|
91
|
-
}
|
|
92
89
|
var init_data_path = () => {};
|
|
93
90
|
|
|
94
91
|
// ../plugin/src/shared/logger.ts
|
|
@@ -142698,7 +142695,7 @@ var databases = new Map;
|
|
|
142698
142695
|
var persistenceByDatabase = new WeakMap;
|
|
142699
142696
|
var persistenceErrorByDatabase = new WeakMap;
|
|
142700
142697
|
var lastSchemaFenceRejection = null;
|
|
142701
|
-
var LATEST_SUPPORTED_VERSION =
|
|
142698
|
+
var LATEST_SUPPORTED_VERSION = 29;
|
|
142702
142699
|
function resolveDatabasePath(dbPathOverride) {
|
|
142703
142700
|
if (dbPathOverride) {
|
|
142704
142701
|
return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
|
|
@@ -143018,6 +143015,17 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143018
143015
|
updated_at INTEGER NOT NULL DEFAULT 0
|
|
143019
143016
|
);
|
|
143020
143017
|
|
|
143018
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
143019
|
+
project_path TEXT PRIMARY KEY,
|
|
143020
|
+
lease_holder TEXT,
|
|
143021
|
+
lease_expires_at INTEGER,
|
|
143022
|
+
last_swept_at INTEGER
|
|
143023
|
+
);
|
|
143024
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
143025
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
143026
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
143027
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
143028
|
+
|
|
143021
143029
|
CREATE TABLE IF NOT EXISTS m0_mutation_log (
|
|
143022
143030
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
143023
143031
|
session_id TEXT NOT NULL,
|
|
@@ -144240,6 +144248,38 @@ var MIGRATIONS = [
|
|
|
144240
144248
|
ON tags(session_id, entry_fingerprint)
|
|
144241
144249
|
WHERE type='message' AND entry_fingerprint IS NOT NULL`);
|
|
144242
144250
|
}
|
|
144251
|
+
},
|
|
144252
|
+
{
|
|
144253
|
+
version: 28,
|
|
144254
|
+
description: "Add git commit sweep coordinator lease/cooldown table",
|
|
144255
|
+
up: (db) => {
|
|
144256
|
+
db.exec(`
|
|
144257
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
144258
|
+
project_path TEXT PRIMARY KEY,
|
|
144259
|
+
lease_holder TEXT,
|
|
144260
|
+
lease_expires_at INTEGER,
|
|
144261
|
+
last_swept_at INTEGER
|
|
144262
|
+
);
|
|
144263
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
144264
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
144265
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
144266
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
144267
|
+
`);
|
|
144268
|
+
}
|
|
144269
|
+
},
|
|
144270
|
+
{
|
|
144271
|
+
version: 29,
|
|
144272
|
+
description: "Add anchor_ordinal to notes (traceback to the conversation tail)",
|
|
144273
|
+
up: (db) => {
|
|
144274
|
+
const notesExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'").get();
|
|
144275
|
+
if (!notesExists) {
|
|
144276
|
+
return;
|
|
144277
|
+
}
|
|
144278
|
+
const columns = db.prepare("PRAGMA table_info(notes)").all();
|
|
144279
|
+
if (!columns.some((column) => column.name === "anchor_ordinal")) {
|
|
144280
|
+
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
144281
|
+
}
|
|
144282
|
+
}
|
|
144243
144283
|
}
|
|
144244
144284
|
];
|
|
144245
144285
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -145127,7 +145167,8 @@ function toNote(row) {
|
|
|
145127
145167
|
updatedAt: row.updated_at,
|
|
145128
145168
|
lastCheckedAt: toNullableNumber(row.last_checked_at),
|
|
145129
145169
|
readyAt: toNullableNumber(row.ready_at),
|
|
145130
|
-
readyReason: toNullableString(row.ready_reason)
|
|
145170
|
+
readyReason: toNullableString(row.ready_reason),
|
|
145171
|
+
anchorOrdinal: toNullableNumber(row.anchor_ordinal)
|
|
145131
145172
|
};
|
|
145132
145173
|
}
|
|
145133
145174
|
function getNoteById(db, noteId) {
|
|
@@ -145179,7 +145220,7 @@ function getNotes(db, options = {}) {
|
|
|
145179
145220
|
}
|
|
145180
145221
|
function addNote(db, type, options) {
|
|
145181
145222
|
const now = Date.now();
|
|
145182
|
-
const result = type === "session" ? db.prepare("INSERT INTO notes (type, status, content, session_id, created_at, updated_at, harness) VALUES ('session', 'active', ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId, now, now, getHarness()) : db.prepare("INSERT INTO notes (type, status, content, session_id, project_path, surface_condition, created_at, updated_at, harness) VALUES ('smart', 'pending', ?, ?, ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId ?? null, options.projectPath, options.surfaceCondition, now, now, getHarness());
|
|
145223
|
+
const result = type === "session" ? db.prepare("INSERT INTO notes (type, status, content, session_id, created_at, updated_at, harness, anchor_ordinal) VALUES ('session', 'active', ?, ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId, now, now, getHarness(), options.anchorOrdinal ?? null) : db.prepare("INSERT INTO notes (type, status, content, session_id, project_path, surface_condition, created_at, updated_at, harness, anchor_ordinal) VALUES ('smart', 'pending', ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId ?? null, options.projectPath, options.surfaceCondition, now, now, getHarness(), options.anchorOrdinal ?? null);
|
|
145183
145224
|
if (!isNoteRow(result)) {
|
|
145184
145225
|
throw new Error("[notes] failed to insert note");
|
|
145185
145226
|
}
|
|
@@ -145949,212 +145990,41 @@ function getAgentFallbackModels(agent) {
|
|
|
145949
145990
|
|
|
145950
145991
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
145951
145992
|
init_data_path();
|
|
145952
|
-
|
|
145953
|
-
import {
|
|
145954
|
-
import { homedir as homedir2, platform } from "node:os";
|
|
145993
|
+
init_logger();
|
|
145994
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync, writeFileSync } from "node:fs";
|
|
145955
145995
|
import { join as join6 } from "node:path";
|
|
145956
|
-
|
|
145957
|
-
|
|
145958
|
-
function
|
|
145959
|
-
|
|
145960
|
-
let inString = false;
|
|
145961
|
-
let escaped = false;
|
|
145962
|
-
let inLineComment = false;
|
|
145963
|
-
let inBlockComment = false;
|
|
145964
|
-
for (let index = 0;index < content.length; index += 1) {
|
|
145965
|
-
const char = content[index];
|
|
145966
|
-
const next = content[index + 1];
|
|
145967
|
-
if (inLineComment) {
|
|
145968
|
-
if (char === `
|
|
145969
|
-
`) {
|
|
145970
|
-
inLineComment = false;
|
|
145971
|
-
result += char;
|
|
145972
|
-
}
|
|
145973
|
-
continue;
|
|
145974
|
-
}
|
|
145975
|
-
if (inBlockComment) {
|
|
145976
|
-
if (char === "*" && next === "/") {
|
|
145977
|
-
inBlockComment = false;
|
|
145978
|
-
index += 1;
|
|
145979
|
-
}
|
|
145980
|
-
continue;
|
|
145981
|
-
}
|
|
145982
|
-
if (inString) {
|
|
145983
|
-
result += char;
|
|
145984
|
-
if (escaped) {
|
|
145985
|
-
escaped = false;
|
|
145986
|
-
} else if (char === "\\") {
|
|
145987
|
-
escaped = true;
|
|
145988
|
-
} else if (char === '"') {
|
|
145989
|
-
inString = false;
|
|
145990
|
-
}
|
|
145991
|
-
continue;
|
|
145992
|
-
}
|
|
145993
|
-
if (char === '"') {
|
|
145994
|
-
inString = true;
|
|
145995
|
-
result += char;
|
|
145996
|
-
continue;
|
|
145997
|
-
}
|
|
145998
|
-
if (char === "/" && next === "/") {
|
|
145999
|
-
inLineComment = true;
|
|
146000
|
-
index += 1;
|
|
146001
|
-
continue;
|
|
146002
|
-
}
|
|
146003
|
-
if (char === "/" && next === "*") {
|
|
146004
|
-
inBlockComment = true;
|
|
146005
|
-
index += 1;
|
|
146006
|
-
continue;
|
|
146007
|
-
}
|
|
146008
|
-
result += char;
|
|
146009
|
-
}
|
|
146010
|
-
return result;
|
|
146011
|
-
}
|
|
146012
|
-
function stripTrailingCommas(content) {
|
|
146013
|
-
let result = "";
|
|
146014
|
-
let inString = false;
|
|
146015
|
-
let escaped = false;
|
|
146016
|
-
for (let index = 0;index < content.length; index += 1) {
|
|
146017
|
-
const char = content[index];
|
|
146018
|
-
if (inString) {
|
|
146019
|
-
result += char;
|
|
146020
|
-
if (escaped) {
|
|
146021
|
-
escaped = false;
|
|
146022
|
-
} else if (char === "\\") {
|
|
146023
|
-
escaped = true;
|
|
146024
|
-
} else if (char === '"') {
|
|
146025
|
-
inString = false;
|
|
146026
|
-
}
|
|
146027
|
-
continue;
|
|
146028
|
-
}
|
|
146029
|
-
if (char === '"') {
|
|
146030
|
-
inString = true;
|
|
146031
|
-
result += char;
|
|
146032
|
-
continue;
|
|
146033
|
-
}
|
|
146034
|
-
if (char === ",") {
|
|
146035
|
-
let lookahead = index + 1;
|
|
146036
|
-
while (lookahead < content.length && /\s/.test(content[lookahead] ?? "")) {
|
|
146037
|
-
lookahead += 1;
|
|
146038
|
-
}
|
|
146039
|
-
const next = content[lookahead];
|
|
146040
|
-
if (next === "}" || next === "]") {
|
|
146041
|
-
continue;
|
|
146042
|
-
}
|
|
146043
|
-
}
|
|
146044
|
-
result += char;
|
|
146045
|
-
}
|
|
146046
|
-
return result;
|
|
145996
|
+
var MIN_SANE_LIMIT = 20000;
|
|
145997
|
+
var MAX_SANE_LIMIT = 3000000;
|
|
145998
|
+
function isSaneLimit(limit) {
|
|
145999
|
+
return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
|
|
146047
146000
|
}
|
|
146048
|
-
function parseJsonc(content) {
|
|
146049
|
-
const normalized = stripTrailingCommas(stripJsonComments(content));
|
|
146050
|
-
return JSON.parse(normalized);
|
|
146051
|
-
}
|
|
146052
|
-
|
|
146053
|
-
// ../plugin/src/shared/models-dev-cache.ts
|
|
146054
|
-
init_logger();
|
|
146055
|
-
var RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
146056
146001
|
var apiCache = null;
|
|
146057
|
-
var
|
|
146058
|
-
|
|
146059
|
-
|
|
146060
|
-
function hashFast(input) {
|
|
146061
|
-
return createHash5("sha1").update(input).digest("hex");
|
|
146062
|
-
}
|
|
146063
|
-
function getModelsJsonPath() {
|
|
146064
|
-
const explicit = process.env.OPENCODE_MODELS_PATH?.trim();
|
|
146065
|
-
if (explicit)
|
|
146066
|
-
return explicit;
|
|
146067
|
-
const cacheBase = getCacheDir();
|
|
146068
|
-
const source = process.env.OPENCODE_MODELS_URL?.trim();
|
|
146069
|
-
const filename = source && source !== "https://models.dev" ? `models-${hashFast(source)}.json` : "models.json";
|
|
146070
|
-
return join6(cacheBase, "opencode", filename);
|
|
146071
|
-
}
|
|
146072
|
-
function getOpencodeConfigPath() {
|
|
146073
|
-
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
146074
|
-
const configDir = envDir ? envDir : platform() === "win32" ? join6(homedir2(), ".config", "opencode") : join6(process.env.XDG_CONFIG_HOME || join6(homedir2(), ".config"), "opencode");
|
|
146075
|
-
const jsonc = join6(configDir, "opencode.jsonc");
|
|
146076
|
-
if (existsSync5(jsonc))
|
|
146077
|
-
return jsonc;
|
|
146078
|
-
const json = join6(configDir, "opencode.json");
|
|
146079
|
-
if (existsSync5(json))
|
|
146080
|
-
return json;
|
|
146081
|
-
return null;
|
|
146002
|
+
var persistSeedLoaded = false;
|
|
146003
|
+
function persistFilePath() {
|
|
146004
|
+
return join6(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
|
|
146082
146005
|
}
|
|
146083
|
-
function
|
|
146084
|
-
if (
|
|
146006
|
+
function loadPersistedApiCacheOnce() {
|
|
146007
|
+
if (persistSeedLoaded || apiCache !== null)
|
|
146085
146008
|
return;
|
|
146086
|
-
|
|
146087
|
-
return limit.input;
|
|
146088
|
-
if (typeof limit.context === "number" && limit.context > 0)
|
|
146089
|
-
return limit.context;
|
|
146090
|
-
return;
|
|
146091
|
-
}
|
|
146092
|
-
function setCachedModelMetadata(cache, key, model) {
|
|
146093
|
-
const limit = resolveLimit(model?.limit);
|
|
146094
|
-
if (limit === undefined) {
|
|
146095
|
-
return;
|
|
146096
|
-
}
|
|
146097
|
-
const value = { limit };
|
|
146098
|
-
cache.set(key, value);
|
|
146099
|
-
const modes = model?.experimental?.modes;
|
|
146100
|
-
if (modes && typeof modes === "object") {
|
|
146101
|
-
for (const mode of Object.keys(modes)) {
|
|
146102
|
-
cache.set(`${key}-${mode}`, value);
|
|
146103
|
-
}
|
|
146104
|
-
}
|
|
146105
|
-
}
|
|
146106
|
-
function loadModelsDevMetadataFromFile() {
|
|
146107
|
-
const metadata = new Map;
|
|
146108
|
-
const modelsJsonPath = getModelsJsonPath();
|
|
146109
|
-
let fileFound = false;
|
|
146009
|
+
persistSeedLoaded = true;
|
|
146110
146010
|
try {
|
|
146111
|
-
|
|
146112
|
-
|
|
146113
|
-
|
|
146114
|
-
|
|
146115
|
-
|
|
146116
|
-
|
|
146117
|
-
continue;
|
|
146118
|
-
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
146119
|
-
setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
|
|
146120
|
-
}
|
|
146121
|
-
}
|
|
146011
|
+
const raw = readFileSync3(persistFilePath(), "utf-8");
|
|
146012
|
+
const obj = JSON.parse(raw);
|
|
146013
|
+
const map = new Map;
|
|
146014
|
+
for (const [key, limit] of Object.entries(obj)) {
|
|
146015
|
+
if (isSaneLimit(limit))
|
|
146016
|
+
map.set(key, { limit });
|
|
146122
146017
|
}
|
|
146123
|
-
|
|
146124
|
-
|
|
146125
|
-
|
|
146126
|
-
try {
|
|
146127
|
-
const configPath = getOpencodeConfigPath();
|
|
146128
|
-
if (configPath && existsSync5(configPath)) {
|
|
146129
|
-
const config = parseJsonc(readFileSync3(configPath, "utf-8"));
|
|
146130
|
-
if (config.provider && typeof config.provider === "object") {
|
|
146131
|
-
for (const [providerId, provider] of Object.entries(config.provider)) {
|
|
146132
|
-
if (!provider?.models || typeof provider.models !== "object")
|
|
146133
|
-
continue;
|
|
146134
|
-
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
146135
|
-
setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
|
|
146136
|
-
}
|
|
146137
|
-
}
|
|
146138
|
-
}
|
|
146018
|
+
if (map.size > 0) {
|
|
146019
|
+
apiCache = map;
|
|
146020
|
+
sessionLog("global", `models-dev-cache: seeded ${map.size} entries from persisted cache (cold start)`);
|
|
146139
146021
|
}
|
|
146140
|
-
} catch
|
|
146141
|
-
sessionLog("global", "models-dev-cache: failed to read opencode config for custom models:", error instanceof Error ? error.message : String(error));
|
|
146142
|
-
}
|
|
146143
|
-
sessionLog("global", `models-dev-cache: file-layer loaded ${metadata.size} model metadata entries (modelsJsonPath=${modelsJsonPath}, found=${fileFound})`);
|
|
146144
|
-
return metadata;
|
|
146022
|
+
} catch {}
|
|
146145
146023
|
}
|
|
146146
|
-
function
|
|
146147
|
-
|
|
146148
|
-
if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
|
|
146149
|
-
fileLastAttempt = now;
|
|
146150
|
-
fileCache = loadModelsDevMetadataFromFile();
|
|
146151
|
-
}
|
|
146024
|
+
function getSdkContextLimit(providerID, modelID) {
|
|
146025
|
+
loadPersistedApiCacheOnce();
|
|
146152
146026
|
const fromApi = lookupLimitWithTagFallback(apiCache, providerID, modelID);
|
|
146153
|
-
|
|
146154
|
-
if (typeof fromApi === "number" && typeof fromFile === "number") {
|
|
146155
|
-
return Math.max(fromApi, fromFile);
|
|
146156
|
-
}
|
|
146157
|
-
return fromApi ?? fromFile;
|
|
146027
|
+
return isSaneLimit(fromApi) ? fromApi : undefined;
|
|
146158
146028
|
}
|
|
146159
146029
|
function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
146160
146030
|
if (!cache)
|
|
@@ -146171,12 +146041,6 @@ function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
|
146171
146041
|
}
|
|
146172
146042
|
return;
|
|
146173
146043
|
}
|
|
146174
|
-
function clearModelsDevCache() {
|
|
146175
|
-
apiCache = null;
|
|
146176
|
-
apiLoadedAt = 0;
|
|
146177
|
-
fileCache = null;
|
|
146178
|
-
fileLastAttempt = 0;
|
|
146179
|
-
}
|
|
146180
146044
|
|
|
146181
146045
|
// ../plugin/src/hooks/magic-context/derive-budgets.ts
|
|
146182
146046
|
var TRIGGER_BUDGET_PERCENTAGE = 0.05;
|
|
@@ -146207,7 +146071,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
146207
146071
|
const [providerID, ...rest] = historianModelOverride.split("/");
|
|
146208
146072
|
const modelID = rest.join("/");
|
|
146209
146073
|
if (providerID && modelID) {
|
|
146210
|
-
const limit =
|
|
146074
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
146211
146075
|
if (typeof limit === "number" && limit > 0)
|
|
146212
146076
|
return limit;
|
|
146213
146077
|
}
|
|
@@ -146226,7 +146090,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
146226
146090
|
const modelID = rest.join("/");
|
|
146227
146091
|
if (!providerID || !modelID)
|
|
146228
146092
|
continue;
|
|
146229
|
-
const limit =
|
|
146093
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
146230
146094
|
if (typeof limit !== "number" || limit <= 0)
|
|
146231
146095
|
continue;
|
|
146232
146096
|
if (minLimit === undefined || limit < minLimit)
|
|
@@ -146239,37 +146103,6 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
146239
146103
|
init_logger();
|
|
146240
146104
|
var DEFAULT_CONTEXT_LIMIT = 128000;
|
|
146241
146105
|
var MAX_EXECUTE_THRESHOLD = 80;
|
|
146242
|
-
function resolveContextLimit(providerID, modelID, ctx) {
|
|
146243
|
-
const fromModelsDev = providerID && modelID ? getModelsDevContextLimit(providerID, modelID) : undefined;
|
|
146244
|
-
const baseline = fromModelsDev ?? DEFAULT_CONTEXT_LIMIT;
|
|
146245
|
-
if (ctx?.db && ctx.sessionID) {
|
|
146246
|
-
try {
|
|
146247
|
-
const overflow = getOverflowState(ctx.db, ctx.sessionID);
|
|
146248
|
-
if (overflow.detectedContextLimit > 0 && overflow.detectedContextLimit < baseline) {
|
|
146249
|
-
return overflow.detectedContextLimit;
|
|
146250
|
-
}
|
|
146251
|
-
} catch {}
|
|
146252
|
-
}
|
|
146253
|
-
return baseline;
|
|
146254
|
-
}
|
|
146255
|
-
function resolveTrustedContextLimit(providerID, modelID, ctx) {
|
|
146256
|
-
const fromModelsDev = providerID && modelID ? getModelsDevContextLimit(providerID, modelID) : undefined;
|
|
146257
|
-
let detected;
|
|
146258
|
-
if (ctx?.db && ctx.sessionID) {
|
|
146259
|
-
try {
|
|
146260
|
-
const overflow = getOverflowState(ctx.db, ctx.sessionID);
|
|
146261
|
-
if (overflow.detectedContextLimit > 0) {
|
|
146262
|
-
detected = overflow.detectedContextLimit;
|
|
146263
|
-
}
|
|
146264
|
-
} catch {}
|
|
146265
|
-
}
|
|
146266
|
-
if (typeof fromModelsDev === "number" && fromModelsDev > 0) {
|
|
146267
|
-
if (detected !== undefined && detected < fromModelsDev)
|
|
146268
|
-
return detected;
|
|
146269
|
-
return fromModelsDev;
|
|
146270
|
-
}
|
|
146271
|
-
return detected;
|
|
146272
|
-
}
|
|
146273
146106
|
function resolveCacheTtl(cacheTtl, modelKey) {
|
|
146274
146107
|
if (typeof cacheTtl === "string") {
|
|
146275
146108
|
return cacheTtl;
|
|
@@ -146490,7 +146323,7 @@ function clearNoteNudgeTriggerOnly(db, sessionId) {
|
|
|
146490
146323
|
}
|
|
146491
146324
|
|
|
146492
146325
|
// ../plugin/src/hooks/magic-context/todo-view.ts
|
|
146493
|
-
import { createHash as
|
|
146326
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
146494
146327
|
var TERMINAL_STATUSES = new Set(["completed", "cancelled"]);
|
|
146495
146328
|
var TITLE_DONE_STATUSES = new Set(["completed"]);
|
|
146496
146329
|
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
@@ -146535,7 +146368,7 @@ function buildSyntheticTodoPart(stateJson) {
|
|
|
146535
146368
|
};
|
|
146536
146369
|
}
|
|
146537
146370
|
function computeSyntheticCallId(stateJson) {
|
|
146538
|
-
const hash =
|
|
146371
|
+
const hash = createHash5("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
146539
146372
|
return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
|
|
146540
146373
|
}
|
|
146541
146374
|
function parseTodoState(stateJson) {
|
|
@@ -146789,7 +146622,7 @@ init_logger();
|
|
|
146789
146622
|
|
|
146790
146623
|
// src/subagent-runner.ts
|
|
146791
146624
|
import * as childProcess from "node:child_process";
|
|
146792
|
-
import { existsSync as
|
|
146625
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
146793
146626
|
import { createRequire as createRequire2 } from "node:module";
|
|
146794
146627
|
import { dirname as dirname3, join as join8, resolve as resolvePath } from "node:path";
|
|
146795
146628
|
import { createInterface } from "node:readline";
|
|
@@ -146893,7 +146726,7 @@ function resolveBundledPiCli() {
|
|
|
146893
146726
|
const require_ = createRequire2(import.meta.url);
|
|
146894
146727
|
const pkgJson = require_.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
146895
146728
|
const cliPath = join8(dirname3(pkgJson), "dist/cli.js");
|
|
146896
|
-
if (
|
|
146729
|
+
if (existsSync6(cliPath))
|
|
146897
146730
|
return cliPath;
|
|
146898
146731
|
return null;
|
|
146899
146732
|
} catch {
|
|
@@ -146904,7 +146737,7 @@ function resolveSubagentEntryPath() {
|
|
|
146904
146737
|
try {
|
|
146905
146738
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
146906
146739
|
const candidate = resolvePath(here, "subagent-entry.js");
|
|
146907
|
-
if (
|
|
146740
|
+
if (existsSync6(candidate))
|
|
146908
146741
|
return candidate;
|
|
146909
146742
|
return;
|
|
146910
146743
|
} catch {
|
|
@@ -147664,7 +147497,7 @@ function clearStaleEntries(db, maxAgeMs, projectIdentity) {
|
|
|
147664
147497
|
// src/commands/ctx-dream.ts
|
|
147665
147498
|
init_logger();
|
|
147666
147499
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
147667
|
-
import { existsSync as
|
|
147500
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
147668
147501
|
import { join as join11 } from "node:path";
|
|
147669
147502
|
|
|
147670
147503
|
// ../plugin/src/shared/index.ts
|
|
@@ -147918,12 +147751,12 @@ init_logger();
|
|
|
147918
147751
|
|
|
147919
147752
|
// ../plugin/src/features/magic-context/key-files/aft-availability.ts
|
|
147920
147753
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
147921
|
-
import { existsSync as
|
|
147922
|
-
import { homedir as
|
|
147754
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
147755
|
+
import { homedir as homedir2 } from "node:os";
|
|
147923
147756
|
import { join as join9 } from "node:path";
|
|
147924
147757
|
var overrideAvailability = null;
|
|
147925
147758
|
function parseConfig(path7) {
|
|
147926
|
-
if (!
|
|
147759
|
+
if (!existsSync7(path7))
|
|
147927
147760
|
return null;
|
|
147928
147761
|
return import_comment_json.parse(readFileSync5(path7, "utf-8"));
|
|
147929
147762
|
}
|
|
@@ -147945,7 +147778,7 @@ function hasAftAtKeys(value, keys) {
|
|
|
147945
147778
|
return false;
|
|
147946
147779
|
}
|
|
147947
147780
|
function getAftAvailability() {
|
|
147948
|
-
const home = process.env.HOME ||
|
|
147781
|
+
const home = process.env.HOME || homedir2();
|
|
147949
147782
|
const opencodePaths = [
|
|
147950
147783
|
join9(home, ".config", "opencode", "opencode.jsonc"),
|
|
147951
147784
|
join9(home, ".config", "opencode", "opencode.json")
|
|
@@ -148589,13 +148422,13 @@ function invalidateMemory(projectPath, memoryId) {
|
|
|
148589
148422
|
}
|
|
148590
148423
|
|
|
148591
148424
|
// ../plugin/src/features/magic-context/memory/normalize-hash.ts
|
|
148592
|
-
import { createHash as
|
|
148425
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
148593
148426
|
function normalizeMemoryContent(content) {
|
|
148594
148427
|
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
148595
148428
|
}
|
|
148596
148429
|
function computeNormalizedHash(content) {
|
|
148597
148430
|
const normalized = normalizeMemoryContent(content);
|
|
148598
|
-
return
|
|
148431
|
+
return createHash6("md5").update(normalized).digest("hex");
|
|
148599
148432
|
}
|
|
148600
148433
|
|
|
148601
148434
|
// ../plugin/src/features/magic-context/memory/storage-memory.ts
|
|
@@ -149746,7 +149579,7 @@ function getOpenCodeDbPath2() {
|
|
|
149746
149579
|
}
|
|
149747
149580
|
function openOpenCodeDb() {
|
|
149748
149581
|
const dbPath = getOpenCodeDbPath2();
|
|
149749
|
-
if (!
|
|
149582
|
+
if (!existsSync8(dbPath)) {
|
|
149750
149583
|
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
149751
149584
|
return null;
|
|
149752
149585
|
}
|
|
@@ -149896,8 +149729,8 @@ async function runDream(args) {
|
|
|
149896
149729
|
try {
|
|
149897
149730
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
149898
149731
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
149899
|
-
architecture:
|
|
149900
|
-
structure:
|
|
149732
|
+
architecture: existsSync8(join11(docsDir, "ARCHITECTURE.md")),
|
|
149733
|
+
structure: existsSync8(join11(docsDir, "STRUCTURE.md"))
|
|
149901
149734
|
} : undefined;
|
|
149902
149735
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
149903
149736
|
id: um.id,
|
|
@@ -165103,7 +164936,7 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
165103
164936
|
}
|
|
165104
164937
|
|
|
165105
164938
|
// ../plugin/src/features/magic-context/memory/embedding-local.ts
|
|
165106
|
-
import { mkdirSync as
|
|
164939
|
+
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
165107
164940
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
165108
164941
|
import { dirname as dirname4, join as join12 } from "node:path";
|
|
165109
164942
|
import { pathToFileURL } from "node:url";
|
|
@@ -165284,7 +165117,7 @@ class LocalEmbeddingProvider {
|
|
|
165284
165117
|
}
|
|
165285
165118
|
const modelCacheDir = join12(getMagicContextStorageDir(), "models");
|
|
165286
165119
|
try {
|
|
165287
|
-
|
|
165120
|
+
mkdirSync5(modelCacheDir, { recursive: true });
|
|
165288
165121
|
env.cacheDir = modelCacheDir;
|
|
165289
165122
|
} catch {
|
|
165290
165123
|
log("[magic-context] could not create model cache dir, using library default");
|
|
@@ -165659,7 +165492,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
165659
165492
|
}
|
|
165660
165493
|
|
|
165661
165494
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
165662
|
-
import { createHash as
|
|
165495
|
+
import { createHash as createHash7, randomUUID } from "node:crypto";
|
|
165663
165496
|
init_logger();
|
|
165664
165497
|
|
|
165665
165498
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
@@ -165763,6 +165596,125 @@ function getDistinctCommitEmbeddingModelIds(db, projectPath) {
|
|
|
165763
165596
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
165764
165597
|
}
|
|
165765
165598
|
|
|
165599
|
+
// ../plugin/src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
165600
|
+
var GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
165601
|
+
var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
165602
|
+
var GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
165603
|
+
function runImmediate2(db, body) {
|
|
165604
|
+
db.exec("BEGIN IMMEDIATE");
|
|
165605
|
+
let committed = false;
|
|
165606
|
+
try {
|
|
165607
|
+
const result = body();
|
|
165608
|
+
db.exec("COMMIT");
|
|
165609
|
+
committed = true;
|
|
165610
|
+
return result;
|
|
165611
|
+
} finally {
|
|
165612
|
+
if (!committed) {
|
|
165613
|
+
try {
|
|
165614
|
+
db.exec("ROLLBACK");
|
|
165615
|
+
} catch {}
|
|
165616
|
+
}
|
|
165617
|
+
}
|
|
165618
|
+
}
|
|
165619
|
+
function rowToState(row) {
|
|
165620
|
+
return {
|
|
165621
|
+
projectPath: row.project_path,
|
|
165622
|
+
leaseHolder: row.lease_holder,
|
|
165623
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
165624
|
+
lastSweptAt: row.last_swept_at
|
|
165625
|
+
};
|
|
165626
|
+
}
|
|
165627
|
+
function getGitSweepCoordinatorState(db, projectPath) {
|
|
165628
|
+
const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
|
|
165629
|
+
FROM git_sweep_coordinator
|
|
165630
|
+
WHERE project_path = ?`).get(projectPath);
|
|
165631
|
+
return row ? rowToState(row) : null;
|
|
165632
|
+
}
|
|
165633
|
+
function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
|
|
165634
|
+
const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
|
|
165635
|
+
const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
|
|
165636
|
+
return runImmediate2(db, () => {
|
|
165637
|
+
const now = Date.now();
|
|
165638
|
+
const row = getGitSweepCoordinatorState(db, projectPath);
|
|
165639
|
+
if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
|
|
165640
|
+
return {
|
|
165641
|
+
acquired: false,
|
|
165642
|
+
projectPath,
|
|
165643
|
+
reason: "lease_active",
|
|
165644
|
+
leaseHolder: row.leaseHolder,
|
|
165645
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
165646
|
+
lastSweptAt: row.lastSweptAt,
|
|
165647
|
+
nextAllowedAt: null
|
|
165648
|
+
};
|
|
165649
|
+
}
|
|
165650
|
+
if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
|
|
165651
|
+
const nextAllowedAt = row.lastSweptAt + cooldownMs;
|
|
165652
|
+
if (nextAllowedAt > now) {
|
|
165653
|
+
return {
|
|
165654
|
+
acquired: false,
|
|
165655
|
+
projectPath,
|
|
165656
|
+
reason: "cooldown_active",
|
|
165657
|
+
leaseHolder: row.leaseHolder,
|
|
165658
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
165659
|
+
lastSweptAt: row.lastSweptAt,
|
|
165660
|
+
nextAllowedAt
|
|
165661
|
+
};
|
|
165662
|
+
}
|
|
165663
|
+
}
|
|
165664
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
165665
|
+
db.prepare(`INSERT INTO git_sweep_coordinator (
|
|
165666
|
+
project_path,
|
|
165667
|
+
lease_holder,
|
|
165668
|
+
lease_expires_at,
|
|
165669
|
+
last_swept_at
|
|
165670
|
+
) VALUES (?, ?, ?, NULL)
|
|
165671
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
165672
|
+
lease_holder = excluded.lease_holder,
|
|
165673
|
+
lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
|
|
165674
|
+
return {
|
|
165675
|
+
acquired: true,
|
|
165676
|
+
projectPath,
|
|
165677
|
+
holderId,
|
|
165678
|
+
acquiredAt: now,
|
|
165679
|
+
leaseExpiresAt
|
|
165680
|
+
};
|
|
165681
|
+
});
|
|
165682
|
+
}
|
|
165683
|
+
function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
|
|
165684
|
+
return runImmediate2(db, () => {
|
|
165685
|
+
const now = Date.now();
|
|
165686
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
165687
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
165688
|
+
SET lease_expires_at = ?
|
|
165689
|
+
WHERE project_path = ?
|
|
165690
|
+
AND lease_holder = ?
|
|
165691
|
+
AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
|
|
165692
|
+
return result.changes === 1;
|
|
165693
|
+
});
|
|
165694
|
+
}
|
|
165695
|
+
function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
165696
|
+
return runImmediate2(db, () => {
|
|
165697
|
+
const now = Date.now();
|
|
165698
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
165699
|
+
SET lease_holder = NULL,
|
|
165700
|
+
lease_expires_at = NULL,
|
|
165701
|
+
last_swept_at = ?
|
|
165702
|
+
WHERE project_path = ?
|
|
165703
|
+
AND lease_holder = ?
|
|
165704
|
+
AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
|
|
165705
|
+
return result.changes === 1;
|
|
165706
|
+
});
|
|
165707
|
+
}
|
|
165708
|
+
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
165709
|
+
runImmediate2(db, () => {
|
|
165710
|
+
db.prepare(`UPDATE git_sweep_coordinator
|
|
165711
|
+
SET lease_holder = NULL,
|
|
165712
|
+
lease_expires_at = NULL
|
|
165713
|
+
WHERE project_path = ?
|
|
165714
|
+
AND lease_holder = ?`).run(projectPath, holderId);
|
|
165715
|
+
});
|
|
165716
|
+
}
|
|
165717
|
+
|
|
165766
165718
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
165767
165719
|
var OFF_PROVIDER_IDENTITY = "embedding-provider:off";
|
|
165768
165720
|
var SWEEP_MAX_WALL_CLOCK_MS = 10 * 60 * 1000;
|
|
@@ -165815,7 +165767,7 @@ function stableStringify2(value) {
|
|
|
165815
165767
|
return JSON.stringify(value);
|
|
165816
165768
|
}
|
|
165817
165769
|
function sha256Prefix(value, length = 16) {
|
|
165818
|
-
return
|
|
165770
|
+
return createHash7("sha256").update(value).digest("hex").slice(0, length);
|
|
165819
165771
|
}
|
|
165820
165772
|
function getRuntimeFingerprint(config2) {
|
|
165821
165773
|
if (config2.provider === "off") {
|
|
@@ -166080,6 +166032,7 @@ var insertStatements = new WeakMap;
|
|
|
166080
166032
|
var existingShasStatements = new WeakMap;
|
|
166081
166033
|
var projectCountStatements = new WeakMap;
|
|
166082
166034
|
var evictStatements = new WeakMap;
|
|
166035
|
+
var evictOverflowStatements = new WeakMap;
|
|
166083
166036
|
var latestCommitTimeStatements = new WeakMap;
|
|
166084
166037
|
function getInsertStatement(db) {
|
|
166085
166038
|
let stmt = insertStatements.get(db);
|
|
@@ -166122,17 +166075,17 @@ function getLatestCommitTimeStatement(db) {
|
|
|
166122
166075
|
}
|
|
166123
166076
|
return stmt;
|
|
166124
166077
|
}
|
|
166125
|
-
function
|
|
166126
|
-
let stmt =
|
|
166078
|
+
function getEvictOverflowStatement(db) {
|
|
166079
|
+
let stmt = evictOverflowStatements.get(db);
|
|
166127
166080
|
if (!stmt) {
|
|
166128
166081
|
stmt = db.prepare(`DELETE FROM git_commits
|
|
166129
|
-
WHERE
|
|
166130
|
-
SELECT
|
|
166082
|
+
WHERE rowid IN (
|
|
166083
|
+
SELECT rowid FROM git_commits
|
|
166131
166084
|
WHERE project_path = ?
|
|
166132
|
-
ORDER BY committed_at
|
|
166133
|
-
LIMIT ?
|
|
166085
|
+
ORDER BY committed_at DESC, sha DESC
|
|
166086
|
+
LIMIT -1 OFFSET ?
|
|
166134
166087
|
)`);
|
|
166135
|
-
|
|
166088
|
+
evictOverflowStatements.set(db, stmt);
|
|
166136
166089
|
}
|
|
166137
166090
|
return stmt;
|
|
166138
166091
|
}
|
|
@@ -166170,22 +166123,15 @@ function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
|
166170
166123
|
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
166171
166124
|
return row?.latest ?? null;
|
|
166172
166125
|
}
|
|
166173
|
-
function evictOldestCommits(db, projectPath, excess) {
|
|
166174
|
-
if (excess <= 0)
|
|
166175
|
-
return 0;
|
|
166176
|
-
const before = getCommitCount(db, projectPath);
|
|
166177
|
-
getEvictStatement(db).run(projectPath, excess);
|
|
166178
|
-
const after = getCommitCount(db, projectPath);
|
|
166179
|
-
return Math.max(0, before - after);
|
|
166180
|
-
}
|
|
166181
166126
|
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
166182
166127
|
if (maxCommits <= 0)
|
|
166183
166128
|
return 0;
|
|
166184
166129
|
const count = getCommitCount(db, projectPath);
|
|
166185
166130
|
if (count <= maxCommits)
|
|
166186
166131
|
return 0;
|
|
166187
|
-
|
|
166188
|
-
const
|
|
166132
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
166133
|
+
const after = getCommitCount(db, projectPath);
|
|
166134
|
+
const evicted = Math.max(0, count - after);
|
|
166189
166135
|
if (evicted > 0) {
|
|
166190
166136
|
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
166191
166137
|
}
|
|
@@ -166565,10 +166511,31 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
166565
166511
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.directory}:`, error51);
|
|
166566
166512
|
}
|
|
166567
166513
|
}
|
|
166514
|
+
function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
|
|
166515
|
+
const timer = setInterval(() => {
|
|
166516
|
+
try {
|
|
166517
|
+
if (!renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
166518
|
+
log(`[git-commits] sweep lease renewal failed for ${projectIdentity}`);
|
|
166519
|
+
}
|
|
166520
|
+
} catch (error51) {
|
|
166521
|
+
log(`[git-commits] sweep lease renewal errored for ${projectIdentity}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
166522
|
+
}
|
|
166523
|
+
}, GIT_SWEEP_LEASE_RENEWAL_MS);
|
|
166524
|
+
timer.unref?.();
|
|
166525
|
+
return () => clearInterval(timer);
|
|
166526
|
+
}
|
|
166568
166527
|
async function sweepGitCommits(args) {
|
|
166569
166528
|
const { directory, projectIdentity, db, gitCommitIndexing } = args;
|
|
166529
|
+
const holderId = crypto.randomUUID();
|
|
166530
|
+
const lease2 = acquireGitSweepLease(db, projectIdentity, holderId);
|
|
166531
|
+
if (!lease2.acquired) {
|
|
166532
|
+
const reason = lease2.reason === "cooldown_active" ? `cooldown active until ${lease2.nextAllowedAt}` : `lease held by ${lease2.leaseHolder ?? "another holder"} until ${lease2.leaseExpiresAt ?? "unknown"}`;
|
|
166533
|
+
log(`[git-commits] sweep skipped for ${projectIdentity} (${directory}): ${reason}`);
|
|
166534
|
+
return;
|
|
166535
|
+
}
|
|
166570
166536
|
const startedAt = Date.now();
|
|
166571
|
-
|
|
166537
|
+
const stopRenewal = startGitSweepLeaseRenewal(db, projectIdentity, holderId);
|
|
166538
|
+
log(`[git-commits] sweep starting for ${directory} (project=${projectIdentity} sinceDays=${gitCommitIndexing.since_days} maxCommits=${gitCommitIndexing.max_commits})`);
|
|
166572
166539
|
try {
|
|
166573
166540
|
const result = await indexCommitsForProject(db, projectIdentity, directory, {
|
|
166574
166541
|
sinceDays: gitCommitIndexing.since_days,
|
|
@@ -166578,16 +166545,24 @@ async function sweepGitCommits(args) {
|
|
|
166578
166545
|
if (result.embedded > 0) {
|
|
166579
166546
|
drainedEmbeddings = await embedUnembeddedCommits(db, projectIdentity);
|
|
166580
166547
|
}
|
|
166548
|
+
const cooldownMarked = markGitSweepSuccessAndRelease(db, projectIdentity, holderId);
|
|
166549
|
+
if (!cooldownMarked) {
|
|
166550
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
166551
|
+
log(`[git-commits] sweep finished for ${projectIdentity}, but lease was no longer active; cooldown not advanced`);
|
|
166552
|
+
}
|
|
166581
166553
|
const elapsedMs = Date.now() - startedAt;
|
|
166582
166554
|
log(`[git-commits] sweep finished for ${projectIdentity} in ${elapsedMs}ms: scanned=${result.scanned} inserted=${result.inserted} updated=${result.updated} evicted=${result.evicted} embedded=${result.embedded} drained=${drainedEmbeddings}`);
|
|
166583
166555
|
} catch (error51) {
|
|
166556
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
166584
166557
|
const elapsedMs = Date.now() - startedAt;
|
|
166585
166558
|
log(`[git-commits] sweep failed for ${directory} after ${elapsedMs}ms: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
166559
|
+
} finally {
|
|
166560
|
+
stopRenewal();
|
|
166586
166561
|
}
|
|
166587
166562
|
}
|
|
166588
166563
|
|
|
166589
166564
|
// ../plugin/src/plugin/embedding-bootstrap-helpers.ts
|
|
166590
|
-
import { createHash as
|
|
166565
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
166591
166566
|
init_logger();
|
|
166592
166567
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
166593
166568
|
"embedding.api_key",
|
|
@@ -166599,7 +166574,7 @@ var EMBEDDING_AFFECTING_TOP_LEVEL_KEYS = new Set(["embedding", "memory", "experi
|
|
|
166599
166574
|
var EMBEDDING_WARNING_TERMS = ["api_key", "endpoint", "model", "provider", "embedding"];
|
|
166600
166575
|
var loggedFailureSignatures = new Map;
|
|
166601
166576
|
function sha256Prefix2(value, length = 16) {
|
|
166602
|
-
return
|
|
166577
|
+
return createHash8("sha256").update(value).digest("hex").slice(0, length);
|
|
166603
166578
|
}
|
|
166604
166579
|
function warningLooksEmbeddingRelated(message) {
|
|
166605
166580
|
const lower = message.toLowerCase();
|
|
@@ -166663,8 +166638,8 @@ function handleUntrustedLoad(db, projectIdentity, directory, detailed) {
|
|
|
166663
166638
|
}
|
|
166664
166639
|
|
|
166665
166640
|
// src/config/index.ts
|
|
166666
|
-
import { existsSync as
|
|
166667
|
-
import { homedir as
|
|
166641
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "node:fs";
|
|
166642
|
+
import { homedir as homedir4 } from "node:os";
|
|
166668
166643
|
import { join as join13 } from "node:path";
|
|
166669
166644
|
|
|
166670
166645
|
// ../plugin/src/config/migrate-experimental.ts
|
|
@@ -166754,9 +166729,67 @@ function migrateLegacyExperimental(rawConfig, warnings) {
|
|
|
166754
166729
|
}
|
|
166755
166730
|
|
|
166756
166731
|
// ../plugin/src/config/variable.ts
|
|
166757
|
-
import { existsSync as
|
|
166758
|
-
import { homedir as
|
|
166732
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
166733
|
+
import { homedir as homedir3 } from "node:os";
|
|
166759
166734
|
import { dirname as dirname5, isAbsolute as isAbsolute2, resolve as resolve3 } from "node:path";
|
|
166735
|
+
|
|
166736
|
+
// ../plugin/src/shared/jsonc-parser.ts
|
|
166737
|
+
function stripJsonComments(content) {
|
|
166738
|
+
let result = "";
|
|
166739
|
+
let inString = false;
|
|
166740
|
+
let escaped = false;
|
|
166741
|
+
let inLineComment = false;
|
|
166742
|
+
let inBlockComment = false;
|
|
166743
|
+
for (let index = 0;index < content.length; index += 1) {
|
|
166744
|
+
const char = content[index];
|
|
166745
|
+
const next = content[index + 1];
|
|
166746
|
+
if (inLineComment) {
|
|
166747
|
+
if (char === `
|
|
166748
|
+
`) {
|
|
166749
|
+
inLineComment = false;
|
|
166750
|
+
result += char;
|
|
166751
|
+
}
|
|
166752
|
+
continue;
|
|
166753
|
+
}
|
|
166754
|
+
if (inBlockComment) {
|
|
166755
|
+
if (char === "*" && next === "/") {
|
|
166756
|
+
inBlockComment = false;
|
|
166757
|
+
index += 1;
|
|
166758
|
+
}
|
|
166759
|
+
continue;
|
|
166760
|
+
}
|
|
166761
|
+
if (inString) {
|
|
166762
|
+
result += char;
|
|
166763
|
+
if (escaped) {
|
|
166764
|
+
escaped = false;
|
|
166765
|
+
} else if (char === "\\") {
|
|
166766
|
+
escaped = true;
|
|
166767
|
+
} else if (char === '"') {
|
|
166768
|
+
inString = false;
|
|
166769
|
+
}
|
|
166770
|
+
continue;
|
|
166771
|
+
}
|
|
166772
|
+
if (char === '"') {
|
|
166773
|
+
inString = true;
|
|
166774
|
+
result += char;
|
|
166775
|
+
continue;
|
|
166776
|
+
}
|
|
166777
|
+
if (char === "/" && next === "/") {
|
|
166778
|
+
inLineComment = true;
|
|
166779
|
+
index += 1;
|
|
166780
|
+
continue;
|
|
166781
|
+
}
|
|
166782
|
+
if (char === "/" && next === "*") {
|
|
166783
|
+
inBlockComment = true;
|
|
166784
|
+
index += 1;
|
|
166785
|
+
continue;
|
|
166786
|
+
}
|
|
166787
|
+
result += char;
|
|
166788
|
+
}
|
|
166789
|
+
return result;
|
|
166790
|
+
}
|
|
166791
|
+
|
|
166792
|
+
// ../plugin/src/config/variable.ts
|
|
166760
166793
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
166761
166794
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
166762
166795
|
function substituteConfigVariables(input) {
|
|
@@ -166808,11 +166841,11 @@ function substituteConfigVariables(input) {
|
|
|
166808
166841
|
}
|
|
166809
166842
|
let filePath = rawPath.trim();
|
|
166810
166843
|
if (filePath.startsWith("~/")) {
|
|
166811
|
-
filePath = resolve3(
|
|
166844
|
+
filePath = resolve3(homedir3(), filePath.slice(2));
|
|
166812
166845
|
} else if (!isAbsolute2(filePath)) {
|
|
166813
166846
|
filePath = resolve3(configDir, filePath);
|
|
166814
166847
|
}
|
|
166815
|
-
if (!
|
|
166848
|
+
if (!existsSync9(filePath)) {
|
|
166816
166849
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
166817
166850
|
continue;
|
|
166818
166851
|
}
|
|
@@ -166838,12 +166871,12 @@ function getProjectConfigPaths(cwd) {
|
|
|
166838
166871
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
166839
166872
|
}
|
|
166840
166873
|
function getUserConfigPaths() {
|
|
166841
|
-
const home = process.env.HOME ??
|
|
166874
|
+
const home = process.env.HOME ?? homedir4();
|
|
166842
166875
|
const basePath = join13(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
166843
166876
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
166844
166877
|
}
|
|
166845
166878
|
function resolveFirstExisting(paths) {
|
|
166846
|
-
return paths.find((path7) =>
|
|
166879
|
+
return paths.find((path7) => existsSync10(path7));
|
|
166847
166880
|
}
|
|
166848
166881
|
function loadConfigFile(path7, scope) {
|
|
166849
166882
|
try {
|
|
@@ -169447,6 +169480,62 @@ function buildToolTarget(part, message) {
|
|
|
169447
169480
|
|
|
169448
169481
|
// ../plugin/src/features/magic-context/search.ts
|
|
169449
169482
|
init_logger();
|
|
169483
|
+
|
|
169484
|
+
// ../plugin/src/features/magic-context/literal-probes.ts
|
|
169485
|
+
var MAX_PROBES = 5;
|
|
169486
|
+
var MIN_PROBE_LENGTH = 3;
|
|
169487
|
+
var SLASH_COMMAND_RE = /\/[a-z][a-z0-9]*(?:-[a-z0-9]+)+/gi;
|
|
169488
|
+
var KEBAB_SNAKE_RE = /[a-z][a-z0-9]*(?:[-_][a-z0-9]+)+/gi;
|
|
169489
|
+
var DOTTED_RE = /[a-z0-9][a-z0-9_-]*(?:\.[a-z0-9_-]+)+/gi;
|
|
169490
|
+
var CAMEL_RE = /\b[a-zA-Z][a-z0-9]*(?:[A-Z][a-z0-9]*)+\b/g;
|
|
169491
|
+
var SHA_RE = /\b[0-9a-f]{7,40}\b/gi;
|
|
169492
|
+
var ERROR_CODE_RE = /\b(?:TS\d{4,}|ERR_[A-Z][A-Z0-9_]*)\b/g;
|
|
169493
|
+
var QUOTED_RE = /["`]([^"`]{3,80})["`]/g;
|
|
169494
|
+
function looksLikeSha(token) {
|
|
169495
|
+
return /[0-9]/.test(token) && /^[0-9a-f]{7,40}$/i.test(token);
|
|
169496
|
+
}
|
|
169497
|
+
function extractLiteralProbes(query) {
|
|
169498
|
+
const trimmed = query.trim();
|
|
169499
|
+
if (trimmed.length === 0)
|
|
169500
|
+
return [];
|
|
169501
|
+
const ordered = [];
|
|
169502
|
+
const seen = new Set;
|
|
169503
|
+
const add = (raw) => {
|
|
169504
|
+
if (!raw)
|
|
169505
|
+
return;
|
|
169506
|
+
const probe = raw.trim();
|
|
169507
|
+
if (probe.length < MIN_PROBE_LENGTH)
|
|
169508
|
+
return;
|
|
169509
|
+
const key = probe.toLowerCase();
|
|
169510
|
+
if (seen.has(key))
|
|
169511
|
+
return;
|
|
169512
|
+
seen.add(key);
|
|
169513
|
+
ordered.push(probe);
|
|
169514
|
+
};
|
|
169515
|
+
for (const m of trimmed.matchAll(QUOTED_RE))
|
|
169516
|
+
add(m[1]);
|
|
169517
|
+
for (const m of trimmed.matchAll(SLASH_COMMAND_RE))
|
|
169518
|
+
add(m[0]);
|
|
169519
|
+
for (const m of trimmed.matchAll(ERROR_CODE_RE))
|
|
169520
|
+
add(m[0]);
|
|
169521
|
+
for (const m of trimmed.matchAll(DOTTED_RE))
|
|
169522
|
+
add(m[0]);
|
|
169523
|
+
for (const m of trimmed.matchAll(KEBAB_SNAKE_RE))
|
|
169524
|
+
add(m[0]);
|
|
169525
|
+
for (const m of trimmed.matchAll(CAMEL_RE))
|
|
169526
|
+
add(m[0]);
|
|
169527
|
+
for (const m of trimmed.matchAll(SHA_RE)) {
|
|
169528
|
+
if (looksLikeSha(m[0]))
|
|
169529
|
+
add(m[0]);
|
|
169530
|
+
}
|
|
169531
|
+
return ordered.slice(0, MAX_PROBES);
|
|
169532
|
+
}
|
|
169533
|
+
function containsProbeVerbatim(text, probes) {
|
|
169534
|
+
if (probes.length === 0)
|
|
169535
|
+
return false;
|
|
169536
|
+
const haystack = text.toLowerCase();
|
|
169537
|
+
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
169538
|
+
}
|
|
169450
169539
|
// ../plugin/src/features/magic-context/memory/embedding-backfill.ts
|
|
169451
169540
|
init_logger();
|
|
169452
169541
|
async function ensureMemoryEmbeddings(args) {
|
|
@@ -169709,36 +169798,82 @@ function linearDecayScore(rank, total) {
|
|
|
169709
169798
|
return 0;
|
|
169710
169799
|
return Math.max(0, 1 - rank / total);
|
|
169711
169800
|
}
|
|
169712
|
-
function
|
|
169713
|
-
|
|
169714
|
-
if (sanitizedQuery.length === 0) {
|
|
169801
|
+
function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
169802
|
+
if (ftsQuery.length === 0)
|
|
169715
169803
|
return [];
|
|
169716
|
-
|
|
169717
|
-
const
|
|
169718
|
-
|
|
169719
|
-
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
169720
|
-
const filtered = rows.map((row) => {
|
|
169804
|
+
const rows = getMessageSearchStatement(db).all(sessionId, ftsQuery, fetchLimit).map((row) => row);
|
|
169805
|
+
const result = [];
|
|
169806
|
+
for (const row of rows) {
|
|
169721
169807
|
const messageOrdinal = getMessageOrdinal(row.messageOrdinal);
|
|
169722
169808
|
if (messageOrdinal === null || typeof row.messageId !== "string" || typeof row.role !== "string" || typeof row.content !== "string") {
|
|
169723
|
-
|
|
169809
|
+
continue;
|
|
169724
169810
|
}
|
|
169725
169811
|
if (cutoff !== null && messageOrdinal > cutoff) {
|
|
169726
|
-
|
|
169812
|
+
continue;
|
|
169727
169813
|
}
|
|
169728
|
-
|
|
169814
|
+
result.push({
|
|
169729
169815
|
messageOrdinal,
|
|
169730
169816
|
messageId: row.messageId,
|
|
169731
169817
|
role: row.role,
|
|
169732
169818
|
content: row.content
|
|
169733
|
-
};
|
|
169734
|
-
}
|
|
169735
|
-
return
|
|
169819
|
+
});
|
|
169820
|
+
}
|
|
169821
|
+
return result;
|
|
169822
|
+
}
|
|
169823
|
+
var RRF_K = 60;
|
|
169824
|
+
var VERBATIM_PROBE_BONUS = 0.5;
|
|
169825
|
+
function searchMessages(args) {
|
|
169826
|
+
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
169827
|
+
const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
|
|
169828
|
+
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
169829
|
+
const probes = args.probes ?? [];
|
|
169830
|
+
if (probes.length === 0) {
|
|
169831
|
+
const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
|
|
169832
|
+
return filtered.map((row, rank) => ({
|
|
169833
|
+
source: "message",
|
|
169834
|
+
content: previewText(row.content),
|
|
169835
|
+
score: linearDecayScore(rank, filtered.length),
|
|
169836
|
+
messageOrdinal: row.messageOrdinal,
|
|
169837
|
+
messageId: row.messageId,
|
|
169838
|
+
role: row.role
|
|
169839
|
+
}));
|
|
169840
|
+
}
|
|
169841
|
+
const queryLists = [];
|
|
169842
|
+
if (baseQuery.length > 0) {
|
|
169843
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff));
|
|
169844
|
+
}
|
|
169845
|
+
for (const probe of probes) {
|
|
169846
|
+
const probeQuery = sanitizeFtsQuery(probe);
|
|
169847
|
+
if (probeQuery.length === 0)
|
|
169848
|
+
continue;
|
|
169849
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, probeQuery, fetchLimit, cutoff));
|
|
169850
|
+
}
|
|
169851
|
+
const fused = new Map;
|
|
169852
|
+
for (const list of queryLists) {
|
|
169853
|
+
list.forEach((row, rank) => {
|
|
169854
|
+
const rrf = 1 / (RRF_K + rank);
|
|
169855
|
+
const existing = fused.get(row.messageId);
|
|
169856
|
+
if (existing) {
|
|
169857
|
+
existing.score += rrf;
|
|
169858
|
+
} else {
|
|
169859
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
169860
|
+
}
|
|
169861
|
+
});
|
|
169862
|
+
}
|
|
169863
|
+
for (const entry of fused.values()) {
|
|
169864
|
+
if (containsProbeVerbatim(entry.row.content, probes)) {
|
|
169865
|
+
entry.score += VERBATIM_PROBE_BONUS;
|
|
169866
|
+
}
|
|
169867
|
+
}
|
|
169868
|
+
const ranked = [...fused.values()].sort((a, b) => b.score !== a.score ? b.score - a.score : a.row.messageOrdinal - b.row.messageOrdinal).slice(0, args.limit);
|
|
169869
|
+
const maxScore = ranked.length > 0 ? ranked[0].score : 1;
|
|
169870
|
+
return ranked.map((entry) => ({
|
|
169736
169871
|
source: "message",
|
|
169737
|
-
content: previewText(row.content),
|
|
169738
|
-
score:
|
|
169739
|
-
messageOrdinal: row.messageOrdinal,
|
|
169740
|
-
messageId: row.messageId,
|
|
169741
|
-
role: row.role
|
|
169872
|
+
content: previewText(entry.row.content),
|
|
169873
|
+
score: maxScore > 0 ? entry.score / maxScore : 0,
|
|
169874
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
169875
|
+
messageId: entry.row.messageId,
|
|
169876
|
+
role: entry.row.role
|
|
169742
169877
|
}));
|
|
169743
169878
|
}
|
|
169744
169879
|
function getSourceBoost(result) {
|
|
@@ -169822,12 +169957,14 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
169822
169957
|
return null;
|
|
169823
169958
|
}) : Promise.resolve(null);
|
|
169824
169959
|
await Promise.resolve();
|
|
169960
|
+
const messageProbes = options.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
|
|
169825
169961
|
const messageResults = runMessages ? searchMessages({
|
|
169826
169962
|
db,
|
|
169827
169963
|
sessionId,
|
|
169828
169964
|
query: trimmedQuery,
|
|
169829
169965
|
limit: tierLimit,
|
|
169830
|
-
maxOrdinal: options.maxMessageOrdinal
|
|
169966
|
+
maxOrdinal: options.maxMessageOrdinal,
|
|
169967
|
+
probes: messageProbes
|
|
169831
169968
|
}) : [];
|
|
169832
169969
|
const queryEmbedding = await queryEmbeddingPromise;
|
|
169833
169970
|
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
@@ -175690,7 +175827,7 @@ function stripPiDroppedPlaceholderMessages(args) {
|
|
|
175690
175827
|
}
|
|
175691
175828
|
|
|
175692
175829
|
// src/system-prompt.ts
|
|
175693
|
-
import { createHash as
|
|
175830
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
175694
175831
|
|
|
175695
175832
|
// ../plugin/src/agents/magic-context-prompt.ts
|
|
175696
175833
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
@@ -175835,7 +175972,7 @@ function processSystemPromptForCache(args) {
|
|
|
175835
175972
|
sessionLog(sessionId, `system prompt date frozen: real=${liveDate}, using=${stickyDate} (cache-stable pass)`);
|
|
175836
175973
|
}
|
|
175837
175974
|
}
|
|
175838
|
-
const currentHash =
|
|
175975
|
+
const currentHash = createHash9("md5").update(frozenPrompt).digest("hex");
|
|
175839
175976
|
const hashChanged = !isFirstHash && currentHash !== previousHash;
|
|
175840
175977
|
if (hashChanged) {
|
|
175841
175978
|
sessionLog(sessionId, `system prompt hash changed: ${previousHash} → ${currentHash} (len=${frozenPrompt.length})`);
|
|
@@ -176951,14 +177088,10 @@ function registerPiContextHandler(pi, options) {
|
|
|
176951
177088
|
}
|
|
176952
177089
|
const sessionMeta = sessionMetaForUsage;
|
|
176953
177090
|
const modelKey = liveModelBySession.get(sessionId);
|
|
176954
|
-
if (usageContextLimit === undefined
|
|
176955
|
-
const
|
|
176956
|
-
|
|
176957
|
-
|
|
176958
|
-
sessionID: sessionId
|
|
176959
|
-
});
|
|
176960
|
-
if (trusted !== undefined && trusted > 0) {
|
|
176961
|
-
usageContextLimit = trusted;
|
|
177091
|
+
if (usageContextLimit === undefined) {
|
|
177092
|
+
const modelWindow = ctx.model?.contextWindow;
|
|
177093
|
+
if (isSaneLimit(modelWindow)) {
|
|
177094
|
+
usageContextLimit = modelWindow;
|
|
176962
177095
|
}
|
|
176963
177096
|
}
|
|
176964
177097
|
let schedulerDecision;
|
|
@@ -177211,27 +177344,8 @@ async function awaitInFlightHistorians() {
|
|
|
177211
177344
|
return;
|
|
177212
177345
|
await Promise.allSettled(Array.from(inFlightHistorian.values()));
|
|
177213
177346
|
}
|
|
177214
|
-
function splitModelKeyForPi(modelKey) {
|
|
177215
|
-
if (!modelKey)
|
|
177216
|
-
return { providerID: undefined, modelID: undefined };
|
|
177217
|
-
const slash = modelKey.indexOf("/");
|
|
177218
|
-
if (slash <= 0 || slash === modelKey.length - 1) {
|
|
177219
|
-
return { providerID: undefined, modelID: undefined };
|
|
177220
|
-
}
|
|
177221
|
-
return {
|
|
177222
|
-
providerID: modelKey.slice(0, slash),
|
|
177223
|
-
modelID: modelKey.slice(slash + 1)
|
|
177224
|
-
};
|
|
177225
|
-
}
|
|
177226
177347
|
function resolvePiHistorianTriggerInputs(args) {
|
|
177227
|
-
const
|
|
177228
|
-
let contextLimit = resolveContextLimit(providerID, modelID, {
|
|
177229
|
-
db: args.db,
|
|
177230
|
-
sessionID: args.sessionId
|
|
177231
|
-
});
|
|
177232
|
-
if ((providerID === undefined || modelID === undefined) && typeof args.usageContextLimit === "number" && Number.isFinite(args.usageContextLimit) && args.usageContextLimit > 0) {
|
|
177233
|
-
contextLimit = args.usageContextLimit;
|
|
177234
|
-
}
|
|
177348
|
+
const contextLimit = typeof args.usageContextLimit === "number" && Number.isFinite(args.usageContextLimit) && args.usageContextLimit > 0 ? args.usageContextLimit : DEFAULT_CONTEXT_LIMIT;
|
|
177235
177349
|
const executeThresholdPercentage = resolveExecuteThreshold(args.historian.executeThresholdPercentage ?? 65, args.modelKey, 65, {
|
|
177236
177350
|
tokensConfig: args.historian.executeThresholdTokens,
|
|
177237
177351
|
contextLimit,
|
|
@@ -178053,7 +178167,7 @@ ${result}`;
|
|
|
178053
178167
|
init_logger();
|
|
178054
178168
|
|
|
178055
178169
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
178056
|
-
import { mkdirSync as
|
|
178170
|
+
import { mkdirSync as mkdirSync6, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
178057
178171
|
init_data_path();
|
|
178058
178172
|
function cleanupHistorianStateFile(path7) {
|
|
178059
178173
|
if (!path7)
|
|
@@ -178257,7 +178371,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
178257
178371
|
}
|
|
178258
178372
|
|
|
178259
178373
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
178260
|
-
import { mkdirSync as
|
|
178374
|
+
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
178261
178375
|
import { join as join16 } from "node:path";
|
|
178262
178376
|
init_data_path();
|
|
178263
178377
|
function historianResponseDumpDir(directory) {
|
|
@@ -178562,11 +178676,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
178562
178676
|
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
178563
178677
|
try {
|
|
178564
178678
|
const dumpDir = historianResponseDumpDir(directory);
|
|
178565
|
-
|
|
178679
|
+
mkdirSync7(dumpDir, { recursive: true });
|
|
178566
178680
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
178567
178681
|
const safeLabel = sanitizeDumpName(label);
|
|
178568
178682
|
const dumpPath = join16(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
178569
|
-
|
|
178683
|
+
writeFileSync4(dumpPath, text, "utf8");
|
|
178570
178684
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
178571
178685
|
label,
|
|
178572
178686
|
dumpPath
|
|
@@ -180478,7 +180592,7 @@ function formatThresholdPercent(value) {
|
|
|
180478
180592
|
// package.json
|
|
180479
180593
|
var package_default = {
|
|
180480
180594
|
name: "@cortexkit/pi-magic-context",
|
|
180481
|
-
version: "0.22.
|
|
180595
|
+
version: "0.22.2",
|
|
180482
180596
|
type: "module",
|
|
180483
180597
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
180484
180598
|
main: "dist/index.js",
|
|
@@ -185582,15 +185696,26 @@ function err3(text) {
|
|
|
185582
185696
|
isError: true
|
|
185583
185697
|
};
|
|
185584
185698
|
}
|
|
185699
|
+
function captureAnchorOrdinal(db, sessionId) {
|
|
185700
|
+
try {
|
|
185701
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
185702
|
+
return ordinal > 0 ? ordinal : null;
|
|
185703
|
+
} catch {
|
|
185704
|
+
return null;
|
|
185705
|
+
}
|
|
185706
|
+
}
|
|
185707
|
+
function anchorSuffix(note) {
|
|
185708
|
+
return note.anchorOrdinal !== null ? ` ↳ @msg ${note.anchorOrdinal}` : "";
|
|
185709
|
+
}
|
|
185585
185710
|
function formatNoteLine(note) {
|
|
185586
185711
|
if (note.type === "smart") {
|
|
185587
185712
|
const conditionLine = note.status === "ready" ? note.readyReason ?? note.surfaceCondition ?? "Condition satisfied" : note.surfaceCondition ?? "No condition recorded";
|
|
185588
185713
|
const statusSuffix2 = note.status === "active" ? "" : ` (${note.status})`;
|
|
185589
|
-
return `- **#${note.id}**${statusSuffix2}: ${note.content}
|
|
185714
|
+
return `- **#${note.id}**${statusSuffix2}: ${note.content}${anchorSuffix(note)}
|
|
185590
185715
|
*Condition*: ${conditionLine}`;
|
|
185591
185716
|
}
|
|
185592
185717
|
const statusSuffix = note.status === "active" ? "" : ` (${note.status})`;
|
|
185593
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}`;
|
|
185718
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}`;
|
|
185594
185719
|
}
|
|
185595
185720
|
var DISMISS_FOOTER = `
|
|
185596
185721
|
|
|
@@ -185612,6 +185737,7 @@ function createCtxNoteTool(deps) {
|
|
|
185612
185737
|
const content = params.content?.trim();
|
|
185613
185738
|
if (!content)
|
|
185614
185739
|
return err3("Error: 'content' is required when action is 'write'.");
|
|
185740
|
+
const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
|
|
185615
185741
|
const surfaceCondition = params.surface_condition?.trim();
|
|
185616
185742
|
if (surfaceCondition) {
|
|
185617
185743
|
if (deps.dreamerEnabled !== true) {
|
|
@@ -185624,13 +185750,18 @@ function createCtxNoteTool(deps) {
|
|
|
185624
185750
|
const note2 = addNote(deps.db, "smart", {
|
|
185625
185751
|
content,
|
|
185626
185752
|
projectPath: projectIdentity,
|
|
185627
|
-
surfaceCondition
|
|
185753
|
+
surfaceCondition,
|
|
185754
|
+
anchorOrdinal
|
|
185628
185755
|
});
|
|
185629
185756
|
return ok3(`Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
185630
185757
|
- Content: ${content}
|
|
185631
185758
|
- Condition: ${surfaceCondition}`);
|
|
185632
185759
|
}
|
|
185633
|
-
const note = addNote(deps.db, "session", {
|
|
185760
|
+
const note = addNote(deps.db, "session", {
|
|
185761
|
+
sessionId,
|
|
185762
|
+
content,
|
|
185763
|
+
anchorOrdinal
|
|
185764
|
+
});
|
|
185634
185765
|
return ok3(`Saved session note #${note.id}.`);
|
|
185635
185766
|
}
|
|
185636
185767
|
if (action2 === "dismiss") {
|
|
@@ -185693,9 +185824,13 @@ function createCtxNoteTool(deps) {
|
|
|
185693
185824
|
|
|
185694
185825
|
No notes for the current filter.`);
|
|
185695
185826
|
}
|
|
185696
|
-
|
|
185827
|
+
const body = sections.join(`
|
|
185828
|
+
|
|
185829
|
+
`);
|
|
185830
|
+
const anchorHint = body.includes("↳ @msg ") ? `
|
|
185697
185831
|
|
|
185698
|
-
|
|
185832
|
+
↳ @msg N marks the conversation tail when a note was written. To see what led to it: ctx_expand(start=N-x, end=N) (pick x for how far back to look).` : "";
|
|
185833
|
+
return ok3(`${body}${anchorHint}${DISMISS_FOOTER}`);
|
|
185699
185834
|
}
|
|
185700
185835
|
};
|
|
185701
185836
|
}
|
|
@@ -186040,7 +186175,8 @@ function createCtxSearchTool(deps) {
|
|
|
186040
186175
|
maxMessageOrdinal: lastCompartmentEnd >= 0 ? lastCompartmentEnd : undefined,
|
|
186041
186176
|
gitCommitsEnabled,
|
|
186042
186177
|
sources: params.sources,
|
|
186043
|
-
visibleMemoryIds
|
|
186178
|
+
visibleMemoryIds,
|
|
186179
|
+
explicitSearch: true
|
|
186044
186180
|
});
|
|
186045
186181
|
return {
|
|
186046
186182
|
content: [{ type: "text", text: formatSearchResults(query, results) }],
|
|
@@ -186188,8 +186324,7 @@ function getPiMessageModel(message) {
|
|
|
186188
186324
|
};
|
|
186189
186325
|
}
|
|
186190
186326
|
function resolvePiPressureContextLimit(args) {
|
|
186191
|
-
|
|
186192
|
-
let effectiveContextLimit = cachedLimit ?? args.piContextWindow;
|
|
186327
|
+
let effectiveContextLimit = isSaneLimit(args.piContextWindow) ? args.piContextWindow : 0;
|
|
186193
186328
|
try {
|
|
186194
186329
|
const overflowState = getOverflowState(args.db, args.sessionId);
|
|
186195
186330
|
if (overflowState.detectedContextLimit > 0) {
|
|
@@ -186205,8 +186340,6 @@ async function persistPiPressureFromMessageEnd(args) {
|
|
|
186205
186340
|
const effectiveContextLimit = resolvePiPressureContextLimit({
|
|
186206
186341
|
db: args.db,
|
|
186207
186342
|
sessionId: args.sessionId,
|
|
186208
|
-
provider: provider2,
|
|
186209
|
-
model,
|
|
186210
186343
|
piContextWindow: args.piContextWindow
|
|
186211
186344
|
});
|
|
186212
186345
|
const usage = extractAssistantUsage(args.message);
|
|
@@ -186215,24 +186348,12 @@ async function persistPiPressureFromMessageEnd(args) {
|
|
|
186215
186348
|
const messageHadOverflowError = typeof msg?.errorMessage === "string" && detectOverflow(msg.errorMessage).isOverflow;
|
|
186216
186349
|
const updates = { lastResponseTime: Date.now() };
|
|
186217
186350
|
if (pressure) {
|
|
186218
|
-
|
|
186219
|
-
|
|
186351
|
+
const percentage = pressure.percentage;
|
|
186352
|
+
const contextLimit = effectiveContextLimit;
|
|
186220
186353
|
const meta3 = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
186221
186354
|
const observedSafeInputTokens = meta3.observedSafeInputTokens ?? 0;
|
|
186222
186355
|
if (percentage > 100 && observedSafeInputTokens > 0 && pressure.inputTokens <= observedSafeInputTokens * 2) {
|
|
186223
|
-
|
|
186224
|
-
clearModelsDevCache();
|
|
186225
|
-
contextLimit = resolvePiPressureContextLimit({
|
|
186226
|
-
db: args.db,
|
|
186227
|
-
sessionId: args.sessionId,
|
|
186228
|
-
provider: provider2,
|
|
186229
|
-
model,
|
|
186230
|
-
piContextWindow: args.piContextWindow
|
|
186231
|
-
});
|
|
186232
|
-
if (contextLimit >= pressure.inputTokens) {
|
|
186233
|
-
percentage = pressure.inputTokens / contextLimit * 100;
|
|
186234
|
-
log(`${PREFIX} models-dev-cache: regression recovered for ${provider2}/${model} via Pi cache reload (was=${oldLimit}, now=${contextLimit})`);
|
|
186235
|
-
} else if (!meta3.cacheAlertSent) {
|
|
186356
|
+
if (!meta3.cacheAlertSent) {
|
|
186236
186357
|
updates.cacheAlertSent = true;
|
|
186237
186358
|
const safeTokens = Math.max(observedSafeInputTokens, pressure.inputTokens);
|
|
186238
186359
|
const modelLabel = provider2 && model ? `${provider2}/${model}` : "the active model";
|
|
@@ -186703,7 +186824,7 @@ ${block}` : event.systemPrompt;
|
|
|
186703
186824
|
cacheTtlConfig: config2.cache_ttl
|
|
186704
186825
|
});
|
|
186705
186826
|
const piUsage = ctx.getContextUsage?.();
|
|
186706
|
-
const piContextWindow = piUsage && typeof piUsage.contextWindow === "number" ? piUsage.contextWindow : 0;
|
|
186827
|
+
const piContextWindow = piUsage && typeof piUsage.contextWindow === "number" && piUsage.contextWindow > 0 ? piUsage.contextWindow : ctx.model?.contextWindow ?? 0;
|
|
186707
186828
|
await persistPiPressureFromMessageEnd({
|
|
186708
186829
|
db,
|
|
186709
186830
|
sessionId,
|