@cortexkit/pi-magic-context 0.22.3 → 0.22.5
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/README.md +1 -3
- package/dist/index.js +985 -582
- package/dist/subagent-entry.js +636 -337
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -46,214 +46,6 @@ var __export = (target, all) => {
|
|
|
46
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
47
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
48
48
|
|
|
49
|
-
// ../plugin/src/shared/harness.ts
|
|
50
|
-
function setHarness(value) {
|
|
51
|
-
if (harnessLocked && currentHarness !== value) {
|
|
52
|
-
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
53
|
-
}
|
|
54
|
-
currentHarness = value;
|
|
55
|
-
harnessLocked = true;
|
|
56
|
-
}
|
|
57
|
-
function getHarness() {
|
|
58
|
-
return currentHarness;
|
|
59
|
-
}
|
|
60
|
-
var currentHarness = "opencode", harnessLocked = false;
|
|
61
|
-
|
|
62
|
-
// ../plugin/src/shared/data-path.ts
|
|
63
|
-
import * as os from "node:os";
|
|
64
|
-
import * as path2 from "node:path";
|
|
65
|
-
function getDataDir() {
|
|
66
|
-
return process.env.XDG_DATA_HOME ?? path2.join(os.homedir(), ".local", "share");
|
|
67
|
-
}
|
|
68
|
-
function getMagicContextTempDir(harness = getHarness()) {
|
|
69
|
-
return path2.join(os.tmpdir(), harness, "magic-context");
|
|
70
|
-
}
|
|
71
|
-
function getMagicContextLogPath(harness = getHarness()) {
|
|
72
|
-
return path2.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
73
|
-
}
|
|
74
|
-
function getProjectMagicContextDir(directory) {
|
|
75
|
-
return path2.join(directory, ".opencode", "magic-context");
|
|
76
|
-
}
|
|
77
|
-
function getProjectMagicContextHistorianDir(directory) {
|
|
78
|
-
return path2.join(getProjectMagicContextDir(directory), "historian");
|
|
79
|
-
}
|
|
80
|
-
function getOpenCodeStorageDir() {
|
|
81
|
-
return path2.join(getDataDir(), "opencode", "storage");
|
|
82
|
-
}
|
|
83
|
-
function getMagicContextStorageDir() {
|
|
84
|
-
return path2.join(getDataDir(), "cortexkit", "magic-context");
|
|
85
|
-
}
|
|
86
|
-
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
87
|
-
return path2.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
88
|
-
}
|
|
89
|
-
var init_data_path = () => {};
|
|
90
|
-
|
|
91
|
-
// ../plugin/src/shared/logger.ts
|
|
92
|
-
import * as fs from "node:fs";
|
|
93
|
-
import * as path3 from "node:path";
|
|
94
|
-
function ensureDir(filePath) {
|
|
95
|
-
const dir = path3.dirname(filePath);
|
|
96
|
-
if (dir === lastEnsuredDir)
|
|
97
|
-
return;
|
|
98
|
-
try {
|
|
99
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
100
|
-
lastEnsuredDir = dir;
|
|
101
|
-
} catch {}
|
|
102
|
-
}
|
|
103
|
-
function flush() {
|
|
104
|
-
if (flushTimer) {
|
|
105
|
-
clearTimeout(flushTimer);
|
|
106
|
-
flushTimer = null;
|
|
107
|
-
}
|
|
108
|
-
if (buffer.length === 0)
|
|
109
|
-
return;
|
|
110
|
-
const data = buffer.join("");
|
|
111
|
-
buffer = [];
|
|
112
|
-
try {
|
|
113
|
-
const logFile = getMagicContextLogPath();
|
|
114
|
-
ensureDir(logFile);
|
|
115
|
-
fs.appendFileSync(logFile, data);
|
|
116
|
-
} catch {}
|
|
117
|
-
}
|
|
118
|
-
function scheduleFlush() {
|
|
119
|
-
if (flushTimer)
|
|
120
|
-
return;
|
|
121
|
-
flushTimer = setTimeout(() => {
|
|
122
|
-
flushTimer = null;
|
|
123
|
-
flush();
|
|
124
|
-
}, FLUSH_INTERVAL_MS);
|
|
125
|
-
}
|
|
126
|
-
function log(message, data) {
|
|
127
|
-
if (isTestEnv)
|
|
128
|
-
return;
|
|
129
|
-
try {
|
|
130
|
-
const timestamp = new Date().toISOString();
|
|
131
|
-
const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
|
|
132
|
-
${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
133
|
-
buffer.push(`[${timestamp}] ${message}${serialized}
|
|
134
|
-
`);
|
|
135
|
-
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
136
|
-
flush();
|
|
137
|
-
} else {
|
|
138
|
-
scheduleFlush();
|
|
139
|
-
}
|
|
140
|
-
} catch {}
|
|
141
|
-
}
|
|
142
|
-
function sessionLog(sessionId, message, data) {
|
|
143
|
-
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
144
|
-
}
|
|
145
|
-
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
|
|
146
|
-
var init_logger = __esm(() => {
|
|
147
|
-
init_data_path();
|
|
148
|
-
buffer = [];
|
|
149
|
-
if (!isTestEnv) {
|
|
150
|
-
process.on("exit", flush);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// ../plugin/src/shared/sqlite.ts
|
|
155
|
-
function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
156
|
-
const SAVEPOINT = "mc_tx_sp";
|
|
157
|
-
|
|
158
|
-
class NodeSqliteDatabase extends DatabaseSync {
|
|
159
|
-
constructor(filename, options) {
|
|
160
|
-
const translated = { ...options };
|
|
161
|
-
if (options && "readonly" in options) {
|
|
162
|
-
translated.readOnly = options.readonly;
|
|
163
|
-
delete translated.readonly;
|
|
164
|
-
}
|
|
165
|
-
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
166
|
-
}
|
|
167
|
-
transaction(fn) {
|
|
168
|
-
const self = this;
|
|
169
|
-
const wrapped = function(...args) {
|
|
170
|
-
const nested = self.isTransaction === true;
|
|
171
|
-
self.exec(nested ? `SAVEPOINT ${SAVEPOINT}` : "BEGIN");
|
|
172
|
-
try {
|
|
173
|
-
const result = fn.apply(this, args);
|
|
174
|
-
self.exec(nested ? `RELEASE ${SAVEPOINT}` : "COMMIT");
|
|
175
|
-
return result;
|
|
176
|
-
} catch (error) {
|
|
177
|
-
if (nested) {
|
|
178
|
-
self.exec(`ROLLBACK TO ${SAVEPOINT}`);
|
|
179
|
-
self.exec(`RELEASE ${SAVEPOINT}`);
|
|
180
|
-
} else {
|
|
181
|
-
self.exec("ROLLBACK");
|
|
182
|
-
}
|
|
183
|
-
throw error;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
return wrapped;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return NodeSqliteDatabase;
|
|
190
|
-
}
|
|
191
|
-
var isBun, bunSpec, nodeSpec, sqliteModule, DatabaseImpl, Database;
|
|
192
|
-
var init_sqlite = __esm(async () => {
|
|
193
|
-
isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
194
|
-
bunSpec = "bun:" + "sqlite";
|
|
195
|
-
nodeSpec = "node:" + "sqlite";
|
|
196
|
-
sqliteModule = isBun ? await import(bunSpec) : await import(nodeSpec);
|
|
197
|
-
DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
198
|
-
Database = DatabaseImpl;
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// ../plugin/src/shared/sqlite-helpers.ts
|
|
202
|
-
function closeQuietly(db) {
|
|
203
|
-
if (!db)
|
|
204
|
-
return;
|
|
205
|
-
try {
|
|
206
|
-
db.close();
|
|
207
|
-
} catch {}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// ../plugin/src/hooks/magic-context/read-session-db.ts
|
|
211
|
-
import { existsSync } from "node:fs";
|
|
212
|
-
import { join as join2 } from "node:path";
|
|
213
|
-
function getOpenCodeDbPath() {
|
|
214
|
-
return join2(getDataDir(), "opencode", "opencode.db");
|
|
215
|
-
}
|
|
216
|
-
function openCodeDbExists() {
|
|
217
|
-
return existsSync(getOpenCodeDbPath());
|
|
218
|
-
}
|
|
219
|
-
function closeCachedReadOnlyDb() {
|
|
220
|
-
if (!cachedReadOnlyDb) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
try {
|
|
224
|
-
closeQuietly(cachedReadOnlyDb.db);
|
|
225
|
-
} catch (error) {
|
|
226
|
-
log("[magic-context] failed to close cached OpenCode read-only DB:", error);
|
|
227
|
-
} finally {
|
|
228
|
-
cachedReadOnlyDb = null;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
function getReadOnlySessionDb() {
|
|
232
|
-
const dbPath = getOpenCodeDbPath();
|
|
233
|
-
if (cachedReadOnlyDb?.path === dbPath) {
|
|
234
|
-
return cachedReadOnlyDb.db;
|
|
235
|
-
}
|
|
236
|
-
closeCachedReadOnlyDb();
|
|
237
|
-
const db = new Database(dbPath, { readonly: true });
|
|
238
|
-
cachedReadOnlyDb = { path: dbPath, db };
|
|
239
|
-
return db;
|
|
240
|
-
}
|
|
241
|
-
function withReadOnlySessionDb(fn) {
|
|
242
|
-
return fn(getReadOnlySessionDb());
|
|
243
|
-
}
|
|
244
|
-
function getRawSessionMessageCountFromDb(db, sessionId) {
|
|
245
|
-
const row = db.prepare(`SELECT COUNT(*) as count FROM message WHERE session_id = ?
|
|
246
|
-
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
247
|
-
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')`).get(sessionId);
|
|
248
|
-
return typeof row?.count === "number" ? row.count : 0;
|
|
249
|
-
}
|
|
250
|
-
var cachedReadOnlyDb = null;
|
|
251
|
-
var init_read_session_db = __esm(async () => {
|
|
252
|
-
init_data_path();
|
|
253
|
-
init_logger();
|
|
254
|
-
await init_sqlite();
|
|
255
|
-
});
|
|
256
|
-
|
|
257
49
|
// ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
|
|
258
50
|
var require_esprima = __commonJS((exports, module) => {
|
|
259
51
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
@@ -8281,9 +8073,129 @@ function hasGitDir(canonical) {
|
|
|
8281
8073
|
return false;
|
|
8282
8074
|
}
|
|
8283
8075
|
}
|
|
8076
|
+
function normalizeStoredProjectPath(rawOrStored) {
|
|
8077
|
+
if (rawOrStored.startsWith("git:") || rawOrStored.startsWith("dir:")) {
|
|
8078
|
+
return rawOrStored;
|
|
8079
|
+
}
|
|
8080
|
+
try {
|
|
8081
|
+
return resolveProjectIdentity(rawOrStored);
|
|
8082
|
+
} catch {
|
|
8083
|
+
return directoryFallback(rawOrStored);
|
|
8084
|
+
}
|
|
8085
|
+
}
|
|
8086
|
+
function storedPathBelongsToIdentity(storedProjectPath, projectIdentity) {
|
|
8087
|
+
return storedProjectPath === projectIdentity || normalizeStoredProjectPath(storedProjectPath) === projectIdentity;
|
|
8088
|
+
}
|
|
8284
8089
|
|
|
8285
|
-
// ../plugin/src/
|
|
8286
|
-
|
|
8090
|
+
// ../plugin/src/shared/logger.ts
|
|
8091
|
+
import * as fs from "node:fs";
|
|
8092
|
+
import * as path3 from "node:path";
|
|
8093
|
+
|
|
8094
|
+
// ../plugin/src/shared/data-path.ts
|
|
8095
|
+
import * as os from "node:os";
|
|
8096
|
+
import * as path2 from "node:path";
|
|
8097
|
+
|
|
8098
|
+
// ../plugin/src/shared/harness.ts
|
|
8099
|
+
var currentHarness = "opencode";
|
|
8100
|
+
var harnessLocked = false;
|
|
8101
|
+
function setHarness(value) {
|
|
8102
|
+
if (harnessLocked && currentHarness !== value) {
|
|
8103
|
+
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
8104
|
+
}
|
|
8105
|
+
currentHarness = value;
|
|
8106
|
+
harnessLocked = true;
|
|
8107
|
+
}
|
|
8108
|
+
function getHarness() {
|
|
8109
|
+
return currentHarness;
|
|
8110
|
+
}
|
|
8111
|
+
|
|
8112
|
+
// ../plugin/src/shared/data-path.ts
|
|
8113
|
+
function getDataDir() {
|
|
8114
|
+
return process.env.XDG_DATA_HOME ?? path2.join(os.homedir(), ".local", "share");
|
|
8115
|
+
}
|
|
8116
|
+
function getMagicContextTempDir(harness = getHarness()) {
|
|
8117
|
+
return path2.join(os.tmpdir(), harness, "magic-context");
|
|
8118
|
+
}
|
|
8119
|
+
function getMagicContextLogPath(harness = getHarness()) {
|
|
8120
|
+
return path2.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
8121
|
+
}
|
|
8122
|
+
function getProjectMagicContextDir(directory) {
|
|
8123
|
+
return path2.join(directory, ".opencode", "magic-context");
|
|
8124
|
+
}
|
|
8125
|
+
function getProjectMagicContextHistorianDir(directory) {
|
|
8126
|
+
return path2.join(getProjectMagicContextDir(directory), "historian");
|
|
8127
|
+
}
|
|
8128
|
+
function getOpenCodeStorageDir() {
|
|
8129
|
+
return path2.join(getDataDir(), "opencode", "storage");
|
|
8130
|
+
}
|
|
8131
|
+
function getMagicContextStorageDir() {
|
|
8132
|
+
return path2.join(getDataDir(), "cortexkit", "magic-context");
|
|
8133
|
+
}
|
|
8134
|
+
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
8135
|
+
return path2.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
8136
|
+
}
|
|
8137
|
+
|
|
8138
|
+
// ../plugin/src/shared/logger.ts
|
|
8139
|
+
var isTestEnv = false;
|
|
8140
|
+
var buffer = [];
|
|
8141
|
+
var flushTimer = null;
|
|
8142
|
+
var FLUSH_INTERVAL_MS = 500;
|
|
8143
|
+
var BUFFER_SIZE_LIMIT = 50;
|
|
8144
|
+
var lastEnsuredDir = null;
|
|
8145
|
+
function ensureDir(filePath) {
|
|
8146
|
+
const dir = path3.dirname(filePath);
|
|
8147
|
+
if (dir === lastEnsuredDir)
|
|
8148
|
+
return;
|
|
8149
|
+
try {
|
|
8150
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
8151
|
+
lastEnsuredDir = dir;
|
|
8152
|
+
} catch {}
|
|
8153
|
+
}
|
|
8154
|
+
function flush() {
|
|
8155
|
+
if (flushTimer) {
|
|
8156
|
+
clearTimeout(flushTimer);
|
|
8157
|
+
flushTimer = null;
|
|
8158
|
+
}
|
|
8159
|
+
if (buffer.length === 0)
|
|
8160
|
+
return;
|
|
8161
|
+
const data = buffer.join("");
|
|
8162
|
+
buffer = [];
|
|
8163
|
+
try {
|
|
8164
|
+
const logFile = getMagicContextLogPath();
|
|
8165
|
+
ensureDir(logFile);
|
|
8166
|
+
fs.appendFileSync(logFile, data);
|
|
8167
|
+
} catch {}
|
|
8168
|
+
}
|
|
8169
|
+
function scheduleFlush() {
|
|
8170
|
+
if (flushTimer)
|
|
8171
|
+
return;
|
|
8172
|
+
flushTimer = setTimeout(() => {
|
|
8173
|
+
flushTimer = null;
|
|
8174
|
+
flush();
|
|
8175
|
+
}, FLUSH_INTERVAL_MS);
|
|
8176
|
+
}
|
|
8177
|
+
function log(message, data) {
|
|
8178
|
+
if (isTestEnv)
|
|
8179
|
+
return;
|
|
8180
|
+
try {
|
|
8181
|
+
const timestamp = new Date().toISOString();
|
|
8182
|
+
const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
|
|
8183
|
+
${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
8184
|
+
buffer.push(`[${timestamp}] ${message}${serialized}
|
|
8185
|
+
`);
|
|
8186
|
+
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
8187
|
+
flush();
|
|
8188
|
+
} else {
|
|
8189
|
+
scheduleFlush();
|
|
8190
|
+
}
|
|
8191
|
+
} catch {}
|
|
8192
|
+
}
|
|
8193
|
+
function sessionLog(sessionId, message, data) {
|
|
8194
|
+
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
8195
|
+
}
|
|
8196
|
+
if (!isTestEnv) {
|
|
8197
|
+
process.on("exit", flush);
|
|
8198
|
+
}
|
|
8287
8199
|
|
|
8288
8200
|
// ../plugin/src/shared/internal-initiator-marker.ts
|
|
8289
8201
|
var OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->";
|
|
@@ -8297,8 +8209,102 @@ function removeSystemReminders(text) {
|
|
|
8297
8209
|
return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/gi, "").trim();
|
|
8298
8210
|
}
|
|
8299
8211
|
|
|
8300
|
-
// ../plugin/src/hooks/magic-context/read-session-
|
|
8301
|
-
|
|
8212
|
+
// ../plugin/src/hooks/magic-context/read-session-db.ts
|
|
8213
|
+
import { existsSync } from "node:fs";
|
|
8214
|
+
import { join as join2 } from "node:path";
|
|
8215
|
+
|
|
8216
|
+
// ../plugin/src/shared/sqlite.ts
|
|
8217
|
+
var isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
8218
|
+
var bunSpec = "bun:" + "sqlite";
|
|
8219
|
+
var nodeSpec = "node:" + "sqlite";
|
|
8220
|
+
var sqliteModule = isBun ? await import(bunSpec) : await import(nodeSpec);
|
|
8221
|
+
var DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
8222
|
+
function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
8223
|
+
const SAVEPOINT = "mc_tx_sp";
|
|
8224
|
+
|
|
8225
|
+
class NodeSqliteDatabase extends DatabaseSync {
|
|
8226
|
+
constructor(filename, options) {
|
|
8227
|
+
const translated = { ...options };
|
|
8228
|
+
if (options && "readonly" in options) {
|
|
8229
|
+
translated.readOnly = options.readonly;
|
|
8230
|
+
delete translated.readonly;
|
|
8231
|
+
}
|
|
8232
|
+
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
8233
|
+
}
|
|
8234
|
+
transaction(fn) {
|
|
8235
|
+
const self = this;
|
|
8236
|
+
const wrapped = function(...args) {
|
|
8237
|
+
const nested = self.isTransaction === true;
|
|
8238
|
+
self.exec(nested ? `SAVEPOINT ${SAVEPOINT}` : "BEGIN");
|
|
8239
|
+
try {
|
|
8240
|
+
const result = fn.apply(this, args);
|
|
8241
|
+
self.exec(nested ? `RELEASE ${SAVEPOINT}` : "COMMIT");
|
|
8242
|
+
return result;
|
|
8243
|
+
} catch (error) {
|
|
8244
|
+
if (nested) {
|
|
8245
|
+
self.exec(`ROLLBACK TO ${SAVEPOINT}`);
|
|
8246
|
+
self.exec(`RELEASE ${SAVEPOINT}`);
|
|
8247
|
+
} else {
|
|
8248
|
+
self.exec("ROLLBACK");
|
|
8249
|
+
}
|
|
8250
|
+
throw error;
|
|
8251
|
+
}
|
|
8252
|
+
};
|
|
8253
|
+
return wrapped;
|
|
8254
|
+
}
|
|
8255
|
+
}
|
|
8256
|
+
return NodeSqliteDatabase;
|
|
8257
|
+
}
|
|
8258
|
+
var Database = DatabaseImpl;
|
|
8259
|
+
|
|
8260
|
+
// ../plugin/src/shared/sqlite-helpers.ts
|
|
8261
|
+
function closeQuietly(db) {
|
|
8262
|
+
if (!db)
|
|
8263
|
+
return;
|
|
8264
|
+
try {
|
|
8265
|
+
db.close();
|
|
8266
|
+
} catch {}
|
|
8267
|
+
}
|
|
8268
|
+
|
|
8269
|
+
// ../plugin/src/hooks/magic-context/read-session-db.ts
|
|
8270
|
+
function getOpenCodeDbPath() {
|
|
8271
|
+
return join2(getDataDir(), "opencode", "opencode.db");
|
|
8272
|
+
}
|
|
8273
|
+
function openCodeDbExists() {
|
|
8274
|
+
return existsSync(getOpenCodeDbPath());
|
|
8275
|
+
}
|
|
8276
|
+
var cachedReadOnlyDb = null;
|
|
8277
|
+
function closeCachedReadOnlyDb() {
|
|
8278
|
+
if (!cachedReadOnlyDb) {
|
|
8279
|
+
return;
|
|
8280
|
+
}
|
|
8281
|
+
try {
|
|
8282
|
+
closeQuietly(cachedReadOnlyDb.db);
|
|
8283
|
+
} catch (error) {
|
|
8284
|
+
log("[magic-context] failed to close cached OpenCode read-only DB:", error);
|
|
8285
|
+
} finally {
|
|
8286
|
+
cachedReadOnlyDb = null;
|
|
8287
|
+
}
|
|
8288
|
+
}
|
|
8289
|
+
function getReadOnlySessionDb() {
|
|
8290
|
+
const dbPath = getOpenCodeDbPath();
|
|
8291
|
+
if (cachedReadOnlyDb?.path === dbPath) {
|
|
8292
|
+
return cachedReadOnlyDb.db;
|
|
8293
|
+
}
|
|
8294
|
+
closeCachedReadOnlyDb();
|
|
8295
|
+
const db = new Database(dbPath, { readonly: true });
|
|
8296
|
+
cachedReadOnlyDb = { path: dbPath, db };
|
|
8297
|
+
return db;
|
|
8298
|
+
}
|
|
8299
|
+
function withReadOnlySessionDb(fn) {
|
|
8300
|
+
return fn(getReadOnlySessionDb());
|
|
8301
|
+
}
|
|
8302
|
+
function getRawSessionMessageCountFromDb(db, sessionId) {
|
|
8303
|
+
const row = db.prepare(`SELECT COUNT(*) as count FROM message WHERE session_id = ?
|
|
8304
|
+
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
8305
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')`).get(sessionId);
|
|
8306
|
+
return typeof row?.count === "number" ? row.count : 0;
|
|
8307
|
+
}
|
|
8302
8308
|
|
|
8303
8309
|
// ../../node_modules/.bun/ai-tokenizer@1.0.6/node_modules/ai-tokenizer/dist/index.js
|
|
8304
8310
|
function _typeof(o) {
|
|
@@ -141342,6 +141348,7 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
141342
141348
|
toolOnlyRanges
|
|
141343
141349
|
};
|
|
141344
141350
|
}
|
|
141351
|
+
|
|
141345
141352
|
// ../plugin/src/features/magic-context/compression-depth-storage.ts
|
|
141346
141353
|
var incrementDepthStatements = new WeakMap;
|
|
141347
141354
|
var totalDepthStatements = new WeakMap;
|
|
@@ -141745,6 +141752,7 @@ function parseReportedLimit(message) {
|
|
|
141745
141752
|
}
|
|
141746
141753
|
return;
|
|
141747
141754
|
}
|
|
141755
|
+
|
|
141748
141756
|
// ../plugin/src/features/magic-context/compartment-lease.ts
|
|
141749
141757
|
var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
141750
141758
|
var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
|
|
@@ -141815,6 +141823,9 @@ var SESSION_META_SELECT_COLUMNS = [
|
|
|
141815
141823
|
"cached_m0_materialized_at",
|
|
141816
141824
|
"cached_m0_session_facts_version",
|
|
141817
141825
|
"cached_m0_upgrade_state",
|
|
141826
|
+
"cached_m0_system_hash",
|
|
141827
|
+
"cached_m0_tool_set_hash",
|
|
141828
|
+
"cached_m0_model_key",
|
|
141818
141829
|
"last_observed_model_key",
|
|
141819
141830
|
"upgrade_reminded_at",
|
|
141820
141831
|
"pi_stable_id_scheme"
|
|
@@ -141851,6 +141862,9 @@ var META_COLUMNS = {
|
|
|
141851
141862
|
cachedM0MaterializedAt: "cached_m0_materialized_at",
|
|
141852
141863
|
cachedM0SessionFactsVersion: "cached_m0_session_facts_version",
|
|
141853
141864
|
cachedM0UpgradeState: "cached_m0_upgrade_state",
|
|
141865
|
+
cachedM0SystemHash: "cached_m0_system_hash",
|
|
141866
|
+
cachedM0ToolSetHash: "cached_m0_tool_set_hash",
|
|
141867
|
+
cachedM0ModelKey: "cached_m0_model_key",
|
|
141854
141868
|
lastObservedModelKey: "last_observed_model_key",
|
|
141855
141869
|
upgradeRemindedAt: "upgrade_reminded_at",
|
|
141856
141870
|
piStableIdScheme: "pi_stable_id_scheme"
|
|
@@ -141893,7 +141907,7 @@ function isSessionMetaRow(row) {
|
|
|
141893
141907
|
if (row === null || typeof row !== "object")
|
|
141894
141908
|
return false;
|
|
141895
141909
|
const r = row;
|
|
141896
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
141910
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
141897
141911
|
}
|
|
141898
141912
|
function getDefaultSessionMeta(sessionId) {
|
|
141899
141913
|
return {
|
|
@@ -141929,6 +141943,9 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
141929
141943
|
cachedM0MaterializedAt: null,
|
|
141930
141944
|
cachedM0SessionFactsVersion: null,
|
|
141931
141945
|
cachedM0UpgradeState: null,
|
|
141946
|
+
cachedM0SystemHash: null,
|
|
141947
|
+
cachedM0ToolSetHash: null,
|
|
141948
|
+
cachedM0ModelKey: null,
|
|
141932
141949
|
lastObservedModelKey: null,
|
|
141933
141950
|
upgradeRemindedAt: null,
|
|
141934
141951
|
piStableIdScheme: null
|
|
@@ -141980,6 +141997,9 @@ function toSessionMeta(row) {
|
|
|
141980
141997
|
cachedM0MaterializedAt: numOrNull(row.cached_m0_materialized_at),
|
|
141981
141998
|
cachedM0SessionFactsVersion: numOrNull(row.cached_m0_session_facts_version),
|
|
141982
141999
|
cachedM0UpgradeState: stringOrNull(row.cached_m0_upgrade_state),
|
|
142000
|
+
cachedM0SystemHash: stringOrNull(row.cached_m0_system_hash),
|
|
142001
|
+
cachedM0ToolSetHash: stringOrNull(row.cached_m0_tool_set_hash),
|
|
142002
|
+
cachedM0ModelKey: stringOrNull(row.cached_m0_model_key),
|
|
141983
142003
|
lastObservedModelKey: stringOrNull(row.last_observed_model_key),
|
|
141984
142004
|
upgradeRemindedAt: numOrNull(row.upgrade_reminded_at),
|
|
141985
142005
|
piStableIdScheme: numOrNull(row.pi_stable_id_scheme)
|
|
@@ -141999,8 +142019,11 @@ function persistCachedM0(db, sessionId, payload) {
|
|
|
141999
142019
|
cached_m0_project_docs_hash = ?,
|
|
142000
142020
|
cached_m0_materialized_at = ?,
|
|
142001
142021
|
cached_m0_session_facts_version = ?,
|
|
142002
|
-
cached_m0_upgrade_state =
|
|
142003
|
-
|
|
142022
|
+
cached_m0_upgrade_state = ?,
|
|
142023
|
+
cached_m0_system_hash = ?,
|
|
142024
|
+
cached_m0_tool_set_hash = ?,
|
|
142025
|
+
cached_m0_model_key = ?
|
|
142026
|
+
WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.projectMemoryEpoch, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.toolSetHash ?? "", payload.modelKey ?? "", sessionId);
|
|
142004
142027
|
}
|
|
142005
142028
|
function clearCachedM0M1(db, sessionId) {
|
|
142006
142029
|
ensureSessionMetaRow(db, sessionId);
|
|
@@ -142018,6 +142041,9 @@ function clearCachedM0M1(db, sessionId) {
|
|
|
142018
142041
|
["cached_m0_materialized_at", null],
|
|
142019
142042
|
["cached_m0_session_facts_version", null],
|
|
142020
142043
|
["cached_m0_upgrade_state", null],
|
|
142044
|
+
["cached_m0_system_hash", null],
|
|
142045
|
+
["cached_m0_tool_set_hash", null],
|
|
142046
|
+
["cached_m0_model_key", null],
|
|
142021
142047
|
["cached_m0_last_baseline_end_message_id", null],
|
|
142022
142048
|
["memory_block_cache", ""],
|
|
142023
142049
|
["memory_block_count", 0],
|
|
@@ -142059,12 +142085,6 @@ function isCompartmentRow(row) {
|
|
|
142059
142085
|
const candidate = row;
|
|
142060
142086
|
return typeof candidate.id === "number" && typeof candidate.session_id === "string" && typeof candidate.sequence === "number" && typeof candidate.start_message === "number" && typeof candidate.end_message === "number" && typeof candidate.start_message_id === "string" && typeof candidate.end_message_id === "string" && typeof candidate.title === "string" && typeof candidate.content === "string" && isStringOrNullish(candidate.p1) && isStringOrNullish(candidate.p2) && isStringOrNullish(candidate.p3) && isStringOrNullish(candidate.p4) && isNumberOrNullish(candidate.importance) && isStringOrNullish(candidate.episode_type) && isNumberOrNullish(candidate.legacy) && typeof candidate.created_at === "number";
|
|
142061
142087
|
}
|
|
142062
|
-
function isSessionFactRow(row) {
|
|
142063
|
-
if (row === null || typeof row !== "object")
|
|
142064
|
-
return false;
|
|
142065
|
-
const candidate = row;
|
|
142066
|
-
return typeof candidate.id === "number" && typeof candidate.session_id === "string" && typeof candidate.category === "string" && typeof candidate.content === "string" && typeof candidate.created_at === "number" && typeof candidate.updated_at === "number";
|
|
142067
|
-
}
|
|
142068
142088
|
function insertCompartmentRows(db, sessionId, compartments, now) {
|
|
142069
142089
|
const stmt = getInsertCompartmentStatement(db);
|
|
142070
142090
|
for (const compartment of compartments) {
|
|
@@ -142093,16 +142113,6 @@ function toCompartment(row) {
|
|
|
142093
142113
|
createdAt: row.created_at
|
|
142094
142114
|
};
|
|
142095
142115
|
}
|
|
142096
|
-
function toSessionFact(row) {
|
|
142097
|
-
return {
|
|
142098
|
-
id: row.id,
|
|
142099
|
-
sessionId: row.session_id,
|
|
142100
|
-
category: row.category,
|
|
142101
|
-
content: row.content,
|
|
142102
|
-
createdAt: row.created_at,
|
|
142103
|
-
updatedAt: row.updated_at
|
|
142104
|
-
};
|
|
142105
|
-
}
|
|
142106
142116
|
function getCompartments(db, sessionId) {
|
|
142107
142117
|
const rows = db.prepare("SELECT * FROM compartments WHERE session_id = ? ORDER BY sequence ASC").all(sessionId).filter(isCompartmentRow);
|
|
142108
142118
|
return rows.map(toCompartment);
|
|
@@ -142123,10 +142133,6 @@ function appendCompartments(db, sessionId, compartments) {
|
|
|
142123
142133
|
insertCompartmentRows(db, sessionId, compartments, now);
|
|
142124
142134
|
})();
|
|
142125
142135
|
}
|
|
142126
|
-
function getSessionFacts(db, sessionId) {
|
|
142127
|
-
const rows = db.prepare("SELECT * FROM session_facts WHERE session_id = ? ORDER BY category ASC, id ASC").all(sessionId).filter(isSessionFactRow);
|
|
142128
|
-
return rows.map(toSessionFact);
|
|
142129
|
-
}
|
|
142130
142136
|
function saveRecompStagingPass(db, sessionId, passNumber, compartments, facts) {
|
|
142131
142137
|
const now = Date.now();
|
|
142132
142138
|
db.transaction(() => {
|
|
@@ -142170,14 +142176,6 @@ function getRecompStaging(db, sessionId) {
|
|
|
142170
142176
|
lastEndMessage: lastEnd
|
|
142171
142177
|
};
|
|
142172
142178
|
}
|
|
142173
|
-
function invalidateAllMemoryBlockCaches(db) {
|
|
142174
|
-
try {
|
|
142175
|
-
const rows = db.prepare("SELECT session_id FROM session_meta").all();
|
|
142176
|
-
for (const row of rows) {
|
|
142177
|
-
clearCachedM0M1(db, row.session_id);
|
|
142178
|
-
}
|
|
142179
|
-
} catch {}
|
|
142180
|
-
}
|
|
142181
142179
|
function clearRecompStaging(db, sessionId) {
|
|
142182
142180
|
db.transaction(() => {
|
|
142183
142181
|
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
@@ -142223,11 +142221,7 @@ function escapeXmlAttr(s) {
|
|
|
142223
142221
|
function escapeXmlContent(s) {
|
|
142224
142222
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
142225
142223
|
}
|
|
142226
|
-
// ../plugin/src/features/magic-context/migrations.ts
|
|
142227
|
-
init_logger();
|
|
142228
|
-
|
|
142229
142224
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
142230
|
-
init_data_path();
|
|
142231
142225
|
import { copyFileSync, cpSync, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "node:fs";
|
|
142232
142226
|
import { dirname as dirname2, join as join5 } from "node:path";
|
|
142233
142227
|
|
|
@@ -142307,12 +142301,7 @@ function safeString(value) {
|
|
|
142307
142301
|
}
|
|
142308
142302
|
}
|
|
142309
142303
|
|
|
142310
|
-
// ../plugin/src/features/magic-context/storage-db.ts
|
|
142311
|
-
init_logger();
|
|
142312
|
-
await init_sqlite();
|
|
142313
|
-
|
|
142314
142304
|
// ../plugin/src/features/magic-context/key-files/project-key-files.ts
|
|
142315
|
-
init_logger();
|
|
142316
142305
|
import { createHash as createHash2 } from "node:crypto";
|
|
142317
142306
|
import { existsSync as existsSync2, readFileSync, realpathSync } from "node:fs";
|
|
142318
142307
|
import { join as join3, resolve, sep } from "node:path";
|
|
@@ -142482,8 +142471,6 @@ function loadToolDefinitionMeasurements(db) {
|
|
|
142482
142471
|
}
|
|
142483
142472
|
|
|
142484
142473
|
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
142485
|
-
init_data_path();
|
|
142486
|
-
init_logger();
|
|
142487
142474
|
import { existsSync as existsSync3 } from "node:fs";
|
|
142488
142475
|
import { join as join4 } from "node:path";
|
|
142489
142476
|
var LEASE_DURATION_MS = 5 * 60 * 1000;
|
|
@@ -142731,7 +142718,7 @@ var databases = new Map;
|
|
|
142731
142718
|
var persistenceByDatabase = new WeakMap;
|
|
142732
142719
|
var persistenceErrorByDatabase = new WeakMap;
|
|
142733
142720
|
var lastSchemaFenceRejection = null;
|
|
142734
|
-
var LATEST_SUPPORTED_VERSION =
|
|
142721
|
+
var LATEST_SUPPORTED_VERSION = 30;
|
|
142735
142722
|
function resolveDatabasePath(dbPathOverride) {
|
|
142736
142723
|
if (dbPathOverride) {
|
|
142737
142724
|
return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
|
|
@@ -143196,6 +143183,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143196
143183
|
cached_m0_materialized_at INTEGER,
|
|
143197
143184
|
cached_m0_session_facts_version INTEGER,
|
|
143198
143185
|
cached_m0_upgrade_state TEXT,
|
|
143186
|
+
cached_m0_system_hash TEXT,
|
|
143187
|
+
cached_m0_tool_set_hash TEXT,
|
|
143188
|
+
cached_m0_model_key TEXT,
|
|
143199
143189
|
cached_m0_last_baseline_end_message_id TEXT,
|
|
143200
143190
|
upgrade_reminded_at INTEGER,
|
|
143201
143191
|
pi_stable_id_scheme INTEGER
|
|
@@ -143326,6 +143316,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143326
143316
|
ensureColumn(db, "session_meta", "system_prompt_hash", "TEXT DEFAULT ''");
|
|
143327
143317
|
ensureColumn(db, "session_meta", "cleared_reasoning_through_tag", "INTEGER DEFAULT 0");
|
|
143328
143318
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
143319
|
+
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
143329
143320
|
ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
|
|
143330
143321
|
ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
|
|
143331
143322
|
ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
|
|
@@ -143387,6 +143378,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143387
143378
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
143388
143379
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
143389
143380
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
143381
|
+
ensureColumn(db, "session_meta", "cached_m0_system_hash", "TEXT");
|
|
143382
|
+
ensureColumn(db, "session_meta", "cached_m0_tool_set_hash", "TEXT");
|
|
143383
|
+
ensureColumn(db, "session_meta", "cached_m0_model_key", "TEXT");
|
|
143390
143384
|
ensureColumn(db, "session_meta", "cached_m0_last_baseline_end_message_id", "TEXT");
|
|
143391
143385
|
ensureColumn(db, "session_meta", "upgrade_reminded_at", "INTEGER");
|
|
143392
143386
|
db.exec(`
|
|
@@ -143473,6 +143467,7 @@ function healNullTextColumns(db) {
|
|
|
143473
143467
|
["todo_synthetic_state_json", ""],
|
|
143474
143468
|
["system_prompt_hash", ""],
|
|
143475
143469
|
["stripped_placeholder_ids", ""],
|
|
143470
|
+
["stale_reduce_stripped_ids", ""],
|
|
143476
143471
|
["memory_block_cache", ""],
|
|
143477
143472
|
["memory_block_ids", ""],
|
|
143478
143473
|
["compaction_marker_state", ""],
|
|
@@ -144316,6 +144311,28 @@ var MIGRATIONS = [
|
|
|
144316
144311
|
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
144317
144312
|
}
|
|
144318
144313
|
}
|
|
144314
|
+
},
|
|
144315
|
+
{
|
|
144316
|
+
version: 30,
|
|
144317
|
+
description: "HARD-bust m[0] markers: cached system/tool-set/model identity",
|
|
144318
|
+
up: (db) => {
|
|
144319
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta' LIMIT 1").get();
|
|
144320
|
+
if (!hasSessionMeta)
|
|
144321
|
+
return;
|
|
144322
|
+
ensureColumn(db, "session_meta", "cached_m0_system_hash", "TEXT");
|
|
144323
|
+
ensureColumn(db, "session_meta", "cached_m0_tool_set_hash", "TEXT");
|
|
144324
|
+
ensureColumn(db, "session_meta", "cached_m0_model_key", "TEXT");
|
|
144325
|
+
const columns = new Set(db.prepare("PRAGMA table_info(session_meta)").all().map((column) => column.name));
|
|
144326
|
+
if (columns.has("cached_m0_bytes")) {
|
|
144327
|
+
db.prepare(`UPDATE session_meta SET
|
|
144328
|
+
cached_m0_bytes = NULL,
|
|
144329
|
+
cached_m1_bytes = NULL,
|
|
144330
|
+
cached_m0_materialized_at = NULL,
|
|
144331
|
+
cached_m0_system_hash = NULL,
|
|
144332
|
+
cached_m0_tool_set_hash = NULL,
|
|
144333
|
+
cached_m0_model_key = NULL`).run();
|
|
144334
|
+
}
|
|
144335
|
+
}
|
|
144319
144336
|
}
|
|
144320
144337
|
];
|
|
144321
144338
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -144386,7 +144403,7 @@ function runMigrations(db) {
|
|
|
144386
144403
|
}
|
|
144387
144404
|
// ../plugin/src/features/magic-context/project-docs-hash.ts
|
|
144388
144405
|
import { createHash as createHash3 } from "node:crypto";
|
|
144389
|
-
import { readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
144406
|
+
import { lstatSync, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
144390
144407
|
import path4 from "node:path";
|
|
144391
144408
|
var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
144392
144409
|
var PROJECT_DOCS_DELIMITER = `
|
|
@@ -144394,6 +144411,7 @@ var PROJECT_DOCS_DELIMITER = `
|
|
|
144394
144411
|
---
|
|
144395
144412
|
|
|
144396
144413
|
`;
|
|
144414
|
+
var MAX_PROJECT_DOC_BYTES = 256 * 1024;
|
|
144397
144415
|
var docsCache = new Map;
|
|
144398
144416
|
function canonicalizeDocContent(raw) {
|
|
144399
144417
|
return raw.replace(/^\uFEFF/, "").replace(/\r\n/g, `
|
|
@@ -144403,9 +144421,10 @@ function canonicalizeDocContent(raw) {
|
|
|
144403
144421
|
}
|
|
144404
144422
|
function fingerprintFile(filePath) {
|
|
144405
144423
|
try {
|
|
144406
|
-
const stat =
|
|
144424
|
+
const stat = lstatSync(filePath);
|
|
144425
|
+
const isReadableDoc = stat.isFile() && stat.size <= MAX_PROJECT_DOC_BYTES;
|
|
144407
144426
|
return {
|
|
144408
|
-
exists:
|
|
144427
|
+
exists: isReadableDoc,
|
|
144409
144428
|
mtimeMs: stat.mtimeMs,
|
|
144410
144429
|
size: stat.size
|
|
144411
144430
|
};
|
|
@@ -144448,6 +144467,16 @@ function readCanonicalPieces(projectDirectory, files) {
|
|
|
144448
144467
|
if (!fingerprint?.exists) {
|
|
144449
144468
|
continue;
|
|
144450
144469
|
}
|
|
144470
|
+
let safeToRead = false;
|
|
144471
|
+
try {
|
|
144472
|
+
const st = lstatSync(filePath);
|
|
144473
|
+
safeToRead = st.isFile() && st.size <= MAX_PROJECT_DOC_BYTES;
|
|
144474
|
+
} catch {
|
|
144475
|
+
safeToRead = false;
|
|
144476
|
+
}
|
|
144477
|
+
if (!safeToRead) {
|
|
144478
|
+
continue;
|
|
144479
|
+
}
|
|
144451
144480
|
const canonicalContent = canonicalizeDocContent(readFileSync2(filePath, "utf8"));
|
|
144452
144481
|
hashPieces.push(`file:${filename}
|
|
144453
144482
|
${canonicalContent}`);
|
|
@@ -144614,7 +144643,6 @@ function getMaxMemoryMutationId(db, projectPath) {
|
|
|
144614
144643
|
return row?.max_id ?? null;
|
|
144615
144644
|
}
|
|
144616
144645
|
// ../plugin/src/features/magic-context/storage-meta-persisted.ts
|
|
144617
|
-
init_logger();
|
|
144618
144646
|
var CAS_RETRY_LIMIT = 5;
|
|
144619
144647
|
var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
144620
144648
|
"below-threshold",
|
|
@@ -144769,7 +144797,8 @@ function casUpdateJsonArrayColumn(db, sessionId, column, validator, mutate, opti
|
|
|
144769
144797
|
}
|
|
144770
144798
|
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
144771
144799
|
const row = db.prepare(`SELECT ${column} FROM session_meta WHERE session_id = ?`).get(sessionId);
|
|
144772
|
-
const
|
|
144800
|
+
const rawCurrent = row?.[column] ?? null;
|
|
144801
|
+
const currentBlob = rawCurrent ?? "[]";
|
|
144773
144802
|
const current = parseJsonArray(currentBlob, validator);
|
|
144774
144803
|
const next = mutate(current);
|
|
144775
144804
|
if (next === null)
|
|
@@ -144777,7 +144806,7 @@ function casUpdateJsonArrayColumn(db, sessionId, column, validator, mutate, opti
|
|
|
144777
144806
|
const nextBlob = stableStringify(next);
|
|
144778
144807
|
if (nextBlob === currentBlob)
|
|
144779
144808
|
return true;
|
|
144780
|
-
const result = db.prepare(`UPDATE session_meta SET ${column} = ? WHERE session_id = ? AND ${column}
|
|
144809
|
+
const result = db.prepare(`UPDATE session_meta SET ${column} = ? WHERE session_id = ? AND ${column} IS ?`).run(nextBlob, sessionId, rawCurrent);
|
|
144781
144810
|
if (result.changes > 0)
|
|
144782
144811
|
return true;
|
|
144783
144812
|
}
|
|
@@ -144906,14 +144935,16 @@ function getHistorianFailureState(db, sessionId) {
|
|
|
144906
144935
|
};
|
|
144907
144936
|
}
|
|
144908
144937
|
function incrementHistorianFailure(db, sessionId, error) {
|
|
144938
|
+
let nextCount = 1;
|
|
144909
144939
|
db.transaction(() => {
|
|
144910
144940
|
ensureSessionMetaRow(db, sessionId);
|
|
144911
144941
|
const current = getHistorianFailureState(db, sessionId);
|
|
144912
|
-
|
|
144942
|
+
nextCount = current.failureCount + 1;
|
|
144913
144943
|
db.prepare("UPDATE session_meta SET historian_failure_count = ?, historian_last_error = ?, historian_last_failure_at = ? WHERE session_id = ?").run(nextCount, error, Date.now(), sessionId);
|
|
144914
144944
|
const reason = error.replace(/\s+/g, " ").trim().slice(0, 300);
|
|
144915
144945
|
sessionLog(sessionId, `historian failure recorded: count=${nextCount} reason="${reason}"`);
|
|
144916
144946
|
})();
|
|
144947
|
+
return nextCount;
|
|
144917
144948
|
}
|
|
144918
144949
|
function clearHistorianFailureState(db, sessionId) {
|
|
144919
144950
|
db.transaction(() => {
|
|
@@ -144982,10 +145013,39 @@ function getStrippedPlaceholderIds(db, sessionId) {
|
|
|
144982
145013
|
} catch {}
|
|
144983
145014
|
return new Set;
|
|
144984
145015
|
}
|
|
144985
|
-
function
|
|
145016
|
+
function applyStrippedPlaceholderDelta(db, sessionId, delta) {
|
|
145017
|
+
const add = delta.add ? [...delta.add] : [];
|
|
145018
|
+
const remove = delta.remove ? [...delta.remove] : [];
|
|
145019
|
+
if (add.length === 0 && remove.length === 0)
|
|
145020
|
+
return true;
|
|
144986
145021
|
ensureSessionMetaRow(db, sessionId);
|
|
144987
|
-
|
|
144988
|
-
|
|
145022
|
+
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
145023
|
+
const row = db.prepare("SELECT stripped_placeholder_ids FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
145024
|
+
const rawStored = row ? row.stripped_placeholder_ids ?? null : null;
|
|
145025
|
+
const current = new Set(parseStrippedBlob(rawStored));
|
|
145026
|
+
for (const id of add)
|
|
145027
|
+
current.add(id);
|
|
145028
|
+
for (const id of remove)
|
|
145029
|
+
current.delete(id);
|
|
145030
|
+
const nextBlob = current.size > 0 ? JSON.stringify([...current]) : "";
|
|
145031
|
+
if (nextBlob === (rawStored ?? ""))
|
|
145032
|
+
return true;
|
|
145033
|
+
const result = db.prepare("UPDATE session_meta SET stripped_placeholder_ids = ? WHERE session_id = ? AND stripped_placeholder_ids IS ?").run(nextBlob, sessionId, rawStored);
|
|
145034
|
+
if (result.changes > 0)
|
|
145035
|
+
return true;
|
|
145036
|
+
}
|
|
145037
|
+
sessionLog(sessionId, `stripped_placeholder_ids CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
|
|
145038
|
+
return false;
|
|
145039
|
+
}
|
|
145040
|
+
function parseStrippedBlob(raw) {
|
|
145041
|
+
if (!raw || raw.length === 0)
|
|
145042
|
+
return [];
|
|
145043
|
+
try {
|
|
145044
|
+
const parsed = JSON.parse(raw);
|
|
145045
|
+
if (Array.isArray(parsed))
|
|
145046
|
+
return parsed.filter((v) => typeof v === "string");
|
|
145047
|
+
} catch {}
|
|
145048
|
+
return [];
|
|
144989
145049
|
}
|
|
144990
145050
|
function isPendingCompactionMarker(value) {
|
|
144991
145051
|
return typeof value === "object" && value !== null && typeof value.ordinal === "number" && typeof value.endMessageId === "string" && typeof value.publishedAt === "number";
|
|
@@ -145077,8 +145137,6 @@ function setSessionWorkMetrics(db, sessionId, newWorkTokens, totalInputTokens) {
|
|
|
145077
145137
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
145078
145138
|
|
|
145079
145139
|
// ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
|
|
145080
|
-
init_logger();
|
|
145081
|
-
await init_read_session_db();
|
|
145082
145140
|
function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
145083
145141
|
try {
|
|
145084
145142
|
return withReadOnlySessionDb((openCodeDb) => {
|
|
@@ -145112,6 +145170,9 @@ var SESSION_META_FALLBACK_SELECTS = {
|
|
|
145112
145170
|
cached_m0_materialized_at: "NULL AS cached_m0_materialized_at",
|
|
145113
145171
|
cached_m0_session_facts_version: "NULL AS cached_m0_session_facts_version",
|
|
145114
145172
|
cached_m0_upgrade_state: "NULL AS cached_m0_upgrade_state",
|
|
145173
|
+
cached_m0_system_hash: "NULL AS cached_m0_system_hash",
|
|
145174
|
+
cached_m0_tool_set_hash: "NULL AS cached_m0_tool_set_hash",
|
|
145175
|
+
cached_m0_model_key: "NULL AS cached_m0_model_key",
|
|
145115
145176
|
last_observed_model_key: "NULL AS last_observed_model_key",
|
|
145116
145177
|
upgrade_reminded_at: "NULL AS upgrade_reminded_at"
|
|
145117
145178
|
};
|
|
@@ -145344,7 +145405,6 @@ function markNoteChecked(db, noteId) {
|
|
|
145344
145405
|
db.prepare("UPDATE notes SET last_checked_at = ?, updated_at = ? WHERE id = ? AND type = 'smart'").run(now, now, noteId);
|
|
145345
145406
|
}
|
|
145346
145407
|
// ../plugin/src/features/magic-context/storage-ops.ts
|
|
145347
|
-
init_logger();
|
|
145348
145408
|
var queuePendingOpStatements = new WeakMap;
|
|
145349
145409
|
var getPendingOpsStatements = new WeakMap;
|
|
145350
145410
|
var clearPendingOpsStatements = new WeakMap;
|
|
@@ -145746,7 +145806,6 @@ var ERROR_CLASSES = new Set([
|
|
|
145746
145806
|
"unknown"
|
|
145747
145807
|
]);
|
|
145748
145808
|
// ../plugin/src/features/magic-context/v22-deferred-backfill.ts
|
|
145749
|
-
init_logger();
|
|
145750
145809
|
import { createHash as createHash4 } from "node:crypto";
|
|
145751
145810
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
145752
145811
|
import path5 from "node:path";
|
|
@@ -146025,8 +146084,6 @@ function getAgentFallbackModels(agent) {
|
|
|
146025
146084
|
}
|
|
146026
146085
|
|
|
146027
146086
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
146028
|
-
init_data_path();
|
|
146029
|
-
init_logger();
|
|
146030
146087
|
import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync, writeFileSync } from "node:fs";
|
|
146031
146088
|
import { join as join6 } from "node:path";
|
|
146032
146089
|
var MIN_SANE_LIMIT = 20000;
|
|
@@ -146136,7 +146193,6 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
146136
146193
|
}
|
|
146137
146194
|
|
|
146138
146195
|
// ../plugin/src/hooks/magic-context/event-resolvers.ts
|
|
146139
|
-
init_logger();
|
|
146140
146196
|
var DEFAULT_CONTEXT_LIMIT = 128000;
|
|
146141
146197
|
var MAX_EXECUTE_THRESHOLD = 80;
|
|
146142
146198
|
function resolveCacheTtl(cacheTtl, modelKey) {
|
|
@@ -146269,7 +146325,6 @@ function resolveTokensMatchWithKey(tokensConfig, modelKey) {
|
|
|
146269
146325
|
}
|
|
146270
146326
|
|
|
146271
146327
|
// ../plugin/src/hooks/magic-context/note-nudger.ts
|
|
146272
|
-
init_logger();
|
|
146273
146328
|
var NOTE_NUDGE_COOLDOWN_MS = 15 * 60 * 1000;
|
|
146274
146329
|
var lastDeliveredAt = new Map;
|
|
146275
146330
|
function getPersistedNoteNudgeDeliveredAt(_db, sessionId) {
|
|
@@ -146437,7 +146492,6 @@ function isTodoItem(value) {
|
|
|
146437
146492
|
}
|
|
146438
146493
|
|
|
146439
146494
|
// ../plugin/src/hooks/magic-context/upgrade-reminder.ts
|
|
146440
|
-
init_logger();
|
|
146441
146495
|
var remindedThisProcess = new Set;
|
|
146442
146496
|
var UPGRADE_REMINDER_TEXT = [
|
|
146443
146497
|
"\uD83C\uDF86 Historian V2 is released!",
|
|
@@ -146538,7 +146592,6 @@ async function maybeSendUpgradeReminder(deps, sessionId) {
|
|
|
146538
146592
|
}
|
|
146539
146593
|
|
|
146540
146594
|
// ../plugin/src/shared/announcement.ts
|
|
146541
|
-
init_data_path();
|
|
146542
146595
|
import * as fs2 from "node:fs";
|
|
146543
146596
|
import * as path6 from "node:path";
|
|
146544
146597
|
var ANNOUNCEMENT_VERSION = "0.22.0";
|
|
@@ -146584,9 +146637,14 @@ function shouldShowAnnouncement() {
|
|
|
146584
146637
|
return lastVersion !== ANNOUNCEMENT_VERSION;
|
|
146585
146638
|
}
|
|
146586
146639
|
|
|
146587
|
-
// src/
|
|
146588
|
-
|
|
146589
|
-
|
|
146640
|
+
// ../plugin/src/shared/keep-subagents.ts
|
|
146641
|
+
var keepSubagents = false;
|
|
146642
|
+
function setKeepSubagents(value) {
|
|
146643
|
+
keepSubagents = value === true;
|
|
146644
|
+
}
|
|
146645
|
+
function shouldKeepSubagents() {
|
|
146646
|
+
return keepSubagents;
|
|
146647
|
+
}
|
|
146590
146648
|
|
|
146591
146649
|
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
146592
146650
|
function resolveFallbackChain(agentName, userFallbacks) {
|
|
@@ -146653,9 +146711,6 @@ function isEmptySidekickResult(text) {
|
|
|
146653
146711
|
return trimmed.length === 0 || trimmed === "no relevant memories found";
|
|
146654
146712
|
}
|
|
146655
146713
|
|
|
146656
|
-
// src/commands/ctx-aug.ts
|
|
146657
|
-
init_logger();
|
|
146658
|
-
|
|
146659
146714
|
// src/subagent-runner.ts
|
|
146660
146715
|
import * as childProcess from "node:child_process";
|
|
146661
146716
|
import { existsSync as existsSync6 } from "node:fs";
|
|
@@ -146665,7 +146720,6 @@ import { createInterface } from "node:readline";
|
|
|
146665
146720
|
import { fileURLToPath } from "node:url";
|
|
146666
146721
|
|
|
146667
146722
|
// ../plugin/src/features/magic-context/subagent-token-capture.ts
|
|
146668
|
-
init_logger();
|
|
146669
146723
|
function asNumber(value) {
|
|
146670
146724
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
146671
146725
|
}
|
|
@@ -146756,7 +146810,6 @@ function recordChildInvocation(input) {
|
|
|
146756
146810
|
}
|
|
146757
146811
|
|
|
146758
146812
|
// src/subagent-runner.ts
|
|
146759
|
-
init_logger();
|
|
146760
146813
|
function resolveBundledPiCli() {
|
|
146761
146814
|
try {
|
|
146762
146815
|
const require_ = createRequire2(import.meta.url);
|
|
@@ -147529,18 +147582,10 @@ function clearStaleEntries(db, maxAgeMs, projectIdentity) {
|
|
|
147529
147582
|
const result = projectIdentity ? db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run(projectIdentity, cutoff) : db.prepare("DELETE FROM dream_queue WHERE started_at IS NOT NULL AND started_at < ?").run(cutoff);
|
|
147530
147583
|
return result.changes;
|
|
147531
147584
|
}
|
|
147532
|
-
|
|
147533
|
-
// src/commands/ctx-dream.ts
|
|
147534
|
-
init_logger();
|
|
147535
147585
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
147536
147586
|
import { existsSync as existsSync8 } from "node:fs";
|
|
147537
147587
|
import { join as join11 } from "node:path";
|
|
147538
|
-
|
|
147539
|
-
// ../plugin/src/shared/index.ts
|
|
147540
|
-
init_logger();
|
|
147541
|
-
|
|
147542
147588
|
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
147543
|
-
init_logger();
|
|
147544
147589
|
function extractMessage(error) {
|
|
147545
147590
|
if (typeof error === "string")
|
|
147546
147591
|
return error;
|
|
@@ -147775,40 +147820,66 @@ function extractLatestAssistantText(messages) {
|
|
|
147775
147820
|
`) || null;
|
|
147776
147821
|
}
|
|
147777
147822
|
|
|
147778
|
-
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
147779
|
-
init_data_path();
|
|
147780
|
-
init_logger();
|
|
147781
|
-
await init_sqlite();
|
|
147782
|
-
|
|
147783
147823
|
// ../plugin/src/features/magic-context/key-files/identify-key-files.ts
|
|
147784
147824
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
147785
|
-
import { isAbsolute, join as join10, relative as relative2 } from "node:path";
|
|
147786
|
-
init_logger();
|
|
147825
|
+
import { isAbsolute as isAbsolute2, join as join10, relative as relative2 } from "node:path";
|
|
147787
147826
|
|
|
147788
147827
|
// ../plugin/src/features/magic-context/key-files/aft-availability.ts
|
|
147789
147828
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
147790
147829
|
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
147791
147830
|
import { homedir as homedir2 } from "node:os";
|
|
147792
|
-
import { join as join9 } from "node:path";
|
|
147831
|
+
import { isAbsolute, join as join9, resolve as resolve2 } from "node:path";
|
|
147832
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
147793
147833
|
var overrideAvailability = null;
|
|
147794
147834
|
function parseConfig(path7) {
|
|
147795
147835
|
if (!existsSync7(path7))
|
|
147796
147836
|
return null;
|
|
147797
147837
|
return import_comment_json.parse(readFileSync5(path7, "utf-8"));
|
|
147798
147838
|
}
|
|
147799
|
-
|
|
147839
|
+
var AFT_NAME_NEEDLES = ["@cortexkit/aft", "aft-opencode", "aft-pi"];
|
|
147840
|
+
function stringMentionsAft(value) {
|
|
147841
|
+
return AFT_NAME_NEEDLES.some((needle) => value.includes(needle));
|
|
147842
|
+
}
|
|
147843
|
+
function resolveLocalEntryPackageName(value, configDir) {
|
|
147844
|
+
let dir = null;
|
|
147845
|
+
if (value.startsWith("file://")) {
|
|
147846
|
+
try {
|
|
147847
|
+
dir = fileURLToPath2(value);
|
|
147848
|
+
} catch {
|
|
147849
|
+
return null;
|
|
147850
|
+
}
|
|
147851
|
+
} else if (value.startsWith("~/")) {
|
|
147852
|
+
dir = join9(homedir2(), value.slice(2));
|
|
147853
|
+
} else if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../")) {
|
|
147854
|
+
dir = isAbsolute(value) ? value : resolve2(configDir, value);
|
|
147855
|
+
} else {
|
|
147856
|
+
return null;
|
|
147857
|
+
}
|
|
147858
|
+
try {
|
|
147859
|
+
const pkg = JSON.parse(readFileSync5(join9(dir, "package.json"), "utf-8"));
|
|
147860
|
+
return typeof pkg.name === "string" ? pkg.name : null;
|
|
147861
|
+
} catch {
|
|
147862
|
+
return null;
|
|
147863
|
+
}
|
|
147864
|
+
}
|
|
147865
|
+
function entryMatchesAft(entry, configDir) {
|
|
147800
147866
|
const value = Array.isArray(entry) ? entry[0] : entry;
|
|
147801
|
-
|
|
147867
|
+
if (typeof value !== "string")
|
|
147868
|
+
return false;
|
|
147869
|
+
if (stringMentionsAft(value))
|
|
147870
|
+
return true;
|
|
147871
|
+
const name2 = resolveLocalEntryPackageName(value, configDir);
|
|
147872
|
+
return name2 != null && stringMentionsAft(name2);
|
|
147802
147873
|
}
|
|
147803
|
-
function hasAftInArray(value) {
|
|
147804
|
-
return Array.isArray(value) && value.some(entryMatchesAft);
|
|
147874
|
+
function hasAftInArray(value, configDir) {
|
|
147875
|
+
return Array.isArray(value) && value.some((entry) => entryMatchesAft(entry, configDir));
|
|
147805
147876
|
}
|
|
147806
|
-
function hasAftAtKeys(value, keys) {
|
|
147877
|
+
function hasAftAtKeys(value, keys, configDir) {
|
|
147807
147878
|
if (!value || typeof value !== "object")
|
|
147808
147879
|
return false;
|
|
147809
147880
|
const record = value;
|
|
147810
147881
|
for (const key of keys) {
|
|
147811
|
-
if (hasAftInArray(record[key]))
|
|
147882
|
+
if (hasAftInArray(record[key], configDir))
|
|
147812
147883
|
return true;
|
|
147813
147884
|
}
|
|
147814
147885
|
return false;
|
|
@@ -147825,7 +147896,8 @@ function getAftAvailability() {
|
|
|
147825
147896
|
for (const path7 of opencodePaths) {
|
|
147826
147897
|
try {
|
|
147827
147898
|
const config = parseConfig(path7);
|
|
147828
|
-
|
|
147899
|
+
const configDir = join9(path7, "..");
|
|
147900
|
+
if (hasAftAtKeys(config, ["plugin", "plugins", "mcp", "mcp_servers"], configDir)) {
|
|
147829
147901
|
opencode = true;
|
|
147830
147902
|
break;
|
|
147831
147903
|
}
|
|
@@ -147835,12 +147907,13 @@ function getAftAvailability() {
|
|
|
147835
147907
|
for (const path7 of piPaths) {
|
|
147836
147908
|
try {
|
|
147837
147909
|
const config = parseConfig(path7);
|
|
147838
|
-
|
|
147910
|
+
const configDir = join9(path7, "..");
|
|
147911
|
+
if (hasAftAtKeys(config, ["packages", "extensions"], configDir)) {
|
|
147839
147912
|
pi = true;
|
|
147840
147913
|
break;
|
|
147841
147914
|
}
|
|
147842
147915
|
const agent = config?.agent;
|
|
147843
|
-
if (hasAftAtKeys(agent, ["packages", "extensions"])) {
|
|
147916
|
+
if (hasAftAtKeys(agent, ["packages", "extensions"], configDir)) {
|
|
147844
147917
|
pi = true;
|
|
147845
147918
|
break;
|
|
147846
147919
|
}
|
|
@@ -147860,7 +147933,7 @@ function isAftAvailable() {
|
|
|
147860
147933
|
|
|
147861
147934
|
// ../plugin/src/features/magic-context/key-files/read-history.ts
|
|
147862
147935
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
147863
|
-
import { relative, resolve as
|
|
147936
|
+
import { relative, resolve as resolve3 } from "node:path";
|
|
147864
147937
|
function toMs(value) {
|
|
147865
147938
|
if (typeof value === "number" && Number.isFinite(value))
|
|
147866
147939
|
return value;
|
|
@@ -147897,7 +147970,7 @@ function coalesceRanges(ranges) {
|
|
|
147897
147970
|
}
|
|
147898
147971
|
function normalizeProjectRelativePath(projectPath, filePath) {
|
|
147899
147972
|
const root = realpathSync3(projectPath);
|
|
147900
|
-
const abs = filePath.startsWith("/") ?
|
|
147973
|
+
const abs = filePath.startsWith("/") ? resolve3(filePath) : resolve3(root, filePath);
|
|
147901
147974
|
let real = abs;
|
|
147902
147975
|
try {
|
|
147903
147976
|
real = realpathSync3(abs);
|
|
@@ -148040,9 +148113,6 @@ function collectKeyFileCandidates(args) {
|
|
|
148040
148113
|
})).sort((a, b) => b.totalReads - a.totalReads || b.lastReadAt - a.lastReadAt).slice(0, 200);
|
|
148041
148114
|
}
|
|
148042
148115
|
|
|
148043
|
-
// ../plugin/src/features/magic-context/key-files/storage-key-files.ts
|
|
148044
|
-
init_logger();
|
|
148045
|
-
|
|
148046
148116
|
// ../plugin/src/features/magic-context/key-files/identify-key-files.ts
|
|
148047
148117
|
var KEY_FILES_SYSTEM_PROMPT = "You are a file importance evaluator. Given read statistics about files in a coding session, identify which are core orientation files worth pinning in context. Return a JSON array.";
|
|
148048
148118
|
class KeyFilesValidationError extends Error {
|
|
@@ -148262,11 +148332,13 @@ async function runKeyFilesLlm(args) {
|
|
|
148262
148332
|
const text = extractLatestAssistantText(messages);
|
|
148263
148333
|
if (!text)
|
|
148264
148334
|
throw new Error("Dreamer returned no key-files output.");
|
|
148265
|
-
return text;
|
|
148335
|
+
return { text, messages };
|
|
148266
148336
|
} finally {
|
|
148267
|
-
|
|
148268
|
-
|
|
148269
|
-
|
|
148337
|
+
if (!shouldKeepSubagents()) {
|
|
148338
|
+
await args.client.session.delete({ path: { id: agentSessionId } }).catch(() => {
|
|
148339
|
+
return;
|
|
148340
|
+
});
|
|
148341
|
+
}
|
|
148270
148342
|
}
|
|
148271
148343
|
}
|
|
148272
148344
|
async function runKeyFilesTask(args) {
|
|
@@ -148312,9 +148384,27 @@ async function runKeyFilesTask(args) {
|
|
|
148312
148384
|
log(`[key-files] lease renewal threw: ${getErrorMessage(error)}`);
|
|
148313
148385
|
}
|
|
148314
148386
|
}, 60000);
|
|
148387
|
+
let invocationRecorded = false;
|
|
148388
|
+
const llmStartedAt = Date.now();
|
|
148389
|
+
const recordKeyFilesInvocation = (params) => {
|
|
148390
|
+
if (!args.parentSessionId || invocationRecorded)
|
|
148391
|
+
return;
|
|
148392
|
+
invocationRecorded = true;
|
|
148393
|
+
recordChildInvocation({
|
|
148394
|
+
db: args.db,
|
|
148395
|
+
parentSessionId: args.parentSessionId,
|
|
148396
|
+
harness: getHarness(),
|
|
148397
|
+
subagent: "dreamer",
|
|
148398
|
+
task: "key files",
|
|
148399
|
+
startedAt: llmStartedAt,
|
|
148400
|
+
status: params.status,
|
|
148401
|
+
messages: params.messages,
|
|
148402
|
+
error: params.error
|
|
148403
|
+
});
|
|
148404
|
+
};
|
|
148315
148405
|
try {
|
|
148316
148406
|
try {
|
|
148317
|
-
const raw = await runKeyFilesLlm({
|
|
148407
|
+
const { text: raw, messages: llmMessages } = await runKeyFilesLlm({
|
|
148318
148408
|
client: args.client,
|
|
148319
148409
|
parentSessionId: args.parentSessionId,
|
|
148320
148410
|
projectPath,
|
|
@@ -148322,8 +148412,10 @@ async function runKeyFilesTask(args) {
|
|
|
148322
148412
|
deadline: args.deadline,
|
|
148323
148413
|
fallbackModels: args.fallbackModels
|
|
148324
148414
|
});
|
|
148415
|
+
recordKeyFilesInvocation({ status: "completed", messages: llmMessages });
|
|
148325
148416
|
validated = validateLlmOutput(raw, args.config, projectPath, new Set(candidates.map((candidate) => candidate.path)));
|
|
148326
148417
|
} catch (error) {
|
|
148418
|
+
recordKeyFilesInvocation({ status: "failed", error });
|
|
148327
148419
|
log(`[key-files] LLM validation failed: ${getErrorMessage(error)}`);
|
|
148328
148420
|
throw error;
|
|
148329
148421
|
}
|
|
@@ -148917,9 +149009,6 @@ function getMemoryCountsByStatus(db, projectPath) {
|
|
|
148917
149009
|
return counts;
|
|
148918
149010
|
}
|
|
148919
149011
|
|
|
148920
|
-
// ../plugin/src/features/magic-context/user-memory/review-user-memories.ts
|
|
148921
|
-
init_logger();
|
|
148922
|
-
|
|
148923
149012
|
// ../plugin/src/features/magic-context/dreamer/task-prompts.ts
|
|
148924
149013
|
var DREAMER_SYSTEM_PROMPT = `You are a memory maintenance agent for the magic-context system.
|
|
148925
149014
|
You run during scheduled dream windows to maintain a project's cross-session memory store and codebase documentation.
|
|
@@ -149422,7 +149511,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
149422
149511
|
db: args.db,
|
|
149423
149512
|
parentSessionId: args.parentSessionId,
|
|
149424
149513
|
harness: "opencode",
|
|
149425
|
-
subagent: "
|
|
149514
|
+
subagent: "dreamer",
|
|
149515
|
+
task: "user memories",
|
|
149426
149516
|
startedAt,
|
|
149427
149517
|
status: params.status,
|
|
149428
149518
|
messages: params.messages,
|
|
@@ -149546,7 +149636,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
149546
149636
|
return result;
|
|
149547
149637
|
} finally {
|
|
149548
149638
|
clearInterval(leaseInterval);
|
|
149549
|
-
if (agentSessionId) {
|
|
149639
|
+
if (agentSessionId && !shouldKeepSubagents()) {
|
|
149550
149640
|
await args.client.session.delete({
|
|
149551
149641
|
path: { id: agentSessionId },
|
|
149552
149642
|
query: { directory: args.sessionDirectory }
|
|
@@ -149673,7 +149763,7 @@ async function runDream(args) {
|
|
|
149673
149763
|
}
|
|
149674
149764
|
}
|
|
149675
149765
|
const deadline = startedAt + args.maxRuntimeMinutes * 60 * 1000;
|
|
149676
|
-
const lastDreamAt = getDreamState(args.db, `last_dream_at:${args.projectIdentity}`)
|
|
149766
|
+
const lastDreamAt = getDreamState(args.db, `last_dream_at:${args.projectIdentity}`);
|
|
149677
149767
|
log(`[dreamer] last dream at: ${lastDreamAt ?? "never"} (project=${args.projectIdentity})`);
|
|
149678
149768
|
let lastErrorSignature = null;
|
|
149679
149769
|
let consecutiveSameErrorFailures = 0;
|
|
@@ -149870,14 +149960,14 @@ async function runDream(args) {
|
|
|
149870
149960
|
}
|
|
149871
149961
|
} finally {
|
|
149872
149962
|
clearInterval(leaseRenewalInterval);
|
|
149873
|
-
if (agentSessionId && !taskFailed) {
|
|
149963
|
+
if (agentSessionId && !taskFailed && !shouldKeepSubagents()) {
|
|
149874
149964
|
await args.client.session.delete({
|
|
149875
149965
|
path: { id: agentSessionId }
|
|
149876
149966
|
}).catch((error) => {
|
|
149877
149967
|
log("[dreamer] failed to delete child session:", error);
|
|
149878
149968
|
});
|
|
149879
|
-
} else if (agentSessionId && taskFailed) {
|
|
149880
|
-
log(`[dreamer] KEEPING
|
|
149969
|
+
} else if (agentSessionId && (taskFailed || shouldKeepSubagents())) {
|
|
149970
|
+
log(`[dreamer] KEEPING child session ${agentSessionId} for task ${taskName} (${taskFailed ? "failed" : "keep_subagents"})`);
|
|
149881
149971
|
}
|
|
149882
149972
|
}
|
|
149883
149973
|
if (lostLease) {
|
|
@@ -150055,7 +150145,6 @@ async function runDream(args) {
|
|
|
150055
150145
|
const hasSuccessfulTask = result.tasks.some((t) => !t.error && !POST_TASK_NAMES.has(t.name));
|
|
150056
150146
|
if (hasSuccessfulTask && !lostLease) {
|
|
150057
150147
|
setDreamState(args.db, `last_dream_at:${args.projectIdentity}`, String(result.finishedAt));
|
|
150058
|
-
setDreamState(args.db, "last_dream_at", String(result.finishedAt));
|
|
150059
150148
|
}
|
|
150060
150149
|
const totalDuration = ((result.finishedAt - startedAt) / 1000).toFixed(1);
|
|
150061
150150
|
const succeeded = result.tasks.filter((t) => !t.error).length;
|
|
@@ -150162,7 +150251,7 @@ Only include notes whose conditions you could definitively evaluate against exte
|
|
|
150162
150251
|
parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
|
|
150163
150252
|
}
|
|
150164
150253
|
}, {
|
|
150165
|
-
timeoutMs: Math.min(remainingMs,
|
|
150254
|
+
timeoutMs: Math.min(remainingMs, 5 * 60 * 1000),
|
|
150166
150255
|
signal: abortController.signal,
|
|
150167
150256
|
fallbackModels: args.fallbackModels,
|
|
150168
150257
|
callContext: "dreamer:smart-notes"
|
|
@@ -150238,7 +150327,7 @@ Only include notes whose conditions you could definitively evaluate against exte
|
|
|
150238
150327
|
});
|
|
150239
150328
|
} finally {
|
|
150240
150329
|
clearInterval(leaseInterval);
|
|
150241
|
-
if (agentSessionId) {
|
|
150330
|
+
if (agentSessionId && !shouldKeepSubagents()) {
|
|
150242
150331
|
await args.client.session.delete({
|
|
150243
150332
|
path: { id: agentSessionId }
|
|
150244
150333
|
}).catch(() => {});
|
|
@@ -150249,7 +150338,7 @@ var MAX_LEASE_RETRIES = 3;
|
|
|
150249
150338
|
async function processDreamQueue(args) {
|
|
150250
150339
|
const maxRuntimeMs = args.maxRuntimeMinutes * 60 * 1000;
|
|
150251
150340
|
if (!hasActiveDreamLease(args.db)) {
|
|
150252
|
-
clearStaleEntries(args.db, maxRuntimeMs +
|
|
150341
|
+
clearStaleEntries(args.db, maxRuntimeMs + 30 * 60 * 1000, args.projectIdentity);
|
|
150253
150342
|
}
|
|
150254
150343
|
const entry = dequeueNext(args.db, args.projectIdentity);
|
|
150255
150344
|
if (!entry) {
|
|
@@ -150292,7 +150381,6 @@ async function processDreamQueue(args) {
|
|
|
150292
150381
|
return result;
|
|
150293
150382
|
}
|
|
150294
150383
|
// ../plugin/src/features/magic-context/dreamer/scheduler.ts
|
|
150295
|
-
init_logger();
|
|
150296
150384
|
function parseScheduleWindow(schedule) {
|
|
150297
150385
|
const match = /^(\d{1,2}):(\d{2})-(\d{1,2}):(\d{2})$/.exec(schedule.trim());
|
|
150298
150386
|
if (!match)
|
|
@@ -150332,8 +150420,7 @@ function findProjectsNeedingDream(db) {
|
|
|
150332
150420
|
const now = new Date;
|
|
150333
150421
|
for (const row of projectRows) {
|
|
150334
150422
|
const lastDreamAtStr = getDreamState(db, `last_dream_at:${row.project_path}`);
|
|
150335
|
-
const
|
|
150336
|
-
const lastDreamAt = Number(lastDreamAtStr ?? fallbackStr ?? "0") || 0;
|
|
150423
|
+
const lastDreamAt = Number(lastDreamAtStr ?? "0") || 0;
|
|
150337
150424
|
if (lastDreamAt > 0 && isDreamFromCurrentWindow(lastDreamAt, now)) {
|
|
150338
150425
|
continue;
|
|
150339
150426
|
}
|
|
@@ -150367,7 +150454,6 @@ function checkScheduleAndEnqueue(db, schedule, ownProjectIdentity) {
|
|
|
150367
150454
|
return enqueued;
|
|
150368
150455
|
}
|
|
150369
150456
|
// ../plugin/src/features/magic-context/git-commits/git-log-reader.ts
|
|
150370
|
-
init_logger();
|
|
150371
150457
|
import { execFile } from "node:child_process";
|
|
150372
150458
|
import { promisify } from "node:util";
|
|
150373
150459
|
var execFileAsync = promisify(execFile);
|
|
@@ -150451,9 +150537,6 @@ ${body}` : subject;
|
|
|
150451
150537
|
}
|
|
150452
150538
|
return commits;
|
|
150453
150539
|
}
|
|
150454
|
-
// ../plugin/src/features/magic-context/git-commits/indexer.ts
|
|
150455
|
-
init_logger();
|
|
150456
|
-
|
|
150457
150540
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
150458
150541
|
var exports_external = {};
|
|
150459
150542
|
__export(exports_external, {
|
|
@@ -164894,6 +164977,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
164894
164977
|
model: DEFAULT_LOCAL_EMBEDDING_MODEL
|
|
164895
164978
|
}).describe("Embedding provider configuration"),
|
|
164896
164979
|
temporal_awareness: exports_external.boolean().default(true).describe('Inject wall-clock gap markers (<!-- +Xm -->) between user messages where > 5 min elapsed since the previous message, and add start/end date attributes on compartments. Gives the agent a sense of session pacing and "how long ago" across multi-day sessions. Graduated from experimental.temporal_awareness; default: true (set false to opt out).'),
|
|
164980
|
+
keep_subagents: exports_external.boolean().default(false).describe("Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, sidekick, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect."),
|
|
164897
164981
|
caveman_text_compression: exports_external.object({
|
|
164898
164982
|
enabled: exports_external.boolean().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Only active when ctx_reduce_enabled=false. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
|
|
164899
164983
|
min_chars: exports_external.number().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
|
|
@@ -164929,9 +165013,6 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
164929
165013
|
};
|
|
164930
165014
|
});
|
|
164931
165015
|
|
|
164932
|
-
// ../plugin/src/features/magic-context/memory/embedding.ts
|
|
164933
|
-
init_logger();
|
|
164934
|
-
|
|
164935
165016
|
// ../plugin/src/features/magic-context/memory/cosine-similarity.ts
|
|
164936
165017
|
function cosineSimilarity(a, b) {
|
|
164937
165018
|
if (a.length !== b.length) {
|
|
@@ -164977,8 +165058,6 @@ import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
|
164977
165058
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
164978
165059
|
import { dirname as dirname4, join as join12 } from "node:path";
|
|
164979
165060
|
import { pathToFileURL } from "node:url";
|
|
164980
|
-
init_data_path();
|
|
164981
|
-
init_logger();
|
|
164982
165061
|
var LOCK_POLL_MS = 150;
|
|
164983
165062
|
var STALE_LOCK_MS = 3 * 60000;
|
|
164984
165063
|
var MAX_LOCK_WAIT_MS = 5 * 60000;
|
|
@@ -165017,7 +165096,7 @@ async function acquireModelLoadLock(lockPath) {
|
|
|
165017
165096
|
if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
|
|
165018
165097
|
throw new Error(`[magic-context] embedding-load lock wait exceeded ${MAX_LOCK_WAIT_MS}ms; another process is still loading the model. Skipping this init attempt to avoid an unsynchronized native load.`);
|
|
165019
165098
|
}
|
|
165020
|
-
await new Promise((
|
|
165099
|
+
await new Promise((resolve4) => setTimeout(resolve4, LOCK_POLL_MS));
|
|
165021
165100
|
}
|
|
165022
165101
|
}
|
|
165023
165102
|
}
|
|
@@ -165186,7 +165265,7 @@ class LocalEmbeddingProvider {
|
|
|
165186
165265
|
}
|
|
165187
165266
|
const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
|
|
165188
165267
|
log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
|
|
165189
|
-
await new Promise((
|
|
165268
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
165190
165269
|
}
|
|
165191
165270
|
}
|
|
165192
165271
|
if (this.pipeline) {
|
|
@@ -165214,8 +165293,8 @@ class LocalEmbeddingProvider {
|
|
|
165214
165293
|
if (this.inFlight === 0) {
|
|
165215
165294
|
return Promise.resolve();
|
|
165216
165295
|
}
|
|
165217
|
-
return new Promise((
|
|
165218
|
-
this.inFlightWaiters.push(
|
|
165296
|
+
return new Promise((resolve4) => {
|
|
165297
|
+
this.inFlightWaiters.push(resolve4);
|
|
165219
165298
|
});
|
|
165220
165299
|
}
|
|
165221
165300
|
finishInFlight() {
|
|
@@ -165313,8 +165392,60 @@ class LocalEmbeddingProvider {
|
|
|
165313
165392
|
}
|
|
165314
165393
|
}
|
|
165315
165394
|
|
|
165395
|
+
// ../plugin/src/features/magic-context/memory/embedding-ssrf.ts
|
|
165396
|
+
var METADATA_HOSTNAMES = new Set(["metadata.google.internal", "metadata.goog"]);
|
|
165397
|
+
var IPV6_METADATA_HOSTS = new Set(["fd00:ec2::254"]);
|
|
165398
|
+
function isLinkLocalIpv4(host) {
|
|
165399
|
+
return /^169\.254\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
165400
|
+
}
|
|
165401
|
+
function ipv4FromMappedIpv6(host) {
|
|
165402
|
+
const m = /^::ffff:(.+)$/.exec(host);
|
|
165403
|
+
if (!m)
|
|
165404
|
+
return null;
|
|
165405
|
+
const tail = m[1];
|
|
165406
|
+
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(tail))
|
|
165407
|
+
return tail;
|
|
165408
|
+
const hex3 = /^([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(tail);
|
|
165409
|
+
if (hex3) {
|
|
165410
|
+
const hi = Number.parseInt(hex3[1], 16);
|
|
165411
|
+
const lo = Number.parseInt(hex3[2], 16);
|
|
165412
|
+
if (Number.isNaN(hi) || Number.isNaN(lo))
|
|
165413
|
+
return null;
|
|
165414
|
+
return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
|
|
165415
|
+
}
|
|
165416
|
+
return null;
|
|
165417
|
+
}
|
|
165418
|
+
function blockedEmbeddingEndpointReason(endpoint) {
|
|
165419
|
+
const trimmed = endpoint.trim();
|
|
165420
|
+
if (trimmed.length === 0)
|
|
165421
|
+
return null;
|
|
165422
|
+
let url2;
|
|
165423
|
+
try {
|
|
165424
|
+
url2 = new URL(trimmed);
|
|
165425
|
+
} catch {
|
|
165426
|
+
return `embedding endpoint is not a valid URL: ${trimmed}`;
|
|
165427
|
+
}
|
|
165428
|
+
const host = url2.hostname.toLowerCase().replace(/^\[/, "").replace(/\]$/, "");
|
|
165429
|
+
if (METADATA_HOSTNAMES.has(host)) {
|
|
165430
|
+
return `embedding endpoint host ${host} is a cloud metadata service (blocked)`;
|
|
165431
|
+
}
|
|
165432
|
+
if (IPV6_METADATA_HOSTS.has(host)) {
|
|
165433
|
+
return `embedding endpoint host ${host} is the AWS IPv6 metadata service (blocked)`;
|
|
165434
|
+
}
|
|
165435
|
+
if (isLinkLocalIpv4(host)) {
|
|
165436
|
+
return `embedding endpoint host ${host} is link-local / cloud metadata (blocked)`;
|
|
165437
|
+
}
|
|
165438
|
+
const mappedV4 = ipv4FromMappedIpv6(host);
|
|
165439
|
+
if (mappedV4 && isLinkLocalIpv4(mappedV4)) {
|
|
165440
|
+
return `embedding endpoint host ${host} (IPv4-mapped ${mappedV4}) is link-local / cloud metadata (blocked)`;
|
|
165441
|
+
}
|
|
165442
|
+
if (host.startsWith("fe80:")) {
|
|
165443
|
+
return `embedding endpoint host ${host} is link-local / cloud metadata (blocked)`;
|
|
165444
|
+
}
|
|
165445
|
+
return null;
|
|
165446
|
+
}
|
|
165447
|
+
|
|
165316
165448
|
// ../plugin/src/features/magic-context/memory/embedding-openai.ts
|
|
165317
|
-
init_logger();
|
|
165318
165449
|
function normalizeEndpoint2(endpoint) {
|
|
165319
165450
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
165320
165451
|
}
|
|
@@ -165356,6 +165487,12 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
165356
165487
|
this.initialized = false;
|
|
165357
165488
|
return false;
|
|
165358
165489
|
}
|
|
165490
|
+
const blockedReason = blockedEmbeddingEndpointReason(this.endpoint);
|
|
165491
|
+
if (blockedReason) {
|
|
165492
|
+
log(`[magic-context] embedding endpoint blocked: ${blockedReason}`);
|
|
165493
|
+
this.initialized = false;
|
|
165494
|
+
return false;
|
|
165495
|
+
}
|
|
165359
165496
|
this.initialized = true;
|
|
165360
165497
|
return true;
|
|
165361
165498
|
}
|
|
@@ -165401,6 +165538,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
165401
165538
|
...this.inputType ? { input_type: this.inputType } : {},
|
|
165402
165539
|
...this.truncate ? { truncate: this.truncate } : {}
|
|
165403
165540
|
}),
|
|
165541
|
+
redirect: "error",
|
|
165404
165542
|
signal: internalController.signal
|
|
165405
165543
|
});
|
|
165406
165544
|
if (!response.ok) {
|
|
@@ -165530,7 +165668,6 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
165530
165668
|
|
|
165531
165669
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
165532
165670
|
import { createHash as createHash7, randomUUID } from "node:crypto";
|
|
165533
|
-
init_logger();
|
|
165534
165671
|
|
|
165535
165672
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
165536
165673
|
var saveStatements = new WeakMap;
|
|
@@ -165768,11 +165905,15 @@ function resolveEmbeddingConfig(config2) {
|
|
|
165768
165905
|
}
|
|
165769
165906
|
if (config2.provider === "openai-compatible") {
|
|
165770
165907
|
const apiKey = config2.api_key?.trim();
|
|
165908
|
+
const inputType = config2.input_type?.trim();
|
|
165909
|
+
const truncate = config2.truncate?.trim();
|
|
165771
165910
|
return {
|
|
165772
165911
|
provider: "openai-compatible",
|
|
165773
165912
|
model: config2.model.trim(),
|
|
165774
165913
|
endpoint: config2.endpoint.trim(),
|
|
165775
|
-
...apiKey ? { api_key: apiKey } : {}
|
|
165914
|
+
...apiKey ? { api_key: apiKey } : {},
|
|
165915
|
+
...inputType ? { input_type: inputType } : {},
|
|
165916
|
+
...truncate ? { truncate } : {}
|
|
165776
165917
|
};
|
|
165777
165918
|
}
|
|
165778
165919
|
return { provider: "off" };
|
|
@@ -165788,7 +165929,9 @@ function createProvider(config2) {
|
|
|
165788
165929
|
return new OpenAICompatibleEmbeddingProvider({
|
|
165789
165930
|
endpoint: config2.endpoint,
|
|
165790
165931
|
model: config2.model,
|
|
165791
|
-
apiKey: config2.api_key
|
|
165932
|
+
apiKey: config2.api_key,
|
|
165933
|
+
inputType: config2.input_type,
|
|
165934
|
+
truncate: config2.truncate
|
|
165792
165935
|
});
|
|
165793
165936
|
}
|
|
165794
165937
|
return new LocalEmbeddingProvider(config2.model);
|
|
@@ -166064,7 +166207,6 @@ async function embedText(text, signal) {
|
|
|
166064
166207
|
var SWEEP_MAX_WALL_CLOCK_MS2 = 10 * 60 * 1000;
|
|
166065
166208
|
|
|
166066
166209
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
166067
|
-
init_logger();
|
|
166068
166210
|
var insertStatements = new WeakMap;
|
|
166069
166211
|
var existingShasStatements = new WeakMap;
|
|
166070
166212
|
var projectCountStatements = new WeakMap;
|
|
@@ -166276,9 +166418,6 @@ async function embedUnembeddedCommits(db, projectPath) {
|
|
|
166276
166418
|
embedInProgress.delete(projectPath);
|
|
166277
166419
|
}
|
|
166278
166420
|
}
|
|
166279
|
-
// ../plugin/src/features/magic-context/git-commits/search-git-commits.ts
|
|
166280
|
-
init_logger();
|
|
166281
|
-
|
|
166282
166421
|
// ../plugin/src/features/magic-context/memory/storage-memory-fts.ts
|
|
166283
166422
|
var DEFAULT_SEARCH_LIMIT = 10;
|
|
166284
166423
|
var searchStatements = new WeakMap;
|
|
@@ -166441,7 +166580,6 @@ function searchGitCommitsSync(db, projectPath, query, options) {
|
|
|
166441
166580
|
return results.slice(0, options.limit);
|
|
166442
166581
|
}
|
|
166443
166582
|
// ../plugin/src/plugin/dream-timer.ts
|
|
166444
|
-
init_logger();
|
|
166445
166583
|
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
166446
166584
|
var activeTimer = null;
|
|
166447
166585
|
function openTimerDatabaseOrNull(context) {
|
|
@@ -166601,15 +166739,24 @@ async function sweepGitCommits(args) {
|
|
|
166601
166739
|
|
|
166602
166740
|
// ../plugin/src/plugin/embedding-bootstrap-helpers.ts
|
|
166603
166741
|
import { createHash as createHash8 } from "node:crypto";
|
|
166604
|
-
init_logger();
|
|
166605
166742
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
166606
166743
|
"embedding.api_key",
|
|
166607
166744
|
"embedding.endpoint",
|
|
166608
166745
|
"embedding.model",
|
|
166609
|
-
"embedding.provider"
|
|
166746
|
+
"embedding.provider",
|
|
166747
|
+
"embedding.input_type",
|
|
166748
|
+
"embedding.truncate"
|
|
166610
166749
|
]);
|
|
166611
166750
|
var EMBEDDING_AFFECTING_TOP_LEVEL_KEYS = new Set(["embedding", "memory", "experimental"]);
|
|
166612
|
-
var EMBEDDING_WARNING_TERMS = [
|
|
166751
|
+
var EMBEDDING_WARNING_TERMS = [
|
|
166752
|
+
"api_key",
|
|
166753
|
+
"endpoint",
|
|
166754
|
+
"model",
|
|
166755
|
+
"provider",
|
|
166756
|
+
"embedding",
|
|
166757
|
+
"input_type",
|
|
166758
|
+
"truncate"
|
|
166759
|
+
];
|
|
166613
166760
|
var loggedFailureSignatures = new Map;
|
|
166614
166761
|
function sha256Prefix2(value, length = 16) {
|
|
166615
166762
|
return createHash8("sha256").update(value).digest("hex").slice(0, length);
|
|
@@ -166675,6 +166822,31 @@ function handleUntrustedLoad(db, projectIdentity, directory, detailed) {
|
|
|
166675
166822
|
return true;
|
|
166676
166823
|
}
|
|
166677
166824
|
|
|
166825
|
+
// ../plugin/src/config/prune-config-leaf.ts
|
|
166826
|
+
function isPlainObject2(value) {
|
|
166827
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
166828
|
+
}
|
|
166829
|
+
function pruneNestedConfigLeaf(block, relativePath) {
|
|
166830
|
+
if (relativePath.length === 0)
|
|
166831
|
+
return null;
|
|
166832
|
+
const result = { ...block };
|
|
166833
|
+
let cursor = result;
|
|
166834
|
+
for (let i = 0;i < relativePath.length - 1; i++) {
|
|
166835
|
+
const seg = String(relativePath[i]);
|
|
166836
|
+
const child = cursor[seg];
|
|
166837
|
+
if (!isPlainObject2(child))
|
|
166838
|
+
return null;
|
|
166839
|
+
const clonedChild = { ...child };
|
|
166840
|
+
cursor[seg] = clonedChild;
|
|
166841
|
+
cursor = clonedChild;
|
|
166842
|
+
}
|
|
166843
|
+
const leaf = String(relativePath[relativePath.length - 1]);
|
|
166844
|
+
if (!(leaf in cursor))
|
|
166845
|
+
return null;
|
|
166846
|
+
delete cursor[leaf];
|
|
166847
|
+
return { block: result, removed: relativePath.map(String).join(".") };
|
|
166848
|
+
}
|
|
166849
|
+
|
|
166678
166850
|
// src/config/index.ts
|
|
166679
166851
|
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "node:fs";
|
|
166680
166852
|
import { homedir as homedir4 } from "node:os";
|
|
@@ -166766,10 +166938,74 @@ function migrateLegacyExperimental(rawConfig, warnings) {
|
|
|
166766
166938
|
return patched;
|
|
166767
166939
|
}
|
|
166768
166940
|
|
|
166941
|
+
// ../plugin/src/config/project-security.ts
|
|
166942
|
+
var HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
|
|
166943
|
+
var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
|
|
166944
|
+
function isPlainObject3(value) {
|
|
166945
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
166946
|
+
}
|
|
166947
|
+
function stripUnsafeProjectConfigFields(projectRaw) {
|
|
166948
|
+
const warnings = [];
|
|
166949
|
+
if ("auto_update" in projectRaw) {
|
|
166950
|
+
delete projectRaw.auto_update;
|
|
166951
|
+
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
166952
|
+
}
|
|
166953
|
+
for (const agentKey of HIDDEN_AGENT_KEYS) {
|
|
166954
|
+
const block = projectRaw[agentKey];
|
|
166955
|
+
if (!isPlainObject3(block))
|
|
166956
|
+
continue;
|
|
166957
|
+
const removed = [];
|
|
166958
|
+
for (const field of AGENT_ESCALATION_FIELDS) {
|
|
166959
|
+
if (field in block) {
|
|
166960
|
+
delete block[field];
|
|
166961
|
+
removed.push(field);
|
|
166962
|
+
}
|
|
166963
|
+
}
|
|
166964
|
+
if (removed.length > 0) {
|
|
166965
|
+
warnings.push(`Ignoring ${agentKey}.${removed.join("/")} from project config ` + "(security: a repository cannot reprogram or re-permission hidden agents).");
|
|
166966
|
+
}
|
|
166967
|
+
}
|
|
166968
|
+
return warnings;
|
|
166969
|
+
}
|
|
166970
|
+
function normalizeEndpoint3(value) {
|
|
166971
|
+
if (typeof value !== "string")
|
|
166972
|
+
return;
|
|
166973
|
+
const trimmed = value.trim().replace(/\/+$/, "");
|
|
166974
|
+
return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;
|
|
166975
|
+
}
|
|
166976
|
+
function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
|
|
166977
|
+
const projectEmbedding = projectRaw.embedding;
|
|
166978
|
+
if (!isPlainObject3(projectEmbedding))
|
|
166979
|
+
return [];
|
|
166980
|
+
const redirectsEndpoint = "endpoint" in projectEmbedding;
|
|
166981
|
+
if (!redirectsEndpoint)
|
|
166982
|
+
return [];
|
|
166983
|
+
const userEmbedding = userRaw?.embedding;
|
|
166984
|
+
if (isPlainObject3(userEmbedding)) {
|
|
166985
|
+
const projectEndpoint = normalizeEndpoint3(projectEmbedding.endpoint);
|
|
166986
|
+
const userEndpoint = normalizeEndpoint3(userEmbedding.endpoint);
|
|
166987
|
+
if (projectEndpoint !== undefined && projectEndpoint === userEndpoint) {
|
|
166988
|
+
return [];
|
|
166989
|
+
}
|
|
166990
|
+
}
|
|
166991
|
+
const providesOwnKey = typeof projectEmbedding.api_key === "string" && projectEmbedding.api_key.length > 0;
|
|
166992
|
+
if (providesOwnKey)
|
|
166993
|
+
return [];
|
|
166994
|
+
const mergedEmbedding = mergedRaw.embedding;
|
|
166995
|
+
if (!isPlainObject3(mergedEmbedding))
|
|
166996
|
+
return [];
|
|
166997
|
+
if (!("api_key" in mergedEmbedding))
|
|
166998
|
+
return [];
|
|
166999
|
+
delete mergedEmbedding.api_key;
|
|
167000
|
+
return [
|
|
167001
|
+
"Dropped inherited user embedding api_key because project config redirected " + "embedding.endpoint without supplying its own key (security: prevents key " + "exfiltration to a repository-chosen endpoint)."
|
|
167002
|
+
];
|
|
167003
|
+
}
|
|
167004
|
+
|
|
166769
167005
|
// ../plugin/src/config/variable.ts
|
|
166770
167006
|
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
166771
167007
|
import { homedir as homedir3 } from "node:os";
|
|
166772
|
-
import { dirname as dirname5, isAbsolute as
|
|
167008
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, resolve as resolve4 } from "node:path";
|
|
166773
167009
|
|
|
166774
167010
|
// ../plugin/src/shared/jsonc-parser.ts
|
|
166775
167011
|
function stripJsonComments(content) {
|
|
@@ -166830,6 +167066,21 @@ function stripJsonComments(content) {
|
|
|
166830
167066
|
// ../plugin/src/config/variable.ts
|
|
166831
167067
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
166832
167068
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
167069
|
+
function sensitiveFilePathReason(resolvedPath) {
|
|
167070
|
+
const home = homedir3();
|
|
167071
|
+
const sensitiveDirs = [
|
|
167072
|
+
{ dir: resolve4(home, ".ssh"), label: "SSH keys" },
|
|
167073
|
+
{ dir: resolve4(home, ".aws"), label: "AWS credentials" },
|
|
167074
|
+
{ dir: resolve4(home, ".gnupg"), label: "GnuPG keyring" },
|
|
167075
|
+
{ dir: resolve4(home, ".config", "gh"), label: "GitHub CLI auth" }
|
|
167076
|
+
];
|
|
167077
|
+
for (const { dir, label } of sensitiveDirs) {
|
|
167078
|
+
if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
|
|
167079
|
+
return label;
|
|
167080
|
+
}
|
|
167081
|
+
}
|
|
167082
|
+
return null;
|
|
167083
|
+
}
|
|
166833
167084
|
function substituteConfigVariables(input) {
|
|
166834
167085
|
const warnings = [];
|
|
166835
167086
|
let text = input.text;
|
|
@@ -166879,9 +167130,13 @@ function substituteConfigVariables(input) {
|
|
|
166879
167130
|
}
|
|
166880
167131
|
let filePath = rawPath.trim();
|
|
166881
167132
|
if (filePath.startsWith("~/")) {
|
|
166882
|
-
filePath =
|
|
166883
|
-
} else if (!
|
|
166884
|
-
filePath =
|
|
167133
|
+
filePath = resolve4(homedir3(), filePath.slice(2));
|
|
167134
|
+
} else if (!isAbsolute3(filePath)) {
|
|
167135
|
+
filePath = resolve4(configDir, filePath);
|
|
167136
|
+
}
|
|
167137
|
+
const sensitiveReason = sensitiveFilePathReason(filePath);
|
|
167138
|
+
if (sensitiveReason) {
|
|
167139
|
+
warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
|
|
166885
167140
|
}
|
|
166886
167141
|
if (!existsSync9(filePath)) {
|
|
166887
167142
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
@@ -166921,7 +167176,8 @@ function loadConfigFile(path7, scope) {
|
|
|
166921
167176
|
const rawText = readFileSync8(path7, "utf-8");
|
|
166922
167177
|
const substituted = substituteConfigVariables({
|
|
166923
167178
|
text: rawText,
|
|
166924
|
-
configPath: path7
|
|
167179
|
+
configPath: path7,
|
|
167180
|
+
isProjectConfig: scope === "project"
|
|
166925
167181
|
});
|
|
166926
167182
|
return {
|
|
166927
167183
|
path: path7,
|
|
@@ -166963,14 +167219,14 @@ function redactConfigValue(value) {
|
|
|
166963
167219
|
}
|
|
166964
167220
|
return typeof value;
|
|
166965
167221
|
}
|
|
166966
|
-
function
|
|
167222
|
+
function isPlainObject4(value) {
|
|
166967
167223
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
166968
167224
|
}
|
|
166969
167225
|
function mergeRawConfigs(base, override) {
|
|
166970
167226
|
const merged = { ...base };
|
|
166971
167227
|
for (const [key, overrideValue] of Object.entries(override)) {
|
|
166972
167228
|
const baseValue = merged[key];
|
|
166973
|
-
merged[key] =
|
|
167229
|
+
merged[key] = isPlainObject4(baseValue) && isPlainObject4(overrideValue) ? mergeRawConfigs(baseValue, overrideValue) : overrideValue;
|
|
166974
167230
|
}
|
|
166975
167231
|
return merged;
|
|
166976
167232
|
}
|
|
@@ -166984,10 +167240,15 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
166984
167240
|
}
|
|
166985
167241
|
const defaults = MagicContextConfigSchema.parse({});
|
|
166986
167242
|
const errorPaths = new Set;
|
|
167243
|
+
const issuePathsByKey = new Map;
|
|
166987
167244
|
for (const issue2 of parsed.error.issues) {
|
|
166988
167245
|
const topKey = issue2.path[0];
|
|
166989
167246
|
if (topKey !== undefined) {
|
|
166990
|
-
|
|
167247
|
+
const key = String(topKey);
|
|
167248
|
+
errorPaths.add(key);
|
|
167249
|
+
const paths = issuePathsByKey.get(key) ?? [];
|
|
167250
|
+
paths.push([...issue2.path]);
|
|
167251
|
+
issuePathsByKey.set(key, paths);
|
|
166991
167252
|
}
|
|
166992
167253
|
}
|
|
166993
167254
|
const patched = { ...migrated };
|
|
@@ -166995,11 +167256,32 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
166995
167256
|
for (const key of errorPaths) {
|
|
166996
167257
|
recoveredTopLevelKeys.push(key);
|
|
166997
167258
|
const isAgentConfig = key === "historian" || key === "dreamer" || key === "sidekick";
|
|
166998
|
-
delete patched[key];
|
|
166999
167259
|
if (isAgentConfig) {
|
|
167260
|
+
delete patched[key];
|
|
167000
167261
|
warnings.push(`"${key}": invalid agent configuration, ignoring. Check your magic-context.jsonc.`);
|
|
167001
167262
|
continue;
|
|
167002
167263
|
}
|
|
167264
|
+
const issuePaths = issuePathsByKey.get(key) ?? [];
|
|
167265
|
+
const rawValue = migrated[key];
|
|
167266
|
+
const allNested = issuePaths.length > 0 && issuePaths.every((p) => p.length >= 2) && typeof rawValue === "object" && rawValue !== null && !Array.isArray(rawValue);
|
|
167267
|
+
if (allNested) {
|
|
167268
|
+
let prunedBlock = {
|
|
167269
|
+
...rawValue
|
|
167270
|
+
};
|
|
167271
|
+
const prunedLeaves = [];
|
|
167272
|
+
for (const p of issuePaths) {
|
|
167273
|
+
const relative3 = p.slice(1);
|
|
167274
|
+
const result = pruneNestedConfigLeaf(prunedBlock, relative3);
|
|
167275
|
+
if (result) {
|
|
167276
|
+
prunedBlock = result.block;
|
|
167277
|
+
prunedLeaves.push(result.removed);
|
|
167278
|
+
}
|
|
167279
|
+
}
|
|
167280
|
+
patched[key] = prunedBlock;
|
|
167281
|
+
warnings.push(`"${key}": invalid nested field(s) ${prunedLeaves.map((l) => `"${l}"`).join(", ")}, using defaults for those.`);
|
|
167282
|
+
continue;
|
|
167283
|
+
}
|
|
167284
|
+
delete patched[key];
|
|
167003
167285
|
const defaultValue = defaults[key];
|
|
167004
167286
|
warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultValue)}.`);
|
|
167005
167287
|
}
|
|
@@ -167032,10 +167314,22 @@ function loadPiConfig(opts = {}) {
|
|
|
167032
167314
|
return 0;
|
|
167033
167315
|
return a.scope === "user" ? -1 : 1;
|
|
167034
167316
|
});
|
|
167317
|
+
const userRaw = mergeFiles.find((f) => f.scope === "user")?.config;
|
|
167035
167318
|
for (const loaded of mergeFiles) {
|
|
167036
167319
|
const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
|
|
167037
167320
|
warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
|
|
167038
|
-
|
|
167321
|
+
if (loaded.scope === "project") {
|
|
167322
|
+
const projectRaw = { ...loaded.config };
|
|
167323
|
+
for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
|
|
167324
|
+
warnings.push(`${prefix} ${warning}`);
|
|
167325
|
+
}
|
|
167326
|
+
rawConfig = mergeRawConfigs(rawConfig, projectRaw);
|
|
167327
|
+
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
|
|
167328
|
+
warnings.push(`${prefix} ${warning}`);
|
|
167329
|
+
}
|
|
167330
|
+
} else {
|
|
167331
|
+
rawConfig = mergeRawConfigs(rawConfig, loaded.config);
|
|
167332
|
+
}
|
|
167039
167333
|
}
|
|
167040
167334
|
const parsed = parsePiConfig(rawConfig);
|
|
167041
167335
|
warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
|
|
@@ -167110,10 +167404,22 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
167110
167404
|
return 0;
|
|
167111
167405
|
return a.scope === "user" ? -1 : 1;
|
|
167112
167406
|
});
|
|
167407
|
+
const userRaw = mergeFiles.find((f) => f.scope === "user")?.config;
|
|
167113
167408
|
for (const loaded of mergeFiles) {
|
|
167114
167409
|
const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
|
|
167115
167410
|
warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
|
|
167116
|
-
|
|
167411
|
+
if (loaded.scope === "project") {
|
|
167412
|
+
const projectRaw = { ...loaded.config };
|
|
167413
|
+
for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
|
|
167414
|
+
warnings.push(`${prefix} ${warning}`);
|
|
167415
|
+
}
|
|
167416
|
+
rawConfig = mergeRawConfigs(rawConfig, projectRaw);
|
|
167417
|
+
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
|
|
167418
|
+
warnings.push(`${prefix} ${warning}`);
|
|
167419
|
+
}
|
|
167420
|
+
} else {
|
|
167421
|
+
rawConfig = mergeRawConfigs(rawConfig, loaded.config);
|
|
167422
|
+
}
|
|
167117
167423
|
}
|
|
167118
167424
|
const recoveredTopLevelKeys = [];
|
|
167119
167425
|
const parsed = parsePiConfig(rawConfig, recoveredTopLevelKeys);
|
|
@@ -167168,7 +167474,11 @@ function registerPiDreamerProject(opts) {
|
|
|
167168
167474
|
}
|
|
167169
167475
|
const existing = registeredProjects2.get(opts.projectIdentity);
|
|
167170
167476
|
if (existing) {
|
|
167171
|
-
|
|
167477
|
+
if (existing.projectDir === opts.projectDir) {
|
|
167478
|
+
return;
|
|
167479
|
+
}
|
|
167480
|
+
existing.cleanup();
|
|
167481
|
+
registeredProjects2.delete(opts.projectIdentity);
|
|
167172
167482
|
}
|
|
167173
167483
|
registerDreamProjectDirectory(opts.projectIdentity, opts.projectDir);
|
|
167174
167484
|
const client = createPiDreamerClient(opts);
|
|
@@ -167214,7 +167524,8 @@ function registerPiDreamerProject(opts) {
|
|
|
167214
167524
|
cancelled = true;
|
|
167215
167525
|
cleanup?.();
|
|
167216
167526
|
},
|
|
167217
|
-
runOnce
|
|
167527
|
+
runOnce,
|
|
167528
|
+
projectDir: opts.projectDir
|
|
167218
167529
|
});
|
|
167219
167530
|
}
|
|
167220
167531
|
async function runPiDreamForProject(projectIdentity) {
|
|
@@ -167241,7 +167552,7 @@ async function awaitInFlightDreamers() {
|
|
|
167241
167552
|
function createPiDreamerClient(opts) {
|
|
167242
167553
|
const runner2 = piSubagentRunnerFactory();
|
|
167243
167554
|
const model = opts.config.model;
|
|
167244
|
-
const fallbackModels =
|
|
167555
|
+
const fallbackModels = resolveFallbackChain(DREAMER_AGENT, opts.config.fallback_models);
|
|
167245
167556
|
const session = {
|
|
167246
167557
|
create: async (args) => {
|
|
167247
167558
|
const sessionId = `magic-context-pi-dream-${++sessionCounter}`;
|
|
@@ -167301,15 +167612,6 @@ function createPiDreamerClient(opts) {
|
|
|
167301
167612
|
};
|
|
167302
167613
|
return { session };
|
|
167303
167614
|
}
|
|
167304
|
-
function normalizeFallbackModels(value) {
|
|
167305
|
-
if (Array.isArray(value)) {
|
|
167306
|
-
return value;
|
|
167307
|
-
}
|
|
167308
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
167309
|
-
return [value];
|
|
167310
|
-
}
|
|
167311
|
-
return;
|
|
167312
|
-
}
|
|
167313
167615
|
function readDirectory(args) {
|
|
167314
167616
|
const query = args.query;
|
|
167315
167617
|
if (typeof query !== "object" || query === null) {
|
|
@@ -167496,7 +167798,6 @@ function registerCtxDreamCommand(pi, deps) {
|
|
|
167496
167798
|
}
|
|
167497
167799
|
|
|
167498
167800
|
// ../plugin/src/hooks/magic-context/execute-flush.ts
|
|
167499
|
-
init_logger();
|
|
167500
167801
|
function executeFlush(db, sessionId) {
|
|
167501
167802
|
try {
|
|
167502
167803
|
const pendingOps = getPendingOps(db, sessionId);
|
|
@@ -167528,7 +167829,6 @@ function executeFlush(db, sessionId) {
|
|
|
167528
167829
|
import * as crypto2 from "node:crypto";
|
|
167529
167830
|
|
|
167530
167831
|
// ../plugin/src/features/magic-context/scheduler.ts
|
|
167531
|
-
init_logger();
|
|
167532
167832
|
var TTL_PATTERN = /^(\d+)([smh])$/;
|
|
167533
167833
|
var NUMERIC_PATTERN = /^\d+$/;
|
|
167534
167834
|
var UNIT_TO_MS = {
|
|
@@ -167583,6 +167883,7 @@ function createScheduler(config2) {
|
|
|
167583
167883
|
}
|
|
167584
167884
|
};
|
|
167585
167885
|
}
|
|
167886
|
+
|
|
167586
167887
|
// ../plugin/src/features/magic-context/tagger.ts
|
|
167587
167888
|
var TOOL_COMPOSITE_KEY_SEP = "\x00";
|
|
167588
167889
|
function makeToolCompositeKey(ownerMsgId, callId) {
|
|
@@ -168342,7 +168643,6 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
|
|
|
168342
168643
|
}
|
|
168343
168644
|
|
|
168344
168645
|
// ../plugin/src/hooks/magic-context/compartment-trigger.ts
|
|
168345
|
-
init_logger();
|
|
168346
168646
|
var PROACTIVE_TRIGGER_OFFSET_PERCENTAGE = 2;
|
|
168347
168647
|
var POST_DROP_TARGET_RATIO = 0.75;
|
|
168348
168648
|
var MIN_PROACTIVE_TAIL_TOKEN_ESTIMATE = 6000;
|
|
@@ -168579,9 +168879,6 @@ class BoundedSessionMap {
|
|
|
168579
168879
|
}
|
|
168580
168880
|
}
|
|
168581
168881
|
|
|
168582
|
-
// ../plugin/src/hooks/magic-context/inject-compartments.ts
|
|
168583
|
-
init_logger();
|
|
168584
|
-
|
|
168585
168882
|
// ../plugin/src/hooks/magic-context/decay-curve.ts
|
|
168586
168883
|
var H50 = 24;
|
|
168587
168884
|
var D = 25;
|
|
@@ -168645,6 +168942,9 @@ function escapeXmlAttr2(s) {
|
|
|
168645
168942
|
function escapeXmlContent2(s) {
|
|
168646
168943
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
168647
168944
|
}
|
|
168945
|
+
function isTieredRow(c) {
|
|
168946
|
+
return typeof c.p1 === "string" && c.p1.length > 0;
|
|
168947
|
+
}
|
|
168648
168948
|
function tierBody(c, tier2) {
|
|
168649
168949
|
const tiers = [c.p1, c.p2, c.p3, c.p4];
|
|
168650
168950
|
const requested = tiers[tier2 - 1];
|
|
@@ -168674,12 +168974,13 @@ function renderOneCompartment(c, tier2) {
|
|
|
168674
168974
|
const baseAttrs = `start="${c.startMessage}" end="${c.endMessage}" title="${escapeXmlAttr2(c.title)}"`;
|
|
168675
168975
|
if (tier2 >= 5)
|
|
168676
168976
|
return "";
|
|
168677
|
-
if (c.legacy === 1) {
|
|
168678
|
-
|
|
168977
|
+
if (c.legacy === 1 || !isTieredRow(c)) {
|
|
168978
|
+
const flat = (c.content ?? "").trim();
|
|
168979
|
+
if (tier2 >= 4 || flat.length === 0)
|
|
168679
168980
|
return `<compartment ${baseAttrs} />`;
|
|
168680
168981
|
return [
|
|
168681
168982
|
`<compartment ${baseAttrs}>`,
|
|
168682
|
-
escapeXmlContent2(legacyBodyForTier(
|
|
168983
|
+
escapeXmlContent2(legacyBodyForTier(flat, tier2)),
|
|
168683
168984
|
"</compartment>"
|
|
168684
168985
|
].join(`
|
|
168685
168986
|
`);
|
|
@@ -168751,7 +169052,6 @@ function extractM0Block(m0Text, tag) {
|
|
|
168751
169052
|
// ../plugin/src/hooks/magic-context/key-files-block.ts
|
|
168752
169053
|
import { readFileSync as readFileSync9, realpathSync as realpathSync4 } from "node:fs";
|
|
168753
169054
|
import { join as join14, sep as sep2 } from "node:path";
|
|
168754
|
-
init_logger();
|
|
168755
169055
|
var cachedKeyFilesBySession = new Map;
|
|
168756
169056
|
var staleUpdates = new Map;
|
|
168757
169057
|
function staleKey(update) {
|
|
@@ -168849,9 +169149,6 @@ ${blocks.join(`
|
|
|
168849
169149
|
return rendered;
|
|
168850
169150
|
}
|
|
168851
169151
|
|
|
168852
|
-
// ../plugin/src/hooks/magic-context/inject-compartments.ts
|
|
168853
|
-
await init_read_session_db();
|
|
168854
|
-
|
|
168855
169152
|
// ../plugin/src/hooks/magic-context/temporal-awareness.ts
|
|
168856
169153
|
var TEMPORAL_AWARENESS_THRESHOLD_SECONDS = 300;
|
|
168857
169154
|
var SECONDS_PER_MINUTE = 60;
|
|
@@ -169008,9 +169305,6 @@ function renderMemoryBlockV2(memories, wrapper = "project-memory") {
|
|
|
169008
169305
|
`);
|
|
169009
169306
|
}
|
|
169010
169307
|
|
|
169011
|
-
// ../plugin/src/hooks/magic-context/nudger.ts
|
|
169012
|
-
init_logger();
|
|
169013
|
-
|
|
169014
169308
|
// ../plugin/src/shared/format-bytes.ts
|
|
169015
169309
|
function formatBytes(bytes) {
|
|
169016
169310
|
if (bytes < 1024)
|
|
@@ -169212,9 +169506,6 @@ function estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags)
|
|
|
169212
169506
|
return contextUsage.percentage * (1 - dropRatio);
|
|
169213
169507
|
}
|
|
169214
169508
|
|
|
169215
|
-
// src/context-handler.ts
|
|
169216
|
-
init_logger();
|
|
169217
|
-
|
|
169218
169509
|
// ../plugin/src/shared/tag-transcript.ts
|
|
169219
169510
|
function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
|
|
169220
169511
|
const skipPrefixInjection = options.skipPrefixInjection === true;
|
|
@@ -169516,9 +169807,6 @@ function buildToolTarget(part, message) {
|
|
|
169516
169807
|
};
|
|
169517
169808
|
}
|
|
169518
169809
|
|
|
169519
|
-
// ../plugin/src/features/magic-context/search.ts
|
|
169520
|
-
init_logger();
|
|
169521
|
-
|
|
169522
169810
|
// ../plugin/src/features/magic-context/literal-probes.ts
|
|
169523
169811
|
var MAX_PROBES = 5;
|
|
169524
169812
|
var MIN_PROBE_LENGTH = 3;
|
|
@@ -169575,7 +169863,6 @@ function containsProbeVerbatim(text, probes) {
|
|
|
169575
169863
|
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
169576
169864
|
}
|
|
169577
169865
|
// ../plugin/src/features/magic-context/memory/embedding-backfill.ts
|
|
169578
|
-
init_logger();
|
|
169579
169866
|
async function ensureMemoryEmbeddings(args) {
|
|
169580
169867
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
169581
169868
|
if (!snapshot?.enabled) {
|
|
@@ -169614,7 +169901,6 @@ async function ensureMemoryEmbeddings(args) {
|
|
|
169614
169901
|
return args.existingEmbeddings;
|
|
169615
169902
|
}
|
|
169616
169903
|
// ../plugin/src/features/magic-context/memory/promotion.ts
|
|
169617
|
-
init_logger();
|
|
169618
169904
|
function isPromotableCategory(category) {
|
|
169619
169905
|
return PROMOTABLE_CATEGORIES.some((promotableCategory) => promotableCategory === category);
|
|
169620
169906
|
}
|
|
@@ -170116,17 +170402,16 @@ ${trimmedBody}…
|
|
|
170116
170402
|
}
|
|
170117
170403
|
|
|
170118
170404
|
// src/auto-search-pi.ts
|
|
170119
|
-
init_logger();
|
|
170120
170405
|
var AUTO_SEARCH_TIMEOUT_MS = 3000;
|
|
170121
170406
|
var DEFAULT_SCORE_THRESHOLD = 0.55;
|
|
170122
170407
|
var DEFAULT_MIN_PROMPT_CHARS = 20;
|
|
170123
170408
|
async function unifiedSearchWithTimeout(db, sessionId, projectPath, prompt, options, timeoutMs) {
|
|
170124
170409
|
const controller = new AbortController;
|
|
170125
170410
|
let timer;
|
|
170126
|
-
const timeoutPromise = new Promise((
|
|
170411
|
+
const timeoutPromise = new Promise((resolve5) => {
|
|
170127
170412
|
timer = setTimeout(() => {
|
|
170128
170413
|
controller.abort();
|
|
170129
|
-
|
|
170414
|
+
resolve5(null);
|
|
170130
170415
|
}, timeoutMs);
|
|
170131
170416
|
});
|
|
170132
170417
|
try {
|
|
@@ -170346,7 +170631,6 @@ ${hintText}`;
|
|
|
170346
170631
|
function clearAutoSearchForPiSession(_sessionId) {}
|
|
170347
170632
|
|
|
170348
170633
|
// src/compaction-marker-manager-pi.ts
|
|
170349
|
-
init_logger();
|
|
170350
170634
|
function applyDeferredPiCompactionMarker(deps, sessionId, pending) {
|
|
170351
170635
|
try {
|
|
170352
170636
|
const matches = getCompartmentsByEndMessageId(deps.db, sessionId, pending.endMessageId);
|
|
@@ -170488,7 +170772,6 @@ function stripSystemInjection(text) {
|
|
|
170488
170772
|
}
|
|
170489
170773
|
|
|
170490
170774
|
// src/heuristic-cleanup-pi.ts
|
|
170491
|
-
init_logger();
|
|
170492
170775
|
var DEDUP_SAFE_TOOLS = new Set([
|
|
170493
170776
|
"mcp_grep",
|
|
170494
170777
|
"mcp_read",
|
|
@@ -170738,9 +171021,6 @@ function buildMessageIdToMaxTagFromTargets(targets) {
|
|
|
170738
171021
|
return byMessage;
|
|
170739
171022
|
}
|
|
170740
171023
|
|
|
170741
|
-
// src/inject-compartments-pi.ts
|
|
170742
|
-
init_logger();
|
|
170743
|
-
|
|
170744
171024
|
// src/read-session-pi.ts
|
|
170745
171025
|
var SYNTH_USER_ID_PREFIX = "synth-user-";
|
|
170746
171026
|
function resolvePiStableId(msg, index, entryIds, entryIdByRef) {
|
|
@@ -171123,6 +171403,16 @@ function safeGetActiveUserMemoriesPi(db) {
|
|
|
171123
171403
|
throw error51;
|
|
171124
171404
|
}
|
|
171125
171405
|
}
|
|
171406
|
+
function memoryProjectPath(state) {
|
|
171407
|
+
return state.memoryEnabled === false ? undefined : state.projectIdentity;
|
|
171408
|
+
}
|
|
171409
|
+
var EMPTY_PI_HARD_SIGNALS = {
|
|
171410
|
+
systemHash: "",
|
|
171411
|
+
toolSetHash: "",
|
|
171412
|
+
modelKey: "",
|
|
171413
|
+
cacheExpired: false,
|
|
171414
|
+
lastResponseTime: 0
|
|
171415
|
+
};
|
|
171126
171416
|
function decodeCachedM0(value) {
|
|
171127
171417
|
if (!value)
|
|
171128
171418
|
return null;
|
|
@@ -171169,7 +171459,10 @@ function getCachedMarkers(db, state, compartmentsForNormalization) {
|
|
|
171169
171459
|
sessionFactsVersion: meta3.cachedM0SessionFactsVersion,
|
|
171170
171460
|
materializedAt: meta3.cachedM0MaterializedAt,
|
|
171171
171461
|
upgradeState: meta3.cachedM0UpgradeState,
|
|
171172
|
-
lastBaselineEndMessageId: cachedBoundary
|
|
171462
|
+
lastBaselineEndMessageId: cachedBoundary,
|
|
171463
|
+
systemHash: meta3.cachedM0SystemHash ?? "",
|
|
171464
|
+
toolSetHash: meta3.cachedM0ToolSetHash ?? "",
|
|
171465
|
+
modelKey: meta3.cachedM0ModelKey ?? ""
|
|
171173
171466
|
};
|
|
171174
171467
|
}
|
|
171175
171468
|
function lastBaselineEndMessageId(compartments) {
|
|
@@ -171180,24 +171473,25 @@ function readCurrentMarkers(db, state, projectDocsHash) {
|
|
|
171180
171473
|
return readCurrentMarkersFromCompartments(db, state, getCompartments(db, state.sessionId), projectDocsHash);
|
|
171181
171474
|
}
|
|
171182
171475
|
function readCurrentMarkersFromCompartments(db, state, compartments, projectDocsHash) {
|
|
171183
|
-
const
|
|
171184
|
-
|
|
171185
|
-
|
|
171186
|
-
]);
|
|
171187
|
-
const projectState = getProjectState(db, state.projectIdentity);
|
|
171476
|
+
const memPath = memoryProjectPath(state);
|
|
171477
|
+
const memories = memPath ? getMemoriesByProject(db, memPath, ["active", "permanent"]) : [];
|
|
171478
|
+
const projectState = memPath ? getProjectState(db, memPath) : undefined;
|
|
171188
171479
|
const globalState = getProjectState(db, GLOBAL_USER_PROFILE_PROJECT_PATH);
|
|
171189
171480
|
return {
|
|
171190
171481
|
maxCompartmentSeq: compartments.length > 0 ? compartments.reduce((max, compartment) => compartment.sequence > max ? compartment.sequence : max, EMPTY_MAX_COMPARTMENT_SEQ) : EMPTY_MAX_COMPARTMENT_SEQ,
|
|
171191
171482
|
maxMemoryId: memories.length > 0 ? memories.reduce((max, memory) => memory.id > max ? memory.id : max, 0) : 0,
|
|
171192
171483
|
maxMutationId: getMaxM0MutationId(db, state.sessionId) ?? 0,
|
|
171193
|
-
maxMemoryMutationId: getMaxMemoryMutationId(db,
|
|
171484
|
+
maxMemoryMutationId: memPath ? getMaxMemoryMutationId(db, memPath) ?? 0 : 0,
|
|
171194
171485
|
projectMemoryEpoch: projectState?.projectMemoryEpoch ?? 0,
|
|
171195
171486
|
projectUserProfileVersion: globalState?.projectUserProfileVersion ?? 0,
|
|
171196
171487
|
projectDocsHash: projectDocsHash ?? readProjectDocsCanonical(state.projectDirectory).canonicalHash,
|
|
171197
171488
|
sessionFactsVersion: getSessionFactsVersion(db, state.sessionId),
|
|
171198
171489
|
materializedAt: Date.now(),
|
|
171199
171490
|
upgradeState: `${PI_M0_UPGRADE_STATE}:${compartments.some((c) => c.legacy === 1) ? "legacy" : "ready"}`,
|
|
171200
|
-
lastBaselineEndMessageId: lastBaselineEndMessageId(compartments)
|
|
171491
|
+
lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
|
|
171492
|
+
systemHash: (state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
|
|
171493
|
+
toolSetHash: (state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).toolSetHash,
|
|
171494
|
+
modelKey: (state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey
|
|
171201
171495
|
};
|
|
171202
171496
|
}
|
|
171203
171497
|
function mustMaterializePi(state, db, currentCompartmentsOverride) {
|
|
@@ -171214,7 +171508,19 @@ function mustMaterializePi(state, db, currentCompartmentsOverride) {
|
|
|
171214
171508
|
if (getCachedMarkers(db, state, currentCompartments) === null) {
|
|
171215
171509
|
return { value: true, reason: "cache_invalid" };
|
|
171216
171510
|
}
|
|
171217
|
-
const
|
|
171511
|
+
const hard = state.hardSignals ?? EMPTY_PI_HARD_SIGNALS;
|
|
171512
|
+
if (hard.modelKey !== "" && hard.modelKey !== (meta3.cachedM0ModelKey ?? "")) {
|
|
171513
|
+
return { value: true, reason: "model_change" };
|
|
171514
|
+
}
|
|
171515
|
+
if (hard.systemHash !== "" && hard.systemHash !== (meta3.cachedM0SystemHash ?? "")) {
|
|
171516
|
+
return { value: true, reason: "system_hash" };
|
|
171517
|
+
}
|
|
171518
|
+
if (hard.toolSetHash !== "" && hard.toolSetHash !== (meta3.cachedM0ToolSetHash ?? "")) {
|
|
171519
|
+
return { value: true, reason: "tool_set_hash" };
|
|
171520
|
+
}
|
|
171521
|
+
if (hard.cacheExpired && hard.lastResponseTime > 0 && hard.lastResponseTime > (meta3.cachedM0MaterializedAt ?? 0)) {
|
|
171522
|
+
return { value: true, reason: "ttl_idle" };
|
|
171523
|
+
}
|
|
171218
171524
|
if (meta3.cachedM0UpgradeState !== current.upgradeState) {
|
|
171219
171525
|
return { value: true, reason: "renderer_upgrade" };
|
|
171220
171526
|
}
|
|
@@ -171224,15 +171530,9 @@ function mustMaterializePi(state, db, currentCompartmentsOverride) {
|
|
|
171224
171530
|
if (current.projectMemoryEpoch !== (meta3.cachedM0ProjectMemoryEpoch ?? 0)) {
|
|
171225
171531
|
return { value: true, reason: "project_memory_change" };
|
|
171226
171532
|
}
|
|
171227
|
-
if (current.projectUserProfileVersion !== (meta3.cachedM0ProjectUserProfileVersion ?? 0)) {
|
|
171228
|
-
return { value: true, reason: "user_profile_change" };
|
|
171229
|
-
}
|
|
171230
171533
|
if (current.maxMutationId !== (meta3.cachedM0MaxMutationId ?? 0)) {
|
|
171231
171534
|
return { value: true, reason: "pending_mutations" };
|
|
171232
171535
|
}
|
|
171233
|
-
if (current.maxCompartmentSeq !== cachedMaxCompartmentSeq) {
|
|
171234
|
-
return { value: true, reason: "new_compartment" };
|
|
171235
|
-
}
|
|
171236
171536
|
return { value: false, reason: null };
|
|
171237
171537
|
}
|
|
171238
171538
|
function renderUserProfileBlock(db, wrapper = "user-profile", memoriesOverride) {
|
|
@@ -171245,7 +171545,8 @@ ${memories.map((memory) => `- ${escapeXmlContent(memory.content)}`).join(`
|
|
|
171245
171545
|
</${wrapper}>`;
|
|
171246
171546
|
}
|
|
171247
171547
|
function renderM0Pi(state, db, projectDocs = readProjectDocsCanonical(state.projectDirectory).renderedBlock, decayPressureMultiplier = 1, memoriesOverride, compartmentsOverride, userProfileOverride) {
|
|
171248
|
-
const
|
|
171548
|
+
const memPath = memoryProjectPath(state);
|
|
171549
|
+
const allMemories = memoriesOverride ?? (memPath ? getMemoriesByProject(db, memPath, ["active", "permanent"]) : []);
|
|
171249
171550
|
const memories = allMemories.length > 0 ? trimMemoriesToBudgetV2(state.sessionId, allMemories, state.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS).renderOrder : allMemories;
|
|
171250
171551
|
const memoryBlock = memories.length > 0 ? renderMemoryBlockV2(memories) : undefined;
|
|
171251
171552
|
const baseHistoryBudget = state.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS;
|
|
@@ -171295,24 +171596,28 @@ class PiMaterializeContentionError extends Error {
|
|
|
171295
171596
|
}
|
|
171296
171597
|
}
|
|
171297
171598
|
function readFrozenM0InputsPi(state, db, docs = readProjectDocsCanonical(state.projectDirectory), memoryCutoff) {
|
|
171599
|
+
const memPath = memoryProjectPath(state);
|
|
171298
171600
|
const read = db.transaction(() => {
|
|
171299
171601
|
const compartments = getCompartments(db, state.sessionId);
|
|
171300
|
-
const memories = getMemoriesByProject(db,
|
|
171602
|
+
const memories = memPath ? getMemoriesByProject(db, memPath, ["active", "permanent"], memoryCutoff) : [];
|
|
171301
171603
|
const userProfile = safeGetActiveUserMemoriesPi(db);
|
|
171302
|
-
const projectState = getProjectState(db,
|
|
171604
|
+
const projectState = memPath ? getProjectState(db, memPath) : undefined;
|
|
171303
171605
|
const globalState = getProjectState(db, GLOBAL_USER_PROFILE_PROJECT_PATH);
|
|
171304
171606
|
const markers = {
|
|
171305
171607
|
maxCompartmentSeq: compartments.reduce((max, compartment) => compartment.sequence > max ? compartment.sequence : max, EMPTY_MAX_COMPARTMENT_SEQ),
|
|
171306
171608
|
maxMemoryId: memories.reduce((max, memory) => memory.id > max ? memory.id : max, 0),
|
|
171307
171609
|
maxMutationId: getMaxM0MutationId(db, state.sessionId) ?? 0,
|
|
171308
|
-
maxMemoryMutationId: getMaxMemoryMutationId(db,
|
|
171610
|
+
maxMemoryMutationId: memPath ? getMaxMemoryMutationId(db, memPath) ?? 0 : 0,
|
|
171309
171611
|
projectMemoryEpoch: projectState?.projectMemoryEpoch ?? 0,
|
|
171310
171612
|
projectUserProfileVersion: globalState?.projectUserProfileVersion ?? 0,
|
|
171311
171613
|
projectDocsHash: docs.canonicalHash,
|
|
171312
171614
|
sessionFactsVersion: getSessionFactsVersion(db, state.sessionId),
|
|
171313
171615
|
materializedAt: Date.now(),
|
|
171314
171616
|
upgradeState: `${PI_M0_UPGRADE_STATE}:${compartments.some((c) => c.legacy === 1) ? "legacy" : "ready"}`,
|
|
171315
|
-
lastBaselineEndMessageId: lastBaselineEndMessageId(compartments)
|
|
171617
|
+
lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
|
|
171618
|
+
systemHash: (state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
|
|
171619
|
+
toolSetHash: (state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).toolSetHash,
|
|
171620
|
+
modelKey: (state.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey
|
|
171316
171621
|
};
|
|
171317
171622
|
return { docs, markers, compartments, memories, userProfile };
|
|
171318
171623
|
});
|
|
@@ -171388,7 +171693,10 @@ function materializeM0Pi(state, db) {
|
|
|
171388
171693
|
projectDocsHash: snapshotMarkers.projectDocsHash,
|
|
171389
171694
|
materializedAt: snapshotMarkers.materializedAt,
|
|
171390
171695
|
sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
|
|
171391
|
-
upgradeState: snapshotMarkers.upgradeState
|
|
171696
|
+
upgradeState: snapshotMarkers.upgradeState,
|
|
171697
|
+
systemHash: snapshotMarkers.systemHash,
|
|
171698
|
+
toolSetHash: snapshotMarkers.toolSetHash,
|
|
171699
|
+
modelKey: snapshotMarkers.modelKey
|
|
171392
171700
|
});
|
|
171393
171701
|
db.prepare("UPDATE session_meta SET memory_block_count = ?, memory_block_ids = ? WHERE session_id = ?").run(renderedMemoryIds.length, JSON.stringify(renderedMemoryIds), state.sessionId);
|
|
171394
171702
|
setCachedBoundary(db, state.sessionId, snapshotMarkers.lastBaselineEndMessageId);
|
|
@@ -171470,20 +171778,21 @@ ${lines.join(`
|
|
|
171470
171778
|
count: mutations.length
|
|
171471
171779
|
};
|
|
171472
171780
|
}
|
|
171473
|
-
function renderM1PiWithMetadata(state, db, markers, renderedMemoryIds, preRenderedKeyFilesBlock) {
|
|
171781
|
+
function renderM1PiWithMetadata(state, db, markers, renderedMemoryIds, preRenderedKeyFilesBlock, compartmentsOverride) {
|
|
171474
171782
|
const sections = [];
|
|
171475
171783
|
const keyFiles = renderedKeyFilesBlockPi(state, db, preRenderedKeyFilesBlock);
|
|
171476
171784
|
if (keyFiles)
|
|
171477
171785
|
sections.push(keyFiles);
|
|
171478
|
-
const
|
|
171786
|
+
const memPath = memoryProjectPath(state);
|
|
171787
|
+
const memoryUpdates = memPath ? renderMemoryUpdatesBlockPi({
|
|
171479
171788
|
db,
|
|
171480
|
-
projectPath:
|
|
171789
|
+
projectPath: memPath,
|
|
171481
171790
|
afterId: markers.maxMemoryMutationId,
|
|
171482
171791
|
renderedMemoryIds
|
|
171483
|
-
});
|
|
171792
|
+
}) : { block: undefined, count: 0 };
|
|
171484
171793
|
if (memoryUpdates.block)
|
|
171485
171794
|
sections.push(memoryUpdates.block);
|
|
171486
|
-
const newCompartments = getCompartments(db, state.sessionId).filter((compartment) => compartment.sequence > markers.maxCompartmentSeq);
|
|
171795
|
+
const newCompartments = (compartmentsOverride ?? getCompartments(db, state.sessionId)).filter((compartment) => compartment.sequence > markers.maxCompartmentSeq);
|
|
171487
171796
|
if (newCompartments.length > 0) {
|
|
171488
171797
|
const body = newCompartments.map((compartment) => renderCompartmentAtTier(compartment, 1)).join(`
|
|
171489
171798
|
|
|
@@ -171492,7 +171801,7 @@ function renderM1PiWithMetadata(state, db, markers, renderedMemoryIds, preRender
|
|
|
171492
171801
|
${body}
|
|
171493
171802
|
</new-compartments>`);
|
|
171494
171803
|
}
|
|
171495
|
-
const newMemories = getMemoriesByProject(db,
|
|
171804
|
+
const newMemories = memPath ? getMemoriesByProject(db, memPath, ["active", "permanent"], markers.materializedAt).filter((memory) => memory.id > markers.maxMemoryId) : [];
|
|
171496
171805
|
if (newMemories.length > 0) {
|
|
171497
171806
|
const memoryBudget = state.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS;
|
|
171498
171807
|
const trimmedNewMemories = trimMemoriesToBudgetV2(state.sessionId, newMemories, Math.max(1, Math.floor(memoryBudget * 0.25))).renderOrder;
|
|
@@ -171554,6 +171863,9 @@ function readCachedPiM0M1Row(db, sessionId) {
|
|
|
171554
171863
|
cached_m0_materialized_at,
|
|
171555
171864
|
cached_m0_session_facts_version,
|
|
171556
171865
|
cached_m0_upgrade_state,
|
|
171866
|
+
cached_m0_system_hash,
|
|
171867
|
+
cached_m0_tool_set_hash,
|
|
171868
|
+
cached_m0_model_key,
|
|
171557
171869
|
cached_m0_last_baseline_end_message_id,
|
|
171558
171870
|
memory_block_ids
|
|
171559
171871
|
FROM session_meta
|
|
@@ -171591,14 +171903,17 @@ function markersFromCachedPiRow(row, compartmentsForNormalization) {
|
|
|
171591
171903
|
materializedAt: row.cached_m0_materialized_at,
|
|
171592
171904
|
sessionFactsVersion: row.cached_m0_session_facts_version,
|
|
171593
171905
|
upgradeState: row.cached_m0_upgrade_state,
|
|
171594
|
-
lastBaselineEndMessageId: typeof row.cached_m0_last_baseline_end_message_id === "string" && row.cached_m0_last_baseline_end_message_id.length > 0 ? row.cached_m0_last_baseline_end_message_id : null
|
|
171906
|
+
lastBaselineEndMessageId: typeof row.cached_m0_last_baseline_end_message_id === "string" && row.cached_m0_last_baseline_end_message_id.length > 0 ? row.cached_m0_last_baseline_end_message_id : null,
|
|
171907
|
+
systemHash: row.cached_m0_system_hash ?? "",
|
|
171908
|
+
toolSetHash: row.cached_m0_tool_set_hash ?? "",
|
|
171909
|
+
modelKey: row.cached_m0_model_key ?? ""
|
|
171595
171910
|
};
|
|
171596
171911
|
}
|
|
171597
171912
|
function cachedPiRowMatchesSnapshot(args) {
|
|
171598
171913
|
const rowMarkers = markersFromCachedPiRow(args.row, args.compartmentsForNormalization);
|
|
171599
171914
|
if (!rowMarkers)
|
|
171600
171915
|
return false;
|
|
171601
|
-
return bufferEqualsNullable(args.row.cached_m0_bytes, args.m0Bytes) && rowMarkers.projectMemoryEpoch === args.markers.projectMemoryEpoch && rowMarkers.projectUserProfileVersion === args.markers.projectUserProfileVersion && rowMarkers.maxCompartmentSeq === args.markers.maxCompartmentSeq && rowMarkers.maxMemoryId === args.markers.maxMemoryId && rowMarkers.maxMutationId === args.markers.maxMutationId && rowMarkers.maxMemoryMutationId === args.markers.maxMemoryMutationId && (rowMarkers.projectDocsHash ?? "") === (args.markers.projectDocsHash ?? "") && rowMarkers.materializedAt === args.markers.materializedAt && rowMarkers.sessionFactsVersion === args.markers.sessionFactsVersion && (rowMarkers.upgradeState ?? null) === (args.markers.upgradeState ?? null);
|
|
171916
|
+
return bufferEqualsNullable(args.row.cached_m0_bytes, args.m0Bytes) && rowMarkers.projectMemoryEpoch === args.markers.projectMemoryEpoch && rowMarkers.projectUserProfileVersion === args.markers.projectUserProfileVersion && rowMarkers.maxCompartmentSeq === args.markers.maxCompartmentSeq && rowMarkers.maxMemoryId === args.markers.maxMemoryId && rowMarkers.maxMutationId === args.markers.maxMutationId && rowMarkers.maxMemoryMutationId === args.markers.maxMemoryMutationId && (rowMarkers.projectDocsHash ?? "") === (args.markers.projectDocsHash ?? "") && rowMarkers.materializedAt === args.markers.materializedAt && rowMarkers.sessionFactsVersion === args.markers.sessionFactsVersion && (rowMarkers.upgradeState ?? null) === (args.markers.upgradeState ?? null) && (rowMarkers.systemHash ?? "") === (args.markers.systemHash ?? "") && (rowMarkers.toolSetHash ?? "") === (args.markers.toolSetHash ?? "") && (rowMarkers.modelKey ?? "") === (args.markers.modelKey ?? "");
|
|
171602
171917
|
}
|
|
171603
171918
|
function decodeCachedM1(row, sessionId) {
|
|
171604
171919
|
if (!row.cached_m1_bytes) {
|
|
@@ -171656,14 +171971,16 @@ function softRefreshCachedM1Pi(args) {
|
|
|
171656
171971
|
if (!markers) {
|
|
171657
171972
|
throw new PiMaterializeContentionError(`invalid cached m[0] markers for ${args.state.sessionId}`);
|
|
171658
171973
|
}
|
|
171659
|
-
const rendered = renderM1PiWithMetadata(args.state, args.db, markers, parseMemoryBlockIds(row.memory_block_ids), preRenderedKeyFilesBlock);
|
|
171974
|
+
const rendered = renderM1PiWithMetadata(args.state, args.db, markers, parseMemoryBlockIds(row.memory_block_ids), preRenderedKeyFilesBlock, args.compartmentsForNormalization);
|
|
171660
171975
|
const m1Bytes = Buffer.from(rendered.text, "utf8");
|
|
171661
|
-
|
|
171976
|
+
const latestCompartment = args.compartmentsForNormalization.at(-1);
|
|
171977
|
+
const advancedBoundary = latestCompartment?.endMessageId && latestCompartment.endMessageId.length > 0 ? latestCompartment.endMessageId : markers.lastBaselineEndMessageId;
|
|
171978
|
+
args.db.prepare("UPDATE session_meta SET cached_m1_bytes = ?, cached_m0_last_baseline_end_message_id = ? WHERE session_id = ?").run(m1Bytes, advancedBoundary, args.state.sessionId);
|
|
171662
171979
|
args.db.exec("COMMIT");
|
|
171663
171980
|
return {
|
|
171664
171981
|
m0: decodeCachedM0(row.cached_m0_bytes) ?? "",
|
|
171665
171982
|
m1: rendered.text,
|
|
171666
|
-
markers,
|
|
171983
|
+
markers: { ...markers, lastBaselineEndMessageId: advancedBoundary },
|
|
171667
171984
|
memoryUpdateCount: rendered.memoryUpdateCount,
|
|
171668
171985
|
recomputed: true
|
|
171669
171986
|
};
|
|
@@ -171782,8 +172099,15 @@ function injectM0M1Pi(state, db, piMessages, entryIds, recomputeM1ThisPass = fal
|
|
|
171782
172099
|
m1 = replayed.m1;
|
|
171783
172100
|
markers = replayed.markers;
|
|
171784
172101
|
}
|
|
171785
|
-
const
|
|
171786
|
-
|
|
172102
|
+
const M0_DRIFT_RATIO_FLOOR_TOKENS = 500;
|
|
172103
|
+
const M1_DRIFT_RATIO = 0.15;
|
|
172104
|
+
const M1_ABSOLUTE_CAP_RATIO = 0.2;
|
|
172105
|
+
const m1AbsoluteBudget = (state.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS) * M1_ABSOLUTE_CAP_RATIO;
|
|
172106
|
+
const m1HasContent = m1 !== PI_M1_PLACEHOLDER;
|
|
172107
|
+
const m1Tokens = m1HasContent ? estimateTokens(m1) : 0;
|
|
172108
|
+
const m0Tokens = estimateTokens(m0);
|
|
172109
|
+
const m1OverAbsoluteCap = m1HasContent && m1Tokens > m1AbsoluteBudget;
|
|
172110
|
+
if (!materialized && !contentionExhausted && m1Recomputed && recomputeM1ThisPass && (memoryUpdateCount > 40 || m1OverAbsoluteCap || m1HasContent && m0Tokens >= M0_DRIFT_RATIO_FLOOR_TOKENS && m1Tokens > m0Tokens * M1_DRIFT_RATIO)) {
|
|
171787
172111
|
decision = { value: true, reason: "drift" };
|
|
171788
172112
|
try {
|
|
171789
172113
|
const result = materializeM0PiWithRetry(state, db);
|
|
@@ -171804,10 +172128,10 @@ function injectM0M1Pi(state, db, piMessages, entryIds, recomputeM1ThisPass = fal
|
|
|
171804
172128
|
injected: true,
|
|
171805
172129
|
compartmentCount: getCompartments(db, state.sessionId).length,
|
|
171806
172130
|
factCount: 0,
|
|
171807
|
-
memoryCount: getMemoriesByProject(db, state
|
|
172131
|
+
memoryCount: memoryProjectPath(state) ? getMemoriesByProject(db, memoryProjectPath(state), [
|
|
171808
172132
|
"active",
|
|
171809
172133
|
"permanent"
|
|
171810
|
-
]).length,
|
|
172134
|
+
]).length : 0,
|
|
171811
172135
|
skippedVisibleMessages,
|
|
171812
172136
|
m0Materialized: materialized,
|
|
171813
172137
|
m0Reason: decision.reason,
|
|
@@ -171966,7 +172290,6 @@ function isRecord3(value) {
|
|
|
171966
172290
|
}
|
|
171967
172291
|
|
|
171968
172292
|
// ../plugin/src/features/magic-context/compartment-embedding.ts
|
|
171969
|
-
init_logger();
|
|
171970
172293
|
async function embedAndStoreCompartments(db, sessionId, projectPath, compartments) {
|
|
171971
172294
|
if (compartments.length === 0)
|
|
171972
172295
|
return;
|
|
@@ -172863,7 +173186,6 @@ Memory is disabled for this project: do NOT emit a <facts> block. Produce compar
|
|
|
172863
173186
|
}
|
|
172864
173187
|
|
|
172865
173188
|
// ../plugin/src/hooks/magic-context/compartment-runner-drop-queue.ts
|
|
172866
|
-
init_logger();
|
|
172867
173189
|
function queueDropsForCompartmentalizedMessages(db, sessionId, upToMessageIndex) {
|
|
172868
173190
|
const tags = getTagsBySession(db, sessionId);
|
|
172869
173191
|
const { messageFileKeys, toolObservations } = getRawSessionTagKeysThrough(sessionId, upToMessageIndex);
|
|
@@ -173105,6 +173427,27 @@ function validateHistorianOutput(text, _sessionId, chunk, _priorCompartments, se
|
|
|
173105
173427
|
events: parsed.events.length > 0 ? parsed.events : undefined
|
|
173106
173428
|
};
|
|
173107
173429
|
}
|
|
173430
|
+
var HISTORIAN_PERSISTENT_FAILURE_THRESHOLD = 3;
|
|
173431
|
+
function buildHistorianFailureNotice(failureCount, lastError) {
|
|
173432
|
+
if (failureCount >= HISTORIAN_PERSISTENT_FAILURE_THRESHOLD) {
|
|
173433
|
+
return [
|
|
173434
|
+
"## Magic Context — history comparting needs attention",
|
|
173435
|
+
"",
|
|
173436
|
+
`Magic Context has been unable to compart this session's history ${failureCount} times in a row. This usually means the configured historian model is misconfigured or unreachable (Magic Context already retried every fallback model automatically).`,
|
|
173437
|
+
"",
|
|
173438
|
+
`Last error: ${lastError}`,
|
|
173439
|
+
"",
|
|
173440
|
+
"Check your historian model in magic-context.jsonc, then restart. Your conversation keeps working normally in the meantime — this only affects how older history is summarized."
|
|
173441
|
+
].join(`
|
|
173442
|
+
`);
|
|
173443
|
+
}
|
|
173444
|
+
return [
|
|
173445
|
+
"## Magic Context",
|
|
173446
|
+
"",
|
|
173447
|
+
"Hit a transient issue comparting history this turn — Magic Context will retry automatically on the next turn. Nothing is lost and your conversation continues normally. You'll only be alerted again if this keeps happening."
|
|
173448
|
+
].join(`
|
|
173449
|
+
`);
|
|
173450
|
+
}
|
|
173108
173451
|
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError) {
|
|
173109
173452
|
return [
|
|
173110
173453
|
originalPrompt,
|
|
@@ -174943,7 +175286,7 @@ ${body}
|
|
|
174943
175286
|
function renderSessionRefCompartment(c) {
|
|
174944
175287
|
const importance = c.importance ?? 50;
|
|
174945
175288
|
const attrs = `start="${c.startMessage}" end="${c.endMessage}" title="${escapeXmlAttr(c.title)}"` + (c.episodeType ? ` episode_type="${escapeXmlAttr(c.episodeType)}"` : "") + ` importance="${importance}"`;
|
|
174946
|
-
if (c.p1
|
|
175289
|
+
if (typeof c.p1 === "string" && c.p1.length > 0) {
|
|
174947
175290
|
const p4 = c.p4 && c.p4.length > 0 ? `<p4>
|
|
174948
175291
|
${escapeXmlContent(c.p4)}
|
|
174949
175292
|
</p4>` : "<p4/>";
|
|
@@ -174987,7 +175330,6 @@ function buildReferenceBlocks(args) {
|
|
|
174987
175330
|
}
|
|
174988
175331
|
|
|
174989
175332
|
// src/pi-historian-runner.ts
|
|
174990
|
-
init_logger();
|
|
174991
175333
|
var HISTORIAN_AGENT_NAME = "magic-context-historian";
|
|
174992
175334
|
var DEFAULT_HISTORIAN_TIMEOUT_MS2 = 120000;
|
|
174993
175335
|
var HISTORIAN_ALERT_COOLDOWN_MS = 60 * 1000;
|
|
@@ -175045,8 +175387,10 @@ async function runPiHistorian(deps) {
|
|
|
175045
175387
|
const existingValidationError = validateStoredCompartments(priorCompartments);
|
|
175046
175388
|
if (existingValidationError) {
|
|
175047
175389
|
sessionLog(sessionId, `historian failure: source=existing-validation reason="${existingValidationError}"`);
|
|
175048
|
-
|
|
175049
|
-
|
|
175390
|
+
{
|
|
175391
|
+
const failCount = incrementHistorianFailure(db, sessionId, existingValidationError);
|
|
175392
|
+
await notify(buildHistorianFailureNotice(failCount, existingValidationError));
|
|
175393
|
+
}
|
|
175050
175394
|
return;
|
|
175051
175395
|
}
|
|
175052
175396
|
const offset = priorCompartments.length > 0 ? priorCompartments[priorCompartments.length - 1].endMessage + 1 : 1;
|
|
@@ -175065,8 +175409,10 @@ async function runPiHistorian(deps) {
|
|
|
175065
175409
|
const chunkCoverageError = validateChunkCoverage(chunk);
|
|
175066
175410
|
if (chunkCoverageError) {
|
|
175067
175411
|
sessionLog(sessionId, `historian failure: source=chunk-coverage reason="${chunkCoverageError}" chunkRange=${chunk.startIndex}-${chunk.endIndex}`);
|
|
175068
|
-
|
|
175069
|
-
|
|
175412
|
+
{
|
|
175413
|
+
const failCount = incrementHistorianFailure(db, sessionId, chunkCoverageError);
|
|
175414
|
+
await notify(buildHistorianFailureNotice(failCount, chunkCoverageError));
|
|
175415
|
+
}
|
|
175070
175416
|
return;
|
|
175071
175417
|
}
|
|
175072
175418
|
const projectPath = resolveProjectIdentity(directory);
|
|
@@ -175195,8 +175541,10 @@ ${chunk.text}`,
|
|
|
175195
175541
|
if (validatedPass.kind !== "ok") {
|
|
175196
175542
|
const errorMsg = validatedPass.kind === "validation-failed" ? validatedPass.error : validatedPass.kind === "spawn-failed" ? `subagent run failed (${validatedPass.reason}): ${validatedPass.error}` : "historian returned no usable text";
|
|
175197
175543
|
sessionLog(sessionId, `historian failure: ${errorMsg}`);
|
|
175198
|
-
|
|
175199
|
-
|
|
175544
|
+
{
|
|
175545
|
+
const failCount = incrementHistorianFailure(db, sessionId, errorMsg);
|
|
175546
|
+
await notify(buildHistorianFailureNotice(failCount, errorMsg));
|
|
175547
|
+
}
|
|
175200
175548
|
return;
|
|
175201
175549
|
}
|
|
175202
175550
|
if (twoPass && validatedPass.kind === "ok") {
|
|
@@ -175241,8 +175589,10 @@ ${chunk.text}`,
|
|
|
175241
175589
|
if (lastNewEnd + 1 <= offset) {
|
|
175242
175590
|
const errorMsg = `historian returned compartments that did not advance past raw message ${offset - 1}`;
|
|
175243
175591
|
sessionLog(sessionId, `historian failure: source=no-progress newCompartmentCount=${newCompartments.length} lastNewEnd=${lastNewEnd} priorEnd=${offset - 1}`);
|
|
175244
|
-
|
|
175245
|
-
|
|
175592
|
+
{
|
|
175593
|
+
const failCount = incrementHistorianFailure(db, sessionId, errorMsg);
|
|
175594
|
+
await notify(buildHistorianFailureNotice(failCount, errorMsg));
|
|
175595
|
+
}
|
|
175246
175596
|
return;
|
|
175247
175597
|
}
|
|
175248
175598
|
const markerSummary = buildPiCompactionSummary(newCompartments);
|
|
@@ -175356,8 +175706,10 @@ ${chunk.text}`,
|
|
|
175356
175706
|
const desc = describeError(error51);
|
|
175357
175707
|
telemetry.failureReason = `exception: ${desc.brief}`;
|
|
175358
175708
|
sessionLog(sessionId, `historian failure: source=exception ${desc.brief}${desc.stackHead ? ` stackHead="${desc.stackHead}"` : ""}`);
|
|
175359
|
-
|
|
175360
|
-
|
|
175709
|
+
{
|
|
175710
|
+
const failCount = incrementHistorianFailure(db, sessionId, desc.brief);
|
|
175711
|
+
await notify(buildHistorianFailureNotice(failCount, desc.brief));
|
|
175712
|
+
}
|
|
175361
175713
|
} finally {
|
|
175362
175714
|
updateSessionMeta(db, sessionId, { compartmentInProgress: false });
|
|
175363
175715
|
try {
|
|
@@ -175770,7 +176122,6 @@ function replayStrippedInlineThinkingPi(args) {
|
|
|
175770
176122
|
}
|
|
175771
176123
|
|
|
175772
176124
|
// src/strip-placeholders-pi.ts
|
|
175773
|
-
init_logger();
|
|
175774
176125
|
var DROPPED_SEGMENT_PATTERN = /^\[dropped(?: §[^§]+§)?\]$/;
|
|
175775
176126
|
function isDroppedOnlyText(text) {
|
|
175776
176127
|
const trimmed = text.trim();
|
|
@@ -175822,6 +176173,7 @@ function stripPiDroppedPlaceholderMessages(args) {
|
|
|
175822
176173
|
};
|
|
175823
176174
|
const canPrune = (isCacheBusting || args.forceDiscovery === true) && !!stableIdByRef;
|
|
175824
176175
|
const presentIds = canPrune ? new Set : null;
|
|
176176
|
+
const discoveredIds = [];
|
|
175825
176177
|
if (isCacheBusting || args.forceDiscovery) {
|
|
175826
176178
|
for (let i = 0;i < messages.length; i++) {
|
|
175827
176179
|
const id = idOf(messages[i], i);
|
|
@@ -175832,6 +176184,7 @@ function stripPiDroppedPlaceholderMessages(args) {
|
|
|
175832
176184
|
continue;
|
|
175833
176185
|
if (!idsToStrip.has(id)) {
|
|
175834
176186
|
idsToStrip.add(id);
|
|
176187
|
+
discoveredIds.push(id);
|
|
175835
176188
|
discovered++;
|
|
175836
176189
|
}
|
|
175837
176190
|
}
|
|
@@ -175846,17 +176199,20 @@ function stripPiDroppedPlaceholderMessages(args) {
|
|
|
175846
176199
|
}
|
|
175847
176200
|
let pruned = 0;
|
|
175848
176201
|
if (presentIds) {
|
|
175849
|
-
const
|
|
175850
|
-
for (const id of
|
|
175851
|
-
if (presentIds.has(id))
|
|
175852
|
-
|
|
175853
|
-
}
|
|
175854
|
-
pruned =
|
|
175855
|
-
if (
|
|
175856
|
-
|
|
176202
|
+
const removedIds = [];
|
|
176203
|
+
for (const id of persistedIds) {
|
|
176204
|
+
if (!presentIds.has(id))
|
|
176205
|
+
removedIds.push(id);
|
|
176206
|
+
}
|
|
176207
|
+
pruned = removedIds.length;
|
|
176208
|
+
if (discoveredIds.length > 0 || removedIds.length > 0) {
|
|
176209
|
+
applyStrippedPlaceholderDelta(db, sessionId, {
|
|
176210
|
+
add: discoveredIds,
|
|
176211
|
+
remove: removedIds
|
|
176212
|
+
});
|
|
175857
176213
|
}
|
|
175858
|
-
} else if (
|
|
175859
|
-
|
|
176214
|
+
} else if (discoveredIds.length > 0) {
|
|
176215
|
+
applyStrippedPlaceholderDelta(db, sessionId, { add: discoveredIds });
|
|
175860
176216
|
}
|
|
175861
176217
|
if (removed > 0 || discovered > 0 || pruned > 0) {
|
|
175862
176218
|
sessionLog(sessionId, `placeholder strip: removed=${removed} discovered=${discovered} pruned=${pruned}`);
|
|
@@ -175881,6 +176237,7 @@ var PARTNER_FRAME_CLOSER_REDUCE = `
|
|
|
175881
176237
|
Reduction prompts are routine housekeeping to keep the session fast and cheap — act on them as light maintenance, never as scarcity warnings. Keep individual operations efficient, but never let context size change *what* work you take on or *how thoroughly* you do it.`;
|
|
175882
176238
|
var PARTNER_FRAME_CLOSER_NO_REDUCE = `
|
|
175883
176239
|
Context is managed for you entirely automatically — there's nothing to prune and no warnings to act on. Stay reasonably concise per operation, and never let context size change *what* work you take on or *how thoroughly* you do it.`;
|
|
176240
|
+
var CTX_NOTE_GUIDANCE = `Use \`ctx_note\` ONLY for genuinely future concerns — something to revisit much later, not work coming up in the next few turns (that's already in your active context) and not active multi-step work (use todos for that). Magic Context preserves your full context across both compaction and restarts, so an upcoming restart or "let's come back to this later" is never a reason to take a note — nothing is lost either way. Notes you do take survive compression and resurface at natural work boundaries (after commits, historian runs, todo completion).`;
|
|
175884
176241
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
175885
176242
|
if (dropToolStructure) {
|
|
175886
176243
|
return `Compressed history intentionally omits tool calls and their outputs — summaries like "I edited file X" are historian records, not patterns to replicate. In the live conversation, older tool calls and their results are cleaned up to save context — you may see your own past messages referencing actions without the corresponding tool call or result visible. This is normal context management. ALWAYS use real tool calls; never simulate, fabricate, or inline tool outputs in your text. If there is no tool result message, the action did not happen. NEVER simulate, hallucinate or claim tool calls, command output, search results, file edits, or diffs in plain text as if they actually occurred.`;
|
|
@@ -175891,7 +176248,8 @@ var BASE_INTRO = (protectedTags, dropToolStructure) => `Messages and tool output
|
|
|
175891
176248
|
Use \`ctx_reduce\` to manage context size. It supports one operation:
|
|
175892
176249
|
- \`drop\`: Remove entirely (best for tool outputs you already acted on).
|
|
175893
176250
|
Syntax: "3-5", "1,2,9", or "1-5,8,12-15". Last ${protectedTags} tags are protected.
|
|
175894
|
-
|
|
176251
|
+
Do not announce or narrate \`ctx_reduce\` drops — just call the tool silently. Saying "I'll drop these outputs" wastes tokens the user does not care about.
|
|
176252
|
+
${CTX_NOTE_GUIDANCE}
|
|
175895
176253
|
Use \`ctx_memory\` to manage cross-session project memories. Write new memories or delete stale ones. Memories persist across sessions and are automatically injected into new sessions.
|
|
175896
176254
|
**Save to memory proactively**: If you spent multiple turns finding something (a file path, a DB location, a config pattern, a workaround), save it with \`ctx_memory\` so future sessions don't repeat the search. Examples:
|
|
175897
176255
|
- Found a project's source code path after searching → \`ctx_memory(action="write", category="ENVIRONMENT", content="OpenCode source is at ~/Work/OSS/opencode")\`
|
|
@@ -175911,7 +176269,7 @@ NEVER drop large ranges blindly (e.g., "1-50"). Review each tag before deciding.
|
|
|
175911
176269
|
NEVER drop user messages — they are short and will be summarized by compartmentalization automatically. Dropping them loses context the historian needs.
|
|
175912
176270
|
NEVER drop assistant text messages unless they are exceptionally large. Your conversation messages are lightweight; only large tool outputs are worth dropping.
|
|
175913
176271
|
Before your turn finishes, consider using \`ctx_reduce\` to drop large tool outputs you no longer need.`;
|
|
175914
|
-
var BASE_INTRO_NO_REDUCE = (dropToolStructure) =>
|
|
176272
|
+
var BASE_INTRO_NO_REDUCE = (dropToolStructure) => `${CTX_NOTE_GUIDANCE}
|
|
175915
176273
|
Use \`ctx_memory\` to manage cross-session project memories. Write new memories or delete stale ones. Memories persist across sessions and are automatically injected into new sessions.
|
|
175916
176274
|
**Save to memory proactively**: If you spent multiple turns finding something (a file path, a DB location, a config pattern, a workaround), save it with \`ctx_memory\` so future sessions don't repeat the search. Examples:
|
|
175917
176275
|
- Found a project's source code path after searching → \`ctx_memory(action="write", category="ENVIRONMENT", content="OpenCode source is at ~/Work/OSS/opencode")\`
|
|
@@ -175974,7 +176332,6 @@ Prefer many small targeted operations over one large blanket operation, and keep
|
|
|
175974
176332
|
}
|
|
175975
176333
|
|
|
175976
176334
|
// src/system-prompt.ts
|
|
175977
|
-
init_logger();
|
|
175978
176335
|
var MAGIC_CONTEXT_MARKER = "## Magic Context";
|
|
175979
176336
|
var stickyDateBySession = new Map;
|
|
175980
176337
|
function buildMagicContextBlock(opts) {
|
|
@@ -176094,8 +176451,8 @@ function injectPiTemporalMarkers(messages) {
|
|
|
176094
176451
|
// src/timeout.ts
|
|
176095
176452
|
function withTimeout(p, ms) {
|
|
176096
176453
|
let handle;
|
|
176097
|
-
const timeout = new Promise((
|
|
176098
|
-
handle = setTimeout(() =>
|
|
176454
|
+
const timeout = new Promise((resolve5) => {
|
|
176455
|
+
handle = setTimeout(() => resolve5(undefined), ms);
|
|
176099
176456
|
handle.unref?.();
|
|
176100
176457
|
});
|
|
176101
176458
|
return Promise.race([p, timeout]).finally(() => {
|
|
@@ -176702,7 +177059,9 @@ function consumeDeferredMaterialization(sessionId) {
|
|
|
176702
177059
|
deferredMaterializationSessions.delete(sessionId);
|
|
176703
177060
|
return wasSet;
|
|
176704
177061
|
}
|
|
177062
|
+
var MAX_TRACKED_SESSIONS = 100;
|
|
176705
177063
|
function trackSessionForProject(projectIdentity, sessionId) {
|
|
177064
|
+
activeContextHandlerSessions.delete(sessionId);
|
|
176706
177065
|
activeContextHandlerSessions.add(sessionId);
|
|
176707
177066
|
let sessions = sessionsByProject.get(projectIdentity);
|
|
176708
177067
|
if (!sessions) {
|
|
@@ -176710,6 +177069,12 @@ function trackSessionForProject(projectIdentity, sessionId) {
|
|
|
176710
177069
|
sessionsByProject.set(projectIdentity, sessions);
|
|
176711
177070
|
}
|
|
176712
177071
|
sessions.add(sessionId);
|
|
177072
|
+
while (activeContextHandlerSessions.size > MAX_TRACKED_SESSIONS) {
|
|
177073
|
+
const oldest = activeContextHandlerSessions.values().next().value;
|
|
177074
|
+
if (oldest === undefined || oldest === sessionId)
|
|
177075
|
+
break;
|
|
177076
|
+
clearContextHandlerSession(oldest);
|
|
177077
|
+
}
|
|
176713
177078
|
}
|
|
176714
177079
|
function isContextHandlerSessionActive(sessionId) {
|
|
176715
177080
|
return activeContextHandlerSessions.has(sessionId);
|
|
@@ -177093,24 +177458,26 @@ function registerPiContextHandler(pi, options) {
|
|
|
177093
177458
|
}
|
|
177094
177459
|
let usagePercentage = 0;
|
|
177095
177460
|
let usageInputTokens = 0;
|
|
177461
|
+
let usedPersistedUsage = false;
|
|
177096
177462
|
if (sessionMetaForUsage.lastContextPercentage > 0 && sessionMetaForUsage.lastInputTokens > 0) {
|
|
177097
177463
|
usagePercentage = sessionMetaForUsage.lastContextPercentage;
|
|
177098
177464
|
usageInputTokens = sessionMetaForUsage.lastInputTokens;
|
|
177465
|
+
usedPersistedUsage = true;
|
|
177099
177466
|
} else {
|
|
177100
177467
|
usagePercentage = typeof piUsage?.percent === "number" ? piUsage.percent : 0;
|
|
177101
177468
|
usageInputTokens = typeof piUsage?.tokens === "number" ? piUsage.tokens : 0;
|
|
177102
177469
|
}
|
|
177103
|
-
let usageContextLimit =
|
|
177470
|
+
let usageContextLimit = isSaneLimit(piUsage?.contextWindow) ? piUsage.contextWindow : undefined;
|
|
177104
177471
|
const tEmergencyRecovery = performance.now();
|
|
177472
|
+
let needsEmergencyBump = false;
|
|
177473
|
+
let emergencyRecoveryArmed = false;
|
|
177105
177474
|
try {
|
|
177106
177475
|
const overflowState = getOverflowState(options.db, sessionId);
|
|
177107
177476
|
if (overflowState.detectedContextLimit > 0) {
|
|
177108
177477
|
usageContextLimit = Math.min(usageContextLimit ?? overflowState.detectedContextLimit, overflowState.detectedContextLimit);
|
|
177109
177478
|
}
|
|
177110
|
-
|
|
177111
|
-
|
|
177112
|
-
usagePercentage = 95;
|
|
177113
|
-
}
|
|
177479
|
+
emergencyRecoveryArmed = overflowState.needsEmergencyRecovery;
|
|
177480
|
+
needsEmergencyBump = overflowState.needsEmergencyRecovery && usagePercentage < 95;
|
|
177114
177481
|
} catch (err) {
|
|
177115
177482
|
sessionLog(sessionId, `transform: overflow state read failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
177116
177483
|
}
|
|
@@ -177122,6 +177489,13 @@ function registerPiContextHandler(pi, options) {
|
|
|
177122
177489
|
usageContextLimit = modelWindow;
|
|
177123
177490
|
}
|
|
177124
177491
|
}
|
|
177492
|
+
if (!usedPersistedUsage && isSaneLimit(usageContextLimit) && usageInputTokens > 0) {
|
|
177493
|
+
usagePercentage = usageInputTokens / usageContextLimit * 100;
|
|
177494
|
+
}
|
|
177495
|
+
if (needsEmergencyBump) {
|
|
177496
|
+
sessionLog(sessionId, `transform: overflow recovery flag set — bumping percentage to 95% (detectedLimit=${usageContextLimit ?? "unknown"})`);
|
|
177497
|
+
usagePercentage = 95;
|
|
177498
|
+
}
|
|
177125
177499
|
let schedulerDecision;
|
|
177126
177500
|
const tScheduler = performance.now();
|
|
177127
177501
|
try {
|
|
@@ -177171,10 +177545,6 @@ function registerPiContextHandler(pi, options) {
|
|
|
177171
177545
|
setDeferredExecutePendingIfAbsent(options.db, sessionId, flagPayload);
|
|
177172
177546
|
}
|
|
177173
177547
|
schedulerDecision = midTurnAdjustedSchedulerDecision;
|
|
177174
|
-
const deferredExecutePending = peekDeferredExecutePending(options.db, sessionId);
|
|
177175
|
-
if (deferredExecutePending !== null && schedulerDecision === "defer" && !midTurn) {
|
|
177176
|
-
schedulerDecision = "execute";
|
|
177177
|
-
}
|
|
177178
177548
|
sessionLog(sessionId, `[boundary-exec] base=${schedulerDecisionEarly} bypass=${bypassReason} midTurn=${midTurn} effective=${midTurnAdjustedSchedulerDecision} sideEffect=${sideEffect}`);
|
|
177179
177549
|
const forceMaterialization = usagePercentage >= FORCE_MATERIALIZATION_PERCENTAGE;
|
|
177180
177550
|
const isEmergency = usagePercentage >= EMERGENCY_BLOCK_PERCENTAGE;
|
|
@@ -177192,6 +177562,14 @@ function registerPiContextHandler(pi, options) {
|
|
|
177192
177562
|
sessionLog(sessionId, "EMERGENCY: historian wait completed (or timed out)");
|
|
177193
177563
|
} catch {}
|
|
177194
177564
|
}
|
|
177565
|
+
if (emergencyRecoveryArmed && !inFlightHistorian.has(sessionId) && !hasEligiblePiCompartmentHistory(options.db, sessionId)) {
|
|
177566
|
+
try {
|
|
177567
|
+
clearEmergencyRecovery(options.db, sessionId);
|
|
177568
|
+
sessionLog(sessionId, "EMERGENCY: disarming recovery — no eligible pre-tail history to compact (would otherwise loop at 95%)");
|
|
177569
|
+
} catch (err) {
|
|
177570
|
+
sessionLog(sessionId, `EMERGENCY: clearEmergencyRecovery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
177571
|
+
}
|
|
177572
|
+
}
|
|
177195
177573
|
}
|
|
177196
177574
|
const isCacheBusting = historyRefreshSessions.has(sessionId);
|
|
177197
177575
|
sessionLog(sessionId, `transform: usage=${usagePercentage.toFixed(1)}% (${usageInputTokens} tokens, limit=${usageContextLimit ?? "?"}) decision=${schedulerDecision}${forceMaterialization ? " force=true" : ""}${isEmergency ? " EMERGENCY=true" : ""}${isCacheBusting ? " busting=true" : ""}`);
|
|
@@ -177209,6 +177587,7 @@ function registerPiContextHandler(pi, options) {
|
|
|
177209
177587
|
heuristics: options.heuristics,
|
|
177210
177588
|
injection: options.injection ? {
|
|
177211
177589
|
...options.injection,
|
|
177590
|
+
memoryEnabled: options.injection.memoryEnabled,
|
|
177212
177591
|
historyBudgetTokens: resolveHistoryBudgetTokensForPi({
|
|
177213
177592
|
historyBudgetPercentage: options.historian?.historyBudgetPercentage,
|
|
177214
177593
|
usagePercentage,
|
|
@@ -177526,7 +177905,16 @@ function maybeFireHistorian(args) {
|
|
|
177526
177905
|
let usageContextLimit;
|
|
177527
177906
|
try {
|
|
177528
177907
|
const piUsage = ctx.getContextUsage?.();
|
|
177529
|
-
usageContextLimit =
|
|
177908
|
+
usageContextLimit = isSaneLimit(piUsage?.contextWindow) ? piUsage.contextWindow : undefined;
|
|
177909
|
+
if (usageContextLimit === undefined && isSaneLimit(ctx.model?.contextWindow)) {
|
|
177910
|
+
usageContextLimit = ctx.model.contextWindow;
|
|
177911
|
+
}
|
|
177912
|
+
try {
|
|
177913
|
+
const overflowState = getOverflowState(db, sessionId);
|
|
177914
|
+
if (overflowState.detectedContextLimit > 0) {
|
|
177915
|
+
usageContextLimit = Math.min(usageContextLimit ?? overflowState.detectedContextLimit, overflowState.detectedContextLimit);
|
|
177916
|
+
}
|
|
177917
|
+
} catch {}
|
|
177530
177918
|
const sessionMetaForUsage = getOrCreateSessionMeta(db, sessionId);
|
|
177531
177919
|
if (sessionMetaForUsage.lastContextPercentage > 0 && sessionMetaForUsage.lastInputTokens > 0) {
|
|
177532
177920
|
usage = {
|
|
@@ -177539,8 +177927,9 @@ function maybeFireHistorian(args) {
|
|
|
177539
177927
|
sessionLog(sessionId, `historian trigger eval: no usage info yet (tokens=${piUsage?.tokens ?? "<no piUsage>"}, percent=${piUsage?.percent ?? "<no piUsage>"}, contextWindow=${piUsage?.contextWindow ?? "<no piUsage>"})`);
|
|
177540
177928
|
return;
|
|
177541
177929
|
}
|
|
177930
|
+
const fallbackPercentage = isSaneLimit(usageContextLimit) && piUsage.tokens > 0 ? piUsage.tokens / usageContextLimit * 100 : piUsage.percent;
|
|
177542
177931
|
usage = {
|
|
177543
|
-
percentage:
|
|
177932
|
+
percentage: fallbackPercentage,
|
|
177544
177933
|
inputTokens: piUsage.tokens
|
|
177545
177934
|
};
|
|
177546
177935
|
sessionLog(sessionId, `historian trigger eval: usage=${usage.percentage.toFixed(1)}% (${usage.inputTokens} tokens) [piUsage fallback], checking trigger...`);
|
|
@@ -177616,6 +178005,7 @@ async function runPipeline(args) {
|
|
|
177616
178005
|
let executedWorkThisPass = false;
|
|
177617
178006
|
let historyWasConsumedThisPass = false;
|
|
177618
178007
|
let materializationSatisfiedThisPass = false;
|
|
178008
|
+
let pendingOpsAppliedThisPass = false;
|
|
177619
178009
|
let suppressDeferredHistoryDrain = false;
|
|
177620
178010
|
let casLost = false;
|
|
177621
178011
|
const deferredHistoryWasPendingAtPassStart = deferredHistoryRefreshSessions.has(args.sessionId);
|
|
@@ -177639,7 +178029,9 @@ async function runPipeline(args) {
|
|
|
177639
178029
|
return findLatestUserMessageIdPi(args.messages, ids)?.messageId ?? null;
|
|
177640
178030
|
})();
|
|
177641
178031
|
const alreadyRanHeuristicsThisTurn = currentTurnId !== null && lastHeuristicsTurnIdBySession.get(args.sessionId) === currentTurnId;
|
|
177642
|
-
const
|
|
178032
|
+
const canConsumeDeferredLate = args.schedulerDecision === "execute" || args.forceMaterialization === true || args.contextUsage.percentage >= FORCE_MATERIALIZATION_PERCENTAGE;
|
|
178033
|
+
const deferredMaterializeEligible = canConsumeDeferredLate && deferredMaterializationSessions.has(args.sessionId);
|
|
178034
|
+
const shouldRunHeuristics = args.heuristics !== undefined && (args.forceMaterialization === true || hasPendingMaterialization(args.sessionId) || deferredMaterializeEligible || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
|
|
177643
178035
|
const entryFingerprintByMessageId = buildEntryFingerprintMap(args.messages, stableIdResolver);
|
|
177644
178036
|
adoptPiFallbackTags(args.db, args.sessionId, args.tagger, entryFingerprintByMessageId);
|
|
177645
178037
|
const tTag = performance.now();
|
|
@@ -177665,15 +178057,13 @@ async function runPipeline(args) {
|
|
|
177665
178057
|
const hasPendingMaterializeSignal = hasPendingMaterialization(args.sessionId);
|
|
177666
178058
|
const deferredMaterializationWasPending = deferredMaterializationSessions.has(args.sessionId);
|
|
177667
178059
|
const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
|
|
177668
|
-
const deferredExecuteWasPending = peekDeferredExecutePending(args.db, args.sessionId) !== null;
|
|
177669
178060
|
const pendingOps = getPendingOps(args.db, args.sessionId);
|
|
177670
|
-
const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal
|
|
177671
|
-
const canConsumeDeferredLate = baseShouldApplyPendingOps || shouldRunHeuristics;
|
|
178061
|
+
const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal;
|
|
177672
178062
|
const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
|
|
177673
178063
|
const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
|
|
177674
178064
|
const shouldApplyPendingOps = baseShouldApplyPendingOps || deferredMaterialize;
|
|
177675
178065
|
if (shouldApplyPendingOps) {
|
|
177676
|
-
const applyReason = hasPendingMaterializeSignal ? "explicit_flush" :
|
|
178066
|
+
const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
177677
178067
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
177678
178068
|
try {
|
|
177679
178069
|
const tApplyPending = performance.now();
|
|
@@ -177681,14 +178071,12 @@ async function runPipeline(args) {
|
|
|
177681
178071
|
logTransformTiming(args.sessionId, "applyPendingOperations", tApplyPending);
|
|
177682
178072
|
executedWorkThisPass = true;
|
|
177683
178073
|
materializationSatisfiedThisPass = true;
|
|
178074
|
+
pendingOpsAppliedThisPass = true;
|
|
177684
178075
|
if (hasPendingMaterializeSignal) {
|
|
177685
178076
|
if (args.heuristics === undefined) {
|
|
177686
178077
|
consumePendingMaterialization(args.sessionId);
|
|
177687
178078
|
}
|
|
177688
178079
|
}
|
|
177689
|
-
if (deferredMaterialize) {
|
|
177690
|
-
consumeDeferredMaterialization(args.sessionId);
|
|
177691
|
-
}
|
|
177692
178080
|
} catch (err) {
|
|
177693
178081
|
sessionLog(args.sessionId, `pending operations failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
177694
178082
|
throw err;
|
|
@@ -177775,6 +178163,12 @@ async function runPipeline(args) {
|
|
|
177775
178163
|
sessionLog(args.sessionId, `heuristic cleanup failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
177776
178164
|
}
|
|
177777
178165
|
}
|
|
178166
|
+
if (deferredMaterialize && pendingOpsAppliedThisPass) {
|
|
178167
|
+
const fullPassSucceeded = shouldRunHeuristics ? heuristicsExecuted : true;
|
|
178168
|
+
if (fullPassSucceeded) {
|
|
178169
|
+
consumeDeferredMaterialization(args.sessionId);
|
|
178170
|
+
}
|
|
178171
|
+
}
|
|
177778
178172
|
if (args.reasoningClearing && shouldRunHeuristics) {
|
|
177779
178173
|
try {
|
|
177780
178174
|
const tClearReasoning = performance.now();
|
|
@@ -177827,18 +178221,29 @@ async function runPipeline(args) {
|
|
|
177827
178221
|
if (args.injection) {
|
|
177828
178222
|
try {
|
|
177829
178223
|
const tInjection = performance.now();
|
|
177830
|
-
|
|
177831
|
-
|
|
177832
|
-
|
|
178224
|
+
const hardMeta = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
178225
|
+
let piTtlMs = 5 * 60 * 1000;
|
|
178226
|
+
try {
|
|
178227
|
+
piTtlMs = parseCacheTtl(hardMeta.cacheTtl);
|
|
178228
|
+
} catch {}
|
|
178229
|
+
const piHardSignals = {
|
|
178230
|
+
systemHash: typeof hardMeta.systemPromptHash === "string" ? hardMeta.systemPromptHash : "",
|
|
178231
|
+
toolSetHash: "",
|
|
178232
|
+
modelKey: liveModelBySession.get(args.sessionId) ?? "",
|
|
178233
|
+
cacheExpired: hardMeta.lastResponseTime > 0 && Date.now() - hardMeta.lastResponseTime >= piTtlMs,
|
|
178234
|
+
lastResponseTime: hardMeta.lastResponseTime
|
|
178235
|
+
};
|
|
177833
178236
|
injectionResult = injectM0M1Pi({
|
|
177834
178237
|
sessionId: args.sessionId,
|
|
177835
178238
|
projectIdentity: args.projectIdentity,
|
|
177836
178239
|
projectDirectory: args.projectDirectory,
|
|
178240
|
+
memoryEnabled: args.injection.memoryEnabled,
|
|
177837
178241
|
injectionBudgetTokens: args.injection.injectionBudgetTokens,
|
|
177838
178242
|
historyBudgetTokens: args.injection.historyBudgetTokens,
|
|
177839
178243
|
keyFilesEnabled: args.injection.keyFilesEnabled,
|
|
177840
|
-
keyFilesTokenBudget: args.injection.keyFilesTokenBudget
|
|
177841
|
-
|
|
178244
|
+
keyFilesTokenBudget: args.injection.keyFilesTokenBudget,
|
|
178245
|
+
hardSignals: piHardSignals
|
|
178246
|
+
}, args.db, args.messages, args.entryIds, args.isCacheBusting || deferredHistoryRefresh || executedWorkThisPass);
|
|
177842
178247
|
if (args.isCacheBusting) {
|
|
177843
178248
|
historyRefreshSessions.delete(args.sessionId);
|
|
177844
178249
|
historyWasConsumedThisPass = true;
|
|
@@ -178191,12 +178596,8 @@ ${result}`;
|
|
|
178191
178596
|
});
|
|
178192
178597
|
}
|
|
178193
178598
|
|
|
178194
|
-
// ../plugin/src/hooks/magic-context/compartment-runner.ts
|
|
178195
|
-
init_logger();
|
|
178196
|
-
|
|
178197
178599
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
178198
178600
|
import { mkdirSync as mkdirSync6, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
178199
|
-
init_data_path();
|
|
178200
178601
|
function cleanupHistorianStateFile(path7) {
|
|
178201
178602
|
if (!path7)
|
|
178202
178603
|
return;
|
|
@@ -178204,13 +178605,7 @@ function cleanupHistorianStateFile(path7) {
|
|
|
178204
178605
|
unlinkSync(path7);
|
|
178205
178606
|
} catch {}
|
|
178206
178607
|
}
|
|
178207
|
-
// ../plugin/src/hooks/magic-context/compartment-runner-incremental.ts
|
|
178208
|
-
init_logger();
|
|
178209
|
-
|
|
178210
178608
|
// ../plugin/src/features/magic-context/compaction-marker.ts
|
|
178211
|
-
init_data_path();
|
|
178212
|
-
init_logger();
|
|
178213
|
-
await init_sqlite();
|
|
178214
178609
|
import { join as join15 } from "node:path";
|
|
178215
178610
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
178216
178611
|
function randomBase62(length) {
|
|
@@ -178365,23 +178760,20 @@ function removeCompactionMarker(state) {
|
|
|
178365
178760
|
}
|
|
178366
178761
|
|
|
178367
178762
|
// ../plugin/src/hooks/magic-context/compaction-marker-manager.ts
|
|
178368
|
-
init_data_path();
|
|
178369
|
-
init_logger();
|
|
178370
|
-
await init_sqlite();
|
|
178371
178763
|
var MARKER_SUMMARY_TEXT = "[Compacted by magic-context — session history is managed by the plugin]";
|
|
178372
178764
|
function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
|
|
178373
178765
|
const existing = getPersistedCompactionMarkerState(db, sessionId);
|
|
178374
178766
|
if (existing) {
|
|
178375
178767
|
if (existing.boundaryOrdinal === lastCompartmentEnd) {
|
|
178376
|
-
return;
|
|
178768
|
+
return true;
|
|
178377
178769
|
}
|
|
178378
|
-
|
|
178379
|
-
|
|
178380
|
-
|
|
178381
|
-
|
|
178382
|
-
} catch (error51) {
|
|
178383
|
-
sessionLog(sessionId, `compaction-marker: failed to remove old boundary at ordinal ${existing.boundaryOrdinal}, proceeding with new injection:`, error51);
|
|
178770
|
+
const removed = removeCompactionMarker(existing);
|
|
178771
|
+
if (!removed) {
|
|
178772
|
+
sessionLog(sessionId, `compaction-marker: failed to remove old boundary at ordinal ${existing.boundaryOrdinal}; preserving persisted state for retry (not injecting new marker this pass)`);
|
|
178773
|
+
return false;
|
|
178384
178774
|
}
|
|
178775
|
+
setPersistedCompactionMarkerState(db, sessionId, null);
|
|
178776
|
+
sessionLog(sessionId, `compaction-marker: removed old boundary at ordinal ${existing.boundaryOrdinal}, moving to ${lastCompartmentEnd}`);
|
|
178385
178777
|
}
|
|
178386
178778
|
const result = injectCompactionMarker({
|
|
178387
178779
|
sessionId,
|
|
@@ -178395,13 +178787,14 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
178395
178787
|
boundaryOrdinal: lastCompartmentEnd
|
|
178396
178788
|
});
|
|
178397
178789
|
sessionLog(sessionId, `compaction-marker: injected at ordinal ${lastCompartmentEnd}, boundary user msg ${result.boundaryMessageId}`);
|
|
178790
|
+
return true;
|
|
178398
178791
|
}
|
|
178792
|
+
return false;
|
|
178399
178793
|
}
|
|
178400
178794
|
|
|
178401
178795
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
178402
178796
|
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
178403
178797
|
import { join as join16 } from "node:path";
|
|
178404
|
-
init_data_path();
|
|
178405
178798
|
function historianResponseDumpDir(directory) {
|
|
178406
178799
|
return getProjectMagicContextHistorianDir(directory);
|
|
178407
178800
|
}
|
|
@@ -178601,12 +178994,12 @@ async function runHistorianPrompt(args) {
|
|
|
178601
178994
|
error: `Historian failed while processing this session: ${desc.brief}`
|
|
178602
178995
|
};
|
|
178603
178996
|
} finally {
|
|
178604
|
-
if (agentSessionId && outcomeOk) {
|
|
178997
|
+
if (agentSessionId && outcomeOk && !shouldKeepSubagents()) {
|
|
178605
178998
|
await client.session.delete({ path: { id: agentSessionId } }).catch((e) => {
|
|
178606
178999
|
sessionLog(parentSessionId, "compartment agent: session cleanup failed", getErrorMessage(e));
|
|
178607
179000
|
});
|
|
178608
|
-
} else if (agentSessionId && !outcomeOk) {
|
|
178609
|
-
sessionLog(parentSessionId, `historian: KEEPING
|
|
179001
|
+
} else if (agentSessionId && (!outcomeOk || shouldKeepSubagents())) {
|
|
179002
|
+
sessionLog(parentSessionId, `historian: KEEPING child session ${agentSessionId} (${outcomeOk ? "keep_subagents" : "failed"}) — not deleted`);
|
|
178610
179003
|
}
|
|
178611
179004
|
}
|
|
178612
179005
|
}
|
|
@@ -178685,8 +179078,8 @@ function isTransientHistorianPromptError(message) {
|
|
|
178685
179078
|
].some((token) => normalized.includes(token));
|
|
178686
179079
|
}
|
|
178687
179080
|
function sleep(ms) {
|
|
178688
|
-
return new Promise((
|
|
178689
|
-
setTimeout(
|
|
179081
|
+
return new Promise((resolve5) => {
|
|
179082
|
+
setTimeout(resolve5, ms);
|
|
178690
179083
|
});
|
|
178691
179084
|
}
|
|
178692
179085
|
function cleanupHistorianDump(sessionId, dumpPath) {
|
|
@@ -178727,7 +179120,6 @@ function sanitizeDumpName(value) {
|
|
|
178727
179120
|
}
|
|
178728
179121
|
|
|
178729
179122
|
// ../plugin/src/hooks/magic-context/send-session-notification.ts
|
|
178730
|
-
init_logger();
|
|
178731
179123
|
function hasNotificationSessionClient(client) {
|
|
178732
179124
|
if (client === null || typeof client !== "object")
|
|
178733
179125
|
return false;
|
|
@@ -178826,11 +179218,7 @@ async function sendIgnoredMessage(client, sessionId, text, params, forcePersist
|
|
|
178826
179218
|
var HISTORIAN_ALERT_COOLDOWN_MS2 = 60 * 1000;
|
|
178827
179219
|
var lastHistorianAlertBySession2 = new Map;
|
|
178828
179220
|
|
|
178829
|
-
// ../plugin/src/hooks/magic-context/compartment-runner-partial-recomp.ts
|
|
178830
|
-
init_logger();
|
|
178831
|
-
|
|
178832
179221
|
// ../plugin/src/hooks/magic-context/compartment-runner-recomp.ts
|
|
178833
|
-
init_logger();
|
|
178834
179222
|
function insertRecompCompartmentRows(db, sessionId, compartments, now) {
|
|
178835
179223
|
const stmt = db.prepare("INSERT INTO compartments (session_id, sequence, start_message, end_message, start_message_id, end_message_id, title, content, p1, p2, p3, p4, importance, episode_type, legacy, created_at, harness) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
178836
179224
|
for (const c of compartments) {
|
|
@@ -178953,7 +179341,6 @@ Found ${existingStaging.compartments.length} staged compartment(s) from ${existi
|
|
|
178953
179341
|
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
178954
179342
|
clearInjectionCache(sessionId);
|
|
178955
179343
|
}
|
|
178956
|
-
deps.onCompartmentStatePublished?.(sessionId);
|
|
178957
179344
|
promoted2.facts;
|
|
178958
179345
|
if (deps.memoryEnabled !== false) {
|
|
178959
179346
|
const projectIdentity = resolveProjectIdentity(sessionDirectory);
|
|
@@ -178966,11 +179353,14 @@ Found ${existingStaging.compartments.length} staged compartment(s) from ${existi
|
|
|
178966
179353
|
if (lastCompartmentEnd2 > 0) {
|
|
178967
179354
|
queueDropsForCompartmentalizedMessages(db, sessionId, lastCompartmentEnd2);
|
|
178968
179355
|
}
|
|
179356
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
178969
179357
|
if (lastCompartmentEnd2 > 0) {
|
|
178970
|
-
updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd2, deps.directory);
|
|
178971
|
-
|
|
178972
|
-
|
|
178973
|
-
|
|
179358
|
+
const markerUpdated = updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd2, deps.directory);
|
|
179359
|
+
if (markerUpdated) {
|
|
179360
|
+
const stalePending = getPendingCompactionMarkerState(db, sessionId);
|
|
179361
|
+
if (stalePending) {
|
|
179362
|
+
clearPendingCompactionMarkerStateIf(db, sessionId, stalePending);
|
|
179363
|
+
}
|
|
178974
179364
|
}
|
|
178975
179365
|
}
|
|
178976
179366
|
return [
|
|
@@ -179159,13 +179549,13 @@ Another process acquired the compartment-state lease before recomp could publish
|
|
|
179159
179549
|
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
179160
179550
|
clearInjectionCache(sessionId);
|
|
179161
179551
|
}
|
|
179162
|
-
deps.onCompartmentStatePublished?.(sessionId);
|
|
179163
179552
|
const finalCompartments = promoted?.compartments ?? candidateCompartments;
|
|
179164
179553
|
const finalFacts = promoted?.facts ?? candidateFacts;
|
|
179165
179554
|
const lastCompartmentEnd = finalCompartments[finalCompartments.length - 1]?.endMessage ?? 0;
|
|
179166
179555
|
if (lastCompartmentEnd > 0) {
|
|
179167
179556
|
queueDropsForCompartmentalizedMessages(db, sessionId, lastCompartmentEnd);
|
|
179168
179557
|
}
|
|
179558
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
179169
179559
|
if (deps.memoryEnabled !== false) {
|
|
179170
179560
|
const projectIdentity = resolveProjectIdentity(sessionDirectory);
|
|
179171
179561
|
await deps.ensureProjectRegistered?.(sessionDirectory, db);
|
|
@@ -179174,10 +179564,12 @@ Another process acquired the compartment-state lease before recomp could publish
|
|
|
179174
179564
|
embedAndStoreCompartments(db, sessionId, projectIdentity, toEmbed);
|
|
179175
179565
|
}
|
|
179176
179566
|
if (lastCompartmentEnd > 0) {
|
|
179177
|
-
updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, deps.directory);
|
|
179178
|
-
|
|
179179
|
-
|
|
179180
|
-
|
|
179567
|
+
const markerUpdated = updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, deps.directory);
|
|
179568
|
+
if (markerUpdated) {
|
|
179569
|
+
const stalePending = getPendingCompactionMarkerState(db, sessionId);
|
|
179570
|
+
if (stalePending) {
|
|
179571
|
+
clearPendingCompactionMarkerStateIf(db, sessionId, stalePending);
|
|
179572
|
+
}
|
|
179181
179573
|
}
|
|
179182
179574
|
}
|
|
179183
179575
|
return [
|
|
@@ -179311,7 +179703,7 @@ Could not acquire the compartment-state lease for this session.`;
|
|
|
179311
179703
|
log(`[magic-context] partial recomp merged validation failed: ${mergedError}`);
|
|
179312
179704
|
return null;
|
|
179313
179705
|
}
|
|
179314
|
-
saveRecompStagingPass(db, sessionId, passCount + 1, merged,
|
|
179706
|
+
saveRecompStagingPass(db, sessionId, passCount + 1, merged, stagedFacts);
|
|
179315
179707
|
const promoted = promoteRecompStagingWithM0Mutation(db, sessionId, leaseHolderId);
|
|
179316
179708
|
if (!promoted) {
|
|
179317
179709
|
log("[magic-context] partial recomp promote returned null");
|
|
@@ -179331,10 +179723,12 @@ Could not acquire the compartment-state lease for this session.`;
|
|
|
179331
179723
|
}
|
|
179332
179724
|
const lastEnd = merged[merged.length - 1]?.endMessage ?? snapEnd;
|
|
179333
179725
|
if (lastEnd > 0) {
|
|
179334
|
-
updateCompactionMarkerAfterPublication(db, sessionId, lastEnd, deps.directory);
|
|
179335
|
-
|
|
179336
|
-
|
|
179337
|
-
|
|
179726
|
+
const markerUpdated = updateCompactionMarkerAfterPublication(db, sessionId, lastEnd, deps.directory);
|
|
179727
|
+
if (markerUpdated) {
|
|
179728
|
+
const stalePending = getPendingCompactionMarkerState(db, sessionId);
|
|
179729
|
+
if (stalePending) {
|
|
179730
|
+
clearPendingCompactionMarkerStateIf(db, sessionId, stalePending);
|
|
179731
|
+
}
|
|
179338
179732
|
}
|
|
179339
179733
|
}
|
|
179340
179734
|
return { compartmentCount: merged.length, lastEndMessage: lastEnd };
|
|
@@ -179376,10 +179770,7 @@ Snapped range ${snapStart}-${snapEnd} would cross into the protected tail (start
|
|
|
179376
179770
|
].join(`
|
|
179377
179771
|
`);
|
|
179378
179772
|
}
|
|
179379
|
-
const
|
|
179380
|
-
category: f.category,
|
|
179381
|
-
content: f.content
|
|
179382
|
-
}));
|
|
179773
|
+
const stagedFacts = [];
|
|
179383
179774
|
const parentSessionResponse = await client.session.get({ path: { id: sessionId } }).catch(() => null);
|
|
179384
179775
|
const parentSession = normalizeSDKResponse(parentSessionResponse, null, { preferResponseOnMissingData: true });
|
|
179385
179776
|
const sessionDirectory = parentSession?.directory ?? directory;
|
|
@@ -179396,7 +179787,7 @@ Snapped range ${snapStart}-${snapEnd} would cross into the protected tail (start
|
|
|
179396
179787
|
candidateCompartments = priorCompartments.map((c, idx) => compartmentToInput(c, idx));
|
|
179397
179788
|
passCount = 0;
|
|
179398
179789
|
offset = snapStart;
|
|
179399
|
-
saveRecompStagingPass(db, sessionId, 0, candidateCompartments,
|
|
179790
|
+
saveRecompStagingPass(db, sessionId, 0, candidateCompartments, stagedFacts);
|
|
179400
179791
|
setRecompPartialRange(db, sessionId, { start: snapStart, end: snapEnd });
|
|
179401
179792
|
}
|
|
179402
179793
|
let currentTokenBudget = historianChunkTokens;
|
|
@@ -179489,7 +179880,7 @@ Original state preserved (staging kept for retry).`;
|
|
|
179489
179880
|
passCount += 1;
|
|
179490
179881
|
currentTokenBudget = historianChunkTokens;
|
|
179491
179882
|
passAttempt = 1;
|
|
179492
|
-
saveRecompStagingPass(db, sessionId, passCount, candidateCompartments,
|
|
179883
|
+
saveRecompStagingPass(db, sessionId, passCount, candidateCompartments, stagedFacts);
|
|
179493
179884
|
const nextOffset = (validatedPass.compartments?.[validatedPass.compartments.length - 1]?.endMessage ?? chunk.endIndex) + 1;
|
|
179494
179885
|
if (nextOffset <= offset) {
|
|
179495
179886
|
return `## Magic Recomp — Failed
|
|
@@ -179510,7 +179901,6 @@ Partial recomp completed historian passes but the final compartment set failed v
|
|
|
179510
179901
|
...resumed ? ["Resumed from previous interrupted partial run."] : [],
|
|
179511
179902
|
`Rebuilt compartments covering messages ${snapStart}-${snapEnd} using ${passCount} historian pass${passCount === 1 ? "" : "es"}.`,
|
|
179512
179903
|
`Preserved ${priorCompartments.length} prior compartment(s) and ${tailCompartments.length} tail compartment(s) unchanged.`,
|
|
179513
|
-
`Facts unchanged (${currentFacts.length} entr${currentFacts.length === 1 ? "y" : "ies"}).`,
|
|
179514
179904
|
`Total compartments: ${finalResult.compartmentCount}.`
|
|
179515
179905
|
].join(`
|
|
179516
179906
|
`);
|
|
@@ -179599,9 +179989,6 @@ async function executeContextRecompWithResult(deps, options = {}) {
|
|
|
179599
179989
|
}
|
|
179600
179990
|
}
|
|
179601
179991
|
|
|
179602
|
-
// src/commands/ctx-recomp.ts
|
|
179603
|
-
init_logger();
|
|
179604
|
-
|
|
179605
179992
|
// src/pi-recomp-client-shared.ts
|
|
179606
179993
|
function createPiHistorianClient(args) {
|
|
179607
179994
|
const sessions = new Map;
|
|
@@ -179733,9 +180120,6 @@ function resolvePiReadBranchEntries2(ctx) {
|
|
|
179733
180120
|
};
|
|
179734
180121
|
}
|
|
179735
180122
|
|
|
179736
|
-
// src/pi-recomp-runner.ts
|
|
179737
|
-
init_logger();
|
|
179738
|
-
|
|
179739
180123
|
// src/status-line.ts
|
|
179740
180124
|
var STATUS_KEY = "magic-context";
|
|
179741
180125
|
var RECENT_FAILURE_MS = 60000;
|
|
@@ -180064,7 +180448,6 @@ function inferLevel(text) {
|
|
|
180064
180448
|
}
|
|
180065
180449
|
|
|
180066
180450
|
// ../plugin/src/features/magic-context/memory/memory-migration.ts
|
|
180067
|
-
init_logger();
|
|
180068
180451
|
function memoryMigrationGuardKey(projectPath) {
|
|
180069
180452
|
return `memory_migration_5cat:${projectPath}`;
|
|
180070
180453
|
}
|
|
@@ -180174,11 +180557,7 @@ function contextualizeUpgradeReason(reason) {
|
|
|
180174
180557
|
return rewritten;
|
|
180175
180558
|
}
|
|
180176
180559
|
|
|
180177
|
-
// src/commands/ctx-session-upgrade.ts
|
|
180178
|
-
init_logger();
|
|
180179
|
-
|
|
180180
180560
|
// src/pi-memory-migration.ts
|
|
180181
|
-
init_logger();
|
|
180182
180561
|
var MIGRATION_SYSTEM_PROMPT2 = "You re-organize a software project's long-term memory into a stricter taxonomy. " + "Follow the user instructions exactly. Output ONLY the requested XML blocks, nothing else.";
|
|
180183
180562
|
async function runPiMemoryMigration(deps) {
|
|
180184
180563
|
const projectPath = resolveProjectIdentity(deps.directory);
|
|
@@ -180453,7 +180832,6 @@ ${migrationSummary}` : "",
|
|
|
180453
180832
|
}
|
|
180454
180833
|
|
|
180455
180834
|
// ../plugin/src/hooks/magic-context/execute-status.ts
|
|
180456
|
-
init_logger();
|
|
180457
180835
|
function formatExecuteThreshold(thresholdPercentage, mode, contextLimit) {
|
|
180458
180836
|
if (mode === "tokens" && contextLimit > 0) {
|
|
180459
180837
|
const tokens = Math.floor(thresholdPercentage / 100 * contextLimit);
|
|
@@ -180620,7 +180998,7 @@ function formatThresholdPercent(value) {
|
|
|
180620
180998
|
// package.json
|
|
180621
180999
|
var package_default = {
|
|
180622
181000
|
name: "@cortexkit/pi-magic-context",
|
|
180623
|
-
version: "0.22.
|
|
181001
|
+
version: "0.22.5",
|
|
180624
181002
|
type: "module",
|
|
180625
181003
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
180626
181004
|
main: "dist/index.js",
|
|
@@ -185358,7 +185736,6 @@ function createCtxExpandTool(deps) {
|
|
|
185358
185736
|
}
|
|
185359
185737
|
|
|
185360
185738
|
// src/tools/ctx-memory.ts
|
|
185361
|
-
init_logger();
|
|
185362
185739
|
var DEFAULT_LIST_LIMIT = 10;
|
|
185363
185740
|
var VALID_CATEGORIES = new Set(CATEGORY_PRIORITY);
|
|
185364
185741
|
function isMemoryCategory2(value) {
|
|
@@ -185503,7 +185880,6 @@ function createCtxMemoryTool(deps) {
|
|
|
185503
185880
|
sourceType: dreamerAllowed ? "dreamer" : "agent"
|
|
185504
185881
|
});
|
|
185505
185882
|
queueEmbedding({ deps, projectIdentity, memoryId: memory2.id, content });
|
|
185506
|
-
invalidateAllMemoryBlockCaches(deps.db);
|
|
185507
185883
|
return ok2(`Saved memory [ID: ${memory2.id}] in ${rawCategory}.`);
|
|
185508
185884
|
}
|
|
185509
185885
|
if (params.action === "delete") {
|
|
@@ -185511,7 +185887,7 @@ function createCtxMemoryTool(deps) {
|
|
|
185511
185887
|
return err2("Error: 'id' is required when action is 'delete'.");
|
|
185512
185888
|
}
|
|
185513
185889
|
const memory2 = getMemoryById(deps.db, params.id);
|
|
185514
|
-
if (!memory2 || memory2.projectPath
|
|
185890
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
185515
185891
|
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
185516
185892
|
}
|
|
185517
185893
|
deps.db.transaction(() => {
|
|
@@ -185540,7 +185916,7 @@ function createCtxMemoryTool(deps) {
|
|
|
185540
185916
|
return err2("Error: 'content' is required when action is 'update'.");
|
|
185541
185917
|
}
|
|
185542
185918
|
const memory2 = getMemoryById(deps.db, params.id);
|
|
185543
|
-
if (!memory2 || memory2.projectPath
|
|
185919
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
185544
185920
|
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
185545
185921
|
}
|
|
185546
185922
|
const normalizedHash = computeNormalizedHash(content);
|
|
@@ -185574,9 +185950,6 @@ function createCtxMemoryTool(deps) {
|
|
|
185574
185950
|
if (sourceMemories.length !== ids.length) {
|
|
185575
185951
|
return err2("Error: One or more source memories were not found.");
|
|
185576
185952
|
}
|
|
185577
|
-
if (sourceMemories.some((memory2) => memory2.projectPath !== projectIdentity)) {
|
|
185578
|
-
return err2("Error: All memories to merge must belong to the current project.");
|
|
185579
|
-
}
|
|
185580
185953
|
const requestedCategory = params.category?.trim();
|
|
185581
185954
|
if (requestedCategory && !isMemoryCategory2(requestedCategory)) {
|
|
185582
185955
|
return err2(`Error: Unknown memory category '${requestedCategory}'. Valid: ${CATEGORY_PRIORITY.join(", ")}`);
|
|
@@ -185635,7 +186008,7 @@ function createCtxMemoryTool(deps) {
|
|
|
185635
186008
|
}
|
|
185636
186009
|
supersededMemory(deps.db, memory2.id, canonicalMemory.id);
|
|
185637
186010
|
queueMemoryMutation(deps.db, {
|
|
185638
|
-
projectPath: memory2.projectPath,
|
|
186011
|
+
projectPath: normalizeStoredProjectPath(memory2.projectPath),
|
|
185639
186012
|
mutationType: "superseded",
|
|
185640
186013
|
targetMemoryId: memory2.id,
|
|
185641
186014
|
supersededById: canonicalMemory.id
|
|
@@ -185643,7 +186016,7 @@ function createCtxMemoryTool(deps) {
|
|
|
185643
186016
|
}
|
|
185644
186017
|
if (canonicalExisting && canonicalContentChanged) {
|
|
185645
186018
|
queueMemoryMutation(deps.db, {
|
|
185646
|
-
projectPath: canonicalMemory.projectPath,
|
|
186019
|
+
projectPath: normalizeStoredProjectPath(canonicalMemory.projectPath),
|
|
185647
186020
|
mutationType: "update",
|
|
185648
186021
|
targetMemoryId: canonicalMemory.id,
|
|
185649
186022
|
category,
|
|
@@ -185665,7 +186038,7 @@ function createCtxMemoryTool(deps) {
|
|
|
185665
186038
|
return err2("Error: 'id' is required when action is 'archive'.");
|
|
185666
186039
|
}
|
|
185667
186040
|
const memory2 = getMemoryById(deps.db, params.id);
|
|
185668
|
-
if (!memory2 || memory2.projectPath
|
|
186041
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
185669
186042
|
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
185670
186043
|
}
|
|
185671
186044
|
deps.db.transaction(() => {
|
|
@@ -185927,7 +186300,7 @@ ${smartNotes.map(formatNoteLine).join(`
|
|
|
185927
186300
|
// ../plugin/src/features/magic-context/range-parser.ts
|
|
185928
186301
|
function parseRangeString(input) {
|
|
185929
186302
|
const maxRangeElements = 1000;
|
|
185930
|
-
const trimmed = input.trim();
|
|
186303
|
+
const trimmed = input.replace(/§/g, "").trim();
|
|
185931
186304
|
if (trimmed === "") {
|
|
185932
186305
|
throw new Error("Range string must not be empty");
|
|
185933
186306
|
}
|
|
@@ -186188,6 +186561,7 @@ function createCtxSearchTool(deps) {
|
|
|
186188
186561
|
const embeddingEnabled = snapshot ? snapshot.enabled || snapshot.gitCommitEnabled : deps.embeddingEnabled;
|
|
186189
186562
|
const gitCommitsEnabled = snapshot?.gitCommitEnabled ?? deps.gitCommitsEnabled ?? false;
|
|
186190
186563
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
186564
|
+
const messageOrdinalCutoff = lastCompartmentEnd >= 0 ? lastCompartmentEnd : 0;
|
|
186191
186565
|
const visibleMemoryIds = getVisibleMemoryIds(deps.db, sessionId);
|
|
186192
186566
|
const results = await unifiedSearch(deps.db, sessionId, projectIdentity, query, {
|
|
186193
186567
|
limit: normalizeLimit3(params.limit),
|
|
@@ -186198,7 +186572,7 @@ function createCtxSearchTool(deps) {
|
|
|
186198
186572
|
return result?.vector ?? null;
|
|
186199
186573
|
},
|
|
186200
186574
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
186201
|
-
maxMessageOrdinal:
|
|
186575
|
+
maxMessageOrdinal: messageOrdinalCutoff,
|
|
186202
186576
|
gitCommitsEnabled,
|
|
186203
186577
|
sources: params.sources,
|
|
186204
186578
|
visibleMemoryIds,
|
|
@@ -186526,6 +186900,7 @@ async function src_default2(pi) {
|
|
|
186526
186900
|
mmapSizeMb: config2.sqlite.mmap_size_mb
|
|
186527
186901
|
});
|
|
186528
186902
|
applySqliteTuningPragmas(db);
|
|
186903
|
+
setKeepSubagents(config2.keep_subagents === true);
|
|
186529
186904
|
if (!config2.enabled) {
|
|
186530
186905
|
info("plugin DISABLED via config (enabled: false) — skipping registration");
|
|
186531
186906
|
return;
|
|
@@ -186566,6 +186941,7 @@ async function src_default2(pi) {
|
|
|
186566
186941
|
clearReasoningAge: config2.clear_reasoning_age
|
|
186567
186942
|
},
|
|
186568
186943
|
injection: {
|
|
186944
|
+
memoryEnabled: config2.memory.enabled,
|
|
186569
186945
|
injectionBudgetTokens: config2.memory.injection_budget_tokens,
|
|
186570
186946
|
temporalAwareness: config2.temporal_awareness === true,
|
|
186571
186947
|
keyFilesEnabled: config2.dreamer?.pin_key_files?.enabled ?? false,
|
|
@@ -186677,6 +187053,33 @@ async function src_default2(pi) {
|
|
|
186677
187053
|
try {
|
|
186678
187054
|
const currentProject = resolveCurrentProject(ctx);
|
|
186679
187055
|
seenDreamerProjectIdentities.add(currentProject.projectIdentity);
|
|
187056
|
+
const switchedProject = currentProject.projectDir !== projectDir;
|
|
187057
|
+
const effectiveConfig = switchedProject ? loadPiConfig({ cwd: currentProject.projectDir }).config : config2;
|
|
187058
|
+
const effectiveDreamerConfig = switchedProject ? resolveDreamerFromConfig(effectiveConfig) : dreamerConfig;
|
|
187059
|
+
if (effectiveDreamerConfig) {
|
|
187060
|
+
try {
|
|
187061
|
+
registerPiDreamerProject({
|
|
187062
|
+
db,
|
|
187063
|
+
projectDir: currentProject.projectDir,
|
|
187064
|
+
projectIdentity: currentProject.projectIdentity,
|
|
187065
|
+
config: effectiveDreamerConfig,
|
|
187066
|
+
embeddingConfig: effectiveConfig.embedding,
|
|
187067
|
+
memoryEnabled: effectiveConfig.memory.enabled,
|
|
187068
|
+
gitCommitIndexing: effectiveConfig.memory.git_commit_indexing,
|
|
187069
|
+
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|
|
187070
|
+
});
|
|
187071
|
+
} catch (err5) {
|
|
187072
|
+
warn("before_agent_start: registerPiDreamerProject threw:", err5);
|
|
187073
|
+
}
|
|
187074
|
+
} else if (switchedProject) {
|
|
187075
|
+
try {
|
|
187076
|
+
unregisterPiDreamerProject({
|
|
187077
|
+
projectIdentity: currentProject.projectIdentity
|
|
187078
|
+
});
|
|
187079
|
+
} catch (err5) {
|
|
187080
|
+
warn("before_agent_start: unregisterPiDreamerProject threw:", err5);
|
|
187081
|
+
}
|
|
187082
|
+
}
|
|
186680
187083
|
const sm = ctx.sessionManager;
|
|
186681
187084
|
let sessionId;
|
|
186682
187085
|
if (sm !== undefined) {
|