@cortexkit/pi-magic-context 0.16.3 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1511 -755
- package/dist/subagent-entry.js +1357 -788
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15453,7 +15453,8 @@ function findLastAssistantModelFromOpenCodeDb(sessionId) {
|
|
|
15453
15453
|
try {
|
|
15454
15454
|
return withReadOnlySessionDb((db) => {
|
|
15455
15455
|
const row = db.prepare(`SELECT json_extract(data, '$.providerID') as providerID,
|
|
15456
|
-
json_extract(data, '$.modelID') as modelID
|
|
15456
|
+
json_extract(data, '$.modelID') as modelID,
|
|
15457
|
+
json_extract(data, '$.agent') as agent
|
|
15457
15458
|
FROM message
|
|
15458
15459
|
WHERE session_id = ?
|
|
15459
15460
|
AND json_extract(data, '$.role') = 'assistant'
|
|
@@ -15464,7 +15465,12 @@ function findLastAssistantModelFromOpenCodeDb(sessionId) {
|
|
|
15464
15465
|
if (!row || typeof row.providerID !== "string" || typeof row.modelID !== "string") {
|
|
15465
15466
|
return null;
|
|
15466
15467
|
}
|
|
15467
|
-
|
|
15468
|
+
const agent = typeof row.agent === "string" && row.agent.length > 0 ? row.agent : undefined;
|
|
15469
|
+
return {
|
|
15470
|
+
providerID: row.providerID,
|
|
15471
|
+
modelID: row.modelID,
|
|
15472
|
+
...agent ? { agent } : {}
|
|
15473
|
+
};
|
|
15468
15474
|
});
|
|
15469
15475
|
} catch (error48) {
|
|
15470
15476
|
log("[magic-context] failed to recover live model from OpenCode DB:", error48);
|
|
@@ -23112,10 +23118,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23112
23118
|
replacer = null;
|
|
23113
23119
|
indent = EMPTY;
|
|
23114
23120
|
};
|
|
23115
|
-
var
|
|
23121
|
+
var join13 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
23116
23122
|
var join_content = (inside, value, gap) => {
|
|
23117
23123
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
23118
|
-
return
|
|
23124
|
+
return join13(comment, inside, gap);
|
|
23119
23125
|
};
|
|
23120
23126
|
var stringify_string = (holder, key, value) => {
|
|
23121
23127
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -23137,13 +23143,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23137
23143
|
if (i !== 0) {
|
|
23138
23144
|
inside += COMMA;
|
|
23139
23145
|
}
|
|
23140
|
-
const before =
|
|
23146
|
+
const before = join13(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
23141
23147
|
inside += before || LF + deeper_gap;
|
|
23142
23148
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
23143
23149
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
23144
23150
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
23145
23151
|
}
|
|
23146
|
-
inside +=
|
|
23152
|
+
inside += join13(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
23147
23153
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
23148
23154
|
};
|
|
23149
23155
|
var object_stringify = (value, gap) => {
|
|
@@ -23164,13 +23170,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23164
23170
|
inside += COMMA;
|
|
23165
23171
|
}
|
|
23166
23172
|
first = false;
|
|
23167
|
-
const before =
|
|
23173
|
+
const before = join13(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
23168
23174
|
inside += before || LF + deeper_gap;
|
|
23169
23175
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
23170
23176
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
23171
23177
|
};
|
|
23172
23178
|
keys.forEach(iteratee);
|
|
23173
|
-
inside +=
|
|
23179
|
+
inside += join13(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
23174
23180
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
23175
23181
|
};
|
|
23176
23182
|
function stringify(key, holder, gap) {
|
|
@@ -23265,7 +23271,7 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
23265
23271
|
// src/index.ts
|
|
23266
23272
|
init_embedding();
|
|
23267
23273
|
import { createRequire as createRequire2 } from "node:module";
|
|
23268
|
-
import { join as
|
|
23274
|
+
import { join as join15 } from "node:path";
|
|
23269
23275
|
|
|
23270
23276
|
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
23271
23277
|
import { execSync } from "node:child_process";
|
|
@@ -23305,422 +23311,9 @@ function resolveProjectIdentity(directory) {
|
|
|
23305
23311
|
return identity;
|
|
23306
23312
|
}
|
|
23307
23313
|
|
|
23308
|
-
// ../plugin/src/features/magic-context/
|
|
23309
|
-
|
|
23310
|
-
/prompt is too long/i,
|
|
23311
|
-
/input is too long for requested model/i,
|
|
23312
|
-
/exceeds the context window/i,
|
|
23313
|
-
/input token count.*exceeds the maximum/i,
|
|
23314
|
-
/maximum prompt length is \d+/i,
|
|
23315
|
-
/reduce the length of the messages/i,
|
|
23316
|
-
/maximum context length is \d+ tokens/i,
|
|
23317
|
-
/exceeds the limit of \d+/i,
|
|
23318
|
-
/exceeds the available context size/i,
|
|
23319
|
-
/greater than the context length/i,
|
|
23320
|
-
/context window exceeds limit/i,
|
|
23321
|
-
/exceeded model token limit/i,
|
|
23322
|
-
/context[_ ]length[_ ]exceeded/i,
|
|
23323
|
-
/request entity too large/i,
|
|
23324
|
-
/context length is only \d+ tokens/i,
|
|
23325
|
-
/input length.*exceeds.*context length/i,
|
|
23326
|
-
/prompt too long; exceeded (?:max )?context length/i,
|
|
23327
|
-
/too large for model with \d+ maximum context length/i,
|
|
23328
|
-
/model_context_window_exceeded/i,
|
|
23329
|
-
/context size has been exceeded/i
|
|
23330
|
-
];
|
|
23331
|
-
var LIMIT_EXTRACTION_PATTERNS = [
|
|
23332
|
-
/maximum prompt length is (\d+)/i,
|
|
23333
|
-
/maximum context length is (\d+) tokens?/i,
|
|
23334
|
-
/context length is only (\d+) tokens?/i,
|
|
23335
|
-
/exceeds the limit of (\d+)/i,
|
|
23336
|
-
/too large for model with (\d+) maximum context length/i,
|
|
23337
|
-
/context size.*(\d+) tokens?/i,
|
|
23338
|
-
/exceeds? the context length of (\d+)/i,
|
|
23339
|
-
/max(?:imum)?.*context.*?(\d+)/i
|
|
23340
|
-
];
|
|
23341
|
-
var MIN_PLAUSIBLE_LIMIT = 1024;
|
|
23342
|
-
var MAX_PLAUSIBLE_LIMIT = 1e7;
|
|
23343
|
-
function extractErrorMessage(error48) {
|
|
23344
|
-
if (!error48)
|
|
23345
|
-
return "";
|
|
23346
|
-
if (typeof error48 === "string")
|
|
23347
|
-
return error48;
|
|
23348
|
-
if (typeof error48 === "object") {
|
|
23349
|
-
const obj = error48;
|
|
23350
|
-
const nested = obj.error;
|
|
23351
|
-
if (nested && typeof nested.message === "string" && nested.message.length > 0) {
|
|
23352
|
-
return nested.message;
|
|
23353
|
-
}
|
|
23354
|
-
}
|
|
23355
|
-
if (error48 instanceof Error)
|
|
23356
|
-
return error48.message;
|
|
23357
|
-
if (typeof error48 === "object") {
|
|
23358
|
-
const obj = error48;
|
|
23359
|
-
if (typeof obj.message === "string")
|
|
23360
|
-
return obj.message;
|
|
23361
|
-
if (typeof obj.responseBody === "string")
|
|
23362
|
-
return obj.responseBody;
|
|
23363
|
-
try {
|
|
23364
|
-
return JSON.stringify(error48);
|
|
23365
|
-
} catch {
|
|
23366
|
-
return String(error48);
|
|
23367
|
-
}
|
|
23368
|
-
}
|
|
23369
|
-
return String(error48);
|
|
23370
|
-
}
|
|
23371
|
-
function detectOverflow(error48) {
|
|
23372
|
-
const message = extractErrorMessage(error48);
|
|
23373
|
-
if (!message) {
|
|
23374
|
-
return { isOverflow: false };
|
|
23375
|
-
}
|
|
23376
|
-
const hasStatus413 = /\b413\b/.test(message) && /(entity|payload|context|prompt)/i.test(message);
|
|
23377
|
-
let matched;
|
|
23378
|
-
for (const pattern of OVERFLOW_PATTERNS) {
|
|
23379
|
-
if (pattern.test(message)) {
|
|
23380
|
-
matched = pattern;
|
|
23381
|
-
break;
|
|
23382
|
-
}
|
|
23383
|
-
}
|
|
23384
|
-
if (!matched && !hasStatus413) {
|
|
23385
|
-
return { isOverflow: false };
|
|
23386
|
-
}
|
|
23387
|
-
const reportedLimit = parseReportedLimit(message);
|
|
23388
|
-
return {
|
|
23389
|
-
isOverflow: true,
|
|
23390
|
-
reportedLimit,
|
|
23391
|
-
matchedPattern: matched?.source
|
|
23392
|
-
};
|
|
23393
|
-
}
|
|
23394
|
-
function parseReportedLimit(message) {
|
|
23395
|
-
if (!message)
|
|
23396
|
-
return;
|
|
23397
|
-
for (const pattern of LIMIT_EXTRACTION_PATTERNS) {
|
|
23398
|
-
const match = message.match(pattern);
|
|
23399
|
-
if (!match)
|
|
23400
|
-
continue;
|
|
23401
|
-
const raw = match[1];
|
|
23402
|
-
if (!raw)
|
|
23403
|
-
continue;
|
|
23404
|
-
const value = Number.parseInt(raw, 10);
|
|
23405
|
-
if (!Number.isFinite(value))
|
|
23406
|
-
continue;
|
|
23407
|
-
if (value < MIN_PLAUSIBLE_LIMIT || value > MAX_PLAUSIBLE_LIMIT)
|
|
23408
|
-
continue;
|
|
23409
|
-
return value;
|
|
23410
|
-
}
|
|
23411
|
-
return;
|
|
23412
|
-
}
|
|
23413
|
-
|
|
23414
|
-
// ../plugin/src/shared/harness.ts
|
|
23415
|
-
var currentHarness = "opencode";
|
|
23416
|
-
var harnessLocked = false;
|
|
23417
|
-
function setHarness(value) {
|
|
23418
|
-
if (harnessLocked && currentHarness !== value) {
|
|
23419
|
-
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
23420
|
-
}
|
|
23421
|
-
currentHarness = value;
|
|
23422
|
-
harnessLocked = true;
|
|
23423
|
-
}
|
|
23424
|
-
function getHarness() {
|
|
23425
|
-
return currentHarness;
|
|
23426
|
-
}
|
|
23314
|
+
// ../plugin/src/features/magic-context/message-index-async.ts
|
|
23315
|
+
init_logger();
|
|
23427
23316
|
|
|
23428
|
-
// ../plugin/src/features/magic-context/compartment-storage.ts
|
|
23429
|
-
var insertCompartmentStatements = new WeakMap;
|
|
23430
|
-
var insertFactStatements = new WeakMap;
|
|
23431
|
-
function getInsertCompartmentStatement(db) {
|
|
23432
|
-
let stmt = insertCompartmentStatements.get(db);
|
|
23433
|
-
if (!stmt) {
|
|
23434
|
-
stmt = db.prepare("INSERT INTO compartments (session_id, sequence, start_message, end_message, start_message_id, end_message_id, title, content, created_at, harness) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
23435
|
-
insertCompartmentStatements.set(db, stmt);
|
|
23436
|
-
}
|
|
23437
|
-
return stmt;
|
|
23438
|
-
}
|
|
23439
|
-
function getInsertFactStatement(db) {
|
|
23440
|
-
let stmt = insertFactStatements.get(db);
|
|
23441
|
-
if (!stmt) {
|
|
23442
|
-
stmt = db.prepare("INSERT INTO session_facts (session_id, category, content, created_at, updated_at, harness) VALUES (?, ?, ?, ?, ?, ?)");
|
|
23443
|
-
insertFactStatements.set(db, stmt);
|
|
23444
|
-
}
|
|
23445
|
-
return stmt;
|
|
23446
|
-
}
|
|
23447
|
-
function isCompartmentRow(row) {
|
|
23448
|
-
if (row === null || typeof row !== "object")
|
|
23449
|
-
return false;
|
|
23450
|
-
const candidate = row;
|
|
23451
|
-
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" && typeof candidate.created_at === "number";
|
|
23452
|
-
}
|
|
23453
|
-
function isSessionFactRow(row) {
|
|
23454
|
-
if (row === null || typeof row !== "object")
|
|
23455
|
-
return false;
|
|
23456
|
-
const candidate = row;
|
|
23457
|
-
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";
|
|
23458
|
-
}
|
|
23459
|
-
function insertCompartmentRows(db, sessionId, compartments, now) {
|
|
23460
|
-
const stmt = getInsertCompartmentStatement(db);
|
|
23461
|
-
for (const compartment of compartments) {
|
|
23462
|
-
stmt.run(sessionId, compartment.sequence, compartment.startMessage, compartment.endMessage, compartment.startMessageId, compartment.endMessageId, compartment.title, compartment.content, now, getHarness());
|
|
23463
|
-
}
|
|
23464
|
-
}
|
|
23465
|
-
function insertFactRows(db, sessionId, facts, now) {
|
|
23466
|
-
const stmt = getInsertFactStatement(db);
|
|
23467
|
-
for (const fact of facts) {
|
|
23468
|
-
stmt.run(sessionId, fact.category, fact.content, now, now, getHarness());
|
|
23469
|
-
}
|
|
23470
|
-
}
|
|
23471
|
-
function toCompartment(row) {
|
|
23472
|
-
return {
|
|
23473
|
-
id: row.id,
|
|
23474
|
-
sessionId: row.session_id,
|
|
23475
|
-
sequence: row.sequence,
|
|
23476
|
-
startMessage: row.start_message,
|
|
23477
|
-
endMessage: row.end_message,
|
|
23478
|
-
startMessageId: row.start_message_id,
|
|
23479
|
-
endMessageId: row.end_message_id,
|
|
23480
|
-
title: row.title,
|
|
23481
|
-
content: row.content,
|
|
23482
|
-
createdAt: row.created_at
|
|
23483
|
-
};
|
|
23484
|
-
}
|
|
23485
|
-
function toSessionFact(row) {
|
|
23486
|
-
return {
|
|
23487
|
-
id: row.id,
|
|
23488
|
-
sessionId: row.session_id,
|
|
23489
|
-
category: row.category,
|
|
23490
|
-
content: row.content,
|
|
23491
|
-
createdAt: row.created_at,
|
|
23492
|
-
updatedAt: row.updated_at
|
|
23493
|
-
};
|
|
23494
|
-
}
|
|
23495
|
-
function getCompartments(db, sessionId) {
|
|
23496
|
-
const rows = db.prepare("SELECT * FROM compartments WHERE session_id = ? ORDER BY sequence ASC").all(sessionId).filter(isCompartmentRow);
|
|
23497
|
-
return rows.map(toCompartment);
|
|
23498
|
-
}
|
|
23499
|
-
function getLastCompartmentEndMessage(db, sessionId) {
|
|
23500
|
-
const row = db.prepare("SELECT MAX(end_message) as max_end FROM compartments WHERE session_id = ?").get(sessionId);
|
|
23501
|
-
return row?.max_end ?? -1;
|
|
23502
|
-
}
|
|
23503
|
-
function appendCompartments(db, sessionId, compartments) {
|
|
23504
|
-
if (compartments.length === 0)
|
|
23505
|
-
return;
|
|
23506
|
-
const now = Date.now();
|
|
23507
|
-
db.transaction(() => {
|
|
23508
|
-
insertCompartmentRows(db, sessionId, compartments, now);
|
|
23509
|
-
})();
|
|
23510
|
-
}
|
|
23511
|
-
function replaceSessionFacts(db, sessionId, facts) {
|
|
23512
|
-
const now = Date.now();
|
|
23513
|
-
db.transaction(() => {
|
|
23514
|
-
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
23515
|
-
insertFactRows(db, sessionId, facts, now);
|
|
23516
|
-
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
23517
|
-
})();
|
|
23518
|
-
}
|
|
23519
|
-
function getSessionFacts(db, sessionId) {
|
|
23520
|
-
const rows = db.prepare("SELECT * FROM session_facts WHERE session_id = ? ORDER BY category ASC, id ASC").all(sessionId).filter(isSessionFactRow);
|
|
23521
|
-
return rows.map(toSessionFact);
|
|
23522
|
-
}
|
|
23523
|
-
function replaceAllCompartmentState(db, sessionId, compartments, facts) {
|
|
23524
|
-
const now = Date.now();
|
|
23525
|
-
db.transaction(() => {
|
|
23526
|
-
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
23527
|
-
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
23528
|
-
insertCompartmentRows(db, sessionId, compartments, now);
|
|
23529
|
-
insertFactRows(db, sessionId, facts, now);
|
|
23530
|
-
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
23531
|
-
})();
|
|
23532
|
-
}
|
|
23533
|
-
function buildCompartmentBlock(compartments, facts, memoryBlock, dateRanges) {
|
|
23534
|
-
const lines = [];
|
|
23535
|
-
if (memoryBlock) {
|
|
23536
|
-
lines.push(memoryBlock);
|
|
23537
|
-
lines.push("");
|
|
23538
|
-
}
|
|
23539
|
-
for (const c of compartments) {
|
|
23540
|
-
const dates = dateRanges?.byId.get(c.id);
|
|
23541
|
-
const dateAttr = dates ? ` start-date="${dates.start}" end-date="${dates.end}"` : "";
|
|
23542
|
-
lines.push(`<compartment start="${c.startMessage}" end="${c.endMessage}"${dateAttr} title="${escapeXmlAttr(c.title)}">`);
|
|
23543
|
-
lines.push(escapeXmlContent(c.content));
|
|
23544
|
-
lines.push("</compartment>");
|
|
23545
|
-
lines.push("");
|
|
23546
|
-
}
|
|
23547
|
-
const factsByCategory = new Map;
|
|
23548
|
-
for (const f of facts) {
|
|
23549
|
-
const existing = factsByCategory.get(f.category) ?? [];
|
|
23550
|
-
existing.push(f.content);
|
|
23551
|
-
factsByCategory.set(f.category, existing);
|
|
23552
|
-
}
|
|
23553
|
-
for (const [category, items] of factsByCategory) {
|
|
23554
|
-
lines.push(`${category}:`);
|
|
23555
|
-
for (const item of items) {
|
|
23556
|
-
lines.push(`* ${escapeXmlContent(item)}`);
|
|
23557
|
-
}
|
|
23558
|
-
lines.push("");
|
|
23559
|
-
}
|
|
23560
|
-
return lines.join(`
|
|
23561
|
-
`).trimEnd();
|
|
23562
|
-
}
|
|
23563
|
-
function saveRecompStagingPass(db, sessionId, passNumber, compartments, facts) {
|
|
23564
|
-
const now = Date.now();
|
|
23565
|
-
db.transaction(() => {
|
|
23566
|
-
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
23567
|
-
const compartmentStmt = db.prepare("INSERT OR REPLACE INTO recomp_compartments (session_id, sequence, start_message, end_message, start_message_id, end_message_id, title, content, pass_number, created_at, harness) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
23568
|
-
for (const c of compartments) {
|
|
23569
|
-
compartmentStmt.run(sessionId, c.sequence, c.startMessage, c.endMessage, c.startMessageId, c.endMessageId, c.title, c.content, passNumber, now, getHarness());
|
|
23570
|
-
}
|
|
23571
|
-
const factStmt = db.prepare("INSERT INTO recomp_facts (session_id, category, content, pass_number, created_at, harness) VALUES (?, ?, ?, ?, ?, ?)");
|
|
23572
|
-
for (const f of facts) {
|
|
23573
|
-
factStmt.run(sessionId, f.category, f.content, passNumber, now, getHarness());
|
|
23574
|
-
}
|
|
23575
|
-
})();
|
|
23576
|
-
}
|
|
23577
|
-
function getRecompStaging(db, sessionId) {
|
|
23578
|
-
const compartmentRows = db.prepare("SELECT * FROM recomp_compartments WHERE session_id = ? ORDER BY sequence ASC").all(sessionId).filter(isRecompCompartmentRow);
|
|
23579
|
-
if (compartmentRows.length === 0)
|
|
23580
|
-
return null;
|
|
23581
|
-
const compartments = compartmentRows.map((row) => ({
|
|
23582
|
-
sequence: row.sequence,
|
|
23583
|
-
startMessage: row.start_message,
|
|
23584
|
-
endMessage: row.end_message,
|
|
23585
|
-
startMessageId: row.start_message_id,
|
|
23586
|
-
endMessageId: row.end_message_id,
|
|
23587
|
-
title: row.title,
|
|
23588
|
-
content: row.content
|
|
23589
|
-
}));
|
|
23590
|
-
const factRows = db.prepare("SELECT category, content FROM recomp_facts WHERE session_id = ?").all(sessionId).filter(isRecompFactRow);
|
|
23591
|
-
const maxPass = compartmentRows.reduce((m, r) => Math.max(m, r.pass_number), 0);
|
|
23592
|
-
const lastEnd = compartmentRows[compartmentRows.length - 1]?.end_message ?? 0;
|
|
23593
|
-
return {
|
|
23594
|
-
compartments,
|
|
23595
|
-
facts: factRows,
|
|
23596
|
-
passCount: maxPass,
|
|
23597
|
-
lastEndMessage: lastEnd
|
|
23598
|
-
};
|
|
23599
|
-
}
|
|
23600
|
-
function promoteRecompStaging(db, sessionId) {
|
|
23601
|
-
const now = Date.now();
|
|
23602
|
-
return db.transaction(() => {
|
|
23603
|
-
const staging = getRecompStaging(db, sessionId);
|
|
23604
|
-
if (!staging || staging.compartments.length === 0)
|
|
23605
|
-
return null;
|
|
23606
|
-
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
23607
|
-
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
23608
|
-
insertCompartmentRows(db, sessionId, staging.compartments, now);
|
|
23609
|
-
insertFactRows(db, sessionId, staging.facts, now);
|
|
23610
|
-
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
23611
|
-
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
23612
|
-
db.prepare("UPDATE session_meta SET memory_block_cache = '' WHERE session_id = ?").run(sessionId);
|
|
23613
|
-
return { compartments: staging.compartments, facts: staging.facts };
|
|
23614
|
-
})();
|
|
23615
|
-
}
|
|
23616
|
-
function invalidateAllMemoryBlockCaches(db) {
|
|
23617
|
-
try {
|
|
23618
|
-
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE memory_block_cache != '' OR memory_block_ids != ''").run();
|
|
23619
|
-
} catch {}
|
|
23620
|
-
}
|
|
23621
|
-
function clearRecompStaging(db, sessionId) {
|
|
23622
|
-
db.transaction(() => {
|
|
23623
|
-
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
23624
|
-
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
23625
|
-
try {
|
|
23626
|
-
db.prepare("UPDATE session_meta SET recomp_partial_range_start = 0, recomp_partial_range_end = 0 WHERE session_id = ?").run(sessionId);
|
|
23627
|
-
} catch {}
|
|
23628
|
-
})();
|
|
23629
|
-
}
|
|
23630
|
-
function getRecompPartialRange(db, sessionId) {
|
|
23631
|
-
try {
|
|
23632
|
-
const row = db.prepare("SELECT recomp_partial_range_start AS start, recomp_partial_range_end AS end FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
23633
|
-
const start = typeof row?.start === "number" ? row.start : 0;
|
|
23634
|
-
const end = typeof row?.end === "number" ? row.end : 0;
|
|
23635
|
-
if (start <= 0 || end <= 0)
|
|
23636
|
-
return null;
|
|
23637
|
-
return { start, end };
|
|
23638
|
-
} catch {
|
|
23639
|
-
return null;
|
|
23640
|
-
}
|
|
23641
|
-
}
|
|
23642
|
-
function setRecompPartialRange(db, sessionId, range) {
|
|
23643
|
-
const start = range ? range.start : 0;
|
|
23644
|
-
const end = range ? range.end : 0;
|
|
23645
|
-
db.prepare("INSERT OR IGNORE INTO session_meta (session_id) VALUES (?)").run(sessionId);
|
|
23646
|
-
db.prepare("UPDATE session_meta SET recomp_partial_range_start = ?, recomp_partial_range_end = ? WHERE session_id = ?").run(start, end, sessionId);
|
|
23647
|
-
}
|
|
23648
|
-
function isRecompCompartmentRow(row) {
|
|
23649
|
-
if (row === null || typeof row !== "object")
|
|
23650
|
-
return false;
|
|
23651
|
-
const candidate = row;
|
|
23652
|
-
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" && typeof candidate.pass_number === "number" && typeof candidate.created_at === "number";
|
|
23653
|
-
}
|
|
23654
|
-
function isRecompFactRow(row) {
|
|
23655
|
-
if (row === null || typeof row !== "object")
|
|
23656
|
-
return false;
|
|
23657
|
-
const candidate = row;
|
|
23658
|
-
return typeof candidate.category === "string" && typeof candidate.content === "string";
|
|
23659
|
-
}
|
|
23660
|
-
function escapeXmlAttr(s) {
|
|
23661
|
-
return s.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
23662
|
-
}
|
|
23663
|
-
function escapeXmlContent(s) {
|
|
23664
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
23665
|
-
}
|
|
23666
|
-
// ../plugin/src/features/magic-context/compression-depth-storage.ts
|
|
23667
|
-
var incrementDepthStatements = new WeakMap;
|
|
23668
|
-
var totalDepthStatements = new WeakMap;
|
|
23669
|
-
var maxDepthStatements = new WeakMap;
|
|
23670
|
-
var clearDepthStatements = new WeakMap;
|
|
23671
|
-
function getIncrementDepthStatement(db) {
|
|
23672
|
-
let stmt = incrementDepthStatements.get(db);
|
|
23673
|
-
if (!stmt) {
|
|
23674
|
-
stmt = db.prepare("INSERT INTO compression_depth (session_id, message_ordinal, depth, harness) VALUES (?, ?, 1, ?) ON CONFLICT(session_id, message_ordinal) DO UPDATE SET depth = depth + 1");
|
|
23675
|
-
incrementDepthStatements.set(db, stmt);
|
|
23676
|
-
}
|
|
23677
|
-
return stmt;
|
|
23678
|
-
}
|
|
23679
|
-
function getTotalDepthStatement(db) {
|
|
23680
|
-
let stmt = totalDepthStatements.get(db);
|
|
23681
|
-
if (!stmt) {
|
|
23682
|
-
stmt = db.prepare("SELECT COALESCE(SUM(depth), 0) AS total_depth FROM compression_depth WHERE session_id = ? AND message_ordinal BETWEEN ? AND ?");
|
|
23683
|
-
totalDepthStatements.set(db, stmt);
|
|
23684
|
-
}
|
|
23685
|
-
return stmt;
|
|
23686
|
-
}
|
|
23687
|
-
function getClearDepthStatement(db) {
|
|
23688
|
-
let stmt = clearDepthStatements.get(db);
|
|
23689
|
-
if (!stmt) {
|
|
23690
|
-
stmt = db.prepare("DELETE FROM compression_depth WHERE session_id = ?");
|
|
23691
|
-
clearDepthStatements.set(db, stmt);
|
|
23692
|
-
}
|
|
23693
|
-
return stmt;
|
|
23694
|
-
}
|
|
23695
|
-
function incrementCompressionDepth(db, sessionId, startOrdinal, endOrdinal) {
|
|
23696
|
-
if (endOrdinal < startOrdinal) {
|
|
23697
|
-
return;
|
|
23698
|
-
}
|
|
23699
|
-
db.transaction(() => {
|
|
23700
|
-
const stmt = getIncrementDepthStatement(db);
|
|
23701
|
-
for (let ordinal = startOrdinal;ordinal <= endOrdinal; ordinal += 1) {
|
|
23702
|
-
stmt.run(sessionId, ordinal, getHarness());
|
|
23703
|
-
}
|
|
23704
|
-
})();
|
|
23705
|
-
}
|
|
23706
|
-
function getAverageCompressionDepth(db, sessionId, startOrdinal, endOrdinal) {
|
|
23707
|
-
if (endOrdinal < startOrdinal) {
|
|
23708
|
-
return 0;
|
|
23709
|
-
}
|
|
23710
|
-
const row = getTotalDepthStatement(db).get(sessionId, startOrdinal, endOrdinal);
|
|
23711
|
-
const totalDepth = typeof row?.total_depth === "number" ? row.total_depth : 0;
|
|
23712
|
-
const messageCount = endOrdinal - startOrdinal + 1;
|
|
23713
|
-
return totalDepth / messageCount;
|
|
23714
|
-
}
|
|
23715
|
-
function clearCompressionDepth(db, sessionId) {
|
|
23716
|
-
getClearDepthStatement(db).run(sessionId);
|
|
23717
|
-
}
|
|
23718
|
-
function clearCompressionDepthRange(db, sessionId, startOrdinal, endOrdinal) {
|
|
23719
|
-
if (endOrdinal < startOrdinal) {
|
|
23720
|
-
return;
|
|
23721
|
-
}
|
|
23722
|
-
db.prepare("DELETE FROM compression_depth WHERE session_id = ? AND message_ordinal BETWEEN ? AND ?").run(sessionId, startOrdinal, endOrdinal);
|
|
23723
|
-
}
|
|
23724
23317
|
// ../plugin/src/shared/internal-initiator-marker.ts
|
|
23725
23318
|
var OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->";
|
|
23726
23319
|
|
|
@@ -156398,21 +155991,85 @@ function isTextPart(part) {
|
|
|
156398
155991
|
const p = part;
|
|
156399
155992
|
return p.type === "text" && typeof p.text === "string";
|
|
156400
155993
|
}
|
|
156401
|
-
function
|
|
155994
|
+
function isFilePart(part) {
|
|
156402
155995
|
if (part === null || typeof part !== "object")
|
|
156403
155996
|
return false;
|
|
156404
155997
|
const p = part;
|
|
156405
|
-
|
|
155998
|
+
return p.type === "file" && typeof p.url === "string";
|
|
155999
|
+
}
|
|
156000
|
+
|
|
156001
|
+
// ../plugin/src/shared/record-type-guard.ts
|
|
156002
|
+
function isRecord(value) {
|
|
156003
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
156004
|
+
}
|
|
156005
|
+
|
|
156006
|
+
// ../plugin/src/hooks/magic-context/tool-drop-target.ts
|
|
156007
|
+
var IGNORE_PART_TYPES = new Set([
|
|
156008
|
+
"thinking",
|
|
156009
|
+
"reasoning",
|
|
156010
|
+
"redacted_thinking",
|
|
156011
|
+
"meta",
|
|
156012
|
+
"step-start",
|
|
156013
|
+
"step-finish"
|
|
156014
|
+
]);
|
|
156015
|
+
function isToolCallId(value) {
|
|
156016
|
+
return typeof value === "string" && value.length > 0;
|
|
156017
|
+
}
|
|
156018
|
+
function hasMeaningfulPart(part) {
|
|
156019
|
+
if (!isRecord(part))
|
|
156406
156020
|
return false;
|
|
156407
|
-
|
|
156021
|
+
const type = part.type;
|
|
156022
|
+
if (type === "text") {
|
|
156023
|
+
return typeof part.text === "string" && part.text.trim().length > 0;
|
|
156024
|
+
}
|
|
156025
|
+
if (typeof type !== "string")
|
|
156408
156026
|
return false;
|
|
156409
|
-
|
|
156410
|
-
}
|
|
156411
|
-
function isFilePart(part) {
|
|
156412
|
-
if (part === null || typeof part !== "object")
|
|
156027
|
+
if (IGNORE_PART_TYPES.has(type))
|
|
156413
156028
|
return false;
|
|
156414
|
-
|
|
156415
|
-
|
|
156029
|
+
return true;
|
|
156030
|
+
}
|
|
156031
|
+
function extractToolCallObservation(part) {
|
|
156032
|
+
if (!isRecord(part))
|
|
156033
|
+
return null;
|
|
156034
|
+
if (part.type === "tool" && isToolCallId(part.callID)) {
|
|
156035
|
+
return { callId: part.callID, kind: "result" };
|
|
156036
|
+
}
|
|
156037
|
+
if (part.type === "tool-invocation" && isToolCallId(part.callID)) {
|
|
156038
|
+
return { callId: part.callID, kind: "invocation" };
|
|
156039
|
+
}
|
|
156040
|
+
if (part.type === "tool_use" && isToolCallId(part.id)) {
|
|
156041
|
+
return { callId: part.id, kind: "invocation" };
|
|
156042
|
+
}
|
|
156043
|
+
if (part.type === "tool_result" && isToolCallId(part.tool_use_id)) {
|
|
156044
|
+
return { callId: part.tool_use_id, kind: "result" };
|
|
156045
|
+
}
|
|
156046
|
+
return null;
|
|
156047
|
+
}
|
|
156048
|
+
class ToolMutationBatch {
|
|
156049
|
+
partsToRemove = new Set;
|
|
156050
|
+
affectedMessages = new Set;
|
|
156051
|
+
messages;
|
|
156052
|
+
constructor(messages) {
|
|
156053
|
+
this.messages = messages;
|
|
156054
|
+
}
|
|
156055
|
+
markForRemoval(occurrence) {
|
|
156056
|
+
this.partsToRemove.add(occurrence.part);
|
|
156057
|
+
this.affectedMessages.add(occurrence.message);
|
|
156058
|
+
}
|
|
156059
|
+
finalize() {
|
|
156060
|
+
if (this.partsToRemove.size === 0)
|
|
156061
|
+
return;
|
|
156062
|
+
for (const message of this.affectedMessages) {
|
|
156063
|
+
message.parts = message.parts.filter((p) => !this.partsToRemove.has(p));
|
|
156064
|
+
}
|
|
156065
|
+
for (let i = this.messages.length - 1;i >= 0; i -= 1) {
|
|
156066
|
+
if (!this.messages[i].parts.some(hasMeaningfulPart)) {
|
|
156067
|
+
this.messages.splice(i, 1);
|
|
156068
|
+
}
|
|
156069
|
+
}
|
|
156070
|
+
this.partsToRemove.clear();
|
|
156071
|
+
this.affectedMessages.clear();
|
|
156072
|
+
}
|
|
156416
156073
|
}
|
|
156417
156074
|
|
|
156418
156075
|
// ../plugin/src/hooks/magic-context/read-session-chunk.ts
|
|
@@ -156479,23 +156136,47 @@ function getRawSessionMessageCount(sessionId) {
|
|
|
156479
156136
|
}
|
|
156480
156137
|
function getRawSessionTagKeysThrough(sessionId, upToMessageIndex) {
|
|
156481
156138
|
const messages = readRawSessionMessages(sessionId);
|
|
156482
|
-
const
|
|
156139
|
+
const messageFileKeys = new Set;
|
|
156140
|
+
const toolObservations = new Map;
|
|
156141
|
+
const unpairedInvocations = new Map;
|
|
156483
156142
|
for (const message of messages) {
|
|
156484
156143
|
if (message.ordinal > upToMessageIndex)
|
|
156485
156144
|
break;
|
|
156486
156145
|
for (const [partIndex, part] of message.parts.entries()) {
|
|
156487
156146
|
if (isTextPart(part)) {
|
|
156488
|
-
|
|
156147
|
+
messageFileKeys.add(`${message.id}:p${partIndex}`);
|
|
156148
|
+
continue;
|
|
156489
156149
|
}
|
|
156490
156150
|
if (isFilePart(part)) {
|
|
156491
|
-
|
|
156151
|
+
messageFileKeys.add(`${message.id}:file${partIndex}`);
|
|
156152
|
+
continue;
|
|
156492
156153
|
}
|
|
156493
|
-
|
|
156494
|
-
|
|
156154
|
+
const obs = extractToolCallObservation(part);
|
|
156155
|
+
if (!obs)
|
|
156156
|
+
continue;
|
|
156157
|
+
let ownerMsgId;
|
|
156158
|
+
if (obs.kind === "invocation") {
|
|
156159
|
+
ownerMsgId = message.id;
|
|
156160
|
+
const queue = unpairedInvocations.get(obs.callId) ?? [];
|
|
156161
|
+
queue.push(message.id);
|
|
156162
|
+
unpairedInvocations.set(obs.callId, queue);
|
|
156163
|
+
} else {
|
|
156164
|
+
const queue = unpairedInvocations.get(obs.callId);
|
|
156165
|
+
if (queue && queue.length > 0) {
|
|
156166
|
+
const popped = queue.shift();
|
|
156167
|
+
if (queue.length === 0)
|
|
156168
|
+
unpairedInvocations.delete(obs.callId);
|
|
156169
|
+
ownerMsgId = popped ?? message.id;
|
|
156170
|
+
} else {
|
|
156171
|
+
ownerMsgId = message.id;
|
|
156172
|
+
}
|
|
156495
156173
|
}
|
|
156174
|
+
const owners = toolObservations.get(obs.callId) ?? new Set;
|
|
156175
|
+
owners.add(ownerMsgId);
|
|
156176
|
+
toolObservations.set(obs.callId, owners);
|
|
156496
156177
|
}
|
|
156497
156178
|
}
|
|
156498
|
-
return
|
|
156179
|
+
return { messageFileKeys, toolObservations };
|
|
156499
156180
|
}
|
|
156500
156181
|
var PROTECTED_TAIL_USER_TURNS = 5;
|
|
156501
156182
|
function getProtectedTailStartOrdinal(sessionId) {
|
|
@@ -156644,6 +156325,79 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
156644
156325
|
};
|
|
156645
156326
|
}
|
|
156646
156327
|
|
|
156328
|
+
// ../plugin/src/shared/harness.ts
|
|
156329
|
+
var currentHarness = "opencode";
|
|
156330
|
+
var harnessLocked = false;
|
|
156331
|
+
function setHarness(value) {
|
|
156332
|
+
if (harnessLocked && currentHarness !== value) {
|
|
156333
|
+
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
156334
|
+
}
|
|
156335
|
+
currentHarness = value;
|
|
156336
|
+
harnessLocked = true;
|
|
156337
|
+
}
|
|
156338
|
+
function getHarness() {
|
|
156339
|
+
return currentHarness;
|
|
156340
|
+
}
|
|
156341
|
+
|
|
156342
|
+
// ../plugin/src/features/magic-context/compression-depth-storage.ts
|
|
156343
|
+
var incrementDepthStatements = new WeakMap;
|
|
156344
|
+
var totalDepthStatements = new WeakMap;
|
|
156345
|
+
var maxDepthStatements = new WeakMap;
|
|
156346
|
+
var clearDepthStatements = new WeakMap;
|
|
156347
|
+
function getIncrementDepthStatement(db) {
|
|
156348
|
+
let stmt = incrementDepthStatements.get(db);
|
|
156349
|
+
if (!stmt) {
|
|
156350
|
+
stmt = db.prepare("INSERT INTO compression_depth (session_id, message_ordinal, depth, harness) VALUES (?, ?, 1, ?) ON CONFLICT(session_id, message_ordinal) DO UPDATE SET depth = depth + 1");
|
|
156351
|
+
incrementDepthStatements.set(db, stmt);
|
|
156352
|
+
}
|
|
156353
|
+
return stmt;
|
|
156354
|
+
}
|
|
156355
|
+
function getTotalDepthStatement(db) {
|
|
156356
|
+
let stmt = totalDepthStatements.get(db);
|
|
156357
|
+
if (!stmt) {
|
|
156358
|
+
stmt = db.prepare("SELECT COALESCE(SUM(depth), 0) AS total_depth FROM compression_depth WHERE session_id = ? AND message_ordinal BETWEEN ? AND ?");
|
|
156359
|
+
totalDepthStatements.set(db, stmt);
|
|
156360
|
+
}
|
|
156361
|
+
return stmt;
|
|
156362
|
+
}
|
|
156363
|
+
function getClearDepthStatement(db) {
|
|
156364
|
+
let stmt = clearDepthStatements.get(db);
|
|
156365
|
+
if (!stmt) {
|
|
156366
|
+
stmt = db.prepare("DELETE FROM compression_depth WHERE session_id = ?");
|
|
156367
|
+
clearDepthStatements.set(db, stmt);
|
|
156368
|
+
}
|
|
156369
|
+
return stmt;
|
|
156370
|
+
}
|
|
156371
|
+
function incrementCompressionDepth(db, sessionId, startOrdinal, endOrdinal) {
|
|
156372
|
+
if (endOrdinal < startOrdinal) {
|
|
156373
|
+
return;
|
|
156374
|
+
}
|
|
156375
|
+
db.transaction(() => {
|
|
156376
|
+
const stmt = getIncrementDepthStatement(db);
|
|
156377
|
+
for (let ordinal = startOrdinal;ordinal <= endOrdinal; ordinal += 1) {
|
|
156378
|
+
stmt.run(sessionId, ordinal, getHarness());
|
|
156379
|
+
}
|
|
156380
|
+
})();
|
|
156381
|
+
}
|
|
156382
|
+
function getAverageCompressionDepth(db, sessionId, startOrdinal, endOrdinal) {
|
|
156383
|
+
if (endOrdinal < startOrdinal) {
|
|
156384
|
+
return 0;
|
|
156385
|
+
}
|
|
156386
|
+
const row = getTotalDepthStatement(db).get(sessionId, startOrdinal, endOrdinal);
|
|
156387
|
+
const totalDepth = typeof row?.total_depth === "number" ? row.total_depth : 0;
|
|
156388
|
+
const messageCount = endOrdinal - startOrdinal + 1;
|
|
156389
|
+
return totalDepth / messageCount;
|
|
156390
|
+
}
|
|
156391
|
+
function clearCompressionDepth(db, sessionId) {
|
|
156392
|
+
getClearDepthStatement(db).run(sessionId);
|
|
156393
|
+
}
|
|
156394
|
+
function clearCompressionDepthRange(db, sessionId, startOrdinal, endOrdinal) {
|
|
156395
|
+
if (endOrdinal < startOrdinal) {
|
|
156396
|
+
return;
|
|
156397
|
+
}
|
|
156398
|
+
db.prepare("DELETE FROM compression_depth WHERE session_id = ? AND message_ordinal BETWEEN ? AND ?").run(sessionId, startOrdinal, endOrdinal);
|
|
156399
|
+
}
|
|
156400
|
+
|
|
156647
156401
|
// ../plugin/src/features/magic-context/message-index.ts
|
|
156648
156402
|
var lastIndexedStatements = new WeakMap;
|
|
156649
156403
|
var insertMessageStatements = new WeakMap;
|
|
@@ -156651,6 +156405,7 @@ var upsertIndexStatements = new WeakMap;
|
|
|
156651
156405
|
var deleteFtsStatements = new WeakMap;
|
|
156652
156406
|
var deleteIndexStatements = new WeakMap;
|
|
156653
156407
|
var countIndexedMessageStatements = new WeakMap;
|
|
156408
|
+
var indexedMessageIdStatements = new WeakMap;
|
|
156654
156409
|
function normalizeIndexText(text) {
|
|
156655
156410
|
return text.replace(/\s+/g, " ").trim();
|
|
156656
156411
|
}
|
|
@@ -156694,10 +156449,34 @@ function getDeleteIndexStatement(db) {
|
|
|
156694
156449
|
}
|
|
156695
156450
|
return stmt;
|
|
156696
156451
|
}
|
|
156452
|
+
function getCountIndexedMessageStatement(db) {
|
|
156453
|
+
let stmt = countIndexedMessageStatements.get(db);
|
|
156454
|
+
if (!stmt) {
|
|
156455
|
+
stmt = db.prepare("SELECT COUNT(*) AS count FROM message_history_fts WHERE session_id = ? AND message_id = ?");
|
|
156456
|
+
countIndexedMessageStatements.set(db, stmt);
|
|
156457
|
+
}
|
|
156458
|
+
return stmt;
|
|
156459
|
+
}
|
|
156460
|
+
function getIndexedMessageIdStatement(db) {
|
|
156461
|
+
let stmt = indexedMessageIdStatements.get(db);
|
|
156462
|
+
if (!stmt) {
|
|
156463
|
+
stmt = db.prepare("SELECT message_id AS messageId FROM message_history_fts WHERE session_id = ?");
|
|
156464
|
+
indexedMessageIdStatements.set(db, stmt);
|
|
156465
|
+
}
|
|
156466
|
+
return stmt;
|
|
156467
|
+
}
|
|
156697
156468
|
function getLastIndexedOrdinal(db, sessionId) {
|
|
156698
156469
|
const row = getLastIndexedStatement(db).get(sessionId);
|
|
156699
156470
|
return typeof row?.last_indexed_ordinal === "number" ? row.last_indexed_ordinal : 0;
|
|
156700
156471
|
}
|
|
156472
|
+
function isMessageAlreadyIndexed(db, sessionId, messageId) {
|
|
156473
|
+
const row = getCountIndexedMessageStatement(db).get(sessionId, messageId);
|
|
156474
|
+
return (typeof row?.count === "number" ? row.count : 0) > 0;
|
|
156475
|
+
}
|
|
156476
|
+
function advanceIndexWatermark(db, sessionId, ordinal, now) {
|
|
156477
|
+
const current = getLastIndexedOrdinal(db, sessionId);
|
|
156478
|
+
getUpsertIndexStatement(db).run(sessionId, Math.max(current, ordinal), now, getHarness());
|
|
156479
|
+
}
|
|
156701
156480
|
function clearIndexedMessages(db, sessionId) {
|
|
156702
156481
|
db.transaction(() => {
|
|
156703
156482
|
getDeleteFtsStatement(db).run(sessionId);
|
|
@@ -156717,39 +156496,510 @@ function getIndexableContent(role, parts) {
|
|
|
156717
156496
|
}
|
|
156718
156497
|
return "";
|
|
156719
156498
|
}
|
|
156720
|
-
function
|
|
156721
|
-
|
|
156722
|
-
|
|
156723
|
-
|
|
156499
|
+
function indexSingleMessageInTransaction(db, sessionId, message, now) {
|
|
156500
|
+
if (message.role !== "user" && message.role !== "assistant") {
|
|
156501
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
156502
|
+
return false;
|
|
156503
|
+
}
|
|
156504
|
+
const content = getIndexableContent(message.role, message.parts);
|
|
156505
|
+
if (content.length === 0) {
|
|
156506
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
156507
|
+
return false;
|
|
156508
|
+
}
|
|
156509
|
+
if (isMessageAlreadyIndexed(db, sessionId, message.id)) {
|
|
156510
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
156511
|
+
return false;
|
|
156512
|
+
}
|
|
156513
|
+
getInsertMessageStatement(db).run(sessionId, message.ordinal, message.id, message.role, content);
|
|
156514
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
156515
|
+
return true;
|
|
156516
|
+
}
|
|
156517
|
+
function indexSingleMessage(db, sessionId, message) {
|
|
156518
|
+
return db.transaction(() => indexSingleMessageInTransaction(db, sessionId, message, Date.now()))();
|
|
156519
|
+
}
|
|
156520
|
+
function indexMessagesAfterOrdinal(db, sessionId, messages, lastIndexedOrdinal, finalWatermark = messages.length) {
|
|
156521
|
+
const now = Date.now();
|
|
156522
|
+
let inserted = 0;
|
|
156523
|
+
db.transaction(() => {
|
|
156524
|
+
const existingMessageIds = new Set(getIndexedMessageIdStatement(db).all(sessionId).map((row) => row.messageId).filter((messageId) => typeof messageId === "string"));
|
|
156525
|
+
const insertMessage = getInsertMessageStatement(db);
|
|
156526
|
+
for (const message of messages) {
|
|
156527
|
+
if (message.ordinal <= lastIndexedOrdinal) {
|
|
156528
|
+
continue;
|
|
156529
|
+
}
|
|
156530
|
+
if (message.role !== "user" && message.role !== "assistant") {
|
|
156531
|
+
continue;
|
|
156532
|
+
}
|
|
156533
|
+
const content = getIndexableContent(message.role, message.parts);
|
|
156534
|
+
if (content.length === 0 || existingMessageIds.has(message.id)) {
|
|
156535
|
+
continue;
|
|
156536
|
+
}
|
|
156537
|
+
insertMessage.run(sessionId, message.ordinal, message.id, message.role, content);
|
|
156538
|
+
existingMessageIds.add(message.id);
|
|
156539
|
+
inserted++;
|
|
156540
|
+
}
|
|
156541
|
+
getUpsertIndexStatement(db).run(sessionId, finalWatermark, now, getHarness());
|
|
156542
|
+
})();
|
|
156543
|
+
return inserted;
|
|
156544
|
+
}
|
|
156545
|
+
|
|
156546
|
+
// ../plugin/src/features/magic-context/message-index-async.ts
|
|
156547
|
+
var INCREMENTAL_DEBOUNCE_MS = 100;
|
|
156548
|
+
var reconciledSessions = new Set;
|
|
156549
|
+
var reconciliationScheduledSessions = new Set;
|
|
156550
|
+
var sessionLocks = new Map;
|
|
156551
|
+
var incrementalTimers = new Map;
|
|
156552
|
+
var pendingIncrementalKeys = new Set;
|
|
156553
|
+
function defer(fn) {
|
|
156554
|
+
const immediate = globalThis.setImmediate;
|
|
156555
|
+
if (typeof immediate === "function") {
|
|
156556
|
+
immediate(fn);
|
|
156724
156557
|
return;
|
|
156725
156558
|
}
|
|
156726
|
-
|
|
156727
|
-
|
|
156728
|
-
|
|
156729
|
-
|
|
156559
|
+
setTimeout(fn, 0);
|
|
156560
|
+
}
|
|
156561
|
+
function runWithSessionLock(sessionId, operation) {
|
|
156562
|
+
const previous = sessionLocks.get(sessionId) ?? Promise.resolve();
|
|
156563
|
+
const run = previous.catch(() => {
|
|
156564
|
+
return;
|
|
156565
|
+
}).then(async () => {
|
|
156566
|
+
await operation();
|
|
156567
|
+
});
|
|
156568
|
+
sessionLocks.set(sessionId, run);
|
|
156569
|
+
run.finally(() => {
|
|
156570
|
+
if (sessionLocks.get(sessionId) === run) {
|
|
156571
|
+
sessionLocks.delete(sessionId);
|
|
156572
|
+
}
|
|
156573
|
+
}).catch(() => {
|
|
156574
|
+
return;
|
|
156575
|
+
});
|
|
156576
|
+
return run;
|
|
156577
|
+
}
|
|
156578
|
+
function logIndexingError(sessionId, action, error48) {
|
|
156579
|
+
sessionLog(sessionId, `message FTS async ${action} failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
156580
|
+
log(`[message-index-async] ${action} failed for ${sessionId}:`, error48);
|
|
156581
|
+
}
|
|
156582
|
+
async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
156583
|
+
await runWithSessionLock(sessionId, () => {
|
|
156584
|
+
if (reconciledSessions.has(sessionId)) {
|
|
156585
|
+
return;
|
|
156586
|
+
}
|
|
156587
|
+
const messages = readMessages(sessionId);
|
|
156588
|
+
if (messages.length === 0) {
|
|
156589
|
+
clearIndexedMessages(db, sessionId);
|
|
156590
|
+
reconciledSessions.add(sessionId);
|
|
156591
|
+
return;
|
|
156592
|
+
}
|
|
156593
|
+
let lastIndexedOrdinal = getLastIndexedOrdinal(db, sessionId);
|
|
156594
|
+
if (lastIndexedOrdinal > messages.length) {
|
|
156595
|
+
clearIndexedMessages(db, sessionId);
|
|
156596
|
+
lastIndexedOrdinal = 0;
|
|
156597
|
+
}
|
|
156598
|
+
const watermark = Math.min(lastIndexedOrdinal, messages.length);
|
|
156599
|
+
indexMessagesAfterOrdinal(db, sessionId, messages, watermark, messages.length);
|
|
156600
|
+
reconciledSessions.add(sessionId);
|
|
156601
|
+
});
|
|
156602
|
+
}
|
|
156603
|
+
function scheduleReconciliation(db, sessionId, readMessages) {
|
|
156604
|
+
if (reconciledSessions.has(sessionId) || reconciliationScheduledSessions.has(sessionId)) {
|
|
156605
|
+
return;
|
|
156730
156606
|
}
|
|
156731
|
-
|
|
156607
|
+
reconciliationScheduledSessions.add(sessionId);
|
|
156608
|
+
defer(() => {
|
|
156609
|
+
reconcileSessionIndex(db, sessionId, readMessages).catch((error48) => {
|
|
156610
|
+
reconciliationScheduledSessions.delete(sessionId);
|
|
156611
|
+
logIndexingError(sessionId, "reconciliation", error48);
|
|
156612
|
+
});
|
|
156613
|
+
});
|
|
156614
|
+
}
|
|
156615
|
+
function scheduleIncrementalIndex(db, sessionId, messageId, readSingleMessage) {
|
|
156616
|
+
const key = `${sessionId}\x00${messageId}`;
|
|
156617
|
+
if (incrementalTimers.has(key) || pendingIncrementalKeys.has(key)) {
|
|
156732
156618
|
return;
|
|
156733
156619
|
}
|
|
156734
|
-
const
|
|
156735
|
-
|
|
156736
|
-
|
|
156737
|
-
|
|
156738
|
-
|
|
156739
|
-
|
|
156620
|
+
const timer = setTimeout(() => {
|
|
156621
|
+
incrementalTimers.delete(key);
|
|
156622
|
+
pendingIncrementalKeys.add(key);
|
|
156623
|
+
runWithSessionLock(sessionId, () => {
|
|
156624
|
+
const message = readSingleMessage(sessionId, messageId);
|
|
156625
|
+
if (!message) {
|
|
156626
|
+
return;
|
|
156627
|
+
}
|
|
156628
|
+
indexSingleMessage(db, sessionId, message);
|
|
156629
|
+
}).catch((error48) => {
|
|
156630
|
+
logIndexingError(sessionId, `incremental index for ${messageId}`, error48);
|
|
156631
|
+
}).finally(() => {
|
|
156632
|
+
pendingIncrementalKeys.delete(key);
|
|
156633
|
+
});
|
|
156634
|
+
}, INCREMENTAL_DEBOUNCE_MS);
|
|
156635
|
+
incrementalTimers.set(key, timer);
|
|
156636
|
+
}
|
|
156637
|
+
function clearSessionTracking(sessionId) {
|
|
156638
|
+
reconciledSessions.delete(sessionId);
|
|
156639
|
+
reconciliationScheduledSessions.delete(sessionId);
|
|
156640
|
+
sessionLocks.delete(sessionId);
|
|
156641
|
+
const prefix = `${sessionId}\x00`;
|
|
156642
|
+
for (const [key, timer] of incrementalTimers) {
|
|
156643
|
+
if (key.startsWith(prefix)) {
|
|
156644
|
+
clearTimeout(timer);
|
|
156645
|
+
incrementalTimers.delete(key);
|
|
156646
|
+
}
|
|
156647
|
+
}
|
|
156648
|
+
for (const key of pendingIncrementalKeys) {
|
|
156649
|
+
if (key.startsWith(prefix)) {
|
|
156650
|
+
pendingIncrementalKeys.delete(key);
|
|
156651
|
+
}
|
|
156652
|
+
}
|
|
156653
|
+
}
|
|
156654
|
+
|
|
156655
|
+
// ../plugin/src/features/magic-context/overflow-detection.ts
|
|
156656
|
+
var OVERFLOW_PATTERNS = [
|
|
156657
|
+
/prompt is too long/i,
|
|
156658
|
+
/input is too long for requested model/i,
|
|
156659
|
+
/exceeds the context window/i,
|
|
156660
|
+
/input token count.*exceeds the maximum/i,
|
|
156661
|
+
/maximum prompt length is \d+/i,
|
|
156662
|
+
/reduce the length of the messages/i,
|
|
156663
|
+
/maximum context length is \d+ tokens/i,
|
|
156664
|
+
/exceeds the limit of \d+/i,
|
|
156665
|
+
/exceeds the available context size/i,
|
|
156666
|
+
/greater than the context length/i,
|
|
156667
|
+
/context window exceeds limit/i,
|
|
156668
|
+
/exceeded model token limit/i,
|
|
156669
|
+
/context[_ ]length[_ ]exceeded/i,
|
|
156670
|
+
/request entity too large/i,
|
|
156671
|
+
/context length is only \d+ tokens/i,
|
|
156672
|
+
/input length.*exceeds.*context length/i,
|
|
156673
|
+
/prompt too long; exceeded (?:max )?context length/i,
|
|
156674
|
+
/too large for model with \d+ maximum context length/i,
|
|
156675
|
+
/model_context_window_exceeded/i,
|
|
156676
|
+
/context size has been exceeded/i
|
|
156677
|
+
];
|
|
156678
|
+
var LIMIT_EXTRACTION_PATTERNS = [
|
|
156679
|
+
/maximum prompt length is (\d+)/i,
|
|
156680
|
+
/maximum context length is (\d+) tokens?/i,
|
|
156681
|
+
/context length is only (\d+) tokens?/i,
|
|
156682
|
+
/exceeds the limit of (\d+)/i,
|
|
156683
|
+
/too large for model with (\d+) maximum context length/i,
|
|
156684
|
+
/context size.*(\d+) tokens?/i,
|
|
156685
|
+
/exceeds? the context length of (\d+)/i,
|
|
156686
|
+
/max(?:imum)?.*context.*?(\d+)/i
|
|
156687
|
+
];
|
|
156688
|
+
var MIN_PLAUSIBLE_LIMIT = 1024;
|
|
156689
|
+
var MAX_PLAUSIBLE_LIMIT = 1e7;
|
|
156690
|
+
function extractErrorMessage(error48) {
|
|
156691
|
+
if (!error48)
|
|
156692
|
+
return "";
|
|
156693
|
+
if (typeof error48 === "string")
|
|
156694
|
+
return error48;
|
|
156695
|
+
if (typeof error48 === "object") {
|
|
156696
|
+
const obj = error48;
|
|
156697
|
+
const nested = obj.error;
|
|
156698
|
+
if (nested && typeof nested.message === "string" && nested.message.length > 0) {
|
|
156699
|
+
return nested.message;
|
|
156700
|
+
}
|
|
156701
|
+
}
|
|
156702
|
+
if (error48 instanceof Error)
|
|
156703
|
+
return error48.message;
|
|
156704
|
+
if (typeof error48 === "object") {
|
|
156705
|
+
const obj = error48;
|
|
156706
|
+
if (typeof obj.message === "string")
|
|
156707
|
+
return obj.message;
|
|
156708
|
+
if (typeof obj.responseBody === "string")
|
|
156709
|
+
return obj.responseBody;
|
|
156710
|
+
try {
|
|
156711
|
+
return JSON.stringify(error48);
|
|
156712
|
+
} catch {
|
|
156713
|
+
return String(error48);
|
|
156714
|
+
}
|
|
156715
|
+
}
|
|
156716
|
+
return String(error48);
|
|
156717
|
+
}
|
|
156718
|
+
function detectOverflow(error48) {
|
|
156719
|
+
const message = extractErrorMessage(error48);
|
|
156720
|
+
if (!message) {
|
|
156721
|
+
return { isOverflow: false };
|
|
156722
|
+
}
|
|
156723
|
+
const hasStatus413 = /\b413\b/.test(message) && /(entity|payload|context|prompt)/i.test(message);
|
|
156724
|
+
let matched;
|
|
156725
|
+
for (const pattern of OVERFLOW_PATTERNS) {
|
|
156726
|
+
if (pattern.test(message)) {
|
|
156727
|
+
matched = pattern;
|
|
156728
|
+
break;
|
|
156729
|
+
}
|
|
156730
|
+
}
|
|
156731
|
+
if (!matched && !hasStatus413) {
|
|
156732
|
+
return { isOverflow: false };
|
|
156733
|
+
}
|
|
156734
|
+
const reportedLimit = parseReportedLimit(message);
|
|
156735
|
+
return {
|
|
156736
|
+
isOverflow: true,
|
|
156737
|
+
reportedLimit,
|
|
156738
|
+
matchedPattern: matched?.source
|
|
156739
|
+
};
|
|
156740
|
+
}
|
|
156741
|
+
function parseReportedLimit(message) {
|
|
156742
|
+
if (!message)
|
|
156743
|
+
return;
|
|
156744
|
+
for (const pattern of LIMIT_EXTRACTION_PATTERNS) {
|
|
156745
|
+
const match = message.match(pattern);
|
|
156746
|
+
if (!match)
|
|
156747
|
+
continue;
|
|
156748
|
+
const raw = match[1];
|
|
156749
|
+
if (!raw)
|
|
156750
|
+
continue;
|
|
156751
|
+
const value = Number.parseInt(raw, 10);
|
|
156752
|
+
if (!Number.isFinite(value))
|
|
156753
|
+
continue;
|
|
156754
|
+
if (value < MIN_PLAUSIBLE_LIMIT || value > MAX_PLAUSIBLE_LIMIT)
|
|
156755
|
+
continue;
|
|
156756
|
+
return value;
|
|
156757
|
+
}
|
|
156758
|
+
return;
|
|
156759
|
+
}
|
|
156760
|
+
|
|
156761
|
+
// ../plugin/src/features/magic-context/compartment-storage.ts
|
|
156762
|
+
var insertCompartmentStatements = new WeakMap;
|
|
156763
|
+
var insertFactStatements = new WeakMap;
|
|
156764
|
+
function getInsertCompartmentStatement(db) {
|
|
156765
|
+
let stmt = insertCompartmentStatements.get(db);
|
|
156766
|
+
if (!stmt) {
|
|
156767
|
+
stmt = db.prepare("INSERT INTO compartments (session_id, sequence, start_message, end_message, start_message_id, end_message_id, title, content, created_at, harness) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
156768
|
+
insertCompartmentStatements.set(db, stmt);
|
|
156769
|
+
}
|
|
156770
|
+
return stmt;
|
|
156771
|
+
}
|
|
156772
|
+
function getInsertFactStatement(db) {
|
|
156773
|
+
let stmt = insertFactStatements.get(db);
|
|
156774
|
+
if (!stmt) {
|
|
156775
|
+
stmt = db.prepare("INSERT INTO session_facts (session_id, category, content, created_at, updated_at, harness) VALUES (?, ?, ?, ?, ?, ?)");
|
|
156776
|
+
insertFactStatements.set(db, stmt);
|
|
156777
|
+
}
|
|
156778
|
+
return stmt;
|
|
156779
|
+
}
|
|
156780
|
+
function isCompartmentRow(row) {
|
|
156781
|
+
if (row === null || typeof row !== "object")
|
|
156782
|
+
return false;
|
|
156783
|
+
const candidate = row;
|
|
156784
|
+
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" && typeof candidate.created_at === "number";
|
|
156785
|
+
}
|
|
156786
|
+
function isSessionFactRow(row) {
|
|
156787
|
+
if (row === null || typeof row !== "object")
|
|
156788
|
+
return false;
|
|
156789
|
+
const candidate = row;
|
|
156790
|
+
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";
|
|
156791
|
+
}
|
|
156792
|
+
function insertCompartmentRows(db, sessionId, compartments, now) {
|
|
156793
|
+
const stmt = getInsertCompartmentStatement(db);
|
|
156794
|
+
for (const compartment of compartments) {
|
|
156795
|
+
stmt.run(sessionId, compartment.sequence, compartment.startMessage, compartment.endMessage, compartment.startMessageId, compartment.endMessageId, compartment.title, compartment.content, now, getHarness());
|
|
156796
|
+
}
|
|
156797
|
+
}
|
|
156798
|
+
function insertFactRows(db, sessionId, facts, now) {
|
|
156799
|
+
const stmt = getInsertFactStatement(db);
|
|
156800
|
+
for (const fact of facts) {
|
|
156801
|
+
stmt.run(sessionId, fact.category, fact.content, now, now, getHarness());
|
|
156802
|
+
}
|
|
156803
|
+
}
|
|
156804
|
+
function toCompartment(row) {
|
|
156805
|
+
return {
|
|
156806
|
+
id: row.id,
|
|
156807
|
+
sessionId: row.session_id,
|
|
156808
|
+
sequence: row.sequence,
|
|
156809
|
+
startMessage: row.start_message,
|
|
156810
|
+
endMessage: row.end_message,
|
|
156811
|
+
startMessageId: row.start_message_id,
|
|
156812
|
+
endMessageId: row.end_message_id,
|
|
156813
|
+
title: row.title,
|
|
156814
|
+
content: row.content,
|
|
156815
|
+
createdAt: row.created_at
|
|
156816
|
+
};
|
|
156817
|
+
}
|
|
156818
|
+
function toSessionFact(row) {
|
|
156819
|
+
return {
|
|
156820
|
+
id: row.id,
|
|
156821
|
+
sessionId: row.session_id,
|
|
156822
|
+
category: row.category,
|
|
156823
|
+
content: row.content,
|
|
156824
|
+
createdAt: row.created_at,
|
|
156825
|
+
updatedAt: row.updated_at
|
|
156826
|
+
};
|
|
156827
|
+
}
|
|
156828
|
+
function getCompartments(db, sessionId) {
|
|
156829
|
+
const rows = db.prepare("SELECT * FROM compartments WHERE session_id = ? ORDER BY sequence ASC").all(sessionId).filter(isCompartmentRow);
|
|
156830
|
+
return rows.map(toCompartment);
|
|
156831
|
+
}
|
|
156832
|
+
function getLastCompartmentEndMessage(db, sessionId) {
|
|
156833
|
+
const row = db.prepare("SELECT MAX(end_message) as max_end FROM compartments WHERE session_id = ?").get(sessionId);
|
|
156834
|
+
return row?.max_end ?? -1;
|
|
156835
|
+
}
|
|
156836
|
+
function appendCompartments(db, sessionId, compartments) {
|
|
156837
|
+
if (compartments.length === 0)
|
|
156838
|
+
return;
|
|
156740
156839
|
const now = Date.now();
|
|
156741
156840
|
db.transaction(() => {
|
|
156742
|
-
|
|
156743
|
-
|
|
156744
|
-
|
|
156841
|
+
insertCompartmentRows(db, sessionId, compartments, now);
|
|
156842
|
+
})();
|
|
156843
|
+
}
|
|
156844
|
+
function replaceSessionFacts(db, sessionId, facts) {
|
|
156845
|
+
const now = Date.now();
|
|
156846
|
+
db.transaction(() => {
|
|
156847
|
+
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
156848
|
+
insertFactRows(db, sessionId, facts, now);
|
|
156849
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
156850
|
+
})();
|
|
156851
|
+
}
|
|
156852
|
+
function getSessionFacts(db, sessionId) {
|
|
156853
|
+
const rows = db.prepare("SELECT * FROM session_facts WHERE session_id = ? ORDER BY category ASC, id ASC").all(sessionId).filter(isSessionFactRow);
|
|
156854
|
+
return rows.map(toSessionFact);
|
|
156855
|
+
}
|
|
156856
|
+
function replaceAllCompartmentState(db, sessionId, compartments, facts) {
|
|
156857
|
+
const now = Date.now();
|
|
156858
|
+
db.transaction(() => {
|
|
156859
|
+
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
156860
|
+
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
156861
|
+
insertCompartmentRows(db, sessionId, compartments, now);
|
|
156862
|
+
insertFactRows(db, sessionId, facts, now);
|
|
156863
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
156864
|
+
})();
|
|
156865
|
+
}
|
|
156866
|
+
function buildCompartmentBlock(compartments, facts, memoryBlock, dateRanges) {
|
|
156867
|
+
const lines = [];
|
|
156868
|
+
if (memoryBlock) {
|
|
156869
|
+
lines.push(memoryBlock);
|
|
156870
|
+
lines.push("");
|
|
156871
|
+
}
|
|
156872
|
+
for (const c of compartments) {
|
|
156873
|
+
const dates = dateRanges?.byId.get(c.id);
|
|
156874
|
+
const dateAttr = dates ? ` start-date="${dates.start}" end-date="${dates.end}"` : "";
|
|
156875
|
+
lines.push(`<compartment start="${c.startMessage}" end="${c.endMessage}"${dateAttr} title="${escapeXmlAttr(c.title)}">`);
|
|
156876
|
+
lines.push(escapeXmlContent(c.content));
|
|
156877
|
+
lines.push("</compartment>");
|
|
156878
|
+
lines.push("");
|
|
156879
|
+
}
|
|
156880
|
+
const factsByCategory = new Map;
|
|
156881
|
+
for (const f of facts) {
|
|
156882
|
+
const existing = factsByCategory.get(f.category) ?? [];
|
|
156883
|
+
existing.push(f.content);
|
|
156884
|
+
factsByCategory.set(f.category, existing);
|
|
156885
|
+
}
|
|
156886
|
+
for (const [category, items] of factsByCategory) {
|
|
156887
|
+
lines.push(`${category}:`);
|
|
156888
|
+
for (const item of items) {
|
|
156889
|
+
lines.push(`* ${escapeXmlContent(item)}`);
|
|
156890
|
+
}
|
|
156891
|
+
lines.push("");
|
|
156892
|
+
}
|
|
156893
|
+
return lines.join(`
|
|
156894
|
+
`).trimEnd();
|
|
156895
|
+
}
|
|
156896
|
+
function saveRecompStagingPass(db, sessionId, passNumber, compartments, facts) {
|
|
156897
|
+
const now = Date.now();
|
|
156898
|
+
db.transaction(() => {
|
|
156899
|
+
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
156900
|
+
const compartmentStmt = db.prepare("INSERT OR REPLACE INTO recomp_compartments (session_id, sequence, start_message, end_message, start_message_id, end_message_id, title, content, pass_number, created_at, harness) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
156901
|
+
for (const c of compartments) {
|
|
156902
|
+
compartmentStmt.run(sessionId, c.sequence, c.startMessage, c.endMessage, c.startMessageId, c.endMessageId, c.title, c.content, passNumber, now, getHarness());
|
|
156903
|
+
}
|
|
156904
|
+
const factStmt = db.prepare("INSERT INTO recomp_facts (session_id, category, content, pass_number, created_at, harness) VALUES (?, ?, ?, ?, ?, ?)");
|
|
156905
|
+
for (const f of facts) {
|
|
156906
|
+
factStmt.run(sessionId, f.category, f.content, passNumber, now, getHarness());
|
|
156745
156907
|
}
|
|
156746
|
-
getUpsertIndexStatement(db).run(sessionId, messages.length, now, getHarness());
|
|
156747
156908
|
})();
|
|
156748
156909
|
}
|
|
156910
|
+
function getRecompStaging(db, sessionId) {
|
|
156911
|
+
const compartmentRows = db.prepare("SELECT * FROM recomp_compartments WHERE session_id = ? ORDER BY sequence ASC").all(sessionId).filter(isRecompCompartmentRow);
|
|
156912
|
+
if (compartmentRows.length === 0)
|
|
156913
|
+
return null;
|
|
156914
|
+
const compartments = compartmentRows.map((row) => ({
|
|
156915
|
+
sequence: row.sequence,
|
|
156916
|
+
startMessage: row.start_message,
|
|
156917
|
+
endMessage: row.end_message,
|
|
156918
|
+
startMessageId: row.start_message_id,
|
|
156919
|
+
endMessageId: row.end_message_id,
|
|
156920
|
+
title: row.title,
|
|
156921
|
+
content: row.content
|
|
156922
|
+
}));
|
|
156923
|
+
const factRows = db.prepare("SELECT category, content FROM recomp_facts WHERE session_id = ?").all(sessionId).filter(isRecompFactRow);
|
|
156924
|
+
const maxPass = compartmentRows.reduce((m, r) => Math.max(m, r.pass_number), 0);
|
|
156925
|
+
const lastEnd = compartmentRows[compartmentRows.length - 1]?.end_message ?? 0;
|
|
156926
|
+
return {
|
|
156927
|
+
compartments,
|
|
156928
|
+
facts: factRows,
|
|
156929
|
+
passCount: maxPass,
|
|
156930
|
+
lastEndMessage: lastEnd
|
|
156931
|
+
};
|
|
156932
|
+
}
|
|
156933
|
+
function promoteRecompStaging(db, sessionId) {
|
|
156934
|
+
const now = Date.now();
|
|
156935
|
+
return db.transaction(() => {
|
|
156936
|
+
const staging = getRecompStaging(db, sessionId);
|
|
156937
|
+
if (!staging || staging.compartments.length === 0)
|
|
156938
|
+
return null;
|
|
156939
|
+
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
156940
|
+
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
156941
|
+
insertCompartmentRows(db, sessionId, staging.compartments, now);
|
|
156942
|
+
insertFactRows(db, sessionId, staging.facts, now);
|
|
156943
|
+
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
156944
|
+
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
156945
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '' WHERE session_id = ?").run(sessionId);
|
|
156946
|
+
return { compartments: staging.compartments, facts: staging.facts };
|
|
156947
|
+
})();
|
|
156948
|
+
}
|
|
156949
|
+
function invalidateAllMemoryBlockCaches(db) {
|
|
156950
|
+
try {
|
|
156951
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE memory_block_cache != '' OR memory_block_ids != ''").run();
|
|
156952
|
+
} catch {}
|
|
156953
|
+
}
|
|
156954
|
+
function clearRecompStaging(db, sessionId) {
|
|
156955
|
+
db.transaction(() => {
|
|
156956
|
+
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
156957
|
+
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
156958
|
+
try {
|
|
156959
|
+
db.prepare("UPDATE session_meta SET recomp_partial_range_start = 0, recomp_partial_range_end = 0 WHERE session_id = ?").run(sessionId);
|
|
156960
|
+
} catch {}
|
|
156961
|
+
})();
|
|
156962
|
+
}
|
|
156963
|
+
function getRecompPartialRange(db, sessionId) {
|
|
156964
|
+
try {
|
|
156965
|
+
const row = db.prepare("SELECT recomp_partial_range_start AS start, recomp_partial_range_end AS end FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
156966
|
+
const start = typeof row?.start === "number" ? row.start : 0;
|
|
156967
|
+
const end = typeof row?.end === "number" ? row.end : 0;
|
|
156968
|
+
if (start <= 0 || end <= 0)
|
|
156969
|
+
return null;
|
|
156970
|
+
return { start, end };
|
|
156971
|
+
} catch {
|
|
156972
|
+
return null;
|
|
156973
|
+
}
|
|
156974
|
+
}
|
|
156975
|
+
function setRecompPartialRange(db, sessionId, range) {
|
|
156976
|
+
const start = range ? range.start : 0;
|
|
156977
|
+
const end = range ? range.end : 0;
|
|
156978
|
+
db.prepare("INSERT OR IGNORE INTO session_meta (session_id) VALUES (?)").run(sessionId);
|
|
156979
|
+
db.prepare("UPDATE session_meta SET recomp_partial_range_start = ?, recomp_partial_range_end = ? WHERE session_id = ?").run(start, end, sessionId);
|
|
156980
|
+
}
|
|
156981
|
+
function isRecompCompartmentRow(row) {
|
|
156982
|
+
if (row === null || typeof row !== "object")
|
|
156983
|
+
return false;
|
|
156984
|
+
const candidate = row;
|
|
156985
|
+
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" && typeof candidate.pass_number === "number" && typeof candidate.created_at === "number";
|
|
156986
|
+
}
|
|
156987
|
+
function isRecompFactRow(row) {
|
|
156988
|
+
if (row === null || typeof row !== "object")
|
|
156989
|
+
return false;
|
|
156990
|
+
const candidate = row;
|
|
156991
|
+
return typeof candidate.category === "string" && typeof candidate.content === "string";
|
|
156992
|
+
}
|
|
156993
|
+
function escapeXmlAttr(s) {
|
|
156994
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
156995
|
+
}
|
|
156996
|
+
function escapeXmlContent(s) {
|
|
156997
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
156998
|
+
}
|
|
156749
156999
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
156750
157000
|
init_data_path();
|
|
156751
|
-
import { copyFileSync, cpSync, existsSync as
|
|
156752
|
-
import { join as
|
|
157001
|
+
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
157002
|
+
import { join as join7 } from "node:path";
|
|
156753
157003
|
|
|
156754
157004
|
// ../plugin/src/shared/error-message.ts
|
|
156755
157005
|
function getErrorMessage(error48) {
|
|
@@ -157034,6 +157284,58 @@ var MIGRATIONS = [
|
|
|
157034
157284
|
db.exec("ALTER TABLE notes ADD COLUMN harness TEXT NOT NULL DEFAULT 'opencode'");
|
|
157035
157285
|
}
|
|
157036
157286
|
}
|
|
157287
|
+
},
|
|
157288
|
+
{
|
|
157289
|
+
version: 8,
|
|
157290
|
+
description: "Add partial indexes on tags(session_id, tag_number) for active and dropped",
|
|
157291
|
+
up: (db) => {
|
|
157292
|
+
db.exec(`
|
|
157293
|
+
CREATE INDEX IF NOT EXISTS idx_tags_active_session_tag_number
|
|
157294
|
+
ON tags(session_id, tag_number)
|
|
157295
|
+
WHERE status = 'active';
|
|
157296
|
+
|
|
157297
|
+
CREATE INDEX IF NOT EXISTS idx_tags_dropped_session_tag_number
|
|
157298
|
+
ON tags(session_id, tag_number)
|
|
157299
|
+
WHERE status = 'dropped';
|
|
157300
|
+
`);
|
|
157301
|
+
db.exec("ANALYZE tags;");
|
|
157302
|
+
}
|
|
157303
|
+
},
|
|
157304
|
+
{
|
|
157305
|
+
version: 9,
|
|
157306
|
+
description: "Persist tool_definition_measurements across plugin restarts",
|
|
157307
|
+
up: (db) => {
|
|
157308
|
+
db.exec(`
|
|
157309
|
+
CREATE TABLE IF NOT EXISTS tool_definition_measurements (
|
|
157310
|
+
provider_id TEXT NOT NULL,
|
|
157311
|
+
model_id TEXT NOT NULL,
|
|
157312
|
+
agent_name TEXT NOT NULL,
|
|
157313
|
+
tool_id TEXT NOT NULL,
|
|
157314
|
+
token_count INTEGER NOT NULL,
|
|
157315
|
+
recorded_at INTEGER NOT NULL,
|
|
157316
|
+
PRIMARY KEY (provider_id, model_id, agent_name, tool_id)
|
|
157317
|
+
);
|
|
157318
|
+
`);
|
|
157319
|
+
}
|
|
157320
|
+
},
|
|
157321
|
+
{
|
|
157322
|
+
version: 10,
|
|
157323
|
+
description: "Add tool_owner_message_id column to tags + composite identity indexes",
|
|
157324
|
+
up: (db) => {
|
|
157325
|
+
const cols = db.prepare("PRAGMA table_info(tags)").all();
|
|
157326
|
+
if (!cols.some((c) => c.name === "tool_owner_message_id")) {
|
|
157327
|
+
db.exec("ALTER TABLE tags ADD COLUMN tool_owner_message_id TEXT DEFAULT NULL");
|
|
157328
|
+
}
|
|
157329
|
+
db.exec(`
|
|
157330
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_tool_composite
|
|
157331
|
+
ON tags(session_id, message_id, tool_owner_message_id)
|
|
157332
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NOT NULL;
|
|
157333
|
+
|
|
157334
|
+
CREATE INDEX IF NOT EXISTS idx_tags_tool_null_owner
|
|
157335
|
+
ON tags(session_id, message_id)
|
|
157336
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
157337
|
+
`);
|
|
157338
|
+
}
|
|
157037
157339
|
}
|
|
157038
157340
|
];
|
|
157039
157341
|
function ensureMigrationsTable(db) {
|
|
@@ -157049,22 +157351,51 @@ function getCurrentVersion(db) {
|
|
|
157049
157351
|
const row = db.prepare("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
157050
157352
|
return row?.version ?? 0;
|
|
157051
157353
|
}
|
|
157354
|
+
function isSiblingMigrationConflict(error48, version2) {
|
|
157355
|
+
if (!(error48 instanceof Error))
|
|
157356
|
+
return false;
|
|
157357
|
+
const code = error48.code;
|
|
157358
|
+
if (code !== "SQLITE_CONSTRAINT_PRIMARYKEY" && code !== "SQLITE_CONSTRAINT_UNIQUE") {
|
|
157359
|
+
return false;
|
|
157360
|
+
}
|
|
157361
|
+
const msg = error48.message;
|
|
157362
|
+
if (!msg.includes("schema_migrations"))
|
|
157363
|
+
return false;
|
|
157364
|
+
if (!msg.toLowerCase().includes("version"))
|
|
157365
|
+
return false;
|
|
157366
|
+
return true;
|
|
157367
|
+
}
|
|
157052
157368
|
function runMigrations(db) {
|
|
157053
157369
|
ensureMigrationsTable(db);
|
|
157054
|
-
|
|
157055
|
-
|
|
157370
|
+
let currentVersion = getCurrentVersion(db);
|
|
157371
|
+
let pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
|
|
157056
157372
|
if (pendingMigrations.length === 0) {
|
|
157057
157373
|
return;
|
|
157058
157374
|
}
|
|
157059
157375
|
log(`[migrations] current schema version: ${currentVersion}, applying ${pendingMigrations.length} migration(s)`);
|
|
157060
|
-
|
|
157376
|
+
let migrationIndex = 0;
|
|
157377
|
+
while (migrationIndex < pendingMigrations.length) {
|
|
157378
|
+
const migration = pendingMigrations[migrationIndex];
|
|
157061
157379
|
try {
|
|
157062
157380
|
db.transaction(() => {
|
|
157063
157381
|
migration.up(db);
|
|
157064
157382
|
db.prepare("INSERT INTO schema_migrations (version, description, applied_at) VALUES (?, ?, ?)").run(migration.version, migration.description, Date.now());
|
|
157065
157383
|
})();
|
|
157066
157384
|
log(`[migrations] applied v${migration.version}: ${migration.description}`);
|
|
157385
|
+
migrationIndex += 1;
|
|
157067
157386
|
} catch (error48) {
|
|
157387
|
+
if (isSiblingMigrationConflict(error48, migration.version)) {
|
|
157388
|
+
log(`[migrations] v${migration.version} already applied by sibling instance — resuming with re-read version`);
|
|
157389
|
+
const reReadVersion = getCurrentVersion(db);
|
|
157390
|
+
if (reReadVersion <= currentVersion) {
|
|
157391
|
+
log(`[migrations] FAILED v${migration.version}: sibling-conflict shape but version not advanced (${reReadVersion} <= ${currentVersion}) — failing closed`);
|
|
157392
|
+
throw new Error(`Migration v${migration.version} failed: sibling conflict reported but version did not advance. Database may need manual repair.`);
|
|
157393
|
+
}
|
|
157394
|
+
currentVersion = reReadVersion;
|
|
157395
|
+
pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
|
|
157396
|
+
migrationIndex = 0;
|
|
157397
|
+
continue;
|
|
157398
|
+
}
|
|
157068
157399
|
log(`[migrations] FAILED v${migration.version}: ${migration.description} — ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
157069
157400
|
throw new Error(`Migration v${migration.version} failed: ${error48 instanceof Error ? error48.message : String(error48)}. Database may need manual repair.`);
|
|
157070
157401
|
}
|
|
@@ -157072,27 +157403,300 @@ function runMigrations(db) {
|
|
|
157072
157403
|
log(`[migrations] schema version now: ${MIGRATIONS[MIGRATIONS.length - 1].version}`);
|
|
157073
157404
|
}
|
|
157074
157405
|
|
|
157406
|
+
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
157407
|
+
var measurements = new Map;
|
|
157408
|
+
var persistenceDb = null;
|
|
157409
|
+
function keyFor(providerID, modelID, agentName) {
|
|
157410
|
+
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
157411
|
+
return `${providerID}/${modelID}/${agent}`;
|
|
157412
|
+
}
|
|
157413
|
+
function setDatabase(db) {
|
|
157414
|
+
persistenceDb = db;
|
|
157415
|
+
}
|
|
157416
|
+
function loadToolDefinitionMeasurements(db) {
|
|
157417
|
+
let rows = [];
|
|
157418
|
+
try {
|
|
157419
|
+
rows = db.prepare("SELECT provider_id, model_id, agent_name, tool_id, token_count FROM tool_definition_measurements").all();
|
|
157420
|
+
} catch {
|
|
157421
|
+
return;
|
|
157422
|
+
}
|
|
157423
|
+
for (const row of rows) {
|
|
157424
|
+
const key = keyFor(row.provider_id, row.model_id, row.agent_name);
|
|
157425
|
+
let inner = measurements.get(key);
|
|
157426
|
+
if (!inner) {
|
|
157427
|
+
inner = new Map;
|
|
157428
|
+
measurements.set(key, inner);
|
|
157429
|
+
}
|
|
157430
|
+
inner.set(row.tool_id, row.token_count);
|
|
157431
|
+
}
|
|
157432
|
+
}
|
|
157433
|
+
|
|
157434
|
+
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
157435
|
+
init_data_path();
|
|
157436
|
+
init_logger();
|
|
157437
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
157438
|
+
import { join as join6 } from "node:path";
|
|
157439
|
+
var LEASE_DURATION_MS = 5 * 60 * 1000;
|
|
157440
|
+
var LEASE_RENEWAL_MS = 60 * 1000;
|
|
157441
|
+
function resolveOpencodeDbPath() {
|
|
157442
|
+
return join6(getDataDir(), "opencode", "opencode.db");
|
|
157443
|
+
}
|
|
157444
|
+
function ensureBackfillStateTable(db) {
|
|
157445
|
+
db.exec(`
|
|
157446
|
+
CREATE TABLE IF NOT EXISTS tool_owner_backfill_state (
|
|
157447
|
+
session_id TEXT PRIMARY KEY,
|
|
157448
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'completed', 'skipped')),
|
|
157449
|
+
started_at INTEGER,
|
|
157450
|
+
lease_expires_at INTEGER,
|
|
157451
|
+
completed_at INTEGER,
|
|
157452
|
+
last_error TEXT
|
|
157453
|
+
);
|
|
157454
|
+
CREATE INDEX IF NOT EXISTS idx_tool_owner_backfill_state_status
|
|
157455
|
+
ON tool_owner_backfill_state(status);
|
|
157456
|
+
`);
|
|
157457
|
+
}
|
|
157458
|
+
function runToolOwnerBackfill(db) {
|
|
157459
|
+
const startedAt = performance.now();
|
|
157460
|
+
ensureBackfillStateTable(db);
|
|
157461
|
+
const result = {
|
|
157462
|
+
sessionsProcessed: 0,
|
|
157463
|
+
sessionsSkippedNoOcDb: 0,
|
|
157464
|
+
sessionsSkippedNoMatches: 0,
|
|
157465
|
+
sessionsCompleted: 0,
|
|
157466
|
+
sessionsBlockedByLease: 0,
|
|
157467
|
+
sessionsErrored: 0,
|
|
157468
|
+
rowsUpdated: 0,
|
|
157469
|
+
rowsLeftNull: 0,
|
|
157470
|
+
durationMs: 0
|
|
157471
|
+
};
|
|
157472
|
+
if (!isToolOwnerBackfillNeeded(db)) {
|
|
157473
|
+
result.durationMs = performance.now() - startedAt;
|
|
157474
|
+
return result;
|
|
157475
|
+
}
|
|
157476
|
+
const opencodeDbPath = resolveOpencodeDbPath();
|
|
157477
|
+
if (!existsSync2(opencodeDbPath)) {
|
|
157478
|
+
log(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
|
|
157479
|
+
markAllUnbackfilledSessionsSkipped(db);
|
|
157480
|
+
result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
|
|
157481
|
+
result.durationMs = performance.now() - startedAt;
|
|
157482
|
+
return result;
|
|
157483
|
+
}
|
|
157484
|
+
db.exec(`ATTACH '${opencodeDbPath}' AS oc_backfill`);
|
|
157485
|
+
try {
|
|
157486
|
+
backfillToolOwnersInChunks(db, result);
|
|
157487
|
+
} finally {
|
|
157488
|
+
try {
|
|
157489
|
+
db.exec("DETACH DATABASE oc_backfill");
|
|
157490
|
+
} catch (error48) {
|
|
157491
|
+
log(`[backfill] failed to detach oc_backfill database: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
157492
|
+
}
|
|
157493
|
+
}
|
|
157494
|
+
result.durationMs = performance.now() - startedAt;
|
|
157495
|
+
log(`[backfill] sessions=${result.sessionsProcessed} completed=${result.sessionsCompleted} skipped_no_oc=${result.sessionsSkippedNoOcDb} skipped_no_matches=${result.sessionsSkippedNoMatches} blocked_by_lease=${result.sessionsBlockedByLease} errored=${result.sessionsErrored} rows_updated=${result.rowsUpdated} rows_left_null=${result.rowsLeftNull} duration_ms=${Math.round(result.durationMs)}`);
|
|
157496
|
+
return result;
|
|
157497
|
+
}
|
|
157498
|
+
function isToolOwnerBackfillNeeded(db) {
|
|
157499
|
+
ensureBackfillStateTable(db);
|
|
157500
|
+
const row = db.prepare(`SELECT 1 AS hit
|
|
157501
|
+
FROM tags
|
|
157502
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL
|
|
157503
|
+
AND NOT EXISTS (
|
|
157504
|
+
SELECT 1 FROM tool_owner_backfill_state s
|
|
157505
|
+
WHERE s.session_id = tags.session_id
|
|
157506
|
+
AND s.status IN ('completed', 'skipped')
|
|
157507
|
+
)
|
|
157508
|
+
LIMIT 1`).get();
|
|
157509
|
+
return row !== null && row !== undefined;
|
|
157510
|
+
}
|
|
157511
|
+
function markAllUnbackfilledSessionsSkipped(db) {
|
|
157512
|
+
const now = Date.now();
|
|
157513
|
+
db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, completed_at, last_error)
|
|
157514
|
+
SELECT DISTINCT session_id, 'skipped', NULL, ?, NULL
|
|
157515
|
+
FROM tags
|
|
157516
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL
|
|
157517
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
157518
|
+
status = 'skipped',
|
|
157519
|
+
completed_at = excluded.completed_at,
|
|
157520
|
+
last_error = NULL
|
|
157521
|
+
WHERE tool_owner_backfill_state.status NOT IN ('completed', 'running')`).run(now);
|
|
157522
|
+
}
|
|
157523
|
+
function countSessionsByStatus(db, status) {
|
|
157524
|
+
const row = db.prepare("SELECT COUNT(*) AS c FROM tool_owner_backfill_state WHERE status = ?").get(status);
|
|
157525
|
+
return row.c;
|
|
157526
|
+
}
|
|
157527
|
+
function acquireSessionLease(db, sessionId, now) {
|
|
157528
|
+
const expiresAt = now + LEASE_DURATION_MS;
|
|
157529
|
+
const result = db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, lease_expires_at)
|
|
157530
|
+
VALUES (?, 'running', ?, ?)
|
|
157531
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
157532
|
+
status = 'running',
|
|
157533
|
+
started_at = excluded.started_at,
|
|
157534
|
+
lease_expires_at = excluded.lease_expires_at,
|
|
157535
|
+
last_error = NULL
|
|
157536
|
+
WHERE tool_owner_backfill_state.status IN ('pending', 'skipped')
|
|
157537
|
+
OR (tool_owner_backfill_state.status = 'running'
|
|
157538
|
+
AND tool_owner_backfill_state.lease_expires_at < ?)`).run(sessionId, now, expiresAt, now);
|
|
157539
|
+
return (result.changes ?? 0) === 1;
|
|
157540
|
+
}
|
|
157541
|
+
function renewSessionLease(db, sessionId, now) {
|
|
157542
|
+
const expiresAt = now + LEASE_DURATION_MS;
|
|
157543
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
157544
|
+
SET lease_expires_at = ?
|
|
157545
|
+
WHERE session_id = ? AND status = 'running'`).run(expiresAt, sessionId);
|
|
157546
|
+
}
|
|
157547
|
+
function markSessionCompleted(db, sessionId, now) {
|
|
157548
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
157549
|
+
SET status = 'completed', completed_at = ?, lease_expires_at = NULL, last_error = NULL
|
|
157550
|
+
WHERE session_id = ?`).run(now, sessionId);
|
|
157551
|
+
}
|
|
157552
|
+
function markSessionSkipped(db, sessionId, now, reason) {
|
|
157553
|
+
db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, completed_at, last_error)
|
|
157554
|
+
VALUES (?, 'skipped', ?, ?)
|
|
157555
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
157556
|
+
status = 'skipped',
|
|
157557
|
+
completed_at = excluded.completed_at,
|
|
157558
|
+
last_error = excluded.last_error,
|
|
157559
|
+
lease_expires_at = NULL`).run(sessionId, now, reason);
|
|
157560
|
+
}
|
|
157561
|
+
function markSessionErrored(db, sessionId, error48) {
|
|
157562
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
157563
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
157564
|
+
SET last_error = ?, lease_expires_at = NULL
|
|
157565
|
+
WHERE session_id = ?`).run(message, sessionId);
|
|
157566
|
+
}
|
|
157567
|
+
function getSessionsNeedingBackfill(db) {
|
|
157568
|
+
const rows = db.prepare(`SELECT DISTINCT t.session_id
|
|
157569
|
+
FROM tags t
|
|
157570
|
+
LEFT JOIN tool_owner_backfill_state s ON s.session_id = t.session_id
|
|
157571
|
+
WHERE t.type = 'tool' AND t.tool_owner_message_id IS NULL
|
|
157572
|
+
AND (s.status IS NULL OR s.status NOT IN ('completed', 'skipped'))
|
|
157573
|
+
ORDER BY t.session_id ASC`).all();
|
|
157574
|
+
return rows.map((r) => r.session_id);
|
|
157575
|
+
}
|
|
157576
|
+
function buildSessionOwnerMap(db, sessionId) {
|
|
157577
|
+
const rows = db.prepare(`SELECT
|
|
157578
|
+
COALESCE(
|
|
157579
|
+
CASE WHEN json_extract(p.data, '$.type') = 'tool_use'
|
|
157580
|
+
THEN json_extract(p.data, '$.id')
|
|
157581
|
+
END,
|
|
157582
|
+
json_extract(p.data, '$.callID')
|
|
157583
|
+
) AS callid,
|
|
157584
|
+
m.id AS owner_id,
|
|
157585
|
+
m.time_created AS owner_t_created,
|
|
157586
|
+
p.id AS part_id,
|
|
157587
|
+
p.time_created AS part_t_created
|
|
157588
|
+
FROM oc_backfill.message m
|
|
157589
|
+
INNER JOIN oc_backfill.part p ON p.message_id = m.id
|
|
157590
|
+
WHERE m.session_id = ?
|
|
157591
|
+
AND json_extract(m.data, '$.role') = 'assistant'
|
|
157592
|
+
AND (
|
|
157593
|
+
(json_extract(p.data, '$.type') IN ('tool', 'tool-invocation')
|
|
157594
|
+
AND json_extract(p.data, '$.callID') IS NOT NULL)
|
|
157595
|
+
OR (json_extract(p.data, '$.type') = 'tool_use'
|
|
157596
|
+
AND json_extract(p.data, '$.id') IS NOT NULL)
|
|
157597
|
+
)
|
|
157598
|
+
ORDER BY
|
|
157599
|
+
m.time_created ASC,
|
|
157600
|
+
m.id ASC,
|
|
157601
|
+
p.time_created ASC,
|
|
157602
|
+
p.id ASC`).all(sessionId);
|
|
157603
|
+
const oldestByCallId = new Map;
|
|
157604
|
+
for (const r of rows) {
|
|
157605
|
+
if (typeof r.callid !== "string" || r.callid.length === 0)
|
|
157606
|
+
continue;
|
|
157607
|
+
if (!oldestByCallId.has(r.callid)) {
|
|
157608
|
+
oldestByCallId.set(r.callid, r.owner_id);
|
|
157609
|
+
}
|
|
157610
|
+
}
|
|
157611
|
+
return oldestByCallId;
|
|
157612
|
+
}
|
|
157613
|
+
function applyOwnersForSession(db, sessionId, ownersByCallId) {
|
|
157614
|
+
if (ownersByCallId.size === 0) {
|
|
157615
|
+
const leftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
|
|
157616
|
+
WHERE session_id = ? AND type = 'tool'
|
|
157617
|
+
AND tool_owner_message_id IS NULL`).get(sessionId).c;
|
|
157618
|
+
return { rowsUpdated: 0, rowsLeftNull: leftNull };
|
|
157619
|
+
}
|
|
157620
|
+
const findOrphanStmt = db.prepare(`SELECT id FROM tags
|
|
157621
|
+
WHERE session_id = ? AND message_id = ? AND type = 'tool'
|
|
157622
|
+
AND tool_owner_message_id IS NULL
|
|
157623
|
+
ORDER BY tag_number ASC
|
|
157624
|
+
LIMIT 1`);
|
|
157625
|
+
const updateRowStmt = db.prepare(`UPDATE tags
|
|
157626
|
+
SET tool_owner_message_id = ?
|
|
157627
|
+
WHERE id = ? AND tool_owner_message_id IS NULL`);
|
|
157628
|
+
let rowsUpdated = 0;
|
|
157629
|
+
db.transaction(() => {
|
|
157630
|
+
for (const [callId, ownerId] of ownersByCallId) {
|
|
157631
|
+
const orphan = findOrphanStmt.get(sessionId, callId);
|
|
157632
|
+
if (!orphan)
|
|
157633
|
+
continue;
|
|
157634
|
+
const result = updateRowStmt.run(ownerId, orphan.id);
|
|
157635
|
+
rowsUpdated += result.changes ?? 0;
|
|
157636
|
+
}
|
|
157637
|
+
})();
|
|
157638
|
+
const rowsLeftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
|
|
157639
|
+
WHERE session_id = ? AND type = 'tool'
|
|
157640
|
+
AND tool_owner_message_id IS NULL`).get(sessionId).c;
|
|
157641
|
+
return { rowsUpdated, rowsLeftNull };
|
|
157642
|
+
}
|
|
157643
|
+
function backfillToolOwnersInChunks(db, result) {
|
|
157644
|
+
const sessionIds = getSessionsNeedingBackfill(db);
|
|
157645
|
+
let lastRenewedAt = Date.now();
|
|
157646
|
+
for (const sessionId of sessionIds) {
|
|
157647
|
+
const now = Date.now();
|
|
157648
|
+
result.sessionsProcessed += 1;
|
|
157649
|
+
const acquired = acquireSessionLease(db, sessionId, now);
|
|
157650
|
+
if (!acquired) {
|
|
157651
|
+
result.sessionsBlockedByLease += 1;
|
|
157652
|
+
continue;
|
|
157653
|
+
}
|
|
157654
|
+
try {
|
|
157655
|
+
const owners = buildSessionOwnerMap(db, sessionId);
|
|
157656
|
+
const { rowsUpdated, rowsLeftNull } = applyOwnersForSession(db, sessionId, owners);
|
|
157657
|
+
result.rowsUpdated += rowsUpdated;
|
|
157658
|
+
result.rowsLeftNull += rowsLeftNull;
|
|
157659
|
+
if (owners.size === 0) {
|
|
157660
|
+
markSessionSkipped(db, sessionId, Date.now(), "no_oc_matches");
|
|
157661
|
+
result.sessionsSkippedNoMatches += 1;
|
|
157662
|
+
} else {
|
|
157663
|
+
markSessionCompleted(db, sessionId, Date.now());
|
|
157664
|
+
result.sessionsCompleted += 1;
|
|
157665
|
+
}
|
|
157666
|
+
} catch (error48) {
|
|
157667
|
+
log(`[backfill] session=${sessionId} errored: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
157668
|
+
markSessionErrored(db, sessionId, error48);
|
|
157669
|
+
result.sessionsErrored += 1;
|
|
157670
|
+
}
|
|
157671
|
+
const sinceRenew = Date.now() - lastRenewedAt;
|
|
157672
|
+
if (sinceRenew > LEASE_RENEWAL_MS) {
|
|
157673
|
+
renewSessionLease(db, sessionId, Date.now());
|
|
157674
|
+
lastRenewedAt = Date.now();
|
|
157675
|
+
}
|
|
157676
|
+
}
|
|
157677
|
+
}
|
|
157678
|
+
|
|
157075
157679
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
157076
157680
|
var databases = new Map;
|
|
157077
157681
|
var persistenceByDatabase = new WeakMap;
|
|
157078
157682
|
var persistenceErrorByDatabase = new WeakMap;
|
|
157079
157683
|
function resolveDatabasePath() {
|
|
157080
157684
|
const dbDir = getMagicContextStorageDir();
|
|
157081
|
-
return { dbDir, dbPath:
|
|
157685
|
+
return { dbDir, dbPath: join7(dbDir, "context.db") };
|
|
157082
157686
|
}
|
|
157083
157687
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
157084
|
-
if (
|
|
157688
|
+
if (existsSync3(targetDbPath))
|
|
157085
157689
|
return;
|
|
157086
157690
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
157087
|
-
const legacyDbPath =
|
|
157088
|
-
if (!
|
|
157691
|
+
const legacyDbPath = join7(legacyDir, "context.db");
|
|
157692
|
+
if (!existsSync3(legacyDbPath))
|
|
157089
157693
|
return;
|
|
157090
157694
|
log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
157091
157695
|
mkdirSync3(targetDbDir, { recursive: true });
|
|
157092
157696
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
157093
157697
|
const src = `${legacyDbPath}${suffix}`;
|
|
157094
|
-
const dst =
|
|
157095
|
-
if (
|
|
157698
|
+
const dst = join7(targetDbDir, `context.db${suffix}`);
|
|
157699
|
+
if (existsSync3(src)) {
|
|
157096
157700
|
try {
|
|
157097
157701
|
copyFileSync(src, dst);
|
|
157098
157702
|
} catch (error48) {
|
|
@@ -157100,9 +157704,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
157100
157704
|
}
|
|
157101
157705
|
}
|
|
157102
157706
|
}
|
|
157103
|
-
const legacyModelsDir =
|
|
157104
|
-
const targetModelsDir =
|
|
157105
|
-
if (
|
|
157707
|
+
const legacyModelsDir = join7(legacyDir, "models");
|
|
157708
|
+
const targetModelsDir = join7(targetDbDir, "models");
|
|
157709
|
+
if (existsSync3(legacyModelsDir) && !existsSync3(targetModelsDir)) {
|
|
157106
157710
|
try {
|
|
157107
157711
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
157108
157712
|
} catch (error48) {
|
|
@@ -157388,6 +157992,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
157388
157992
|
ensureColumn(db, "tags", "tool_name", "TEXT");
|
|
157389
157993
|
ensureColumn(db, "tags", "input_byte_size", "INTEGER DEFAULT 0");
|
|
157390
157994
|
ensureColumn(db, "tags", "caveman_depth", "INTEGER DEFAULT 0");
|
|
157995
|
+
ensureColumn(db, "tags", "tool_owner_message_id", "TEXT DEFAULT NULL");
|
|
157391
157996
|
ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
|
|
157392
157997
|
ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
|
|
157393
157998
|
ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
|
|
@@ -157486,6 +158091,13 @@ function openDatabase() {
|
|
|
157486
158091
|
const db = new Database(dbPath);
|
|
157487
158092
|
initializeDatabase(db);
|
|
157488
158093
|
runMigrations(db);
|
|
158094
|
+
try {
|
|
158095
|
+
runToolOwnerBackfill(db);
|
|
158096
|
+
} catch (error48) {
|
|
158097
|
+
log(`[magic-context] tool-owner backfill failed (continuing with lazy adoption fallback): ${getErrorMessage(error48)}`);
|
|
158098
|
+
}
|
|
158099
|
+
setDatabase(db);
|
|
158100
|
+
loadToolDefinitionMeasurements(db);
|
|
157489
158101
|
databases.set(dbPath, db);
|
|
157490
158102
|
persistenceByDatabase.set(db, true);
|
|
157491
158103
|
persistenceErrorByDatabase.delete(db);
|
|
@@ -158093,7 +158705,7 @@ var getTagNumberByMessageIdStatements = new WeakMap;
|
|
|
158093
158705
|
function getInsertTagStatement(db) {
|
|
158094
158706
|
let stmt = insertTagStatements.get(db);
|
|
158095
158707
|
if (!stmt) {
|
|
158096
|
-
stmt = db.prepare("INSERT INTO tags (session_id, message_id, type, byte_size, reasoning_byte_size, tag_number, tool_name, input_byte_size, harness) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
158708
|
+
stmt = db.prepare("INSERT INTO tags (session_id, message_id, type, byte_size, reasoning_byte_size, tag_number, tool_name, input_byte_size, harness, tool_owner_message_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
158097
158709
|
insertTagStatements.set(db, stmt);
|
|
158098
158710
|
}
|
|
158099
158711
|
return stmt;
|
|
@@ -158174,7 +158786,8 @@ function toTagEntry(row) {
|
|
|
158174
158786
|
byteSize: row.byte_size,
|
|
158175
158787
|
reasoningByteSize: row.reasoning_byte_size ?? 0,
|
|
158176
158788
|
sessionId: row.session_id,
|
|
158177
|
-
cavemanDepth: typeof row.caveman_depth === "number" && Number.isFinite(row.caveman_depth) ? row.caveman_depth : 0
|
|
158789
|
+
cavemanDepth: typeof row.caveman_depth === "number" && Number.isFinite(row.caveman_depth) ? row.caveman_depth : 0,
|
|
158790
|
+
toolOwnerMessageId: typeof row.tool_owner_message_id === "string" ? row.tool_owner_message_id : null
|
|
158178
158791
|
};
|
|
158179
158792
|
}
|
|
158180
158793
|
function isTagNumberRow(row) {
|
|
@@ -158189,8 +158802,8 @@ function isMaxTagNumberRow(row) {
|
|
|
158189
158802
|
const r = row;
|
|
158190
158803
|
return typeof r.max_tag_number === "number";
|
|
158191
158804
|
}
|
|
158192
|
-
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0) {
|
|
158193
|
-
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness());
|
|
158805
|
+
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null) {
|
|
158806
|
+
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId);
|
|
158194
158807
|
return tagNumber;
|
|
158195
158808
|
}
|
|
158196
158809
|
function updateTagStatus(db, sessionId, tagId, status) {
|
|
@@ -158202,6 +158815,7 @@ function updateTagDropMode(db, sessionId, tagNumber, dropMode) {
|
|
|
158202
158815
|
function updateCavemanDepth(db, sessionId, tagNumber, depth) {
|
|
158203
158816
|
db.prepare("UPDATE tags SET caveman_depth = ? WHERE session_id = ? AND tag_number = ?").run(depth, sessionId, tagNumber);
|
|
158204
158817
|
}
|
|
158818
|
+
var getOwnerScopedToolTagNumbersStatements = new WeakMap;
|
|
158205
158819
|
function getMaxTagNumberBySession(db, sessionId) {
|
|
158206
158820
|
const row = getMaxTagNumberBySessionStatement(db).get(sessionId);
|
|
158207
158821
|
return isMaxTagNumberRow(row) ? row.max_tag_number : 0;
|
|
@@ -158210,17 +158824,103 @@ function getTagNumberByMessageId(db, sessionId, messageId) {
|
|
|
158210
158824
|
const row = getTagNumberByMessageIdStatement(db).get(sessionId, messageId);
|
|
158211
158825
|
return isTagNumberRow(row) ? row.tag_number : null;
|
|
158212
158826
|
}
|
|
158827
|
+
var TAG_SELECT_COLUMNS = "id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth, tool_owner_message_id";
|
|
158213
158828
|
function getTagsBySession(db, sessionId) {
|
|
158214
|
-
const rows = db.prepare(
|
|
158829
|
+
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? ORDER BY tag_number ASC, id ASC`).all(sessionId).filter(isTagRow);
|
|
158830
|
+
return rows.map(toTagEntry);
|
|
158831
|
+
}
|
|
158832
|
+
var getActiveTagsBySessionStatements = new WeakMap;
|
|
158833
|
+
var getMaxDroppedTagNumberStatements = new WeakMap;
|
|
158834
|
+
function getActiveTagsBySessionStatement(db) {
|
|
158835
|
+
let stmt = getActiveTagsBySessionStatements.get(db);
|
|
158836
|
+
if (!stmt) {
|
|
158837
|
+
stmt = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND status = 'active' ORDER BY tag_number ASC, id ASC`);
|
|
158838
|
+
getActiveTagsBySessionStatements.set(db, stmt);
|
|
158839
|
+
}
|
|
158840
|
+
return stmt;
|
|
158841
|
+
}
|
|
158842
|
+
function getActiveTagsBySession(db, sessionId) {
|
|
158843
|
+
const rows = getActiveTagsBySessionStatement(db).all(sessionId).filter(isTagRow);
|
|
158844
|
+
return rows.map(toTagEntry);
|
|
158845
|
+
}
|
|
158846
|
+
function getTagsByNumbers(db, sessionId, tagNumbers) {
|
|
158847
|
+
if (tagNumbers.length === 0)
|
|
158848
|
+
return [];
|
|
158849
|
+
if (tagNumbers.length > 900) {
|
|
158850
|
+
const all = [];
|
|
158851
|
+
for (let i = 0;i < tagNumbers.length; i += 900) {
|
|
158852
|
+
all.push(...getTagsByNumbers(db, sessionId, tagNumbers.slice(i, i + 900)));
|
|
158853
|
+
}
|
|
158854
|
+
return all;
|
|
158855
|
+
}
|
|
158856
|
+
const placeholders = tagNumbers.map(() => "?").join(",");
|
|
158857
|
+
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND tag_number IN (${placeholders}) ORDER BY tag_number ASC, id ASC`).all(sessionId, ...tagNumbers).filter(isTagRow);
|
|
158215
158858
|
return rows.map(toTagEntry);
|
|
158216
158859
|
}
|
|
158217
158860
|
function getTopNBySize(db, sessionId, n) {
|
|
158218
158861
|
if (n <= 0) {
|
|
158219
158862
|
return [];
|
|
158220
158863
|
}
|
|
158221
|
-
const rows = db.prepare(
|
|
158864
|
+
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND status = 'active' ORDER BY byte_size DESC, tag_number ASC LIMIT ?`).all(sessionId, n).filter(isTagRow);
|
|
158222
158865
|
return rows.map(toTagEntry);
|
|
158223
158866
|
}
|
|
158867
|
+
var getToolTagNumberByOwnerStatements = new WeakMap;
|
|
158868
|
+
var getNullOwnerToolTagStatements = new WeakMap;
|
|
158869
|
+
var adoptNullOwnerToolTagStatements = new WeakMap;
|
|
158870
|
+
var deleteToolTagsByOwnerStatements = new WeakMap;
|
|
158871
|
+
function getGetToolTagNumberByOwnerStatement(db) {
|
|
158872
|
+
let stmt = getToolTagNumberByOwnerStatements.get(db);
|
|
158873
|
+
if (!stmt) {
|
|
158874
|
+
stmt = db.prepare(`SELECT tag_number FROM tags
|
|
158875
|
+
WHERE session_id = ? AND message_id = ?
|
|
158876
|
+
AND type = 'tool' AND tool_owner_message_id = ?
|
|
158877
|
+
LIMIT 1`);
|
|
158878
|
+
getToolTagNumberByOwnerStatements.set(db, stmt);
|
|
158879
|
+
}
|
|
158880
|
+
return stmt;
|
|
158881
|
+
}
|
|
158882
|
+
function getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId) {
|
|
158883
|
+
const row = getGetToolTagNumberByOwnerStatement(db).get(sessionId, callId, ownerMsgId);
|
|
158884
|
+
return isTagNumberRow(row) ? row.tag_number : null;
|
|
158885
|
+
}
|
|
158886
|
+
function isNullOwnerToolTagRow(row) {
|
|
158887
|
+
if (row === null || typeof row !== "object")
|
|
158888
|
+
return false;
|
|
158889
|
+
const r = row;
|
|
158890
|
+
return typeof r.id === "number" && typeof r.tag_number === "number";
|
|
158891
|
+
}
|
|
158892
|
+
function getGetNullOwnerToolTagStatement(db) {
|
|
158893
|
+
let stmt = getNullOwnerToolTagStatements.get(db);
|
|
158894
|
+
if (!stmt) {
|
|
158895
|
+
stmt = db.prepare(`SELECT id, tag_number FROM tags
|
|
158896
|
+
WHERE session_id = ? AND message_id = ?
|
|
158897
|
+
AND type = 'tool' AND tool_owner_message_id IS NULL
|
|
158898
|
+
ORDER BY tag_number ASC
|
|
158899
|
+
LIMIT 1`);
|
|
158900
|
+
getNullOwnerToolTagStatements.set(db, stmt);
|
|
158901
|
+
}
|
|
158902
|
+
return stmt;
|
|
158903
|
+
}
|
|
158904
|
+
function getNullOwnerToolTag(db, sessionId, callId) {
|
|
158905
|
+
const row = getGetNullOwnerToolTagStatement(db).get(sessionId, callId);
|
|
158906
|
+
if (!isNullOwnerToolTagRow(row))
|
|
158907
|
+
return null;
|
|
158908
|
+
return { id: row.id, tagNumber: row.tag_number };
|
|
158909
|
+
}
|
|
158910
|
+
function getAdoptNullOwnerToolTagStatement(db) {
|
|
158911
|
+
let stmt = adoptNullOwnerToolTagStatements.get(db);
|
|
158912
|
+
if (!stmt) {
|
|
158913
|
+
stmt = db.prepare(`UPDATE tags
|
|
158914
|
+
SET tool_owner_message_id = ?
|
|
158915
|
+
WHERE id = ? AND tool_owner_message_id IS NULL`);
|
|
158916
|
+
adoptNullOwnerToolTagStatements.set(db, stmt);
|
|
158917
|
+
}
|
|
158918
|
+
return stmt;
|
|
158919
|
+
}
|
|
158920
|
+
function adoptNullOwnerToolTag(db, rowId, ownerMsgId) {
|
|
158921
|
+
const result = getAdoptNullOwnerToolTagStatement(db).run(ownerMsgId, rowId);
|
|
158922
|
+
return (result.changes ?? 0) === 1;
|
|
158923
|
+
}
|
|
158224
158924
|
// ../plugin/src/agents/historian.ts
|
|
158225
158925
|
var HISTORIAN_AGENT = "historian";
|
|
158226
158926
|
var HISTORIAN_EDITOR_AGENT = "historian-editor";
|
|
@@ -158278,11 +158978,12 @@ function expandFallbackChain(chain) {
|
|
|
158278
158978
|
init_data_path();
|
|
158279
158979
|
init_logger();
|
|
158280
158980
|
import { createHash as createHash3 } from "node:crypto";
|
|
158281
|
-
import { existsSync as
|
|
158981
|
+
import { existsSync as existsSync4, readFileSync } from "node:fs";
|
|
158282
158982
|
import { homedir as homedir2, platform } from "node:os";
|
|
158283
|
-
import { join as
|
|
158983
|
+
import { join as join8 } from "node:path";
|
|
158284
158984
|
var RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
158285
158985
|
var apiCache = null;
|
|
158986
|
+
var recentlySeenApiSizes = new Set;
|
|
158286
158987
|
var fileCache = null;
|
|
158287
158988
|
var fileLastAttempt = 0;
|
|
158288
158989
|
function hashFast(input) {
|
|
@@ -158295,16 +158996,16 @@ function getModelsJsonPath() {
|
|
|
158295
158996
|
const cacheBase = getCacheDir();
|
|
158296
158997
|
const source = process.env.OPENCODE_MODELS_URL?.trim();
|
|
158297
158998
|
const filename = source && source !== "https://models.dev" ? `models-${hashFast(source)}.json` : "models.json";
|
|
158298
|
-
return
|
|
158999
|
+
return join8(cacheBase, "opencode", filename);
|
|
158299
159000
|
}
|
|
158300
159001
|
function getOpencodeConfigPath() {
|
|
158301
159002
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
158302
|
-
const configDir = envDir ? envDir : platform() === "win32" ?
|
|
158303
|
-
const jsonc =
|
|
158304
|
-
if (
|
|
159003
|
+
const configDir = envDir ? envDir : platform() === "win32" ? join8(homedir2(), ".config", "opencode") : join8(process.env.XDG_CONFIG_HOME || join8(homedir2(), ".config"), "opencode");
|
|
159004
|
+
const jsonc = join8(configDir, "opencode.jsonc");
|
|
159005
|
+
if (existsSync4(jsonc))
|
|
158305
159006
|
return jsonc;
|
|
158306
|
-
const json2 =
|
|
158307
|
-
if (
|
|
159007
|
+
const json2 = join8(configDir, "opencode.json");
|
|
159008
|
+
if (existsSync4(json2))
|
|
158308
159009
|
return json2;
|
|
158309
159010
|
return null;
|
|
158310
159011
|
}
|
|
@@ -158317,23 +159018,12 @@ function resolveLimit(limit) {
|
|
|
158317
159018
|
return limit.context;
|
|
158318
159019
|
return;
|
|
158319
159020
|
}
|
|
158320
|
-
function resolveInterleavedField(interleaved) {
|
|
158321
|
-
if (interleaved && typeof interleaved === "object" && typeof interleaved.field === "string" && interleaved.field.length > 0) {
|
|
158322
|
-
return interleaved.field;
|
|
158323
|
-
}
|
|
158324
|
-
return;
|
|
158325
|
-
}
|
|
158326
159021
|
function setCachedModelMetadata(cache, key, model) {
|
|
158327
159022
|
const limit = resolveLimit(model?.limit);
|
|
158328
|
-
|
|
158329
|
-
if (limit === undefined && interleavedField === undefined) {
|
|
159023
|
+
if (limit === undefined) {
|
|
158330
159024
|
return;
|
|
158331
159025
|
}
|
|
158332
|
-
const value = {};
|
|
158333
|
-
if (limit !== undefined)
|
|
158334
|
-
value.limit = limit;
|
|
158335
|
-
if (interleavedField !== undefined)
|
|
158336
|
-
value.interleavedField = interleavedField;
|
|
159026
|
+
const value = { limit };
|
|
158337
159027
|
cache.set(key, value);
|
|
158338
159028
|
const modes = model?.experimental?.modes;
|
|
158339
159029
|
if (modes && typeof modes === "object") {
|
|
@@ -158347,7 +159037,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
158347
159037
|
const modelsJsonPath = getModelsJsonPath();
|
|
158348
159038
|
let fileFound = false;
|
|
158349
159039
|
try {
|
|
158350
|
-
if (
|
|
159040
|
+
if (existsSync4(modelsJsonPath)) {
|
|
158351
159041
|
fileFound = true;
|
|
158352
159042
|
const raw = readFileSync(modelsJsonPath, "utf-8");
|
|
158353
159043
|
const data = JSON.parse(raw);
|
|
@@ -158364,7 +159054,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
158364
159054
|
}
|
|
158365
159055
|
try {
|
|
158366
159056
|
const configPath = getOpencodeConfigPath();
|
|
158367
|
-
if (configPath &&
|
|
159057
|
+
if (configPath && existsSync4(configPath)) {
|
|
158368
159058
|
let raw = readFileSync(configPath, "utf-8");
|
|
158369
159059
|
raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
|
|
158370
159060
|
const config2 = JSON.parse(raw);
|
|
@@ -158398,22 +159088,6 @@ function getModelsDevContextLimit(providerID, modelID) {
|
|
|
158398
159088
|
}
|
|
158399
159089
|
return fileCache.get(key)?.limit;
|
|
158400
159090
|
}
|
|
158401
|
-
function getModelsDevInterleavedField(providerID, modelID) {
|
|
158402
|
-
const key = `${providerID}/${modelID}`;
|
|
158403
|
-
if (apiCache) {
|
|
158404
|
-
const fromApi = apiCache.get(key)?.interleavedField;
|
|
158405
|
-
if (typeof fromApi === "string" && fromApi.length > 0) {
|
|
158406
|
-
return fromApi;
|
|
158407
|
-
}
|
|
158408
|
-
}
|
|
158409
|
-
const now = Date.now();
|
|
158410
|
-
if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
|
|
158411
|
-
fileLastAttempt = now;
|
|
158412
|
-
fileCache = loadModelsDevMetadataFromFile();
|
|
158413
|
-
}
|
|
158414
|
-
const fromFile = fileCache.get(key)?.interleavedField;
|
|
158415
|
-
return typeof fromFile === "string" && fromFile.length > 0 ? fromFile : undefined;
|
|
158416
|
-
}
|
|
158417
159091
|
|
|
158418
159092
|
// ../plugin/src/hooks/magic-context/derive-budgets.ts
|
|
158419
159093
|
var TRIGGER_BUDGET_PERCENTAGE = 0.05;
|
|
@@ -158707,7 +159381,7 @@ init_logger();
|
|
|
158707
159381
|
|
|
158708
159382
|
// src/subagent-runner.ts
|
|
158709
159383
|
import * as childProcess from "node:child_process";
|
|
158710
|
-
import { existsSync as
|
|
159384
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
158711
159385
|
import { dirname as dirname2, resolve as resolvePath } from "node:path";
|
|
158712
159386
|
import { createInterface } from "node:readline";
|
|
158713
159387
|
import { fileURLToPath } from "node:url";
|
|
@@ -158715,7 +159389,7 @@ function resolveSubagentEntryPath() {
|
|
|
158715
159389
|
try {
|
|
158716
159390
|
const here = dirname2(fileURLToPath(import.meta.url));
|
|
158717
159391
|
const candidate = resolvePath(here, "subagent-entry.js");
|
|
158718
|
-
if (
|
|
159392
|
+
if (existsSync5(candidate))
|
|
158719
159393
|
return candidate;
|
|
158720
159394
|
return;
|
|
158721
159395
|
} catch {
|
|
@@ -159261,7 +159935,7 @@ function deleteDreamState(db, key) {
|
|
|
159261
159935
|
var LEASE_HOLDER_KEY = "dreaming_lease_holder";
|
|
159262
159936
|
var LEASE_HEARTBEAT_KEY = "dreaming_lease_heartbeat";
|
|
159263
159937
|
var LEASE_EXPIRY_KEY = "dreaming_lease_expiry";
|
|
159264
|
-
var
|
|
159938
|
+
var LEASE_DURATION_MS2 = 2 * 60 * 1000;
|
|
159265
159939
|
function getLeaseExpiry(db) {
|
|
159266
159940
|
const value = getDreamState(db, LEASE_EXPIRY_KEY);
|
|
159267
159941
|
if (!value) {
|
|
@@ -159288,7 +159962,7 @@ function acquireLease(db, holderId) {
|
|
|
159288
159962
|
const now = Date.now();
|
|
159289
159963
|
setDreamState(db, LEASE_HOLDER_KEY, holderId);
|
|
159290
159964
|
setDreamState(db, LEASE_HEARTBEAT_KEY, String(now));
|
|
159291
|
-
setDreamState(db, LEASE_EXPIRY_KEY, String(now +
|
|
159965
|
+
setDreamState(db, LEASE_EXPIRY_KEY, String(now + LEASE_DURATION_MS2));
|
|
159292
159966
|
return true;
|
|
159293
159967
|
})();
|
|
159294
159968
|
}
|
|
@@ -159299,7 +159973,7 @@ function renewLease(db, holderId) {
|
|
|
159299
159973
|
}
|
|
159300
159974
|
const now = Date.now();
|
|
159301
159975
|
setDreamState(db, LEASE_HEARTBEAT_KEY, String(now));
|
|
159302
|
-
setDreamState(db, LEASE_EXPIRY_KEY, String(now +
|
|
159976
|
+
setDreamState(db, LEASE_EXPIRY_KEY, String(now + LEASE_DURATION_MS2));
|
|
159303
159977
|
return true;
|
|
159304
159978
|
})();
|
|
159305
159979
|
}
|
|
@@ -159314,8 +159988,8 @@ function releaseLease(db, holderId) {
|
|
|
159314
159988
|
})();
|
|
159315
159989
|
}
|
|
159316
159990
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
159317
|
-
import { existsSync as
|
|
159318
|
-
import { join as
|
|
159991
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
159992
|
+
import { join as join9 } from "node:path";
|
|
159319
159993
|
|
|
159320
159994
|
// ../plugin/src/shared/index.ts
|
|
159321
159995
|
init_logger();
|
|
@@ -159446,11 +160120,6 @@ function normalizeSDKResponse(response, fallback, options) {
|
|
|
159446
160120
|
}
|
|
159447
160121
|
return fallback;
|
|
159448
160122
|
}
|
|
159449
|
-
// ../plugin/src/shared/record-type-guard.ts
|
|
159450
|
-
function isRecord(value) {
|
|
159451
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
159452
|
-
}
|
|
159453
|
-
|
|
159454
160123
|
// ../plugin/src/shared/assistant-message-extractor.ts
|
|
159455
160124
|
function asSessionMessage(value) {
|
|
159456
160125
|
if (!isRecord(value))
|
|
@@ -160713,11 +161382,11 @@ function countNewIds(beforeIds, afterIds) {
|
|
|
160713
161382
|
return count;
|
|
160714
161383
|
}
|
|
160715
161384
|
function getOpenCodeDbPath2() {
|
|
160716
|
-
return
|
|
161385
|
+
return join9(getDataDir(), "opencode", "opencode.db");
|
|
160717
161386
|
}
|
|
160718
161387
|
function openOpenCodeDb() {
|
|
160719
161388
|
const dbPath = getOpenCodeDbPath2();
|
|
160720
|
-
if (!
|
|
161389
|
+
if (!existsSync6(dbPath)) {
|
|
160721
161390
|
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
160722
161391
|
return null;
|
|
160723
161392
|
}
|
|
@@ -160967,8 +161636,8 @@ async function runDream(args) {
|
|
|
160967
161636
|
try {
|
|
160968
161637
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
160969
161638
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
160970
|
-
architecture:
|
|
160971
|
-
structure:
|
|
161639
|
+
architecture: existsSync6(join9(docsDir, "ARCHITECTURE.md")),
|
|
161640
|
+
structure: existsSync6(join9(docsDir, "STRUCTURE.md"))
|
|
160972
161641
|
} : undefined;
|
|
160973
161642
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
160974
161643
|
id: um.id,
|
|
@@ -162478,14 +163147,46 @@ function createScheduler(config2) {
|
|
|
162478
163147
|
}
|
|
162479
163148
|
|
|
162480
163149
|
// ../plugin/src/features/magic-context/tagger.ts
|
|
163150
|
+
var TOOL_COMPOSITE_KEY_SEP = "\x00";
|
|
163151
|
+
function makeToolCompositeKey(ownerMsgId, callId) {
|
|
163152
|
+
return `${ownerMsgId}${TOOL_COMPOSITE_KEY_SEP}${callId}`;
|
|
163153
|
+
}
|
|
162481
163154
|
var GET_COUNTER_SQL = `SELECT counter FROM session_meta WHERE session_id = ?`;
|
|
162482
|
-
var GET_ASSIGNMENTS_SQL = "SELECT message_id, tag_number FROM tags WHERE session_id = ? ORDER BY tag_number ASC";
|
|
163155
|
+
var GET_ASSIGNMENTS_SQL = "SELECT message_id, tag_number, type, tool_owner_message_id FROM tags WHERE session_id = ? ORDER BY tag_number ASC";
|
|
163156
|
+
var PROBE_DATA_VERSION_SQL = "PRAGMA main.data_version";
|
|
163157
|
+
var PROBE_TOTAL_CHANGES_SQL = "SELECT total_changes() AS tc";
|
|
163158
|
+
var probeDataVersionStatements = new WeakMap;
|
|
163159
|
+
var probeTotalChangesStatements = new WeakMap;
|
|
163160
|
+
function getProbeDataVersionStatement(db) {
|
|
163161
|
+
let stmt = probeDataVersionStatements.get(db);
|
|
163162
|
+
if (!stmt) {
|
|
163163
|
+
stmt = db.prepare(PROBE_DATA_VERSION_SQL);
|
|
163164
|
+
probeDataVersionStatements.set(db, stmt);
|
|
163165
|
+
}
|
|
163166
|
+
return stmt;
|
|
163167
|
+
}
|
|
163168
|
+
function getProbeTotalChangesStatement(db) {
|
|
163169
|
+
let stmt = probeTotalChangesStatements.get(db);
|
|
163170
|
+
if (!stmt) {
|
|
163171
|
+
stmt = db.prepare(PROBE_TOTAL_CHANGES_SQL);
|
|
163172
|
+
probeTotalChangesStatements.set(db, stmt);
|
|
163173
|
+
}
|
|
163174
|
+
return stmt;
|
|
163175
|
+
}
|
|
162483
163176
|
function isAssignmentRow(row) {
|
|
162484
163177
|
if (row === null || typeof row !== "object") {
|
|
162485
163178
|
return false;
|
|
162486
163179
|
}
|
|
162487
163180
|
const candidate = row;
|
|
162488
|
-
|
|
163181
|
+
if (typeof candidate.message_id !== "string")
|
|
163182
|
+
return false;
|
|
163183
|
+
if (typeof candidate.tag_number !== "number")
|
|
163184
|
+
return false;
|
|
163185
|
+
if (candidate.type !== "message" && candidate.type !== "tool" && candidate.type !== "file")
|
|
163186
|
+
return false;
|
|
163187
|
+
if (candidate.tool_owner_message_id !== null && typeof candidate.tool_owner_message_id !== "string")
|
|
163188
|
+
return false;
|
|
163189
|
+
return true;
|
|
162489
163190
|
}
|
|
162490
163191
|
var UPSERT_COUNTER_SQL = `
|
|
162491
163192
|
INSERT INTO session_meta (session_id, counter, harness)
|
|
@@ -162519,6 +163220,7 @@ var MAX_TAG_ALLOC_RETRIES = 5;
|
|
|
162519
163220
|
function createTagger() {
|
|
162520
163221
|
const counters = new Map;
|
|
162521
163222
|
const assignments = new Map;
|
|
163223
|
+
const loadSignatures = new Map;
|
|
162522
163224
|
function getSessionAssignments(sessionId) {
|
|
162523
163225
|
let map2 = assignments.get(sessionId);
|
|
162524
163226
|
if (!map2) {
|
|
@@ -162537,15 +163239,15 @@ function createTagger() {
|
|
|
162537
163239
|
counters.set(sessionId, next);
|
|
162538
163240
|
getUpsertCounterStatement(db).run(sessionId, next, getHarness());
|
|
162539
163241
|
}
|
|
162540
|
-
function
|
|
163242
|
+
function allocateTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize, toolName, inputByteSize, toolOwnerMessageId, mapKey, dbExistingLookup) {
|
|
162541
163243
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
162542
|
-
const existing = sessionAssignments.get(
|
|
163244
|
+
const existing = sessionAssignments.get(mapKey);
|
|
162543
163245
|
if (existing !== undefined) {
|
|
162544
163246
|
return existing;
|
|
162545
163247
|
}
|
|
162546
|
-
const dbExisting =
|
|
163248
|
+
const dbExisting = dbExistingLookup();
|
|
162547
163249
|
if (dbExisting !== null) {
|
|
162548
|
-
sessionAssignments.set(
|
|
163250
|
+
sessionAssignments.set(mapKey, dbExisting);
|
|
162549
163251
|
syncCounterAtLeast(sessionId, db, dbExisting);
|
|
162550
163252
|
return dbExisting;
|
|
162551
163253
|
}
|
|
@@ -162555,16 +163257,16 @@ function createTagger() {
|
|
|
162555
163257
|
const next = Math.max(memCounter, dbMax) + 1;
|
|
162556
163258
|
try {
|
|
162557
163259
|
db.transaction(() => {
|
|
162558
|
-
insertTag(db, sessionId, messageId, type, byteSize2, next, reasoningByteSize, toolName, inputByteSize);
|
|
163260
|
+
insertTag(db, sessionId, messageId, type, byteSize2, next, reasoningByteSize, toolName, inputByteSize, toolOwnerMessageId);
|
|
162559
163261
|
getUpsertCounterStatement(db).run(sessionId, next, getHarness());
|
|
162560
163262
|
})();
|
|
162561
163263
|
} catch (error48) {
|
|
162562
163264
|
if (!isUniqueConstraintError(error48)) {
|
|
162563
163265
|
throw error48;
|
|
162564
163266
|
}
|
|
162565
|
-
const racedRow =
|
|
163267
|
+
const racedRow = dbExistingLookup();
|
|
162566
163268
|
if (racedRow !== null) {
|
|
162567
|
-
sessionAssignments.set(
|
|
163269
|
+
sessionAssignments.set(mapKey, racedRow);
|
|
162568
163270
|
syncCounterAtLeast(sessionId, db, racedRow);
|
|
162569
163271
|
return racedRow;
|
|
162570
163272
|
}
|
|
@@ -162573,51 +163275,124 @@ function createTagger() {
|
|
|
162573
163275
|
continue;
|
|
162574
163276
|
}
|
|
162575
163277
|
counters.set(sessionId, next);
|
|
162576
|
-
sessionAssignments.set(
|
|
163278
|
+
sessionAssignments.set(mapKey, next);
|
|
162577
163279
|
return next;
|
|
162578
163280
|
}
|
|
162579
|
-
throw new Error(`tagger.
|
|
163281
|
+
throw new Error(`tagger.allocateTag: failed to allocate tag for session=${sessionId} key=${mapKey} after ${MAX_TAG_ALLOC_RETRIES} retries`);
|
|
162580
163282
|
}
|
|
162581
|
-
function
|
|
163283
|
+
function assignTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize = 0, toolName = null, inputByteSize = 0) {
|
|
163284
|
+
if (type === "tool") {
|
|
163285
|
+
throw new Error("tagger.assignTag: type='tool' is forbidden — use assignToolTag(sessionId, callId, ownerMsgId, ...)");
|
|
163286
|
+
}
|
|
163287
|
+
return allocateTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize, toolName, inputByteSize, null, messageId, () => getTagNumberByMessageId(db, sessionId, messageId));
|
|
163288
|
+
}
|
|
163289
|
+
function assignToolTag(sessionId, callId, ownerMsgId, byteSize2, db, reasoningByteSize = 0, toolName = null, inputByteSize = 0) {
|
|
163290
|
+
const compositeKey = makeToolCompositeKey(ownerMsgId, callId);
|
|
163291
|
+
const sessionAssignments = getSessionAssignments(sessionId);
|
|
163292
|
+
const existing = sessionAssignments.get(compositeKey);
|
|
163293
|
+
if (existing !== undefined) {
|
|
163294
|
+
return existing;
|
|
163295
|
+
}
|
|
163296
|
+
const dbHit = getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId);
|
|
163297
|
+
if (dbHit !== null) {
|
|
163298
|
+
sessionAssignments.set(compositeKey, dbHit);
|
|
163299
|
+
syncCounterAtLeast(sessionId, db, dbHit);
|
|
163300
|
+
return dbHit;
|
|
163301
|
+
}
|
|
163302
|
+
for (let attempt = 0;attempt < MAX_TAG_ALLOC_RETRIES; attempt += 1) {
|
|
163303
|
+
const orphan = getNullOwnerToolTag(db, sessionId, callId);
|
|
163304
|
+
if (orphan === null)
|
|
163305
|
+
break;
|
|
163306
|
+
const claimed = adoptNullOwnerToolTag(db, orphan.id, ownerMsgId);
|
|
163307
|
+
if (claimed) {
|
|
163308
|
+
sessionAssignments.set(compositeKey, orphan.tagNumber);
|
|
163309
|
+
syncCounterAtLeast(sessionId, db, orphan.tagNumber);
|
|
163310
|
+
return orphan.tagNumber;
|
|
163311
|
+
}
|
|
163312
|
+
const recheck = getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId);
|
|
163313
|
+
if (recheck !== null) {
|
|
163314
|
+
sessionAssignments.set(compositeKey, recheck);
|
|
163315
|
+
syncCounterAtLeast(sessionId, db, recheck);
|
|
163316
|
+
return recheck;
|
|
163317
|
+
}
|
|
163318
|
+
}
|
|
163319
|
+
return allocateTag(sessionId, callId, "tool", byteSize2, db, reasoningByteSize, toolName, inputByteSize, ownerMsgId, compositeKey, () => getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId));
|
|
163320
|
+
}
|
|
163321
|
+
function getTag(sessionId, messageId, _type) {
|
|
162582
163322
|
return assignments.get(sessionId)?.get(messageId);
|
|
162583
163323
|
}
|
|
163324
|
+
function getToolTag(sessionId, callId, ownerMsgId) {
|
|
163325
|
+
return assignments.get(sessionId)?.get(makeToolCompositeKey(ownerMsgId, callId));
|
|
163326
|
+
}
|
|
162584
163327
|
function bindTag(sessionId, messageId, tagNumber) {
|
|
162585
163328
|
getSessionAssignments(sessionId).set(messageId, tagNumber);
|
|
162586
163329
|
}
|
|
163330
|
+
function bindToolTag(sessionId, callId, ownerMsgId, tagNumber) {
|
|
163331
|
+
getSessionAssignments(sessionId).set(makeToolCompositeKey(ownerMsgId, callId), tagNumber);
|
|
163332
|
+
}
|
|
162587
163333
|
function getAssignments(sessionId) {
|
|
162588
163334
|
return getSessionAssignments(sessionId);
|
|
162589
163335
|
}
|
|
162590
163336
|
function resetCounter(sessionId, db) {
|
|
162591
163337
|
counters.set(sessionId, 0);
|
|
162592
163338
|
assignments.delete(sessionId);
|
|
163339
|
+
loadSignatures.delete(sessionId);
|
|
162593
163340
|
getResetCounterStatement(db).run(sessionId, getHarness());
|
|
162594
163341
|
}
|
|
162595
163342
|
function getCounter(sessionId) {
|
|
162596
163343
|
return counters.get(sessionId) ?? 0;
|
|
162597
163344
|
}
|
|
163345
|
+
function probeSignature(db) {
|
|
163346
|
+
const dvRow = getProbeDataVersionStatement(db).get();
|
|
163347
|
+
const tcRow = getProbeTotalChangesStatement(db).get();
|
|
163348
|
+
return {
|
|
163349
|
+
dataVersion: dvRow?.data_version ?? 0,
|
|
163350
|
+
totalChanges: tcRow?.tc ?? 0
|
|
163351
|
+
};
|
|
163352
|
+
}
|
|
162598
163353
|
function initFromDb(sessionId, db) {
|
|
163354
|
+
const probe = probeSignature(db);
|
|
163355
|
+
const cached2 = loadSignatures.get(sessionId);
|
|
163356
|
+
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.totalChanges === probe.totalChanges) {
|
|
163357
|
+
return;
|
|
163358
|
+
}
|
|
162599
163359
|
const row = db.prepare(GET_COUNTER_SQL).get(sessionId);
|
|
162600
163360
|
const assignmentRows = db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId).filter(isAssignmentRow);
|
|
162601
163361
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
162602
163362
|
sessionAssignments.clear();
|
|
162603
163363
|
let maxTagNumber = 0;
|
|
162604
163364
|
for (const assignment of assignmentRows) {
|
|
162605
|
-
|
|
163365
|
+
if (assignment.type === "tool") {
|
|
163366
|
+
if (assignment.tool_owner_message_id !== null) {
|
|
163367
|
+
sessionAssignments.set(makeToolCompositeKey(assignment.tool_owner_message_id, assignment.message_id), assignment.tag_number);
|
|
163368
|
+
}
|
|
163369
|
+
} else {
|
|
163370
|
+
sessionAssignments.set(assignment.message_id, assignment.tag_number);
|
|
163371
|
+
}
|
|
162606
163372
|
if (assignment.tag_number > maxTagNumber) {
|
|
162607
163373
|
maxTagNumber = assignment.tag_number;
|
|
162608
163374
|
}
|
|
162609
163375
|
}
|
|
162610
163376
|
const counter = Math.max(row?.counter ?? 0, maxTagNumber, counters.get(sessionId) ?? 0);
|
|
162611
163377
|
counters.set(sessionId, counter);
|
|
163378
|
+
loadSignatures.set(sessionId, {
|
|
163379
|
+
db,
|
|
163380
|
+
dataVersion: probe.dataVersion,
|
|
163381
|
+
totalChanges: probe.totalChanges
|
|
163382
|
+
});
|
|
162612
163383
|
}
|
|
162613
163384
|
function cleanup(sessionId) {
|
|
162614
163385
|
counters.delete(sessionId);
|
|
162615
163386
|
assignments.delete(sessionId);
|
|
163387
|
+
loadSignatures.delete(sessionId);
|
|
162616
163388
|
}
|
|
162617
163389
|
return {
|
|
162618
163390
|
assignTag,
|
|
163391
|
+
assignToolTag,
|
|
162619
163392
|
getTag,
|
|
163393
|
+
getToolTag,
|
|
162620
163394
|
bindTag,
|
|
163395
|
+
bindToolTag,
|
|
162621
163396
|
getAssignments,
|
|
162622
163397
|
resetCounter,
|
|
162623
163398
|
getCounter,
|
|
@@ -163630,7 +164405,7 @@ function createNudger(config2) {
|
|
|
163630
164405
|
}
|
|
163631
164406
|
const largest = formatLargestTags(topNFn(db, sessionId, 3));
|
|
163632
164407
|
const protectedCount = config2.protected_tags;
|
|
163633
|
-
const activeTags =
|
|
164408
|
+
const activeTags = preloadedTags ? preloadedTags.filter((t) => t.status === "active") : getActiveTagsBySession(db, sessionId);
|
|
163634
164409
|
const highestProtected = activeTags.map((t) => t.tagNumber).sort((a, b) => b - a).slice(0, protectedCount)[0];
|
|
163635
164410
|
const protectedHint = highestProtected ? ` Tags §${highestProtected}§ and above are protected (last ${protectedCount}) — You MUST NOT try to reduce those.` : "";
|
|
163636
164411
|
const oldToolHint = formatOldToolTags(activeTags, protectedCount, 5);
|
|
@@ -163721,7 +164496,7 @@ function estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags)
|
|
|
163721
164496
|
if (pendingDrops.length === 0) {
|
|
163722
164497
|
return null;
|
|
163723
164498
|
}
|
|
163724
|
-
const activeTags =
|
|
164499
|
+
const activeTags = preloadedTags ? preloadedTags.filter((t) => t.status === "active") : getActiveTagsBySession(db, sessionId);
|
|
163725
164500
|
const totalActiveBytes = activeTags.reduce((sum, t) => sum + t.byteSize, 0);
|
|
163726
164501
|
if (totalActiveBytes === 0) {
|
|
163727
164502
|
return null;
|
|
@@ -163732,15 +164507,6 @@ function estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags)
|
|
|
163732
164507
|
return contextUsage.percentage * (1 - dropRatio);
|
|
163733
164508
|
}
|
|
163734
164509
|
|
|
163735
|
-
// ../plugin/src/hooks/magic-context/reasoning-capability.ts
|
|
163736
|
-
function modelRequiresInterleavedReasoning(model) {
|
|
163737
|
-
if (!model?.providerID || !model?.modelID) {
|
|
163738
|
-
return false;
|
|
163739
|
-
}
|
|
163740
|
-
const field = getModelsDevInterleavedField(model.providerID, model.modelID);
|
|
163741
|
-
return typeof field === "string" && field.length > 0;
|
|
163742
|
-
}
|
|
163743
|
-
|
|
163744
164510
|
// src/context-handler.ts
|
|
163745
164511
|
init_logger();
|
|
163746
164512
|
|
|
@@ -163749,107 +164515,105 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
|
|
|
163749
164515
|
const skipPrefixInjection = options.skipPrefixInjection === true;
|
|
163750
164516
|
const targets = new Map;
|
|
163751
164517
|
const toolAggregates = new Map;
|
|
163752
|
-
|
|
163753
|
-
|
|
163754
|
-
|
|
163755
|
-
|
|
164518
|
+
for (let msgIndex = 0;msgIndex < transcript.messages.length; msgIndex += 1) {
|
|
164519
|
+
const message = transcript.messages[msgIndex];
|
|
164520
|
+
if (message === undefined)
|
|
164521
|
+
continue;
|
|
164522
|
+
const messageId = message.info.id;
|
|
164523
|
+
let textOrdinal = 0;
|
|
164524
|
+
for (let partIndex = 0;partIndex < message.parts.length; partIndex += 1) {
|
|
164525
|
+
const part = message.parts[partIndex];
|
|
164526
|
+
if (part === undefined)
|
|
163756
164527
|
continue;
|
|
163757
|
-
|
|
163758
|
-
|
|
163759
|
-
|
|
163760
|
-
const part = message.parts[partIndex];
|
|
163761
|
-
if (part === undefined)
|
|
164528
|
+
if (part.kind === "text") {
|
|
164529
|
+
if (messageId === undefined) {
|
|
164530
|
+
textOrdinal += 1;
|
|
163762
164531
|
continue;
|
|
163763
|
-
|
|
163764
|
-
|
|
163765
|
-
|
|
163766
|
-
|
|
163767
|
-
|
|
163768
|
-
|
|
164532
|
+
}
|
|
164533
|
+
tagTextPart({
|
|
164534
|
+
sessionId,
|
|
164535
|
+
message,
|
|
164536
|
+
messageId,
|
|
164537
|
+
msgIndex,
|
|
164538
|
+
textOrdinal,
|
|
164539
|
+
part,
|
|
164540
|
+
tagger,
|
|
164541
|
+
db,
|
|
164542
|
+
targets,
|
|
164543
|
+
skipPrefixInjection
|
|
164544
|
+
});
|
|
164545
|
+
textOrdinal += 1;
|
|
164546
|
+
continue;
|
|
164547
|
+
}
|
|
164548
|
+
if (part.kind === "tool_use" || part.kind === "tool_result") {
|
|
164549
|
+
if (messageId === undefined)
|
|
164550
|
+
continue;
|
|
164551
|
+
const callId = part.id;
|
|
164552
|
+
const text = part.getText() ?? "";
|
|
164553
|
+
const meta3 = part.getToolMetadata();
|
|
164554
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
164555
|
+
tagToolPart({
|
|
163769
164556
|
sessionId,
|
|
163770
164557
|
message,
|
|
163771
164558
|
messageId,
|
|
163772
164559
|
msgIndex,
|
|
163773
|
-
|
|
164560
|
+
partIndex,
|
|
163774
164561
|
part,
|
|
163775
164562
|
tagger,
|
|
163776
164563
|
db,
|
|
163777
164564
|
targets,
|
|
163778
164565
|
skipPrefixInjection
|
|
163779
164566
|
});
|
|
163780
|
-
textOrdinal += 1;
|
|
163781
164567
|
continue;
|
|
163782
164568
|
}
|
|
163783
|
-
|
|
163784
|
-
|
|
163785
|
-
|
|
163786
|
-
|
|
163787
|
-
|
|
163788
|
-
|
|
163789
|
-
|
|
163790
|
-
|
|
163791
|
-
|
|
163792
|
-
|
|
163793
|
-
|
|
163794
|
-
msgIndex,
|
|
163795
|
-
partIndex,
|
|
163796
|
-
part,
|
|
163797
|
-
tagger,
|
|
163798
|
-
db,
|
|
163799
|
-
targets,
|
|
163800
|
-
skipPrefixInjection
|
|
163801
|
-
});
|
|
163802
|
-
continue;
|
|
164569
|
+
const existing = toolAggregates.get(callId);
|
|
164570
|
+
if (existing) {
|
|
164571
|
+
existing.occurrences.push({
|
|
164572
|
+
message,
|
|
164573
|
+
part,
|
|
164574
|
+
kind: part.kind
|
|
164575
|
+
});
|
|
164576
|
+
const newByteSize = byteSize(text);
|
|
164577
|
+
if (newByteSize > existing.maxByteSize) {
|
|
164578
|
+
existing.maxByteSize = newByteSize;
|
|
164579
|
+
updateTagByteSize(db, sessionId, existing.tagId, newByteSize);
|
|
163803
164580
|
}
|
|
163804
|
-
|
|
163805
|
-
|
|
163806
|
-
|
|
163807
|
-
|
|
163808
|
-
|
|
163809
|
-
|
|
163810
|
-
|
|
163811
|
-
|
|
163812
|
-
|
|
163813
|
-
existing.maxByteSize = newByteSize;
|
|
163814
|
-
updateTagByteSize(db, sessionId, existing.tagId, newByteSize);
|
|
163815
|
-
}
|
|
163816
|
-
if (existing.toolName === null && meta3.toolName) {
|
|
163817
|
-
existing.toolName = meta3.toolName;
|
|
163818
|
-
}
|
|
163819
|
-
if (existing.inputByteSize === 0 && part.kind === "tool_use" && meta3.inputByteSize > 0) {
|
|
163820
|
-
existing.inputByteSize = meta3.inputByteSize;
|
|
163821
|
-
updateTagInputByteSize(db, sessionId, existing.tagId, meta3.inputByteSize);
|
|
163822
|
-
}
|
|
163823
|
-
if (!skipPrefixInjection && part.kind === "tool_result") {
|
|
163824
|
-
part.setText(prependTag(existing.tagId, text));
|
|
163825
|
-
}
|
|
163826
|
-
targets.set(existing.tagId, buildAggregateTarget(existing.tagId, existing.occurrences));
|
|
163827
|
-
} else {
|
|
163828
|
-
const tagId = tagger.assignTag(sessionId, callId, "tool", byteSize(text), db, 0, meta3.toolName ?? null, meta3.inputByteSize);
|
|
163829
|
-
const aggregate = {
|
|
163830
|
-
callId,
|
|
163831
|
-
tagId,
|
|
163832
|
-
occurrences: [
|
|
163833
|
-
{
|
|
163834
|
-
message,
|
|
163835
|
-
part,
|
|
163836
|
-
kind: part.kind
|
|
163837
|
-
}
|
|
163838
|
-
],
|
|
163839
|
-
maxByteSize: byteSize(text),
|
|
163840
|
-
toolName: meta3.toolName ?? null,
|
|
163841
|
-
inputByteSize: part.kind === "tool_use" ? meta3.inputByteSize : 0
|
|
163842
|
-
};
|
|
163843
|
-
toolAggregates.set(callId, aggregate);
|
|
163844
|
-
if (!skipPrefixInjection && part.kind === "tool_result") {
|
|
163845
|
-
part.setText(prependTag(tagId, text));
|
|
163846
|
-
}
|
|
163847
|
-
targets.set(tagId, buildAggregateTarget(tagId, aggregate.occurrences));
|
|
164581
|
+
if (existing.toolName === null && meta3.toolName) {
|
|
164582
|
+
existing.toolName = meta3.toolName;
|
|
164583
|
+
}
|
|
164584
|
+
if (existing.inputByteSize === 0 && part.kind === "tool_use" && meta3.inputByteSize > 0) {
|
|
164585
|
+
existing.inputByteSize = meta3.inputByteSize;
|
|
164586
|
+
updateTagInputByteSize(db, sessionId, existing.tagId, meta3.inputByteSize);
|
|
164587
|
+
}
|
|
164588
|
+
if (!skipPrefixInjection && part.kind === "tool_result") {
|
|
164589
|
+
part.setText(prependTag(existing.tagId, text));
|
|
163848
164590
|
}
|
|
164591
|
+
targets.set(existing.tagId, buildAggregateTarget(existing.tagId, existing.occurrences));
|
|
164592
|
+
} else {
|
|
164593
|
+
const tagId = tagger.assignToolTag(sessionId, callId, messageId, byteSize(text), db, 0, meta3.toolName ?? null, meta3.inputByteSize);
|
|
164594
|
+
const aggregate = {
|
|
164595
|
+
callId,
|
|
164596
|
+
tagId,
|
|
164597
|
+
occurrences: [
|
|
164598
|
+
{
|
|
164599
|
+
message,
|
|
164600
|
+
part,
|
|
164601
|
+
kind: part.kind
|
|
164602
|
+
}
|
|
164603
|
+
],
|
|
164604
|
+
maxByteSize: byteSize(text),
|
|
164605
|
+
toolName: meta3.toolName ?? null,
|
|
164606
|
+
inputByteSize: part.kind === "tool_use" ? meta3.inputByteSize : 0
|
|
164607
|
+
};
|
|
164608
|
+
toolAggregates.set(callId, aggregate);
|
|
164609
|
+
if (!skipPrefixInjection && part.kind === "tool_result") {
|
|
164610
|
+
part.setText(prependTag(tagId, text));
|
|
164611
|
+
}
|
|
164612
|
+
targets.set(tagId, buildAggregateTarget(tagId, aggregate.occurrences));
|
|
163849
164613
|
}
|
|
163850
164614
|
}
|
|
163851
164615
|
}
|
|
163852
|
-
}
|
|
164616
|
+
}
|
|
163853
164617
|
return { targets };
|
|
163854
164618
|
}
|
|
163855
164619
|
function tagTextPart(args) {
|
|
@@ -163870,7 +164634,7 @@ function tagToolPart(args) {
|
|
|
163870
164634
|
const contentId = stableId ?? `${args.messageId}:t${args.partIndex}`;
|
|
163871
164635
|
const text = args.part.getText() ?? "";
|
|
163872
164636
|
const meta3 = args.part.getToolMetadata();
|
|
163873
|
-
const tagId = args.tagger.
|
|
164637
|
+
const tagId = args.tagger.assignToolTag(args.sessionId, contentId, contentId, byteSize(text), args.db, 0, meta3.toolName ?? null, meta3.inputByteSize);
|
|
163874
164638
|
if (!args.skipPrefixInjection && args.part.kind === "tool_result") {
|
|
163875
164639
|
const tagged = prependTag(tagId, text);
|
|
163876
164640
|
args.part.setText(tagged);
|
|
@@ -164110,11 +164874,7 @@ function getMessageOrdinal(value) {
|
|
|
164110
164874
|
}
|
|
164111
164875
|
async function getSemanticScores(args) {
|
|
164112
164876
|
const semanticScores = new Map;
|
|
164113
|
-
if (!args.
|
|
164114
|
-
return semanticScores;
|
|
164115
|
-
}
|
|
164116
|
-
const queryEmbedding = await args.embedQuery(args.query, args.signal);
|
|
164117
|
-
if (!queryEmbedding) {
|
|
164877
|
+
if (!args.queryEmbedding || args.memories.length === 0) {
|
|
164118
164878
|
return semanticScores;
|
|
164119
164879
|
}
|
|
164120
164880
|
const cachedEmbeddings = getProjectEmbeddings(args.db, args.projectPath);
|
|
@@ -164128,7 +164888,7 @@ async function getSemanticScores(args) {
|
|
|
164128
164888
|
if (!memoryEmbedding) {
|
|
164129
164889
|
continue;
|
|
164130
164890
|
}
|
|
164131
|
-
semanticScores.set(memory.id, normalizeCosineScore(cosineSimilarity(queryEmbedding, memoryEmbedding)));
|
|
164891
|
+
semanticScores.set(memory.id, normalizeCosineScore(cosineSimilarity(args.queryEmbedding, memoryEmbedding)));
|
|
164132
164892
|
}
|
|
164133
164893
|
return semanticScores;
|
|
164134
164894
|
}
|
|
@@ -164224,12 +164984,8 @@ async function searchMemories(args) {
|
|
|
164224
164984
|
const semanticScores = await getSemanticScores({
|
|
164225
164985
|
db: args.db,
|
|
164226
164986
|
projectPath: args.projectPath,
|
|
164227
|
-
query: args.query,
|
|
164228
164987
|
memories: semanticCandidates,
|
|
164229
|
-
|
|
164230
|
-
embedQuery: args.embedQuery,
|
|
164231
|
-
isEmbeddingRuntimeEnabled: args.isEmbeddingRuntimeEnabled,
|
|
164232
|
-
signal: args.signal
|
|
164988
|
+
queryEmbedding: args.queryEmbedding
|
|
164233
164989
|
});
|
|
164234
164990
|
return mergeMemoryResults({
|
|
164235
164991
|
memories,
|
|
@@ -164245,7 +165001,6 @@ function linearDecayScore(rank, total) {
|
|
|
164245
165001
|
return Math.max(0, 1 - rank / total);
|
|
164246
165002
|
}
|
|
164247
165003
|
function searchMessages(args) {
|
|
164248
|
-
ensureMessagesIndexed(args.db, args.sessionId, args.readMessages);
|
|
164249
165004
|
const sanitizedQuery = sanitizeFtsQuery(args.query.trim());
|
|
164250
165005
|
if (sanitizedQuery.length === 0) {
|
|
164251
165006
|
return [];
|
|
@@ -164316,20 +165071,12 @@ function toGitCommitResult(hit) {
|
|
|
164316
165071
|
matchType: hit.matchType
|
|
164317
165072
|
};
|
|
164318
165073
|
}
|
|
164319
|
-
|
|
165074
|
+
function searchGitCommits(args) {
|
|
164320
165075
|
if (args.limit <= 0)
|
|
164321
165076
|
return [];
|
|
164322
|
-
let queryEmbedding = null;
|
|
164323
|
-
if (args.embeddingEnabled && args.isEmbeddingRuntimeEnabled()) {
|
|
164324
|
-
try {
|
|
164325
|
-
queryEmbedding = await args.embedQuery(args.query, args.signal);
|
|
164326
|
-
} catch (error48) {
|
|
164327
|
-
log(`[search] git commit query embedding failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
164328
|
-
}
|
|
164329
|
-
}
|
|
164330
165077
|
const hits = searchGitCommitsSync(args.db, args.projectPath, args.query, {
|
|
164331
165078
|
limit: args.limit,
|
|
164332
|
-
queryEmbedding
|
|
165079
|
+
queryEmbedding: args.queryEmbedding
|
|
164333
165080
|
});
|
|
164334
165081
|
return hits.map(toGitCommitResult);
|
|
164335
165082
|
}
|
|
@@ -164360,37 +165107,37 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
164360
165107
|
const runMemory = activeSources.has("memory") && (options.memoryEnabled ?? true);
|
|
164361
165108
|
const runMessages = activeSources.has("message");
|
|
164362
165109
|
const runGitCommits = activeSources.has("git_commit") && gitCommitsEnabled;
|
|
164363
|
-
const
|
|
165110
|
+
const needsEmbedding = (runMemory || runGitCommits) && embeddingEnabled && isEmbeddingRuntimeEnabled();
|
|
165111
|
+
const queryEmbeddingPromise = needsEmbedding ? embedQuery(trimmedQuery, options.signal).catch((error48) => {
|
|
165112
|
+
log(`[search] query embedding failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
165113
|
+
return null;
|
|
165114
|
+
}) : Promise.resolve(null);
|
|
165115
|
+
await Promise.resolve();
|
|
165116
|
+
const messageResults = runMessages ? searchMessages({
|
|
165117
|
+
db,
|
|
165118
|
+
sessionId,
|
|
165119
|
+
query: trimmedQuery,
|
|
165120
|
+
limit: tierLimit,
|
|
165121
|
+
maxOrdinal: options.maxMessageOrdinal
|
|
165122
|
+
}) : [];
|
|
165123
|
+
const queryEmbedding = await queryEmbeddingPromise;
|
|
165124
|
+
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
164364
165125
|
runMemory ? searchMemories({
|
|
164365
165126
|
db,
|
|
164366
165127
|
projectPath,
|
|
164367
165128
|
query: trimmedQuery,
|
|
164368
165129
|
limit: tierLimit,
|
|
164369
165130
|
memoryEnabled: true,
|
|
164370
|
-
|
|
164371
|
-
|
|
164372
|
-
isEmbeddingRuntimeEnabled,
|
|
164373
|
-
visibleMemoryIds: options.visibleMemoryIds,
|
|
164374
|
-
signal: options.signal
|
|
165131
|
+
queryEmbedding,
|
|
165132
|
+
visibleMemoryIds: options.visibleMemoryIds
|
|
164375
165133
|
}) : Promise.resolve([]),
|
|
164376
|
-
|
|
164377
|
-
db,
|
|
164378
|
-
sessionId,
|
|
164379
|
-
query: trimmedQuery,
|
|
164380
|
-
limit: tierLimit,
|
|
164381
|
-
readMessages: options.readMessages ?? readRawSessionMessages,
|
|
164382
|
-
maxOrdinal: options.maxMessageOrdinal
|
|
164383
|
-
})) : Promise.resolve([]),
|
|
164384
|
-
runGitCommits ? searchGitCommitsAsync({
|
|
165134
|
+
runGitCommits ? Promise.resolve(searchGitCommits({
|
|
164385
165135
|
db,
|
|
164386
165136
|
projectPath,
|
|
164387
165137
|
query: trimmedQuery,
|
|
164388
165138
|
limit: tierLimit,
|
|
164389
|
-
|
|
164390
|
-
|
|
164391
|
-
isEmbeddingRuntimeEnabled,
|
|
164392
|
-
signal: options.signal
|
|
164393
|
-
}) : Promise.resolve([])
|
|
165139
|
+
queryEmbedding
|
|
165140
|
+
})) : Promise.resolve([])
|
|
164394
165141
|
]);
|
|
164395
165142
|
const results = [...memoryResults, ...messageResults, ...gitCommitResults].sort(compareUnifiedResults).slice(0, limit);
|
|
164396
165143
|
const countRetrievals = options.countRetrievals ?? true;
|
|
@@ -164807,8 +165554,8 @@ function collectStaleReduceCallIds(messages, messageIdToMaxTag, toolAgeCutoff) {
|
|
|
164807
165554
|
return staleCallIds;
|
|
164808
165555
|
}
|
|
164809
165556
|
function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, preloadedTags) {
|
|
164810
|
-
const tags = preloadedTags ??
|
|
164811
|
-
const maxTag =
|
|
165557
|
+
const tags = preloadedTags ?? getActiveTagsBySession(db, sessionId);
|
|
165558
|
+
const maxTag = getMaxTagNumberBySession(db, sessionId);
|
|
164812
165559
|
const toolAgeCutoff = maxTag - config2.autoDropToolAge;
|
|
164813
165560
|
const protectedCutoff = maxTag - config2.protectedTags;
|
|
164814
165561
|
let droppedTools = 0;
|
|
@@ -165921,12 +166668,24 @@ function clearPiCompressorState(sessionId) {
|
|
|
165921
166668
|
init_logger();
|
|
165922
166669
|
function queueDropsForCompartmentalizedMessages(db, sessionId, upToMessageIndex) {
|
|
165923
166670
|
const tags = getTagsBySession(db, sessionId);
|
|
165924
|
-
const
|
|
166671
|
+
const { messageFileKeys, toolObservations } = getRawSessionTagKeysThrough(sessionId, upToMessageIndex);
|
|
165925
166672
|
let dropsQueued = 0;
|
|
165926
166673
|
for (const tag of tags) {
|
|
165927
166674
|
if (tag.status !== "active")
|
|
165928
166675
|
continue;
|
|
165929
|
-
if (
|
|
166676
|
+
if (tag.type === "tool") {
|
|
166677
|
+
const observedOwners = toolObservations.get(tag.messageId);
|
|
166678
|
+
if (!observedOwners)
|
|
166679
|
+
continue;
|
|
166680
|
+
if (tag.toolOwnerMessageId !== null) {
|
|
166681
|
+
if (!observedOwners.has(tag.toolOwnerMessageId))
|
|
166682
|
+
continue;
|
|
166683
|
+
}
|
|
166684
|
+
queuePendingOp(db, sessionId, tag.tagNumber, "drop");
|
|
166685
|
+
dropsQueued += 1;
|
|
166686
|
+
continue;
|
|
166687
|
+
}
|
|
166688
|
+
if (messageFileKeys.has(tag.messageId)) {
|
|
165930
166689
|
queuePendingOp(db, sessionId, tag.tagNumber, "drop");
|
|
165931
166690
|
dropsQueued += 1;
|
|
165932
166691
|
}
|
|
@@ -166134,15 +166893,15 @@ function getReducedRecompTokenBudget(currentBudget) {
|
|
|
166134
166893
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
166135
166894
|
import { mkdirSync as mkdirSync4, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
166136
166895
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
166137
|
-
import { join as
|
|
166896
|
+
import { join as join10 } from "node:path";
|
|
166138
166897
|
var HISTORIAN_STATE_INLINE_THRESHOLD = 30000;
|
|
166139
|
-
var HISTORIAN_STATE_DIR =
|
|
166898
|
+
var HISTORIAN_STATE_DIR = join10(tmpdir2(), "magic-context-historian");
|
|
166140
166899
|
function maybeWriteHistorianStateFile(sessionId, existingState) {
|
|
166141
166900
|
if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
|
|
166142
166901
|
return;
|
|
166143
166902
|
try {
|
|
166144
166903
|
mkdirSync4(HISTORIAN_STATE_DIR, { recursive: true });
|
|
166145
|
-
const path5 =
|
|
166904
|
+
const path5 = join10(HISTORIAN_STATE_DIR, `state-${sessionId}-${Date.now()}.xml`);
|
|
166146
166905
|
writeFileSync2(path5, existingState, "utf8");
|
|
166147
166906
|
return path5;
|
|
166148
166907
|
} catch {
|
|
@@ -166252,24 +167011,12 @@ ${chunk.text}`, { stateFilePath });
|
|
|
166252
167011
|
const maxExistingSequence = priorCompartments.reduce((max, c) => c.sequence > max ? c.sequence : max, -1);
|
|
166253
167012
|
const sequenceOffset = priorCompartments.length === 0 ? 0 : maxExistingSequence + 1;
|
|
166254
167013
|
sessionLog(sessionId, `pi-historian: invoking subagent (model=${historianModel}, chunk=${chunk.startIndex}-${chunk.endIndex}, ${chunk.messageCount} msgs, ~${chunk.tokenEstimate} tokens)`);
|
|
167014
|
+
const traceRawEvents = process.env.MC_PI_HISTORIAN_TRACE === "1";
|
|
166255
167015
|
const buildProgressLogger = (passLabel) => {
|
|
166256
167016
|
return (event) => {
|
|
166257
167017
|
try {
|
|
166258
|
-
if (event.type === "
|
|
166259
|
-
let serialized;
|
|
166260
|
-
try {
|
|
166261
|
-
serialized = JSON.stringify(event.event);
|
|
166262
|
-
} catch {
|
|
166263
|
-
serialized = "[unserializable]";
|
|
166264
|
-
}
|
|
166265
|
-
if (serialized.length > 4000) {
|
|
166266
|
-
serialized = `${serialized.slice(0, 4000)}…[truncated ${serialized.length - 4000} chars]`;
|
|
166267
|
-
}
|
|
166268
|
-
sessionLog(sessionId, `pi-historian[${passLabel}] raw_event @${event.ms}ms type=${event.eventType ?? "?"}: ${serialized}`);
|
|
166269
|
-
} else if (event.type === "spawned") {
|
|
167018
|
+
if (event.type === "spawned") {
|
|
166270
167019
|
sessionLog(sessionId, `pi-historian[${passLabel}] spawned pid=${event.pid ?? "?"} argv=${event.argv.length} args`);
|
|
166271
|
-
} else if (event.type === "first_event") {
|
|
166272
|
-
sessionLog(sessionId, `pi-historian[${passLabel}] first_event @${event.ms}ms type=${event.eventType}`);
|
|
166273
167020
|
} else if (event.type === "terminal") {
|
|
166274
167021
|
sessionLog(sessionId, `pi-historian[${passLabel}] terminal @${event.ms}ms stopReason=${event.stopReason ?? "?"} textLen=${event.textLength} hasToolCall=${event.hasToolCall}`);
|
|
166275
167022
|
} else if (event.type === "stderr") {
|
|
@@ -166279,6 +167026,21 @@ ${chunk.text}`, { stateFilePath });
|
|
|
166279
167026
|
}
|
|
166280
167027
|
} else if (event.type === "child_exit") {
|
|
166281
167028
|
sessionLog(sessionId, `pi-historian[${passLabel}] child_exit @${event.ms}ms code=${event.code} signal=${event.signal}`);
|
|
167029
|
+
} else if (traceRawEvents) {
|
|
167030
|
+
if (event.type === "raw_event") {
|
|
167031
|
+
let serialized;
|
|
167032
|
+
try {
|
|
167033
|
+
serialized = JSON.stringify(event.event);
|
|
167034
|
+
} catch {
|
|
167035
|
+
serialized = "[unserializable]";
|
|
167036
|
+
}
|
|
167037
|
+
if (serialized.length > 4000) {
|
|
167038
|
+
serialized = `${serialized.slice(0, 4000)}…[truncated ${serialized.length - 4000} chars]`;
|
|
167039
|
+
}
|
|
167040
|
+
sessionLog(sessionId, `pi-historian[${passLabel}] raw_event @${event.ms}ms type=${event.eventType ?? "?"}: ${serialized}`);
|
|
167041
|
+
} else if (event.type === "first_event") {
|
|
167042
|
+
sessionLog(sessionId, `pi-historian[${passLabel}] first_event @${event.ms}ms type=${event.eventType}`);
|
|
167043
|
+
}
|
|
166282
167044
|
}
|
|
166283
167045
|
} catch {}
|
|
166284
167046
|
};
|
|
@@ -166693,16 +167455,7 @@ function clearOldReasoningPi(args) {
|
|
|
166693
167455
|
return { cleared, newWatermark };
|
|
166694
167456
|
}
|
|
166695
167457
|
function replayClearedReasoningPi(args) {
|
|
166696
|
-
const {
|
|
166697
|
-
db,
|
|
166698
|
-
sessionId,
|
|
166699
|
-
messages,
|
|
166700
|
-
messageIdToMaxTag,
|
|
166701
|
-
piMessageStableId,
|
|
166702
|
-
skipTypedReasoningCleanup
|
|
166703
|
-
} = args;
|
|
166704
|
-
if (skipTypedReasoningCleanup)
|
|
166705
|
-
return 0;
|
|
167458
|
+
const { db, sessionId, messages, messageIdToMaxTag, piMessageStableId } = args;
|
|
166706
167459
|
const meta3 = getOrCreateSessionMeta(db, sessionId);
|
|
166707
167460
|
const watermark = meta3.clearedReasoningThroughTag ?? 0;
|
|
166708
167461
|
if (watermark <= 0)
|
|
@@ -167402,19 +168155,6 @@ var TOOL_HEAVY_TURN_REMINDER_THRESHOLD = 5;
|
|
|
167402
168155
|
var TOOL_HEAVY_TURN_REMINDER_TEXT = `
|
|
167403
168156
|
|
|
167404
168157
|
<instruction name="ctx_reduce_turn_cleanup">Also drop via \`ctx_reduce\` things you don't need anymore from the last turn before continuing.</instruction>`;
|
|
167405
|
-
function resolveLiveModelId(ctx) {
|
|
167406
|
-
const model = ctx.model;
|
|
167407
|
-
if (!model)
|
|
167408
|
-
return;
|
|
167409
|
-
const providerID = model.provider;
|
|
167410
|
-
const modelID = model.id;
|
|
167411
|
-
if (typeof providerID !== "string" || typeof modelID !== "string") {
|
|
167412
|
-
return;
|
|
167413
|
-
}
|
|
167414
|
-
if (providerID.length === 0 || modelID.length === 0)
|
|
167415
|
-
return;
|
|
167416
|
-
return { providerID, modelID };
|
|
167417
|
-
}
|
|
167418
168158
|
var DEFAULT_CLEAR_REASONING_AGE = 50;
|
|
167419
168159
|
var lastEmergencyNotificationAtMs = new Map;
|
|
167420
168160
|
var EMERGENCY_NOTIFICATION_COOLDOWN_MS = 60000;
|
|
@@ -167427,6 +168167,9 @@ var recentReduceBySession = new Map;
|
|
|
167427
168167
|
var liveModelBySession = new Map;
|
|
167428
168168
|
var toolUsageSinceUserTurn = new Map;
|
|
167429
168169
|
var latestUserMessageBySession = new Map;
|
|
168170
|
+
function readPiSessionMessageById(ctx, messageId) {
|
|
168171
|
+
return readPiSessionMessages(ctx).find((message) => message.id === messageId) ?? null;
|
|
168172
|
+
}
|
|
167430
168173
|
function signalPiHistoryRefresh(sessionId) {
|
|
167431
168174
|
historyRefreshSessions.add(sessionId);
|
|
167432
168175
|
}
|
|
@@ -167627,8 +168370,15 @@ function registerPiContextHandler(pi, options) {
|
|
|
167627
168370
|
return;
|
|
167628
168371
|
}
|
|
167629
168372
|
sessionIdForError = sessionId;
|
|
168373
|
+
const rawMessageProvider = {
|
|
168374
|
+
readMessages: () => readPiSessionMessages(ctx),
|
|
168375
|
+
readMessageById: (messageId) => readPiSessionMessageById(ctx, messageId)
|
|
168376
|
+
};
|
|
168377
|
+
setRawMessageProvider(sessionId, rawMessageProvider);
|
|
168378
|
+
scheduleReconciliation(options.db, sessionId, readRawSessionMessages);
|
|
167630
168379
|
const latestUserId = findLatestUserMessageIdPi(event.messages);
|
|
167631
168380
|
if (latestUserId) {
|
|
168381
|
+
scheduleIncrementalIndex(options.db, sessionId, latestUserId, (_sessionId, messageId) => readPiSessionMessageById(ctx, messageId));
|
|
167632
168382
|
const previousUserId = latestUserMessageBySession.get(sessionId);
|
|
167633
168383
|
if (previousUserId !== latestUserId) {
|
|
167634
168384
|
onPiNewUserMessage({ db: options.db, sessionId });
|
|
@@ -167691,8 +168441,6 @@ function registerPiContextHandler(pi, options) {
|
|
|
167691
168441
|
}
|
|
167692
168442
|
const isCacheBusting = historyRefreshSessions.has(sessionId);
|
|
167693
168443
|
sessionLog(sessionId, `pi transform: usage=${usagePercentage.toFixed(1)}% (${usageInputTokens} tokens, limit=${usageContextLimit ?? "?"}) decision=${schedulerDecision}${forceMaterialization ? " force=true" : ""}${isEmergency ? " EMERGENCY=true" : ""}${isCacheBusting ? " busting=true" : ""}`);
|
|
167694
|
-
const liveModelId = resolveLiveModelId(ctx);
|
|
167695
|
-
const skipTypedReasoningCleanup = liveModelId ? modelRequiresInterleavedReasoning(liveModelId) : false;
|
|
167696
168444
|
const entryIds = collectMessageEntryIds(ctx, event.messages.length, sessionId);
|
|
167697
168445
|
const result = await runPipeline({
|
|
167698
168446
|
db: options.db,
|
|
@@ -167709,8 +168457,7 @@ function registerPiContextHandler(pi, options) {
|
|
|
167709
168457
|
forceMaterialization: forceMaterialization || isEmergency,
|
|
167710
168458
|
isCacheBusting,
|
|
167711
168459
|
reasoningClearing: {
|
|
167712
|
-
clearReasoningAge: options.heuristics?.clearReasoningAge ?? DEFAULT_CLEAR_REASONING_AGE
|
|
167713
|
-
skipTypedReasoningCleanup
|
|
168460
|
+
clearReasoningAge: options.heuristics?.clearReasoningAge ?? DEFAULT_CLEAR_REASONING_AGE
|
|
167714
168461
|
},
|
|
167715
168462
|
temporalAwareness: options.injection?.temporalAwareness === true
|
|
167716
168463
|
});
|
|
@@ -168058,7 +168805,10 @@ async function runPipeline(args) {
|
|
|
168058
168805
|
consumePendingMaterialization(args.sessionId);
|
|
168059
168806
|
}
|
|
168060
168807
|
}
|
|
168061
|
-
|
|
168808
|
+
const flushedSliceTags = getTagsByNumbers(args.db, args.sessionId, [
|
|
168809
|
+
...targets.keys()
|
|
168810
|
+
]);
|
|
168811
|
+
applyFlushedStatuses(args.sessionId, args.db, targets, flushedSliceTags);
|
|
168062
168812
|
const messageIdToMaxTag = buildMessageIdToMaxTag(targets);
|
|
168063
168813
|
if (args.reasoningClearing) {
|
|
168064
168814
|
try {
|
|
@@ -168067,8 +168817,7 @@ async function runPipeline(args) {
|
|
|
168067
168817
|
sessionId: args.sessionId,
|
|
168068
168818
|
messages: args.messages,
|
|
168069
168819
|
messageIdToMaxTag,
|
|
168070
|
-
piMessageStableId
|
|
168071
|
-
skipTypedReasoningCleanup: args.reasoningClearing.skipTypedReasoningCleanup
|
|
168820
|
+
piMessageStableId
|
|
168072
168821
|
});
|
|
168073
168822
|
const inlineReplay = replayStrippedInlineThinkingPi({
|
|
168074
168823
|
db: args.db,
|
|
@@ -168085,7 +168834,8 @@ async function runPipeline(args) {
|
|
|
168085
168834
|
}
|
|
168086
168835
|
}
|
|
168087
168836
|
try {
|
|
168088
|
-
const
|
|
168837
|
+
const targetTagNumbers = [...targets.keys()];
|
|
168838
|
+
const tags = getTagsByNumbers(args.db, args.sessionId, targetTagNumbers);
|
|
168089
168839
|
const replayed = replayCavemanCompression(args.sessionId, args.db, targets, tags);
|
|
168090
168840
|
if (replayed > 0) {
|
|
168091
168841
|
sessionLog(args.sessionId, `pi caveman replay: ${replayed} tags re-compressed from source`);
|
|
@@ -168110,7 +168860,7 @@ async function runPipeline(args) {
|
|
|
168110
168860
|
sessionLog(args.sessionId, `pi heuristic cleanup failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
168111
168861
|
}
|
|
168112
168862
|
}
|
|
168113
|
-
if (args.reasoningClearing &&
|
|
168863
|
+
if (args.reasoningClearing && (args.schedulerDecision === "execute" || args.forceMaterialization === true)) {
|
|
168114
168864
|
try {
|
|
168115
168865
|
const clearOutcome = clearOldReasoningPi({
|
|
168116
168866
|
messages: args.messages,
|
|
@@ -168179,7 +168929,7 @@ function applyRollingNudge(args) {
|
|
|
168179
168929
|
inputTokens: piUsage.tokens,
|
|
168180
168930
|
contextLimit: piUsage.contextWindow
|
|
168181
168931
|
};
|
|
168182
|
-
const tags =
|
|
168932
|
+
const tags = getActiveTagsBySession(db, sessionId);
|
|
168183
168933
|
const messagesSinceLastUser = countMessagesSinceLastUserPi(messages);
|
|
168184
168934
|
const nudge = nudgerFn(sessionId, usage, db, getTopNBySize, tags, messagesSinceLastUser, undefined);
|
|
168185
168935
|
if (!nudge)
|
|
@@ -168309,6 +169059,7 @@ function clearContextHandlerSession(sessionId) {
|
|
|
168309
169059
|
liveModelBySession.delete(sessionId);
|
|
168310
169060
|
toolUsageSinceUserTurn.delete(sessionId);
|
|
168311
169061
|
latestUserMessageBySession.delete(sessionId);
|
|
169062
|
+
clearSessionTracking(sessionId);
|
|
168312
169063
|
clearPiCompressorState(sessionId);
|
|
168313
169064
|
}
|
|
168314
169065
|
|
|
@@ -168358,7 +169109,7 @@ init_logger();
|
|
|
168358
169109
|
init_data_path();
|
|
168359
169110
|
init_logger();
|
|
168360
169111
|
await init_sqlite();
|
|
168361
|
-
import { join as
|
|
169112
|
+
import { join as join11 } from "node:path";
|
|
168362
169113
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
168363
169114
|
function randomBase62(length) {
|
|
168364
169115
|
const chars = [];
|
|
@@ -168379,7 +169130,7 @@ function generatePartId(timestampMs, counter = 0n) {
|
|
|
168379
169130
|
return generateId("prt", timestampMs, counter);
|
|
168380
169131
|
}
|
|
168381
169132
|
function getOpenCodeDbPath3() {
|
|
168382
|
-
return
|
|
169133
|
+
return join11(getDataDir(), "opencode", "opencode.db");
|
|
168383
169134
|
}
|
|
168384
169135
|
var cachedWriteDb = null;
|
|
168385
169136
|
var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
@@ -168934,9 +169685,9 @@ async function runCompressorPass2(args) {
|
|
|
168934
169685
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
168935
169686
|
import { mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
168936
169687
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
168937
|
-
import { join as
|
|
169688
|
+
import { join as join12 } from "node:path";
|
|
168938
169689
|
init_magic_context();
|
|
168939
|
-
var HISTORIAN_RESPONSE_DUMP_DIR =
|
|
169690
|
+
var HISTORIAN_RESPONSE_DUMP_DIR = join12(tmpdir3(), "magic-context-historian");
|
|
168940
169691
|
var MAX_HISTORIAN_RETRIES = 2;
|
|
168941
169692
|
async function runValidatedHistorianPass(args) {
|
|
168942
169693
|
const firstRun = await runHistorianPrompt({
|
|
@@ -169180,7 +169931,7 @@ function dumpHistorianResponse(sessionId, label, text) {
|
|
|
169180
169931
|
mkdirSync5(HISTORIAN_RESPONSE_DUMP_DIR, { recursive: true });
|
|
169181
169932
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
169182
169933
|
const safeLabel = sanitizeDumpName(label);
|
|
169183
|
-
const dumpPath =
|
|
169934
|
+
const dumpPath = join12(HISTORIAN_RESPONSE_DUMP_DIR, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
169184
169935
|
writeFileSync3(dumpPath, text, "utf8");
|
|
169185
169936
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
169186
169937
|
label,
|
|
@@ -170348,7 +171099,7 @@ import {
|
|
|
170348
171099
|
// package.json
|
|
170349
171100
|
var package_default = {
|
|
170350
171101
|
name: "@cortexkit/pi-magic-context",
|
|
170351
|
-
version: "0.
|
|
171102
|
+
version: "0.17.0",
|
|
170352
171103
|
type: "module",
|
|
170353
171104
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
170354
171105
|
main: "dist/index.js",
|
|
@@ -170885,12 +171636,12 @@ function readHistorianState(db, sessionId, meta3) {
|
|
|
170885
171636
|
|
|
170886
171637
|
// src/config/index.ts
|
|
170887
171638
|
init_magic_context();
|
|
170888
|
-
import { existsSync as
|
|
171639
|
+
import { existsSync as existsSync8, readFileSync as readFileSync3 } from "node:fs";
|
|
170889
171640
|
import { homedir as homedir4 } from "node:os";
|
|
170890
|
-
import { join as
|
|
171641
|
+
import { join as join13 } from "node:path";
|
|
170891
171642
|
|
|
170892
171643
|
// ../plugin/src/config/variable.ts
|
|
170893
|
-
import { existsSync as
|
|
171644
|
+
import { existsSync as existsSync7, readFileSync as readFileSync2 } from "node:fs";
|
|
170894
171645
|
import { homedir as homedir3 } from "node:os";
|
|
170895
171646
|
import { dirname as dirname3, isAbsolute, resolve } from "node:path";
|
|
170896
171647
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
@@ -170933,7 +171684,7 @@ function substituteConfigVariables(input) {
|
|
|
170933
171684
|
} else if (!isAbsolute(filePath)) {
|
|
170934
171685
|
filePath = resolve(configDir, filePath);
|
|
170935
171686
|
}
|
|
170936
|
-
if (!
|
|
171687
|
+
if (!existsSync7(filePath)) {
|
|
170937
171688
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
170938
171689
|
continue;
|
|
170939
171690
|
}
|
|
@@ -170955,16 +171706,16 @@ function substituteConfigVariables(input) {
|
|
|
170955
171706
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
170956
171707
|
var CONFIG_FILE_NAME = "magic-context";
|
|
170957
171708
|
function getProjectConfigPaths(cwd) {
|
|
170958
|
-
const basePath =
|
|
171709
|
+
const basePath = join13(cwd, ".pi", CONFIG_FILE_NAME);
|
|
170959
171710
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
170960
171711
|
}
|
|
170961
171712
|
function getUserConfigPaths() {
|
|
170962
171713
|
const home = process.env.HOME ?? homedir4();
|
|
170963
|
-
const basePath =
|
|
171714
|
+
const basePath = join13(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
170964
171715
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
170965
171716
|
}
|
|
170966
171717
|
function resolveFirstExisting(paths) {
|
|
170967
|
-
return paths.find((path5) =>
|
|
171718
|
+
return paths.find((path5) => existsSync8(path5));
|
|
170968
171719
|
}
|
|
170969
171720
|
function loadConfigFile(path5, scope) {
|
|
170970
171721
|
try {
|
|
@@ -171116,8 +171867,8 @@ function stripTagPrefixFromAssistantMessage(message) {
|
|
|
171116
171867
|
|
|
171117
171868
|
// src/system-prompt.ts
|
|
171118
171869
|
import { createHash as createHash4 } from "node:crypto";
|
|
171119
|
-
import { existsSync as
|
|
171120
|
-
import { join as
|
|
171870
|
+
import { existsSync as existsSync9, readFileSync as readFileSync4, realpathSync } from "node:fs";
|
|
171871
|
+
import { join as join14, resolve as resolve2, sep } from "node:path";
|
|
171121
171872
|
|
|
171122
171873
|
// ../plugin/src/agents/magic-context-prompt.ts
|
|
171123
171874
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
@@ -171219,9 +171970,9 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
171219
171970
|
function readProjectDocs(directory) {
|
|
171220
171971
|
const sections = [];
|
|
171221
171972
|
for (const filename of DOC_FILES) {
|
|
171222
|
-
const filePath =
|
|
171973
|
+
const filePath = join14(directory, filename);
|
|
171223
171974
|
try {
|
|
171224
|
-
if (
|
|
171975
|
+
if (existsSync9(filePath)) {
|
|
171225
171976
|
const content = readFileSync4(filePath, "utf-8").trim();
|
|
171226
171977
|
if (content.length > 0) {
|
|
171227
171978
|
sections.push(`<${filename}>
|
|
@@ -171265,7 +172016,7 @@ function buildKeyFilesBlock(db, sessionId, directory, tokenBudget) {
|
|
|
171265
172016
|
log(`[magic-context-pi] key file path escapes project root, skipping: ${entry.filePath}`);
|
|
171266
172017
|
continue;
|
|
171267
172018
|
}
|
|
171268
|
-
if (!
|
|
172019
|
+
if (!existsSync9(absPath))
|
|
171269
172020
|
continue;
|
|
171270
172021
|
let realPath;
|
|
171271
172022
|
try {
|
|
@@ -176447,7 +177198,7 @@ function resolveDreamerFromConfig(config2) {
|
|
|
176447
177198
|
}
|
|
176448
177199
|
async function src_default2(pi) {
|
|
176449
177200
|
const storageDir = getMagicContextStorageDir();
|
|
176450
|
-
const dbPath =
|
|
177201
|
+
const dbPath = join15(storageDir, "context.db");
|
|
176451
177202
|
let db;
|
|
176452
177203
|
try {
|
|
176453
177204
|
db = openDatabase();
|
|
@@ -176701,6 +177452,11 @@ ${block}` : event.systemPrompt;
|
|
|
176701
177452
|
const sessionId = sm?.getSessionId?.();
|
|
176702
177453
|
if (typeof sessionId !== "string" || sessionId.length === 0)
|
|
176703
177454
|
return;
|
|
177455
|
+
const rawMessages = readPiSessionMessages(ctx);
|
|
177456
|
+
const latest = rawMessages[rawMessages.length - 1];
|
|
177457
|
+
if (latest?.role === "assistant" && latest.id.length > 0) {
|
|
177458
|
+
scheduleIncrementalIndex(db, sessionId, latest.id, () => latest);
|
|
177459
|
+
}
|
|
176704
177460
|
persistPiMessageEndModelMeta({
|
|
176705
177461
|
db,
|
|
176706
177462
|
sessionId,
|