@cortexkit/opencode-magic-context 0.16.2 → 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/README.md +8 -8
- package/dist/features/magic-context/message-index-async.d.ts +12 -0
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts +4 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts +7 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +2 -2
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +3 -6
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +163 -1
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +52 -2
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +26 -3
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts +90 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/types.d.ts +17 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/cache.d.ts +12 -1
- package/dist/hooks/auto-update-checker/cache.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +23 -0
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +8 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +6 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +16 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/live-session-state.d.ts +13 -0
- package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +24 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +1 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +1 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +9 -6
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +16 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +0 -11
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +7 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2073 -768
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +3 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts +3 -10
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/native-binding.d.ts +87 -0
- package/dist/shared/native-binding.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +0 -12
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/shared/conflict-detector.ts +1 -1
- package/src/shared/models-dev-cache.test.ts +64 -57
- package/src/shared/models-dev-cache.ts +49 -68
- package/src/shared/native-binding.ts +311 -0
- package/src/shared/sqlite.ts +57 -14
- package/src/shared/tag-transcript.ts +137 -126
- package/src/tui/index.tsx +2 -2
- package/dist/hooks/magic-context/reasoning-capability.d.ts +0 -23
- package/dist/hooks/magic-context/reasoning-capability.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -147149,6 +147149,74 @@ var init_read_session_formatting = __esm(() => {
|
|
|
147149
147149
|
tokenizer = new src_default(exports_claude);
|
|
147150
147150
|
});
|
|
147151
147151
|
|
|
147152
|
+
// src/features/magic-context/tool-definition-tokens.ts
|
|
147153
|
+
function keyFor(providerID, modelID, agentName) {
|
|
147154
|
+
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
147155
|
+
return `${providerID}/${modelID}/${agent}`;
|
|
147156
|
+
}
|
|
147157
|
+
function setDatabase(db) {
|
|
147158
|
+
persistenceDb = db;
|
|
147159
|
+
}
|
|
147160
|
+
function loadToolDefinitionMeasurements(db) {
|
|
147161
|
+
let rows = [];
|
|
147162
|
+
try {
|
|
147163
|
+
rows = db.prepare("SELECT provider_id, model_id, agent_name, tool_id, token_count FROM tool_definition_measurements").all();
|
|
147164
|
+
} catch {
|
|
147165
|
+
return;
|
|
147166
|
+
}
|
|
147167
|
+
for (const row of rows) {
|
|
147168
|
+
const key = keyFor(row.provider_id, row.model_id, row.agent_name);
|
|
147169
|
+
let inner = measurements.get(key);
|
|
147170
|
+
if (!inner) {
|
|
147171
|
+
inner = new Map;
|
|
147172
|
+
measurements.set(key, inner);
|
|
147173
|
+
}
|
|
147174
|
+
inner.set(row.tool_id, row.token_count);
|
|
147175
|
+
}
|
|
147176
|
+
}
|
|
147177
|
+
function recordToolDefinition(providerID, modelID, agentName, toolID, description, parameters) {
|
|
147178
|
+
if (!providerID || !modelID || !toolID)
|
|
147179
|
+
return;
|
|
147180
|
+
const key = keyFor(providerID, modelID, agentName);
|
|
147181
|
+
let paramsText = "";
|
|
147182
|
+
try {
|
|
147183
|
+
paramsText = parameters === undefined ? "" : JSON.stringify(parameters);
|
|
147184
|
+
} catch {
|
|
147185
|
+
paramsText = "";
|
|
147186
|
+
}
|
|
147187
|
+
const tokens = estimateTokens(description ?? "") + estimateTokens(paramsText);
|
|
147188
|
+
let inner = measurements.get(key);
|
|
147189
|
+
if (!inner) {
|
|
147190
|
+
inner = new Map;
|
|
147191
|
+
measurements.set(key, inner);
|
|
147192
|
+
}
|
|
147193
|
+
inner.set(toolID, tokens);
|
|
147194
|
+
if (persistenceDb) {
|
|
147195
|
+
try {
|
|
147196
|
+
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
147197
|
+
persistenceDb.prepare(`INSERT OR REPLACE INTO tool_definition_measurements
|
|
147198
|
+
(provider_id, model_id, agent_name, tool_id, token_count, recorded_at)
|
|
147199
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(providerID, modelID, agent, toolID, tokens, Date.now());
|
|
147200
|
+
} catch {}
|
|
147201
|
+
}
|
|
147202
|
+
}
|
|
147203
|
+
function getMeasuredToolDefinitionTokens(providerID, modelID, agentName) {
|
|
147204
|
+
if (!providerID || !modelID)
|
|
147205
|
+
return;
|
|
147206
|
+
const inner = measurements.get(keyFor(providerID, modelID, agentName));
|
|
147207
|
+
if (!inner || inner.size === 0)
|
|
147208
|
+
return;
|
|
147209
|
+
let total = 0;
|
|
147210
|
+
for (const tokens of inner.values())
|
|
147211
|
+
total += tokens;
|
|
147212
|
+
return total;
|
|
147213
|
+
}
|
|
147214
|
+
var measurements, persistenceDb = null;
|
|
147215
|
+
var init_tool_definition_tokens = __esm(() => {
|
|
147216
|
+
init_read_session_formatting();
|
|
147217
|
+
measurements = new Map;
|
|
147218
|
+
});
|
|
147219
|
+
|
|
147152
147220
|
// ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
|
|
147153
147221
|
var require_esprima = __commonJS((exports, module) => {
|
|
147154
147222
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
@@ -155708,7 +155776,7 @@ function formatConflictShort(result) {
|
|
|
155708
155776
|
"",
|
|
155709
155777
|
...result.reasons.map((r) => `• ${r}`),
|
|
155710
155778
|
"",
|
|
155711
|
-
"Fix: run `
|
|
155779
|
+
"Fix: run `npx @cortexkit/opencode-magic-context@latest doctor`"
|
|
155712
155780
|
];
|
|
155713
155781
|
return lines.join(`
|
|
155714
155782
|
`);
|
|
@@ -156108,14 +156176,334 @@ function safeString(value) {
|
|
|
156108
156176
|
}
|
|
156109
156177
|
}
|
|
156110
156178
|
|
|
156179
|
+
// ../../node_modules/.bun/nanotar@0.3.0/node_modules/nanotar/dist/index.mjs
|
|
156180
|
+
function parseTar(data, opts) {
|
|
156181
|
+
const buffer2 = data.buffer || data;
|
|
156182
|
+
const files = [];
|
|
156183
|
+
let offset = 0;
|
|
156184
|
+
let nextExtendedHeader;
|
|
156185
|
+
let globalExtendedHeader;
|
|
156186
|
+
while (offset < buffer2.byteLength - 512) {
|
|
156187
|
+
let name2 = _readString(buffer2, offset, 100);
|
|
156188
|
+
if (name2.length === 0) {
|
|
156189
|
+
break;
|
|
156190
|
+
}
|
|
156191
|
+
if (nextExtendedHeader) {
|
|
156192
|
+
const longName = nextExtendedHeader.path || nextExtendedHeader.linkpath;
|
|
156193
|
+
if (longName) {
|
|
156194
|
+
name2 = longName;
|
|
156195
|
+
}
|
|
156196
|
+
}
|
|
156197
|
+
const mode = _readString(buffer2, offset + 100, 8).trim();
|
|
156198
|
+
const uid = Number.parseInt(_readString(buffer2, offset + 108, 8));
|
|
156199
|
+
const gid = Number.parseInt(_readString(buffer2, offset + 116, 8));
|
|
156200
|
+
const size = _readNumber(buffer2, offset + 124, 12);
|
|
156201
|
+
const seek = 512 + 512 * Math.trunc(size / 512) + (size % 512 ? 512 : 0);
|
|
156202
|
+
const mtime = _readNumber(buffer2, offset + 136, 12);
|
|
156203
|
+
const _type = _readString(buffer2, offset + 156, 1) || "0";
|
|
156204
|
+
const type = tarItemTypeMap[_type] || _type;
|
|
156205
|
+
switch (type) {
|
|
156206
|
+
case "extendedHeader":
|
|
156207
|
+
case "globalExtendedHeader": {
|
|
156208
|
+
const headers = _parseExtendedHeaders(new Uint8Array(buffer2, offset + 512, size));
|
|
156209
|
+
if (type === "extendedHeader") {
|
|
156210
|
+
nextExtendedHeader = headers;
|
|
156211
|
+
} else {
|
|
156212
|
+
nextExtendedHeader = undefined;
|
|
156213
|
+
globalExtendedHeader = {
|
|
156214
|
+
...globalExtendedHeader,
|
|
156215
|
+
...headers
|
|
156216
|
+
};
|
|
156217
|
+
}
|
|
156218
|
+
offset += seek;
|
|
156219
|
+
continue;
|
|
156220
|
+
}
|
|
156221
|
+
case "gnuLongFileName":
|
|
156222
|
+
case "gnuOldLongFileName":
|
|
156223
|
+
case "gnuLongLinkName": {
|
|
156224
|
+
nextExtendedHeader = { path: _readString(buffer2, offset + 512, size) };
|
|
156225
|
+
offset += seek;
|
|
156226
|
+
continue;
|
|
156227
|
+
}
|
|
156228
|
+
}
|
|
156229
|
+
const user = _readString(buffer2, offset + 265, 32);
|
|
156230
|
+
const group = _readString(buffer2, offset + 297, 32);
|
|
156231
|
+
name2 = _sanitizePath(name2);
|
|
156232
|
+
const meta3 = {
|
|
156233
|
+
name: name2,
|
|
156234
|
+
type,
|
|
156235
|
+
size,
|
|
156236
|
+
attrs: {
|
|
156237
|
+
...globalExtendedHeader,
|
|
156238
|
+
...nextExtendedHeader,
|
|
156239
|
+
mode,
|
|
156240
|
+
uid,
|
|
156241
|
+
gid,
|
|
156242
|
+
mtime,
|
|
156243
|
+
user,
|
|
156244
|
+
group
|
|
156245
|
+
}
|
|
156246
|
+
};
|
|
156247
|
+
nextExtendedHeader = undefined;
|
|
156248
|
+
if (opts?.filter && !opts.filter(meta3)) {
|
|
156249
|
+
offset += seek;
|
|
156250
|
+
continue;
|
|
156251
|
+
}
|
|
156252
|
+
if (opts?.metaOnly) {
|
|
156253
|
+
files.push(meta3);
|
|
156254
|
+
offset += seek;
|
|
156255
|
+
continue;
|
|
156256
|
+
}
|
|
156257
|
+
const data2 = size === 0 ? undefined : new Uint8Array(buffer2, offset + 512, size);
|
|
156258
|
+
files.push({
|
|
156259
|
+
...meta3,
|
|
156260
|
+
data: data2,
|
|
156261
|
+
get text() {
|
|
156262
|
+
return new TextDecoder().decode(this.data);
|
|
156263
|
+
}
|
|
156264
|
+
});
|
|
156265
|
+
offset += seek;
|
|
156266
|
+
}
|
|
156267
|
+
return files;
|
|
156268
|
+
}
|
|
156269
|
+
async function parseTarGzip(data, opts = {}) {
|
|
156270
|
+
const stream = new ReadableStream({
|
|
156271
|
+
start(controller) {
|
|
156272
|
+
controller.enqueue(new Uint8Array(data));
|
|
156273
|
+
controller.close();
|
|
156274
|
+
}
|
|
156275
|
+
}).pipeThrough(new DecompressionStream(opts.compression ?? "gzip"));
|
|
156276
|
+
const decompressedData = await new Response(stream).arrayBuffer();
|
|
156277
|
+
return parseTar(decompressedData, opts);
|
|
156278
|
+
}
|
|
156279
|
+
function _sanitizePath(path3) {
|
|
156280
|
+
let normalized = path3.replace(/\\/g, "/");
|
|
156281
|
+
normalized = normalized.replace(/^[a-zA-Z]:\//, "");
|
|
156282
|
+
normalized = normalized.replace(/^\/+/, "");
|
|
156283
|
+
const hasLeadingDotSlash = normalized.startsWith("./");
|
|
156284
|
+
const parts = normalized.split("/");
|
|
156285
|
+
const resolved = [];
|
|
156286
|
+
for (const part of parts) {
|
|
156287
|
+
if (part === "..") {
|
|
156288
|
+
resolved.pop();
|
|
156289
|
+
} else if (part !== "." && part !== "") {
|
|
156290
|
+
resolved.push(part);
|
|
156291
|
+
}
|
|
156292
|
+
}
|
|
156293
|
+
let result = resolved.join("/");
|
|
156294
|
+
if (hasLeadingDotSlash && !result.startsWith("./")) {
|
|
156295
|
+
result = "./" + result;
|
|
156296
|
+
}
|
|
156297
|
+
if (path3.endsWith("/") && !result.endsWith("/")) {
|
|
156298
|
+
result += "/";
|
|
156299
|
+
}
|
|
156300
|
+
return result;
|
|
156301
|
+
}
|
|
156302
|
+
function _readString(buffer2, offset, size) {
|
|
156303
|
+
const view = new Uint8Array(buffer2, offset, size);
|
|
156304
|
+
const i = view.indexOf(0);
|
|
156305
|
+
const td = new TextDecoder;
|
|
156306
|
+
return td.decode(i === -1 ? view : view.slice(0, i));
|
|
156307
|
+
}
|
|
156308
|
+
function _readNumber(buffer2, offset, size) {
|
|
156309
|
+
const view = new Uint8Array(buffer2, offset, size);
|
|
156310
|
+
let str = "";
|
|
156311
|
+
for (let i = 0;i < size; i++) {
|
|
156312
|
+
str += String.fromCodePoint(view[i]);
|
|
156313
|
+
}
|
|
156314
|
+
return Number.parseInt(str, 8);
|
|
156315
|
+
}
|
|
156316
|
+
function _parseExtendedHeaders(data) {
|
|
156317
|
+
const dataStr = new TextDecoder().decode(data);
|
|
156318
|
+
const headers = {};
|
|
156319
|
+
for (const line of dataStr.split(`
|
|
156320
|
+
`)) {
|
|
156321
|
+
const s = line.split(" ")[1]?.split("=");
|
|
156322
|
+
if (s) {
|
|
156323
|
+
headers[s[0]] = s[1];
|
|
156324
|
+
}
|
|
156325
|
+
}
|
|
156326
|
+
return headers;
|
|
156327
|
+
}
|
|
156328
|
+
var tarItemTypeMap;
|
|
156329
|
+
var init_dist2 = __esm(() => {
|
|
156330
|
+
tarItemTypeMap = {
|
|
156331
|
+
"0": "file",
|
|
156332
|
+
"1": "hardLink",
|
|
156333
|
+
"2": "symbolicLink",
|
|
156334
|
+
"3": "characterDevice",
|
|
156335
|
+
"4": "blockDevice",
|
|
156336
|
+
"5": "directory",
|
|
156337
|
+
"6": "fifo",
|
|
156338
|
+
"7": "contiguousFile",
|
|
156339
|
+
g: "globalExtendedHeader",
|
|
156340
|
+
x: "extendedHeader",
|
|
156341
|
+
D: "gnuDirectory",
|
|
156342
|
+
I: "gnuInodeMetadata",
|
|
156343
|
+
K: "gnuLongLinkName",
|
|
156344
|
+
L: "gnuLongFileName",
|
|
156345
|
+
N: "gnuOldLongFileName",
|
|
156346
|
+
M: "gnuMultiVolume",
|
|
156347
|
+
S: "gnuSparseFile",
|
|
156348
|
+
E: "gnuExtendedSparse",
|
|
156349
|
+
A: "solarisAcl",
|
|
156350
|
+
V: "solarisVolumeLabel",
|
|
156351
|
+
X: "solarisOldExtendedHeader"
|
|
156352
|
+
};
|
|
156353
|
+
});
|
|
156354
|
+
|
|
156355
|
+
// src/shared/native-binding.ts
|
|
156356
|
+
var exports_native_binding = {};
|
|
156357
|
+
__export(exports_native_binding, {
|
|
156358
|
+
resolveBetterSqliteNativeBinding: () => resolveBetterSqliteNativeBinding
|
|
156359
|
+
});
|
|
156360
|
+
import { existsSync as existsSync7, mkdirSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
156361
|
+
import { createRequire } from "node:module";
|
|
156362
|
+
import * as path3 from "node:path";
|
|
156363
|
+
function logInfo(message) {
|
|
156364
|
+
log(`${PREFIX} ${message}`);
|
|
156365
|
+
}
|
|
156366
|
+
function logWarn(message) {
|
|
156367
|
+
log(`${PREFIX} WARN ${message}`);
|
|
156368
|
+
}
|
|
156369
|
+
function probeAbi(binaryPath) {
|
|
156370
|
+
const expected = process.versions.modules;
|
|
156371
|
+
try {
|
|
156372
|
+
const sandbox = { exports: {} };
|
|
156373
|
+
process.dlopen(sandbox, binaryPath);
|
|
156374
|
+
return { ok: true };
|
|
156375
|
+
} catch (err) {
|
|
156376
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
156377
|
+
const pair = message.match(/NODE_MODULE_VERSION (\d+).*NODE_MODULE_VERSION (\d+)/s);
|
|
156378
|
+
if (pair?.[1] && pair[2]) {
|
|
156379
|
+
return { ok: false, expected: pair[2], actual: pair[1] };
|
|
156380
|
+
}
|
|
156381
|
+
const single = message.match(/NODE_MODULE_VERSION[ =:]+(\d+)/);
|
|
156382
|
+
if (single?.[1]) {
|
|
156383
|
+
return { ok: false, expected, actual: single[1] };
|
|
156384
|
+
}
|
|
156385
|
+
logWarn(`could not parse ABI from dlopen error: ${message}`);
|
|
156386
|
+
return { ok: false, expected, actual: null };
|
|
156387
|
+
}
|
|
156388
|
+
}
|
|
156389
|
+
function resolveBetterSqlite3OnDisk(requireFn) {
|
|
156390
|
+
try {
|
|
156391
|
+
const pkgJsonPath = requireFn.resolve("better-sqlite3/package.json");
|
|
156392
|
+
const pkgDir = path3.dirname(pkgJsonPath);
|
|
156393
|
+
const pkgJson = requireFn(pkgJsonPath);
|
|
156394
|
+
const binaryPath = path3.join(pkgDir, "build", "Release", "better_sqlite3.node");
|
|
156395
|
+
return { binaryPath, pkgVersion: pkgJson.version };
|
|
156396
|
+
} catch (err) {
|
|
156397
|
+
logWarn(`could not resolve better-sqlite3 in node_modules: ${err instanceof Error ? err.message : String(err)}`);
|
|
156398
|
+
return null;
|
|
156399
|
+
}
|
|
156400
|
+
}
|
|
156401
|
+
function getCachedBinaryPath(pkgVersion, abi) {
|
|
156402
|
+
return path3.join(getCacheDir(), "cortexkit", "native-bindings", "better-sqlite3", `v${pkgVersion}`, `electron-v${abi}-${process.platform}-${process.arch}`, "better_sqlite3.node");
|
|
156403
|
+
}
|
|
156404
|
+
async function downloadElectronPrebuild(pkgVersion, abi) {
|
|
156405
|
+
const filename = `better-sqlite3-v${pkgVersion}-electron-v${abi}-${process.platform}-${process.arch}.tar.gz`;
|
|
156406
|
+
const url2 = `https://github.com/WiseLibs/better-sqlite3/releases/download/v${pkgVersion}/${filename}`;
|
|
156407
|
+
logInfo(`downloading ${url2}`);
|
|
156408
|
+
const response = await fetch(url2, {
|
|
156409
|
+
redirect: "follow",
|
|
156410
|
+
headers: { "User-Agent": "magic-context-plugin/native-binding" }
|
|
156411
|
+
});
|
|
156412
|
+
if (!response.ok) {
|
|
156413
|
+
throw new Error(`failed to download Electron prebuild (HTTP ${response.status} ${response.statusText}) from ${url2}`);
|
|
156414
|
+
}
|
|
156415
|
+
const tarballBytes = new Uint8Array(await response.arrayBuffer());
|
|
156416
|
+
logInfo(`downloaded ${(tarballBytes.length / 1024).toFixed(1)} KB; extracting`);
|
|
156417
|
+
const files = await parseTarGzip(tarballBytes);
|
|
156418
|
+
const nodeFile = files.find((f) => f.name.endsWith("better_sqlite3.node"));
|
|
156419
|
+
if (!nodeFile?.data) {
|
|
156420
|
+
const names = files.map((f) => f.name).join(", ");
|
|
156421
|
+
throw new Error(`Electron prebuild tarball did not contain better_sqlite3.node; got: [${names}]`);
|
|
156422
|
+
}
|
|
156423
|
+
return nodeFile.data instanceof Uint8Array ? nodeFile.data : new Uint8Array(nodeFile.data);
|
|
156424
|
+
}
|
|
156425
|
+
async function resolveBetterSqliteNativeBinding() {
|
|
156426
|
+
if (!process.versions.electron) {
|
|
156427
|
+
return null;
|
|
156428
|
+
}
|
|
156429
|
+
if (inFlight) {
|
|
156430
|
+
return inFlight;
|
|
156431
|
+
}
|
|
156432
|
+
const promise2 = (async () => {
|
|
156433
|
+
const expected = process.versions.modules;
|
|
156434
|
+
logInfo(`Electron detected (v${process.versions.electron}, NODE_MODULE_VERSION ${expected}); verifying better-sqlite3 binding`);
|
|
156435
|
+
const requireFn = createRequire(import.meta.url);
|
|
156436
|
+
const resolved = resolveBetterSqlite3OnDisk(requireFn);
|
|
156437
|
+
if (!resolved) {
|
|
156438
|
+
return null;
|
|
156439
|
+
}
|
|
156440
|
+
const { binaryPath: diskPath, pkgVersion } = resolved;
|
|
156441
|
+
if (existsSync7(diskPath)) {
|
|
156442
|
+
const diskProbe = probeAbi(diskPath);
|
|
156443
|
+
if (diskProbe.ok) {
|
|
156444
|
+
logInfo(`on-disk binary already matches Electron ABI v${expected}; using default bindings() lookup`);
|
|
156445
|
+
return null;
|
|
156446
|
+
}
|
|
156447
|
+
logInfo(`on-disk binary ABI ${diskProbe.actual ?? "unknown"} != required ${expected}; will use Electron prebuild`);
|
|
156448
|
+
} else {
|
|
156449
|
+
logWarn(`expected better-sqlite3 binary not found at ${diskPath}; will fetch Electron prebuild anyway`);
|
|
156450
|
+
}
|
|
156451
|
+
const cachedPath = getCachedBinaryPath(pkgVersion, expected);
|
|
156452
|
+
if (existsSync7(cachedPath)) {
|
|
156453
|
+
const cachedProbe = probeAbi(cachedPath);
|
|
156454
|
+
if (cachedProbe.ok) {
|
|
156455
|
+
logInfo(`using cached Electron prebuild at ${cachedPath}`);
|
|
156456
|
+
return cachedPath;
|
|
156457
|
+
}
|
|
156458
|
+
logWarn(`cached binary at ${cachedPath} has wrong ABI (${cachedProbe.actual ?? "unknown"} != ${expected}); refetching`);
|
|
156459
|
+
}
|
|
156460
|
+
mkdirSync(path3.dirname(cachedPath), { recursive: true });
|
|
156461
|
+
const nodeFileBytes = await downloadElectronPrebuild(pkgVersion, expected);
|
|
156462
|
+
writeFileSync3(cachedPath, nodeFileBytes);
|
|
156463
|
+
logInfo(`cached Electron prebuild at ${cachedPath} (${(nodeFileBytes.length / 1024).toFixed(1)} KB)`);
|
|
156464
|
+
const finalProbe = probeAbi(cachedPath);
|
|
156465
|
+
if (!finalProbe.ok) {
|
|
156466
|
+
throw new Error(`downloaded Electron prebuild has wrong ABI (${finalProbe.actual ?? "unknown"} != ${expected}); refusing to use`);
|
|
156467
|
+
}
|
|
156468
|
+
return cachedPath;
|
|
156469
|
+
})();
|
|
156470
|
+
inFlight = promise2;
|
|
156471
|
+
try {
|
|
156472
|
+
return await promise2;
|
|
156473
|
+
} finally {
|
|
156474
|
+
if (inFlight === promise2) {
|
|
156475
|
+
inFlight = null;
|
|
156476
|
+
}
|
|
156477
|
+
}
|
|
156478
|
+
}
|
|
156479
|
+
var PREFIX = "[native-binding]", inFlight = null;
|
|
156480
|
+
var init_native_binding = __esm(() => {
|
|
156481
|
+
init_dist2();
|
|
156482
|
+
init_data_path();
|
|
156483
|
+
init_logger();
|
|
156484
|
+
});
|
|
156485
|
+
|
|
156111
156486
|
// src/shared/sqlite.ts
|
|
156112
|
-
var isBun, bunSpec, betterSpec, sqliteModule, DatabaseImpl, Database;
|
|
156487
|
+
var isBun, bunSpec, betterSpec, electronNativeBinding, sqliteModule, RawDatabaseImpl, DatabaseImpl, Database;
|
|
156113
156488
|
var init_sqlite = __esm(async () => {
|
|
156114
156489
|
isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
156115
156490
|
bunSpec = "bun:" + "sqlite";
|
|
156116
156491
|
betterSpec = "better-" + "sqlite3";
|
|
156492
|
+
electronNativeBinding = isBun ? null : await (async () => {
|
|
156493
|
+
const mod = await Promise.resolve().then(() => (init_native_binding(), exports_native_binding));
|
|
156494
|
+
return mod.resolveBetterSqliteNativeBinding();
|
|
156495
|
+
})();
|
|
156117
156496
|
sqliteModule = isBun ? await import(bunSpec) : await import(betterSpec);
|
|
156118
|
-
|
|
156497
|
+
RawDatabaseImpl = isBun ? sqliteModule.Database : sqliteModule.default;
|
|
156498
|
+
DatabaseImpl = electronNativeBinding == null ? RawDatabaseImpl : class DatabaseWithElectronBinding extends RawDatabaseImpl {
|
|
156499
|
+
constructor(filename, options) {
|
|
156500
|
+
const fallback = electronNativeBinding;
|
|
156501
|
+
super(filename, {
|
|
156502
|
+
...options,
|
|
156503
|
+
nativeBinding: options?.nativeBinding ?? fallback
|
|
156504
|
+
});
|
|
156505
|
+
}
|
|
156506
|
+
};
|
|
156119
156507
|
Database = DatabaseImpl;
|
|
156120
156508
|
});
|
|
156121
156509
|
|
|
@@ -156847,9 +157235,9 @@ __export(exports_read_session_db, {
|
|
|
156847
157235
|
findLastAssistantModelFromOpenCodeDb: () => findLastAssistantModelFromOpenCodeDb,
|
|
156848
157236
|
closeReadOnlySessionDb: () => closeReadOnlySessionDb
|
|
156849
157237
|
});
|
|
156850
|
-
import { join as
|
|
157238
|
+
import { join as join11 } from "node:path";
|
|
156851
157239
|
function getOpenCodeDbPath() {
|
|
156852
|
-
return
|
|
157240
|
+
return join11(getDataDir(), "opencode", "opencode.db");
|
|
156853
157241
|
}
|
|
156854
157242
|
function closeCachedReadOnlyDb() {
|
|
156855
157243
|
if (!cachedReadOnlyDb) {
|
|
@@ -156908,7 +157296,8 @@ function findLastAssistantModelFromOpenCodeDb(sessionId) {
|
|
|
156908
157296
|
try {
|
|
156909
157297
|
return withReadOnlySessionDb((db) => {
|
|
156910
157298
|
const row = db.prepare(`SELECT json_extract(data, '$.providerID') as providerID,
|
|
156911
|
-
json_extract(data, '$.modelID') as modelID
|
|
157299
|
+
json_extract(data, '$.modelID') as modelID,
|
|
157300
|
+
json_extract(data, '$.agent') as agent
|
|
156912
157301
|
FROM message
|
|
156913
157302
|
WHERE session_id = ?
|
|
156914
157303
|
AND json_extract(data, '$.role') = 'assistant'
|
|
@@ -156919,7 +157308,12 @@ function findLastAssistantModelFromOpenCodeDb(sessionId) {
|
|
|
156919
157308
|
if (!row || typeof row.providerID !== "string" || typeof row.modelID !== "string") {
|
|
156920
157309
|
return null;
|
|
156921
157310
|
}
|
|
156922
|
-
|
|
157311
|
+
const agent = typeof row.agent === "string" && row.agent.length > 0 ? row.agent : undefined;
|
|
157312
|
+
return {
|
|
157313
|
+
providerID: row.providerID,
|
|
157314
|
+
modelID: row.modelID,
|
|
157315
|
+
...agent ? { agent } : {}
|
|
157316
|
+
};
|
|
156923
157317
|
});
|
|
156924
157318
|
} catch (error48) {
|
|
156925
157319
|
log("[magic-context] failed to recover live model from OpenCode DB:", error48);
|
|
@@ -156951,9 +157345,9 @@ function cosineSimilarity(a, b) {
|
|
|
156951
157345
|
}
|
|
156952
157346
|
|
|
156953
157347
|
// src/features/magic-context/memory/embedding-local.ts
|
|
156954
|
-
import { mkdirSync } from "node:fs";
|
|
157348
|
+
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
156955
157349
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
156956
|
-
import { join as
|
|
157350
|
+
import { join as join13 } from "node:path";
|
|
156957
157351
|
async function acquireModelLoadLock(lockPath) {
|
|
156958
157352
|
const waitStart = Date.now();
|
|
156959
157353
|
while (true) {
|
|
@@ -157087,15 +157481,15 @@ class LocalEmbeddingProvider {
|
|
|
157087
157481
|
if (LogLevel && "ERROR" in LogLevel) {
|
|
157088
157482
|
env.logLevel = LogLevel.ERROR;
|
|
157089
157483
|
}
|
|
157090
|
-
const modelCacheDir =
|
|
157484
|
+
const modelCacheDir = join13(getMagicContextStorageDir(), "models");
|
|
157091
157485
|
try {
|
|
157092
|
-
|
|
157486
|
+
mkdirSync2(modelCacheDir, { recursive: true });
|
|
157093
157487
|
env.cacheDir = modelCacheDir;
|
|
157094
157488
|
} catch {
|
|
157095
157489
|
log("[magic-context] could not create model cache dir, using library default");
|
|
157096
157490
|
}
|
|
157097
157491
|
const createPipeline = transformersModule.pipeline;
|
|
157098
|
-
const lockPath =
|
|
157492
|
+
const lockPath = join13(modelCacheDir, ".load.lock");
|
|
157099
157493
|
const releaseLock = await acquireModelLoadLock(lockPath);
|
|
157100
157494
|
const stopHeartbeat = startLockHeartbeat(lockPath);
|
|
157101
157495
|
try {
|
|
@@ -157666,7 +158060,7 @@ var init_storage_memory_fts = __esm(() => {
|
|
|
157666
158060
|
// src/features/magic-context/memory/project-identity.ts
|
|
157667
158061
|
import { execSync } from "node:child_process";
|
|
157668
158062
|
import { createHash as createHash2 } from "node:crypto";
|
|
157669
|
-
import
|
|
158063
|
+
import path4 from "node:path";
|
|
157670
158064
|
function getRootCommitHash(directory) {
|
|
157671
158065
|
try {
|
|
157672
158066
|
const hash2 = execSync("git rev-list --max-parents=0 HEAD", {
|
|
@@ -157683,12 +158077,12 @@ function getRootCommitHash(directory) {
|
|
|
157683
158077
|
}
|
|
157684
158078
|
}
|
|
157685
158079
|
function directoryFallback(directory) {
|
|
157686
|
-
const canonical =
|
|
158080
|
+
const canonical = path4.resolve(directory);
|
|
157687
158081
|
const hash2 = createHash2("md5").update(canonical).digest("hex").slice(0, 12);
|
|
157688
158082
|
return `dir:${hash2}`;
|
|
157689
158083
|
}
|
|
157690
158084
|
function resolveProjectIdentity(directory) {
|
|
157691
|
-
const resolved =
|
|
158085
|
+
const resolved = path4.resolve(directory);
|
|
157692
158086
|
const cached2 = resolvedCache.get(resolved);
|
|
157693
158087
|
if (cached2 !== undefined) {
|
|
157694
158088
|
return cached2;
|
|
@@ -157822,6 +158216,33 @@ function readRawSessionMessagesFromDb(db, sessionId) {
|
|
|
157822
158216
|
};
|
|
157823
158217
|
});
|
|
157824
158218
|
}
|
|
158219
|
+
function readRawSessionMessageByIdFromDb(db, sessionId, messageId) {
|
|
158220
|
+
const row = db.prepare("SELECT id, data, time_created FROM message WHERE session_id = ? AND id = ?").get(sessionId, messageId);
|
|
158221
|
+
if (!row || !isRawMessageRow(row) || typeof row.time_created !== "number") {
|
|
158222
|
+
return null;
|
|
158223
|
+
}
|
|
158224
|
+
const info = parseJsonRecord(row.data);
|
|
158225
|
+
if (!info || info.summary === true && info.finish === "stop") {
|
|
158226
|
+
return null;
|
|
158227
|
+
}
|
|
158228
|
+
const ordinalRow = db.prepare(`SELECT COUNT(*) AS ordinal FROM message
|
|
158229
|
+
WHERE session_id = ?
|
|
158230
|
+
AND NOT (COALESCE(json_extract(data, '$.summary'), 0) = 1
|
|
158231
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop')
|
|
158232
|
+
AND (time_created < ? OR (time_created = ? AND id <= ?))`).get(sessionId, row.time_created, row.time_created, messageId);
|
|
158233
|
+
const ordinal = typeof ordinalRow?.ordinal === "number" ? ordinalRow.ordinal : 0;
|
|
158234
|
+
if (ordinal <= 0) {
|
|
158235
|
+
return null;
|
|
158236
|
+
}
|
|
158237
|
+
const partRows = db.prepare("SELECT message_id, data FROM part WHERE session_id = ? AND message_id = ? ORDER BY time_created ASC, id ASC").all(sessionId, messageId).filter(isRawPartRow);
|
|
158238
|
+
const role = typeof info.role === "string" ? info.role : "unknown";
|
|
158239
|
+
return {
|
|
158240
|
+
ordinal,
|
|
158241
|
+
id: row.id,
|
|
158242
|
+
role,
|
|
158243
|
+
parts: partRows.map((part) => parseJsonUnknown(part.data))
|
|
158244
|
+
};
|
|
158245
|
+
}
|
|
157825
158246
|
|
|
157826
158247
|
// src/hooks/magic-context/tag-content-primitives.ts
|
|
157827
158248
|
function byteSize(value) {
|
|
@@ -157881,86 +158302,339 @@ var init_tag_part_guards = __esm(() => {
|
|
|
157881
158302
|
init_tag_content_primitives();
|
|
157882
158303
|
});
|
|
157883
158304
|
|
|
157884
|
-
// src/hooks/magic-context/
|
|
157885
|
-
function
|
|
157886
|
-
return
|
|
158305
|
+
// src/hooks/magic-context/tool-drop-target.ts
|
|
158306
|
+
function isToolCallId(value) {
|
|
158307
|
+
return typeof value === "string" && value.length > 0;
|
|
157887
158308
|
}
|
|
157888
|
-
function
|
|
157889
|
-
|
|
157890
|
-
|
|
157891
|
-
|
|
158309
|
+
function getToolContent(part) {
|
|
158310
|
+
if (!isRecord(part))
|
|
158311
|
+
return;
|
|
158312
|
+
if (part.type === "tool" && isRecord(part.state)) {
|
|
158313
|
+
return typeof part.state.output === "string" ? part.state.output : undefined;
|
|
157892
158314
|
}
|
|
157893
|
-
|
|
157894
|
-
return
|
|
157895
|
-
} finally {
|
|
157896
|
-
if (!outerCache) {
|
|
157897
|
-
activeRawMessageCache = null;
|
|
157898
|
-
}
|
|
158315
|
+
if (part.type === "tool_result") {
|
|
158316
|
+
return typeof part.content === "string" ? part.content : undefined;
|
|
157899
158317
|
}
|
|
158318
|
+
return;
|
|
157900
158319
|
}
|
|
157901
|
-
function
|
|
157902
|
-
if (
|
|
157903
|
-
|
|
157904
|
-
|
|
157905
|
-
|
|
157906
|
-
|
|
157907
|
-
const messages = readRawSessionMessagesFromSource(sessionId);
|
|
157908
|
-
activeRawMessageCache.set(sessionId, messages);
|
|
157909
|
-
return messages;
|
|
158320
|
+
function setToolContent(part, content) {
|
|
158321
|
+
if (!isRecord(part))
|
|
158322
|
+
return;
|
|
158323
|
+
if (part.type === "tool" && isRecord(part.state)) {
|
|
158324
|
+
part.state.output = content;
|
|
158325
|
+
return;
|
|
157910
158326
|
}
|
|
157911
|
-
|
|
157912
|
-
|
|
157913
|
-
function readRawSessionMessagesFromSource(sessionId) {
|
|
157914
|
-
const provider2 = sessionProviders.get(sessionId);
|
|
157915
|
-
if (provider2)
|
|
157916
|
-
return provider2.readMessages();
|
|
157917
|
-
return withReadOnlySessionDb((db) => readRawSessionMessagesFromDb(db, sessionId));
|
|
157918
|
-
}
|
|
157919
|
-
function getRawSessionMessageCount(sessionId) {
|
|
157920
|
-
const provider2 = sessionProviders.get(sessionId);
|
|
157921
|
-
if (provider2) {
|
|
157922
|
-
if (provider2.getMessageCount)
|
|
157923
|
-
return provider2.getMessageCount();
|
|
157924
|
-
return provider2.readMessages().length;
|
|
158327
|
+
if (part.type === "tool_result") {
|
|
158328
|
+
part.content = content;
|
|
157925
158329
|
}
|
|
157926
|
-
return withReadOnlySessionDb((db) => getRawSessionMessageCountFromDb(db, sessionId));
|
|
157927
158330
|
}
|
|
157928
|
-
function
|
|
157929
|
-
|
|
157930
|
-
|
|
157931
|
-
|
|
157932
|
-
|
|
157933
|
-
|
|
157934
|
-
|
|
157935
|
-
|
|
157936
|
-
|
|
157937
|
-
|
|
157938
|
-
if (isFilePart(part)) {
|
|
157939
|
-
keys.push(`${message.id}:file${partIndex}`);
|
|
157940
|
-
}
|
|
157941
|
-
if (isToolPartWithOutput(part)) {
|
|
157942
|
-
keys.push(part.callID);
|
|
158331
|
+
function truncateToolPart(part) {
|
|
158332
|
+
if (!isRecord(part))
|
|
158333
|
+
return;
|
|
158334
|
+
if (part.type === "tool" && isRecord(part.state)) {
|
|
158335
|
+
const state = part.state;
|
|
158336
|
+
state.output = "[truncated]";
|
|
158337
|
+
if (isRecord(state.input)) {
|
|
158338
|
+
const inputSize = estimateInputSize(state.input);
|
|
158339
|
+
if (inputSize > 500) {
|
|
158340
|
+
truncateInputValues(state.input);
|
|
157943
158341
|
}
|
|
157944
158342
|
}
|
|
158343
|
+
return;
|
|
158344
|
+
}
|
|
158345
|
+
if (part.type === "tool_result") {
|
|
158346
|
+
part.content = "[truncated]";
|
|
158347
|
+
return;
|
|
158348
|
+
}
|
|
158349
|
+
if (part.type === "tool-invocation" && isRecord(part.args)) {
|
|
158350
|
+
const inputSize = estimateInputSize(part.args);
|
|
158351
|
+
if (inputSize > 500) {
|
|
158352
|
+
truncateInputValues(part.args);
|
|
158353
|
+
}
|
|
158354
|
+
return;
|
|
158355
|
+
}
|
|
158356
|
+
if (part.type === "tool_use" && isRecord(part.input)) {
|
|
158357
|
+
const inputSize = estimateInputSize(part.input);
|
|
158358
|
+
if (inputSize > 500) {
|
|
158359
|
+
truncateInputValues(part.input);
|
|
158360
|
+
}
|
|
157945
158361
|
}
|
|
157946
|
-
return keys;
|
|
157947
158362
|
}
|
|
157948
|
-
function
|
|
157949
|
-
|
|
157950
|
-
|
|
157951
|
-
|
|
157952
|
-
return
|
|
158363
|
+
function estimateInputSize(input) {
|
|
158364
|
+
try {
|
|
158365
|
+
return JSON.stringify(input).length;
|
|
158366
|
+
} catch {
|
|
158367
|
+
return 0;
|
|
157953
158368
|
}
|
|
157954
|
-
return userOrdinals[userOrdinals.length - PROTECTED_TAIL_USER_TURNS];
|
|
157955
158369
|
}
|
|
157956
|
-
function
|
|
157957
|
-
|
|
157958
|
-
|
|
157959
|
-
const
|
|
157960
|
-
|
|
157961
|
-
|
|
157962
|
-
|
|
157963
|
-
|
|
158370
|
+
function safeSlice(str, maxLen) {
|
|
158371
|
+
if (str.length <= maxLen)
|
|
158372
|
+
return str;
|
|
158373
|
+
const lastCharCode = str.charCodeAt(maxLen - 1);
|
|
158374
|
+
if (lastCharCode >= 55296 && lastCharCode <= 56319) {
|
|
158375
|
+
return str.slice(0, maxLen - 1);
|
|
158376
|
+
}
|
|
158377
|
+
return str.slice(0, maxLen);
|
|
158378
|
+
}
|
|
158379
|
+
function truncateInputValues(input) {
|
|
158380
|
+
for (const key of Object.keys(input)) {
|
|
158381
|
+
const value = input[key];
|
|
158382
|
+
if (typeof value === "string") {
|
|
158383
|
+
if (value.endsWith(TRUNCATION_SENTINEL) || value === "[object]" || /^\[\d+ items\]$/.test(value))
|
|
158384
|
+
continue;
|
|
158385
|
+
input[key] = value.length > 5 ? `${safeSlice(value, 5)}${TRUNCATION_SENTINEL}` : value;
|
|
158386
|
+
} else if (Array.isArray(value)) {
|
|
158387
|
+
input[key] = `[${value.length} items]`;
|
|
158388
|
+
} else if (value !== null && typeof value === "object") {
|
|
158389
|
+
input[key] = "[object]";
|
|
158390
|
+
}
|
|
158391
|
+
}
|
|
158392
|
+
}
|
|
158393
|
+
function hasMeaningfulPart(part) {
|
|
158394
|
+
if (!isRecord(part))
|
|
158395
|
+
return false;
|
|
158396
|
+
const type = part.type;
|
|
158397
|
+
if (type === "text") {
|
|
158398
|
+
return typeof part.text === "string" && part.text.trim().length > 0;
|
|
158399
|
+
}
|
|
158400
|
+
if (typeof type !== "string")
|
|
158401
|
+
return false;
|
|
158402
|
+
if (IGNORE_PART_TYPES.has(type))
|
|
158403
|
+
return false;
|
|
158404
|
+
return true;
|
|
158405
|
+
}
|
|
158406
|
+
function clearThinkingParts(thinkingParts) {
|
|
158407
|
+
for (const part of thinkingParts) {
|
|
158408
|
+
if (part.thinking !== undefined)
|
|
158409
|
+
part.thinking = "[cleared]";
|
|
158410
|
+
if (part.text !== undefined)
|
|
158411
|
+
part.text = "[cleared]";
|
|
158412
|
+
}
|
|
158413
|
+
}
|
|
158414
|
+
function extractToolCallObservation(part) {
|
|
158415
|
+
if (!isRecord(part))
|
|
158416
|
+
return null;
|
|
158417
|
+
if (part.type === "tool" && isToolCallId(part.callID)) {
|
|
158418
|
+
return { callId: part.callID, kind: "result" };
|
|
158419
|
+
}
|
|
158420
|
+
if (part.type === "tool-invocation" && isToolCallId(part.callID)) {
|
|
158421
|
+
return { callId: part.callID, kind: "invocation" };
|
|
158422
|
+
}
|
|
158423
|
+
if (part.type === "tool_use" && isToolCallId(part.id)) {
|
|
158424
|
+
return { callId: part.id, kind: "invocation" };
|
|
158425
|
+
}
|
|
158426
|
+
if (part.type === "tool_result" && isToolCallId(part.tool_use_id)) {
|
|
158427
|
+
return { callId: part.tool_use_id, kind: "result" };
|
|
158428
|
+
}
|
|
158429
|
+
return null;
|
|
158430
|
+
}
|
|
158431
|
+
function isDropContent(content) {
|
|
158432
|
+
return content.startsWith(DROP_PREFIX);
|
|
158433
|
+
}
|
|
158434
|
+
|
|
158435
|
+
class ToolMutationBatch {
|
|
158436
|
+
partsToRemove = new Set;
|
|
158437
|
+
affectedMessages = new Set;
|
|
158438
|
+
messages;
|
|
158439
|
+
constructor(messages) {
|
|
158440
|
+
this.messages = messages;
|
|
158441
|
+
}
|
|
158442
|
+
markForRemoval(occurrence) {
|
|
158443
|
+
this.partsToRemove.add(occurrence.part);
|
|
158444
|
+
this.affectedMessages.add(occurrence.message);
|
|
158445
|
+
}
|
|
158446
|
+
finalize() {
|
|
158447
|
+
if (this.partsToRemove.size === 0)
|
|
158448
|
+
return;
|
|
158449
|
+
for (const message of this.affectedMessages) {
|
|
158450
|
+
message.parts = message.parts.filter((p) => !this.partsToRemove.has(p));
|
|
158451
|
+
}
|
|
158452
|
+
for (let i = this.messages.length - 1;i >= 0; i -= 1) {
|
|
158453
|
+
if (!this.messages[i].parts.some(hasMeaningfulPart)) {
|
|
158454
|
+
this.messages.splice(i, 1);
|
|
158455
|
+
}
|
|
158456
|
+
}
|
|
158457
|
+
this.partsToRemove.clear();
|
|
158458
|
+
this.affectedMessages.clear();
|
|
158459
|
+
}
|
|
158460
|
+
}
|
|
158461
|
+
function createToolDropTarget(compositeKey, thinkingParts, index, batch) {
|
|
158462
|
+
const drop = () => {
|
|
158463
|
+
const entry = index.get(compositeKey);
|
|
158464
|
+
if (!entry || entry.occurrences.length === 0)
|
|
158465
|
+
return "absent";
|
|
158466
|
+
if (!entry.hasResult)
|
|
158467
|
+
return "incomplete";
|
|
158468
|
+
for (const occurrence of entry.occurrences) {
|
|
158469
|
+
batch.markForRemoval(occurrence);
|
|
158470
|
+
}
|
|
158471
|
+
clearThinkingParts(thinkingParts);
|
|
158472
|
+
index.delete(compositeKey);
|
|
158473
|
+
return "removed";
|
|
158474
|
+
};
|
|
158475
|
+
const truncate = () => {
|
|
158476
|
+
const entry = index.get(compositeKey);
|
|
158477
|
+
if (!entry || entry.occurrences.length === 0)
|
|
158478
|
+
return "absent";
|
|
158479
|
+
if (!entry.hasResult)
|
|
158480
|
+
return "incomplete";
|
|
158481
|
+
for (const occurrence of entry.occurrences) {
|
|
158482
|
+
truncateToolPart(occurrence.part);
|
|
158483
|
+
}
|
|
158484
|
+
clearThinkingParts(thinkingParts);
|
|
158485
|
+
return "truncated";
|
|
158486
|
+
};
|
|
158487
|
+
return {
|
|
158488
|
+
setContent: (content) => {
|
|
158489
|
+
if (isDropContent(content)) {
|
|
158490
|
+
drop();
|
|
158491
|
+
return true;
|
|
158492
|
+
}
|
|
158493
|
+
const entry = index.get(compositeKey);
|
|
158494
|
+
if (!entry)
|
|
158495
|
+
return false;
|
|
158496
|
+
let changed = false;
|
|
158497
|
+
for (const occurrence of entry.occurrences) {
|
|
158498
|
+
if (occurrence.kind !== "result")
|
|
158499
|
+
continue;
|
|
158500
|
+
const prevContent = getToolContent(occurrence.part);
|
|
158501
|
+
if (prevContent !== content) {
|
|
158502
|
+
setToolContent(occurrence.part, content);
|
|
158503
|
+
changed = true;
|
|
158504
|
+
}
|
|
158505
|
+
}
|
|
158506
|
+
return changed;
|
|
158507
|
+
},
|
|
158508
|
+
drop,
|
|
158509
|
+
truncate
|
|
158510
|
+
};
|
|
158511
|
+
}
|
|
158512
|
+
var DROP_PREFIX = "[dropped", IGNORE_PART_TYPES, TRUNCATION_SENTINEL = "...[truncated]";
|
|
158513
|
+
var init_tool_drop_target = __esm(() => {
|
|
158514
|
+
IGNORE_PART_TYPES = new Set([
|
|
158515
|
+
"thinking",
|
|
158516
|
+
"reasoning",
|
|
158517
|
+
"redacted_thinking",
|
|
158518
|
+
"meta",
|
|
158519
|
+
"step-start",
|
|
158520
|
+
"step-finish"
|
|
158521
|
+
]);
|
|
158522
|
+
});
|
|
158523
|
+
|
|
158524
|
+
// src/hooks/magic-context/read-session-chunk.ts
|
|
158525
|
+
function cleanUserText(text) {
|
|
158526
|
+
return removeSystemReminders(text).replace(OMO_INTERNAL_INITIATOR_MARKER, "").trim();
|
|
158527
|
+
}
|
|
158528
|
+
function withRawSessionMessageCache(fn) {
|
|
158529
|
+
const outerCache = activeRawMessageCache;
|
|
158530
|
+
if (!outerCache) {
|
|
158531
|
+
activeRawMessageCache = new Map;
|
|
158532
|
+
}
|
|
158533
|
+
try {
|
|
158534
|
+
return fn();
|
|
158535
|
+
} finally {
|
|
158536
|
+
if (!outerCache) {
|
|
158537
|
+
activeRawMessageCache = null;
|
|
158538
|
+
}
|
|
158539
|
+
}
|
|
158540
|
+
}
|
|
158541
|
+
function readRawSessionMessages(sessionId) {
|
|
158542
|
+
if (activeRawMessageCache) {
|
|
158543
|
+
const cached2 = activeRawMessageCache.get(sessionId);
|
|
158544
|
+
if (cached2) {
|
|
158545
|
+
return cached2;
|
|
158546
|
+
}
|
|
158547
|
+
const messages = readRawSessionMessagesFromSource(sessionId);
|
|
158548
|
+
activeRawMessageCache.set(sessionId, messages);
|
|
158549
|
+
return messages;
|
|
158550
|
+
}
|
|
158551
|
+
return readRawSessionMessagesFromSource(sessionId);
|
|
158552
|
+
}
|
|
158553
|
+
function readRawSessionMessageById(sessionId, messageId) {
|
|
158554
|
+
const provider2 = sessionProviders.get(sessionId);
|
|
158555
|
+
if (provider2?.readMessageById) {
|
|
158556
|
+
return provider2.readMessageById(messageId);
|
|
158557
|
+
}
|
|
158558
|
+
if (provider2) {
|
|
158559
|
+
return provider2.readMessages().find((message) => message.id === messageId) ?? null;
|
|
158560
|
+
}
|
|
158561
|
+
return withReadOnlySessionDb((db) => readRawSessionMessageByIdFromDb(db, sessionId, messageId));
|
|
158562
|
+
}
|
|
158563
|
+
function readRawSessionMessagesFromSource(sessionId) {
|
|
158564
|
+
const provider2 = sessionProviders.get(sessionId);
|
|
158565
|
+
if (provider2)
|
|
158566
|
+
return provider2.readMessages();
|
|
158567
|
+
return withReadOnlySessionDb((db) => readRawSessionMessagesFromDb(db, sessionId));
|
|
158568
|
+
}
|
|
158569
|
+
function getRawSessionMessageCount(sessionId) {
|
|
158570
|
+
const provider2 = sessionProviders.get(sessionId);
|
|
158571
|
+
if (provider2) {
|
|
158572
|
+
if (provider2.getMessageCount)
|
|
158573
|
+
return provider2.getMessageCount();
|
|
158574
|
+
return provider2.readMessages().length;
|
|
158575
|
+
}
|
|
158576
|
+
return withReadOnlySessionDb((db) => getRawSessionMessageCountFromDb(db, sessionId));
|
|
158577
|
+
}
|
|
158578
|
+
function getRawSessionTagKeysThrough(sessionId, upToMessageIndex) {
|
|
158579
|
+
const messages = readRawSessionMessages(sessionId);
|
|
158580
|
+
const messageFileKeys = new Set;
|
|
158581
|
+
const toolObservations = new Map;
|
|
158582
|
+
const unpairedInvocations = new Map;
|
|
158583
|
+
for (const message of messages) {
|
|
158584
|
+
if (message.ordinal > upToMessageIndex)
|
|
158585
|
+
break;
|
|
158586
|
+
for (const [partIndex, part] of message.parts.entries()) {
|
|
158587
|
+
if (isTextPart(part)) {
|
|
158588
|
+
messageFileKeys.add(`${message.id}:p${partIndex}`);
|
|
158589
|
+
continue;
|
|
158590
|
+
}
|
|
158591
|
+
if (isFilePart(part)) {
|
|
158592
|
+
messageFileKeys.add(`${message.id}:file${partIndex}`);
|
|
158593
|
+
continue;
|
|
158594
|
+
}
|
|
158595
|
+
const obs = extractToolCallObservation(part);
|
|
158596
|
+
if (!obs)
|
|
158597
|
+
continue;
|
|
158598
|
+
let ownerMsgId;
|
|
158599
|
+
if (obs.kind === "invocation") {
|
|
158600
|
+
ownerMsgId = message.id;
|
|
158601
|
+
const queue2 = unpairedInvocations.get(obs.callId) ?? [];
|
|
158602
|
+
queue2.push(message.id);
|
|
158603
|
+
unpairedInvocations.set(obs.callId, queue2);
|
|
158604
|
+
} else {
|
|
158605
|
+
const queue2 = unpairedInvocations.get(obs.callId);
|
|
158606
|
+
if (queue2 && queue2.length > 0) {
|
|
158607
|
+
const popped = queue2.shift();
|
|
158608
|
+
if (queue2.length === 0)
|
|
158609
|
+
unpairedInvocations.delete(obs.callId);
|
|
158610
|
+
ownerMsgId = popped ?? message.id;
|
|
158611
|
+
} else {
|
|
158612
|
+
ownerMsgId = message.id;
|
|
158613
|
+
}
|
|
158614
|
+
}
|
|
158615
|
+
const owners = toolObservations.get(obs.callId) ?? new Set;
|
|
158616
|
+
owners.add(ownerMsgId);
|
|
158617
|
+
toolObservations.set(obs.callId, owners);
|
|
158618
|
+
}
|
|
158619
|
+
}
|
|
158620
|
+
return { messageFileKeys, toolObservations };
|
|
158621
|
+
}
|
|
158622
|
+
function getProtectedTailStartOrdinal(sessionId) {
|
|
158623
|
+
const messages = readRawSessionMessages(sessionId);
|
|
158624
|
+
const userOrdinals = messages.filter((m) => m.role === "user" && hasMeaningfulUserText(m.parts)).map((m) => m.ordinal);
|
|
158625
|
+
if (userOrdinals.length < PROTECTED_TAIL_USER_TURNS) {
|
|
158626
|
+
return 1;
|
|
158627
|
+
}
|
|
158628
|
+
return userOrdinals[userOrdinals.length - PROTECTED_TAIL_USER_TURNS];
|
|
158629
|
+
}
|
|
158630
|
+
function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal) {
|
|
158631
|
+
const messages = readRawSessionMessages(sessionId);
|
|
158632
|
+
const startOrdinal = Math.max(1, offset);
|
|
158633
|
+
const lines = [];
|
|
158634
|
+
const lineMeta = [];
|
|
158635
|
+
const flushedToolOnlyBlocks = [];
|
|
158636
|
+
let totalTokens = 0;
|
|
158637
|
+
let messagesProcessed = 0;
|
|
157964
158638
|
let lastOrdinal = startOrdinal - 1;
|
|
157965
158639
|
let lastMessageId = "";
|
|
157966
158640
|
let firstMessageId = "";
|
|
@@ -158094,6 +158768,7 @@ var activeRawMessageCache = null, sessionProviders, PROTECTED_TAIL_USER_TURNS =
|
|
|
158094
158768
|
var init_read_session_chunk = __esm(async () => {
|
|
158095
158769
|
init_read_session_formatting();
|
|
158096
158770
|
init_tag_part_guards();
|
|
158771
|
+
init_tool_drop_target();
|
|
158097
158772
|
init_read_session_formatting();
|
|
158098
158773
|
await init_read_session_db();
|
|
158099
158774
|
sessionProviders = new Map;
|
|
@@ -158151,10 +158826,26 @@ function getCountIndexedMessageStatement(db) {
|
|
|
158151
158826
|
}
|
|
158152
158827
|
return stmt;
|
|
158153
158828
|
}
|
|
158829
|
+
function getIndexedMessageIdStatement(db) {
|
|
158830
|
+
let stmt = indexedMessageIdStatements.get(db);
|
|
158831
|
+
if (!stmt) {
|
|
158832
|
+
stmt = db.prepare("SELECT message_id AS messageId FROM message_history_fts WHERE session_id = ?");
|
|
158833
|
+
indexedMessageIdStatements.set(db, stmt);
|
|
158834
|
+
}
|
|
158835
|
+
return stmt;
|
|
158836
|
+
}
|
|
158154
158837
|
function getLastIndexedOrdinal(db, sessionId) {
|
|
158155
158838
|
const row = getLastIndexedStatement(db).get(sessionId);
|
|
158156
158839
|
return typeof row?.last_indexed_ordinal === "number" ? row.last_indexed_ordinal : 0;
|
|
158157
158840
|
}
|
|
158841
|
+
function isMessageAlreadyIndexed(db, sessionId, messageId) {
|
|
158842
|
+
const row = getCountIndexedMessageStatement(db).get(sessionId, messageId);
|
|
158843
|
+
return (typeof row?.count === "number" ? row.count : 0) > 0;
|
|
158844
|
+
}
|
|
158845
|
+
function advanceIndexWatermark(db, sessionId, ordinal, now) {
|
|
158846
|
+
const current = getLastIndexedOrdinal(db, sessionId);
|
|
158847
|
+
getUpsertIndexStatement(db).run(sessionId, Math.max(current, ordinal), now, getHarness());
|
|
158848
|
+
}
|
|
158158
158849
|
function deleteIndexedMessage(db, sessionId, messageId) {
|
|
158159
158850
|
const row = getCountIndexedMessageStatement(db).get(sessionId, messageId);
|
|
158160
158851
|
const count = typeof row?.count === "number" ? row.count : 0;
|
|
@@ -158180,36 +158871,53 @@ function getIndexableContent(role, parts) {
|
|
|
158180
158871
|
}
|
|
158181
158872
|
return "";
|
|
158182
158873
|
}
|
|
158183
|
-
function
|
|
158184
|
-
|
|
158185
|
-
|
|
158186
|
-
|
|
158187
|
-
return;
|
|
158874
|
+
function indexSingleMessageInTransaction(db, sessionId, message, now) {
|
|
158875
|
+
if (message.role !== "user" && message.role !== "assistant") {
|
|
158876
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
158877
|
+
return false;
|
|
158188
158878
|
}
|
|
158189
|
-
|
|
158190
|
-
if (
|
|
158191
|
-
db
|
|
158192
|
-
|
|
158879
|
+
const content = getIndexableContent(message.role, message.parts);
|
|
158880
|
+
if (content.length === 0) {
|
|
158881
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
158882
|
+
return false;
|
|
158193
158883
|
}
|
|
158194
|
-
if (
|
|
158195
|
-
|
|
158884
|
+
if (isMessageAlreadyIndexed(db, sessionId, message.id)) {
|
|
158885
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
158886
|
+
return false;
|
|
158196
158887
|
}
|
|
158197
|
-
|
|
158198
|
-
|
|
158199
|
-
|
|
158200
|
-
|
|
158201
|
-
|
|
158202
|
-
|
|
158888
|
+
getInsertMessageStatement(db).run(sessionId, message.ordinal, message.id, message.role, content);
|
|
158889
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
158890
|
+
return true;
|
|
158891
|
+
}
|
|
158892
|
+
function indexSingleMessage(db, sessionId, message) {
|
|
158893
|
+
return db.transaction(() => indexSingleMessageInTransaction(db, sessionId, message, Date.now()))();
|
|
158894
|
+
}
|
|
158895
|
+
function indexMessagesAfterOrdinal(db, sessionId, messages, lastIndexedOrdinal, finalWatermark = messages.length) {
|
|
158203
158896
|
const now = Date.now();
|
|
158897
|
+
let inserted = 0;
|
|
158204
158898
|
db.transaction(() => {
|
|
158899
|
+
const existingMessageIds = new Set(getIndexedMessageIdStatement(db).all(sessionId).map((row) => row.messageId).filter((messageId) => typeof messageId === "string"));
|
|
158205
158900
|
const insertMessage = getInsertMessageStatement(db);
|
|
158206
|
-
for (const message of
|
|
158207
|
-
|
|
158901
|
+
for (const message of messages) {
|
|
158902
|
+
if (message.ordinal <= lastIndexedOrdinal) {
|
|
158903
|
+
continue;
|
|
158904
|
+
}
|
|
158905
|
+
if (message.role !== "user" && message.role !== "assistant") {
|
|
158906
|
+
continue;
|
|
158907
|
+
}
|
|
158908
|
+
const content = getIndexableContent(message.role, message.parts);
|
|
158909
|
+
if (content.length === 0 || existingMessageIds.has(message.id)) {
|
|
158910
|
+
continue;
|
|
158911
|
+
}
|
|
158912
|
+
insertMessage.run(sessionId, message.ordinal, message.id, message.role, content);
|
|
158913
|
+
existingMessageIds.add(message.id);
|
|
158914
|
+
inserted++;
|
|
158208
158915
|
}
|
|
158209
|
-
getUpsertIndexStatement(db).run(sessionId,
|
|
158916
|
+
getUpsertIndexStatement(db).run(sessionId, finalWatermark, now, getHarness());
|
|
158210
158917
|
})();
|
|
158918
|
+
return inserted;
|
|
158211
158919
|
}
|
|
158212
|
-
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements;
|
|
158920
|
+
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements, indexedMessageIdStatements;
|
|
158213
158921
|
var init_message_index = __esm(async () => {
|
|
158214
158922
|
init_compression_depth_storage();
|
|
158215
158923
|
await init_read_session_chunk();
|
|
@@ -158219,6 +158927,7 @@ var init_message_index = __esm(async () => {
|
|
|
158219
158927
|
deleteFtsStatements = new WeakMap;
|
|
158220
158928
|
deleteIndexStatements = new WeakMap;
|
|
158221
158929
|
countIndexedMessageStatements = new WeakMap;
|
|
158930
|
+
indexedMessageIdStatements = new WeakMap;
|
|
158222
158931
|
});
|
|
158223
158932
|
|
|
158224
158933
|
// src/features/magic-context/migrations.ts
|
|
@@ -158235,22 +158944,51 @@ function getCurrentVersion(db) {
|
|
|
158235
158944
|
const row = db.prepare("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
158236
158945
|
return row?.version ?? 0;
|
|
158237
158946
|
}
|
|
158947
|
+
function isSiblingMigrationConflict(error48, version2) {
|
|
158948
|
+
if (!(error48 instanceof Error))
|
|
158949
|
+
return false;
|
|
158950
|
+
const code = error48.code;
|
|
158951
|
+
if (code !== "SQLITE_CONSTRAINT_PRIMARYKEY" && code !== "SQLITE_CONSTRAINT_UNIQUE") {
|
|
158952
|
+
return false;
|
|
158953
|
+
}
|
|
158954
|
+
const msg = error48.message;
|
|
158955
|
+
if (!msg.includes("schema_migrations"))
|
|
158956
|
+
return false;
|
|
158957
|
+
if (!msg.toLowerCase().includes("version"))
|
|
158958
|
+
return false;
|
|
158959
|
+
return true;
|
|
158960
|
+
}
|
|
158238
158961
|
function runMigrations(db) {
|
|
158239
158962
|
ensureMigrationsTable(db);
|
|
158240
|
-
|
|
158241
|
-
|
|
158963
|
+
let currentVersion = getCurrentVersion(db);
|
|
158964
|
+
let pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
|
|
158242
158965
|
if (pendingMigrations.length === 0) {
|
|
158243
158966
|
return;
|
|
158244
158967
|
}
|
|
158245
158968
|
log(`[migrations] current schema version: ${currentVersion}, applying ${pendingMigrations.length} migration(s)`);
|
|
158246
|
-
|
|
158969
|
+
let migrationIndex = 0;
|
|
158970
|
+
while (migrationIndex < pendingMigrations.length) {
|
|
158971
|
+
const migration = pendingMigrations[migrationIndex];
|
|
158247
158972
|
try {
|
|
158248
158973
|
db.transaction(() => {
|
|
158249
158974
|
migration.up(db);
|
|
158250
158975
|
db.prepare("INSERT INTO schema_migrations (version, description, applied_at) VALUES (?, ?, ?)").run(migration.version, migration.description, Date.now());
|
|
158251
158976
|
})();
|
|
158252
158977
|
log(`[migrations] applied v${migration.version}: ${migration.description}`);
|
|
158978
|
+
migrationIndex += 1;
|
|
158253
158979
|
} catch (error48) {
|
|
158980
|
+
if (isSiblingMigrationConflict(error48, migration.version)) {
|
|
158981
|
+
log(`[migrations] v${migration.version} already applied by sibling instance — resuming with re-read version`);
|
|
158982
|
+
const reReadVersion = getCurrentVersion(db);
|
|
158983
|
+
if (reReadVersion <= currentVersion) {
|
|
158984
|
+
log(`[migrations] FAILED v${migration.version}: sibling-conflict shape but version not advanced (${reReadVersion} <= ${currentVersion}) — failing closed`);
|
|
158985
|
+
throw new Error(`Migration v${migration.version} failed: sibling conflict reported but version did not advance. Database may need manual repair.`);
|
|
158986
|
+
}
|
|
158987
|
+
currentVersion = reReadVersion;
|
|
158988
|
+
pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
|
|
158989
|
+
migrationIndex = 0;
|
|
158990
|
+
continue;
|
|
158991
|
+
}
|
|
158254
158992
|
log(`[migrations] FAILED v${migration.version}: ${migration.description} — ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
158255
158993
|
throw new Error(`Migration v${migration.version} failed: ${error48 instanceof Error ? error48.message : String(error48)}. Database may need manual repair.`);
|
|
158256
158994
|
}
|
|
@@ -158462,30 +159200,330 @@ var init_migrations = __esm(async () => {
|
|
|
158462
159200
|
db.exec("ALTER TABLE notes ADD COLUMN harness TEXT NOT NULL DEFAULT 'opencode'");
|
|
158463
159201
|
}
|
|
158464
159202
|
}
|
|
159203
|
+
},
|
|
159204
|
+
{
|
|
159205
|
+
version: 8,
|
|
159206
|
+
description: "Add partial indexes on tags(session_id, tag_number) for active and dropped",
|
|
159207
|
+
up: (db) => {
|
|
159208
|
+
db.exec(`
|
|
159209
|
+
CREATE INDEX IF NOT EXISTS idx_tags_active_session_tag_number
|
|
159210
|
+
ON tags(session_id, tag_number)
|
|
159211
|
+
WHERE status = 'active';
|
|
159212
|
+
|
|
159213
|
+
CREATE INDEX IF NOT EXISTS idx_tags_dropped_session_tag_number
|
|
159214
|
+
ON tags(session_id, tag_number)
|
|
159215
|
+
WHERE status = 'dropped';
|
|
159216
|
+
`);
|
|
159217
|
+
db.exec("ANALYZE tags;");
|
|
159218
|
+
}
|
|
159219
|
+
},
|
|
159220
|
+
{
|
|
159221
|
+
version: 9,
|
|
159222
|
+
description: "Persist tool_definition_measurements across plugin restarts",
|
|
159223
|
+
up: (db) => {
|
|
159224
|
+
db.exec(`
|
|
159225
|
+
CREATE TABLE IF NOT EXISTS tool_definition_measurements (
|
|
159226
|
+
provider_id TEXT NOT NULL,
|
|
159227
|
+
model_id TEXT NOT NULL,
|
|
159228
|
+
agent_name TEXT NOT NULL,
|
|
159229
|
+
tool_id TEXT NOT NULL,
|
|
159230
|
+
token_count INTEGER NOT NULL,
|
|
159231
|
+
recorded_at INTEGER NOT NULL,
|
|
159232
|
+
PRIMARY KEY (provider_id, model_id, agent_name, tool_id)
|
|
159233
|
+
);
|
|
159234
|
+
`);
|
|
159235
|
+
}
|
|
159236
|
+
},
|
|
159237
|
+
{
|
|
159238
|
+
version: 10,
|
|
159239
|
+
description: "Add tool_owner_message_id column to tags + composite identity indexes",
|
|
159240
|
+
up: (db) => {
|
|
159241
|
+
const cols = db.prepare("PRAGMA table_info(tags)").all();
|
|
159242
|
+
if (!cols.some((c) => c.name === "tool_owner_message_id")) {
|
|
159243
|
+
db.exec("ALTER TABLE tags ADD COLUMN tool_owner_message_id TEXT DEFAULT NULL");
|
|
159244
|
+
}
|
|
159245
|
+
db.exec(`
|
|
159246
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_tool_composite
|
|
159247
|
+
ON tags(session_id, message_id, tool_owner_message_id)
|
|
159248
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NOT NULL;
|
|
159249
|
+
|
|
159250
|
+
CREATE INDEX IF NOT EXISTS idx_tags_tool_null_owner
|
|
159251
|
+
ON tags(session_id, message_id)
|
|
159252
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
159253
|
+
`);
|
|
159254
|
+
}
|
|
158465
159255
|
}
|
|
158466
159256
|
];
|
|
158467
159257
|
});
|
|
158468
159258
|
|
|
159259
|
+
// src/features/magic-context/tool-owner-backfill.ts
|
|
159260
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
159261
|
+
import { join as join14 } from "node:path";
|
|
159262
|
+
function resolveOpencodeDbPath() {
|
|
159263
|
+
return join14(getDataDir(), "opencode", "opencode.db");
|
|
159264
|
+
}
|
|
159265
|
+
function ensureBackfillStateTable(db) {
|
|
159266
|
+
db.exec(`
|
|
159267
|
+
CREATE TABLE IF NOT EXISTS tool_owner_backfill_state (
|
|
159268
|
+
session_id TEXT PRIMARY KEY,
|
|
159269
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'completed', 'skipped')),
|
|
159270
|
+
started_at INTEGER,
|
|
159271
|
+
lease_expires_at INTEGER,
|
|
159272
|
+
completed_at INTEGER,
|
|
159273
|
+
last_error TEXT
|
|
159274
|
+
);
|
|
159275
|
+
CREATE INDEX IF NOT EXISTS idx_tool_owner_backfill_state_status
|
|
159276
|
+
ON tool_owner_backfill_state(status);
|
|
159277
|
+
`);
|
|
159278
|
+
}
|
|
159279
|
+
function runToolOwnerBackfill(db) {
|
|
159280
|
+
const startedAt = performance.now();
|
|
159281
|
+
ensureBackfillStateTable(db);
|
|
159282
|
+
const result = {
|
|
159283
|
+
sessionsProcessed: 0,
|
|
159284
|
+
sessionsSkippedNoOcDb: 0,
|
|
159285
|
+
sessionsSkippedNoMatches: 0,
|
|
159286
|
+
sessionsCompleted: 0,
|
|
159287
|
+
sessionsBlockedByLease: 0,
|
|
159288
|
+
sessionsErrored: 0,
|
|
159289
|
+
rowsUpdated: 0,
|
|
159290
|
+
rowsLeftNull: 0,
|
|
159291
|
+
durationMs: 0
|
|
159292
|
+
};
|
|
159293
|
+
if (!isToolOwnerBackfillNeeded(db)) {
|
|
159294
|
+
result.durationMs = performance.now() - startedAt;
|
|
159295
|
+
return result;
|
|
159296
|
+
}
|
|
159297
|
+
const opencodeDbPath = resolveOpencodeDbPath();
|
|
159298
|
+
if (!existsSync9(opencodeDbPath)) {
|
|
159299
|
+
log(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
|
|
159300
|
+
markAllUnbackfilledSessionsSkipped(db);
|
|
159301
|
+
result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
|
|
159302
|
+
result.durationMs = performance.now() - startedAt;
|
|
159303
|
+
return result;
|
|
159304
|
+
}
|
|
159305
|
+
db.exec(`ATTACH '${opencodeDbPath}' AS oc_backfill`);
|
|
159306
|
+
try {
|
|
159307
|
+
backfillToolOwnersInChunks(db, result);
|
|
159308
|
+
} finally {
|
|
159309
|
+
try {
|
|
159310
|
+
db.exec("DETACH DATABASE oc_backfill");
|
|
159311
|
+
} catch (error48) {
|
|
159312
|
+
log(`[backfill] failed to detach oc_backfill database: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
159313
|
+
}
|
|
159314
|
+
}
|
|
159315
|
+
result.durationMs = performance.now() - startedAt;
|
|
159316
|
+
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)}`);
|
|
159317
|
+
return result;
|
|
159318
|
+
}
|
|
159319
|
+
function isToolOwnerBackfillNeeded(db) {
|
|
159320
|
+
ensureBackfillStateTable(db);
|
|
159321
|
+
const row = db.prepare(`SELECT 1 AS hit
|
|
159322
|
+
FROM tags
|
|
159323
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL
|
|
159324
|
+
AND NOT EXISTS (
|
|
159325
|
+
SELECT 1 FROM tool_owner_backfill_state s
|
|
159326
|
+
WHERE s.session_id = tags.session_id
|
|
159327
|
+
AND s.status IN ('completed', 'skipped')
|
|
159328
|
+
)
|
|
159329
|
+
LIMIT 1`).get();
|
|
159330
|
+
return row !== null && row !== undefined;
|
|
159331
|
+
}
|
|
159332
|
+
function markAllUnbackfilledSessionsSkipped(db) {
|
|
159333
|
+
const now = Date.now();
|
|
159334
|
+
db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, completed_at, last_error)
|
|
159335
|
+
SELECT DISTINCT session_id, 'skipped', NULL, ?, NULL
|
|
159336
|
+
FROM tags
|
|
159337
|
+
WHERE type = 'tool' AND tool_owner_message_id IS NULL
|
|
159338
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
159339
|
+
status = 'skipped',
|
|
159340
|
+
completed_at = excluded.completed_at,
|
|
159341
|
+
last_error = NULL
|
|
159342
|
+
WHERE tool_owner_backfill_state.status NOT IN ('completed', 'running')`).run(now);
|
|
159343
|
+
}
|
|
159344
|
+
function countSessionsByStatus(db, status) {
|
|
159345
|
+
const row = db.prepare("SELECT COUNT(*) AS c FROM tool_owner_backfill_state WHERE status = ?").get(status);
|
|
159346
|
+
return row.c;
|
|
159347
|
+
}
|
|
159348
|
+
function acquireSessionLease(db, sessionId, now) {
|
|
159349
|
+
const expiresAt = now + LEASE_DURATION_MS2;
|
|
159350
|
+
const result = db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, lease_expires_at)
|
|
159351
|
+
VALUES (?, 'running', ?, ?)
|
|
159352
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
159353
|
+
status = 'running',
|
|
159354
|
+
started_at = excluded.started_at,
|
|
159355
|
+
lease_expires_at = excluded.lease_expires_at,
|
|
159356
|
+
last_error = NULL
|
|
159357
|
+
WHERE tool_owner_backfill_state.status IN ('pending', 'skipped')
|
|
159358
|
+
OR (tool_owner_backfill_state.status = 'running'
|
|
159359
|
+
AND tool_owner_backfill_state.lease_expires_at < ?)`).run(sessionId, now, expiresAt, now);
|
|
159360
|
+
return (result.changes ?? 0) === 1;
|
|
159361
|
+
}
|
|
159362
|
+
function renewSessionLease(db, sessionId, now) {
|
|
159363
|
+
const expiresAt = now + LEASE_DURATION_MS2;
|
|
159364
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
159365
|
+
SET lease_expires_at = ?
|
|
159366
|
+
WHERE session_id = ? AND status = 'running'`).run(expiresAt, sessionId);
|
|
159367
|
+
}
|
|
159368
|
+
function markSessionCompleted(db, sessionId, now) {
|
|
159369
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
159370
|
+
SET status = 'completed', completed_at = ?, lease_expires_at = NULL, last_error = NULL
|
|
159371
|
+
WHERE session_id = ?`).run(now, sessionId);
|
|
159372
|
+
}
|
|
159373
|
+
function markSessionSkipped(db, sessionId, now, reason) {
|
|
159374
|
+
db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, completed_at, last_error)
|
|
159375
|
+
VALUES (?, 'skipped', ?, ?)
|
|
159376
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
159377
|
+
status = 'skipped',
|
|
159378
|
+
completed_at = excluded.completed_at,
|
|
159379
|
+
last_error = excluded.last_error,
|
|
159380
|
+
lease_expires_at = NULL`).run(sessionId, now, reason);
|
|
159381
|
+
}
|
|
159382
|
+
function markSessionErrored(db, sessionId, error48) {
|
|
159383
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
159384
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
159385
|
+
SET last_error = ?, lease_expires_at = NULL
|
|
159386
|
+
WHERE session_id = ?`).run(message, sessionId);
|
|
159387
|
+
}
|
|
159388
|
+
function getSessionsNeedingBackfill(db) {
|
|
159389
|
+
const rows = db.prepare(`SELECT DISTINCT t.session_id
|
|
159390
|
+
FROM tags t
|
|
159391
|
+
LEFT JOIN tool_owner_backfill_state s ON s.session_id = t.session_id
|
|
159392
|
+
WHERE t.type = 'tool' AND t.tool_owner_message_id IS NULL
|
|
159393
|
+
AND (s.status IS NULL OR s.status NOT IN ('completed', 'skipped'))
|
|
159394
|
+
ORDER BY t.session_id ASC`).all();
|
|
159395
|
+
return rows.map((r) => r.session_id);
|
|
159396
|
+
}
|
|
159397
|
+
function buildSessionOwnerMap(db, sessionId) {
|
|
159398
|
+
const rows = db.prepare(`SELECT
|
|
159399
|
+
COALESCE(
|
|
159400
|
+
CASE WHEN json_extract(p.data, '$.type') = 'tool_use'
|
|
159401
|
+
THEN json_extract(p.data, '$.id')
|
|
159402
|
+
END,
|
|
159403
|
+
json_extract(p.data, '$.callID')
|
|
159404
|
+
) AS callid,
|
|
159405
|
+
m.id AS owner_id,
|
|
159406
|
+
m.time_created AS owner_t_created,
|
|
159407
|
+
p.id AS part_id,
|
|
159408
|
+
p.time_created AS part_t_created
|
|
159409
|
+
FROM oc_backfill.message m
|
|
159410
|
+
INNER JOIN oc_backfill.part p ON p.message_id = m.id
|
|
159411
|
+
WHERE m.session_id = ?
|
|
159412
|
+
AND json_extract(m.data, '$.role') = 'assistant'
|
|
159413
|
+
AND (
|
|
159414
|
+
(json_extract(p.data, '$.type') IN ('tool', 'tool-invocation')
|
|
159415
|
+
AND json_extract(p.data, '$.callID') IS NOT NULL)
|
|
159416
|
+
OR (json_extract(p.data, '$.type') = 'tool_use'
|
|
159417
|
+
AND json_extract(p.data, '$.id') IS NOT NULL)
|
|
159418
|
+
)
|
|
159419
|
+
ORDER BY
|
|
159420
|
+
m.time_created ASC,
|
|
159421
|
+
m.id ASC,
|
|
159422
|
+
p.time_created ASC,
|
|
159423
|
+
p.id ASC`).all(sessionId);
|
|
159424
|
+
const oldestByCallId = new Map;
|
|
159425
|
+
for (const r of rows) {
|
|
159426
|
+
if (typeof r.callid !== "string" || r.callid.length === 0)
|
|
159427
|
+
continue;
|
|
159428
|
+
if (!oldestByCallId.has(r.callid)) {
|
|
159429
|
+
oldestByCallId.set(r.callid, r.owner_id);
|
|
159430
|
+
}
|
|
159431
|
+
}
|
|
159432
|
+
return oldestByCallId;
|
|
159433
|
+
}
|
|
159434
|
+
function applyOwnersForSession(db, sessionId, ownersByCallId) {
|
|
159435
|
+
if (ownersByCallId.size === 0) {
|
|
159436
|
+
const leftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
|
|
159437
|
+
WHERE session_id = ? AND type = 'tool'
|
|
159438
|
+
AND tool_owner_message_id IS NULL`).get(sessionId).c;
|
|
159439
|
+
return { rowsUpdated: 0, rowsLeftNull: leftNull };
|
|
159440
|
+
}
|
|
159441
|
+
const findOrphanStmt = db.prepare(`SELECT id FROM tags
|
|
159442
|
+
WHERE session_id = ? AND message_id = ? AND type = 'tool'
|
|
159443
|
+
AND tool_owner_message_id IS NULL
|
|
159444
|
+
ORDER BY tag_number ASC
|
|
159445
|
+
LIMIT 1`);
|
|
159446
|
+
const updateRowStmt = db.prepare(`UPDATE tags
|
|
159447
|
+
SET tool_owner_message_id = ?
|
|
159448
|
+
WHERE id = ? AND tool_owner_message_id IS NULL`);
|
|
159449
|
+
let rowsUpdated = 0;
|
|
159450
|
+
db.transaction(() => {
|
|
159451
|
+
for (const [callId, ownerId] of ownersByCallId) {
|
|
159452
|
+
const orphan = findOrphanStmt.get(sessionId, callId);
|
|
159453
|
+
if (!orphan)
|
|
159454
|
+
continue;
|
|
159455
|
+
const result = updateRowStmt.run(ownerId, orphan.id);
|
|
159456
|
+
rowsUpdated += result.changes ?? 0;
|
|
159457
|
+
}
|
|
159458
|
+
})();
|
|
159459
|
+
const rowsLeftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
|
|
159460
|
+
WHERE session_id = ? AND type = 'tool'
|
|
159461
|
+
AND tool_owner_message_id IS NULL`).get(sessionId).c;
|
|
159462
|
+
return { rowsUpdated, rowsLeftNull };
|
|
159463
|
+
}
|
|
159464
|
+
function backfillToolOwnersInChunks(db, result) {
|
|
159465
|
+
const sessionIds = getSessionsNeedingBackfill(db);
|
|
159466
|
+
let lastRenewedAt = Date.now();
|
|
159467
|
+
for (const sessionId of sessionIds) {
|
|
159468
|
+
const now = Date.now();
|
|
159469
|
+
result.sessionsProcessed += 1;
|
|
159470
|
+
const acquired = acquireSessionLease(db, sessionId, now);
|
|
159471
|
+
if (!acquired) {
|
|
159472
|
+
result.sessionsBlockedByLease += 1;
|
|
159473
|
+
continue;
|
|
159474
|
+
}
|
|
159475
|
+
try {
|
|
159476
|
+
const owners = buildSessionOwnerMap(db, sessionId);
|
|
159477
|
+
const { rowsUpdated, rowsLeftNull } = applyOwnersForSession(db, sessionId, owners);
|
|
159478
|
+
result.rowsUpdated += rowsUpdated;
|
|
159479
|
+
result.rowsLeftNull += rowsLeftNull;
|
|
159480
|
+
if (owners.size === 0) {
|
|
159481
|
+
markSessionSkipped(db, sessionId, Date.now(), "no_oc_matches");
|
|
159482
|
+
result.sessionsSkippedNoMatches += 1;
|
|
159483
|
+
} else {
|
|
159484
|
+
markSessionCompleted(db, sessionId, Date.now());
|
|
159485
|
+
result.sessionsCompleted += 1;
|
|
159486
|
+
}
|
|
159487
|
+
} catch (error48) {
|
|
159488
|
+
log(`[backfill] session=${sessionId} errored: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
159489
|
+
markSessionErrored(db, sessionId, error48);
|
|
159490
|
+
result.sessionsErrored += 1;
|
|
159491
|
+
}
|
|
159492
|
+
const sinceRenew = Date.now() - lastRenewedAt;
|
|
159493
|
+
if (sinceRenew > LEASE_RENEWAL_MS) {
|
|
159494
|
+
renewSessionLease(db, sessionId, Date.now());
|
|
159495
|
+
lastRenewedAt = Date.now();
|
|
159496
|
+
}
|
|
159497
|
+
}
|
|
159498
|
+
}
|
|
159499
|
+
var LEASE_DURATION_MS2, LEASE_RENEWAL_MS;
|
|
159500
|
+
var init_tool_owner_backfill = __esm(() => {
|
|
159501
|
+
init_data_path();
|
|
159502
|
+
init_logger();
|
|
159503
|
+
LEASE_DURATION_MS2 = 5 * 60 * 1000;
|
|
159504
|
+
LEASE_RENEWAL_MS = 60 * 1000;
|
|
159505
|
+
});
|
|
159506
|
+
|
|
158469
159507
|
// src/features/magic-context/storage-db.ts
|
|
158470
|
-
import { copyFileSync, cpSync, existsSync as
|
|
158471
|
-
import { join as
|
|
159508
|
+
import { copyFileSync, cpSync, existsSync as existsSync10, mkdirSync as mkdirSync3 } from "node:fs";
|
|
159509
|
+
import { join as join15 } from "node:path";
|
|
158472
159510
|
function resolveDatabasePath() {
|
|
158473
159511
|
const dbDir = getMagicContextStorageDir();
|
|
158474
|
-
return { dbDir, dbPath:
|
|
159512
|
+
return { dbDir, dbPath: join15(dbDir, "context.db") };
|
|
158475
159513
|
}
|
|
158476
159514
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
158477
|
-
if (
|
|
159515
|
+
if (existsSync10(targetDbPath))
|
|
158478
159516
|
return;
|
|
158479
159517
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
158480
|
-
const legacyDbPath =
|
|
158481
|
-
if (!
|
|
159518
|
+
const legacyDbPath = join15(legacyDir, "context.db");
|
|
159519
|
+
if (!existsSync10(legacyDbPath))
|
|
158482
159520
|
return;
|
|
158483
159521
|
log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
158484
|
-
|
|
159522
|
+
mkdirSync3(targetDbDir, { recursive: true });
|
|
158485
159523
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
158486
159524
|
const src = `${legacyDbPath}${suffix}`;
|
|
158487
|
-
const dst =
|
|
158488
|
-
if (
|
|
159525
|
+
const dst = join15(targetDbDir, `context.db${suffix}`);
|
|
159526
|
+
if (existsSync10(src)) {
|
|
158489
159527
|
try {
|
|
158490
159528
|
copyFileSync(src, dst);
|
|
158491
159529
|
} catch (error48) {
|
|
@@ -158493,9 +159531,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
158493
159531
|
}
|
|
158494
159532
|
}
|
|
158495
159533
|
}
|
|
158496
|
-
const legacyModelsDir =
|
|
158497
|
-
const targetModelsDir =
|
|
158498
|
-
if (
|
|
159534
|
+
const legacyModelsDir = join15(legacyDir, "models");
|
|
159535
|
+
const targetModelsDir = join15(targetDbDir, "models");
|
|
159536
|
+
if (existsSync10(legacyModelsDir) && !existsSync10(targetModelsDir)) {
|
|
158499
159537
|
try {
|
|
158500
159538
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
158501
159539
|
} catch (error48) {
|
|
@@ -158781,6 +159819,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158781
159819
|
ensureColumn(db, "tags", "tool_name", "TEXT");
|
|
158782
159820
|
ensureColumn(db, "tags", "input_byte_size", "INTEGER DEFAULT 0");
|
|
158783
159821
|
ensureColumn(db, "tags", "caveman_depth", "INTEGER DEFAULT 0");
|
|
159822
|
+
ensureColumn(db, "tags", "tool_owner_message_id", "TEXT DEFAULT NULL");
|
|
158784
159823
|
ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
|
|
158785
159824
|
ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
|
|
158786
159825
|
ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
|
|
@@ -158875,10 +159914,17 @@ function openDatabase() {
|
|
|
158875
159914
|
}
|
|
158876
159915
|
try {
|
|
158877
159916
|
migrateLegacyStorageIfNeeded(dbPath, dbDir);
|
|
158878
|
-
|
|
159917
|
+
mkdirSync3(dbDir, { recursive: true });
|
|
158879
159918
|
const db = new Database(dbPath);
|
|
158880
159919
|
initializeDatabase(db);
|
|
158881
159920
|
runMigrations(db);
|
|
159921
|
+
try {
|
|
159922
|
+
runToolOwnerBackfill(db);
|
|
159923
|
+
} catch (error48) {
|
|
159924
|
+
log(`[magic-context] tool-owner backfill failed (continuing with lazy adoption fallback): ${getErrorMessage(error48)}`);
|
|
159925
|
+
}
|
|
159926
|
+
setDatabase(db);
|
|
159927
|
+
loadToolDefinitionMeasurements(db);
|
|
158882
159928
|
databases.set(dbPath, db);
|
|
158883
159929
|
persistenceByDatabase.set(db, true);
|
|
158884
159930
|
persistenceErrorByDatabase.delete(db);
|
|
@@ -158899,6 +159945,8 @@ var databases, persistenceByDatabase, persistenceErrorByDatabase;
|
|
|
158899
159945
|
var init_storage_db = __esm(async () => {
|
|
158900
159946
|
init_data_path();
|
|
158901
159947
|
init_logger();
|
|
159948
|
+
init_tool_definition_tokens();
|
|
159949
|
+
init_tool_owner_backfill();
|
|
158902
159950
|
await __promiseAll([
|
|
158903
159951
|
init_sqlite(),
|
|
158904
159952
|
init_migrations()
|
|
@@ -159469,7 +160517,7 @@ var init_storage_source = () => {};
|
|
|
159469
160517
|
function getInsertTagStatement(db) {
|
|
159470
160518
|
let stmt = insertTagStatements.get(db);
|
|
159471
160519
|
if (!stmt) {
|
|
159472
|
-
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 (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
160520
|
+
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
159473
160521
|
insertTagStatements.set(db, stmt);
|
|
159474
160522
|
}
|
|
159475
160523
|
return stmt;
|
|
@@ -159550,7 +160598,8 @@ function toTagEntry(row) {
|
|
|
159550
160598
|
byteSize: row.byte_size,
|
|
159551
160599
|
reasoningByteSize: row.reasoning_byte_size ?? 0,
|
|
159552
160600
|
sessionId: row.session_id,
|
|
159553
|
-
cavemanDepth: typeof row.caveman_depth === "number" && Number.isFinite(row.caveman_depth) ? row.caveman_depth : 0
|
|
160601
|
+
cavemanDepth: typeof row.caveman_depth === "number" && Number.isFinite(row.caveman_depth) ? row.caveman_depth : 0,
|
|
160602
|
+
toolOwnerMessageId: typeof row.tool_owner_message_id === "string" ? row.tool_owner_message_id : null
|
|
159554
160603
|
};
|
|
159555
160604
|
}
|
|
159556
160605
|
function isTagNumberRow(row) {
|
|
@@ -159568,8 +160617,8 @@ function isMaxTagNumberRow(row) {
|
|
|
159568
160617
|
function escapeLikePattern(value) {
|
|
159569
160618
|
return value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
159570
160619
|
}
|
|
159571
|
-
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0) {
|
|
159572
|
-
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness());
|
|
160620
|
+
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null) {
|
|
160621
|
+
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId);
|
|
159573
160622
|
return tagNumber;
|
|
159574
160623
|
}
|
|
159575
160624
|
function updateTagStatus(db, sessionId, tagId, status) {
|
|
@@ -159588,12 +160637,27 @@ function deleteTagsByMessageId(db, sessionId, messageId) {
|
|
|
159588
160637
|
const escapedMessageId = escapeLikePattern(messageId);
|
|
159589
160638
|
const textPartPattern = `${escapedMessageId}:p%`;
|
|
159590
160639
|
const filePartPattern = `${escapedMessageId}:file%`;
|
|
159591
|
-
const
|
|
159592
|
-
|
|
160640
|
+
const messageScopedTags = getTagNumbersByMessageIdStatement(db).all(sessionId, messageId, textPartPattern, filePartPattern).filter(isTagNumberRow).map((row) => row.tag_number);
|
|
160641
|
+
const ownerScopedTagNumbers = getOwnerScopedToolTagNumbers(db, sessionId, messageId);
|
|
160642
|
+
if (messageScopedTags.length === 0 && ownerScopedTagNumbers.length === 0) {
|
|
159593
160643
|
return [];
|
|
159594
160644
|
}
|
|
159595
|
-
|
|
159596
|
-
|
|
160645
|
+
if (messageScopedTags.length > 0) {
|
|
160646
|
+
getDeleteTagsByMessageIdStatement(db).run(sessionId, messageId, textPartPattern, filePartPattern);
|
|
160647
|
+
}
|
|
160648
|
+
if (ownerScopedTagNumbers.length > 0) {
|
|
160649
|
+
deleteToolTagsByOwner(db, sessionId, messageId);
|
|
160650
|
+
}
|
|
160651
|
+
const merged = new Set([...messageScopedTags, ...ownerScopedTagNumbers]);
|
|
160652
|
+
return Array.from(merged).sort((a, b) => a - b);
|
|
160653
|
+
}
|
|
160654
|
+
function getOwnerScopedToolTagNumbers(db, sessionId, ownerMsgId) {
|
|
160655
|
+
let stmt = getOwnerScopedToolTagNumbersStatements.get(db);
|
|
160656
|
+
if (!stmt) {
|
|
160657
|
+
stmt = db.prepare("SELECT tag_number FROM tags WHERE session_id = ? AND type = 'tool' AND tool_owner_message_id = ? ORDER BY tag_number ASC");
|
|
160658
|
+
getOwnerScopedToolTagNumbersStatements.set(db, stmt);
|
|
160659
|
+
}
|
|
160660
|
+
return stmt.all(sessionId, ownerMsgId).filter(isTagNumberRow).map((row) => row.tag_number);
|
|
159597
160661
|
}
|
|
159598
160662
|
function getMaxTagNumberBySession(db, sessionId) {
|
|
159599
160663
|
const row = getMaxTagNumberBySessionStatement(db).get(sessionId);
|
|
@@ -159604,17 +160668,151 @@ function getTagNumberByMessageId(db, sessionId, messageId) {
|
|
|
159604
160668
|
return isTagNumberRow(row) ? row.tag_number : null;
|
|
159605
160669
|
}
|
|
159606
160670
|
function getTagsBySession(db, sessionId) {
|
|
159607
|
-
const rows = db.prepare(
|
|
160671
|
+
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? ORDER BY tag_number ASC, id ASC`).all(sessionId).filter(isTagRow);
|
|
160672
|
+
return rows.map(toTagEntry);
|
|
160673
|
+
}
|
|
160674
|
+
function getActiveTagsBySessionStatement(db) {
|
|
160675
|
+
let stmt = getActiveTagsBySessionStatements.get(db);
|
|
160676
|
+
if (!stmt) {
|
|
160677
|
+
stmt = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND status = 'active' ORDER BY tag_number ASC, id ASC`);
|
|
160678
|
+
getActiveTagsBySessionStatements.set(db, stmt);
|
|
160679
|
+
}
|
|
160680
|
+
return stmt;
|
|
160681
|
+
}
|
|
160682
|
+
function getMaxDroppedTagNumberStatement(db) {
|
|
160683
|
+
let stmt = getMaxDroppedTagNumberStatements.get(db);
|
|
160684
|
+
if (!stmt) {
|
|
160685
|
+
stmt = db.prepare("SELECT COALESCE(MAX(tag_number), 0) AS max_tag_number FROM tags WHERE session_id = ? AND status = 'dropped'");
|
|
160686
|
+
getMaxDroppedTagNumberStatements.set(db, stmt);
|
|
160687
|
+
}
|
|
160688
|
+
return stmt;
|
|
160689
|
+
}
|
|
160690
|
+
function getActiveTagsBySession(db, sessionId) {
|
|
160691
|
+
const rows = getActiveTagsBySessionStatement(db).all(sessionId).filter(isTagRow);
|
|
160692
|
+
return rows.map(toTagEntry);
|
|
160693
|
+
}
|
|
160694
|
+
function getTagsByNumbers(db, sessionId, tagNumbers) {
|
|
160695
|
+
if (tagNumbers.length === 0)
|
|
160696
|
+
return [];
|
|
160697
|
+
if (tagNumbers.length > 900) {
|
|
160698
|
+
const all = [];
|
|
160699
|
+
for (let i = 0;i < tagNumbers.length; i += 900) {
|
|
160700
|
+
all.push(...getTagsByNumbers(db, sessionId, tagNumbers.slice(i, i + 900)));
|
|
160701
|
+
}
|
|
160702
|
+
return all;
|
|
160703
|
+
}
|
|
160704
|
+
const placeholders = tagNumbers.map(() => "?").join(",");
|
|
160705
|
+
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);
|
|
159608
160706
|
return rows.map(toTagEntry);
|
|
159609
160707
|
}
|
|
160708
|
+
function getMaxDroppedTagNumber(db, sessionId) {
|
|
160709
|
+
const row = getMaxDroppedTagNumberStatement(db).get(sessionId);
|
|
160710
|
+
return isMaxTagNumberRow(row) ? row.max_tag_number : 0;
|
|
160711
|
+
}
|
|
159610
160712
|
function getTopNBySize(db, sessionId, n) {
|
|
159611
160713
|
if (n <= 0) {
|
|
159612
160714
|
return [];
|
|
159613
160715
|
}
|
|
159614
|
-
const rows = db.prepare(
|
|
160716
|
+
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);
|
|
159615
160717
|
return rows.map(toTagEntry);
|
|
159616
160718
|
}
|
|
159617
|
-
|
|
160719
|
+
function getGetToolTagNumberByOwnerStatement(db) {
|
|
160720
|
+
let stmt = getToolTagNumberByOwnerStatements.get(db);
|
|
160721
|
+
if (!stmt) {
|
|
160722
|
+
stmt = db.prepare(`SELECT tag_number FROM tags
|
|
160723
|
+
WHERE session_id = ? AND message_id = ?
|
|
160724
|
+
AND type = 'tool' AND tool_owner_message_id = ?
|
|
160725
|
+
LIMIT 1`);
|
|
160726
|
+
getToolTagNumberByOwnerStatements.set(db, stmt);
|
|
160727
|
+
}
|
|
160728
|
+
return stmt;
|
|
160729
|
+
}
|
|
160730
|
+
function getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId) {
|
|
160731
|
+
const row = getGetToolTagNumberByOwnerStatement(db).get(sessionId, callId, ownerMsgId);
|
|
160732
|
+
return isTagNumberRow(row) ? row.tag_number : null;
|
|
160733
|
+
}
|
|
160734
|
+
function isNullOwnerToolTagRow(row) {
|
|
160735
|
+
if (row === null || typeof row !== "object")
|
|
160736
|
+
return false;
|
|
160737
|
+
const r = row;
|
|
160738
|
+
return typeof r.id === "number" && typeof r.tag_number === "number";
|
|
160739
|
+
}
|
|
160740
|
+
function getGetNullOwnerToolTagStatement(db) {
|
|
160741
|
+
let stmt = getNullOwnerToolTagStatements.get(db);
|
|
160742
|
+
if (!stmt) {
|
|
160743
|
+
stmt = db.prepare(`SELECT id, tag_number FROM tags
|
|
160744
|
+
WHERE session_id = ? AND message_id = ?
|
|
160745
|
+
AND type = 'tool' AND tool_owner_message_id IS NULL
|
|
160746
|
+
ORDER BY tag_number ASC
|
|
160747
|
+
LIMIT 1`);
|
|
160748
|
+
getNullOwnerToolTagStatements.set(db, stmt);
|
|
160749
|
+
}
|
|
160750
|
+
return stmt;
|
|
160751
|
+
}
|
|
160752
|
+
function getNullOwnerToolTag(db, sessionId, callId) {
|
|
160753
|
+
const row = getGetNullOwnerToolTagStatement(db).get(sessionId, callId);
|
|
160754
|
+
if (!isNullOwnerToolTagRow(row))
|
|
160755
|
+
return null;
|
|
160756
|
+
return { id: row.id, tagNumber: row.tag_number };
|
|
160757
|
+
}
|
|
160758
|
+
function getAdoptNullOwnerToolTagStatement(db) {
|
|
160759
|
+
let stmt = adoptNullOwnerToolTagStatements.get(db);
|
|
160760
|
+
if (!stmt) {
|
|
160761
|
+
stmt = db.prepare(`UPDATE tags
|
|
160762
|
+
SET tool_owner_message_id = ?
|
|
160763
|
+
WHERE id = ? AND tool_owner_message_id IS NULL`);
|
|
160764
|
+
adoptNullOwnerToolTagStatements.set(db, stmt);
|
|
160765
|
+
}
|
|
160766
|
+
return stmt;
|
|
160767
|
+
}
|
|
160768
|
+
function adoptNullOwnerToolTag(db, rowId, ownerMsgId) {
|
|
160769
|
+
const result = getAdoptNullOwnerToolTagStatement(db).run(ownerMsgId, rowId);
|
|
160770
|
+
return (result.changes ?? 0) === 1;
|
|
160771
|
+
}
|
|
160772
|
+
function getCandidateToolOwners(db, sessionId, callId) {
|
|
160773
|
+
const rows = db.prepare(`SELECT DISTINCT tool_owner_message_id
|
|
160774
|
+
FROM tags
|
|
160775
|
+
WHERE session_id = ?
|
|
160776
|
+
AND message_id = ?
|
|
160777
|
+
AND type = 'tool'
|
|
160778
|
+
AND tool_owner_message_id IS NOT NULL`).all(sessionId, callId);
|
|
160779
|
+
return rows.map((r) => r.tool_owner_message_id);
|
|
160780
|
+
}
|
|
160781
|
+
function pickNearestPriorOwner(candidates, currentMessageId, times) {
|
|
160782
|
+
const currentTime = times.get(currentMessageId);
|
|
160783
|
+
if (typeof currentTime !== "number")
|
|
160784
|
+
return null;
|
|
160785
|
+
let best = null;
|
|
160786
|
+
for (const id of candidates) {
|
|
160787
|
+
const t = times.get(id);
|
|
160788
|
+
if (typeof t !== "number")
|
|
160789
|
+
continue;
|
|
160790
|
+
if (t > currentTime)
|
|
160791
|
+
continue;
|
|
160792
|
+
if (t === currentTime && id >= currentMessageId)
|
|
160793
|
+
continue;
|
|
160794
|
+
if (best === null || t > best.time || t === best.time && id > best.id) {
|
|
160795
|
+
best = { id, time: t };
|
|
160796
|
+
}
|
|
160797
|
+
}
|
|
160798
|
+
return best?.id ?? null;
|
|
160799
|
+
}
|
|
160800
|
+
function getDeleteToolTagsByOwnerStatement(db) {
|
|
160801
|
+
let stmt = deleteToolTagsByOwnerStatements.get(db);
|
|
160802
|
+
if (!stmt) {
|
|
160803
|
+
stmt = db.prepare(`DELETE FROM tags
|
|
160804
|
+
WHERE session_id = ?
|
|
160805
|
+
AND type = 'tool'
|
|
160806
|
+
AND tool_owner_message_id = ?`);
|
|
160807
|
+
deleteToolTagsByOwnerStatements.set(db, stmt);
|
|
160808
|
+
}
|
|
160809
|
+
return stmt;
|
|
160810
|
+
}
|
|
160811
|
+
function deleteToolTagsByOwner(db, sessionId, ownerMsgId) {
|
|
160812
|
+
const result = getDeleteToolTagsByOwnerStatement(db).run(sessionId, ownerMsgId);
|
|
160813
|
+
return result.changes ?? 0;
|
|
160814
|
+
}
|
|
160815
|
+
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, getOwnerScopedToolTagNumbersStatements, 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", getActiveTagsBySessionStatements, getMaxDroppedTagNumberStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, deleteToolTagsByOwnerStatements;
|
|
159618
160816
|
var init_storage_tags = __esm(() => {
|
|
159619
160817
|
insertTagStatements = new WeakMap;
|
|
159620
160818
|
updateTagStatusStatements = new WeakMap;
|
|
@@ -159626,6 +160824,13 @@ var init_storage_tags = __esm(() => {
|
|
|
159626
160824
|
getTagNumberByMessageIdStatements = new WeakMap;
|
|
159627
160825
|
updateTagByteSizeStatements = new WeakMap;
|
|
159628
160826
|
updateTagInputByteSizeStatements = new WeakMap;
|
|
160827
|
+
getOwnerScopedToolTagNumbersStatements = new WeakMap;
|
|
160828
|
+
getActiveTagsBySessionStatements = new WeakMap;
|
|
160829
|
+
getMaxDroppedTagNumberStatements = new WeakMap;
|
|
160830
|
+
getToolTagNumberByOwnerStatements = new WeakMap;
|
|
160831
|
+
getNullOwnerToolTagStatements = new WeakMap;
|
|
160832
|
+
adoptNullOwnerToolTagStatements = new WeakMap;
|
|
160833
|
+
deleteToolTagsByOwnerStatements = new WeakMap;
|
|
159629
160834
|
});
|
|
159630
160835
|
|
|
159631
160836
|
// src/features/magic-context/storage.ts
|
|
@@ -159645,9 +160850,9 @@ var init_storage = __esm(async () => {
|
|
|
159645
160850
|
|
|
159646
160851
|
// src/shared/models-dev-cache.ts
|
|
159647
160852
|
import { createHash as createHash3 } from "node:crypto";
|
|
159648
|
-
import { existsSync as
|
|
160853
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
|
|
159649
160854
|
import { homedir as homedir8, platform as platform3 } from "node:os";
|
|
159650
|
-
import { join as
|
|
160855
|
+
import { join as join16 } from "node:path";
|
|
159651
160856
|
function hashFast(input) {
|
|
159652
160857
|
return createHash3("sha1").update(input).digest("hex");
|
|
159653
160858
|
}
|
|
@@ -159658,16 +160863,16 @@ function getModelsJsonPath() {
|
|
|
159658
160863
|
const cacheBase = getCacheDir();
|
|
159659
160864
|
const source = process.env.OPENCODE_MODELS_URL?.trim();
|
|
159660
160865
|
const filename = source && source !== "https://models.dev" ? `models-${hashFast(source)}.json` : "models.json";
|
|
159661
|
-
return
|
|
160866
|
+
return join16(cacheBase, "opencode", filename);
|
|
159662
160867
|
}
|
|
159663
160868
|
function getOpencodeConfigPath() {
|
|
159664
160869
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
159665
|
-
const configDir = envDir ? envDir : platform3() === "win32" ?
|
|
159666
|
-
const jsonc =
|
|
159667
|
-
if (
|
|
160870
|
+
const configDir = envDir ? envDir : platform3() === "win32" ? join16(homedir8(), ".config", "opencode") : join16(process.env.XDG_CONFIG_HOME || join16(homedir8(), ".config"), "opencode");
|
|
160871
|
+
const jsonc = join16(configDir, "opencode.jsonc");
|
|
160872
|
+
if (existsSync11(jsonc))
|
|
159668
160873
|
return jsonc;
|
|
159669
|
-
const json2 =
|
|
159670
|
-
if (
|
|
160874
|
+
const json2 = join16(configDir, "opencode.json");
|
|
160875
|
+
if (existsSync11(json2))
|
|
159671
160876
|
return json2;
|
|
159672
160877
|
return null;
|
|
159673
160878
|
}
|
|
@@ -159680,23 +160885,12 @@ function resolveLimit(limit) {
|
|
|
159680
160885
|
return limit.context;
|
|
159681
160886
|
return;
|
|
159682
160887
|
}
|
|
159683
|
-
function resolveInterleavedField(interleaved) {
|
|
159684
|
-
if (interleaved && typeof interleaved === "object" && typeof interleaved.field === "string" && interleaved.field.length > 0) {
|
|
159685
|
-
return interleaved.field;
|
|
159686
|
-
}
|
|
159687
|
-
return;
|
|
159688
|
-
}
|
|
159689
160888
|
function setCachedModelMetadata(cache, key, model) {
|
|
159690
160889
|
const limit = resolveLimit(model?.limit);
|
|
159691
|
-
|
|
159692
|
-
if (limit === undefined && interleavedField === undefined) {
|
|
160890
|
+
if (limit === undefined) {
|
|
159693
160891
|
return;
|
|
159694
160892
|
}
|
|
159695
|
-
const value = {};
|
|
159696
|
-
if (limit !== undefined)
|
|
159697
|
-
value.limit = limit;
|
|
159698
|
-
if (interleavedField !== undefined)
|
|
159699
|
-
value.interleavedField = interleavedField;
|
|
160893
|
+
const value = { limit };
|
|
159700
160894
|
cache.set(key, value);
|
|
159701
160895
|
const modes = model?.experimental?.modes;
|
|
159702
160896
|
if (modes && typeof modes === "object") {
|
|
@@ -159710,7 +160904,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
159710
160904
|
const modelsJsonPath = getModelsJsonPath();
|
|
159711
160905
|
let fileFound = false;
|
|
159712
160906
|
try {
|
|
159713
|
-
if (
|
|
160907
|
+
if (existsSync11(modelsJsonPath)) {
|
|
159714
160908
|
fileFound = true;
|
|
159715
160909
|
const raw = readFileSync7(modelsJsonPath, "utf-8");
|
|
159716
160910
|
const data = JSON.parse(raw);
|
|
@@ -159727,7 +160921,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
159727
160921
|
}
|
|
159728
160922
|
try {
|
|
159729
160923
|
const configPath = getOpencodeConfigPath();
|
|
159730
|
-
if (configPath &&
|
|
160924
|
+
if (configPath && existsSync11(configPath)) {
|
|
159731
160925
|
let raw = readFileSync7(configPath, "utf-8");
|
|
159732
160926
|
raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
|
|
159733
160927
|
const config2 = JSON.parse(raw);
|
|
@@ -159768,8 +160962,18 @@ async function refreshModelLimitsFromApi(client) {
|
|
|
159768
160962
|
const previousSize = apiCache?.size ?? null;
|
|
159769
160963
|
apiCache = map2;
|
|
159770
160964
|
apiLoadedAt = Date.now();
|
|
159771
|
-
if (previousSize === null
|
|
159772
|
-
|
|
160965
|
+
if (previousSize === null) {
|
|
160966
|
+
recentlySeenApiSizes.add(map2.size);
|
|
160967
|
+
sessionLog("global", `models-dev-cache: API layer loaded ${map2.size} model metadata entries`);
|
|
160968
|
+
} else if (previousSize !== map2.size) {
|
|
160969
|
+
const sizeAlreadySeen = recentlySeenApiSizes.has(map2.size);
|
|
160970
|
+
recentlySeenApiSizes.add(map2.size);
|
|
160971
|
+
if (!sizeAlreadySeen) {
|
|
160972
|
+
sessionLog("global", `models-dev-cache: API layer loaded ${map2.size} model metadata entries (was ${previousSize})`);
|
|
160973
|
+
} else if (!oscillationLogged) {
|
|
160974
|
+
oscillationLogged = true;
|
|
160975
|
+
sessionLog("global", `models-dev-cache: API count oscillating between ${[...recentlySeenApiSizes].sort((a, b) => a - b).join(" ↔ ")} — likely upstream provider plugin returning slightly different model sets between calls (e.g. github-copilot's /models endpoint toggling model_picker_enabled). Suppressing further size-change logs.`);
|
|
160976
|
+
}
|
|
159773
160977
|
}
|
|
159774
160978
|
} catch (error48) {
|
|
159775
160979
|
sessionLog("global", "models-dev-cache: API refresh failed:", error48 instanceof Error ? error48.message : String(error48));
|
|
@@ -159789,27 +160993,12 @@ function getModelsDevContextLimit(providerID, modelID) {
|
|
|
159789
160993
|
}
|
|
159790
160994
|
return fileCache.get(key)?.limit;
|
|
159791
160995
|
}
|
|
159792
|
-
|
|
159793
|
-
const key = `${providerID}/${modelID}`;
|
|
159794
|
-
if (apiCache) {
|
|
159795
|
-
const fromApi = apiCache.get(key)?.interleavedField;
|
|
159796
|
-
if (typeof fromApi === "string" && fromApi.length > 0) {
|
|
159797
|
-
return fromApi;
|
|
159798
|
-
}
|
|
159799
|
-
}
|
|
159800
|
-
const now = Date.now();
|
|
159801
|
-
if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
|
|
159802
|
-
fileLastAttempt = now;
|
|
159803
|
-
fileCache = loadModelsDevMetadataFromFile();
|
|
159804
|
-
}
|
|
159805
|
-
const fromFile = fileCache.get(key)?.interleavedField;
|
|
159806
|
-
return typeof fromFile === "string" && fromFile.length > 0 ? fromFile : undefined;
|
|
159807
|
-
}
|
|
159808
|
-
var RELOAD_INTERVAL_MS, apiCache = null, apiLoadedAt = 0, fileCache = null, fileLastAttempt = 0;
|
|
160996
|
+
var RELOAD_INTERVAL_MS, apiCache = null, apiLoadedAt = 0, recentlySeenApiSizes, oscillationLogged = false, fileCache = null, fileLastAttempt = 0;
|
|
159809
160997
|
var init_models_dev_cache = __esm(() => {
|
|
159810
160998
|
init_data_path();
|
|
159811
160999
|
init_logger();
|
|
159812
161000
|
RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
161001
|
+
recentlySeenApiSizes = new Set;
|
|
159813
161002
|
});
|
|
159814
161003
|
|
|
159815
161004
|
// src/shared/rpc-notifications.ts
|
|
@@ -160059,9 +161248,9 @@ var init_compartment_runner_validation = __esm(async () => {
|
|
|
160059
161248
|
});
|
|
160060
161249
|
|
|
160061
161250
|
// src/hooks/magic-context/compartment-runner-historian.ts
|
|
160062
|
-
import { mkdirSync as
|
|
161251
|
+
import { mkdirSync as mkdirSync4, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
160063
161252
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
160064
|
-
import { join as
|
|
161253
|
+
import { join as join17 } from "node:path";
|
|
160065
161254
|
async function runValidatedHistorianPass(args) {
|
|
160066
161255
|
const firstRun = await runHistorianPrompt({
|
|
160067
161256
|
...args,
|
|
@@ -160301,11 +161490,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
160301
161490
|
}
|
|
160302
161491
|
function dumpHistorianResponse(sessionId, label, text) {
|
|
160303
161492
|
try {
|
|
160304
|
-
|
|
161493
|
+
mkdirSync4(HISTORIAN_RESPONSE_DUMP_DIR, { recursive: true });
|
|
160305
161494
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
160306
161495
|
const safeLabel = sanitizeDumpName(label);
|
|
160307
|
-
const dumpPath =
|
|
160308
|
-
|
|
161496
|
+
const dumpPath = join17(HISTORIAN_RESPONSE_DUMP_DIR, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
161497
|
+
writeFileSync4(dumpPath, text, "utf8");
|
|
160309
161498
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
160310
161499
|
label,
|
|
160311
161500
|
dumpPath
|
|
@@ -160329,7 +161518,7 @@ var init_compartment_runner_historian = __esm(async () => {
|
|
|
160329
161518
|
init_assistant_message_extractor();
|
|
160330
161519
|
init_compartment_prompt();
|
|
160331
161520
|
await init_compartment_runner_validation();
|
|
160332
|
-
HISTORIAN_RESPONSE_DUMP_DIR =
|
|
161521
|
+
HISTORIAN_RESPONSE_DUMP_DIR = join17(tmpdir2(), "magic-context-historian");
|
|
160333
161522
|
});
|
|
160334
161523
|
|
|
160335
161524
|
// src/hooks/magic-context/compartment-runner-state-xml.ts
|
|
@@ -161308,7 +162497,7 @@ var init_derive_budgets = __esm(() => {
|
|
|
161308
162497
|
});
|
|
161309
162498
|
|
|
161310
162499
|
// src/features/magic-context/compaction-marker.ts
|
|
161311
|
-
import { join as
|
|
162500
|
+
import { join as join18 } from "node:path";
|
|
161312
162501
|
function randomBase62(length) {
|
|
161313
162502
|
const chars = [];
|
|
161314
162503
|
for (let i = 0;i < length; i++) {
|
|
@@ -161328,7 +162517,7 @@ function generatePartId(timestampMs, counter = 0n) {
|
|
|
161328
162517
|
return generateId("prt", timestampMs, counter);
|
|
161329
162518
|
}
|
|
161330
162519
|
function getOpenCodeDbPath3() {
|
|
161331
|
-
return
|
|
162520
|
+
return join18(getDataDir(), "opencode", "opencode.db");
|
|
161332
162521
|
}
|
|
161333
162522
|
function isOpenCodeSchemaCompatible(db, dbPath) {
|
|
161334
162523
|
if (cachedSchemaCompatible?.path === dbPath) {
|
|
@@ -161465,7 +162654,7 @@ var init_compaction_marker = __esm(async () => {
|
|
|
161465
162654
|
});
|
|
161466
162655
|
|
|
161467
162656
|
// src/hooks/magic-context/compaction-marker-manager.ts
|
|
161468
|
-
import { join as
|
|
162657
|
+
import { join as join19 } from "node:path";
|
|
161469
162658
|
function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
|
|
161470
162659
|
const existing = getPersistedCompactionMarkerState(db, sessionId);
|
|
161471
162660
|
if (existing) {
|
|
@@ -161508,7 +162697,7 @@ function removeCompactionMarkerForSession(db, sessionId) {
|
|
|
161508
162697
|
}
|
|
161509
162698
|
}
|
|
161510
162699
|
function checkCompactionMarkerConsistency(db) {
|
|
161511
|
-
const opencodeDbPath =
|
|
162700
|
+
const opencodeDbPath = join19(getDataDir(), "opencode", "opencode.db");
|
|
161512
162701
|
let opencodeDb;
|
|
161513
162702
|
try {
|
|
161514
162703
|
opencodeDb = new Database(opencodeDbPath, { readonly: true });
|
|
@@ -161895,31 +163084,31 @@ var init_caveman = __esm(() => {
|
|
|
161895
163084
|
});
|
|
161896
163085
|
|
|
161897
163086
|
// src/hooks/magic-context/historian-state-file.ts
|
|
161898
|
-
import { mkdirSync as
|
|
163087
|
+
import { mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
161899
163088
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
161900
|
-
import { join as
|
|
163089
|
+
import { join as join20 } from "node:path";
|
|
161901
163090
|
function maybeWriteHistorianStateFile(sessionId, existingState) {
|
|
161902
163091
|
if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
|
|
161903
163092
|
return;
|
|
161904
163093
|
try {
|
|
161905
|
-
|
|
161906
|
-
const
|
|
161907
|
-
|
|
161908
|
-
return
|
|
163094
|
+
mkdirSync5(HISTORIAN_STATE_DIR, { recursive: true });
|
|
163095
|
+
const path5 = join20(HISTORIAN_STATE_DIR, `state-${sessionId}-${Date.now()}.xml`);
|
|
163096
|
+
writeFileSync5(path5, existingState, "utf8");
|
|
163097
|
+
return path5;
|
|
161909
163098
|
} catch {
|
|
161910
163099
|
return;
|
|
161911
163100
|
}
|
|
161912
163101
|
}
|
|
161913
|
-
function cleanupHistorianStateFile(
|
|
161914
|
-
if (!
|
|
163102
|
+
function cleanupHistorianStateFile(path5) {
|
|
163103
|
+
if (!path5)
|
|
161915
163104
|
return;
|
|
161916
163105
|
try {
|
|
161917
|
-
unlinkSync2(
|
|
163106
|
+
unlinkSync2(path5);
|
|
161918
163107
|
} catch {}
|
|
161919
163108
|
}
|
|
161920
163109
|
var HISTORIAN_STATE_INLINE_THRESHOLD = 30000, HISTORIAN_STATE_DIR;
|
|
161921
163110
|
var init_historian_state_file = __esm(() => {
|
|
161922
|
-
HISTORIAN_STATE_DIR =
|
|
163111
|
+
HISTORIAN_STATE_DIR = join20(tmpdir3(), "magic-context-historian");
|
|
161923
163112
|
});
|
|
161924
163113
|
|
|
161925
163114
|
// src/features/magic-context/memory/embedding-backfill.ts
|
|
@@ -162424,12 +163613,24 @@ var init_compartment_runner_compressor = __esm(async () => {
|
|
|
162424
163613
|
// src/hooks/magic-context/compartment-runner-drop-queue.ts
|
|
162425
163614
|
function queueDropsForCompartmentalizedMessages(db, sessionId, upToMessageIndex) {
|
|
162426
163615
|
const tags = getTagsBySession(db, sessionId);
|
|
162427
|
-
const
|
|
163616
|
+
const { messageFileKeys, toolObservations } = getRawSessionTagKeysThrough(sessionId, upToMessageIndex);
|
|
162428
163617
|
let dropsQueued = 0;
|
|
162429
163618
|
for (const tag of tags) {
|
|
162430
163619
|
if (tag.status !== "active")
|
|
162431
163620
|
continue;
|
|
162432
|
-
if (
|
|
163621
|
+
if (tag.type === "tool") {
|
|
163622
|
+
const observedOwners = toolObservations.get(tag.messageId);
|
|
163623
|
+
if (!observedOwners)
|
|
163624
|
+
continue;
|
|
163625
|
+
if (tag.toolOwnerMessageId !== null) {
|
|
163626
|
+
if (!observedOwners.has(tag.toolOwnerMessageId))
|
|
163627
|
+
continue;
|
|
163628
|
+
}
|
|
163629
|
+
queuePendingOp(db, sessionId, tag.tagNumber, "drop");
|
|
163630
|
+
dropsQueued += 1;
|
|
163631
|
+
continue;
|
|
163632
|
+
}
|
|
163633
|
+
if (messageFileKeys.has(tag.messageId)) {
|
|
162433
163634
|
queuePendingOp(db, sessionId, tag.tagNumber, "drop");
|
|
162434
163635
|
dropsQueued += 1;
|
|
162435
163636
|
}
|
|
@@ -162989,8 +164190,8 @@ var exports_tui_config = {};
|
|
|
162989
164190
|
__export(exports_tui_config, {
|
|
162990
164191
|
ensureTuiPluginEntry: () => ensureTuiPluginEntry
|
|
162991
164192
|
});
|
|
162992
|
-
import { existsSync as
|
|
162993
|
-
import { dirname as
|
|
164193
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
|
|
164194
|
+
import { dirname as dirname6, join as join23 } from "node:path";
|
|
162994
164195
|
function isMagicContextEntry(entry) {
|
|
162995
164196
|
if (!entry)
|
|
162996
164197
|
return false;
|
|
@@ -163004,11 +164205,11 @@ function isMagicContextEntry(entry) {
|
|
|
163004
164205
|
}
|
|
163005
164206
|
function resolveTuiConfigPath() {
|
|
163006
164207
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
163007
|
-
const jsoncPath =
|
|
163008
|
-
const jsonPath =
|
|
163009
|
-
if (
|
|
164208
|
+
const jsoncPath = join23(configDir, "tui.jsonc");
|
|
164209
|
+
const jsonPath = join23(configDir, "tui.json");
|
|
164210
|
+
if (existsSync13(jsoncPath))
|
|
163010
164211
|
return jsoncPath;
|
|
163011
|
-
if (
|
|
164212
|
+
if (existsSync13(jsonPath))
|
|
163012
164213
|
return jsonPath;
|
|
163013
164214
|
return jsonPath;
|
|
163014
164215
|
}
|
|
@@ -163016,7 +164217,7 @@ function ensureTuiPluginEntry() {
|
|
|
163016
164217
|
try {
|
|
163017
164218
|
const configPath = resolveTuiConfigPath();
|
|
163018
164219
|
let config2 = {};
|
|
163019
|
-
if (
|
|
164220
|
+
if (existsSync13(configPath)) {
|
|
163020
164221
|
const raw = readFileSync9(configPath, "utf-8");
|
|
163021
164222
|
config2 = import_comment_json3.parse(raw) ?? {};
|
|
163022
164223
|
}
|
|
@@ -163036,8 +164237,8 @@ function ensureTuiPluginEntry() {
|
|
|
163036
164237
|
plugins.push(PLUGIN_ENTRY);
|
|
163037
164238
|
}
|
|
163038
164239
|
config2.plugin = plugins;
|
|
163039
|
-
|
|
163040
|
-
|
|
164240
|
+
mkdirSync7(dirname6(configPath), { recursive: true });
|
|
164241
|
+
writeFileSync7(configPath, `${import_comment_json3.stringify(config2, null, 2)}
|
|
163041
164242
|
`);
|
|
163042
164243
|
log(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
163043
164244
|
return true;
|
|
@@ -163813,42 +165014,8 @@ async function runSidekick(deps) {
|
|
|
163813
165014
|
}
|
|
163814
165015
|
}
|
|
163815
165016
|
|
|
163816
|
-
// src/
|
|
163817
|
-
|
|
163818
|
-
var measurements = new Map;
|
|
163819
|
-
function keyFor(providerID, modelID, agentName) {
|
|
163820
|
-
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
163821
|
-
return `${providerID}/${modelID}/${agent}`;
|
|
163822
|
-
}
|
|
163823
|
-
function recordToolDefinition(providerID, modelID, agentName, toolID, description, parameters) {
|
|
163824
|
-
if (!providerID || !modelID || !toolID)
|
|
163825
|
-
return;
|
|
163826
|
-
const key = keyFor(providerID, modelID, agentName);
|
|
163827
|
-
let paramsText = "";
|
|
163828
|
-
try {
|
|
163829
|
-
paramsText = parameters === undefined ? "" : JSON.stringify(parameters);
|
|
163830
|
-
} catch {
|
|
163831
|
-
paramsText = "";
|
|
163832
|
-
}
|
|
163833
|
-
const tokens = estimateTokens(description ?? "") + estimateTokens(paramsText);
|
|
163834
|
-
let inner = measurements.get(key);
|
|
163835
|
-
if (!inner) {
|
|
163836
|
-
inner = new Map;
|
|
163837
|
-
measurements.set(key, inner);
|
|
163838
|
-
}
|
|
163839
|
-
inner.set(toolID, tokens);
|
|
163840
|
-
}
|
|
163841
|
-
function getMeasuredToolDefinitionTokens(providerID, modelID, agentName) {
|
|
163842
|
-
if (!providerID || !modelID)
|
|
163843
|
-
return;
|
|
163844
|
-
const inner = measurements.get(keyFor(providerID, modelID, agentName));
|
|
163845
|
-
if (!inner || inner.size === 0)
|
|
163846
|
-
return;
|
|
163847
|
-
let total = 0;
|
|
163848
|
-
for (const tokens of inner.values())
|
|
163849
|
-
total += tokens;
|
|
163850
|
-
return total;
|
|
163851
|
-
}
|
|
165017
|
+
// src/index.ts
|
|
165018
|
+
init_tool_definition_tokens();
|
|
163852
165019
|
|
|
163853
165020
|
// src/hooks/auto-update-checker/index.ts
|
|
163854
165021
|
init_logger();
|
|
@@ -164130,24 +165297,27 @@ function stripPackageNameFromPath(pathValue, packageName) {
|
|
|
164130
165297
|
}
|
|
164131
165298
|
return current;
|
|
164132
165299
|
}
|
|
164133
|
-
function
|
|
164134
|
-
const lockPath = join5(installDir, "
|
|
165300
|
+
function removeFromPackageLock(installDir, packageName) {
|
|
165301
|
+
const lockPath = join5(installDir, "package-lock.json");
|
|
164135
165302
|
if (!existsSync5(lockPath))
|
|
164136
165303
|
return false;
|
|
164137
165304
|
try {
|
|
164138
165305
|
const lock = import_comment_json2.parse(readFileSync5(lockPath, "utf-8"));
|
|
164139
165306
|
let modified = false;
|
|
164140
|
-
if (lock.
|
|
164141
|
-
|
|
164142
|
-
|
|
165307
|
+
if (lock.packages) {
|
|
165308
|
+
const key = `node_modules/${packageName}`;
|
|
165309
|
+
if (lock.packages[key] !== undefined) {
|
|
165310
|
+
delete lock.packages[key];
|
|
165311
|
+
modified = true;
|
|
165312
|
+
}
|
|
164143
165313
|
}
|
|
164144
|
-
if (lock.
|
|
164145
|
-
delete lock.
|
|
165314
|
+
if (lock.dependencies?.[packageName]) {
|
|
165315
|
+
delete lock.dependencies[packageName];
|
|
164146
165316
|
modified = true;
|
|
164147
165317
|
}
|
|
164148
165318
|
if (modified) {
|
|
164149
165319
|
writeFileSync2(lockPath, JSON.stringify(lock, null, 2));
|
|
164150
|
-
log(`[auto-update-checker] Removed from
|
|
165320
|
+
log(`[auto-update-checker] Removed from package-lock.json: ${packageName}`);
|
|
164151
165321
|
}
|
|
164152
165322
|
return modified;
|
|
164153
165323
|
} catch {
|
|
@@ -164212,7 +165382,7 @@ function preparePackageUpdate(version2, packageName = PACKAGE_NAME, runtimePacka
|
|
|
164212
165382
|
if (!ensureDependencyVersion(installContext.packageJsonPath, packageName, version2))
|
|
164213
165383
|
return null;
|
|
164214
165384
|
const packageRemoved = removeInstalledPackage(installContext.installDir, packageName);
|
|
164215
|
-
const lockRemoved =
|
|
165385
|
+
const lockRemoved = removeFromPackageLock(installContext.installDir, packageName);
|
|
164216
165386
|
if (!packageRemoved && !lockRemoved) {
|
|
164217
165387
|
log(`[auto-update-checker] No cached package artifacts removed for ${packageName}; continuing with updated dependency spec`);
|
|
164218
165388
|
}
|
|
@@ -164222,12 +165392,12 @@ function preparePackageUpdate(version2, packageName = PACKAGE_NAME, runtimePacka
|
|
|
164222
165392
|
return null;
|
|
164223
165393
|
}
|
|
164224
165394
|
}
|
|
164225
|
-
async function
|
|
165395
|
+
async function runNpmInstallSafe(installDir, options = {}) {
|
|
164226
165396
|
let timeout = null;
|
|
164227
165397
|
try {
|
|
164228
165398
|
if (options.signal?.aborted)
|
|
164229
165399
|
return false;
|
|
164230
|
-
const proc = spawn("
|
|
165400
|
+
const proc = spawn("npm", ["install", "--no-audit", "--no-fund", "--no-progress"], {
|
|
164231
165401
|
cwd: installDir,
|
|
164232
165402
|
stdio: "pipe"
|
|
164233
165403
|
});
|
|
@@ -164252,7 +165422,7 @@ async function runBunInstallSafe(installDir, options = {}) {
|
|
|
164252
165422
|
}
|
|
164253
165423
|
return result;
|
|
164254
165424
|
} catch (err) {
|
|
164255
|
-
warn2(`[auto-update-checker]
|
|
165425
|
+
warn2(`[auto-update-checker] npm install error: ${String(err)}`);
|
|
164256
165426
|
return false;
|
|
164257
165427
|
} finally {
|
|
164258
165428
|
if (timeout)
|
|
@@ -164370,7 +165540,7 @@ async function runBackgroundUpdateCheck(ctx, options) {
|
|
|
164370
165540
|
warn3("[auto-update-checker] Failed to prepare install root for auto-update");
|
|
164371
165541
|
return;
|
|
164372
165542
|
}
|
|
164373
|
-
const installSuccess = await
|
|
165543
|
+
const installSuccess = await runNpmInstallSafe(installDir, { signal: options.signal });
|
|
164374
165544
|
if (installSuccess) {
|
|
164375
165545
|
showToast(ctx, "Magic Context Updated!", `v${currentVersion} → v${latestVersion}
|
|
164376
165546
|
Restart OpenCode to apply.`, "success", 8000);
|
|
@@ -164378,7 +165548,7 @@ Restart OpenCode to apply.`, "success", 8000);
|
|
|
164378
165548
|
return;
|
|
164379
165549
|
}
|
|
164380
165550
|
showToast(ctx, `Magic Context ${latestVersion}`, `v${latestVersion} available, but auto-update failed to install it. Check logs or retry manually.`, "error", 8000);
|
|
164381
|
-
warn3("[auto-update-checker]
|
|
165551
|
+
warn3("[auto-update-checker] npm install failed; update not installed");
|
|
164382
165552
|
}
|
|
164383
165553
|
function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
|
|
164384
165554
|
ctx.client.tui.showToast({ body: { title, message, variant, duration: duration3 } }).catch(() => {});
|
|
@@ -164395,7 +165565,8 @@ function createLiveSessionState() {
|
|
|
164395
165565
|
agentBySession: new Map,
|
|
164396
165566
|
historyRefreshSessions: new Set,
|
|
164397
165567
|
systemPromptRefreshSessions: new Set,
|
|
164398
|
-
pendingMaterializationSessions: new Set
|
|
165568
|
+
pendingMaterializationSessions: new Set,
|
|
165569
|
+
sessionDirectoryBySession: new Map
|
|
164399
165570
|
};
|
|
164400
165571
|
}
|
|
164401
165572
|
|
|
@@ -164562,8 +165733,8 @@ init_assistant_message_extractor();
|
|
|
164562
165733
|
init_data_path();
|
|
164563
165734
|
init_logger();
|
|
164564
165735
|
await init_sqlite();
|
|
164565
|
-
import { existsSync as
|
|
164566
|
-
import { join as
|
|
165736
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
165737
|
+
import { join as join12 } from "node:path";
|
|
164567
165738
|
|
|
164568
165739
|
// src/features/magic-context/key-files/identify-key-files.ts
|
|
164569
165740
|
init_logger();
|
|
@@ -164954,11 +166125,11 @@ function countNewIds(beforeIds, afterIds) {
|
|
|
164954
166125
|
return count;
|
|
164955
166126
|
}
|
|
164956
166127
|
function getOpenCodeDbPath2() {
|
|
164957
|
-
return
|
|
166128
|
+
return join12(getDataDir(), "opencode", "opencode.db");
|
|
164958
166129
|
}
|
|
164959
166130
|
function openOpenCodeDb() {
|
|
164960
166131
|
const dbPath = getOpenCodeDbPath2();
|
|
164961
|
-
if (!
|
|
166132
|
+
if (!existsSync8(dbPath)) {
|
|
164962
166133
|
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
164963
166134
|
return null;
|
|
164964
166135
|
}
|
|
@@ -165208,8 +166379,8 @@ async function runDream(args) {
|
|
|
165208
166379
|
try {
|
|
165209
166380
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
165210
166381
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
165211
|
-
architecture:
|
|
165212
|
-
structure:
|
|
166382
|
+
architecture: existsSync8(join12(docsDir, "ARCHITECTURE.md")),
|
|
166383
|
+
structure: existsSync8(join12(docsDir, "STRUCTURE.md"))
|
|
165213
166384
|
} : undefined;
|
|
165214
166385
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
165215
166386
|
id: um.id,
|
|
@@ -166535,14 +167706,46 @@ function createScheduler(config2) {
|
|
|
166535
167706
|
|
|
166536
167707
|
// src/features/magic-context/tagger.ts
|
|
166537
167708
|
init_storage_tags();
|
|
167709
|
+
var TOOL_COMPOSITE_KEY_SEP = "\x00";
|
|
167710
|
+
function makeToolCompositeKey(ownerMsgId, callId) {
|
|
167711
|
+
return `${ownerMsgId}${TOOL_COMPOSITE_KEY_SEP}${callId}`;
|
|
167712
|
+
}
|
|
166538
167713
|
var GET_COUNTER_SQL = `SELECT counter FROM session_meta WHERE session_id = ?`;
|
|
166539
|
-
var GET_ASSIGNMENTS_SQL = "SELECT message_id, tag_number FROM tags WHERE session_id = ? ORDER BY tag_number ASC";
|
|
167714
|
+
var GET_ASSIGNMENTS_SQL = "SELECT message_id, tag_number, type, tool_owner_message_id FROM tags WHERE session_id = ? ORDER BY tag_number ASC";
|
|
167715
|
+
var PROBE_DATA_VERSION_SQL = "PRAGMA main.data_version";
|
|
167716
|
+
var PROBE_TOTAL_CHANGES_SQL = "SELECT total_changes() AS tc";
|
|
167717
|
+
var probeDataVersionStatements = new WeakMap;
|
|
167718
|
+
var probeTotalChangesStatements = new WeakMap;
|
|
167719
|
+
function getProbeDataVersionStatement(db) {
|
|
167720
|
+
let stmt = probeDataVersionStatements.get(db);
|
|
167721
|
+
if (!stmt) {
|
|
167722
|
+
stmt = db.prepare(PROBE_DATA_VERSION_SQL);
|
|
167723
|
+
probeDataVersionStatements.set(db, stmt);
|
|
167724
|
+
}
|
|
167725
|
+
return stmt;
|
|
167726
|
+
}
|
|
167727
|
+
function getProbeTotalChangesStatement(db) {
|
|
167728
|
+
let stmt = probeTotalChangesStatements.get(db);
|
|
167729
|
+
if (!stmt) {
|
|
167730
|
+
stmt = db.prepare(PROBE_TOTAL_CHANGES_SQL);
|
|
167731
|
+
probeTotalChangesStatements.set(db, stmt);
|
|
167732
|
+
}
|
|
167733
|
+
return stmt;
|
|
167734
|
+
}
|
|
166540
167735
|
function isAssignmentRow(row) {
|
|
166541
167736
|
if (row === null || typeof row !== "object") {
|
|
166542
167737
|
return false;
|
|
166543
167738
|
}
|
|
166544
167739
|
const candidate = row;
|
|
166545
|
-
|
|
167740
|
+
if (typeof candidate.message_id !== "string")
|
|
167741
|
+
return false;
|
|
167742
|
+
if (typeof candidate.tag_number !== "number")
|
|
167743
|
+
return false;
|
|
167744
|
+
if (candidate.type !== "message" && candidate.type !== "tool" && candidate.type !== "file")
|
|
167745
|
+
return false;
|
|
167746
|
+
if (candidate.tool_owner_message_id !== null && typeof candidate.tool_owner_message_id !== "string")
|
|
167747
|
+
return false;
|
|
167748
|
+
return true;
|
|
166546
167749
|
}
|
|
166547
167750
|
var UPSERT_COUNTER_SQL = `
|
|
166548
167751
|
INSERT INTO session_meta (session_id, counter, harness)
|
|
@@ -166576,6 +167779,7 @@ var MAX_TAG_ALLOC_RETRIES = 5;
|
|
|
166576
167779
|
function createTagger() {
|
|
166577
167780
|
const counters = new Map;
|
|
166578
167781
|
const assignments = new Map;
|
|
167782
|
+
const loadSignatures = new Map;
|
|
166579
167783
|
function getSessionAssignments(sessionId) {
|
|
166580
167784
|
let map2 = assignments.get(sessionId);
|
|
166581
167785
|
if (!map2) {
|
|
@@ -166594,15 +167798,15 @@ function createTagger() {
|
|
|
166594
167798
|
counters.set(sessionId, next);
|
|
166595
167799
|
getUpsertCounterStatement(db).run(sessionId, next, getHarness());
|
|
166596
167800
|
}
|
|
166597
|
-
function
|
|
167801
|
+
function allocateTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize, toolName, inputByteSize, toolOwnerMessageId, mapKey, dbExistingLookup) {
|
|
166598
167802
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
166599
|
-
const existing = sessionAssignments.get(
|
|
167803
|
+
const existing = sessionAssignments.get(mapKey);
|
|
166600
167804
|
if (existing !== undefined) {
|
|
166601
167805
|
return existing;
|
|
166602
167806
|
}
|
|
166603
|
-
const dbExisting =
|
|
167807
|
+
const dbExisting = dbExistingLookup();
|
|
166604
167808
|
if (dbExisting !== null) {
|
|
166605
|
-
sessionAssignments.set(
|
|
167809
|
+
sessionAssignments.set(mapKey, dbExisting);
|
|
166606
167810
|
syncCounterAtLeast(sessionId, db, dbExisting);
|
|
166607
167811
|
return dbExisting;
|
|
166608
167812
|
}
|
|
@@ -166612,16 +167816,16 @@ function createTagger() {
|
|
|
166612
167816
|
const next = Math.max(memCounter, dbMax) + 1;
|
|
166613
167817
|
try {
|
|
166614
167818
|
db.transaction(() => {
|
|
166615
|
-
insertTag(db, sessionId, messageId, type, byteSize2, next, reasoningByteSize, toolName, inputByteSize);
|
|
167819
|
+
insertTag(db, sessionId, messageId, type, byteSize2, next, reasoningByteSize, toolName, inputByteSize, toolOwnerMessageId);
|
|
166616
167820
|
getUpsertCounterStatement(db).run(sessionId, next, getHarness());
|
|
166617
167821
|
})();
|
|
166618
167822
|
} catch (error48) {
|
|
166619
167823
|
if (!isUniqueConstraintError(error48)) {
|
|
166620
167824
|
throw error48;
|
|
166621
167825
|
}
|
|
166622
|
-
const racedRow =
|
|
167826
|
+
const racedRow = dbExistingLookup();
|
|
166623
167827
|
if (racedRow !== null) {
|
|
166624
|
-
sessionAssignments.set(
|
|
167828
|
+
sessionAssignments.set(mapKey, racedRow);
|
|
166625
167829
|
syncCounterAtLeast(sessionId, db, racedRow);
|
|
166626
167830
|
return racedRow;
|
|
166627
167831
|
}
|
|
@@ -166630,51 +167834,124 @@ function createTagger() {
|
|
|
166630
167834
|
continue;
|
|
166631
167835
|
}
|
|
166632
167836
|
counters.set(sessionId, next);
|
|
166633
|
-
sessionAssignments.set(
|
|
167837
|
+
sessionAssignments.set(mapKey, next);
|
|
166634
167838
|
return next;
|
|
166635
167839
|
}
|
|
166636
|
-
throw new Error(`tagger.
|
|
167840
|
+
throw new Error(`tagger.allocateTag: failed to allocate tag for session=${sessionId} key=${mapKey} after ${MAX_TAG_ALLOC_RETRIES} retries`);
|
|
167841
|
+
}
|
|
167842
|
+
function assignTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize = 0, toolName = null, inputByteSize = 0) {
|
|
167843
|
+
if (type === "tool") {
|
|
167844
|
+
throw new Error("tagger.assignTag: type='tool' is forbidden — use assignToolTag(sessionId, callId, ownerMsgId, ...)");
|
|
167845
|
+
}
|
|
167846
|
+
return allocateTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize, toolName, inputByteSize, null, messageId, () => getTagNumberByMessageId(db, sessionId, messageId));
|
|
167847
|
+
}
|
|
167848
|
+
function assignToolTag(sessionId, callId, ownerMsgId, byteSize2, db, reasoningByteSize = 0, toolName = null, inputByteSize = 0) {
|
|
167849
|
+
const compositeKey = makeToolCompositeKey(ownerMsgId, callId);
|
|
167850
|
+
const sessionAssignments = getSessionAssignments(sessionId);
|
|
167851
|
+
const existing = sessionAssignments.get(compositeKey);
|
|
167852
|
+
if (existing !== undefined) {
|
|
167853
|
+
return existing;
|
|
167854
|
+
}
|
|
167855
|
+
const dbHit = getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId);
|
|
167856
|
+
if (dbHit !== null) {
|
|
167857
|
+
sessionAssignments.set(compositeKey, dbHit);
|
|
167858
|
+
syncCounterAtLeast(sessionId, db, dbHit);
|
|
167859
|
+
return dbHit;
|
|
167860
|
+
}
|
|
167861
|
+
for (let attempt = 0;attempt < MAX_TAG_ALLOC_RETRIES; attempt += 1) {
|
|
167862
|
+
const orphan = getNullOwnerToolTag(db, sessionId, callId);
|
|
167863
|
+
if (orphan === null)
|
|
167864
|
+
break;
|
|
167865
|
+
const claimed = adoptNullOwnerToolTag(db, orphan.id, ownerMsgId);
|
|
167866
|
+
if (claimed) {
|
|
167867
|
+
sessionAssignments.set(compositeKey, orphan.tagNumber);
|
|
167868
|
+
syncCounterAtLeast(sessionId, db, orphan.tagNumber);
|
|
167869
|
+
return orphan.tagNumber;
|
|
167870
|
+
}
|
|
167871
|
+
const recheck = getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId);
|
|
167872
|
+
if (recheck !== null) {
|
|
167873
|
+
sessionAssignments.set(compositeKey, recheck);
|
|
167874
|
+
syncCounterAtLeast(sessionId, db, recheck);
|
|
167875
|
+
return recheck;
|
|
167876
|
+
}
|
|
167877
|
+
}
|
|
167878
|
+
return allocateTag(sessionId, callId, "tool", byteSize2, db, reasoningByteSize, toolName, inputByteSize, ownerMsgId, compositeKey, () => getToolTagNumberByOwner(db, sessionId, callId, ownerMsgId));
|
|
166637
167879
|
}
|
|
166638
|
-
function getTag(sessionId, messageId) {
|
|
167880
|
+
function getTag(sessionId, messageId, _type) {
|
|
166639
167881
|
return assignments.get(sessionId)?.get(messageId);
|
|
166640
167882
|
}
|
|
167883
|
+
function getToolTag(sessionId, callId, ownerMsgId) {
|
|
167884
|
+
return assignments.get(sessionId)?.get(makeToolCompositeKey(ownerMsgId, callId));
|
|
167885
|
+
}
|
|
166641
167886
|
function bindTag(sessionId, messageId, tagNumber) {
|
|
166642
167887
|
getSessionAssignments(sessionId).set(messageId, tagNumber);
|
|
166643
167888
|
}
|
|
167889
|
+
function bindToolTag(sessionId, callId, ownerMsgId, tagNumber) {
|
|
167890
|
+
getSessionAssignments(sessionId).set(makeToolCompositeKey(ownerMsgId, callId), tagNumber);
|
|
167891
|
+
}
|
|
166644
167892
|
function getAssignments(sessionId) {
|
|
166645
167893
|
return getSessionAssignments(sessionId);
|
|
166646
167894
|
}
|
|
166647
167895
|
function resetCounter(sessionId, db) {
|
|
166648
167896
|
counters.set(sessionId, 0);
|
|
166649
167897
|
assignments.delete(sessionId);
|
|
167898
|
+
loadSignatures.delete(sessionId);
|
|
166650
167899
|
getResetCounterStatement(db).run(sessionId, getHarness());
|
|
166651
167900
|
}
|
|
166652
167901
|
function getCounter(sessionId) {
|
|
166653
167902
|
return counters.get(sessionId) ?? 0;
|
|
166654
167903
|
}
|
|
167904
|
+
function probeSignature(db) {
|
|
167905
|
+
const dvRow = getProbeDataVersionStatement(db).get();
|
|
167906
|
+
const tcRow = getProbeTotalChangesStatement(db).get();
|
|
167907
|
+
return {
|
|
167908
|
+
dataVersion: dvRow?.data_version ?? 0,
|
|
167909
|
+
totalChanges: tcRow?.tc ?? 0
|
|
167910
|
+
};
|
|
167911
|
+
}
|
|
166655
167912
|
function initFromDb(sessionId, db) {
|
|
167913
|
+
const probe = probeSignature(db);
|
|
167914
|
+
const cached2 = loadSignatures.get(sessionId);
|
|
167915
|
+
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.totalChanges === probe.totalChanges) {
|
|
167916
|
+
return;
|
|
167917
|
+
}
|
|
166656
167918
|
const row = db.prepare(GET_COUNTER_SQL).get(sessionId);
|
|
166657
167919
|
const assignmentRows = db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId).filter(isAssignmentRow);
|
|
166658
167920
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
166659
167921
|
sessionAssignments.clear();
|
|
166660
167922
|
let maxTagNumber = 0;
|
|
166661
167923
|
for (const assignment of assignmentRows) {
|
|
166662
|
-
|
|
167924
|
+
if (assignment.type === "tool") {
|
|
167925
|
+
if (assignment.tool_owner_message_id !== null) {
|
|
167926
|
+
sessionAssignments.set(makeToolCompositeKey(assignment.tool_owner_message_id, assignment.message_id), assignment.tag_number);
|
|
167927
|
+
}
|
|
167928
|
+
} else {
|
|
167929
|
+
sessionAssignments.set(assignment.message_id, assignment.tag_number);
|
|
167930
|
+
}
|
|
166663
167931
|
if (assignment.tag_number > maxTagNumber) {
|
|
166664
167932
|
maxTagNumber = assignment.tag_number;
|
|
166665
167933
|
}
|
|
166666
167934
|
}
|
|
166667
167935
|
const counter = Math.max(row?.counter ?? 0, maxTagNumber, counters.get(sessionId) ?? 0);
|
|
166668
167936
|
counters.set(sessionId, counter);
|
|
167937
|
+
loadSignatures.set(sessionId, {
|
|
167938
|
+
db,
|
|
167939
|
+
dataVersion: probe.dataVersion,
|
|
167940
|
+
totalChanges: probe.totalChanges
|
|
167941
|
+
});
|
|
166669
167942
|
}
|
|
166670
167943
|
function cleanup(sessionId) {
|
|
166671
167944
|
counters.delete(sessionId);
|
|
166672
167945
|
assignments.delete(sessionId);
|
|
167946
|
+
loadSignatures.delete(sessionId);
|
|
166673
167947
|
}
|
|
166674
167948
|
return {
|
|
166675
167949
|
assignTag,
|
|
167950
|
+
assignToolTag,
|
|
166676
167951
|
getTag,
|
|
167952
|
+
getToolTag,
|
|
166677
167953
|
bindTag,
|
|
167954
|
+
bindToolTag,
|
|
166678
167955
|
getAssignments,
|
|
166679
167956
|
resetCounter,
|
|
166680
167957
|
getCounter,
|
|
@@ -167318,21 +168595,146 @@ ${snap.error}`;
|
|
|
167318
168595
|
// src/hooks/magic-context/hook.ts
|
|
167319
168596
|
init_derive_budgets();
|
|
167320
168597
|
|
|
167321
|
-
// src/features/magic-context/
|
|
167322
|
-
|
|
167323
|
-
|
|
167324
|
-
|
|
167325
|
-
|
|
167326
|
-
|
|
167327
|
-
|
|
167328
|
-
|
|
167329
|
-
|
|
167330
|
-
|
|
167331
|
-
|
|
167332
|
-
|
|
167333
|
-
|
|
167334
|
-
|
|
167335
|
-
|
|
168598
|
+
// src/features/magic-context/message-index-async.ts
|
|
168599
|
+
init_logger();
|
|
168600
|
+
await init_message_index();
|
|
168601
|
+
var INCREMENTAL_DEBOUNCE_MS = 100;
|
|
168602
|
+
var reconciledSessions = new Set;
|
|
168603
|
+
var reconciliationScheduledSessions = new Set;
|
|
168604
|
+
var sessionLocks = new Map;
|
|
168605
|
+
var incrementalTimers = new Map;
|
|
168606
|
+
var pendingIncrementalKeys = new Set;
|
|
168607
|
+
function defer(fn) {
|
|
168608
|
+
const immediate = globalThis.setImmediate;
|
|
168609
|
+
if (typeof immediate === "function") {
|
|
168610
|
+
immediate(fn);
|
|
168611
|
+
return;
|
|
168612
|
+
}
|
|
168613
|
+
setTimeout(fn, 0);
|
|
168614
|
+
}
|
|
168615
|
+
function runWithSessionLock(sessionId, operation) {
|
|
168616
|
+
const previous = sessionLocks.get(sessionId) ?? Promise.resolve();
|
|
168617
|
+
const run = previous.catch(() => {
|
|
168618
|
+
return;
|
|
168619
|
+
}).then(async () => {
|
|
168620
|
+
await operation();
|
|
168621
|
+
});
|
|
168622
|
+
sessionLocks.set(sessionId, run);
|
|
168623
|
+
run.finally(() => {
|
|
168624
|
+
if (sessionLocks.get(sessionId) === run) {
|
|
168625
|
+
sessionLocks.delete(sessionId);
|
|
168626
|
+
}
|
|
168627
|
+
}).catch(() => {
|
|
168628
|
+
return;
|
|
168629
|
+
});
|
|
168630
|
+
return run;
|
|
168631
|
+
}
|
|
168632
|
+
function logIndexingError(sessionId, action, error48) {
|
|
168633
|
+
sessionLog(sessionId, `message FTS async ${action} failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
168634
|
+
log(`[message-index-async] ${action} failed for ${sessionId}:`, error48);
|
|
168635
|
+
}
|
|
168636
|
+
async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
168637
|
+
await runWithSessionLock(sessionId, () => {
|
|
168638
|
+
if (reconciledSessions.has(sessionId)) {
|
|
168639
|
+
return;
|
|
168640
|
+
}
|
|
168641
|
+
const messages = readMessages(sessionId);
|
|
168642
|
+
if (messages.length === 0) {
|
|
168643
|
+
clearIndexedMessages(db, sessionId);
|
|
168644
|
+
reconciledSessions.add(sessionId);
|
|
168645
|
+
return;
|
|
168646
|
+
}
|
|
168647
|
+
let lastIndexedOrdinal = getLastIndexedOrdinal(db, sessionId);
|
|
168648
|
+
if (lastIndexedOrdinal > messages.length) {
|
|
168649
|
+
clearIndexedMessages(db, sessionId);
|
|
168650
|
+
lastIndexedOrdinal = 0;
|
|
168651
|
+
}
|
|
168652
|
+
const watermark = Math.min(lastIndexedOrdinal, messages.length);
|
|
168653
|
+
indexMessagesAfterOrdinal(db, sessionId, messages, watermark, messages.length);
|
|
168654
|
+
reconciledSessions.add(sessionId);
|
|
168655
|
+
});
|
|
168656
|
+
}
|
|
168657
|
+
function scheduleReconciliation(db, sessionId, readMessages) {
|
|
168658
|
+
if (reconciledSessions.has(sessionId) || reconciliationScheduledSessions.has(sessionId)) {
|
|
168659
|
+
return;
|
|
168660
|
+
}
|
|
168661
|
+
reconciliationScheduledSessions.add(sessionId);
|
|
168662
|
+
defer(() => {
|
|
168663
|
+
reconcileSessionIndex(db, sessionId, readMessages).catch((error48) => {
|
|
168664
|
+
reconciliationScheduledSessions.delete(sessionId);
|
|
168665
|
+
logIndexingError(sessionId, "reconciliation", error48);
|
|
168666
|
+
});
|
|
168667
|
+
});
|
|
168668
|
+
}
|
|
168669
|
+
function scheduleIncrementalIndex(db, sessionId, messageId, readSingleMessage) {
|
|
168670
|
+
const key = `${sessionId}\x00${messageId}`;
|
|
168671
|
+
if (incrementalTimers.has(key) || pendingIncrementalKeys.has(key)) {
|
|
168672
|
+
return;
|
|
168673
|
+
}
|
|
168674
|
+
const timer = setTimeout(() => {
|
|
168675
|
+
incrementalTimers.delete(key);
|
|
168676
|
+
pendingIncrementalKeys.add(key);
|
|
168677
|
+
runWithSessionLock(sessionId, () => {
|
|
168678
|
+
const message = readSingleMessage(sessionId, messageId);
|
|
168679
|
+
if (!message) {
|
|
168680
|
+
return;
|
|
168681
|
+
}
|
|
168682
|
+
indexSingleMessage(db, sessionId, message);
|
|
168683
|
+
}).catch((error48) => {
|
|
168684
|
+
logIndexingError(sessionId, `incremental index for ${messageId}`, error48);
|
|
168685
|
+
}).finally(() => {
|
|
168686
|
+
pendingIncrementalKeys.delete(key);
|
|
168687
|
+
});
|
|
168688
|
+
}, INCREMENTAL_DEBOUNCE_MS);
|
|
168689
|
+
incrementalTimers.set(key, timer);
|
|
168690
|
+
}
|
|
168691
|
+
function scheduleClearAndReindex(db, sessionId, readMessages) {
|
|
168692
|
+
reconciledSessions.delete(sessionId);
|
|
168693
|
+
reconciliationScheduledSessions.delete(sessionId);
|
|
168694
|
+
defer(() => {
|
|
168695
|
+
runWithSessionLock(sessionId, () => {
|
|
168696
|
+
clearIndexedMessages(db, sessionId);
|
|
168697
|
+
const messages = readMessages(sessionId);
|
|
168698
|
+
indexMessagesAfterOrdinal(db, sessionId, messages, 0, messages.length);
|
|
168699
|
+
reconciledSessions.add(sessionId);
|
|
168700
|
+
}).catch((error48) => {
|
|
168701
|
+
logIndexingError(sessionId, "clear and reindex", error48);
|
|
168702
|
+
});
|
|
168703
|
+
});
|
|
168704
|
+
}
|
|
168705
|
+
function clearSessionTracking(sessionId) {
|
|
168706
|
+
reconciledSessions.delete(sessionId);
|
|
168707
|
+
reconciliationScheduledSessions.delete(sessionId);
|
|
168708
|
+
sessionLocks.delete(sessionId);
|
|
168709
|
+
const prefix = `${sessionId}\x00`;
|
|
168710
|
+
for (const [key, timer] of incrementalTimers) {
|
|
168711
|
+
if (key.startsWith(prefix)) {
|
|
168712
|
+
clearTimeout(timer);
|
|
168713
|
+
incrementalTimers.delete(key);
|
|
168714
|
+
}
|
|
168715
|
+
}
|
|
168716
|
+
for (const key of pendingIncrementalKeys) {
|
|
168717
|
+
if (key.startsWith(prefix)) {
|
|
168718
|
+
pendingIncrementalKeys.delete(key);
|
|
168719
|
+
}
|
|
168720
|
+
}
|
|
168721
|
+
}
|
|
168722
|
+
|
|
168723
|
+
// src/features/magic-context/overflow-detection.ts
|
|
168724
|
+
var OVERFLOW_PATTERNS = [
|
|
168725
|
+
/prompt is too long/i,
|
|
168726
|
+
/input is too long for requested model/i,
|
|
168727
|
+
/exceeds the context window/i,
|
|
168728
|
+
/input token count.*exceeds the maximum/i,
|
|
168729
|
+
/maximum prompt length is \d+/i,
|
|
168730
|
+
/reduce the length of the messages/i,
|
|
168731
|
+
/maximum context length is \d+ tokens/i,
|
|
168732
|
+
/exceeds the limit of \d+/i,
|
|
168733
|
+
/exceeds the available context size/i,
|
|
168734
|
+
/greater than the context length/i,
|
|
168735
|
+
/context window exceeds limit/i,
|
|
168736
|
+
/exceeded model token limit/i,
|
|
168737
|
+
/context[_ ]length[_ ]exceeded/i,
|
|
167336
168738
|
/request entity too large/i,
|
|
167337
168739
|
/context length is only \d+ tokens/i,
|
|
167338
168740
|
/input length.*exceeds.*context length/i,
|
|
@@ -167488,6 +168890,24 @@ function getMessageUpdatedAssistantInfo(properties) {
|
|
|
167488
168890
|
error: info.error !== undefined ? info.error : undefined
|
|
167489
168891
|
};
|
|
167490
168892
|
}
|
|
168893
|
+
function getMessageUpdatedInfo(properties) {
|
|
168894
|
+
const eventProps = getSessionProperties(properties);
|
|
168895
|
+
if (!eventProps || !isRecord(eventProps.info)) {
|
|
168896
|
+
return null;
|
|
168897
|
+
}
|
|
168898
|
+
const info = eventProps.info;
|
|
168899
|
+
if (typeof info.role !== "string" || typeof info.sessionID !== "string") {
|
|
168900
|
+
return null;
|
|
168901
|
+
}
|
|
168902
|
+
const time3 = isRecord(info.time) ? info.time : undefined;
|
|
168903
|
+
return {
|
|
168904
|
+
role: info.role,
|
|
168905
|
+
sessionID: info.sessionID,
|
|
168906
|
+
messageID: typeof info.id === "string" ? info.id : undefined,
|
|
168907
|
+
finish: typeof info.finish === "string" ? info.finish : undefined,
|
|
168908
|
+
completedAt: typeof time3?.completed === "number" ? time3.completed : undefined
|
|
168909
|
+
};
|
|
168910
|
+
}
|
|
167491
168911
|
function getSessionErrorInfo(properties) {
|
|
167492
168912
|
if (!isRecord(properties))
|
|
167493
168913
|
return null;
|
|
@@ -167511,6 +168931,7 @@ function getMessageRemovedInfo(properties) {
|
|
|
167511
168931
|
|
|
167512
168932
|
// src/hooks/magic-context/event-handler.ts
|
|
167513
168933
|
init_note_nudger();
|
|
168934
|
+
await init_read_session_chunk();
|
|
167514
168935
|
|
|
167515
168936
|
// src/hooks/magic-context/transform.ts
|
|
167516
168937
|
init_compartment_storage();
|
|
@@ -167786,23 +169207,11 @@ function readUint32BE(b, offset) {
|
|
|
167786
169207
|
// src/hooks/magic-context/transform.ts
|
|
167787
169208
|
init_note_nudger();
|
|
167788
169209
|
init_read_session_formatting();
|
|
169210
|
+
init_send_session_notification();
|
|
167789
169211
|
await __promiseAll([
|
|
167790
169212
|
init_inject_compartments(),
|
|
167791
169213
|
init_read_session_chunk()
|
|
167792
169214
|
]);
|
|
167793
|
-
|
|
167794
|
-
// src/hooks/magic-context/reasoning-capability.ts
|
|
167795
|
-
init_models_dev_cache();
|
|
167796
|
-
function modelRequiresInterleavedReasoning(model) {
|
|
167797
|
-
if (!model?.providerID || !model?.modelID) {
|
|
167798
|
-
return false;
|
|
167799
|
-
}
|
|
167800
|
-
const field = getModelsDevInterleavedField(model.providerID, model.modelID);
|
|
167801
|
-
return typeof field === "string" && field.length > 0;
|
|
167802
|
-
}
|
|
167803
|
-
|
|
167804
|
-
// src/hooks/magic-context/transform.ts
|
|
167805
|
-
init_send_session_notification();
|
|
167806
169215
|
// src/hooks/magic-context/sentinel.ts
|
|
167807
169216
|
function makeSentinel(originalPart) {
|
|
167808
169217
|
const sentinel = {
|
|
@@ -167979,9 +169388,7 @@ function stripDroppedPlaceholderMessages(messages) {
|
|
|
167979
169388
|
}
|
|
167980
169389
|
return { stripped, sentineledIds };
|
|
167981
169390
|
}
|
|
167982
|
-
function replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedWatermark
|
|
167983
|
-
if (skipTypedReasoningCleanup)
|
|
167984
|
-
return 0;
|
|
169391
|
+
function replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedWatermark) {
|
|
167985
169392
|
if (persistedWatermark <= 0)
|
|
167986
169393
|
return 0;
|
|
167987
169394
|
let cleared = 0;
|
|
@@ -168027,9 +169434,7 @@ function replayStrippedInlineThinking(messages, messageTagNumbers, persistedWate
|
|
|
168027
169434
|
}
|
|
168028
169435
|
return stripped;
|
|
168029
169436
|
}
|
|
168030
|
-
function clearOldReasoning(messages, reasoningByMessage, messageTagNumbers, clearReasoningAge
|
|
168031
|
-
if (skipTypedReasoningCleanup)
|
|
168032
|
-
return 0;
|
|
169437
|
+
function clearOldReasoning(messages, reasoningByMessage, messageTagNumbers, clearReasoningAge) {
|
|
168033
169438
|
const maxTag = findMaxTag(messageTagNumbers);
|
|
168034
169439
|
if (maxTag === 0)
|
|
168035
169440
|
return 0;
|
|
@@ -168064,9 +169469,7 @@ function findMaxTag(messageTagNumbers) {
|
|
|
168064
169469
|
return max;
|
|
168065
169470
|
}
|
|
168066
169471
|
var CLEARED_REASONING_TYPES = new Set(["thinking", "reasoning"]);
|
|
168067
|
-
function stripClearedReasoning(messages
|
|
168068
|
-
if (skipTypedReasoningCleanup)
|
|
168069
|
-
return 0;
|
|
169472
|
+
function stripClearedReasoning(messages) {
|
|
168070
169473
|
let stripped = 0;
|
|
168071
169474
|
for (const message of messages) {
|
|
168072
169475
|
if (message.info.role !== "assistant")
|
|
@@ -168588,374 +169991,189 @@ function isStructuralNoisePart(part) {
|
|
|
168588
169991
|
if (!isRecord(part) || typeof part.type !== "string") {
|
|
168589
169992
|
return false;
|
|
168590
169993
|
}
|
|
168591
|
-
if (!STRUCTURAL_PART_TYPES.has(part.type)) {
|
|
168592
|
-
return false;
|
|
168593
|
-
}
|
|
168594
|
-
if (part.type === "reasoning" && typeof part.text === "string" && part.text !== "[cleared]") {
|
|
168595
|
-
return false;
|
|
168596
|
-
}
|
|
168597
|
-
return true;
|
|
168598
|
-
}
|
|
168599
|
-
function stripStructuralNoise(messages) {
|
|
168600
|
-
let strippedParts = 0;
|
|
168601
|
-
for (const message of messages) {
|
|
168602
|
-
if (!Array.isArray(message.parts)) {
|
|
168603
|
-
continue;
|
|
168604
|
-
}
|
|
168605
|
-
for (let i = 0;i < message.parts.length; i++) {
|
|
168606
|
-
const part = message.parts[i];
|
|
168607
|
-
if (isSentinel(part))
|
|
168608
|
-
continue;
|
|
168609
|
-
if (!isStructuralNoisePart(part))
|
|
168610
|
-
continue;
|
|
168611
|
-
message.parts[i] = makeSentinel(part);
|
|
168612
|
-
strippedParts++;
|
|
168613
|
-
}
|
|
168614
|
-
}
|
|
168615
|
-
return strippedParts;
|
|
168616
|
-
}
|
|
168617
|
-
// src/hooks/magic-context/tag-messages.ts
|
|
168618
|
-
await init_storage();
|
|
168619
|
-
// src/hooks/magic-context/drop-stale-reduce-calls.ts
|
|
168620
|
-
var STALE_TOOL_NAMES = new Set(["ctx_reduce"]);
|
|
168621
|
-
function isReduceToolPart(part) {
|
|
168622
|
-
if (!isRecord(part))
|
|
168623
|
-
return false;
|
|
168624
|
-
if (part.type === "tool" && typeof part.tool === "string" && STALE_TOOL_NAMES.has(part.tool))
|
|
168625
|
-
return true;
|
|
168626
|
-
if (part.type === "tool-invocation" && typeof part.toolName === "string" && STALE_TOOL_NAMES.has(part.toolName))
|
|
168627
|
-
return true;
|
|
168628
|
-
if (part.type === "tool_use" && typeof part.name === "string" && STALE_TOOL_NAMES.has(part.name))
|
|
168629
|
-
return true;
|
|
168630
|
-
return false;
|
|
168631
|
-
}
|
|
168632
|
-
function hasAnyMeaningfulPart(parts) {
|
|
168633
|
-
for (const part of parts) {
|
|
168634
|
-
if (!isRecord(part))
|
|
168635
|
-
continue;
|
|
168636
|
-
if (part.type === "text" && typeof part.text === "string" && part.text.trim().length > 0)
|
|
168637
|
-
return true;
|
|
168638
|
-
if (part.type === "thinking" || part.type === "reasoning" || part.type === "redacted_thinking")
|
|
168639
|
-
continue;
|
|
168640
|
-
if (part.type === "meta" || part.type === "step-start" || part.type === "step-finish")
|
|
168641
|
-
continue;
|
|
168642
|
-
if (part.type !== "tool" || !isReduceToolPart(part))
|
|
168643
|
-
return true;
|
|
168644
|
-
}
|
|
168645
|
-
return false;
|
|
168646
|
-
}
|
|
168647
|
-
function dropStaleReduceCalls(messages, protectedCount = 0) {
|
|
168648
|
-
let didDrop = false;
|
|
168649
|
-
const protectedStart = messages.length - protectedCount;
|
|
168650
|
-
for (let i = 0;i < messages.length; i++) {
|
|
168651
|
-
if (i >= protectedStart)
|
|
168652
|
-
break;
|
|
168653
|
-
const message = messages[i];
|
|
168654
|
-
let touched = false;
|
|
168655
|
-
for (let j = 0;j < message.parts.length; j++) {
|
|
168656
|
-
const part = message.parts[j];
|
|
168657
|
-
if (isSentinel(part))
|
|
168658
|
-
continue;
|
|
168659
|
-
if (isReduceToolPart(part)) {
|
|
168660
|
-
message.parts[j] = makeSentinel(part);
|
|
168661
|
-
touched = true;
|
|
168662
|
-
}
|
|
168663
|
-
}
|
|
168664
|
-
if (touched) {
|
|
168665
|
-
didDrop = true;
|
|
168666
|
-
if (!hasAnyMeaningfulPart(message.parts)) {
|
|
168667
|
-
message.parts.length = 0;
|
|
168668
|
-
message.parts.push(makeSentinel(undefined));
|
|
168669
|
-
}
|
|
168670
|
-
}
|
|
168671
|
-
}
|
|
168672
|
-
return didDrop;
|
|
168673
|
-
}
|
|
168674
|
-
|
|
168675
|
-
// src/hooks/magic-context/tag-messages.ts
|
|
168676
|
-
init_tag_content_primitives();
|
|
168677
|
-
|
|
168678
|
-
// src/hooks/magic-context/tag-id-fallback.ts
|
|
168679
|
-
await init_storage();
|
|
168680
|
-
function parseScopedContentId(contentId) {
|
|
168681
|
-
const match = /^(.*):(p|file)(\d+)$/.exec(contentId);
|
|
168682
|
-
if (!match)
|
|
168683
|
-
return null;
|
|
168684
|
-
return {
|
|
168685
|
-
messageId: match[1],
|
|
168686
|
-
type: match[2] === "file" ? "file" : "message",
|
|
168687
|
-
partIndex: Number.parseInt(match[3], 10)
|
|
168688
|
-
};
|
|
168689
|
-
}
|
|
168690
|
-
function createScopedAssignments(assignments) {
|
|
168691
|
-
const scoped = new Map;
|
|
168692
|
-
for (const [contentId, tagNumber] of assignments) {
|
|
168693
|
-
const parsed = parseScopedContentId(contentId);
|
|
168694
|
-
if (!parsed)
|
|
168695
|
-
continue;
|
|
168696
|
-
const entry = scoped.get(parsed.messageId) ?? { message: [], file: [] };
|
|
168697
|
-
entry[parsed.type].push({ tagNumber, contentId, partIndex: parsed.partIndex });
|
|
168698
|
-
scoped.set(parsed.messageId, entry);
|
|
168699
|
-
}
|
|
168700
|
-
for (const entry of scoped.values()) {
|
|
168701
|
-
entry.message.sort((left, right) => left.partIndex - right.partIndex);
|
|
168702
|
-
entry.file.sort((left, right) => left.partIndex - right.partIndex);
|
|
168703
|
-
}
|
|
168704
|
-
return scoped;
|
|
168705
|
-
}
|
|
168706
|
-
function createExistingTagResolver(sessionId, tagger, db) {
|
|
168707
|
-
const assignments = tagger.getAssignments(sessionId);
|
|
168708
|
-
let cachedAssignmentSize = -1;
|
|
168709
|
-
let cachedScopedAssignments = null;
|
|
168710
|
-
const usedTagNumbers = new Set;
|
|
168711
|
-
function getScopedAssignments() {
|
|
168712
|
-
if (!cachedScopedAssignments || cachedAssignmentSize !== assignments.size) {
|
|
168713
|
-
cachedScopedAssignments = createScopedAssignments(assignments);
|
|
168714
|
-
cachedAssignmentSize = assignments.size;
|
|
168715
|
-
}
|
|
168716
|
-
return cachedScopedAssignments;
|
|
168717
|
-
}
|
|
168718
|
-
return {
|
|
168719
|
-
resolve(messageId, type, currentContentId, ordinal) {
|
|
168720
|
-
const exactTagId = assignments.get(currentContentId);
|
|
168721
|
-
if (exactTagId !== undefined) {
|
|
168722
|
-
usedTagNumbers.add(exactTagId);
|
|
168723
|
-
return exactTagId;
|
|
168724
|
-
}
|
|
168725
|
-
const fallback = getScopedAssignments().get(messageId)?.[type][ordinal];
|
|
168726
|
-
if (!fallback || usedTagNumbers.has(fallback.tagNumber)) {
|
|
168727
|
-
return;
|
|
168728
|
-
}
|
|
168729
|
-
updateTagMessageId(db, sessionId, fallback.tagNumber, currentContentId);
|
|
168730
|
-
tagger.bindTag(sessionId, currentContentId, fallback.tagNumber);
|
|
168731
|
-
usedTagNumbers.add(fallback.tagNumber);
|
|
168732
|
-
return fallback.tagNumber;
|
|
168733
|
-
}
|
|
168734
|
-
};
|
|
168735
|
-
}
|
|
168736
|
-
|
|
168737
|
-
// src/hooks/magic-context/tag-messages.ts
|
|
168738
|
-
init_tag_part_guards();
|
|
168739
|
-
|
|
168740
|
-
// src/hooks/magic-context/tool-drop-target.ts
|
|
168741
|
-
var DROP_PREFIX = "[dropped";
|
|
168742
|
-
var IGNORE_PART_TYPES = new Set([
|
|
168743
|
-
"thinking",
|
|
168744
|
-
"reasoning",
|
|
168745
|
-
"redacted_thinking",
|
|
168746
|
-
"meta",
|
|
168747
|
-
"step-start",
|
|
168748
|
-
"step-finish"
|
|
168749
|
-
]);
|
|
168750
|
-
function isToolCallId(value) {
|
|
168751
|
-
return typeof value === "string" && value.length > 0;
|
|
168752
|
-
}
|
|
168753
|
-
function getToolContent(part) {
|
|
168754
|
-
if (!isRecord(part))
|
|
168755
|
-
return;
|
|
168756
|
-
if (part.type === "tool" && isRecord(part.state)) {
|
|
168757
|
-
return typeof part.state.output === "string" ? part.state.output : undefined;
|
|
168758
|
-
}
|
|
168759
|
-
if (part.type === "tool_result") {
|
|
168760
|
-
return typeof part.content === "string" ? part.content : undefined;
|
|
168761
|
-
}
|
|
168762
|
-
return;
|
|
168763
|
-
}
|
|
168764
|
-
function setToolContent(part, content) {
|
|
168765
|
-
if (!isRecord(part))
|
|
168766
|
-
return;
|
|
168767
|
-
if (part.type === "tool" && isRecord(part.state)) {
|
|
168768
|
-
part.state.output = content;
|
|
168769
|
-
return;
|
|
168770
|
-
}
|
|
168771
|
-
if (part.type === "tool_result") {
|
|
168772
|
-
part.content = content;
|
|
168773
|
-
}
|
|
168774
|
-
}
|
|
168775
|
-
function truncateToolPart(part) {
|
|
168776
|
-
if (!isRecord(part))
|
|
168777
|
-
return;
|
|
168778
|
-
if (part.type === "tool" && isRecord(part.state)) {
|
|
168779
|
-
const state = part.state;
|
|
168780
|
-
state.output = "[truncated]";
|
|
168781
|
-
if (isRecord(state.input)) {
|
|
168782
|
-
const inputSize = estimateInputSize(state.input);
|
|
168783
|
-
if (inputSize > 500) {
|
|
168784
|
-
truncateInputValues(state.input);
|
|
168785
|
-
}
|
|
168786
|
-
}
|
|
168787
|
-
return;
|
|
168788
|
-
}
|
|
168789
|
-
if (part.type === "tool_result") {
|
|
168790
|
-
part.content = "[truncated]";
|
|
168791
|
-
return;
|
|
168792
|
-
}
|
|
168793
|
-
if (part.type === "tool-invocation" && isRecord(part.args)) {
|
|
168794
|
-
const inputSize = estimateInputSize(part.args);
|
|
168795
|
-
if (inputSize > 500) {
|
|
168796
|
-
truncateInputValues(part.args);
|
|
168797
|
-
}
|
|
168798
|
-
return;
|
|
168799
|
-
}
|
|
168800
|
-
if (part.type === "tool_use" && isRecord(part.input)) {
|
|
168801
|
-
const inputSize = estimateInputSize(part.input);
|
|
168802
|
-
if (inputSize > 500) {
|
|
168803
|
-
truncateInputValues(part.input);
|
|
168804
|
-
}
|
|
168805
|
-
}
|
|
168806
|
-
}
|
|
168807
|
-
function estimateInputSize(input) {
|
|
168808
|
-
try {
|
|
168809
|
-
return JSON.stringify(input).length;
|
|
168810
|
-
} catch {
|
|
168811
|
-
return 0;
|
|
168812
|
-
}
|
|
168813
|
-
}
|
|
168814
|
-
var TRUNCATION_SENTINEL = "...[truncated]";
|
|
168815
|
-
function safeSlice(str, maxLen) {
|
|
168816
|
-
if (str.length <= maxLen)
|
|
168817
|
-
return str;
|
|
168818
|
-
const lastCharCode = str.charCodeAt(maxLen - 1);
|
|
168819
|
-
if (lastCharCode >= 55296 && lastCharCode <= 56319) {
|
|
168820
|
-
return str.slice(0, maxLen - 1);
|
|
168821
|
-
}
|
|
168822
|
-
return str.slice(0, maxLen);
|
|
168823
|
-
}
|
|
168824
|
-
function truncateInputValues(input) {
|
|
168825
|
-
for (const key of Object.keys(input)) {
|
|
168826
|
-
const value = input[key];
|
|
168827
|
-
if (typeof value === "string") {
|
|
168828
|
-
if (value.endsWith(TRUNCATION_SENTINEL) || value === "[object]" || /^\[\d+ items\]$/.test(value))
|
|
168829
|
-
continue;
|
|
168830
|
-
input[key] = value.length > 5 ? `${safeSlice(value, 5)}${TRUNCATION_SENTINEL}` : value;
|
|
168831
|
-
} else if (Array.isArray(value)) {
|
|
168832
|
-
input[key] = `[${value.length} items]`;
|
|
168833
|
-
} else if (value !== null && typeof value === "object") {
|
|
168834
|
-
input[key] = "[object]";
|
|
168835
|
-
}
|
|
168836
|
-
}
|
|
168837
|
-
}
|
|
168838
|
-
function hasMeaningfulPart(part) {
|
|
168839
|
-
if (!isRecord(part))
|
|
168840
|
-
return false;
|
|
168841
|
-
const type = part.type;
|
|
168842
|
-
if (type === "text") {
|
|
168843
|
-
return typeof part.text === "string" && part.text.trim().length > 0;
|
|
168844
|
-
}
|
|
168845
|
-
if (typeof type !== "string")
|
|
168846
|
-
return false;
|
|
168847
|
-
if (IGNORE_PART_TYPES.has(type))
|
|
168848
|
-
return false;
|
|
168849
|
-
return true;
|
|
168850
|
-
}
|
|
168851
|
-
function clearThinkingParts(thinkingParts) {
|
|
168852
|
-
for (const part of thinkingParts) {
|
|
168853
|
-
if (part.thinking !== undefined)
|
|
168854
|
-
part.thinking = "[cleared]";
|
|
168855
|
-
if (part.text !== undefined)
|
|
168856
|
-
part.text = "[cleared]";
|
|
168857
|
-
}
|
|
168858
|
-
}
|
|
168859
|
-
function extractToolCallObservation(part) {
|
|
168860
|
-
if (!isRecord(part))
|
|
168861
|
-
return null;
|
|
168862
|
-
if (part.type === "tool" && isToolCallId(part.callID)) {
|
|
168863
|
-
return { callId: part.callID, kind: "result" };
|
|
168864
|
-
}
|
|
168865
|
-
if (part.type === "tool-invocation" && isToolCallId(part.callID)) {
|
|
168866
|
-
return { callId: part.callID, kind: "invocation" };
|
|
168867
|
-
}
|
|
168868
|
-
if (part.type === "tool_use" && isToolCallId(part.id)) {
|
|
168869
|
-
return { callId: part.id, kind: "invocation" };
|
|
169994
|
+
if (!STRUCTURAL_PART_TYPES.has(part.type)) {
|
|
169995
|
+
return false;
|
|
168870
169996
|
}
|
|
168871
|
-
if (part.type === "
|
|
168872
|
-
return
|
|
169997
|
+
if (part.type === "reasoning" && typeof part.text === "string" && part.text !== "[cleared]") {
|
|
169998
|
+
return false;
|
|
168873
169999
|
}
|
|
168874
|
-
return
|
|
168875
|
-
}
|
|
168876
|
-
function isDropContent(content) {
|
|
168877
|
-
return content.startsWith(DROP_PREFIX);
|
|
170000
|
+
return true;
|
|
168878
170001
|
}
|
|
168879
|
-
|
|
168880
|
-
|
|
168881
|
-
|
|
168882
|
-
|
|
168883
|
-
|
|
168884
|
-
|
|
168885
|
-
|
|
170002
|
+
function stripStructuralNoise(messages) {
|
|
170003
|
+
let strippedParts = 0;
|
|
170004
|
+
for (const message of messages) {
|
|
170005
|
+
if (!Array.isArray(message.parts)) {
|
|
170006
|
+
continue;
|
|
170007
|
+
}
|
|
170008
|
+
for (let i = 0;i < message.parts.length; i++) {
|
|
170009
|
+
const part = message.parts[i];
|
|
170010
|
+
if (isSentinel(part))
|
|
170011
|
+
continue;
|
|
170012
|
+
if (!isStructuralNoisePart(part))
|
|
170013
|
+
continue;
|
|
170014
|
+
message.parts[i] = makeSentinel(part);
|
|
170015
|
+
strippedParts++;
|
|
170016
|
+
}
|
|
168886
170017
|
}
|
|
168887
|
-
|
|
168888
|
-
|
|
168889
|
-
|
|
170018
|
+
return strippedParts;
|
|
170019
|
+
}
|
|
170020
|
+
// src/hooks/magic-context/tag-messages.ts
|
|
170021
|
+
init_storage_tags();
|
|
170022
|
+
await init_storage();
|
|
170023
|
+
// src/hooks/magic-context/drop-stale-reduce-calls.ts
|
|
170024
|
+
var STALE_TOOL_NAMES = new Set(["ctx_reduce"]);
|
|
170025
|
+
function isReduceToolPart(part) {
|
|
170026
|
+
if (!isRecord(part))
|
|
170027
|
+
return false;
|
|
170028
|
+
if (part.type === "tool" && typeof part.tool === "string" && STALE_TOOL_NAMES.has(part.tool))
|
|
170029
|
+
return true;
|
|
170030
|
+
if (part.type === "tool-invocation" && typeof part.toolName === "string" && STALE_TOOL_NAMES.has(part.toolName))
|
|
170031
|
+
return true;
|
|
170032
|
+
if (part.type === "tool_use" && typeof part.name === "string" && STALE_TOOL_NAMES.has(part.name))
|
|
170033
|
+
return true;
|
|
170034
|
+
return false;
|
|
170035
|
+
}
|
|
170036
|
+
function hasAnyMeaningfulPart(parts) {
|
|
170037
|
+
for (const part of parts) {
|
|
170038
|
+
if (!isRecord(part))
|
|
170039
|
+
continue;
|
|
170040
|
+
if (part.type === "text" && typeof part.text === "string" && part.text.trim().length > 0)
|
|
170041
|
+
return true;
|
|
170042
|
+
if (part.type === "thinking" || part.type === "reasoning" || part.type === "redacted_thinking")
|
|
170043
|
+
continue;
|
|
170044
|
+
if (part.type === "meta" || part.type === "step-start" || part.type === "step-finish")
|
|
170045
|
+
continue;
|
|
170046
|
+
if (part.type !== "tool" || !isReduceToolPart(part))
|
|
170047
|
+
return true;
|
|
168890
170048
|
}
|
|
168891
|
-
|
|
168892
|
-
|
|
168893
|
-
|
|
168894
|
-
|
|
168895
|
-
|
|
170049
|
+
return false;
|
|
170050
|
+
}
|
|
170051
|
+
function dropStaleReduceCalls(messages, protectedCount = 0) {
|
|
170052
|
+
let didDrop = false;
|
|
170053
|
+
const protectedStart = messages.length - protectedCount;
|
|
170054
|
+
for (let i = 0;i < messages.length; i++) {
|
|
170055
|
+
if (i >= protectedStart)
|
|
170056
|
+
break;
|
|
170057
|
+
const message = messages[i];
|
|
170058
|
+
let touched = false;
|
|
170059
|
+
for (let j = 0;j < message.parts.length; j++) {
|
|
170060
|
+
const part = message.parts[j];
|
|
170061
|
+
if (isSentinel(part))
|
|
170062
|
+
continue;
|
|
170063
|
+
if (isReduceToolPart(part)) {
|
|
170064
|
+
message.parts[j] = makeSentinel(part);
|
|
170065
|
+
touched = true;
|
|
170066
|
+
}
|
|
168896
170067
|
}
|
|
168897
|
-
|
|
168898
|
-
|
|
168899
|
-
|
|
170068
|
+
if (touched) {
|
|
170069
|
+
didDrop = true;
|
|
170070
|
+
if (!hasAnyMeaningfulPart(message.parts)) {
|
|
170071
|
+
message.parts.length = 0;
|
|
170072
|
+
message.parts.push(makeSentinel(undefined));
|
|
168900
170073
|
}
|
|
168901
170074
|
}
|
|
168902
|
-
this.partsToRemove.clear();
|
|
168903
|
-
this.affectedMessages.clear();
|
|
168904
170075
|
}
|
|
170076
|
+
return didDrop;
|
|
168905
170077
|
}
|
|
168906
|
-
|
|
168907
|
-
|
|
168908
|
-
|
|
168909
|
-
|
|
168910
|
-
|
|
168911
|
-
|
|
168912
|
-
|
|
168913
|
-
|
|
168914
|
-
|
|
168915
|
-
|
|
168916
|
-
|
|
168917
|
-
|
|
168918
|
-
|
|
170078
|
+
|
|
170079
|
+
// src/hooks/magic-context/tag-messages.ts
|
|
170080
|
+
init_tag_content_primitives();
|
|
170081
|
+
await init_read_session_db();
|
|
170082
|
+
|
|
170083
|
+
// src/hooks/magic-context/tag-id-fallback.ts
|
|
170084
|
+
await init_storage();
|
|
170085
|
+
function parseScopedContentId(contentId) {
|
|
170086
|
+
const match = /^(.*):(p|file)(\d+)$/.exec(contentId);
|
|
170087
|
+
if (!match)
|
|
170088
|
+
return null;
|
|
170089
|
+
return {
|
|
170090
|
+
messageId: match[1],
|
|
170091
|
+
type: match[2] === "file" ? "file" : "message",
|
|
170092
|
+
partIndex: Number.parseInt(match[3], 10)
|
|
168919
170093
|
};
|
|
168920
|
-
|
|
168921
|
-
|
|
168922
|
-
|
|
168923
|
-
|
|
168924
|
-
|
|
168925
|
-
|
|
168926
|
-
|
|
168927
|
-
|
|
170094
|
+
}
|
|
170095
|
+
function createScopedAssignments(assignments) {
|
|
170096
|
+
const scoped = new Map;
|
|
170097
|
+
for (const [contentId, tagNumber] of assignments) {
|
|
170098
|
+
const parsed = parseScopedContentId(contentId);
|
|
170099
|
+
if (!parsed)
|
|
170100
|
+
continue;
|
|
170101
|
+
const entry = scoped.get(parsed.messageId) ?? { message: [], file: [] };
|
|
170102
|
+
entry[parsed.type].push({ tagNumber, contentId, partIndex: parsed.partIndex });
|
|
170103
|
+
scoped.set(parsed.messageId, entry);
|
|
170104
|
+
}
|
|
170105
|
+
for (const entry of scoped.values()) {
|
|
170106
|
+
entry.message.sort((left, right) => left.partIndex - right.partIndex);
|
|
170107
|
+
entry.file.sort((left, right) => left.partIndex - right.partIndex);
|
|
170108
|
+
}
|
|
170109
|
+
return scoped;
|
|
170110
|
+
}
|
|
170111
|
+
function createExistingTagResolver(sessionId, tagger, db) {
|
|
170112
|
+
const assignments = tagger.getAssignments(sessionId);
|
|
170113
|
+
let cachedAssignmentSize = -1;
|
|
170114
|
+
let cachedScopedAssignments = null;
|
|
170115
|
+
const usedTagNumbers = new Set;
|
|
170116
|
+
function getScopedAssignments() {
|
|
170117
|
+
if (!cachedScopedAssignments || cachedAssignmentSize !== assignments.size) {
|
|
170118
|
+
cachedScopedAssignments = createScopedAssignments(assignments);
|
|
170119
|
+
cachedAssignmentSize = assignments.size;
|
|
168928
170120
|
}
|
|
168929
|
-
|
|
168930
|
-
|
|
168931
|
-
};
|
|
170121
|
+
return cachedScopedAssignments;
|
|
170122
|
+
}
|
|
168932
170123
|
return {
|
|
168933
|
-
|
|
168934
|
-
|
|
168935
|
-
|
|
168936
|
-
|
|
170124
|
+
resolve(messageId, type, currentContentId, ordinal) {
|
|
170125
|
+
const exactTagId = assignments.get(currentContentId);
|
|
170126
|
+
if (exactTagId !== undefined) {
|
|
170127
|
+
usedTagNumbers.add(exactTagId);
|
|
170128
|
+
return exactTagId;
|
|
168937
170129
|
}
|
|
168938
|
-
const
|
|
168939
|
-
if (!
|
|
168940
|
-
return
|
|
168941
|
-
let changed = false;
|
|
168942
|
-
for (const occurrence of entry.occurrences) {
|
|
168943
|
-
if (occurrence.kind !== "result")
|
|
168944
|
-
continue;
|
|
168945
|
-
const prevContent = getToolContent(occurrence.part);
|
|
168946
|
-
if (prevContent !== content) {
|
|
168947
|
-
setToolContent(occurrence.part, content);
|
|
168948
|
-
changed = true;
|
|
168949
|
-
}
|
|
170130
|
+
const fallback = getScopedAssignments().get(messageId)?.[type][ordinal];
|
|
170131
|
+
if (!fallback || usedTagNumbers.has(fallback.tagNumber)) {
|
|
170132
|
+
return;
|
|
168950
170133
|
}
|
|
168951
|
-
|
|
168952
|
-
|
|
168953
|
-
|
|
168954
|
-
|
|
170134
|
+
updateTagMessageId(db, sessionId, fallback.tagNumber, currentContentId);
|
|
170135
|
+
tagger.bindTag(sessionId, currentContentId, fallback.tagNumber);
|
|
170136
|
+
usedTagNumbers.add(fallback.tagNumber);
|
|
170137
|
+
return fallback.tagNumber;
|
|
170138
|
+
}
|
|
168955
170139
|
};
|
|
168956
170140
|
}
|
|
168957
170141
|
|
|
168958
170142
|
// src/hooks/magic-context/tag-messages.ts
|
|
170143
|
+
init_tag_part_guards();
|
|
170144
|
+
init_tool_drop_target();
|
|
170145
|
+
function deriveToolOwnerMessageId(sessionId, db, message, obs, unpaired) {
|
|
170146
|
+
const messageId = typeof message.info.id === "string" ? message.info.id : "";
|
|
170147
|
+
if (obs.kind === "invocation") {
|
|
170148
|
+
if (messageId) {
|
|
170149
|
+
const queue4 = unpaired.get(obs.callId) ?? [];
|
|
170150
|
+
queue4.push(messageId);
|
|
170151
|
+
unpaired.set(obs.callId, queue4);
|
|
170152
|
+
return messageId;
|
|
170153
|
+
}
|
|
170154
|
+
return obs.callId;
|
|
170155
|
+
}
|
|
170156
|
+
const queue3 = unpaired.get(obs.callId);
|
|
170157
|
+
if (queue3 && queue3.length > 0) {
|
|
170158
|
+
const popped = queue3.shift();
|
|
170159
|
+
if (queue3.length === 0)
|
|
170160
|
+
unpaired.delete(obs.callId);
|
|
170161
|
+
if (popped !== undefined)
|
|
170162
|
+
return popped;
|
|
170163
|
+
}
|
|
170164
|
+
if (messageId) {
|
|
170165
|
+
const candidates = getCandidateToolOwners(db, sessionId, obs.callId);
|
|
170166
|
+
if (candidates.length > 0) {
|
|
170167
|
+
const ids = [...candidates, messageId];
|
|
170168
|
+
const times = getMessageTimesFromOpenCodeDb(sessionId, ids);
|
|
170169
|
+
const persisted = pickNearestPriorOwner(candidates, messageId, times);
|
|
170170
|
+
if (persisted !== null)
|
|
170171
|
+
return persisted;
|
|
170172
|
+
}
|
|
170173
|
+
return messageId;
|
|
170174
|
+
}
|
|
170175
|
+
return obs.callId;
|
|
170176
|
+
}
|
|
168959
170177
|
function collectRelevantSourceTagIds(messages, assignments) {
|
|
168960
170178
|
const currentMessageIds = new Set(messages.flatMap((message) => typeof message.info.id === "string" ? [message.info.id] : []));
|
|
168961
170179
|
const relevantTagIds = new Set;
|
|
@@ -169006,6 +170224,8 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169006
170224
|
const toolTagByCallId = new Map;
|
|
169007
170225
|
const toolThinkingByCallId = new Map;
|
|
169008
170226
|
const toolCallIndex = new Map;
|
|
170227
|
+
const unpairedInvocations = new Map;
|
|
170228
|
+
const ownerByPartKey = new Map;
|
|
169009
170229
|
const batch = new ToolMutationBatch(messages);
|
|
169010
170230
|
const assignments = tagger.getAssignments(sessionId);
|
|
169011
170231
|
const resolver = createExistingTagResolver(sessionId, tagger, db);
|
|
@@ -169036,22 +170256,37 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169036
170256
|
}
|
|
169037
170257
|
const toolObservation = extractToolCallObservation(part);
|
|
169038
170258
|
if (toolObservation) {
|
|
169039
|
-
const
|
|
170259
|
+
const ownerMsgId = deriveToolOwnerMessageId(sessionId, db, message, toolObservation, unpairedInvocations);
|
|
170260
|
+
const compositeKey = makeToolCompositeKey(ownerMsgId, toolObservation.callId);
|
|
170261
|
+
const entry = toolCallIndex.get(compositeKey) ?? {
|
|
169040
170262
|
occurrences: [],
|
|
169041
170263
|
hasResult: false
|
|
169042
170264
|
};
|
|
169043
170265
|
entry.occurrences.push({ message, part, kind: toolObservation.kind });
|
|
169044
170266
|
if (toolObservation.kind === "result")
|
|
169045
170267
|
entry.hasResult = true;
|
|
169046
|
-
toolCallIndex.set(
|
|
169047
|
-
|
|
170268
|
+
toolCallIndex.set(compositeKey, entry);
|
|
170269
|
+
let existingTagId = tagger.getToolTag(sessionId, toolObservation.callId, ownerMsgId);
|
|
170270
|
+
if (existingTagId === undefined) {
|
|
170271
|
+
const orphan = getNullOwnerToolTag(db, sessionId, toolObservation.callId);
|
|
170272
|
+
if (orphan !== null) {
|
|
170273
|
+
const claimed = adoptNullOwnerToolTag(db, orphan.id, ownerMsgId);
|
|
170274
|
+
if (claimed) {
|
|
170275
|
+
tagger.bindToolTag(sessionId, toolObservation.callId, ownerMsgId, orphan.tagNumber);
|
|
170276
|
+
existingTagId = orphan.tagNumber;
|
|
170277
|
+
} else {
|
|
170278
|
+
existingTagId = tagger.getToolTag(sessionId, toolObservation.callId, ownerMsgId);
|
|
170279
|
+
}
|
|
170280
|
+
}
|
|
170281
|
+
}
|
|
169048
170282
|
if (existingTagId !== undefined) {
|
|
169049
|
-
toolTagByCallId.set(
|
|
170283
|
+
toolTagByCallId.set(compositeKey, existingTagId);
|
|
169050
170284
|
messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, existingTagId));
|
|
169051
|
-
if (message.info.role === "tool" && precedingThinkingParts.length > 0 && !toolThinkingByCallId.has(
|
|
169052
|
-
toolThinkingByCallId.set(
|
|
170285
|
+
if (message.info.role === "tool" && precedingThinkingParts.length > 0 && !toolThinkingByCallId.has(compositeKey)) {
|
|
170286
|
+
toolThinkingByCallId.set(compositeKey, precedingThinkingParts);
|
|
169053
170287
|
}
|
|
169054
170288
|
}
|
|
170289
|
+
ownerByPartKey.set(part, { ownerMsgId, callId: toolObservation.callId });
|
|
169055
170290
|
}
|
|
169056
170291
|
if (messageId && isTextPart(part)) {
|
|
169057
170292
|
const textPart = part;
|
|
@@ -169097,14 +170332,17 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169097
170332
|
const thinkingParts = precedingThinkingParts;
|
|
169098
170333
|
const reasoningBytes = getReasoningByteSize(thinkingParts);
|
|
169099
170334
|
const { toolName, inputByteSize } = extractToolTagMetadata(toolPart);
|
|
169100
|
-
const
|
|
170335
|
+
const memo = ownerByPartKey.get(part);
|
|
170336
|
+
const ownerMsgId = memo?.ownerMsgId ?? messageId ?? toolPart.callID;
|
|
170337
|
+
const compositeKey = makeToolCompositeKey(ownerMsgId, toolPart.callID);
|
|
170338
|
+
const tagId = tagger.assignToolTag(sessionId, toolPart.callID, ownerMsgId, byteSize(toolPart.state.output), db, reasoningBytes, toolName, inputByteSize);
|
|
169101
170339
|
messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, tagId));
|
|
169102
170340
|
if (!skipPrefixInjection) {
|
|
169103
170341
|
toolPart.state.output = prependTag(tagId, toolPart.state.output);
|
|
169104
170342
|
}
|
|
169105
|
-
toolTagByCallId.set(
|
|
169106
|
-
if (thinkingParts.length > 0 && !toolThinkingByCallId.has(
|
|
169107
|
-
toolThinkingByCallId.set(
|
|
170343
|
+
toolTagByCallId.set(compositeKey, tagId);
|
|
170344
|
+
if (thinkingParts.length > 0 && !toolThinkingByCallId.has(compositeKey)) {
|
|
170345
|
+
toolThinkingByCallId.set(compositeKey, thinkingParts);
|
|
169108
170346
|
}
|
|
169109
170347
|
}
|
|
169110
170348
|
if (messageId && isFilePart(part)) {
|
|
@@ -169152,9 +170390,9 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169152
170390
|
}
|
|
169153
170391
|
}
|
|
169154
170392
|
}
|
|
169155
|
-
for (const [
|
|
169156
|
-
const thinkingParts = toolThinkingByCallId.get(
|
|
169157
|
-
targets.set(tagId, createToolDropTarget(
|
|
170393
|
+
for (const [compositeKey, tagId] of toolTagByCallId) {
|
|
170394
|
+
const thinkingParts = toolThinkingByCallId.get(compositeKey) ?? [];
|
|
170395
|
+
targets.set(tagId, createToolDropTarget(compositeKey, thinkingParts, toolCallIndex, batch));
|
|
169158
170396
|
}
|
|
169159
170397
|
const hasRecentReduceCall = lastReduceMessageIndex >= 0 && messages.length - lastReduceMessageIndex <= RECENT_REDUCE_LOOKBACK;
|
|
169160
170398
|
return {
|
|
@@ -169315,11 +170553,9 @@ function applyContextNudge(messages, nudge, nudgePlacements, sessionId) {
|
|
|
169315
170553
|
|
|
169316
170554
|
// src/features/magic-context/search.ts
|
|
169317
170555
|
init_logger();
|
|
169318
|
-
await init_read_session_chunk();
|
|
169319
170556
|
init_memory();
|
|
169320
170557
|
init_embedding();
|
|
169321
170558
|
init_storage_memory_fts();
|
|
169322
|
-
await init_message_index();
|
|
169323
170559
|
var DEFAULT_UNIFIED_SEARCH_LIMIT = 10;
|
|
169324
170560
|
var FTS_SEMANTIC_CANDIDATE_LIMIT = 50;
|
|
169325
170561
|
var SEMANTIC_WEIGHT = 0.7;
|
|
@@ -169369,11 +170605,7 @@ function getMessageOrdinal(value) {
|
|
|
169369
170605
|
}
|
|
169370
170606
|
async function getSemanticScores(args) {
|
|
169371
170607
|
const semanticScores = new Map;
|
|
169372
|
-
if (!args.
|
|
169373
|
-
return semanticScores;
|
|
169374
|
-
}
|
|
169375
|
-
const queryEmbedding = await args.embedQuery(args.query, args.signal);
|
|
169376
|
-
if (!queryEmbedding) {
|
|
170608
|
+
if (!args.queryEmbedding || args.memories.length === 0) {
|
|
169377
170609
|
return semanticScores;
|
|
169378
170610
|
}
|
|
169379
170611
|
const cachedEmbeddings = getProjectEmbeddings(args.db, args.projectPath);
|
|
@@ -169387,7 +170619,7 @@ async function getSemanticScores(args) {
|
|
|
169387
170619
|
if (!memoryEmbedding) {
|
|
169388
170620
|
continue;
|
|
169389
170621
|
}
|
|
169390
|
-
semanticScores.set(memory.id, normalizeCosineScore(cosineSimilarity(queryEmbedding, memoryEmbedding)));
|
|
170622
|
+
semanticScores.set(memory.id, normalizeCosineScore(cosineSimilarity(args.queryEmbedding, memoryEmbedding)));
|
|
169391
170623
|
}
|
|
169392
170624
|
return semanticScores;
|
|
169393
170625
|
}
|
|
@@ -169483,12 +170715,8 @@ async function searchMemories(args) {
|
|
|
169483
170715
|
const semanticScores = await getSemanticScores({
|
|
169484
170716
|
db: args.db,
|
|
169485
170717
|
projectPath: args.projectPath,
|
|
169486
|
-
query: args.query,
|
|
169487
170718
|
memories: semanticCandidates,
|
|
169488
|
-
|
|
169489
|
-
embedQuery: args.embedQuery,
|
|
169490
|
-
isEmbeddingRuntimeEnabled: args.isEmbeddingRuntimeEnabled,
|
|
169491
|
-
signal: args.signal
|
|
170719
|
+
queryEmbedding: args.queryEmbedding
|
|
169492
170720
|
});
|
|
169493
170721
|
return mergeMemoryResults({
|
|
169494
170722
|
memories,
|
|
@@ -169504,7 +170732,6 @@ function linearDecayScore(rank, total) {
|
|
|
169504
170732
|
return Math.max(0, 1 - rank / total);
|
|
169505
170733
|
}
|
|
169506
170734
|
function searchMessages(args) {
|
|
169507
|
-
ensureMessagesIndexed(args.db, args.sessionId, args.readMessages);
|
|
169508
170735
|
const sanitizedQuery = sanitizeFtsQuery(args.query.trim());
|
|
169509
170736
|
if (sanitizedQuery.length === 0) {
|
|
169510
170737
|
return [];
|
|
@@ -169575,20 +170802,12 @@ function toGitCommitResult(hit) {
|
|
|
169575
170802
|
matchType: hit.matchType
|
|
169576
170803
|
};
|
|
169577
170804
|
}
|
|
169578
|
-
|
|
170805
|
+
function searchGitCommits(args) {
|
|
169579
170806
|
if (args.limit <= 0)
|
|
169580
170807
|
return [];
|
|
169581
|
-
let queryEmbedding = null;
|
|
169582
|
-
if (args.embeddingEnabled && args.isEmbeddingRuntimeEnabled()) {
|
|
169583
|
-
try {
|
|
169584
|
-
queryEmbedding = await args.embedQuery(args.query, args.signal);
|
|
169585
|
-
} catch (error48) {
|
|
169586
|
-
log(`[search] git commit query embedding failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
169587
|
-
}
|
|
169588
|
-
}
|
|
169589
170808
|
const hits = searchGitCommitsSync(args.db, args.projectPath, args.query, {
|
|
169590
170809
|
limit: args.limit,
|
|
169591
|
-
queryEmbedding
|
|
170810
|
+
queryEmbedding: args.queryEmbedding
|
|
169592
170811
|
});
|
|
169593
170812
|
return hits.map(toGitCommitResult);
|
|
169594
170813
|
}
|
|
@@ -169619,37 +170838,37 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
169619
170838
|
const runMemory = activeSources.has("memory") && (options.memoryEnabled ?? true);
|
|
169620
170839
|
const runMessages = activeSources.has("message");
|
|
169621
170840
|
const runGitCommits = activeSources.has("git_commit") && gitCommitsEnabled;
|
|
169622
|
-
const
|
|
170841
|
+
const needsEmbedding = (runMemory || runGitCommits) && embeddingEnabled && isEmbeddingRuntimeEnabled();
|
|
170842
|
+
const queryEmbeddingPromise = needsEmbedding ? embedQuery(trimmedQuery, options.signal).catch((error48) => {
|
|
170843
|
+
log(`[search] query embedding failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
170844
|
+
return null;
|
|
170845
|
+
}) : Promise.resolve(null);
|
|
170846
|
+
await Promise.resolve();
|
|
170847
|
+
const messageResults = runMessages ? searchMessages({
|
|
170848
|
+
db,
|
|
170849
|
+
sessionId,
|
|
170850
|
+
query: trimmedQuery,
|
|
170851
|
+
limit: tierLimit,
|
|
170852
|
+
maxOrdinal: options.maxMessageOrdinal
|
|
170853
|
+
}) : [];
|
|
170854
|
+
const queryEmbedding = await queryEmbeddingPromise;
|
|
170855
|
+
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
169623
170856
|
runMemory ? searchMemories({
|
|
169624
170857
|
db,
|
|
169625
170858
|
projectPath,
|
|
169626
170859
|
query: trimmedQuery,
|
|
169627
170860
|
limit: tierLimit,
|
|
169628
170861
|
memoryEnabled: true,
|
|
169629
|
-
|
|
169630
|
-
|
|
169631
|
-
isEmbeddingRuntimeEnabled,
|
|
169632
|
-
visibleMemoryIds: options.visibleMemoryIds,
|
|
169633
|
-
signal: options.signal
|
|
170862
|
+
queryEmbedding,
|
|
170863
|
+
visibleMemoryIds: options.visibleMemoryIds
|
|
169634
170864
|
}) : Promise.resolve([]),
|
|
169635
|
-
|
|
169636
|
-
db,
|
|
169637
|
-
sessionId,
|
|
169638
|
-
query: trimmedQuery,
|
|
169639
|
-
limit: tierLimit,
|
|
169640
|
-
readMessages: options.readMessages ?? readRawSessionMessages,
|
|
169641
|
-
maxOrdinal: options.maxMessageOrdinal
|
|
169642
|
-
})) : Promise.resolve([]),
|
|
169643
|
-
runGitCommits ? searchGitCommitsAsync({
|
|
170865
|
+
runGitCommits ? Promise.resolve(searchGitCommits({
|
|
169644
170866
|
db,
|
|
169645
170867
|
projectPath,
|
|
169646
170868
|
query: trimmedQuery,
|
|
169647
170869
|
limit: tierLimit,
|
|
169648
|
-
|
|
169649
|
-
|
|
169650
|
-
isEmbeddingRuntimeEnabled,
|
|
169651
|
-
signal: options.signal
|
|
169652
|
-
}) : Promise.resolve([])
|
|
170870
|
+
queryEmbedding
|
|
170871
|
+
})) : Promise.resolve([])
|
|
169653
170872
|
]);
|
|
169654
170873
|
const results = [...memoryResults, ...messageResults, ...gitCommitResults].sort(compareUnifiedResults).slice(0, limit);
|
|
169655
170874
|
const countRetrievals = options.countRetrievals ?? true;
|
|
@@ -169787,8 +171006,31 @@ function collectUserPromptParts(message) {
|
|
|
169787
171006
|
function hasStackedAugmentation(rawText) {
|
|
169788
171007
|
return rawText.includes("<sidekick-augmentation>") || rawText.includes("<ctx-search-hint>") || rawText.includes("<ctx-search-auto>");
|
|
169789
171008
|
}
|
|
171009
|
+
function stripNestedSystemReminders(text) {
|
|
171010
|
+
const OPEN = "<system-reminder>";
|
|
171011
|
+
const CLOSE = "</system-reminder>";
|
|
171012
|
+
let result = "";
|
|
171013
|
+
let depth = 0;
|
|
171014
|
+
let i = 0;
|
|
171015
|
+
while (i < text.length) {
|
|
171016
|
+
if (text.startsWith(OPEN, i)) {
|
|
171017
|
+
depth += 1;
|
|
171018
|
+
i += OPEN.length;
|
|
171019
|
+
} else if (text.startsWith(CLOSE, i)) {
|
|
171020
|
+
if (depth > 0)
|
|
171021
|
+
depth -= 1;
|
|
171022
|
+
i += CLOSE.length;
|
|
171023
|
+
} else if (depth === 0) {
|
|
171024
|
+
result += text[i];
|
|
171025
|
+
i += 1;
|
|
171026
|
+
} else {
|
|
171027
|
+
i += 1;
|
|
171028
|
+
}
|
|
171029
|
+
}
|
|
171030
|
+
return result;
|
|
171031
|
+
}
|
|
169790
171032
|
function extractUserPromptText(message) {
|
|
169791
|
-
return collectUserPromptParts(message).replace(/§\d+§\s*/g, "").replace(/<!--\s*\+[\d\s.hmdw]+\s*-->/g, "").replace(/<!--\s*OMO_INTERNAL_INITIATOR[\s\S]*?-->/g, "").replace(
|
|
171033
|
+
return stripNestedSystemReminders(collectUserPromptParts(message)).replace(/§\d+§\s*/g, "").replace(/<!--\s*\+[\d\s.hmdw]+\s*-->/g, "").replace(/<!--\s*OMO_INTERNAL_INITIATOR[\s\S]*?-->/g, "").replace(/<!--\s*ALFONSO_INTERNAL_INITIATOR[\s\S]*?-->/g, "").replace(/<ctx-search-hint>[\s\S]*?<\/ctx-search-hint>/g, "").replace(/<ctx-search-auto>[\s\S]*?<\/ctx-search-auto>/g, "").replace(/<instruction[^>]*>[\s\S]*?<\/instruction>/g, "").replace(/<sidekick-augmentation>[\s\S]*?<\/sidekick-augmentation>/g, "").replace(/[ \t]+\n/g, `
|
|
169792
171034
|
`).replace(/\n{3,}/g, `
|
|
169793
171035
|
|
|
169794
171036
|
`).trim();
|
|
@@ -169944,8 +171186,8 @@ var DEDUP_SAFE_TOOLS = new Set([
|
|
|
169944
171186
|
"mcp_lsp_prepare_rename"
|
|
169945
171187
|
]);
|
|
169946
171188
|
function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config2, preloadedTags) {
|
|
169947
|
-
const tags = preloadedTags ??
|
|
169948
|
-
const maxTag =
|
|
171189
|
+
const tags = preloadedTags ?? getActiveTagsBySession(db, sessionId);
|
|
171190
|
+
const maxTag = getMaxTagNumberBySession(db, sessionId);
|
|
169949
171191
|
const toolAgeCutoff = maxTag - config2.autoDropToolAge;
|
|
169950
171192
|
const protectedCutoff = maxTag - config2.protectedTags;
|
|
169951
171193
|
let droppedTools = 0;
|
|
@@ -170010,15 +171252,16 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
170010
171252
|
const allMessages = Array.from(messageTagNumbers.keys());
|
|
170011
171253
|
const toolFingerprints = buildToolFingerprints(allMessages);
|
|
170012
171254
|
if (toolFingerprints.size > 0) {
|
|
170013
|
-
const
|
|
171255
|
+
const tagsByCompositeKey = new Map;
|
|
170014
171256
|
for (const tag of tags) {
|
|
170015
171257
|
if (tag.type === "tool" && tag.status === "active" && tag.messageId) {
|
|
170016
|
-
|
|
171258
|
+
const key = tag.toolOwnerMessageId ? `${tag.toolOwnerMessageId}\x00${tag.messageId}` : tag.messageId;
|
|
171259
|
+
tagsByCompositeKey.set(key, tag);
|
|
170017
171260
|
}
|
|
170018
171261
|
}
|
|
170019
171262
|
const fingerprintGroups = new Map;
|
|
170020
|
-
for (const [
|
|
170021
|
-
const tag =
|
|
171263
|
+
for (const [compositeKey, fingerprint] of toolFingerprints) {
|
|
171264
|
+
const tag = tagsByCompositeKey.get(compositeKey);
|
|
170022
171265
|
if (!tag || tag.tagNumber > protectedCutoff)
|
|
170023
171266
|
continue;
|
|
170024
171267
|
const group = fingerprintGroups.get(fingerprint) ?? [];
|
|
@@ -170075,6 +171318,9 @@ function buildToolFingerprints(messages) {
|
|
|
170075
171318
|
for (const message of messages) {
|
|
170076
171319
|
if (message.info.role !== "assistant")
|
|
170077
171320
|
continue;
|
|
171321
|
+
const ownerMsgId = typeof message.info.id === "string" ? message.info.id : null;
|
|
171322
|
+
if (!ownerMsgId)
|
|
171323
|
+
continue;
|
|
170078
171324
|
for (const part of message.parts) {
|
|
170079
171325
|
const record2 = part;
|
|
170080
171326
|
const info = extractToolInfo(record2);
|
|
@@ -170084,8 +171330,9 @@ function buildToolFingerprints(messages) {
|
|
|
170084
171330
|
if (!callId)
|
|
170085
171331
|
continue;
|
|
170086
171332
|
try {
|
|
170087
|
-
const fingerprint = `${info.toolName}:${JSON.stringify(info.args)}`;
|
|
170088
|
-
|
|
171333
|
+
const fingerprint = `${ownerMsgId}:${info.toolName}:${JSON.stringify(info.args)}`;
|
|
171334
|
+
const compositeKey = `${ownerMsgId}\x00${callId}`;
|
|
171335
|
+
fingerprints.set(compositeKey, fingerprint);
|
|
170089
171336
|
} catch {}
|
|
170090
171337
|
}
|
|
170091
171338
|
}
|
|
@@ -170191,7 +171438,7 @@ async function runPostTransformPhase(args) {
|
|
|
170191
171438
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
170192
171439
|
const pendingCountBefore = pendingOps.length;
|
|
170193
171440
|
const tApply = performance.now();
|
|
170194
|
-
didMutateFromPendingOperations = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags,
|
|
171441
|
+
didMutateFromPendingOperations = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, pendingOps);
|
|
170195
171442
|
const pendingCountAfter = getPendingOps(args.db, args.sessionId).length;
|
|
170196
171443
|
if (pendingCountBefore > 0 && pendingCountAfter === 0) {
|
|
170197
171444
|
clearPersistedStickyTurnReminder(args.db, args.sessionId);
|
|
@@ -170222,8 +171469,8 @@ async function runPostTransformPhase(args) {
|
|
|
170222
171469
|
logTransformTiming(args.sessionId, "watermarkCleanup", t6);
|
|
170223
171470
|
}
|
|
170224
171471
|
const t7 = performance.now();
|
|
170225
|
-
const clearedReasoning = clearOldReasoning(args.messages, args.reasoningByMessage, args.messageTagNumbers, args.clearReasoningAge
|
|
170226
|
-
stripClearedReasoning(args.messages
|
|
171472
|
+
const clearedReasoning = clearOldReasoning(args.messages, args.reasoningByMessage, args.messageTagNumbers, args.clearReasoningAge);
|
|
171473
|
+
stripClearedReasoning(args.messages);
|
|
170227
171474
|
const strippedInline = stripInlineThinking(args.messages, args.messageTagNumbers, args.clearReasoningAge);
|
|
170228
171475
|
if (clearedReasoning > 0 || strippedInline > 0) {
|
|
170229
171476
|
let maxTag = 0;
|
|
@@ -170493,6 +171740,9 @@ function createTransform(deps) {
|
|
|
170493
171740
|
const resolvedSessionId = sessionId;
|
|
170494
171741
|
logTransformTiming(sessionId, "findSessionId", startTime, `messages=${messages.length}`);
|
|
170495
171742
|
const db = deps.db;
|
|
171743
|
+
if (deps.client !== undefined) {
|
|
171744
|
+
scheduleReconciliation(db, sessionId, readRawSessionMessages);
|
|
171745
|
+
}
|
|
170496
171746
|
const tUserMsg = performance.now();
|
|
170497
171747
|
const currentTurnId = findLastUserMessageId(messages);
|
|
170498
171748
|
logTransformTiming(sessionId, "findLastUserMessageId", tUserMsg);
|
|
@@ -170508,12 +171758,16 @@ function createTransform(deps) {
|
|
|
170508
171758
|
const reducedMode = sessionMeta.isSubagent;
|
|
170509
171759
|
const fullFeatureMode = !reducedMode;
|
|
170510
171760
|
let sessionDirectory = deps.directory ?? "";
|
|
170511
|
-
|
|
171761
|
+
const cachedDirectory = deps.sessionDirectoryBySession?.get(sessionId);
|
|
171762
|
+
if (cachedDirectory && cachedDirectory.length > 0) {
|
|
171763
|
+
sessionDirectory = cachedDirectory;
|
|
171764
|
+
} else if (deps.client !== undefined) {
|
|
170512
171765
|
try {
|
|
170513
171766
|
const sessionResponse = await deps.client.session.get({ path: { id: sessionId } }).catch(() => null);
|
|
170514
171767
|
const sessionInfo = sessionResponse?.data;
|
|
170515
171768
|
if (sessionInfo && typeof sessionInfo.directory === "string" && sessionInfo.directory.length > 0) {
|
|
170516
171769
|
sessionDirectory = sessionInfo.directory;
|
|
171770
|
+
deps.sessionDirectoryBySession?.set(sessionId, sessionDirectory);
|
|
170517
171771
|
}
|
|
170518
171772
|
} catch {}
|
|
170519
171773
|
}
|
|
@@ -170710,13 +171964,17 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
170710
171964
|
}
|
|
170711
171965
|
}
|
|
170712
171966
|
const t1 = performance.now();
|
|
170713
|
-
const
|
|
170714
|
-
logTransformTiming(sessionId, "
|
|
171967
|
+
const activeTags = getActiveTagsBySession(db, sessionId);
|
|
171968
|
+
logTransformTiming(sessionId, "getActiveTagsBySession", t1, `count=${activeTags.length}`);
|
|
171969
|
+
const t1b = performance.now();
|
|
171970
|
+
const targetTagNumbers = [...targets.keys()];
|
|
171971
|
+
const targetsSliceTags = getTagsByNumbers(db, sessionId, targetTagNumbers);
|
|
171972
|
+
logTransformTiming(sessionId, "getTagsByNumbers", t1b, `targets=${targetTagNumbers.length} fetched=${targetsSliceTags.length}`);
|
|
170715
171973
|
let didMutateFromFlushedStatuses = false;
|
|
170716
171974
|
if (taggingSucceeded) {
|
|
170717
171975
|
try {
|
|
170718
171976
|
const t2 = performance.now();
|
|
170719
|
-
didMutateFromFlushedStatuses = applyFlushedStatuses(sessionId, db, targets,
|
|
171977
|
+
didMutateFromFlushedStatuses = applyFlushedStatuses(sessionId, db, targets, targetsSliceTags);
|
|
170720
171978
|
logTransformTiming(sessionId, "applyFlushedStatuses", t2);
|
|
170721
171979
|
batch?.finalize();
|
|
170722
171980
|
logTransformTiming(sessionId, "batchFinalize:flushed", t2);
|
|
@@ -170732,12 +171990,10 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
170732
171990
|
const t3 = performance.now();
|
|
170733
171991
|
const strippedStructuralNoise = stripStructuralNoise(messages);
|
|
170734
171992
|
logTransformTiming(sessionId, "stripStructuralNoise", t3, `strippedParts=${strippedStructuralNoise}`);
|
|
170735
|
-
const currentSessionModel = deps.liveModelBySession?.get(sessionId) ?? findLastAssistantModel(messages) ?? undefined;
|
|
170736
|
-
const skipTypedReasoningCleanup = modelRequiresInterleavedReasoning(currentSessionModel);
|
|
170737
171993
|
const persistedReasoningWatermark = sessionMeta?.clearedReasoningThroughTag ?? 0;
|
|
170738
171994
|
if (persistedReasoningWatermark > 0) {
|
|
170739
171995
|
const tReplay = performance.now();
|
|
170740
|
-
const replayed = replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark
|
|
171996
|
+
const replayed = replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark);
|
|
170741
171997
|
const replayedInline = replayStrippedInlineThinking(messages, messageTagNumbers, persistedReasoningWatermark);
|
|
170742
171998
|
if (replayed > 0 || replayedInline > 0) {
|
|
170743
171999
|
sessionLog(sessionId, `reasoning replay: cleared=${replayed} inlineStripped=${replayedInline} (watermark=${persistedReasoningWatermark})`);
|
|
@@ -170746,27 +172002,22 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
170746
172002
|
}
|
|
170747
172003
|
if (!deps.ctxReduceEnabled && !reducedMode && deps.cavemanTextCompression?.enabled) {
|
|
170748
172004
|
const tCavemanReplay = performance.now();
|
|
170749
|
-
const replayedCaveman = replayCavemanCompression(sessionId, db, targets,
|
|
172005
|
+
const replayedCaveman = replayCavemanCompression(sessionId, db, targets, targetsSliceTags);
|
|
170750
172006
|
if (replayedCaveman > 0) {
|
|
170751
172007
|
sessionLog(sessionId, `caveman replay: re-applied ${replayedCaveman} text tags`);
|
|
170752
172008
|
}
|
|
170753
172009
|
logTransformTiming(sessionId, "replayCavemanCompression", tCavemanReplay);
|
|
170754
172010
|
}
|
|
170755
172011
|
const t4 = performance.now();
|
|
170756
|
-
const strippedClearedReasoning = stripClearedReasoning(messages
|
|
172012
|
+
const strippedClearedReasoning = stripClearedReasoning(messages);
|
|
170757
172013
|
logTransformTiming(sessionId, "stripClearedReasoning", t4, `strippedParts=${strippedClearedReasoning}`);
|
|
170758
172014
|
const tMergeStrip = performance.now();
|
|
170759
|
-
const strippedMergedReasoning =
|
|
172015
|
+
const strippedMergedReasoning = stripReasoningFromMergedAssistants(messages);
|
|
170760
172016
|
if (strippedMergedReasoning > 0) {
|
|
170761
172017
|
sessionLog(sessionId, `stripped ${strippedMergedReasoning} reasoning parts from merged assistants (anthropic groupIntoBlocks workaround)`);
|
|
170762
172018
|
}
|
|
170763
172019
|
logTransformTiming(sessionId, "stripReasoningFromMergedAssistants", tMergeStrip, `strippedParts=${strippedMergedReasoning}`);
|
|
170764
|
-
|
|
170765
|
-
for (const tag of tags) {
|
|
170766
|
-
if (tag.status === "dropped" && tag.tagNumber > watermark) {
|
|
170767
|
-
watermark = tag.tagNumber;
|
|
170768
|
-
}
|
|
170769
|
-
}
|
|
172020
|
+
const watermark = getMaxDroppedTagNumber(db, sessionId);
|
|
170770
172021
|
const contextUsage = contextUsageEarly;
|
|
170771
172022
|
const schedulerDecision = schedulerDecisionEarly;
|
|
170772
172023
|
const rawGetNotifParams = deps.getNotificationParams;
|
|
@@ -170816,7 +172067,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
170816
172067
|
sessionId,
|
|
170817
172068
|
db,
|
|
170818
172069
|
messages,
|
|
170819
|
-
tags,
|
|
172070
|
+
tags: activeTags,
|
|
170820
172071
|
targets,
|
|
170821
172072
|
reasoningByMessage,
|
|
170822
172073
|
messageTagNumbers,
|
|
@@ -170842,7 +172093,6 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
170842
172093
|
watermark,
|
|
170843
172094
|
forceMaterializationPercentage: FORCE_MATERIALIZE_PERCENTAGE,
|
|
170844
172095
|
hasRecentReduceCall,
|
|
170845
|
-
skipTypedReasoningCleanup,
|
|
170846
172096
|
projectPath: deps.projectPath,
|
|
170847
172097
|
autoSearch: deps.autoSearch,
|
|
170848
172098
|
cavemanTextCompression: deps.ctxReduceEnabled === false && !reducedMode ? deps.cavemanTextCompression : undefined
|
|
@@ -171211,6 +172461,7 @@ function createEventHandler2(deps) {
|
|
|
171211
172461
|
sessionLog(info.sessionID, `event message.removed: invalidating state for message ${info.messageID}`);
|
|
171212
172462
|
try {
|
|
171213
172463
|
const cleanup = cleanupRemovedMessageState(deps, info.sessionID, info.messageID);
|
|
172464
|
+
scheduleClearAndReindex(deps.db, info.sessionID, readRawSessionMessages);
|
|
171214
172465
|
deps.tagger.cleanup(info.sessionID);
|
|
171215
172466
|
sessionLog(info.sessionID, "event message.removed: invalidated tagger session cache");
|
|
171216
172467
|
if (cleanup.clearedNudgePlacement) {
|
|
@@ -171329,7 +172580,7 @@ function createNudger(config2) {
|
|
|
171329
172580
|
}
|
|
171330
172581
|
const largest = formatLargestTags(topNFn(db, sessionId, 3));
|
|
171331
172582
|
const protectedCount = config2.protected_tags;
|
|
171332
|
-
const activeTags =
|
|
172583
|
+
const activeTags = preloadedTags ? preloadedTags.filter((t) => t.status === "active") : getActiveTagsBySession(db, sessionId);
|
|
171333
172584
|
const highestProtected = activeTags.map((t) => t.tagNumber).sort((a, b) => b - a).slice(0, protectedCount)[0];
|
|
171334
172585
|
const protectedHint = highestProtected ? ` Tags §${highestProtected}§ and above are protected (last ${protectedCount}) — You MUST NOT try to reduce those.` : "";
|
|
171335
172586
|
const oldToolHint = formatOldToolTags(activeTags, protectedCount, 5);
|
|
@@ -171420,7 +172671,7 @@ function estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags)
|
|
|
171420
172671
|
if (pendingDrops.length === 0) {
|
|
171421
172672
|
return null;
|
|
171422
172673
|
}
|
|
171423
|
-
const activeTags =
|
|
172674
|
+
const activeTags = preloadedTags ? preloadedTags.filter((t) => t.status === "active") : getActiveTagsBySession(db, sessionId);
|
|
171424
172675
|
const totalActiveBytes = activeTags.reduce((sum, t) => sum + t.byteSize, 0);
|
|
171425
172676
|
if (totalActiveBytes === 0) {
|
|
171426
172677
|
return null;
|
|
@@ -171493,6 +172744,7 @@ function clearSidebarSnapshotCache(sessionId) {
|
|
|
171493
172744
|
// src/hooks/magic-context/hook-handlers.ts
|
|
171494
172745
|
init_logger();
|
|
171495
172746
|
init_note_nudger();
|
|
172747
|
+
await init_read_session_chunk();
|
|
171496
172748
|
var TOOL_HEAVY_TURN_REMINDER_THRESHOLD = 5;
|
|
171497
172749
|
var TOOL_HEAVY_TURN_REMINDER_TEXT = `
|
|
171498
172750
|
|
|
@@ -171545,6 +172797,14 @@ function createEventHook(args) {
|
|
|
171545
172797
|
return async (input) => {
|
|
171546
172798
|
await args.eventHandler(input);
|
|
171547
172799
|
if (input.event.type === "message.updated") {
|
|
172800
|
+
const messageInfo = getMessageUpdatedInfo(input.event.properties);
|
|
172801
|
+
if (messageInfo?.messageID) {
|
|
172802
|
+
const isTerminalUser = messageInfo.role === "user";
|
|
172803
|
+
const isTerminalAssistant = messageInfo.role === "assistant" && (typeof messageInfo.completedAt === "number" || typeof messageInfo.finish === "string");
|
|
172804
|
+
if (isTerminalUser || isTerminalAssistant) {
|
|
172805
|
+
scheduleIncrementalIndex(args.db, messageInfo.sessionID, messageInfo.messageID, readRawSessionMessageById);
|
|
172806
|
+
}
|
|
172807
|
+
}
|
|
171548
172808
|
const assistantInfo = getMessageUpdatedAssistantInfo(input.event.properties);
|
|
171549
172809
|
if (assistantInfo?.providerID && assistantInfo?.modelID) {
|
|
171550
172810
|
const previous = args.liveModelBySession.get(assistantInfo.sessionID);
|
|
@@ -171566,10 +172826,14 @@ function createEventHook(args) {
|
|
|
171566
172826
|
const sessionId = resolveSessionId(properties);
|
|
171567
172827
|
if (!sessionId)
|
|
171568
172828
|
return;
|
|
172829
|
+
if (input.event.type !== "session.deleted") {
|
|
172830
|
+
scheduleReconciliation(args.db, sessionId, readRawSessionMessages);
|
|
172831
|
+
}
|
|
171569
172832
|
if (input.event.type === "session.deleted") {
|
|
171570
172833
|
args.liveModelBySession.delete(sessionId);
|
|
171571
172834
|
args.variantBySession.delete(sessionId);
|
|
171572
172835
|
args.agentBySession.delete(sessionId);
|
|
172836
|
+
args.sessionDirectoryBySession.delete(sessionId);
|
|
171573
172837
|
args.recentReduceBySession.delete(sessionId);
|
|
171574
172838
|
args.toolUsageSinceUserTurn.delete(sessionId);
|
|
171575
172839
|
args.historyRefreshSessions.delete(sessionId);
|
|
@@ -171580,6 +172844,7 @@ function createEventHook(args) {
|
|
|
171580
172844
|
clearNoteNudgeState(args.db, sessionId);
|
|
171581
172845
|
clearAutoSearchForSession(sessionId);
|
|
171582
172846
|
clearSidebarSnapshotCache(sessionId);
|
|
172847
|
+
clearSessionTracking(sessionId);
|
|
171583
172848
|
}
|
|
171584
172849
|
};
|
|
171585
172850
|
}
|
|
@@ -171627,8 +172892,8 @@ init_send_session_notification();
|
|
|
171627
172892
|
|
|
171628
172893
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
171629
172894
|
import { createHash as createHash4 } from "node:crypto";
|
|
171630
|
-
import { existsSync as
|
|
171631
|
-
import { join as
|
|
172895
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8, realpathSync } from "node:fs";
|
|
172896
|
+
import { join as join21, resolve as resolve4, sep } from "node:path";
|
|
171632
172897
|
|
|
171633
172898
|
// src/agents/magic-context-prompt.ts
|
|
171634
172899
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
@@ -171741,9 +173006,9 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
171741
173006
|
function readProjectDocs(directory) {
|
|
171742
173007
|
const sections = [];
|
|
171743
173008
|
for (const filename of DOC_FILES) {
|
|
171744
|
-
const filePath =
|
|
173009
|
+
const filePath = join21(directory, filename);
|
|
171745
173010
|
try {
|
|
171746
|
-
if (
|
|
173011
|
+
if (existsSync12(filePath)) {
|
|
171747
173012
|
const content = readFileSync8(filePath, "utf-8").trim();
|
|
171748
173013
|
if (content.length > 0) {
|
|
171749
173014
|
sections.push(`<${filename}>
|
|
@@ -171856,7 +173121,7 @@ ${items}
|
|
|
171856
173121
|
log(`[magic-context] key file path escapes project root, skipping: ${entry.filePath}`);
|
|
171857
173122
|
continue;
|
|
171858
173123
|
}
|
|
171859
|
-
if (!
|
|
173124
|
+
if (!existsSync12(absPath))
|
|
171860
173125
|
continue;
|
|
171861
173126
|
let realPath;
|
|
171862
173127
|
try {
|
|
@@ -172024,6 +173289,7 @@ function createMagicContextHook(deps) {
|
|
|
172024
173289
|
const variantBySession = deps.liveSessionState?.variantBySession ?? new Map;
|
|
172025
173290
|
const liveModelBySession = deps.liveSessionState?.liveModelBySession ?? new Map;
|
|
172026
173291
|
const agentBySession = deps.liveSessionState?.agentBySession ?? new Map;
|
|
173292
|
+
const sessionDirectoryBySession = deps.liveSessionState?.sessionDirectoryBySession ?? new Map;
|
|
172027
173293
|
const recentReduceBySession = new Map;
|
|
172028
173294
|
const toolUsageSinceUserTurn = new Map;
|
|
172029
173295
|
const resolveLiveModel = (sessionId) => {
|
|
@@ -172091,6 +173357,7 @@ function createMagicContextHook(deps) {
|
|
|
172091
173357
|
compressorMaxMergeDepth: deps.config.compressor?.enabled === false ? undefined : deps.config.compressor?.max_merge_depth,
|
|
172092
173358
|
compressorCooldownMs: deps.config.compressor?.enabled === false ? undefined : deps.config.compressor?.cooldown_ms,
|
|
172093
173359
|
liveModelBySession,
|
|
173360
|
+
sessionDirectoryBySession,
|
|
172094
173361
|
autoSearch: deps.config.experimental?.auto_search?.enabled ? {
|
|
172095
173362
|
enabled: true,
|
|
172096
173363
|
scoreThreshold: deps.config.experimental.auto_search.score_threshold,
|
|
@@ -172255,6 +173522,7 @@ function createMagicContextHook(deps) {
|
|
|
172255
173522
|
liveModelBySession,
|
|
172256
173523
|
variantBySession,
|
|
172257
173524
|
agentBySession,
|
|
173525
|
+
sessionDirectoryBySession,
|
|
172258
173526
|
recentReduceBySession,
|
|
172259
173527
|
toolUsageSinceUserTurn,
|
|
172260
173528
|
historyRefreshSessions,
|
|
@@ -172398,8 +173666,14 @@ function truncateError(name2, code, message, maxLen = 240) {
|
|
|
172398
173666
|
|
|
172399
173667
|
// src/plugin/rpc-handlers.ts
|
|
172400
173668
|
init_project_identity();
|
|
173669
|
+
init_storage_memory();
|
|
173670
|
+
init_tool_definition_tokens();
|
|
172401
173671
|
await init_storage();
|
|
172402
173672
|
init_read_session_formatting();
|
|
173673
|
+
await __promiseAll([
|
|
173674
|
+
init_inject_compartments(),
|
|
173675
|
+
init_read_session_db()
|
|
173676
|
+
]);
|
|
172403
173677
|
|
|
172404
173678
|
// src/hooks/magic-context/tokenizer-calibration.ts
|
|
172405
173679
|
var CALIBRATION_TABLE = [
|
|
@@ -172606,7 +173880,7 @@ function resolveConfigValue(cfg, key, modelKey, defaultValue) {
|
|
|
172606
173880
|
}
|
|
172607
173881
|
return defaultValue;
|
|
172608
173882
|
}
|
|
172609
|
-
function buildSidebarSnapshot(db, sessionId, directory, liveSessionState) {
|
|
173883
|
+
function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens) {
|
|
172610
173884
|
const empty = {
|
|
172611
173885
|
sessionId,
|
|
172612
173886
|
usagePercentage: 0,
|
|
@@ -172691,6 +173965,20 @@ ${c.content}
|
|
|
172691
173965
|
const cached2 = meta3.memory_block_cache;
|
|
172692
173966
|
if (typeof cached2 === "string" && cached2.length > 0) {
|
|
172693
173967
|
memoryTokens = estimateTokens(cached2);
|
|
173968
|
+
} else if (memoryBlockCount > 0 && projectIdentity) {
|
|
173969
|
+
try {
|
|
173970
|
+
let memories = getMemoriesByProject(db, projectIdentity, [
|
|
173971
|
+
"active",
|
|
173972
|
+
"permanent"
|
|
173973
|
+
]);
|
|
173974
|
+
if (injectionBudgetTokens && memories.length > 0) {
|
|
173975
|
+
memories = trimMemoriesToBudget(sessionId, memories, injectionBudgetTokens);
|
|
173976
|
+
}
|
|
173977
|
+
const block = renderMemoryBlock(memories);
|
|
173978
|
+
memoryTokens = block ? estimateTokens(block) : 0;
|
|
173979
|
+
} catch {
|
|
173980
|
+
memoryTokens = 0;
|
|
173981
|
+
}
|
|
172694
173982
|
}
|
|
172695
173983
|
}
|
|
172696
173984
|
let lastDreamerRunAt = null;
|
|
@@ -172709,8 +173997,24 @@ ${c.content}
|
|
|
172709
173997
|
let activeProviderID;
|
|
172710
173998
|
let activeModelID;
|
|
172711
173999
|
if (liveSessionState) {
|
|
172712
|
-
|
|
172713
|
-
|
|
174000
|
+
let model = liveSessionState.liveModelBySession.get(sessionId);
|
|
174001
|
+
let agent = liveSessionState.agentBySession.get(sessionId);
|
|
174002
|
+
if (!model || !agent) {
|
|
174003
|
+
const recovered = findLastAssistantModelFromOpenCodeDb(sessionId);
|
|
174004
|
+
if (recovered) {
|
|
174005
|
+
if (!model) {
|
|
174006
|
+
model = {
|
|
174007
|
+
providerID: recovered.providerID,
|
|
174008
|
+
modelID: recovered.modelID
|
|
174009
|
+
};
|
|
174010
|
+
liveSessionState.liveModelBySession.set(sessionId, model);
|
|
174011
|
+
}
|
|
174012
|
+
if (!agent && recovered.agent) {
|
|
174013
|
+
agent = recovered.agent;
|
|
174014
|
+
liveSessionState.agentBySession.set(sessionId, agent);
|
|
174015
|
+
}
|
|
174016
|
+
}
|
|
174017
|
+
}
|
|
172714
174018
|
if (model) {
|
|
172715
174019
|
activeProviderID = model.providerID;
|
|
172716
174020
|
activeModelID = model.modelID;
|
|
@@ -172759,8 +174063,8 @@ ${c.content}
|
|
|
172759
174063
|
return empty;
|
|
172760
174064
|
}
|
|
172761
174065
|
}
|
|
172762
|
-
function buildStatusDetail(db, sessionId, directory, modelKey, config2, liveSessionState) {
|
|
172763
|
-
const base = buildSidebarSnapshot(db, sessionId, directory, liveSessionState);
|
|
174066
|
+
function buildStatusDetail(db, sessionId, directory, modelKey, config2, liveSessionState, injectionBudgetTokens) {
|
|
174067
|
+
const base = buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens);
|
|
172764
174068
|
const detail = {
|
|
172765
174069
|
...base,
|
|
172766
174070
|
tagCounter: 0,
|
|
@@ -172876,13 +174180,14 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
172876
174180
|
const { directory, config: config2, liveSessionState } = args;
|
|
172877
174181
|
const rawConfig = config2;
|
|
172878
174182
|
const getNotificationParams = (sessionId) => getLiveNotificationParams(sessionId, liveSessionState.liveModelBySession, liveSessionState.variantBySession, liveSessionState.agentBySession);
|
|
174183
|
+
const injectionBudgetTokens = config2.memory?.injection_budget_tokens;
|
|
172879
174184
|
rpcServer.handle("sidebar-snapshot", async (params) => {
|
|
172880
174185
|
const sessionId = String(params.sessionId ?? "");
|
|
172881
174186
|
const dir = String(params.directory ?? directory);
|
|
172882
174187
|
const db = getDb();
|
|
172883
174188
|
if (!db || !sessionId)
|
|
172884
174189
|
return { error: "unavailable" };
|
|
172885
|
-
return buildSidebarSnapshot(db, sessionId, dir, liveSessionState);
|
|
174190
|
+
return buildSidebarSnapshot(db, sessionId, dir, liveSessionState, injectionBudgetTokens);
|
|
172886
174191
|
});
|
|
172887
174192
|
rpcServer.handle("status-detail", async (params) => {
|
|
172888
174193
|
const sessionId = String(params.sessionId ?? "");
|
|
@@ -172891,7 +174196,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
172891
174196
|
const db = getDb();
|
|
172892
174197
|
if (!db || !sessionId)
|
|
172893
174198
|
return { error: "unavailable" };
|
|
172894
|
-
return buildStatusDetail(db, sessionId, dir, modelKey, rawConfig, liveSessionState);
|
|
174199
|
+
return buildStatusDetail(db, sessionId, dir, modelKey, rawConfig, liveSessionState, injectionBudgetTokens);
|
|
172895
174200
|
});
|
|
172896
174201
|
rpcServer.handle("compartment-count", async (params) => {
|
|
172897
174202
|
const sessionId = String(params.sessionId ?? "");
|
|
@@ -173898,19 +175203,19 @@ init_models_dev_cache();
|
|
|
173898
175203
|
|
|
173899
175204
|
// src/shared/rpc-server.ts
|
|
173900
175205
|
init_logger();
|
|
173901
|
-
import { mkdirSync as
|
|
175206
|
+
import { mkdirSync as mkdirSync6, renameSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
173902
175207
|
import { createServer } from "node:http";
|
|
173903
|
-
import { dirname as
|
|
175208
|
+
import { dirname as dirname5 } from "node:path";
|
|
173904
175209
|
|
|
173905
175210
|
// src/shared/rpc-utils.ts
|
|
173906
175211
|
import { createHash as createHash5 } from "node:crypto";
|
|
173907
|
-
import { join as
|
|
175212
|
+
import { join as join22 } from "node:path";
|
|
173908
175213
|
function projectHash(directory) {
|
|
173909
175214
|
const normalized = directory.replace(/\/+$/, "");
|
|
173910
175215
|
return createHash5("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
173911
175216
|
}
|
|
173912
175217
|
function rpcPortFilePath(storageDir, directory) {
|
|
173913
|
-
return
|
|
175218
|
+
return join22(storageDir, "rpc", projectHash(directory), "port");
|
|
173914
175219
|
}
|
|
173915
175220
|
|
|
173916
175221
|
// src/shared/rpc-server.ts
|
|
@@ -173941,10 +175246,10 @@ class MagicContextRpcServer {
|
|
|
173941
175246
|
this.port = addr.port;
|
|
173942
175247
|
this.server = server;
|
|
173943
175248
|
try {
|
|
173944
|
-
const dir =
|
|
173945
|
-
|
|
175249
|
+
const dir = dirname5(this.portFilePath);
|
|
175250
|
+
mkdirSync6(dir, { recursive: true });
|
|
173946
175251
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
173947
|
-
|
|
175252
|
+
writeFileSync6(tmpPath, String(this.port), "utf-8");
|
|
173948
175253
|
renameSync(tmpPath, this.portFilePath);
|
|
173949
175254
|
log(`[rpc] server listening on 127.0.0.1:${this.port}`);
|
|
173950
175255
|
} catch (err) {
|
|
@@ -174106,7 +175411,7 @@ var plugin = async (ctx) => {
|
|
|
174106
175411
|
refreshModelLimitsFromApi(ctx.client);
|
|
174107
175412
|
setInterval(() => {
|
|
174108
175413
|
refreshModelLimitsFromApi(ctx.client);
|
|
174109
|
-
},
|
|
175414
|
+
}, 60 * 60 * 1000);
|
|
174110
175415
|
}
|
|
174111
175416
|
if (conflictResult?.hasConflict) {
|
|
174112
175417
|
sendConflictWarning(ctx.client, ctx.directory, conflictResult);
|