@wolfx/pi-magic-context 0.22.1-patch.0 → 0.22.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +574 -431
- package/dist/subagent-entry.js +375 -97
- 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
|
|
@@ -140945,14 +140942,48 @@ function readRawSessionMessagesFromDb(db, sessionId) {
|
|
|
140945
140942
|
var encoder = new TextEncoder;
|
|
140946
140943
|
var TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
140947
140944
|
var MALFORMED_TAG_PREFIX_REGEX = /^(?:§\d+">§(?:\d+§)?\s*)+/;
|
|
140945
|
+
var COMPLETE_TAG_PAIR_GLOBAL_REGEX = /\u00a7\d+\u00a7/g;
|
|
140946
|
+
var MALFORMED_TAG_GLOBAL_REGEX = /\u00a7\d+">(?:\u00a7(?:\d+\u00a7)?)?/g;
|
|
140947
|
+
var STRAY_SECTION_CHAR_REGEX = /\u00a7/g;
|
|
140948
|
+
function stripWellFormedLeadingTagPrefix(value) {
|
|
140949
|
+
return value.replace(/^(\u00a7\d+\u00a7\s*)+/, "");
|
|
140950
|
+
}
|
|
140951
|
+
function stripCompleteTagPairsGlobally(value) {
|
|
140952
|
+
return value.replace(COMPLETE_TAG_PAIR_GLOBAL_REGEX, "");
|
|
140953
|
+
}
|
|
140954
|
+
function stripMalformedTagNotationGlobally(value) {
|
|
140955
|
+
return value.replace(MALFORMED_TAG_GLOBAL_REGEX, "");
|
|
140956
|
+
}
|
|
140957
|
+
function stripTagSectionCharacters(value) {
|
|
140958
|
+
return value.replace(STRAY_SECTION_CHAR_REGEX, "");
|
|
140959
|
+
}
|
|
140960
|
+
function stripPersistedAssistantText(value) {
|
|
140961
|
+
let text = stripWellFormedLeadingTagPrefix(value);
|
|
140962
|
+
text = stripCompleteTagPairsGlobally(text);
|
|
140963
|
+
text = stripMalformedTagNotationGlobally(text);
|
|
140964
|
+
text = stripTagSectionCharacters(text);
|
|
140965
|
+
return text.trim();
|
|
140966
|
+
}
|
|
140948
140967
|
function byteSize(value) {
|
|
140949
140968
|
return encoder.encode(value).length;
|
|
140950
140969
|
}
|
|
140951
140970
|
function stripTagPrefix(value) {
|
|
140952
|
-
let stripped = value
|
|
140953
|
-
|
|
140971
|
+
let stripped = value;
|
|
140972
|
+
for (let pass = 0;pass < 8; pass++) {
|
|
140973
|
+
const prev = stripped;
|
|
140974
|
+
stripped = stripped.replace(MALFORMED_TAG_PREFIX_REGEX, "");
|
|
140975
|
+
stripped = stripped.replace(TAG_PREFIX_REGEX, "");
|
|
140976
|
+
if (stripped === prev)
|
|
140977
|
+
break;
|
|
140978
|
+
}
|
|
140954
140979
|
return stripped;
|
|
140955
140980
|
}
|
|
140981
|
+
function peelLeadingMcTagNotation(value) {
|
|
140982
|
+
const body = stripTagPrefix(value);
|
|
140983
|
+
if (body === value)
|
|
140984
|
+
return { tagPrefix: "", body };
|
|
140985
|
+
return { tagPrefix: value.slice(0, value.length - body.length), body };
|
|
140986
|
+
}
|
|
140956
140987
|
function prependTag(tagId, value) {
|
|
140957
140988
|
const stripped = stripTagPrefix(value);
|
|
140958
140989
|
return `§${tagId}§ ${stripped}`;
|
|
@@ -140994,7 +141025,9 @@ function hasMeaningfulPart(part) {
|
|
|
140994
141025
|
return false;
|
|
140995
141026
|
const type = part.type;
|
|
140996
141027
|
if (type === "text") {
|
|
140997
|
-
|
|
141028
|
+
if (typeof part.text !== "string")
|
|
141029
|
+
return false;
|
|
141030
|
+
return stripTagPrefix(part.text).trim().length > 0;
|
|
140998
141031
|
}
|
|
140999
141032
|
if (typeof type !== "string")
|
|
141000
141033
|
return false;
|
|
@@ -142698,7 +142731,7 @@ var databases = new Map;
|
|
|
142698
142731
|
var persistenceByDatabase = new WeakMap;
|
|
142699
142732
|
var persistenceErrorByDatabase = new WeakMap;
|
|
142700
142733
|
var lastSchemaFenceRejection = null;
|
|
142701
|
-
var LATEST_SUPPORTED_VERSION =
|
|
142734
|
+
var LATEST_SUPPORTED_VERSION = 29;
|
|
142702
142735
|
function resolveDatabasePath(dbPathOverride) {
|
|
142703
142736
|
if (dbPathOverride) {
|
|
142704
142737
|
return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
|
|
@@ -143018,6 +143051,17 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143018
143051
|
updated_at INTEGER NOT NULL DEFAULT 0
|
|
143019
143052
|
);
|
|
143020
143053
|
|
|
143054
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
143055
|
+
project_path TEXT PRIMARY KEY,
|
|
143056
|
+
lease_holder TEXT,
|
|
143057
|
+
lease_expires_at INTEGER,
|
|
143058
|
+
last_swept_at INTEGER
|
|
143059
|
+
);
|
|
143060
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
143061
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
143062
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
143063
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
143064
|
+
|
|
143021
143065
|
CREATE TABLE IF NOT EXISTS m0_mutation_log (
|
|
143022
143066
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
143023
143067
|
session_id TEXT NOT NULL,
|
|
@@ -144240,6 +144284,38 @@ var MIGRATIONS = [
|
|
|
144240
144284
|
ON tags(session_id, entry_fingerprint)
|
|
144241
144285
|
WHERE type='message' AND entry_fingerprint IS NOT NULL`);
|
|
144242
144286
|
}
|
|
144287
|
+
},
|
|
144288
|
+
{
|
|
144289
|
+
version: 28,
|
|
144290
|
+
description: "Add git commit sweep coordinator lease/cooldown table",
|
|
144291
|
+
up: (db) => {
|
|
144292
|
+
db.exec(`
|
|
144293
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
144294
|
+
project_path TEXT PRIMARY KEY,
|
|
144295
|
+
lease_holder TEXT,
|
|
144296
|
+
lease_expires_at INTEGER,
|
|
144297
|
+
last_swept_at INTEGER
|
|
144298
|
+
);
|
|
144299
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
144300
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
144301
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
144302
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
144303
|
+
`);
|
|
144304
|
+
}
|
|
144305
|
+
},
|
|
144306
|
+
{
|
|
144307
|
+
version: 29,
|
|
144308
|
+
description: "Add anchor_ordinal to notes (traceback to the conversation tail)",
|
|
144309
|
+
up: (db) => {
|
|
144310
|
+
const notesExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'").get();
|
|
144311
|
+
if (!notesExists) {
|
|
144312
|
+
return;
|
|
144313
|
+
}
|
|
144314
|
+
const columns = db.prepare("PRAGMA table_info(notes)").all();
|
|
144315
|
+
if (!columns.some((column) => column.name === "anchor_ordinal")) {
|
|
144316
|
+
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
144317
|
+
}
|
|
144318
|
+
}
|
|
144243
144319
|
}
|
|
144244
144320
|
];
|
|
144245
144321
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -145127,7 +145203,8 @@ function toNote(row) {
|
|
|
145127
145203
|
updatedAt: row.updated_at,
|
|
145128
145204
|
lastCheckedAt: toNullableNumber(row.last_checked_at),
|
|
145129
145205
|
readyAt: toNullableNumber(row.ready_at),
|
|
145130
|
-
readyReason: toNullableString(row.ready_reason)
|
|
145206
|
+
readyReason: toNullableString(row.ready_reason),
|
|
145207
|
+
anchorOrdinal: toNullableNumber(row.anchor_ordinal)
|
|
145131
145208
|
};
|
|
145132
145209
|
}
|
|
145133
145210
|
function getNoteById(db, noteId) {
|
|
@@ -145179,7 +145256,7 @@ function getNotes(db, options = {}) {
|
|
|
145179
145256
|
}
|
|
145180
145257
|
function addNote(db, type, options) {
|
|
145181
145258
|
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());
|
|
145259
|
+
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
145260
|
if (!isNoteRow(result)) {
|
|
145184
145261
|
throw new Error("[notes] failed to insert note");
|
|
145185
145262
|
}
|
|
@@ -145949,212 +146026,41 @@ function getAgentFallbackModels(agent) {
|
|
|
145949
146026
|
|
|
145950
146027
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
145951
146028
|
init_data_path();
|
|
145952
|
-
|
|
145953
|
-
import {
|
|
145954
|
-
import { homedir as homedir2, platform } from "node:os";
|
|
146029
|
+
init_logger();
|
|
146030
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync, writeFileSync } from "node:fs";
|
|
145955
146031
|
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;
|
|
146032
|
+
var MIN_SANE_LIMIT = 20000;
|
|
146033
|
+
var MAX_SANE_LIMIT = 3000000;
|
|
146034
|
+
function isSaneLimit(limit) {
|
|
146035
|
+
return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
|
|
146011
146036
|
}
|
|
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;
|
|
146047
|
-
}
|
|
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
146037
|
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;
|
|
146082
|
-
}
|
|
146083
|
-
function resolveLimit(limit) {
|
|
146084
|
-
if (!limit)
|
|
146085
|
-
return;
|
|
146086
|
-
if (typeof limit.input === "number" && limit.input > 0)
|
|
146087
|
-
return limit.input;
|
|
146088
|
-
if (typeof limit.context === "number" && limit.context > 0)
|
|
146089
|
-
return limit.context;
|
|
146090
|
-
return;
|
|
146038
|
+
var persistSeedLoaded = false;
|
|
146039
|
+
function persistFilePath() {
|
|
146040
|
+
return join6(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
|
|
146091
146041
|
}
|
|
146092
|
-
function
|
|
146093
|
-
|
|
146094
|
-
if (limit === undefined) {
|
|
146042
|
+
function loadPersistedApiCacheOnce() {
|
|
146043
|
+
if (persistSeedLoaded || apiCache !== null)
|
|
146095
146044
|
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;
|
|
146045
|
+
persistSeedLoaded = true;
|
|
146110
146046
|
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
|
-
}
|
|
146047
|
+
const raw = readFileSync3(persistFilePath(), "utf-8");
|
|
146048
|
+
const obj = JSON.parse(raw);
|
|
146049
|
+
const map = new Map;
|
|
146050
|
+
for (const [key, limit] of Object.entries(obj)) {
|
|
146051
|
+
if (isSaneLimit(limit))
|
|
146052
|
+
map.set(key, { limit });
|
|
146122
146053
|
}
|
|
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
|
-
}
|
|
146054
|
+
if (map.size > 0) {
|
|
146055
|
+
apiCache = map;
|
|
146056
|
+
sessionLog("global", `models-dev-cache: seeded ${map.size} entries from persisted cache (cold start)`);
|
|
146139
146057
|
}
|
|
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;
|
|
146058
|
+
} catch {}
|
|
146145
146059
|
}
|
|
146146
|
-
function
|
|
146147
|
-
|
|
146148
|
-
if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
|
|
146149
|
-
fileLastAttempt = now;
|
|
146150
|
-
fileCache = loadModelsDevMetadataFromFile();
|
|
146151
|
-
}
|
|
146060
|
+
function getSdkContextLimit(providerID, modelID) {
|
|
146061
|
+
loadPersistedApiCacheOnce();
|
|
146152
146062
|
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;
|
|
146063
|
+
return isSaneLimit(fromApi) ? fromApi : undefined;
|
|
146158
146064
|
}
|
|
146159
146065
|
function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
146160
146066
|
if (!cache)
|
|
@@ -146171,12 +146077,6 @@ function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
|
146171
146077
|
}
|
|
146172
146078
|
return;
|
|
146173
146079
|
}
|
|
146174
|
-
function clearModelsDevCache() {
|
|
146175
|
-
apiCache = null;
|
|
146176
|
-
apiLoadedAt = 0;
|
|
146177
|
-
fileCache = null;
|
|
146178
|
-
fileLastAttempt = 0;
|
|
146179
|
-
}
|
|
146180
146080
|
|
|
146181
146081
|
// ../plugin/src/hooks/magic-context/derive-budgets.ts
|
|
146182
146082
|
var TRIGGER_BUDGET_PERCENTAGE = 0.05;
|
|
@@ -146207,7 +146107,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
146207
146107
|
const [providerID, ...rest] = historianModelOverride.split("/");
|
|
146208
146108
|
const modelID = rest.join("/");
|
|
146209
146109
|
if (providerID && modelID) {
|
|
146210
|
-
const limit =
|
|
146110
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
146211
146111
|
if (typeof limit === "number" && limit > 0)
|
|
146212
146112
|
return limit;
|
|
146213
146113
|
}
|
|
@@ -146226,7 +146126,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
146226
146126
|
const modelID = rest.join("/");
|
|
146227
146127
|
if (!providerID || !modelID)
|
|
146228
146128
|
continue;
|
|
146229
|
-
const limit =
|
|
146129
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
146230
146130
|
if (typeof limit !== "number" || limit <= 0)
|
|
146231
146131
|
continue;
|
|
146232
146132
|
if (minLimit === undefined || limit < minLimit)
|
|
@@ -146239,37 +146139,6 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
146239
146139
|
init_logger();
|
|
146240
146140
|
var DEFAULT_CONTEXT_LIMIT = 128000;
|
|
146241
146141
|
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
146142
|
function resolveCacheTtl(cacheTtl, modelKey) {
|
|
146274
146143
|
if (typeof cacheTtl === "string") {
|
|
146275
146144
|
return cacheTtl;
|
|
@@ -146490,7 +146359,7 @@ function clearNoteNudgeTriggerOnly(db, sessionId) {
|
|
|
146490
146359
|
}
|
|
146491
146360
|
|
|
146492
146361
|
// ../plugin/src/hooks/magic-context/todo-view.ts
|
|
146493
|
-
import { createHash as
|
|
146362
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
146494
146363
|
var TERMINAL_STATUSES = new Set(["completed", "cancelled"]);
|
|
146495
146364
|
var TITLE_DONE_STATUSES = new Set(["completed"]);
|
|
146496
146365
|
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
@@ -146535,7 +146404,7 @@ function buildSyntheticTodoPart(stateJson) {
|
|
|
146535
146404
|
};
|
|
146536
146405
|
}
|
|
146537
146406
|
function computeSyntheticCallId(stateJson) {
|
|
146538
|
-
const hash =
|
|
146407
|
+
const hash = createHash5("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
146539
146408
|
return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
|
|
146540
146409
|
}
|
|
146541
146410
|
function parseTodoState(stateJson) {
|
|
@@ -146789,7 +146658,7 @@ init_logger();
|
|
|
146789
146658
|
|
|
146790
146659
|
// src/subagent-runner.ts
|
|
146791
146660
|
import * as childProcess from "node:child_process";
|
|
146792
|
-
import { existsSync as
|
|
146661
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
146793
146662
|
import { createRequire as createRequire2 } from "node:module";
|
|
146794
146663
|
import { dirname as dirname3, join as join8, resolve as resolvePath } from "node:path";
|
|
146795
146664
|
import { createInterface } from "node:readline";
|
|
@@ -146893,7 +146762,7 @@ function resolveBundledPiCli() {
|
|
|
146893
146762
|
const require_ = createRequire2(import.meta.url);
|
|
146894
146763
|
const pkgJson = require_.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
146895
146764
|
const cliPath = join8(dirname3(pkgJson), "dist/cli.js");
|
|
146896
|
-
if (
|
|
146765
|
+
if (existsSync6(cliPath))
|
|
146897
146766
|
return cliPath;
|
|
146898
146767
|
return null;
|
|
146899
146768
|
} catch {
|
|
@@ -146904,7 +146773,7 @@ function resolveSubagentEntryPath() {
|
|
|
146904
146773
|
try {
|
|
146905
146774
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
146906
146775
|
const candidate = resolvePath(here, "subagent-entry.js");
|
|
146907
|
-
if (
|
|
146776
|
+
if (existsSync6(candidate))
|
|
146908
146777
|
return candidate;
|
|
146909
146778
|
return;
|
|
146910
146779
|
} catch {
|
|
@@ -147664,7 +147533,7 @@ function clearStaleEntries(db, maxAgeMs, projectIdentity) {
|
|
|
147664
147533
|
// src/commands/ctx-dream.ts
|
|
147665
147534
|
init_logger();
|
|
147666
147535
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
147667
|
-
import { existsSync as
|
|
147536
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
147668
147537
|
import { join as join11 } from "node:path";
|
|
147669
147538
|
|
|
147670
147539
|
// ../plugin/src/shared/index.ts
|
|
@@ -147918,12 +147787,12 @@ init_logger();
|
|
|
147918
147787
|
|
|
147919
147788
|
// ../plugin/src/features/magic-context/key-files/aft-availability.ts
|
|
147920
147789
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
147921
|
-
import { existsSync as
|
|
147922
|
-
import { homedir as
|
|
147790
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
147791
|
+
import { homedir as homedir2 } from "node:os";
|
|
147923
147792
|
import { join as join9 } from "node:path";
|
|
147924
147793
|
var overrideAvailability = null;
|
|
147925
147794
|
function parseConfig(path7) {
|
|
147926
|
-
if (!
|
|
147795
|
+
if (!existsSync7(path7))
|
|
147927
147796
|
return null;
|
|
147928
147797
|
return import_comment_json.parse(readFileSync5(path7, "utf-8"));
|
|
147929
147798
|
}
|
|
@@ -147945,7 +147814,7 @@ function hasAftAtKeys(value, keys) {
|
|
|
147945
147814
|
return false;
|
|
147946
147815
|
}
|
|
147947
147816
|
function getAftAvailability() {
|
|
147948
|
-
const home = process.env.HOME ||
|
|
147817
|
+
const home = process.env.HOME || homedir2();
|
|
147949
147818
|
const opencodePaths = [
|
|
147950
147819
|
join9(home, ".config", "opencode", "opencode.jsonc"),
|
|
147951
147820
|
join9(home, ".config", "opencode", "opencode.json")
|
|
@@ -148589,13 +148458,13 @@ function invalidateMemory(projectPath, memoryId) {
|
|
|
148589
148458
|
}
|
|
148590
148459
|
|
|
148591
148460
|
// ../plugin/src/features/magic-context/memory/normalize-hash.ts
|
|
148592
|
-
import { createHash as
|
|
148461
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
148593
148462
|
function normalizeMemoryContent(content) {
|
|
148594
148463
|
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
148595
148464
|
}
|
|
148596
148465
|
function computeNormalizedHash(content) {
|
|
148597
148466
|
const normalized = normalizeMemoryContent(content);
|
|
148598
|
-
return
|
|
148467
|
+
return createHash6("md5").update(normalized).digest("hex");
|
|
148599
148468
|
}
|
|
148600
148469
|
|
|
148601
148470
|
// ../plugin/src/features/magic-context/memory/storage-memory.ts
|
|
@@ -149746,7 +149615,7 @@ function getOpenCodeDbPath2() {
|
|
|
149746
149615
|
}
|
|
149747
149616
|
function openOpenCodeDb() {
|
|
149748
149617
|
const dbPath = getOpenCodeDbPath2();
|
|
149749
|
-
if (!
|
|
149618
|
+
if (!existsSync8(dbPath)) {
|
|
149750
149619
|
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
149751
149620
|
return null;
|
|
149752
149621
|
}
|
|
@@ -149896,8 +149765,8 @@ async function runDream(args) {
|
|
|
149896
149765
|
try {
|
|
149897
149766
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
149898
149767
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
149899
|
-
architecture:
|
|
149900
|
-
structure:
|
|
149768
|
+
architecture: existsSync8(join11(docsDir, "ARCHITECTURE.md")),
|
|
149769
|
+
structure: existsSync8(join11(docsDir, "STRUCTURE.md"))
|
|
149901
149770
|
} : undefined;
|
|
149902
149771
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
149903
149772
|
id: um.id,
|
|
@@ -150387,7 +150256,7 @@ async function processDreamQueue(args) {
|
|
|
150387
150256
|
return null;
|
|
150388
150257
|
}
|
|
150389
150258
|
const projectDirectory = args.sessionDirectoryOverride ?? resolveDreamSessionDirectory(entry.projectIdentity);
|
|
150390
|
-
log(`[dreamer] dequeued project ${entry.projectIdentity}
|
|
150259
|
+
log(`[dreamer] dequeued project ${entry.projectIdentity}, starting dream run`);
|
|
150391
150260
|
let result;
|
|
150392
150261
|
try {
|
|
150393
150262
|
result = await runDream({
|
|
@@ -150511,6 +150380,7 @@ async function readGitCommits(directory, options = {}) {
|
|
|
150511
150380
|
if (revision.startsWith("-")) {
|
|
150512
150381
|
throw new Error(`readGitCommits: refusing revision that looks like an option: "${revision}"`);
|
|
150513
150382
|
}
|
|
150383
|
+
const projectLabel = options.projectIdentity ?? "<project>";
|
|
150514
150384
|
const args = [
|
|
150515
150385
|
"log",
|
|
150516
150386
|
revision,
|
|
@@ -150533,11 +150403,11 @@ async function readGitCommits(directory, options = {}) {
|
|
|
150533
150403
|
stdout = result.stdout;
|
|
150534
150404
|
} catch (error) {
|
|
150535
150405
|
const message = error instanceof Error ? error.message : String(error);
|
|
150536
|
-
log(`[git-commits] readGitCommits failed
|
|
150406
|
+
log(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
|
|
150537
150407
|
return [];
|
|
150538
150408
|
}
|
|
150539
150409
|
if (stdout.trim().length === 0) {
|
|
150540
|
-
log(`[git-commits] readGitCommits returned empty stdout
|
|
150410
|
+
log(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
|
|
150541
150411
|
}
|
|
150542
150412
|
return parseGitLogOutput(stdout);
|
|
150543
150413
|
}
|
|
@@ -165106,7 +164976,7 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
165106
164976
|
}
|
|
165107
164977
|
|
|
165108
164978
|
// ../plugin/src/features/magic-context/memory/embedding-local.ts
|
|
165109
|
-
import { mkdirSync as
|
|
164979
|
+
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
165110
164980
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
165111
164981
|
import { dirname as dirname4, join as join12 } from "node:path";
|
|
165112
164982
|
import { pathToFileURL } from "node:url";
|
|
@@ -165287,7 +165157,7 @@ class LocalEmbeddingProvider {
|
|
|
165287
165157
|
}
|
|
165288
165158
|
const modelCacheDir = join12(getMagicContextStorageDir(), "models");
|
|
165289
165159
|
try {
|
|
165290
|
-
|
|
165160
|
+
mkdirSync5(modelCacheDir, { recursive: true });
|
|
165291
165161
|
env.cacheDir = modelCacheDir;
|
|
165292
165162
|
} catch {
|
|
165293
165163
|
log("[magic-context] could not create model cache dir, using library default");
|
|
@@ -165662,7 +165532,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
165662
165532
|
}
|
|
165663
165533
|
|
|
165664
165534
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
165665
|
-
import { createHash as
|
|
165535
|
+
import { createHash as createHash7, randomUUID } from "node:crypto";
|
|
165666
165536
|
init_logger();
|
|
165667
165537
|
|
|
165668
165538
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
@@ -165766,6 +165636,125 @@ function getDistinctCommitEmbeddingModelIds(db, projectPath) {
|
|
|
165766
165636
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
165767
165637
|
}
|
|
165768
165638
|
|
|
165639
|
+
// ../plugin/src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
165640
|
+
var GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
165641
|
+
var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
165642
|
+
var GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
165643
|
+
function runImmediate2(db, body) {
|
|
165644
|
+
db.exec("BEGIN IMMEDIATE");
|
|
165645
|
+
let committed = false;
|
|
165646
|
+
try {
|
|
165647
|
+
const result = body();
|
|
165648
|
+
db.exec("COMMIT");
|
|
165649
|
+
committed = true;
|
|
165650
|
+
return result;
|
|
165651
|
+
} finally {
|
|
165652
|
+
if (!committed) {
|
|
165653
|
+
try {
|
|
165654
|
+
db.exec("ROLLBACK");
|
|
165655
|
+
} catch {}
|
|
165656
|
+
}
|
|
165657
|
+
}
|
|
165658
|
+
}
|
|
165659
|
+
function rowToState(row) {
|
|
165660
|
+
return {
|
|
165661
|
+
projectPath: row.project_path,
|
|
165662
|
+
leaseHolder: row.lease_holder,
|
|
165663
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
165664
|
+
lastSweptAt: row.last_swept_at
|
|
165665
|
+
};
|
|
165666
|
+
}
|
|
165667
|
+
function getGitSweepCoordinatorState(db, projectPath) {
|
|
165668
|
+
const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
|
|
165669
|
+
FROM git_sweep_coordinator
|
|
165670
|
+
WHERE project_path = ?`).get(projectPath);
|
|
165671
|
+
return row ? rowToState(row) : null;
|
|
165672
|
+
}
|
|
165673
|
+
function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
|
|
165674
|
+
const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
|
|
165675
|
+
const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
|
|
165676
|
+
return runImmediate2(db, () => {
|
|
165677
|
+
const now = Date.now();
|
|
165678
|
+
const row = getGitSweepCoordinatorState(db, projectPath);
|
|
165679
|
+
if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
|
|
165680
|
+
return {
|
|
165681
|
+
acquired: false,
|
|
165682
|
+
projectPath,
|
|
165683
|
+
reason: "lease_active",
|
|
165684
|
+
leaseHolder: row.leaseHolder,
|
|
165685
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
165686
|
+
lastSweptAt: row.lastSweptAt,
|
|
165687
|
+
nextAllowedAt: null
|
|
165688
|
+
};
|
|
165689
|
+
}
|
|
165690
|
+
if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
|
|
165691
|
+
const nextAllowedAt = row.lastSweptAt + cooldownMs;
|
|
165692
|
+
if (nextAllowedAt > now) {
|
|
165693
|
+
return {
|
|
165694
|
+
acquired: false,
|
|
165695
|
+
projectPath,
|
|
165696
|
+
reason: "cooldown_active",
|
|
165697
|
+
leaseHolder: row.leaseHolder,
|
|
165698
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
165699
|
+
lastSweptAt: row.lastSweptAt,
|
|
165700
|
+
nextAllowedAt
|
|
165701
|
+
};
|
|
165702
|
+
}
|
|
165703
|
+
}
|
|
165704
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
165705
|
+
db.prepare(`INSERT INTO git_sweep_coordinator (
|
|
165706
|
+
project_path,
|
|
165707
|
+
lease_holder,
|
|
165708
|
+
lease_expires_at,
|
|
165709
|
+
last_swept_at
|
|
165710
|
+
) VALUES (?, ?, ?, NULL)
|
|
165711
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
165712
|
+
lease_holder = excluded.lease_holder,
|
|
165713
|
+
lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
|
|
165714
|
+
return {
|
|
165715
|
+
acquired: true,
|
|
165716
|
+
projectPath,
|
|
165717
|
+
holderId,
|
|
165718
|
+
acquiredAt: now,
|
|
165719
|
+
leaseExpiresAt
|
|
165720
|
+
};
|
|
165721
|
+
});
|
|
165722
|
+
}
|
|
165723
|
+
function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
|
|
165724
|
+
return runImmediate2(db, () => {
|
|
165725
|
+
const now = Date.now();
|
|
165726
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
165727
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
165728
|
+
SET lease_expires_at = ?
|
|
165729
|
+
WHERE project_path = ?
|
|
165730
|
+
AND lease_holder = ?
|
|
165731
|
+
AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
|
|
165732
|
+
return result.changes === 1;
|
|
165733
|
+
});
|
|
165734
|
+
}
|
|
165735
|
+
function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
165736
|
+
return runImmediate2(db, () => {
|
|
165737
|
+
const now = Date.now();
|
|
165738
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
165739
|
+
SET lease_holder = NULL,
|
|
165740
|
+
lease_expires_at = NULL,
|
|
165741
|
+
last_swept_at = ?
|
|
165742
|
+
WHERE project_path = ?
|
|
165743
|
+
AND lease_holder = ?
|
|
165744
|
+
AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
|
|
165745
|
+
return result.changes === 1;
|
|
165746
|
+
});
|
|
165747
|
+
}
|
|
165748
|
+
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
165749
|
+
runImmediate2(db, () => {
|
|
165750
|
+
db.prepare(`UPDATE git_sweep_coordinator
|
|
165751
|
+
SET lease_holder = NULL,
|
|
165752
|
+
lease_expires_at = NULL
|
|
165753
|
+
WHERE project_path = ?
|
|
165754
|
+
AND lease_holder = ?`).run(projectPath, holderId);
|
|
165755
|
+
});
|
|
165756
|
+
}
|
|
165757
|
+
|
|
165769
165758
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
165770
165759
|
var OFF_PROVIDER_IDENTITY = "embedding-provider:off";
|
|
165771
165760
|
var SWEEP_MAX_WALL_CLOCK_MS = 10 * 60 * 1000;
|
|
@@ -165818,7 +165807,7 @@ function stableStringify2(value) {
|
|
|
165818
165807
|
return JSON.stringify(value);
|
|
165819
165808
|
}
|
|
165820
165809
|
function sha256Prefix(value, length = 16) {
|
|
165821
|
-
return
|
|
165810
|
+
return createHash7("sha256").update(value).digest("hex").slice(0, length);
|
|
165822
165811
|
}
|
|
165823
165812
|
function getRuntimeFingerprint(config2) {
|
|
165824
165813
|
if (config2.provider === "off") {
|
|
@@ -166083,6 +166072,7 @@ var insertStatements = new WeakMap;
|
|
|
166083
166072
|
var existingShasStatements = new WeakMap;
|
|
166084
166073
|
var projectCountStatements = new WeakMap;
|
|
166085
166074
|
var evictStatements = new WeakMap;
|
|
166075
|
+
var evictOverflowStatements = new WeakMap;
|
|
166086
166076
|
var latestCommitTimeStatements = new WeakMap;
|
|
166087
166077
|
function getInsertStatement(db) {
|
|
166088
166078
|
let stmt = insertStatements.get(db);
|
|
@@ -166125,17 +166115,17 @@ function getLatestCommitTimeStatement(db) {
|
|
|
166125
166115
|
}
|
|
166126
166116
|
return stmt;
|
|
166127
166117
|
}
|
|
166128
|
-
function
|
|
166129
|
-
let stmt =
|
|
166118
|
+
function getEvictOverflowStatement(db) {
|
|
166119
|
+
let stmt = evictOverflowStatements.get(db);
|
|
166130
166120
|
if (!stmt) {
|
|
166131
166121
|
stmt = db.prepare(`DELETE FROM git_commits
|
|
166132
|
-
WHERE
|
|
166133
|
-
SELECT
|
|
166122
|
+
WHERE rowid IN (
|
|
166123
|
+
SELECT rowid FROM git_commits
|
|
166134
166124
|
WHERE project_path = ?
|
|
166135
|
-
ORDER BY committed_at
|
|
166136
|
-
LIMIT ?
|
|
166125
|
+
ORDER BY committed_at DESC, sha DESC
|
|
166126
|
+
LIMIT -1 OFFSET ?
|
|
166137
166127
|
)`);
|
|
166138
|
-
|
|
166128
|
+
evictOverflowStatements.set(db, stmt);
|
|
166139
166129
|
}
|
|
166140
166130
|
return stmt;
|
|
166141
166131
|
}
|
|
@@ -166173,22 +166163,15 @@ function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
|
166173
166163
|
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
166174
166164
|
return row?.latest ?? null;
|
|
166175
166165
|
}
|
|
166176
|
-
function evictOldestCommits(db, projectPath, excess) {
|
|
166177
|
-
if (excess <= 0)
|
|
166178
|
-
return 0;
|
|
166179
|
-
const before = getCommitCount(db, projectPath);
|
|
166180
|
-
getEvictStatement(db).run(projectPath, excess);
|
|
166181
|
-
const after = getCommitCount(db, projectPath);
|
|
166182
|
-
return Math.max(0, before - after);
|
|
166183
|
-
}
|
|
166184
166166
|
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
166185
166167
|
if (maxCommits <= 0)
|
|
166186
166168
|
return 0;
|
|
166187
166169
|
const count = getCommitCount(db, projectPath);
|
|
166188
166170
|
if (count <= maxCommits)
|
|
166189
166171
|
return 0;
|
|
166190
|
-
|
|
166191
|
-
const
|
|
166172
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
166173
|
+
const after = getCommitCount(db, projectPath);
|
|
166174
|
+
const evicted = Math.max(0, count - after);
|
|
166192
166175
|
if (evicted > 0) {
|
|
166193
166176
|
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
166194
166177
|
}
|
|
@@ -166220,7 +166203,8 @@ async function indexCommitsForProject(db, projectPath, directory, options) {
|
|
|
166220
166203
|
const sinceMs = latestIndexed !== null ? Math.max(latestIndexed - 60000, Date.now() - options.sinceDays * MS_PER_DAY) : Date.now() - options.sinceDays * MS_PER_DAY;
|
|
166221
166204
|
const commits = await readGitCommits(directory, {
|
|
166222
166205
|
sinceMs,
|
|
166223
|
-
maxCommits: options.maxCommits
|
|
166206
|
+
maxCommits: options.maxCommits,
|
|
166207
|
+
projectIdentity: projectPath
|
|
166224
166208
|
});
|
|
166225
166209
|
result.scanned = commits.length;
|
|
166226
166210
|
if (commits.length === 0) {
|
|
@@ -166487,7 +166471,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
166487
166471
|
const isNewRegistration = !registeredProjects.has(args.directory);
|
|
166488
166472
|
registeredProjects.set(args.directory, args);
|
|
166489
166473
|
if (isNewRegistration) {
|
|
166490
|
-
log(`[dreamer] registered project ${args.
|
|
166474
|
+
log(`[dreamer] registered project ${args.projectIdentity} (dreaming=${dreamingEnabled} embeddings=${embeddingSweepEnabled} commits=${commitIndexingEnabled}; total=${registeredProjects.size})`);
|
|
166491
166475
|
}
|
|
166492
166476
|
if (!activeTimer) {
|
|
166493
166477
|
log(`[dreamer] started independent schedule timer (every ${DREAM_TIMER_INTERVAL_MS / 60000}m)`);
|
|
@@ -166502,7 +166486,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
166502
166486
|
}
|
|
166503
166487
|
return () => {
|
|
166504
166488
|
registeredProjects.delete(args.directory);
|
|
166505
|
-
log(`[dreamer] unregistered project ${args.
|
|
166489
|
+
log(`[dreamer] unregistered project ${args.projectIdentity} (remaining=${registeredProjects.size})`);
|
|
166506
166490
|
if (registeredProjects.size === 0 && activeTimer) {
|
|
166507
166491
|
clearInterval(activeTimer);
|
|
166508
166492
|
activeTimer = null;
|
|
@@ -166550,7 +166534,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
166550
166534
|
return;
|
|
166551
166535
|
}
|
|
166552
166536
|
try {
|
|
166553
|
-
log(`[dreamer] timer tick (${origin}) ${reg.
|
|
166537
|
+
log(`[dreamer] timer tick (${origin}) ${reg.projectIdentity} — checking schedule window "${reg.dreamerConfig.schedule}"`);
|
|
166554
166538
|
checkScheduleAndEnqueue(db, reg.dreamerConfig.schedule, reg.projectIdentity);
|
|
166555
166539
|
await processDreamQueue({
|
|
166556
166540
|
db,
|
|
@@ -166565,13 +166549,34 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
166565
166549
|
fallbackModels: resolveFallbackChain(DREAMER_AGENT, reg.dreamerConfig.fallback_models)
|
|
166566
166550
|
});
|
|
166567
166551
|
} catch (error51) {
|
|
166568
|
-
log(`[dreamer] timer-triggered queue processing failed for ${reg.
|
|
166552
|
+
log(`[dreamer] timer-triggered queue processing failed for ${reg.projectIdentity}:`, error51);
|
|
166569
166553
|
}
|
|
166570
166554
|
}
|
|
166555
|
+
function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
|
|
166556
|
+
const timer = setInterval(() => {
|
|
166557
|
+
try {
|
|
166558
|
+
if (!renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
166559
|
+
log(`[git-commits] sweep lease renewal failed for ${projectIdentity}`);
|
|
166560
|
+
}
|
|
166561
|
+
} catch (error51) {
|
|
166562
|
+
log(`[git-commits] sweep lease renewal errored for ${projectIdentity}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
166563
|
+
}
|
|
166564
|
+
}, GIT_SWEEP_LEASE_RENEWAL_MS);
|
|
166565
|
+
timer.unref?.();
|
|
166566
|
+
return () => clearInterval(timer);
|
|
166567
|
+
}
|
|
166571
166568
|
async function sweepGitCommits(args) {
|
|
166572
166569
|
const { directory, projectIdentity, db, gitCommitIndexing } = args;
|
|
166570
|
+
const holderId = crypto.randomUUID();
|
|
166571
|
+
const lease2 = acquireGitSweepLease(db, projectIdentity, holderId);
|
|
166572
|
+
if (!lease2.acquired) {
|
|
166573
|
+
const reason = lease2.reason === "cooldown_active" ? `cooldown active until ${lease2.nextAllowedAt}` : `lease held by ${lease2.leaseHolder ?? "another holder"} until ${lease2.leaseExpiresAt ?? "unknown"}`;
|
|
166574
|
+
log(`[git-commits] sweep skipped for ${projectIdentity}: ${reason}`);
|
|
166575
|
+
return;
|
|
166576
|
+
}
|
|
166573
166577
|
const startedAt = Date.now();
|
|
166574
|
-
|
|
166578
|
+
const stopRenewal = startGitSweepLeaseRenewal(db, projectIdentity, holderId);
|
|
166579
|
+
log(`[git-commits] sweep starting for ${projectIdentity} (sinceDays=${gitCommitIndexing.since_days} maxCommits=${gitCommitIndexing.max_commits})`);
|
|
166575
166580
|
try {
|
|
166576
166581
|
const result = await indexCommitsForProject(db, projectIdentity, directory, {
|
|
166577
166582
|
sinceDays: gitCommitIndexing.since_days,
|
|
@@ -166581,16 +166586,24 @@ async function sweepGitCommits(args) {
|
|
|
166581
166586
|
if (result.embedded > 0) {
|
|
166582
166587
|
drainedEmbeddings = await embedUnembeddedCommits(db, projectIdentity);
|
|
166583
166588
|
}
|
|
166589
|
+
const cooldownMarked = markGitSweepSuccessAndRelease(db, projectIdentity, holderId);
|
|
166590
|
+
if (!cooldownMarked) {
|
|
166591
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
166592
|
+
log(`[git-commits] sweep finished for ${projectIdentity}, but lease was no longer active; cooldown not advanced`);
|
|
166593
|
+
}
|
|
166584
166594
|
const elapsedMs = Date.now() - startedAt;
|
|
166585
166595
|
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}`);
|
|
166586
166596
|
} catch (error51) {
|
|
166597
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
166587
166598
|
const elapsedMs = Date.now() - startedAt;
|
|
166588
|
-
log(`[git-commits] sweep failed for ${
|
|
166599
|
+
log(`[git-commits] sweep failed for ${projectIdentity} after ${elapsedMs}ms: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
166600
|
+
} finally {
|
|
166601
|
+
stopRenewal();
|
|
166589
166602
|
}
|
|
166590
166603
|
}
|
|
166591
166604
|
|
|
166592
166605
|
// ../plugin/src/plugin/embedding-bootstrap-helpers.ts
|
|
166593
|
-
import { createHash as
|
|
166606
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
166594
166607
|
init_logger();
|
|
166595
166608
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
166596
166609
|
"embedding.api_key",
|
|
@@ -166602,7 +166615,7 @@ var EMBEDDING_AFFECTING_TOP_LEVEL_KEYS = new Set(["embedding", "memory", "experi
|
|
|
166602
166615
|
var EMBEDDING_WARNING_TERMS = ["api_key", "endpoint", "model", "provider", "embedding"];
|
|
166603
166616
|
var loggedFailureSignatures = new Map;
|
|
166604
166617
|
function sha256Prefix2(value, length = 16) {
|
|
166605
|
-
return
|
|
166618
|
+
return createHash8("sha256").update(value).digest("hex").slice(0, length);
|
|
166606
166619
|
}
|
|
166607
166620
|
function warningLooksEmbeddingRelated(message) {
|
|
166608
166621
|
const lower = message.toLowerCase();
|
|
@@ -166666,8 +166679,8 @@ function handleUntrustedLoad(db, projectIdentity, directory, detailed) {
|
|
|
166666
166679
|
}
|
|
166667
166680
|
|
|
166668
166681
|
// src/config/index.ts
|
|
166669
|
-
import { existsSync as
|
|
166670
|
-
import { homedir as
|
|
166682
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "node:fs";
|
|
166683
|
+
import { homedir as homedir4 } from "node:os";
|
|
166671
166684
|
import { join as join13 } from "node:path";
|
|
166672
166685
|
|
|
166673
166686
|
// ../plugin/src/config/migrate-experimental.ts
|
|
@@ -166761,9 +166774,67 @@ function migrateLegacyExperimental(rawConfig, warnings) {
|
|
|
166761
166774
|
}
|
|
166762
166775
|
|
|
166763
166776
|
// ../plugin/src/config/variable.ts
|
|
166764
|
-
import { existsSync as
|
|
166765
|
-
import { homedir as
|
|
166777
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
166778
|
+
import { homedir as homedir3 } from "node:os";
|
|
166766
166779
|
import { dirname as dirname5, isAbsolute as isAbsolute2, resolve as resolve3 } from "node:path";
|
|
166780
|
+
|
|
166781
|
+
// ../plugin/src/shared/jsonc-parser.ts
|
|
166782
|
+
function stripJsonComments(content) {
|
|
166783
|
+
let result = "";
|
|
166784
|
+
let inString = false;
|
|
166785
|
+
let escaped = false;
|
|
166786
|
+
let inLineComment = false;
|
|
166787
|
+
let inBlockComment = false;
|
|
166788
|
+
for (let index = 0;index < content.length; index += 1) {
|
|
166789
|
+
const char = content[index];
|
|
166790
|
+
const next = content[index + 1];
|
|
166791
|
+
if (inLineComment) {
|
|
166792
|
+
if (char === `
|
|
166793
|
+
`) {
|
|
166794
|
+
inLineComment = false;
|
|
166795
|
+
result += char;
|
|
166796
|
+
}
|
|
166797
|
+
continue;
|
|
166798
|
+
}
|
|
166799
|
+
if (inBlockComment) {
|
|
166800
|
+
if (char === "*" && next === "/") {
|
|
166801
|
+
inBlockComment = false;
|
|
166802
|
+
index += 1;
|
|
166803
|
+
}
|
|
166804
|
+
continue;
|
|
166805
|
+
}
|
|
166806
|
+
if (inString) {
|
|
166807
|
+
result += char;
|
|
166808
|
+
if (escaped) {
|
|
166809
|
+
escaped = false;
|
|
166810
|
+
} else if (char === "\\") {
|
|
166811
|
+
escaped = true;
|
|
166812
|
+
} else if (char === '"') {
|
|
166813
|
+
inString = false;
|
|
166814
|
+
}
|
|
166815
|
+
continue;
|
|
166816
|
+
}
|
|
166817
|
+
if (char === '"') {
|
|
166818
|
+
inString = true;
|
|
166819
|
+
result += char;
|
|
166820
|
+
continue;
|
|
166821
|
+
}
|
|
166822
|
+
if (char === "/" && next === "/") {
|
|
166823
|
+
inLineComment = true;
|
|
166824
|
+
index += 1;
|
|
166825
|
+
continue;
|
|
166826
|
+
}
|
|
166827
|
+
if (char === "/" && next === "*") {
|
|
166828
|
+
inBlockComment = true;
|
|
166829
|
+
index += 1;
|
|
166830
|
+
continue;
|
|
166831
|
+
}
|
|
166832
|
+
result += char;
|
|
166833
|
+
}
|
|
166834
|
+
return result;
|
|
166835
|
+
}
|
|
166836
|
+
|
|
166837
|
+
// ../plugin/src/config/variable.ts
|
|
166767
166838
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
166768
166839
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
166769
166840
|
function substituteConfigVariables(input) {
|
|
@@ -166815,11 +166886,11 @@ function substituteConfigVariables(input) {
|
|
|
166815
166886
|
}
|
|
166816
166887
|
let filePath = rawPath.trim();
|
|
166817
166888
|
if (filePath.startsWith("~/")) {
|
|
166818
|
-
filePath = resolve3(
|
|
166889
|
+
filePath = resolve3(homedir3(), filePath.slice(2));
|
|
166819
166890
|
} else if (!isAbsolute2(filePath)) {
|
|
166820
166891
|
filePath = resolve3(configDir, filePath);
|
|
166821
166892
|
}
|
|
166822
|
-
if (!
|
|
166893
|
+
if (!existsSync9(filePath)) {
|
|
166823
166894
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
166824
166895
|
continue;
|
|
166825
166896
|
}
|
|
@@ -166845,12 +166916,12 @@ function getProjectConfigPaths(cwd) {
|
|
|
166845
166916
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
166846
166917
|
}
|
|
166847
166918
|
function getUserConfigPaths() {
|
|
166848
|
-
const home = process.env.HOME ??
|
|
166919
|
+
const home = process.env.HOME ?? homedir4();
|
|
166849
166920
|
const basePath = join13(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
166850
166921
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
166851
166922
|
}
|
|
166852
166923
|
function resolveFirstExisting(paths) {
|
|
166853
|
-
return paths.find((path7) =>
|
|
166924
|
+
return paths.find((path7) => existsSync10(path7));
|
|
166854
166925
|
}
|
|
166855
166926
|
function loadConfigFile(path7, scope) {
|
|
166856
166927
|
try {
|
|
@@ -169454,6 +169525,62 @@ function buildToolTarget(part, message) {
|
|
|
169454
169525
|
|
|
169455
169526
|
// ../plugin/src/features/magic-context/search.ts
|
|
169456
169527
|
init_logger();
|
|
169528
|
+
|
|
169529
|
+
// ../plugin/src/features/magic-context/literal-probes.ts
|
|
169530
|
+
var MAX_PROBES = 5;
|
|
169531
|
+
var MIN_PROBE_LENGTH = 3;
|
|
169532
|
+
var SLASH_COMMAND_RE = /\/[a-z][a-z0-9]*(?:-[a-z0-9]+)+/gi;
|
|
169533
|
+
var KEBAB_SNAKE_RE = /[a-z][a-z0-9]*(?:[-_][a-z0-9]+)+/gi;
|
|
169534
|
+
var DOTTED_RE = /[a-z0-9][a-z0-9_-]*(?:\.[a-z0-9_-]+)+/gi;
|
|
169535
|
+
var CAMEL_RE = /\b[a-zA-Z][a-z0-9]*(?:[A-Z][a-z0-9]*)+\b/g;
|
|
169536
|
+
var SHA_RE = /\b[0-9a-f]{7,40}\b/gi;
|
|
169537
|
+
var ERROR_CODE_RE = /\b(?:TS\d{4,}|ERR_[A-Z][A-Z0-9_]*)\b/g;
|
|
169538
|
+
var QUOTED_RE = /["`]([^"`]{3,80})["`]/g;
|
|
169539
|
+
function looksLikeSha(token) {
|
|
169540
|
+
return /[0-9]/.test(token) && /^[0-9a-f]{7,40}$/i.test(token);
|
|
169541
|
+
}
|
|
169542
|
+
function extractLiteralProbes(query) {
|
|
169543
|
+
const trimmed = query.trim();
|
|
169544
|
+
if (trimmed.length === 0)
|
|
169545
|
+
return [];
|
|
169546
|
+
const ordered = [];
|
|
169547
|
+
const seen = new Set;
|
|
169548
|
+
const add = (raw) => {
|
|
169549
|
+
if (!raw)
|
|
169550
|
+
return;
|
|
169551
|
+
const probe = raw.trim();
|
|
169552
|
+
if (probe.length < MIN_PROBE_LENGTH)
|
|
169553
|
+
return;
|
|
169554
|
+
const key = probe.toLowerCase();
|
|
169555
|
+
if (seen.has(key))
|
|
169556
|
+
return;
|
|
169557
|
+
seen.add(key);
|
|
169558
|
+
ordered.push(probe);
|
|
169559
|
+
};
|
|
169560
|
+
for (const m of trimmed.matchAll(QUOTED_RE))
|
|
169561
|
+
add(m[1]);
|
|
169562
|
+
for (const m of trimmed.matchAll(SLASH_COMMAND_RE))
|
|
169563
|
+
add(m[0]);
|
|
169564
|
+
for (const m of trimmed.matchAll(ERROR_CODE_RE))
|
|
169565
|
+
add(m[0]);
|
|
169566
|
+
for (const m of trimmed.matchAll(DOTTED_RE))
|
|
169567
|
+
add(m[0]);
|
|
169568
|
+
for (const m of trimmed.matchAll(KEBAB_SNAKE_RE))
|
|
169569
|
+
add(m[0]);
|
|
169570
|
+
for (const m of trimmed.matchAll(CAMEL_RE))
|
|
169571
|
+
add(m[0]);
|
|
169572
|
+
for (const m of trimmed.matchAll(SHA_RE)) {
|
|
169573
|
+
if (looksLikeSha(m[0]))
|
|
169574
|
+
add(m[0]);
|
|
169575
|
+
}
|
|
169576
|
+
return ordered.slice(0, MAX_PROBES);
|
|
169577
|
+
}
|
|
169578
|
+
function containsProbeVerbatim(text, probes) {
|
|
169579
|
+
if (probes.length === 0)
|
|
169580
|
+
return false;
|
|
169581
|
+
const haystack = text.toLowerCase();
|
|
169582
|
+
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
169583
|
+
}
|
|
169457
169584
|
// ../plugin/src/features/magic-context/memory/embedding-backfill.ts
|
|
169458
169585
|
init_logger();
|
|
169459
169586
|
async function ensureMemoryEmbeddings(args) {
|
|
@@ -169716,36 +169843,82 @@ function linearDecayScore(rank, total) {
|
|
|
169716
169843
|
return 0;
|
|
169717
169844
|
return Math.max(0, 1 - rank / total);
|
|
169718
169845
|
}
|
|
169719
|
-
function
|
|
169720
|
-
|
|
169721
|
-
if (sanitizedQuery.length === 0) {
|
|
169846
|
+
function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
169847
|
+
if (ftsQuery.length === 0)
|
|
169722
169848
|
return [];
|
|
169723
|
-
|
|
169724
|
-
const
|
|
169725
|
-
|
|
169726
|
-
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
169727
|
-
const filtered = rows.map((row) => {
|
|
169849
|
+
const rows = getMessageSearchStatement(db).all(sessionId, ftsQuery, fetchLimit).map((row) => row);
|
|
169850
|
+
const result = [];
|
|
169851
|
+
for (const row of rows) {
|
|
169728
169852
|
const messageOrdinal = getMessageOrdinal(row.messageOrdinal);
|
|
169729
169853
|
if (messageOrdinal === null || typeof row.messageId !== "string" || typeof row.role !== "string" || typeof row.content !== "string") {
|
|
169730
|
-
|
|
169854
|
+
continue;
|
|
169731
169855
|
}
|
|
169732
169856
|
if (cutoff !== null && messageOrdinal > cutoff) {
|
|
169733
|
-
|
|
169857
|
+
continue;
|
|
169734
169858
|
}
|
|
169735
|
-
|
|
169859
|
+
result.push({
|
|
169736
169860
|
messageOrdinal,
|
|
169737
169861
|
messageId: row.messageId,
|
|
169738
169862
|
role: row.role,
|
|
169739
169863
|
content: row.content
|
|
169740
|
-
};
|
|
169741
|
-
}
|
|
169742
|
-
return
|
|
169864
|
+
});
|
|
169865
|
+
}
|
|
169866
|
+
return result;
|
|
169867
|
+
}
|
|
169868
|
+
var RRF_K = 60;
|
|
169869
|
+
var VERBATIM_PROBE_BONUS = 0.5;
|
|
169870
|
+
function searchMessages(args) {
|
|
169871
|
+
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
169872
|
+
const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
|
|
169873
|
+
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
169874
|
+
const probes = args.probes ?? [];
|
|
169875
|
+
if (probes.length === 0) {
|
|
169876
|
+
const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
|
|
169877
|
+
return filtered.map((row, rank) => ({
|
|
169878
|
+
source: "message",
|
|
169879
|
+
content: previewText(row.content),
|
|
169880
|
+
score: linearDecayScore(rank, filtered.length),
|
|
169881
|
+
messageOrdinal: row.messageOrdinal,
|
|
169882
|
+
messageId: row.messageId,
|
|
169883
|
+
role: row.role
|
|
169884
|
+
}));
|
|
169885
|
+
}
|
|
169886
|
+
const queryLists = [];
|
|
169887
|
+
if (baseQuery.length > 0) {
|
|
169888
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff));
|
|
169889
|
+
}
|
|
169890
|
+
for (const probe of probes) {
|
|
169891
|
+
const probeQuery = sanitizeFtsQuery(probe);
|
|
169892
|
+
if (probeQuery.length === 0)
|
|
169893
|
+
continue;
|
|
169894
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, probeQuery, fetchLimit, cutoff));
|
|
169895
|
+
}
|
|
169896
|
+
const fused = new Map;
|
|
169897
|
+
for (const list of queryLists) {
|
|
169898
|
+
list.forEach((row, rank) => {
|
|
169899
|
+
const rrf = 1 / (RRF_K + rank);
|
|
169900
|
+
const existing = fused.get(row.messageId);
|
|
169901
|
+
if (existing) {
|
|
169902
|
+
existing.score += rrf;
|
|
169903
|
+
} else {
|
|
169904
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
169905
|
+
}
|
|
169906
|
+
});
|
|
169907
|
+
}
|
|
169908
|
+
for (const entry of fused.values()) {
|
|
169909
|
+
if (containsProbeVerbatim(entry.row.content, probes)) {
|
|
169910
|
+
entry.score += VERBATIM_PROBE_BONUS;
|
|
169911
|
+
}
|
|
169912
|
+
}
|
|
169913
|
+
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);
|
|
169914
|
+
const maxScore = ranked.length > 0 ? ranked[0].score : 1;
|
|
169915
|
+
return ranked.map((entry) => ({
|
|
169743
169916
|
source: "message",
|
|
169744
|
-
content: previewText(row.content),
|
|
169745
|
-
score:
|
|
169746
|
-
messageOrdinal: row.messageOrdinal,
|
|
169747
|
-
messageId: row.messageId,
|
|
169748
|
-
role: row.role
|
|
169917
|
+
content: previewText(entry.row.content),
|
|
169918
|
+
score: maxScore > 0 ? entry.score / maxScore : 0,
|
|
169919
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
169920
|
+
messageId: entry.row.messageId,
|
|
169921
|
+
role: entry.row.role
|
|
169749
169922
|
}));
|
|
169750
169923
|
}
|
|
169751
169924
|
function getSourceBoost(result) {
|
|
@@ -169829,12 +170002,14 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
169829
170002
|
return null;
|
|
169830
170003
|
}) : Promise.resolve(null);
|
|
169831
170004
|
await Promise.resolve();
|
|
170005
|
+
const messageProbes = options.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
|
|
169832
170006
|
const messageResults = runMessages ? searchMessages({
|
|
169833
170007
|
db,
|
|
169834
170008
|
sessionId,
|
|
169835
170009
|
query: trimmedQuery,
|
|
169836
170010
|
limit: tierLimit,
|
|
169837
|
-
maxOrdinal: options.maxMessageOrdinal
|
|
170011
|
+
maxOrdinal: options.maxMessageOrdinal,
|
|
170012
|
+
probes: messageProbes
|
|
169838
170013
|
}) : [];
|
|
169839
170014
|
const queryEmbedding = await queryEmbeddingPromise;
|
|
169840
170015
|
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
@@ -175697,7 +175872,7 @@ function stripPiDroppedPlaceholderMessages(args) {
|
|
|
175697
175872
|
}
|
|
175698
175873
|
|
|
175699
175874
|
// src/system-prompt.ts
|
|
175700
|
-
import { createHash as
|
|
175875
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
175701
175876
|
|
|
175702
175877
|
// ../plugin/src/agents/magic-context-prompt.ts
|
|
175703
175878
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
@@ -175842,7 +176017,7 @@ function processSystemPromptForCache(args) {
|
|
|
175842
176017
|
sessionLog(sessionId, `system prompt date frozen: real=${liveDate}, using=${stickyDate} (cache-stable pass)`);
|
|
175843
176018
|
}
|
|
175844
176019
|
}
|
|
175845
|
-
const currentHash =
|
|
176020
|
+
const currentHash = createHash9("md5").update(frozenPrompt).digest("hex");
|
|
175846
176021
|
const hashChanged = !isFirstHash && currentHash !== previousHash;
|
|
175847
176022
|
if (hashChanged) {
|
|
175848
176023
|
sessionLog(sessionId, `system prompt hash changed: ${previousHash} → ${currentHash} (len=${frozenPrompt.length})`);
|
|
@@ -175887,10 +176062,8 @@ function injectPiTemporalMarkers(messages) {
|
|
|
175887
176062
|
if (prefix !== null) {
|
|
175888
176063
|
const userMsg = msg;
|
|
175889
176064
|
if (typeof userMsg.content === "string") {
|
|
175890
|
-
if (!TEMPORAL_MARKER_PATTERN.test(
|
|
175891
|
-
const
|
|
175892
|
-
const tagPrefix = tagMatch ? tagMatch[0] : "";
|
|
175893
|
-
const body = userMsg.content.slice(tagPrefix.length);
|
|
176065
|
+
if (!TEMPORAL_MARKER_PATTERN.test(stripTagPrefix(userMsg.content))) {
|
|
176066
|
+
const { tagPrefix, body } = peelLeadingMcTagNotation(userMsg.content);
|
|
175894
176067
|
messages[i] = {
|
|
175895
176068
|
...userMsg,
|
|
175896
176069
|
content: tagPrefix + prefix + body
|
|
@@ -175901,9 +176074,7 @@ function injectPiTemporalMarkers(messages) {
|
|
|
175901
176074
|
const firstTextIndex = userMsg.content.findIndex((p) => p && typeof p === "object" && p.type === "text");
|
|
175902
176075
|
if (firstTextIndex >= 0) {
|
|
175903
176076
|
const existing = userMsg.content[firstTextIndex];
|
|
175904
|
-
const
|
|
175905
|
-
const tagPrefix = tagMatch ? tagMatch[0] : "";
|
|
175906
|
-
const body = existing.text.slice(tagPrefix.length);
|
|
176077
|
+
const { tagPrefix, body } = peelLeadingMcTagNotation(existing.text);
|
|
175907
176078
|
if (!TEMPORAL_MARKER_PATTERN.test(body)) {
|
|
175908
176079
|
const newContent = userMsg.content.slice();
|
|
175909
176080
|
newContent[firstTextIndex] = {
|
|
@@ -175926,12 +176097,6 @@ function injectPiTemporalMarkers(messages) {
|
|
|
175926
176097
|
}
|
|
175927
176098
|
return injected;
|
|
175928
176099
|
}
|
|
175929
|
-
function stripTagPrefix2(text) {
|
|
175930
|
-
const match = text.match(/^(?:§\d+§\s*)+/);
|
|
175931
|
-
if (!match)
|
|
175932
|
-
return text;
|
|
175933
|
-
return text.slice(match[0].length);
|
|
175934
|
-
}
|
|
175935
176100
|
|
|
175936
176101
|
// src/timeout.ts
|
|
175937
176102
|
function withTimeout(p, ms) {
|
|
@@ -176958,14 +177123,10 @@ function registerPiContextHandler(pi, options) {
|
|
|
176958
177123
|
}
|
|
176959
177124
|
const sessionMeta = sessionMetaForUsage;
|
|
176960
177125
|
const modelKey = liveModelBySession.get(sessionId);
|
|
176961
|
-
if (usageContextLimit === undefined
|
|
176962
|
-
const
|
|
176963
|
-
|
|
176964
|
-
|
|
176965
|
-
sessionID: sessionId
|
|
176966
|
-
});
|
|
176967
|
-
if (trusted !== undefined && trusted > 0) {
|
|
176968
|
-
usageContextLimit = trusted;
|
|
177126
|
+
if (usageContextLimit === undefined) {
|
|
177127
|
+
const modelWindow = ctx.model?.contextWindow;
|
|
177128
|
+
if (isSaneLimit(modelWindow)) {
|
|
177129
|
+
usageContextLimit = modelWindow;
|
|
176969
177130
|
}
|
|
176970
177131
|
}
|
|
176971
177132
|
let schedulerDecision;
|
|
@@ -177218,27 +177379,8 @@ async function awaitInFlightHistorians() {
|
|
|
177218
177379
|
return;
|
|
177219
177380
|
await Promise.allSettled(Array.from(inFlightHistorian.values()));
|
|
177220
177381
|
}
|
|
177221
|
-
function splitModelKeyForPi(modelKey) {
|
|
177222
|
-
if (!modelKey)
|
|
177223
|
-
return { providerID: undefined, modelID: undefined };
|
|
177224
|
-
const slash = modelKey.indexOf("/");
|
|
177225
|
-
if (slash <= 0 || slash === modelKey.length - 1) {
|
|
177226
|
-
return { providerID: undefined, modelID: undefined };
|
|
177227
|
-
}
|
|
177228
|
-
return {
|
|
177229
|
-
providerID: modelKey.slice(0, slash),
|
|
177230
|
-
modelID: modelKey.slice(slash + 1)
|
|
177231
|
-
};
|
|
177232
|
-
}
|
|
177233
177382
|
function resolvePiHistorianTriggerInputs(args) {
|
|
177234
|
-
const
|
|
177235
|
-
let contextLimit = resolveContextLimit(providerID, modelID, {
|
|
177236
|
-
db: args.db,
|
|
177237
|
-
sessionID: args.sessionId
|
|
177238
|
-
});
|
|
177239
|
-
if ((providerID === undefined || modelID === undefined) && typeof args.usageContextLimit === "number" && Number.isFinite(args.usageContextLimit) && args.usageContextLimit > 0) {
|
|
177240
|
-
contextLimit = args.usageContextLimit;
|
|
177241
|
-
}
|
|
177383
|
+
const contextLimit = typeof args.usageContextLimit === "number" && Number.isFinite(args.usageContextLimit) && args.usageContextLimit > 0 ? args.usageContextLimit : DEFAULT_CONTEXT_LIMIT;
|
|
177242
177384
|
const executeThresholdPercentage = resolveExecuteThreshold(args.historian.executeThresholdPercentage ?? 65, args.modelKey, 65, {
|
|
177243
177385
|
tokensConfig: args.historian.executeThresholdTokens,
|
|
177244
177386
|
contextLimit,
|
|
@@ -178060,7 +178202,7 @@ ${result}`;
|
|
|
178060
178202
|
init_logger();
|
|
178061
178203
|
|
|
178062
178204
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
178063
|
-
import { mkdirSync as
|
|
178205
|
+
import { mkdirSync as mkdirSync6, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
178064
178206
|
init_data_path();
|
|
178065
178207
|
function cleanupHistorianStateFile(path7) {
|
|
178066
178208
|
if (!path7)
|
|
@@ -178264,7 +178406,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
178264
178406
|
}
|
|
178265
178407
|
|
|
178266
178408
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
178267
|
-
import { mkdirSync as
|
|
178409
|
+
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
178268
178410
|
import { join as join16 } from "node:path";
|
|
178269
178411
|
init_data_path();
|
|
178270
178412
|
function historianResponseDumpDir(directory) {
|
|
@@ -178569,11 +178711,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
178569
178711
|
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
178570
178712
|
try {
|
|
178571
178713
|
const dumpDir = historianResponseDumpDir(directory);
|
|
178572
|
-
|
|
178714
|
+
mkdirSync7(dumpDir, { recursive: true });
|
|
178573
178715
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
178574
178716
|
const safeLabel = sanitizeDumpName(label);
|
|
178575
178717
|
const dumpPath = join16(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
178576
|
-
|
|
178718
|
+
writeFileSync4(dumpPath, text, "utf8");
|
|
178577
178719
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
178578
178720
|
label,
|
|
178579
178721
|
dumpPath
|
|
@@ -180485,7 +180627,7 @@ function formatThresholdPercent(value) {
|
|
|
180485
180627
|
// package.json
|
|
180486
180628
|
var package_default = {
|
|
180487
180629
|
name: "@wolfx/pi-magic-context",
|
|
180488
|
-
version: "0.22.
|
|
180630
|
+
version: "0.22.3",
|
|
180489
180631
|
type: "module",
|
|
180490
180632
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
180491
180633
|
main: "dist/index.js",
|
|
@@ -181070,10 +181212,6 @@ function computePiPressure(usage, contextLimit) {
|
|
|
181070
181212
|
}
|
|
181071
181213
|
|
|
181072
181214
|
// src/strip-tag-prefix.ts
|
|
181073
|
-
var DEFAULT_PATTERNS = [
|
|
181074
|
-
/^(\u00a7\d+\u00a7\s*)+/,
|
|
181075
|
-
/\u00a7/g
|
|
181076
|
-
];
|
|
181077
181215
|
function parseRegex(src) {
|
|
181078
181216
|
if (src.startsWith("/")) {
|
|
181079
181217
|
const lastSlash = src.lastIndexOf("/");
|
|
@@ -181085,43 +181223,42 @@ function parseRegex(src) {
|
|
|
181085
181223
|
}
|
|
181086
181224
|
return new RegExp(src);
|
|
181087
181225
|
}
|
|
181088
|
-
function
|
|
181226
|
+
function stripTagPrefixFromAssistantMessage(message, stripConfig) {
|
|
181227
|
+
if (message.role !== "assistant")
|
|
181228
|
+
return false;
|
|
181229
|
+
if (!Array.isArray(message.content))
|
|
181230
|
+
return false;
|
|
181089
181231
|
const isEnabled = stripConfig?.enabled ?? true;
|
|
181090
181232
|
if (!isEnabled)
|
|
181091
|
-
return
|
|
181233
|
+
return false;
|
|
181234
|
+
let patterns = null;
|
|
181092
181235
|
if (stripConfig?.patterns && stripConfig.patterns.length > 0) {
|
|
181093
|
-
|
|
181236
|
+
patterns = stripConfig.patterns.map(parseRegex);
|
|
181094
181237
|
}
|
|
181095
|
-
|
|
181096
|
-
|
|
181097
|
-
|
|
181098
|
-
|
|
181099
|
-
|
|
181100
|
-
|
|
181101
|
-
|
|
181102
|
-
|
|
181103
|
-
|
|
181104
|
-
|
|
181105
|
-
|
|
181106
|
-
if (part === null || typeof part !== "object" || part.type !== "text") {
|
|
181107
|
-
continue;
|
|
181108
|
-
}
|
|
181109
|
-
const textPart = part;
|
|
181110
|
-
if (typeof textPart.text !== "string")
|
|
181111
|
-
continue;
|
|
181112
|
-
let stripped = textPart.text;
|
|
181238
|
+
let mutated = false;
|
|
181239
|
+
for (const part of message.content) {
|
|
181240
|
+
if (part === null || typeof part !== "object" || part.type !== "text") {
|
|
181241
|
+
continue;
|
|
181242
|
+
}
|
|
181243
|
+
const textPart = part;
|
|
181244
|
+
if (typeof textPart.text !== "string")
|
|
181245
|
+
continue;
|
|
181246
|
+
let stripped;
|
|
181247
|
+
if (patterns) {
|
|
181248
|
+
stripped = textPart.text;
|
|
181113
181249
|
for (const regex of patterns) {
|
|
181114
181250
|
stripped = stripped.replace(regex, "");
|
|
181115
181251
|
}
|
|
181116
|
-
|
|
181117
|
-
|
|
181118
|
-
mutated = true;
|
|
181119
|
-
}
|
|
181252
|
+
} else {
|
|
181253
|
+
stripped = stripPersistedAssistantText(textPart.text);
|
|
181120
181254
|
}
|
|
181121
|
-
|
|
181122
|
-
|
|
181255
|
+
if (stripped !== textPart.text) {
|
|
181256
|
+
textPart.text = stripped;
|
|
181257
|
+
mutated = true;
|
|
181258
|
+
}
|
|
181259
|
+
}
|
|
181260
|
+
return mutated;
|
|
181123
181261
|
}
|
|
181124
|
-
var defaultHandler = createStripTagPrefixHandler();
|
|
181125
181262
|
|
|
181126
181263
|
// ../plugin/src/tools/ctx-expand/constants.ts
|
|
181127
181264
|
var CTX_EXPAND_DESCRIPTION = "Decompress a compartment range to see the original conversation transcript. " + 'Use start/end from <compartment start="N" end="M"> attributes. ' + "Returns the compacted U:/A: transcript for that message range, capped at ~15K tokens.";
|
|
@@ -185618,15 +185755,26 @@ function err3(text) {
|
|
|
185618
185755
|
isError: true
|
|
185619
185756
|
};
|
|
185620
185757
|
}
|
|
185758
|
+
function captureAnchorOrdinal(db, sessionId) {
|
|
185759
|
+
try {
|
|
185760
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
185761
|
+
return ordinal > 0 ? ordinal : null;
|
|
185762
|
+
} catch {
|
|
185763
|
+
return null;
|
|
185764
|
+
}
|
|
185765
|
+
}
|
|
185766
|
+
function anchorSuffix(note) {
|
|
185767
|
+
return note.anchorOrdinal !== null ? ` ↳ @msg ${note.anchorOrdinal}` : "";
|
|
185768
|
+
}
|
|
185621
185769
|
function formatNoteLine(note) {
|
|
185622
185770
|
if (note.type === "smart") {
|
|
185623
185771
|
const conditionLine = note.status === "ready" ? note.readyReason ?? note.surfaceCondition ?? "Condition satisfied" : note.surfaceCondition ?? "No condition recorded";
|
|
185624
185772
|
const statusSuffix2 = note.status === "active" ? "" : ` (${note.status})`;
|
|
185625
|
-
return `- **#${note.id}**${statusSuffix2}: ${note.content}
|
|
185773
|
+
return `- **#${note.id}**${statusSuffix2}: ${note.content}${anchorSuffix(note)}
|
|
185626
185774
|
*Condition*: ${conditionLine}`;
|
|
185627
185775
|
}
|
|
185628
185776
|
const statusSuffix = note.status === "active" ? "" : ` (${note.status})`;
|
|
185629
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}`;
|
|
185777
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}`;
|
|
185630
185778
|
}
|
|
185631
185779
|
var DISMISS_FOOTER = `
|
|
185632
185780
|
|
|
@@ -185648,6 +185796,7 @@ function createCtxNoteTool(deps) {
|
|
|
185648
185796
|
const content = params.content?.trim();
|
|
185649
185797
|
if (!content)
|
|
185650
185798
|
return err3("Error: 'content' is required when action is 'write'.");
|
|
185799
|
+
const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
|
|
185651
185800
|
const surfaceCondition = params.surface_condition?.trim();
|
|
185652
185801
|
if (surfaceCondition) {
|
|
185653
185802
|
if (deps.dreamerEnabled !== true) {
|
|
@@ -185660,13 +185809,18 @@ function createCtxNoteTool(deps) {
|
|
|
185660
185809
|
const note2 = addNote(deps.db, "smart", {
|
|
185661
185810
|
content,
|
|
185662
185811
|
projectPath: projectIdentity,
|
|
185663
|
-
surfaceCondition
|
|
185812
|
+
surfaceCondition,
|
|
185813
|
+
anchorOrdinal
|
|
185664
185814
|
});
|
|
185665
185815
|
return ok3(`Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
185666
185816
|
- Content: ${content}
|
|
185667
185817
|
- Condition: ${surfaceCondition}`);
|
|
185668
185818
|
}
|
|
185669
|
-
const note = addNote(deps.db, "session", {
|
|
185819
|
+
const note = addNote(deps.db, "session", {
|
|
185820
|
+
sessionId,
|
|
185821
|
+
content,
|
|
185822
|
+
anchorOrdinal
|
|
185823
|
+
});
|
|
185670
185824
|
return ok3(`Saved session note #${note.id}.`);
|
|
185671
185825
|
}
|
|
185672
185826
|
if (action2 === "dismiss") {
|
|
@@ -185729,9 +185883,13 @@ function createCtxNoteTool(deps) {
|
|
|
185729
185883
|
|
|
185730
185884
|
No notes for the current filter.`);
|
|
185731
185885
|
}
|
|
185732
|
-
|
|
185886
|
+
const body = sections.join(`
|
|
185733
185887
|
|
|
185734
|
-
`)
|
|
185888
|
+
`);
|
|
185889
|
+
const anchorHint = body.includes("↳ @msg ") ? `
|
|
185890
|
+
|
|
185891
|
+
↳ @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).` : "";
|
|
185892
|
+
return ok3(`${body}${anchorHint}${DISMISS_FOOTER}`);
|
|
185735
185893
|
}
|
|
185736
185894
|
};
|
|
185737
185895
|
}
|
|
@@ -186076,7 +186234,8 @@ function createCtxSearchTool(deps) {
|
|
|
186076
186234
|
maxMessageOrdinal: lastCompartmentEnd >= 0 ? lastCompartmentEnd : undefined,
|
|
186077
186235
|
gitCommitsEnabled,
|
|
186078
186236
|
sources: params.sources,
|
|
186079
|
-
visibleMemoryIds
|
|
186237
|
+
visibleMemoryIds,
|
|
186238
|
+
explicitSearch: true
|
|
186080
186239
|
});
|
|
186081
186240
|
return {
|
|
186082
186241
|
content: [{ type: "text", text: formatSearchResults(query, results) }],
|
|
@@ -186224,8 +186383,7 @@ function getPiMessageModel(message) {
|
|
|
186224
186383
|
};
|
|
186225
186384
|
}
|
|
186226
186385
|
function resolvePiPressureContextLimit(args) {
|
|
186227
|
-
|
|
186228
|
-
let effectiveContextLimit = cachedLimit ?? args.piContextWindow;
|
|
186386
|
+
let effectiveContextLimit = isSaneLimit(args.piContextWindow) ? args.piContextWindow : 0;
|
|
186229
186387
|
try {
|
|
186230
186388
|
const overflowState = getOverflowState(args.db, args.sessionId);
|
|
186231
186389
|
if (overflowState.detectedContextLimit > 0) {
|
|
@@ -186241,8 +186399,6 @@ async function persistPiPressureFromMessageEnd(args) {
|
|
|
186241
186399
|
const effectiveContextLimit = resolvePiPressureContextLimit({
|
|
186242
186400
|
db: args.db,
|
|
186243
186401
|
sessionId: args.sessionId,
|
|
186244
|
-
provider: provider2,
|
|
186245
|
-
model,
|
|
186246
186402
|
piContextWindow: args.piContextWindow
|
|
186247
186403
|
});
|
|
186248
186404
|
const usage = extractAssistantUsage(args.message);
|
|
@@ -186251,28 +186407,16 @@ async function persistPiPressureFromMessageEnd(args) {
|
|
|
186251
186407
|
const messageHadOverflowError = typeof msg?.errorMessage === "string" && detectOverflow(msg.errorMessage).isOverflow;
|
|
186252
186408
|
const updates = { lastResponseTime: Date.now() };
|
|
186253
186409
|
if (pressure) {
|
|
186254
|
-
|
|
186255
|
-
|
|
186410
|
+
const percentage = pressure.percentage;
|
|
186411
|
+
const contextLimit = effectiveContextLimit;
|
|
186256
186412
|
const meta3 = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
186257
186413
|
const observedSafeInputTokens = meta3.observedSafeInputTokens ?? 0;
|
|
186258
186414
|
if (percentage > 100 && observedSafeInputTokens > 0 && pressure.inputTokens <= observedSafeInputTokens * 2) {
|
|
186259
|
-
|
|
186260
|
-
clearModelsDevCache();
|
|
186261
|
-
contextLimit = resolvePiPressureContextLimit({
|
|
186262
|
-
db: args.db,
|
|
186263
|
-
sessionId: args.sessionId,
|
|
186264
|
-
provider: provider2,
|
|
186265
|
-
model,
|
|
186266
|
-
piContextWindow: args.piContextWindow
|
|
186267
|
-
});
|
|
186268
|
-
if (contextLimit >= pressure.inputTokens) {
|
|
186269
|
-
percentage = pressure.inputTokens / contextLimit * 100;
|
|
186270
|
-
log(`${PREFIX} models-dev-cache: regression recovered for ${provider2}/${model} via Pi cache reload (was=${oldLimit}, now=${contextLimit})`);
|
|
186271
|
-
} else if (!meta3.cacheAlertSent) {
|
|
186415
|
+
if (!meta3.cacheAlertSent) {
|
|
186272
186416
|
updates.cacheAlertSent = true;
|
|
186273
186417
|
const safeTokens = Math.max(observedSafeInputTokens, pressure.inputTokens);
|
|
186274
186418
|
const modelLabel = provider2 && model ? `${provider2}/${model}` : "the active model";
|
|
186275
|
-
await args.notifyIssue?.(`⚠️ Magic Context: Pi reports a context limit of ${formatTokens(contextLimit)} tokens for ${modelLabel} but you've successfully sent ${formatTokens(safeTokens)} tokens in this session — the
|
|
186419
|
+
await args.notifyIssue?.(`⚠️ Magic Context: Pi reports a context limit of ${formatTokens(contextLimit)} tokens for ${modelLabel} but you've successfully sent ${formatTokens(safeTokens)} tokens in this session — the reported limit looks wrong. Restart Pi if you suspect this is incorrect.`);
|
|
186276
186420
|
}
|
|
186277
186421
|
}
|
|
186278
186422
|
updates.lastContextPercentage = percentage;
|
|
@@ -186710,15 +186854,14 @@ ${block}` : event.systemPrompt;
|
|
|
186710
186854
|
info("session_before_compact: cancelling — magic-context owns compaction");
|
|
186711
186855
|
return { cancel: true };
|
|
186712
186856
|
});
|
|
186713
|
-
const stripTagPrefix3 = createStripTagPrefixHandler(config2.text_complete_strip);
|
|
186714
186857
|
pi.on("message_end", async (event, ctx) => {
|
|
186715
186858
|
try {
|
|
186716
186859
|
const msg = event.message;
|
|
186717
186860
|
if (msg !== null && typeof msg === "object") {
|
|
186718
|
-
|
|
186861
|
+
stripTagPrefixFromAssistantMessage(msg, config2.text_complete_strip);
|
|
186719
186862
|
}
|
|
186720
186863
|
} catch (err5) {
|
|
186721
|
-
warn("message_end:
|
|
186864
|
+
warn("message_end: stripTagPrefixFromAssistantMessage threw:", err5);
|
|
186722
186865
|
}
|
|
186723
186866
|
try {
|
|
186724
186867
|
const sm = ctx.sessionManager;
|
|
@@ -186740,7 +186883,7 @@ ${block}` : event.systemPrompt;
|
|
|
186740
186883
|
cacheTtlConfig: config2.cache_ttl
|
|
186741
186884
|
});
|
|
186742
186885
|
const piUsage = ctx.getContextUsage?.();
|
|
186743
|
-
const piContextWindow = piUsage && typeof piUsage.contextWindow === "number" ? piUsage.contextWindow : 0;
|
|
186886
|
+
const piContextWindow = piUsage && typeof piUsage.contextWindow === "number" && piUsage.contextWindow > 0 ? piUsage.contextWindow : ctx.model?.contextWindow ?? 0;
|
|
186744
186887
|
await persistPiPressureFromMessageEnd({
|
|
186745
186888
|
db,
|
|
186746
186889
|
sessionId,
|