@cortexkit/opencode-magic-context 0.16.3 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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/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.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/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.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1731 -758
- 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/tag-transcript.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/models-dev-cache.test.ts +64 -57
- package/src/shared/models-dev-cache.ts +49 -68
- package/src/shared/tag-transcript.ts +137 -126
- 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) {
|
|
@@ -157228,7 +157296,8 @@ function findLastAssistantModelFromOpenCodeDb(sessionId) {
|
|
|
157228
157296
|
try {
|
|
157229
157297
|
return withReadOnlySessionDb((db) => {
|
|
157230
157298
|
const row = db.prepare(`SELECT json_extract(data, '$.providerID') as providerID,
|
|
157231
|
-
json_extract(data, '$.modelID') as modelID
|
|
157299
|
+
json_extract(data, '$.modelID') as modelID,
|
|
157300
|
+
json_extract(data, '$.agent') as agent
|
|
157232
157301
|
FROM message
|
|
157233
157302
|
WHERE session_id = ?
|
|
157234
157303
|
AND json_extract(data, '$.role') = 'assistant'
|
|
@@ -157239,7 +157308,12 @@ function findLastAssistantModelFromOpenCodeDb(sessionId) {
|
|
|
157239
157308
|
if (!row || typeof row.providerID !== "string" || typeof row.modelID !== "string") {
|
|
157240
157309
|
return null;
|
|
157241
157310
|
}
|
|
157242
|
-
|
|
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
|
+
};
|
|
157243
157317
|
});
|
|
157244
157318
|
} catch (error48) {
|
|
157245
157319
|
log("[magic-context] failed to recover live model from OpenCode DB:", error48);
|
|
@@ -158142,6 +158216,33 @@ function readRawSessionMessagesFromDb(db, sessionId) {
|
|
|
158142
158216
|
};
|
|
158143
158217
|
});
|
|
158144
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
|
+
}
|
|
158145
158246
|
|
|
158146
158247
|
// src/hooks/magic-context/tag-content-primitives.ts
|
|
158147
158248
|
function byteSize(value) {
|
|
@@ -158201,127 +158302,380 @@ var init_tag_part_guards = __esm(() => {
|
|
|
158201
158302
|
init_tag_content_primitives();
|
|
158202
158303
|
});
|
|
158203
158304
|
|
|
158204
|
-
// src/hooks/magic-context/
|
|
158205
|
-
function
|
|
158206
|
-
return
|
|
158305
|
+
// src/hooks/magic-context/tool-drop-target.ts
|
|
158306
|
+
function isToolCallId(value) {
|
|
158307
|
+
return typeof value === "string" && value.length > 0;
|
|
158207
158308
|
}
|
|
158208
|
-
function
|
|
158209
|
-
|
|
158210
|
-
|
|
158211
|
-
|
|
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;
|
|
158212
158314
|
}
|
|
158213
|
-
|
|
158214
|
-
return
|
|
158215
|
-
} finally {
|
|
158216
|
-
if (!outerCache) {
|
|
158217
|
-
activeRawMessageCache = null;
|
|
158218
|
-
}
|
|
158315
|
+
if (part.type === "tool_result") {
|
|
158316
|
+
return typeof part.content === "string" ? part.content : undefined;
|
|
158219
158317
|
}
|
|
158318
|
+
return;
|
|
158220
158319
|
}
|
|
158221
|
-
function
|
|
158222
|
-
if (
|
|
158223
|
-
|
|
158224
|
-
|
|
158225
|
-
|
|
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;
|
|
158326
|
+
}
|
|
158327
|
+
if (part.type === "tool_result") {
|
|
158328
|
+
part.content = content;
|
|
158329
|
+
}
|
|
158330
|
+
}
|
|
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);
|
|
158341
|
+
}
|
|
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);
|
|
158226
158360
|
}
|
|
158227
|
-
const messages = readRawSessionMessagesFromSource(sessionId);
|
|
158228
|
-
activeRawMessageCache.set(sessionId, messages);
|
|
158229
|
-
return messages;
|
|
158230
158361
|
}
|
|
158231
|
-
return readRawSessionMessagesFromSource(sessionId);
|
|
158232
158362
|
}
|
|
158233
|
-
function
|
|
158234
|
-
|
|
158235
|
-
|
|
158236
|
-
|
|
158237
|
-
|
|
158363
|
+
function estimateInputSize(input) {
|
|
158364
|
+
try {
|
|
158365
|
+
return JSON.stringify(input).length;
|
|
158366
|
+
} catch {
|
|
158367
|
+
return 0;
|
|
158368
|
+
}
|
|
158238
158369
|
}
|
|
158239
|
-
function
|
|
158240
|
-
|
|
158241
|
-
|
|
158242
|
-
|
|
158243
|
-
|
|
158244
|
-
return
|
|
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);
|
|
158245
158376
|
}
|
|
158246
|
-
return
|
|
158377
|
+
return str.slice(0, maxLen);
|
|
158247
158378
|
}
|
|
158248
|
-
function
|
|
158249
|
-
const
|
|
158250
|
-
|
|
158251
|
-
|
|
158252
|
-
|
|
158253
|
-
|
|
158254
|
-
|
|
158255
|
-
|
|
158256
|
-
|
|
158257
|
-
|
|
158258
|
-
|
|
158259
|
-
keys.push(`${message.id}:file${partIndex}`);
|
|
158260
|
-
}
|
|
158261
|
-
if (isToolPartWithOutput(part)) {
|
|
158262
|
-
keys.push(part.callID);
|
|
158263
|
-
}
|
|
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]";
|
|
158264
158390
|
}
|
|
158265
158391
|
}
|
|
158266
|
-
return keys;
|
|
158267
158392
|
}
|
|
158268
|
-
function
|
|
158269
|
-
|
|
158270
|
-
|
|
158271
|
-
|
|
158272
|
-
|
|
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;
|
|
158273
158399
|
}
|
|
158274
|
-
|
|
158400
|
+
if (typeof type !== "string")
|
|
158401
|
+
return false;
|
|
158402
|
+
if (IGNORE_PART_TYPES.has(type))
|
|
158403
|
+
return false;
|
|
158404
|
+
return true;
|
|
158275
158405
|
}
|
|
158276
|
-
function
|
|
158277
|
-
const
|
|
158278
|
-
|
|
158279
|
-
|
|
158280
|
-
|
|
158281
|
-
|
|
158282
|
-
let totalTokens = 0;
|
|
158283
|
-
let messagesProcessed = 0;
|
|
158284
|
-
let lastOrdinal = startOrdinal - 1;
|
|
158285
|
-
let lastMessageId = "";
|
|
158286
|
-
let firstMessageId = "";
|
|
158287
|
-
let currentBlock = null;
|
|
158288
|
-
let pendingNoiseMeta = [];
|
|
158289
|
-
let commitClusters = 0;
|
|
158290
|
-
let lastFlushedRole = "";
|
|
158291
|
-
function flushCurrentBlock() {
|
|
158292
|
-
if (!currentBlock)
|
|
158293
|
-
return true;
|
|
158294
|
-
const blockText = formatBlock(currentBlock);
|
|
158295
|
-
const blockTokens = estimateTokens(blockText);
|
|
158296
|
-
if (totalTokens + blockTokens > tokenBudget && totalTokens > 0) {
|
|
158297
|
-
return false;
|
|
158298
|
-
}
|
|
158299
|
-
if (currentBlock.role === "A" && currentBlock.commitHashes.length > 0 && lastFlushedRole !== "A") {
|
|
158300
|
-
commitClusters++;
|
|
158301
|
-
}
|
|
158302
|
-
lastFlushedRole = currentBlock.role;
|
|
158303
|
-
if (!firstMessageId)
|
|
158304
|
-
firstMessageId = currentBlock.meta[0]?.messageId ?? "";
|
|
158305
|
-
lastOrdinal = currentBlock.meta[currentBlock.meta.length - 1]?.ordinal ?? currentBlock.endOrdinal;
|
|
158306
|
-
lastMessageId = currentBlock.meta[currentBlock.meta.length - 1]?.messageId ?? "";
|
|
158307
|
-
messagesProcessed += currentBlock.meta.length;
|
|
158308
|
-
lines.push(blockText);
|
|
158309
|
-
lineMeta.push(...currentBlock.meta);
|
|
158310
|
-
totalTokens += blockTokens;
|
|
158311
|
-
if (currentBlock.isToolOnly) {
|
|
158312
|
-
flushedToolOnlyBlocks.push({
|
|
158313
|
-
start: currentBlock.startOrdinal,
|
|
158314
|
-
end: currentBlock.endOrdinal
|
|
158315
|
-
});
|
|
158316
|
-
}
|
|
158317
|
-
currentBlock = null;
|
|
158318
|
-
return true;
|
|
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]";
|
|
158319
158412
|
}
|
|
158320
|
-
|
|
158321
|
-
|
|
158322
|
-
|
|
158323
|
-
|
|
158324
|
-
|
|
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;
|
|
158638
|
+
let lastOrdinal = startOrdinal - 1;
|
|
158639
|
+
let lastMessageId = "";
|
|
158640
|
+
let firstMessageId = "";
|
|
158641
|
+
let currentBlock = null;
|
|
158642
|
+
let pendingNoiseMeta = [];
|
|
158643
|
+
let commitClusters = 0;
|
|
158644
|
+
let lastFlushedRole = "";
|
|
158645
|
+
function flushCurrentBlock() {
|
|
158646
|
+
if (!currentBlock)
|
|
158647
|
+
return true;
|
|
158648
|
+
const blockText = formatBlock(currentBlock);
|
|
158649
|
+
const blockTokens = estimateTokens(blockText);
|
|
158650
|
+
if (totalTokens + blockTokens > tokenBudget && totalTokens > 0) {
|
|
158651
|
+
return false;
|
|
158652
|
+
}
|
|
158653
|
+
if (currentBlock.role === "A" && currentBlock.commitHashes.length > 0 && lastFlushedRole !== "A") {
|
|
158654
|
+
commitClusters++;
|
|
158655
|
+
}
|
|
158656
|
+
lastFlushedRole = currentBlock.role;
|
|
158657
|
+
if (!firstMessageId)
|
|
158658
|
+
firstMessageId = currentBlock.meta[0]?.messageId ?? "";
|
|
158659
|
+
lastOrdinal = currentBlock.meta[currentBlock.meta.length - 1]?.ordinal ?? currentBlock.endOrdinal;
|
|
158660
|
+
lastMessageId = currentBlock.meta[currentBlock.meta.length - 1]?.messageId ?? "";
|
|
158661
|
+
messagesProcessed += currentBlock.meta.length;
|
|
158662
|
+
lines.push(blockText);
|
|
158663
|
+
lineMeta.push(...currentBlock.meta);
|
|
158664
|
+
totalTokens += blockTokens;
|
|
158665
|
+
if (currentBlock.isToolOnly) {
|
|
158666
|
+
flushedToolOnlyBlocks.push({
|
|
158667
|
+
start: currentBlock.startOrdinal,
|
|
158668
|
+
end: currentBlock.endOrdinal
|
|
158669
|
+
});
|
|
158670
|
+
}
|
|
158671
|
+
currentBlock = null;
|
|
158672
|
+
return true;
|
|
158673
|
+
}
|
|
158674
|
+
for (const msg of messages) {
|
|
158675
|
+
if (eligibleEndOrdinal !== undefined && msg.ordinal >= eligibleEndOrdinal)
|
|
158676
|
+
break;
|
|
158677
|
+
if (msg.ordinal < startOrdinal)
|
|
158678
|
+
continue;
|
|
158325
158679
|
const meta3 = { ordinal: msg.ordinal, messageId: msg.id };
|
|
158326
158680
|
if (msg.role === "user" && !hasMeaningfulUserText(msg.parts)) {
|
|
158327
158681
|
const tcSummaries = extractToolCallSummaries(msg.parts);
|
|
@@ -158414,6 +158768,7 @@ var activeRawMessageCache = null, sessionProviders, PROTECTED_TAIL_USER_TURNS =
|
|
|
158414
158768
|
var init_read_session_chunk = __esm(async () => {
|
|
158415
158769
|
init_read_session_formatting();
|
|
158416
158770
|
init_tag_part_guards();
|
|
158771
|
+
init_tool_drop_target();
|
|
158417
158772
|
init_read_session_formatting();
|
|
158418
158773
|
await init_read_session_db();
|
|
158419
158774
|
sessionProviders = new Map;
|
|
@@ -158471,10 +158826,26 @@ function getCountIndexedMessageStatement(db) {
|
|
|
158471
158826
|
}
|
|
158472
158827
|
return stmt;
|
|
158473
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
|
+
}
|
|
158474
158837
|
function getLastIndexedOrdinal(db, sessionId) {
|
|
158475
158838
|
const row = getLastIndexedStatement(db).get(sessionId);
|
|
158476
158839
|
return typeof row?.last_indexed_ordinal === "number" ? row.last_indexed_ordinal : 0;
|
|
158477
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
|
+
}
|
|
158478
158849
|
function deleteIndexedMessage(db, sessionId, messageId) {
|
|
158479
158850
|
const row = getCountIndexedMessageStatement(db).get(sessionId, messageId);
|
|
158480
158851
|
const count = typeof row?.count === "number" ? row.count : 0;
|
|
@@ -158500,36 +158871,53 @@ function getIndexableContent(role, parts) {
|
|
|
158500
158871
|
}
|
|
158501
158872
|
return "";
|
|
158502
158873
|
}
|
|
158503
|
-
function
|
|
158504
|
-
|
|
158505
|
-
|
|
158506
|
-
|
|
158507
|
-
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;
|
|
158508
158878
|
}
|
|
158509
|
-
|
|
158510
|
-
if (
|
|
158511
|
-
db
|
|
158512
|
-
|
|
158879
|
+
const content = getIndexableContent(message.role, message.parts);
|
|
158880
|
+
if (content.length === 0) {
|
|
158881
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
158882
|
+
return false;
|
|
158513
158883
|
}
|
|
158514
|
-
if (
|
|
158515
|
-
|
|
158884
|
+
if (isMessageAlreadyIndexed(db, sessionId, message.id)) {
|
|
158885
|
+
advanceIndexWatermark(db, sessionId, message.ordinal, now);
|
|
158886
|
+
return false;
|
|
158516
158887
|
}
|
|
158517
|
-
|
|
158518
|
-
|
|
158519
|
-
|
|
158520
|
-
|
|
158521
|
-
|
|
158522
|
-
|
|
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) {
|
|
158523
158896
|
const now = Date.now();
|
|
158897
|
+
let inserted = 0;
|
|
158524
158898
|
db.transaction(() => {
|
|
158899
|
+
const existingMessageIds = new Set(getIndexedMessageIdStatement(db).all(sessionId).map((row) => row.messageId).filter((messageId) => typeof messageId === "string"));
|
|
158525
158900
|
const insertMessage = getInsertMessageStatement(db);
|
|
158526
|
-
for (const message of
|
|
158527
|
-
|
|
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++;
|
|
158528
158915
|
}
|
|
158529
|
-
getUpsertIndexStatement(db).run(sessionId,
|
|
158916
|
+
getUpsertIndexStatement(db).run(sessionId, finalWatermark, now, getHarness());
|
|
158530
158917
|
})();
|
|
158918
|
+
return inserted;
|
|
158531
158919
|
}
|
|
158532
|
-
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements;
|
|
158920
|
+
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements, indexedMessageIdStatements;
|
|
158533
158921
|
var init_message_index = __esm(async () => {
|
|
158534
158922
|
init_compression_depth_storage();
|
|
158535
158923
|
await init_read_session_chunk();
|
|
@@ -158539,6 +158927,7 @@ var init_message_index = __esm(async () => {
|
|
|
158539
158927
|
deleteFtsStatements = new WeakMap;
|
|
158540
158928
|
deleteIndexStatements = new WeakMap;
|
|
158541
158929
|
countIndexedMessageStatements = new WeakMap;
|
|
158930
|
+
indexedMessageIdStatements = new WeakMap;
|
|
158542
158931
|
});
|
|
158543
158932
|
|
|
158544
158933
|
// src/features/magic-context/migrations.ts
|
|
@@ -158555,24 +158944,53 @@ function getCurrentVersion(db) {
|
|
|
158555
158944
|
const row = db.prepare("SELECT MAX(version) as version FROM schema_migrations").get();
|
|
158556
158945
|
return row?.version ?? 0;
|
|
158557
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
|
+
}
|
|
158558
158961
|
function runMigrations(db) {
|
|
158559
158962
|
ensureMigrationsTable(db);
|
|
158560
|
-
|
|
158561
|
-
|
|
158963
|
+
let currentVersion = getCurrentVersion(db);
|
|
158964
|
+
let pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
|
|
158562
158965
|
if (pendingMigrations.length === 0) {
|
|
158563
158966
|
return;
|
|
158564
158967
|
}
|
|
158565
158968
|
log(`[migrations] current schema version: ${currentVersion}, applying ${pendingMigrations.length} migration(s)`);
|
|
158566
|
-
|
|
158969
|
+
let migrationIndex = 0;
|
|
158970
|
+
while (migrationIndex < pendingMigrations.length) {
|
|
158971
|
+
const migration = pendingMigrations[migrationIndex];
|
|
158567
158972
|
try {
|
|
158568
158973
|
db.transaction(() => {
|
|
158569
158974
|
migration.up(db);
|
|
158570
158975
|
db.prepare("INSERT INTO schema_migrations (version, description, applied_at) VALUES (?, ?, ?)").run(migration.version, migration.description, Date.now());
|
|
158571
158976
|
})();
|
|
158572
158977
|
log(`[migrations] applied v${migration.version}: ${migration.description}`);
|
|
158978
|
+
migrationIndex += 1;
|
|
158573
158979
|
} catch (error48) {
|
|
158574
|
-
|
|
158575
|
-
|
|
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
|
+
}
|
|
158992
|
+
log(`[migrations] FAILED v${migration.version}: ${migration.description} — ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
158993
|
+
throw new Error(`Migration v${migration.version} failed: ${error48 instanceof Error ? error48.message : String(error48)}. Database may need manual repair.`);
|
|
158576
158994
|
}
|
|
158577
158995
|
}
|
|
158578
158996
|
log(`[migrations] schema version now: ${MIGRATIONS[MIGRATIONS.length - 1].version}`);
|
|
@@ -158782,30 +159200,330 @@ var init_migrations = __esm(async () => {
|
|
|
158782
159200
|
db.exec("ALTER TABLE notes ADD COLUMN harness TEXT NOT NULL DEFAULT 'opencode'");
|
|
158783
159201
|
}
|
|
158784
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
|
+
}
|
|
158785
159255
|
}
|
|
158786
159256
|
];
|
|
158787
159257
|
});
|
|
158788
159258
|
|
|
158789
|
-
// src/features/magic-context/
|
|
158790
|
-
import {
|
|
159259
|
+
// src/features/magic-context/tool-owner-backfill.ts
|
|
159260
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
158791
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
|
+
|
|
159507
|
+
// src/features/magic-context/storage-db.ts
|
|
159508
|
+
import { copyFileSync, cpSync, existsSync as existsSync10, mkdirSync as mkdirSync3 } from "node:fs";
|
|
159509
|
+
import { join as join15 } from "node:path";
|
|
158792
159510
|
function resolveDatabasePath() {
|
|
158793
159511
|
const dbDir = getMagicContextStorageDir();
|
|
158794
|
-
return { dbDir, dbPath:
|
|
159512
|
+
return { dbDir, dbPath: join15(dbDir, "context.db") };
|
|
158795
159513
|
}
|
|
158796
159514
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
158797
|
-
if (
|
|
159515
|
+
if (existsSync10(targetDbPath))
|
|
158798
159516
|
return;
|
|
158799
159517
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
158800
|
-
const legacyDbPath =
|
|
158801
|
-
if (!
|
|
159518
|
+
const legacyDbPath = join15(legacyDir, "context.db");
|
|
159519
|
+
if (!existsSync10(legacyDbPath))
|
|
158802
159520
|
return;
|
|
158803
159521
|
log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
158804
159522
|
mkdirSync3(targetDbDir, { recursive: true });
|
|
158805
159523
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
158806
159524
|
const src = `${legacyDbPath}${suffix}`;
|
|
158807
|
-
const dst =
|
|
158808
|
-
if (
|
|
159525
|
+
const dst = join15(targetDbDir, `context.db${suffix}`);
|
|
159526
|
+
if (existsSync10(src)) {
|
|
158809
159527
|
try {
|
|
158810
159528
|
copyFileSync(src, dst);
|
|
158811
159529
|
} catch (error48) {
|
|
@@ -158813,9 +159531,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
158813
159531
|
}
|
|
158814
159532
|
}
|
|
158815
159533
|
}
|
|
158816
|
-
const legacyModelsDir =
|
|
158817
|
-
const targetModelsDir =
|
|
158818
|
-
if (
|
|
159534
|
+
const legacyModelsDir = join15(legacyDir, "models");
|
|
159535
|
+
const targetModelsDir = join15(targetDbDir, "models");
|
|
159536
|
+
if (existsSync10(legacyModelsDir) && !existsSync10(targetModelsDir)) {
|
|
158819
159537
|
try {
|
|
158820
159538
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
158821
159539
|
} catch (error48) {
|
|
@@ -159101,6 +159819,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
159101
159819
|
ensureColumn(db, "tags", "tool_name", "TEXT");
|
|
159102
159820
|
ensureColumn(db, "tags", "input_byte_size", "INTEGER DEFAULT 0");
|
|
159103
159821
|
ensureColumn(db, "tags", "caveman_depth", "INTEGER DEFAULT 0");
|
|
159822
|
+
ensureColumn(db, "tags", "tool_owner_message_id", "TEXT DEFAULT NULL");
|
|
159104
159823
|
ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
|
|
159105
159824
|
ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
|
|
159106
159825
|
ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
|
|
@@ -159199,6 +159918,13 @@ function openDatabase() {
|
|
|
159199
159918
|
const db = new Database(dbPath);
|
|
159200
159919
|
initializeDatabase(db);
|
|
159201
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);
|
|
159202
159928
|
databases.set(dbPath, db);
|
|
159203
159929
|
persistenceByDatabase.set(db, true);
|
|
159204
159930
|
persistenceErrorByDatabase.delete(db);
|
|
@@ -159219,6 +159945,8 @@ var databases, persistenceByDatabase, persistenceErrorByDatabase;
|
|
|
159219
159945
|
var init_storage_db = __esm(async () => {
|
|
159220
159946
|
init_data_path();
|
|
159221
159947
|
init_logger();
|
|
159948
|
+
init_tool_definition_tokens();
|
|
159949
|
+
init_tool_owner_backfill();
|
|
159222
159950
|
await __promiseAll([
|
|
159223
159951
|
init_sqlite(),
|
|
159224
159952
|
init_migrations()
|
|
@@ -159789,7 +160517,7 @@ var init_storage_source = () => {};
|
|
|
159789
160517
|
function getInsertTagStatement(db) {
|
|
159790
160518
|
let stmt = insertTagStatements.get(db);
|
|
159791
160519
|
if (!stmt) {
|
|
159792
|
-
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
159793
160521
|
insertTagStatements.set(db, stmt);
|
|
159794
160522
|
}
|
|
159795
160523
|
return stmt;
|
|
@@ -159870,7 +160598,8 @@ function toTagEntry(row) {
|
|
|
159870
160598
|
byteSize: row.byte_size,
|
|
159871
160599
|
reasoningByteSize: row.reasoning_byte_size ?? 0,
|
|
159872
160600
|
sessionId: row.session_id,
|
|
159873
|
-
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
|
|
159874
160603
|
};
|
|
159875
160604
|
}
|
|
159876
160605
|
function isTagNumberRow(row) {
|
|
@@ -159888,8 +160617,8 @@ function isMaxTagNumberRow(row) {
|
|
|
159888
160617
|
function escapeLikePattern(value) {
|
|
159889
160618
|
return value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
159890
160619
|
}
|
|
159891
|
-
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0) {
|
|
159892
|
-
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);
|
|
159893
160622
|
return tagNumber;
|
|
159894
160623
|
}
|
|
159895
160624
|
function updateTagStatus(db, sessionId, tagId, status) {
|
|
@@ -159908,12 +160637,27 @@ function deleteTagsByMessageId(db, sessionId, messageId) {
|
|
|
159908
160637
|
const escapedMessageId = escapeLikePattern(messageId);
|
|
159909
160638
|
const textPartPattern = `${escapedMessageId}:p%`;
|
|
159910
160639
|
const filePartPattern = `${escapedMessageId}:file%`;
|
|
159911
|
-
const
|
|
159912
|
-
|
|
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) {
|
|
159913
160643
|
return [];
|
|
159914
160644
|
}
|
|
159915
|
-
|
|
159916
|
-
|
|
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);
|
|
159917
160661
|
}
|
|
159918
160662
|
function getMaxTagNumberBySession(db, sessionId) {
|
|
159919
160663
|
const row = getMaxTagNumberBySessionStatement(db).get(sessionId);
|
|
@@ -159924,17 +160668,151 @@ function getTagNumberByMessageId(db, sessionId, messageId) {
|
|
|
159924
160668
|
return isTagNumberRow(row) ? row.tag_number : null;
|
|
159925
160669
|
}
|
|
159926
160670
|
function getTagsBySession(db, sessionId) {
|
|
159927
|
-
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);
|
|
159928
160706
|
return rows.map(toTagEntry);
|
|
159929
160707
|
}
|
|
160708
|
+
function getMaxDroppedTagNumber(db, sessionId) {
|
|
160709
|
+
const row = getMaxDroppedTagNumberStatement(db).get(sessionId);
|
|
160710
|
+
return isMaxTagNumberRow(row) ? row.max_tag_number : 0;
|
|
160711
|
+
}
|
|
159930
160712
|
function getTopNBySize(db, sessionId, n) {
|
|
159931
160713
|
if (n <= 0) {
|
|
159932
160714
|
return [];
|
|
159933
160715
|
}
|
|
159934
|
-
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);
|
|
159935
160717
|
return rows.map(toTagEntry);
|
|
159936
160718
|
}
|
|
159937
|
-
|
|
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;
|
|
159938
160816
|
var init_storage_tags = __esm(() => {
|
|
159939
160817
|
insertTagStatements = new WeakMap;
|
|
159940
160818
|
updateTagStatusStatements = new WeakMap;
|
|
@@ -159946,6 +160824,13 @@ var init_storage_tags = __esm(() => {
|
|
|
159946
160824
|
getTagNumberByMessageIdStatements = new WeakMap;
|
|
159947
160825
|
updateTagByteSizeStatements = new WeakMap;
|
|
159948
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;
|
|
159949
160834
|
});
|
|
159950
160835
|
|
|
159951
160836
|
// src/features/magic-context/storage.ts
|
|
@@ -159965,9 +160850,9 @@ var init_storage = __esm(async () => {
|
|
|
159965
160850
|
|
|
159966
160851
|
// src/shared/models-dev-cache.ts
|
|
159967
160852
|
import { createHash as createHash3 } from "node:crypto";
|
|
159968
|
-
import { existsSync as
|
|
160853
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
|
|
159969
160854
|
import { homedir as homedir8, platform as platform3 } from "node:os";
|
|
159970
|
-
import { join as
|
|
160855
|
+
import { join as join16 } from "node:path";
|
|
159971
160856
|
function hashFast(input) {
|
|
159972
160857
|
return createHash3("sha1").update(input).digest("hex");
|
|
159973
160858
|
}
|
|
@@ -159978,16 +160863,16 @@ function getModelsJsonPath() {
|
|
|
159978
160863
|
const cacheBase = getCacheDir();
|
|
159979
160864
|
const source = process.env.OPENCODE_MODELS_URL?.trim();
|
|
159980
160865
|
const filename = source && source !== "https://models.dev" ? `models-${hashFast(source)}.json` : "models.json";
|
|
159981
|
-
return
|
|
160866
|
+
return join16(cacheBase, "opencode", filename);
|
|
159982
160867
|
}
|
|
159983
160868
|
function getOpencodeConfigPath() {
|
|
159984
160869
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
159985
|
-
const configDir = envDir ? envDir : platform3() === "win32" ?
|
|
159986
|
-
const jsonc =
|
|
159987
|
-
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))
|
|
159988
160873
|
return jsonc;
|
|
159989
|
-
const json2 =
|
|
159990
|
-
if (
|
|
160874
|
+
const json2 = join16(configDir, "opencode.json");
|
|
160875
|
+
if (existsSync11(json2))
|
|
159991
160876
|
return json2;
|
|
159992
160877
|
return null;
|
|
159993
160878
|
}
|
|
@@ -160000,23 +160885,12 @@ function resolveLimit(limit) {
|
|
|
160000
160885
|
return limit.context;
|
|
160001
160886
|
return;
|
|
160002
160887
|
}
|
|
160003
|
-
function resolveInterleavedField(interleaved) {
|
|
160004
|
-
if (interleaved && typeof interleaved === "object" && typeof interleaved.field === "string" && interleaved.field.length > 0) {
|
|
160005
|
-
return interleaved.field;
|
|
160006
|
-
}
|
|
160007
|
-
return;
|
|
160008
|
-
}
|
|
160009
160888
|
function setCachedModelMetadata(cache, key, model) {
|
|
160010
160889
|
const limit = resolveLimit(model?.limit);
|
|
160011
|
-
|
|
160012
|
-
if (limit === undefined && interleavedField === undefined) {
|
|
160890
|
+
if (limit === undefined) {
|
|
160013
160891
|
return;
|
|
160014
160892
|
}
|
|
160015
|
-
const value = {};
|
|
160016
|
-
if (limit !== undefined)
|
|
160017
|
-
value.limit = limit;
|
|
160018
|
-
if (interleavedField !== undefined)
|
|
160019
|
-
value.interleavedField = interleavedField;
|
|
160893
|
+
const value = { limit };
|
|
160020
160894
|
cache.set(key, value);
|
|
160021
160895
|
const modes = model?.experimental?.modes;
|
|
160022
160896
|
if (modes && typeof modes === "object") {
|
|
@@ -160030,7 +160904,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
160030
160904
|
const modelsJsonPath = getModelsJsonPath();
|
|
160031
160905
|
let fileFound = false;
|
|
160032
160906
|
try {
|
|
160033
|
-
if (
|
|
160907
|
+
if (existsSync11(modelsJsonPath)) {
|
|
160034
160908
|
fileFound = true;
|
|
160035
160909
|
const raw = readFileSync7(modelsJsonPath, "utf-8");
|
|
160036
160910
|
const data = JSON.parse(raw);
|
|
@@ -160047,7 +160921,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
160047
160921
|
}
|
|
160048
160922
|
try {
|
|
160049
160923
|
const configPath = getOpencodeConfigPath();
|
|
160050
|
-
if (configPath &&
|
|
160924
|
+
if (configPath && existsSync11(configPath)) {
|
|
160051
160925
|
let raw = readFileSync7(configPath, "utf-8");
|
|
160052
160926
|
raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
|
|
160053
160927
|
const config2 = JSON.parse(raw);
|
|
@@ -160088,8 +160962,18 @@ async function refreshModelLimitsFromApi(client) {
|
|
|
160088
160962
|
const previousSize = apiCache?.size ?? null;
|
|
160089
160963
|
apiCache = map2;
|
|
160090
160964
|
apiLoadedAt = Date.now();
|
|
160091
|
-
if (previousSize === null
|
|
160092
|
-
|
|
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
|
+
}
|
|
160093
160977
|
}
|
|
160094
160978
|
} catch (error48) {
|
|
160095
160979
|
sessionLog("global", "models-dev-cache: API refresh failed:", error48 instanceof Error ? error48.message : String(error48));
|
|
@@ -160109,27 +160993,12 @@ function getModelsDevContextLimit(providerID, modelID) {
|
|
|
160109
160993
|
}
|
|
160110
160994
|
return fileCache.get(key)?.limit;
|
|
160111
160995
|
}
|
|
160112
|
-
|
|
160113
|
-
const key = `${providerID}/${modelID}`;
|
|
160114
|
-
if (apiCache) {
|
|
160115
|
-
const fromApi = apiCache.get(key)?.interleavedField;
|
|
160116
|
-
if (typeof fromApi === "string" && fromApi.length > 0) {
|
|
160117
|
-
return fromApi;
|
|
160118
|
-
}
|
|
160119
|
-
}
|
|
160120
|
-
const now = Date.now();
|
|
160121
|
-
if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
|
|
160122
|
-
fileLastAttempt = now;
|
|
160123
|
-
fileCache = loadModelsDevMetadataFromFile();
|
|
160124
|
-
}
|
|
160125
|
-
const fromFile = fileCache.get(key)?.interleavedField;
|
|
160126
|
-
return typeof fromFile === "string" && fromFile.length > 0 ? fromFile : undefined;
|
|
160127
|
-
}
|
|
160128
|
-
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;
|
|
160129
160997
|
var init_models_dev_cache = __esm(() => {
|
|
160130
160998
|
init_data_path();
|
|
160131
160999
|
init_logger();
|
|
160132
161000
|
RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
161001
|
+
recentlySeenApiSizes = new Set;
|
|
160133
161002
|
});
|
|
160134
161003
|
|
|
160135
161004
|
// src/shared/rpc-notifications.ts
|
|
@@ -160381,7 +161250,7 @@ var init_compartment_runner_validation = __esm(async () => {
|
|
|
160381
161250
|
// src/hooks/magic-context/compartment-runner-historian.ts
|
|
160382
161251
|
import { mkdirSync as mkdirSync4, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
160383
161252
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
160384
|
-
import { join as
|
|
161253
|
+
import { join as join17 } from "node:path";
|
|
160385
161254
|
async function runValidatedHistorianPass(args) {
|
|
160386
161255
|
const firstRun = await runHistorianPrompt({
|
|
160387
161256
|
...args,
|
|
@@ -160624,7 +161493,7 @@ function dumpHistorianResponse(sessionId, label, text) {
|
|
|
160624
161493
|
mkdirSync4(HISTORIAN_RESPONSE_DUMP_DIR, { recursive: true });
|
|
160625
161494
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
160626
161495
|
const safeLabel = sanitizeDumpName(label);
|
|
160627
|
-
const dumpPath =
|
|
161496
|
+
const dumpPath = join17(HISTORIAN_RESPONSE_DUMP_DIR, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
160628
161497
|
writeFileSync4(dumpPath, text, "utf8");
|
|
160629
161498
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
160630
161499
|
label,
|
|
@@ -160649,7 +161518,7 @@ var init_compartment_runner_historian = __esm(async () => {
|
|
|
160649
161518
|
init_assistant_message_extractor();
|
|
160650
161519
|
init_compartment_prompt();
|
|
160651
161520
|
await init_compartment_runner_validation();
|
|
160652
|
-
HISTORIAN_RESPONSE_DUMP_DIR =
|
|
161521
|
+
HISTORIAN_RESPONSE_DUMP_DIR = join17(tmpdir2(), "magic-context-historian");
|
|
160653
161522
|
});
|
|
160654
161523
|
|
|
160655
161524
|
// src/hooks/magic-context/compartment-runner-state-xml.ts
|
|
@@ -161628,7 +162497,7 @@ var init_derive_budgets = __esm(() => {
|
|
|
161628
162497
|
});
|
|
161629
162498
|
|
|
161630
162499
|
// src/features/magic-context/compaction-marker.ts
|
|
161631
|
-
import { join as
|
|
162500
|
+
import { join as join18 } from "node:path";
|
|
161632
162501
|
function randomBase62(length) {
|
|
161633
162502
|
const chars = [];
|
|
161634
162503
|
for (let i = 0;i < length; i++) {
|
|
@@ -161648,7 +162517,7 @@ function generatePartId(timestampMs, counter = 0n) {
|
|
|
161648
162517
|
return generateId("prt", timestampMs, counter);
|
|
161649
162518
|
}
|
|
161650
162519
|
function getOpenCodeDbPath3() {
|
|
161651
|
-
return
|
|
162520
|
+
return join18(getDataDir(), "opencode", "opencode.db");
|
|
161652
162521
|
}
|
|
161653
162522
|
function isOpenCodeSchemaCompatible(db, dbPath) {
|
|
161654
162523
|
if (cachedSchemaCompatible?.path === dbPath) {
|
|
@@ -161785,7 +162654,7 @@ var init_compaction_marker = __esm(async () => {
|
|
|
161785
162654
|
});
|
|
161786
162655
|
|
|
161787
162656
|
// src/hooks/magic-context/compaction-marker-manager.ts
|
|
161788
|
-
import { join as
|
|
162657
|
+
import { join as join19 } from "node:path";
|
|
161789
162658
|
function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
|
|
161790
162659
|
const existing = getPersistedCompactionMarkerState(db, sessionId);
|
|
161791
162660
|
if (existing) {
|
|
@@ -161828,7 +162697,7 @@ function removeCompactionMarkerForSession(db, sessionId) {
|
|
|
161828
162697
|
}
|
|
161829
162698
|
}
|
|
161830
162699
|
function checkCompactionMarkerConsistency(db) {
|
|
161831
|
-
const opencodeDbPath =
|
|
162700
|
+
const opencodeDbPath = join19(getDataDir(), "opencode", "opencode.db");
|
|
161832
162701
|
let opencodeDb;
|
|
161833
162702
|
try {
|
|
161834
162703
|
opencodeDb = new Database(opencodeDbPath, { readonly: true });
|
|
@@ -162217,13 +163086,13 @@ var init_caveman = __esm(() => {
|
|
|
162217
163086
|
// src/hooks/magic-context/historian-state-file.ts
|
|
162218
163087
|
import { mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
162219
163088
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
162220
|
-
import { join as
|
|
163089
|
+
import { join as join20 } from "node:path";
|
|
162221
163090
|
function maybeWriteHistorianStateFile(sessionId, existingState) {
|
|
162222
163091
|
if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
|
|
162223
163092
|
return;
|
|
162224
163093
|
try {
|
|
162225
163094
|
mkdirSync5(HISTORIAN_STATE_DIR, { recursive: true });
|
|
162226
|
-
const path5 =
|
|
163095
|
+
const path5 = join20(HISTORIAN_STATE_DIR, `state-${sessionId}-${Date.now()}.xml`);
|
|
162227
163096
|
writeFileSync5(path5, existingState, "utf8");
|
|
162228
163097
|
return path5;
|
|
162229
163098
|
} catch {
|
|
@@ -162239,7 +163108,7 @@ function cleanupHistorianStateFile(path5) {
|
|
|
162239
163108
|
}
|
|
162240
163109
|
var HISTORIAN_STATE_INLINE_THRESHOLD = 30000, HISTORIAN_STATE_DIR;
|
|
162241
163110
|
var init_historian_state_file = __esm(() => {
|
|
162242
|
-
HISTORIAN_STATE_DIR =
|
|
163111
|
+
HISTORIAN_STATE_DIR = join20(tmpdir3(), "magic-context-historian");
|
|
162243
163112
|
});
|
|
162244
163113
|
|
|
162245
163114
|
// src/features/magic-context/memory/embedding-backfill.ts
|
|
@@ -162744,12 +163613,24 @@ var init_compartment_runner_compressor = __esm(async () => {
|
|
|
162744
163613
|
// src/hooks/magic-context/compartment-runner-drop-queue.ts
|
|
162745
163614
|
function queueDropsForCompartmentalizedMessages(db, sessionId, upToMessageIndex) {
|
|
162746
163615
|
const tags = getTagsBySession(db, sessionId);
|
|
162747
|
-
const
|
|
163616
|
+
const { messageFileKeys, toolObservations } = getRawSessionTagKeysThrough(sessionId, upToMessageIndex);
|
|
162748
163617
|
let dropsQueued = 0;
|
|
162749
163618
|
for (const tag of tags) {
|
|
162750
163619
|
if (tag.status !== "active")
|
|
162751
163620
|
continue;
|
|
162752
|
-
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)) {
|
|
162753
163634
|
queuePendingOp(db, sessionId, tag.tagNumber, "drop");
|
|
162754
163635
|
dropsQueued += 1;
|
|
162755
163636
|
}
|
|
@@ -163309,8 +164190,8 @@ var exports_tui_config = {};
|
|
|
163309
164190
|
__export(exports_tui_config, {
|
|
163310
164191
|
ensureTuiPluginEntry: () => ensureTuiPluginEntry
|
|
163311
164192
|
});
|
|
163312
|
-
import { existsSync as
|
|
163313
|
-
import { dirname as dirname6, join 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";
|
|
163314
164195
|
function isMagicContextEntry(entry) {
|
|
163315
164196
|
if (!entry)
|
|
163316
164197
|
return false;
|
|
@@ -163324,11 +164205,11 @@ function isMagicContextEntry(entry) {
|
|
|
163324
164205
|
}
|
|
163325
164206
|
function resolveTuiConfigPath() {
|
|
163326
164207
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
163327
|
-
const jsoncPath =
|
|
163328
|
-
const jsonPath =
|
|
163329
|
-
if (
|
|
164208
|
+
const jsoncPath = join23(configDir, "tui.jsonc");
|
|
164209
|
+
const jsonPath = join23(configDir, "tui.json");
|
|
164210
|
+
if (existsSync13(jsoncPath))
|
|
163330
164211
|
return jsoncPath;
|
|
163331
|
-
if (
|
|
164212
|
+
if (existsSync13(jsonPath))
|
|
163332
164213
|
return jsonPath;
|
|
163333
164214
|
return jsonPath;
|
|
163334
164215
|
}
|
|
@@ -163336,7 +164217,7 @@ function ensureTuiPluginEntry() {
|
|
|
163336
164217
|
try {
|
|
163337
164218
|
const configPath = resolveTuiConfigPath();
|
|
163338
164219
|
let config2 = {};
|
|
163339
|
-
if (
|
|
164220
|
+
if (existsSync13(configPath)) {
|
|
163340
164221
|
const raw = readFileSync9(configPath, "utf-8");
|
|
163341
164222
|
config2 = import_comment_json3.parse(raw) ?? {};
|
|
163342
164223
|
}
|
|
@@ -164133,42 +165014,8 @@ async function runSidekick(deps) {
|
|
|
164133
165014
|
}
|
|
164134
165015
|
}
|
|
164135
165016
|
|
|
164136
|
-
// src/
|
|
164137
|
-
|
|
164138
|
-
var measurements = new Map;
|
|
164139
|
-
function keyFor(providerID, modelID, agentName) {
|
|
164140
|
-
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
164141
|
-
return `${providerID}/${modelID}/${agent}`;
|
|
164142
|
-
}
|
|
164143
|
-
function recordToolDefinition(providerID, modelID, agentName, toolID, description, parameters) {
|
|
164144
|
-
if (!providerID || !modelID || !toolID)
|
|
164145
|
-
return;
|
|
164146
|
-
const key = keyFor(providerID, modelID, agentName);
|
|
164147
|
-
let paramsText = "";
|
|
164148
|
-
try {
|
|
164149
|
-
paramsText = parameters === undefined ? "" : JSON.stringify(parameters);
|
|
164150
|
-
} catch {
|
|
164151
|
-
paramsText = "";
|
|
164152
|
-
}
|
|
164153
|
-
const tokens = estimateTokens(description ?? "") + estimateTokens(paramsText);
|
|
164154
|
-
let inner = measurements.get(key);
|
|
164155
|
-
if (!inner) {
|
|
164156
|
-
inner = new Map;
|
|
164157
|
-
measurements.set(key, inner);
|
|
164158
|
-
}
|
|
164159
|
-
inner.set(toolID, tokens);
|
|
164160
|
-
}
|
|
164161
|
-
function getMeasuredToolDefinitionTokens(providerID, modelID, agentName) {
|
|
164162
|
-
if (!providerID || !modelID)
|
|
164163
|
-
return;
|
|
164164
|
-
const inner = measurements.get(keyFor(providerID, modelID, agentName));
|
|
164165
|
-
if (!inner || inner.size === 0)
|
|
164166
|
-
return;
|
|
164167
|
-
let total = 0;
|
|
164168
|
-
for (const tokens of inner.values())
|
|
164169
|
-
total += tokens;
|
|
164170
|
-
return total;
|
|
164171
|
-
}
|
|
165017
|
+
// src/index.ts
|
|
165018
|
+
init_tool_definition_tokens();
|
|
164172
165019
|
|
|
164173
165020
|
// src/hooks/auto-update-checker/index.ts
|
|
164174
165021
|
init_logger();
|
|
@@ -166859,14 +167706,46 @@ function createScheduler(config2) {
|
|
|
166859
167706
|
|
|
166860
167707
|
// src/features/magic-context/tagger.ts
|
|
166861
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
|
+
}
|
|
166862
167713
|
var GET_COUNTER_SQL = `SELECT counter FROM session_meta WHERE session_id = ?`;
|
|
166863
|
-
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
|
+
}
|
|
166864
167735
|
function isAssignmentRow(row) {
|
|
166865
167736
|
if (row === null || typeof row !== "object") {
|
|
166866
167737
|
return false;
|
|
166867
167738
|
}
|
|
166868
167739
|
const candidate = row;
|
|
166869
|
-
|
|
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;
|
|
166870
167749
|
}
|
|
166871
167750
|
var UPSERT_COUNTER_SQL = `
|
|
166872
167751
|
INSERT INTO session_meta (session_id, counter, harness)
|
|
@@ -166900,6 +167779,7 @@ var MAX_TAG_ALLOC_RETRIES = 5;
|
|
|
166900
167779
|
function createTagger() {
|
|
166901
167780
|
const counters = new Map;
|
|
166902
167781
|
const assignments = new Map;
|
|
167782
|
+
const loadSignatures = new Map;
|
|
166903
167783
|
function getSessionAssignments(sessionId) {
|
|
166904
167784
|
let map2 = assignments.get(sessionId);
|
|
166905
167785
|
if (!map2) {
|
|
@@ -166918,15 +167798,15 @@ function createTagger() {
|
|
|
166918
167798
|
counters.set(sessionId, next);
|
|
166919
167799
|
getUpsertCounterStatement(db).run(sessionId, next, getHarness());
|
|
166920
167800
|
}
|
|
166921
|
-
function
|
|
167801
|
+
function allocateTag(sessionId, messageId, type, byteSize2, db, reasoningByteSize, toolName, inputByteSize, toolOwnerMessageId, mapKey, dbExistingLookup) {
|
|
166922
167802
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
166923
|
-
const existing = sessionAssignments.get(
|
|
167803
|
+
const existing = sessionAssignments.get(mapKey);
|
|
166924
167804
|
if (existing !== undefined) {
|
|
166925
167805
|
return existing;
|
|
166926
167806
|
}
|
|
166927
|
-
const dbExisting =
|
|
167807
|
+
const dbExisting = dbExistingLookup();
|
|
166928
167808
|
if (dbExisting !== null) {
|
|
166929
|
-
sessionAssignments.set(
|
|
167809
|
+
sessionAssignments.set(mapKey, dbExisting);
|
|
166930
167810
|
syncCounterAtLeast(sessionId, db, dbExisting);
|
|
166931
167811
|
return dbExisting;
|
|
166932
167812
|
}
|
|
@@ -166936,16 +167816,16 @@ function createTagger() {
|
|
|
166936
167816
|
const next = Math.max(memCounter, dbMax) + 1;
|
|
166937
167817
|
try {
|
|
166938
167818
|
db.transaction(() => {
|
|
166939
|
-
insertTag(db, sessionId, messageId, type, byteSize2, next, reasoningByteSize, toolName, inputByteSize);
|
|
167819
|
+
insertTag(db, sessionId, messageId, type, byteSize2, next, reasoningByteSize, toolName, inputByteSize, toolOwnerMessageId);
|
|
166940
167820
|
getUpsertCounterStatement(db).run(sessionId, next, getHarness());
|
|
166941
167821
|
})();
|
|
166942
167822
|
} catch (error48) {
|
|
166943
167823
|
if (!isUniqueConstraintError(error48)) {
|
|
166944
167824
|
throw error48;
|
|
166945
167825
|
}
|
|
166946
|
-
const racedRow =
|
|
167826
|
+
const racedRow = dbExistingLookup();
|
|
166947
167827
|
if (racedRow !== null) {
|
|
166948
|
-
sessionAssignments.set(
|
|
167828
|
+
sessionAssignments.set(mapKey, racedRow);
|
|
166949
167829
|
syncCounterAtLeast(sessionId, db, racedRow);
|
|
166950
167830
|
return racedRow;
|
|
166951
167831
|
}
|
|
@@ -166954,51 +167834,124 @@ function createTagger() {
|
|
|
166954
167834
|
continue;
|
|
166955
167835
|
}
|
|
166956
167836
|
counters.set(sessionId, next);
|
|
166957
|
-
sessionAssignments.set(
|
|
167837
|
+
sessionAssignments.set(mapKey, next);
|
|
166958
167838
|
return next;
|
|
166959
167839
|
}
|
|
166960
|
-
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));
|
|
166961
167879
|
}
|
|
166962
|
-
function getTag(sessionId, messageId) {
|
|
167880
|
+
function getTag(sessionId, messageId, _type) {
|
|
166963
167881
|
return assignments.get(sessionId)?.get(messageId);
|
|
166964
167882
|
}
|
|
167883
|
+
function getToolTag(sessionId, callId, ownerMsgId) {
|
|
167884
|
+
return assignments.get(sessionId)?.get(makeToolCompositeKey(ownerMsgId, callId));
|
|
167885
|
+
}
|
|
166965
167886
|
function bindTag(sessionId, messageId, tagNumber) {
|
|
166966
167887
|
getSessionAssignments(sessionId).set(messageId, tagNumber);
|
|
166967
167888
|
}
|
|
167889
|
+
function bindToolTag(sessionId, callId, ownerMsgId, tagNumber) {
|
|
167890
|
+
getSessionAssignments(sessionId).set(makeToolCompositeKey(ownerMsgId, callId), tagNumber);
|
|
167891
|
+
}
|
|
166968
167892
|
function getAssignments(sessionId) {
|
|
166969
167893
|
return getSessionAssignments(sessionId);
|
|
166970
167894
|
}
|
|
166971
167895
|
function resetCounter(sessionId, db) {
|
|
166972
167896
|
counters.set(sessionId, 0);
|
|
166973
167897
|
assignments.delete(sessionId);
|
|
167898
|
+
loadSignatures.delete(sessionId);
|
|
166974
167899
|
getResetCounterStatement(db).run(sessionId, getHarness());
|
|
166975
167900
|
}
|
|
166976
167901
|
function getCounter(sessionId) {
|
|
166977
167902
|
return counters.get(sessionId) ?? 0;
|
|
166978
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
|
+
}
|
|
166979
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
|
+
}
|
|
166980
167918
|
const row = db.prepare(GET_COUNTER_SQL).get(sessionId);
|
|
166981
167919
|
const assignmentRows = db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId).filter(isAssignmentRow);
|
|
166982
167920
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
166983
167921
|
sessionAssignments.clear();
|
|
166984
167922
|
let maxTagNumber = 0;
|
|
166985
167923
|
for (const assignment of assignmentRows) {
|
|
166986
|
-
|
|
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
|
+
}
|
|
166987
167931
|
if (assignment.tag_number > maxTagNumber) {
|
|
166988
167932
|
maxTagNumber = assignment.tag_number;
|
|
166989
167933
|
}
|
|
166990
167934
|
}
|
|
166991
167935
|
const counter = Math.max(row?.counter ?? 0, maxTagNumber, counters.get(sessionId) ?? 0);
|
|
166992
167936
|
counters.set(sessionId, counter);
|
|
167937
|
+
loadSignatures.set(sessionId, {
|
|
167938
|
+
db,
|
|
167939
|
+
dataVersion: probe.dataVersion,
|
|
167940
|
+
totalChanges: probe.totalChanges
|
|
167941
|
+
});
|
|
166993
167942
|
}
|
|
166994
167943
|
function cleanup(sessionId) {
|
|
166995
167944
|
counters.delete(sessionId);
|
|
166996
167945
|
assignments.delete(sessionId);
|
|
167946
|
+
loadSignatures.delete(sessionId);
|
|
166997
167947
|
}
|
|
166998
167948
|
return {
|
|
166999
167949
|
assignTag,
|
|
167950
|
+
assignToolTag,
|
|
167000
167951
|
getTag,
|
|
167952
|
+
getToolTag,
|
|
167001
167953
|
bindTag,
|
|
167954
|
+
bindToolTag,
|
|
167002
167955
|
getAssignments,
|
|
167003
167956
|
resetCounter,
|
|
167004
167957
|
getCounter,
|
|
@@ -167642,24 +168595,149 @@ ${snap.error}`;
|
|
|
167642
168595
|
// src/hooks/magic-context/hook.ts
|
|
167643
168596
|
init_derive_budgets();
|
|
167644
168597
|
|
|
167645
|
-
// src/features/magic-context/
|
|
167646
|
-
|
|
167647
|
-
|
|
167648
|
-
|
|
167649
|
-
|
|
167650
|
-
|
|
167651
|
-
|
|
167652
|
-
|
|
167653
|
-
|
|
167654
|
-
|
|
167655
|
-
|
|
167656
|
-
|
|
167657
|
-
|
|
167658
|
-
|
|
167659
|
-
|
|
167660
|
-
|
|
167661
|
-
|
|
167662
|
-
|
|
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,
|
|
168738
|
+
/request entity too large/i,
|
|
168739
|
+
/context length is only \d+ tokens/i,
|
|
168740
|
+
/input length.*exceeds.*context length/i,
|
|
167663
168741
|
/prompt too long; exceeded (?:max )?context length/i,
|
|
167664
168742
|
/too large for model with \d+ maximum context length/i,
|
|
167665
168743
|
/model_context_window_exceeded/i,
|
|
@@ -167812,6 +168890,24 @@ function getMessageUpdatedAssistantInfo(properties) {
|
|
|
167812
168890
|
error: info.error !== undefined ? info.error : undefined
|
|
167813
168891
|
};
|
|
167814
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
|
+
}
|
|
167815
168911
|
function getSessionErrorInfo(properties) {
|
|
167816
168912
|
if (!isRecord(properties))
|
|
167817
168913
|
return null;
|
|
@@ -167835,6 +168931,7 @@ function getMessageRemovedInfo(properties) {
|
|
|
167835
168931
|
|
|
167836
168932
|
// src/hooks/magic-context/event-handler.ts
|
|
167837
168933
|
init_note_nudger();
|
|
168934
|
+
await init_read_session_chunk();
|
|
167838
168935
|
|
|
167839
168936
|
// src/hooks/magic-context/transform.ts
|
|
167840
168937
|
init_compartment_storage();
|
|
@@ -168110,23 +169207,11 @@ function readUint32BE(b, offset) {
|
|
|
168110
169207
|
// src/hooks/magic-context/transform.ts
|
|
168111
169208
|
init_note_nudger();
|
|
168112
169209
|
init_read_session_formatting();
|
|
169210
|
+
init_send_session_notification();
|
|
168113
169211
|
await __promiseAll([
|
|
168114
169212
|
init_inject_compartments(),
|
|
168115
169213
|
init_read_session_chunk()
|
|
168116
169214
|
]);
|
|
168117
|
-
|
|
168118
|
-
// src/hooks/magic-context/reasoning-capability.ts
|
|
168119
|
-
init_models_dev_cache();
|
|
168120
|
-
function modelRequiresInterleavedReasoning(model) {
|
|
168121
|
-
if (!model?.providerID || !model?.modelID) {
|
|
168122
|
-
return false;
|
|
168123
|
-
}
|
|
168124
|
-
const field = getModelsDevInterleavedField(model.providerID, model.modelID);
|
|
168125
|
-
return typeof field === "string" && field.length > 0;
|
|
168126
|
-
}
|
|
168127
|
-
|
|
168128
|
-
// src/hooks/magic-context/transform.ts
|
|
168129
|
-
init_send_session_notification();
|
|
168130
169215
|
// src/hooks/magic-context/sentinel.ts
|
|
168131
169216
|
function makeSentinel(originalPart) {
|
|
168132
169217
|
const sentinel = {
|
|
@@ -168303,9 +169388,7 @@ function stripDroppedPlaceholderMessages(messages) {
|
|
|
168303
169388
|
}
|
|
168304
169389
|
return { stripped, sentineledIds };
|
|
168305
169390
|
}
|
|
168306
|
-
function replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedWatermark
|
|
168307
|
-
if (skipTypedReasoningCleanup)
|
|
168308
|
-
return 0;
|
|
169391
|
+
function replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedWatermark) {
|
|
168309
169392
|
if (persistedWatermark <= 0)
|
|
168310
169393
|
return 0;
|
|
168311
169394
|
let cleared = 0;
|
|
@@ -168351,9 +169434,7 @@ function replayStrippedInlineThinking(messages, messageTagNumbers, persistedWate
|
|
|
168351
169434
|
}
|
|
168352
169435
|
return stripped;
|
|
168353
169436
|
}
|
|
168354
|
-
function clearOldReasoning(messages, reasoningByMessage, messageTagNumbers, clearReasoningAge
|
|
168355
|
-
if (skipTypedReasoningCleanup)
|
|
168356
|
-
return 0;
|
|
169437
|
+
function clearOldReasoning(messages, reasoningByMessage, messageTagNumbers, clearReasoningAge) {
|
|
168357
169438
|
const maxTag = findMaxTag(messageTagNumbers);
|
|
168358
169439
|
if (maxTag === 0)
|
|
168359
169440
|
return 0;
|
|
@@ -168388,9 +169469,7 @@ function findMaxTag(messageTagNumbers) {
|
|
|
168388
169469
|
return max;
|
|
168389
169470
|
}
|
|
168390
169471
|
var CLEARED_REASONING_TYPES = new Set(["thinking", "reasoning"]);
|
|
168391
|
-
function stripClearedReasoning(messages
|
|
168392
|
-
if (skipTypedReasoningCleanup)
|
|
168393
|
-
return 0;
|
|
169472
|
+
function stripClearedReasoning(messages) {
|
|
168394
169473
|
let stripped = 0;
|
|
168395
169474
|
for (const message of messages) {
|
|
168396
169475
|
if (message.info.role !== "assistant")
|
|
@@ -168909,377 +169988,192 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
|
|
|
168909
169988
|
// src/hooks/magic-context/strip-structural-noise.ts
|
|
168910
169989
|
var STRUCTURAL_PART_TYPES = new Set(["meta", "step-start", "step-finish", "reasoning"]);
|
|
168911
169990
|
function isStructuralNoisePart(part) {
|
|
168912
|
-
if (!isRecord(part) || typeof part.type !== "string") {
|
|
168913
|
-
return false;
|
|
168914
|
-
}
|
|
168915
|
-
if (!STRUCTURAL_PART_TYPES.has(part.type)) {
|
|
168916
|
-
return false;
|
|
168917
|
-
}
|
|
168918
|
-
if (part.type === "reasoning" && typeof part.text === "string" && part.text !== "[cleared]") {
|
|
168919
|
-
return false;
|
|
168920
|
-
}
|
|
168921
|
-
return true;
|
|
168922
|
-
}
|
|
168923
|
-
function stripStructuralNoise(messages) {
|
|
168924
|
-
let strippedParts = 0;
|
|
168925
|
-
for (const message of messages) {
|
|
168926
|
-
if (!Array.isArray(message.parts)) {
|
|
168927
|
-
continue;
|
|
168928
|
-
}
|
|
168929
|
-
for (let i = 0;i < message.parts.length; i++) {
|
|
168930
|
-
const part = message.parts[i];
|
|
168931
|
-
if (isSentinel(part))
|
|
168932
|
-
continue;
|
|
168933
|
-
if (!isStructuralNoisePart(part))
|
|
168934
|
-
continue;
|
|
168935
|
-
message.parts[i] = makeSentinel(part);
|
|
168936
|
-
strippedParts++;
|
|
168937
|
-
}
|
|
168938
|
-
}
|
|
168939
|
-
return strippedParts;
|
|
168940
|
-
}
|
|
168941
|
-
// src/hooks/magic-context/tag-messages.ts
|
|
168942
|
-
await init_storage();
|
|
168943
|
-
// src/hooks/magic-context/drop-stale-reduce-calls.ts
|
|
168944
|
-
var STALE_TOOL_NAMES = new Set(["ctx_reduce"]);
|
|
168945
|
-
function isReduceToolPart(part) {
|
|
168946
|
-
if (!isRecord(part))
|
|
168947
|
-
return false;
|
|
168948
|
-
if (part.type === "tool" && typeof part.tool === "string" && STALE_TOOL_NAMES.has(part.tool))
|
|
168949
|
-
return true;
|
|
168950
|
-
if (part.type === "tool-invocation" && typeof part.toolName === "string" && STALE_TOOL_NAMES.has(part.toolName))
|
|
168951
|
-
return true;
|
|
168952
|
-
if (part.type === "tool_use" && typeof part.name === "string" && STALE_TOOL_NAMES.has(part.name))
|
|
168953
|
-
return true;
|
|
168954
|
-
return false;
|
|
168955
|
-
}
|
|
168956
|
-
function hasAnyMeaningfulPart(parts) {
|
|
168957
|
-
for (const part of parts) {
|
|
168958
|
-
if (!isRecord(part))
|
|
168959
|
-
continue;
|
|
168960
|
-
if (part.type === "text" && typeof part.text === "string" && part.text.trim().length > 0)
|
|
168961
|
-
return true;
|
|
168962
|
-
if (part.type === "thinking" || part.type === "reasoning" || part.type === "redacted_thinking")
|
|
168963
|
-
continue;
|
|
168964
|
-
if (part.type === "meta" || part.type === "step-start" || part.type === "step-finish")
|
|
168965
|
-
continue;
|
|
168966
|
-
if (part.type !== "tool" || !isReduceToolPart(part))
|
|
168967
|
-
return true;
|
|
168968
|
-
}
|
|
168969
|
-
return false;
|
|
168970
|
-
}
|
|
168971
|
-
function dropStaleReduceCalls(messages, protectedCount = 0) {
|
|
168972
|
-
let didDrop = false;
|
|
168973
|
-
const protectedStart = messages.length - protectedCount;
|
|
168974
|
-
for (let i = 0;i < messages.length; i++) {
|
|
168975
|
-
if (i >= protectedStart)
|
|
168976
|
-
break;
|
|
168977
|
-
const message = messages[i];
|
|
168978
|
-
let touched = false;
|
|
168979
|
-
for (let j = 0;j < message.parts.length; j++) {
|
|
168980
|
-
const part = message.parts[j];
|
|
168981
|
-
if (isSentinel(part))
|
|
168982
|
-
continue;
|
|
168983
|
-
if (isReduceToolPart(part)) {
|
|
168984
|
-
message.parts[j] = makeSentinel(part);
|
|
168985
|
-
touched = true;
|
|
168986
|
-
}
|
|
168987
|
-
}
|
|
168988
|
-
if (touched) {
|
|
168989
|
-
didDrop = true;
|
|
168990
|
-
if (!hasAnyMeaningfulPart(message.parts)) {
|
|
168991
|
-
message.parts.length = 0;
|
|
168992
|
-
message.parts.push(makeSentinel(undefined));
|
|
168993
|
-
}
|
|
168994
|
-
}
|
|
168995
|
-
}
|
|
168996
|
-
return didDrop;
|
|
168997
|
-
}
|
|
168998
|
-
|
|
168999
|
-
// src/hooks/magic-context/tag-messages.ts
|
|
169000
|
-
init_tag_content_primitives();
|
|
169001
|
-
|
|
169002
|
-
// src/hooks/magic-context/tag-id-fallback.ts
|
|
169003
|
-
await init_storage();
|
|
169004
|
-
function parseScopedContentId(contentId) {
|
|
169005
|
-
const match = /^(.*):(p|file)(\d+)$/.exec(contentId);
|
|
169006
|
-
if (!match)
|
|
169007
|
-
return null;
|
|
169008
|
-
return {
|
|
169009
|
-
messageId: match[1],
|
|
169010
|
-
type: match[2] === "file" ? "file" : "message",
|
|
169011
|
-
partIndex: Number.parseInt(match[3], 10)
|
|
169012
|
-
};
|
|
169013
|
-
}
|
|
169014
|
-
function createScopedAssignments(assignments) {
|
|
169015
|
-
const scoped = new Map;
|
|
169016
|
-
for (const [contentId, tagNumber] of assignments) {
|
|
169017
|
-
const parsed = parseScopedContentId(contentId);
|
|
169018
|
-
if (!parsed)
|
|
169019
|
-
continue;
|
|
169020
|
-
const entry = scoped.get(parsed.messageId) ?? { message: [], file: [] };
|
|
169021
|
-
entry[parsed.type].push({ tagNumber, contentId, partIndex: parsed.partIndex });
|
|
169022
|
-
scoped.set(parsed.messageId, entry);
|
|
169023
|
-
}
|
|
169024
|
-
for (const entry of scoped.values()) {
|
|
169025
|
-
entry.message.sort((left, right) => left.partIndex - right.partIndex);
|
|
169026
|
-
entry.file.sort((left, right) => left.partIndex - right.partIndex);
|
|
169027
|
-
}
|
|
169028
|
-
return scoped;
|
|
169029
|
-
}
|
|
169030
|
-
function createExistingTagResolver(sessionId, tagger, db) {
|
|
169031
|
-
const assignments = tagger.getAssignments(sessionId);
|
|
169032
|
-
let cachedAssignmentSize = -1;
|
|
169033
|
-
let cachedScopedAssignments = null;
|
|
169034
|
-
const usedTagNumbers = new Set;
|
|
169035
|
-
function getScopedAssignments() {
|
|
169036
|
-
if (!cachedScopedAssignments || cachedAssignmentSize !== assignments.size) {
|
|
169037
|
-
cachedScopedAssignments = createScopedAssignments(assignments);
|
|
169038
|
-
cachedAssignmentSize = assignments.size;
|
|
169039
|
-
}
|
|
169040
|
-
return cachedScopedAssignments;
|
|
169041
|
-
}
|
|
169042
|
-
return {
|
|
169043
|
-
resolve(messageId, type, currentContentId, ordinal) {
|
|
169044
|
-
const exactTagId = assignments.get(currentContentId);
|
|
169045
|
-
if (exactTagId !== undefined) {
|
|
169046
|
-
usedTagNumbers.add(exactTagId);
|
|
169047
|
-
return exactTagId;
|
|
169048
|
-
}
|
|
169049
|
-
const fallback = getScopedAssignments().get(messageId)?.[type][ordinal];
|
|
169050
|
-
if (!fallback || usedTagNumbers.has(fallback.tagNumber)) {
|
|
169051
|
-
return;
|
|
169052
|
-
}
|
|
169053
|
-
updateTagMessageId(db, sessionId, fallback.tagNumber, currentContentId);
|
|
169054
|
-
tagger.bindTag(sessionId, currentContentId, fallback.tagNumber);
|
|
169055
|
-
usedTagNumbers.add(fallback.tagNumber);
|
|
169056
|
-
return fallback.tagNumber;
|
|
169057
|
-
}
|
|
169058
|
-
};
|
|
169059
|
-
}
|
|
169060
|
-
|
|
169061
|
-
// src/hooks/magic-context/tag-messages.ts
|
|
169062
|
-
init_tag_part_guards();
|
|
169063
|
-
|
|
169064
|
-
// src/hooks/magic-context/tool-drop-target.ts
|
|
169065
|
-
var DROP_PREFIX = "[dropped";
|
|
169066
|
-
var IGNORE_PART_TYPES = new Set([
|
|
169067
|
-
"thinking",
|
|
169068
|
-
"reasoning",
|
|
169069
|
-
"redacted_thinking",
|
|
169070
|
-
"meta",
|
|
169071
|
-
"step-start",
|
|
169072
|
-
"step-finish"
|
|
169073
|
-
]);
|
|
169074
|
-
function isToolCallId(value) {
|
|
169075
|
-
return typeof value === "string" && value.length > 0;
|
|
169076
|
-
}
|
|
169077
|
-
function getToolContent(part) {
|
|
169078
|
-
if (!isRecord(part))
|
|
169079
|
-
return;
|
|
169080
|
-
if (part.type === "tool" && isRecord(part.state)) {
|
|
169081
|
-
return typeof part.state.output === "string" ? part.state.output : undefined;
|
|
169082
|
-
}
|
|
169083
|
-
if (part.type === "tool_result") {
|
|
169084
|
-
return typeof part.content === "string" ? part.content : undefined;
|
|
169085
|
-
}
|
|
169086
|
-
return;
|
|
169087
|
-
}
|
|
169088
|
-
function setToolContent(part, content) {
|
|
169089
|
-
if (!isRecord(part))
|
|
169090
|
-
return;
|
|
169091
|
-
if (part.type === "tool" && isRecord(part.state)) {
|
|
169092
|
-
part.state.output = content;
|
|
169093
|
-
return;
|
|
169094
|
-
}
|
|
169095
|
-
if (part.type === "tool_result") {
|
|
169096
|
-
part.content = content;
|
|
169097
|
-
}
|
|
169098
|
-
}
|
|
169099
|
-
function truncateToolPart(part) {
|
|
169100
|
-
if (!isRecord(part))
|
|
169101
|
-
return;
|
|
169102
|
-
if (part.type === "tool" && isRecord(part.state)) {
|
|
169103
|
-
const state = part.state;
|
|
169104
|
-
state.output = "[truncated]";
|
|
169105
|
-
if (isRecord(state.input)) {
|
|
169106
|
-
const inputSize = estimateInputSize(state.input);
|
|
169107
|
-
if (inputSize > 500) {
|
|
169108
|
-
truncateInputValues(state.input);
|
|
169109
|
-
}
|
|
169110
|
-
}
|
|
169111
|
-
return;
|
|
169112
|
-
}
|
|
169113
|
-
if (part.type === "tool_result") {
|
|
169114
|
-
part.content = "[truncated]";
|
|
169115
|
-
return;
|
|
169116
|
-
}
|
|
169117
|
-
if (part.type === "tool-invocation" && isRecord(part.args)) {
|
|
169118
|
-
const inputSize = estimateInputSize(part.args);
|
|
169119
|
-
if (inputSize > 500) {
|
|
169120
|
-
truncateInputValues(part.args);
|
|
169121
|
-
}
|
|
169122
|
-
return;
|
|
169123
|
-
}
|
|
169124
|
-
if (part.type === "tool_use" && isRecord(part.input)) {
|
|
169125
|
-
const inputSize = estimateInputSize(part.input);
|
|
169126
|
-
if (inputSize > 500) {
|
|
169127
|
-
truncateInputValues(part.input);
|
|
169128
|
-
}
|
|
169129
|
-
}
|
|
169130
|
-
}
|
|
169131
|
-
function estimateInputSize(input) {
|
|
169132
|
-
try {
|
|
169133
|
-
return JSON.stringify(input).length;
|
|
169134
|
-
} catch {
|
|
169135
|
-
return 0;
|
|
169136
|
-
}
|
|
169137
|
-
}
|
|
169138
|
-
var TRUNCATION_SENTINEL = "...[truncated]";
|
|
169139
|
-
function safeSlice(str, maxLen) {
|
|
169140
|
-
if (str.length <= maxLen)
|
|
169141
|
-
return str;
|
|
169142
|
-
const lastCharCode = str.charCodeAt(maxLen - 1);
|
|
169143
|
-
if (lastCharCode >= 55296 && lastCharCode <= 56319) {
|
|
169144
|
-
return str.slice(0, maxLen - 1);
|
|
169145
|
-
}
|
|
169146
|
-
return str.slice(0, maxLen);
|
|
169147
|
-
}
|
|
169148
|
-
function truncateInputValues(input) {
|
|
169149
|
-
for (const key of Object.keys(input)) {
|
|
169150
|
-
const value = input[key];
|
|
169151
|
-
if (typeof value === "string") {
|
|
169152
|
-
if (value.endsWith(TRUNCATION_SENTINEL) || value === "[object]" || /^\[\d+ items\]$/.test(value))
|
|
169153
|
-
continue;
|
|
169154
|
-
input[key] = value.length > 5 ? `${safeSlice(value, 5)}${TRUNCATION_SENTINEL}` : value;
|
|
169155
|
-
} else if (Array.isArray(value)) {
|
|
169156
|
-
input[key] = `[${value.length} items]`;
|
|
169157
|
-
} else if (value !== null && typeof value === "object") {
|
|
169158
|
-
input[key] = "[object]";
|
|
169159
|
-
}
|
|
169160
|
-
}
|
|
169161
|
-
}
|
|
169162
|
-
function hasMeaningfulPart(part) {
|
|
169163
|
-
if (!isRecord(part))
|
|
169164
|
-
return false;
|
|
169165
|
-
const type = part.type;
|
|
169166
|
-
if (type === "text") {
|
|
169167
|
-
return typeof part.text === "string" && part.text.trim().length > 0;
|
|
169168
|
-
}
|
|
169169
|
-
if (typeof type !== "string")
|
|
169170
|
-
return false;
|
|
169171
|
-
if (IGNORE_PART_TYPES.has(type))
|
|
169172
|
-
return false;
|
|
169173
|
-
return true;
|
|
169174
|
-
}
|
|
169175
|
-
function clearThinkingParts(thinkingParts) {
|
|
169176
|
-
for (const part of thinkingParts) {
|
|
169177
|
-
if (part.thinking !== undefined)
|
|
169178
|
-
part.thinking = "[cleared]";
|
|
169179
|
-
if (part.text !== undefined)
|
|
169180
|
-
part.text = "[cleared]";
|
|
169181
|
-
}
|
|
169182
|
-
}
|
|
169183
|
-
function extractToolCallObservation(part) {
|
|
169184
|
-
if (!isRecord(part))
|
|
169185
|
-
return null;
|
|
169186
|
-
if (part.type === "tool" && isToolCallId(part.callID)) {
|
|
169187
|
-
return { callId: part.callID, kind: "result" };
|
|
169991
|
+
if (!isRecord(part) || typeof part.type !== "string") {
|
|
169992
|
+
return false;
|
|
169188
169993
|
}
|
|
169189
|
-
if (
|
|
169190
|
-
return
|
|
169994
|
+
if (!STRUCTURAL_PART_TYPES.has(part.type)) {
|
|
169995
|
+
return false;
|
|
169191
169996
|
}
|
|
169192
|
-
if (part.type === "
|
|
169193
|
-
return
|
|
169997
|
+
if (part.type === "reasoning" && typeof part.text === "string" && part.text !== "[cleared]") {
|
|
169998
|
+
return false;
|
|
169194
169999
|
}
|
|
169195
|
-
|
|
169196
|
-
|
|
170000
|
+
return true;
|
|
170001
|
+
}
|
|
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
|
+
}
|
|
169197
170017
|
}
|
|
169198
|
-
return
|
|
170018
|
+
return strippedParts;
|
|
169199
170019
|
}
|
|
169200
|
-
|
|
169201
|
-
|
|
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;
|
|
169202
170035
|
}
|
|
169203
|
-
|
|
169204
|
-
|
|
169205
|
-
|
|
169206
|
-
|
|
169207
|
-
|
|
169208
|
-
|
|
169209
|
-
|
|
169210
|
-
|
|
169211
|
-
|
|
169212
|
-
|
|
169213
|
-
|
|
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;
|
|
169214
170048
|
}
|
|
169215
|
-
|
|
169216
|
-
|
|
169217
|
-
|
|
169218
|
-
|
|
169219
|
-
|
|
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
|
+
}
|
|
169220
170067
|
}
|
|
169221
|
-
|
|
169222
|
-
|
|
169223
|
-
|
|
170068
|
+
if (touched) {
|
|
170069
|
+
didDrop = true;
|
|
170070
|
+
if (!hasAnyMeaningfulPart(message.parts)) {
|
|
170071
|
+
message.parts.length = 0;
|
|
170072
|
+
message.parts.push(makeSentinel(undefined));
|
|
169224
170073
|
}
|
|
169225
170074
|
}
|
|
169226
|
-
this.partsToRemove.clear();
|
|
169227
|
-
this.affectedMessages.clear();
|
|
169228
170075
|
}
|
|
170076
|
+
return didDrop;
|
|
169229
170077
|
}
|
|
169230
|
-
|
|
169231
|
-
|
|
169232
|
-
|
|
169233
|
-
|
|
169234
|
-
|
|
169235
|
-
|
|
169236
|
-
|
|
169237
|
-
|
|
169238
|
-
|
|
169239
|
-
|
|
169240
|
-
|
|
169241
|
-
|
|
169242
|
-
|
|
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)
|
|
169243
170093
|
};
|
|
169244
|
-
|
|
169245
|
-
|
|
169246
|
-
|
|
169247
|
-
|
|
169248
|
-
|
|
169249
|
-
|
|
169250
|
-
|
|
169251
|
-
|
|
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;
|
|
169252
170120
|
}
|
|
169253
|
-
|
|
169254
|
-
|
|
169255
|
-
};
|
|
170121
|
+
return cachedScopedAssignments;
|
|
170122
|
+
}
|
|
169256
170123
|
return {
|
|
169257
|
-
|
|
169258
|
-
|
|
169259
|
-
|
|
169260
|
-
|
|
170124
|
+
resolve(messageId, type, currentContentId, ordinal) {
|
|
170125
|
+
const exactTagId = assignments.get(currentContentId);
|
|
170126
|
+
if (exactTagId !== undefined) {
|
|
170127
|
+
usedTagNumbers.add(exactTagId);
|
|
170128
|
+
return exactTagId;
|
|
169261
170129
|
}
|
|
169262
|
-
const
|
|
169263
|
-
if (!
|
|
169264
|
-
return
|
|
169265
|
-
let changed = false;
|
|
169266
|
-
for (const occurrence of entry.occurrences) {
|
|
169267
|
-
if (occurrence.kind !== "result")
|
|
169268
|
-
continue;
|
|
169269
|
-
const prevContent = getToolContent(occurrence.part);
|
|
169270
|
-
if (prevContent !== content) {
|
|
169271
|
-
setToolContent(occurrence.part, content);
|
|
169272
|
-
changed = true;
|
|
169273
|
-
}
|
|
170130
|
+
const fallback = getScopedAssignments().get(messageId)?.[type][ordinal];
|
|
170131
|
+
if (!fallback || usedTagNumbers.has(fallback.tagNumber)) {
|
|
170132
|
+
return;
|
|
169274
170133
|
}
|
|
169275
|
-
|
|
169276
|
-
|
|
169277
|
-
|
|
169278
|
-
|
|
170134
|
+
updateTagMessageId(db, sessionId, fallback.tagNumber, currentContentId);
|
|
170135
|
+
tagger.bindTag(sessionId, currentContentId, fallback.tagNumber);
|
|
170136
|
+
usedTagNumbers.add(fallback.tagNumber);
|
|
170137
|
+
return fallback.tagNumber;
|
|
170138
|
+
}
|
|
169279
170139
|
};
|
|
169280
170140
|
}
|
|
169281
170141
|
|
|
169282
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
|
+
}
|
|
169283
170177
|
function collectRelevantSourceTagIds(messages, assignments) {
|
|
169284
170178
|
const currentMessageIds = new Set(messages.flatMap((message) => typeof message.info.id === "string" ? [message.info.id] : []));
|
|
169285
170179
|
const relevantTagIds = new Set;
|
|
@@ -169330,6 +170224,8 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169330
170224
|
const toolTagByCallId = new Map;
|
|
169331
170225
|
const toolThinkingByCallId = new Map;
|
|
169332
170226
|
const toolCallIndex = new Map;
|
|
170227
|
+
const unpairedInvocations = new Map;
|
|
170228
|
+
const ownerByPartKey = new Map;
|
|
169333
170229
|
const batch = new ToolMutationBatch(messages);
|
|
169334
170230
|
const assignments = tagger.getAssignments(sessionId);
|
|
169335
170231
|
const resolver = createExistingTagResolver(sessionId, tagger, db);
|
|
@@ -169360,22 +170256,37 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169360
170256
|
}
|
|
169361
170257
|
const toolObservation = extractToolCallObservation(part);
|
|
169362
170258
|
if (toolObservation) {
|
|
169363
|
-
const
|
|
170259
|
+
const ownerMsgId = deriveToolOwnerMessageId(sessionId, db, message, toolObservation, unpairedInvocations);
|
|
170260
|
+
const compositeKey = makeToolCompositeKey(ownerMsgId, toolObservation.callId);
|
|
170261
|
+
const entry = toolCallIndex.get(compositeKey) ?? {
|
|
169364
170262
|
occurrences: [],
|
|
169365
170263
|
hasResult: false
|
|
169366
170264
|
};
|
|
169367
170265
|
entry.occurrences.push({ message, part, kind: toolObservation.kind });
|
|
169368
170266
|
if (toolObservation.kind === "result")
|
|
169369
170267
|
entry.hasResult = true;
|
|
169370
|
-
toolCallIndex.set(
|
|
169371
|
-
|
|
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
|
+
}
|
|
169372
170282
|
if (existingTagId !== undefined) {
|
|
169373
|
-
toolTagByCallId.set(
|
|
170283
|
+
toolTagByCallId.set(compositeKey, existingTagId);
|
|
169374
170284
|
messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, existingTagId));
|
|
169375
|
-
if (message.info.role === "tool" && precedingThinkingParts.length > 0 && !toolThinkingByCallId.has(
|
|
169376
|
-
toolThinkingByCallId.set(
|
|
170285
|
+
if (message.info.role === "tool" && precedingThinkingParts.length > 0 && !toolThinkingByCallId.has(compositeKey)) {
|
|
170286
|
+
toolThinkingByCallId.set(compositeKey, precedingThinkingParts);
|
|
169377
170287
|
}
|
|
169378
170288
|
}
|
|
170289
|
+
ownerByPartKey.set(part, { ownerMsgId, callId: toolObservation.callId });
|
|
169379
170290
|
}
|
|
169380
170291
|
if (messageId && isTextPart(part)) {
|
|
169381
170292
|
const textPart = part;
|
|
@@ -169421,14 +170332,17 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169421
170332
|
const thinkingParts = precedingThinkingParts;
|
|
169422
170333
|
const reasoningBytes = getReasoningByteSize(thinkingParts);
|
|
169423
170334
|
const { toolName, inputByteSize } = extractToolTagMetadata(toolPart);
|
|
169424
|
-
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);
|
|
169425
170339
|
messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, tagId));
|
|
169426
170340
|
if (!skipPrefixInjection) {
|
|
169427
170341
|
toolPart.state.output = prependTag(tagId, toolPart.state.output);
|
|
169428
170342
|
}
|
|
169429
|
-
toolTagByCallId.set(
|
|
169430
|
-
if (thinkingParts.length > 0 && !toolThinkingByCallId.has(
|
|
169431
|
-
toolThinkingByCallId.set(
|
|
170343
|
+
toolTagByCallId.set(compositeKey, tagId);
|
|
170344
|
+
if (thinkingParts.length > 0 && !toolThinkingByCallId.has(compositeKey)) {
|
|
170345
|
+
toolThinkingByCallId.set(compositeKey, thinkingParts);
|
|
169432
170346
|
}
|
|
169433
170347
|
}
|
|
169434
170348
|
if (messageId && isFilePart(part)) {
|
|
@@ -169476,9 +170390,9 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
169476
170390
|
}
|
|
169477
170391
|
}
|
|
169478
170392
|
}
|
|
169479
|
-
for (const [
|
|
169480
|
-
const thinkingParts = toolThinkingByCallId.get(
|
|
169481
|
-
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));
|
|
169482
170396
|
}
|
|
169483
170397
|
const hasRecentReduceCall = lastReduceMessageIndex >= 0 && messages.length - lastReduceMessageIndex <= RECENT_REDUCE_LOOKBACK;
|
|
169484
170398
|
return {
|
|
@@ -169639,11 +170553,9 @@ function applyContextNudge(messages, nudge, nudgePlacements, sessionId) {
|
|
|
169639
170553
|
|
|
169640
170554
|
// src/features/magic-context/search.ts
|
|
169641
170555
|
init_logger();
|
|
169642
|
-
await init_read_session_chunk();
|
|
169643
170556
|
init_memory();
|
|
169644
170557
|
init_embedding();
|
|
169645
170558
|
init_storage_memory_fts();
|
|
169646
|
-
await init_message_index();
|
|
169647
170559
|
var DEFAULT_UNIFIED_SEARCH_LIMIT = 10;
|
|
169648
170560
|
var FTS_SEMANTIC_CANDIDATE_LIMIT = 50;
|
|
169649
170561
|
var SEMANTIC_WEIGHT = 0.7;
|
|
@@ -169693,11 +170605,7 @@ function getMessageOrdinal(value) {
|
|
|
169693
170605
|
}
|
|
169694
170606
|
async function getSemanticScores(args) {
|
|
169695
170607
|
const semanticScores = new Map;
|
|
169696
|
-
if (!args.
|
|
169697
|
-
return semanticScores;
|
|
169698
|
-
}
|
|
169699
|
-
const queryEmbedding = await args.embedQuery(args.query, args.signal);
|
|
169700
|
-
if (!queryEmbedding) {
|
|
170608
|
+
if (!args.queryEmbedding || args.memories.length === 0) {
|
|
169701
170609
|
return semanticScores;
|
|
169702
170610
|
}
|
|
169703
170611
|
const cachedEmbeddings = getProjectEmbeddings(args.db, args.projectPath);
|
|
@@ -169711,7 +170619,7 @@ async function getSemanticScores(args) {
|
|
|
169711
170619
|
if (!memoryEmbedding) {
|
|
169712
170620
|
continue;
|
|
169713
170621
|
}
|
|
169714
|
-
semanticScores.set(memory.id, normalizeCosineScore(cosineSimilarity(queryEmbedding, memoryEmbedding)));
|
|
170622
|
+
semanticScores.set(memory.id, normalizeCosineScore(cosineSimilarity(args.queryEmbedding, memoryEmbedding)));
|
|
169715
170623
|
}
|
|
169716
170624
|
return semanticScores;
|
|
169717
170625
|
}
|
|
@@ -169807,12 +170715,8 @@ async function searchMemories(args) {
|
|
|
169807
170715
|
const semanticScores = await getSemanticScores({
|
|
169808
170716
|
db: args.db,
|
|
169809
170717
|
projectPath: args.projectPath,
|
|
169810
|
-
query: args.query,
|
|
169811
170718
|
memories: semanticCandidates,
|
|
169812
|
-
|
|
169813
|
-
embedQuery: args.embedQuery,
|
|
169814
|
-
isEmbeddingRuntimeEnabled: args.isEmbeddingRuntimeEnabled,
|
|
169815
|
-
signal: args.signal
|
|
170719
|
+
queryEmbedding: args.queryEmbedding
|
|
169816
170720
|
});
|
|
169817
170721
|
return mergeMemoryResults({
|
|
169818
170722
|
memories,
|
|
@@ -169828,7 +170732,6 @@ function linearDecayScore(rank, total) {
|
|
|
169828
170732
|
return Math.max(0, 1 - rank / total);
|
|
169829
170733
|
}
|
|
169830
170734
|
function searchMessages(args) {
|
|
169831
|
-
ensureMessagesIndexed(args.db, args.sessionId, args.readMessages);
|
|
169832
170735
|
const sanitizedQuery = sanitizeFtsQuery(args.query.trim());
|
|
169833
170736
|
if (sanitizedQuery.length === 0) {
|
|
169834
170737
|
return [];
|
|
@@ -169899,20 +170802,12 @@ function toGitCommitResult(hit) {
|
|
|
169899
170802
|
matchType: hit.matchType
|
|
169900
170803
|
};
|
|
169901
170804
|
}
|
|
169902
|
-
|
|
170805
|
+
function searchGitCommits(args) {
|
|
169903
170806
|
if (args.limit <= 0)
|
|
169904
170807
|
return [];
|
|
169905
|
-
let queryEmbedding = null;
|
|
169906
|
-
if (args.embeddingEnabled && args.isEmbeddingRuntimeEnabled()) {
|
|
169907
|
-
try {
|
|
169908
|
-
queryEmbedding = await args.embedQuery(args.query, args.signal);
|
|
169909
|
-
} catch (error48) {
|
|
169910
|
-
log(`[search] git commit query embedding failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
169911
|
-
}
|
|
169912
|
-
}
|
|
169913
170808
|
const hits = searchGitCommitsSync(args.db, args.projectPath, args.query, {
|
|
169914
170809
|
limit: args.limit,
|
|
169915
|
-
queryEmbedding
|
|
170810
|
+
queryEmbedding: args.queryEmbedding
|
|
169916
170811
|
});
|
|
169917
170812
|
return hits.map(toGitCommitResult);
|
|
169918
170813
|
}
|
|
@@ -169943,37 +170838,37 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
169943
170838
|
const runMemory = activeSources.has("memory") && (options.memoryEnabled ?? true);
|
|
169944
170839
|
const runMessages = activeSources.has("message");
|
|
169945
170840
|
const runGitCommits = activeSources.has("git_commit") && gitCommitsEnabled;
|
|
169946
|
-
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([
|
|
169947
170856
|
runMemory ? searchMemories({
|
|
169948
170857
|
db,
|
|
169949
170858
|
projectPath,
|
|
169950
170859
|
query: trimmedQuery,
|
|
169951
170860
|
limit: tierLimit,
|
|
169952
170861
|
memoryEnabled: true,
|
|
169953
|
-
|
|
169954
|
-
|
|
169955
|
-
isEmbeddingRuntimeEnabled,
|
|
169956
|
-
visibleMemoryIds: options.visibleMemoryIds,
|
|
169957
|
-
signal: options.signal
|
|
170862
|
+
queryEmbedding,
|
|
170863
|
+
visibleMemoryIds: options.visibleMemoryIds
|
|
169958
170864
|
}) : Promise.resolve([]),
|
|
169959
|
-
|
|
169960
|
-
db,
|
|
169961
|
-
sessionId,
|
|
169962
|
-
query: trimmedQuery,
|
|
169963
|
-
limit: tierLimit,
|
|
169964
|
-
readMessages: options.readMessages ?? readRawSessionMessages,
|
|
169965
|
-
maxOrdinal: options.maxMessageOrdinal
|
|
169966
|
-
})) : Promise.resolve([]),
|
|
169967
|
-
runGitCommits ? searchGitCommitsAsync({
|
|
170865
|
+
runGitCommits ? Promise.resolve(searchGitCommits({
|
|
169968
170866
|
db,
|
|
169969
170867
|
projectPath,
|
|
169970
170868
|
query: trimmedQuery,
|
|
169971
170869
|
limit: tierLimit,
|
|
169972
|
-
|
|
169973
|
-
|
|
169974
|
-
isEmbeddingRuntimeEnabled,
|
|
169975
|
-
signal: options.signal
|
|
169976
|
-
}) : Promise.resolve([])
|
|
170870
|
+
queryEmbedding
|
|
170871
|
+
})) : Promise.resolve([])
|
|
169977
170872
|
]);
|
|
169978
170873
|
const results = [...memoryResults, ...messageResults, ...gitCommitResults].sort(compareUnifiedResults).slice(0, limit);
|
|
169979
170874
|
const countRetrievals = options.countRetrievals ?? true;
|
|
@@ -170111,8 +171006,31 @@ function collectUserPromptParts(message) {
|
|
|
170111
171006
|
function hasStackedAugmentation(rawText) {
|
|
170112
171007
|
return rawText.includes("<sidekick-augmentation>") || rawText.includes("<ctx-search-hint>") || rawText.includes("<ctx-search-auto>");
|
|
170113
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
|
+
}
|
|
170114
171032
|
function extractUserPromptText(message) {
|
|
170115
|
-
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, `
|
|
170116
171034
|
`).replace(/\n{3,}/g, `
|
|
170117
171035
|
|
|
170118
171036
|
`).trim();
|
|
@@ -170268,8 +171186,8 @@ var DEDUP_SAFE_TOOLS = new Set([
|
|
|
170268
171186
|
"mcp_lsp_prepare_rename"
|
|
170269
171187
|
]);
|
|
170270
171188
|
function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config2, preloadedTags) {
|
|
170271
|
-
const tags = preloadedTags ??
|
|
170272
|
-
const maxTag =
|
|
171189
|
+
const tags = preloadedTags ?? getActiveTagsBySession(db, sessionId);
|
|
171190
|
+
const maxTag = getMaxTagNumberBySession(db, sessionId);
|
|
170273
171191
|
const toolAgeCutoff = maxTag - config2.autoDropToolAge;
|
|
170274
171192
|
const protectedCutoff = maxTag - config2.protectedTags;
|
|
170275
171193
|
let droppedTools = 0;
|
|
@@ -170334,15 +171252,16 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
170334
171252
|
const allMessages = Array.from(messageTagNumbers.keys());
|
|
170335
171253
|
const toolFingerprints = buildToolFingerprints(allMessages);
|
|
170336
171254
|
if (toolFingerprints.size > 0) {
|
|
170337
|
-
const
|
|
171255
|
+
const tagsByCompositeKey = new Map;
|
|
170338
171256
|
for (const tag of tags) {
|
|
170339
171257
|
if (tag.type === "tool" && tag.status === "active" && tag.messageId) {
|
|
170340
|
-
|
|
171258
|
+
const key = tag.toolOwnerMessageId ? `${tag.toolOwnerMessageId}\x00${tag.messageId}` : tag.messageId;
|
|
171259
|
+
tagsByCompositeKey.set(key, tag);
|
|
170341
171260
|
}
|
|
170342
171261
|
}
|
|
170343
171262
|
const fingerprintGroups = new Map;
|
|
170344
|
-
for (const [
|
|
170345
|
-
const tag =
|
|
171263
|
+
for (const [compositeKey, fingerprint] of toolFingerprints) {
|
|
171264
|
+
const tag = tagsByCompositeKey.get(compositeKey);
|
|
170346
171265
|
if (!tag || tag.tagNumber > protectedCutoff)
|
|
170347
171266
|
continue;
|
|
170348
171267
|
const group = fingerprintGroups.get(fingerprint) ?? [];
|
|
@@ -170399,6 +171318,9 @@ function buildToolFingerprints(messages) {
|
|
|
170399
171318
|
for (const message of messages) {
|
|
170400
171319
|
if (message.info.role !== "assistant")
|
|
170401
171320
|
continue;
|
|
171321
|
+
const ownerMsgId = typeof message.info.id === "string" ? message.info.id : null;
|
|
171322
|
+
if (!ownerMsgId)
|
|
171323
|
+
continue;
|
|
170402
171324
|
for (const part of message.parts) {
|
|
170403
171325
|
const record2 = part;
|
|
170404
171326
|
const info = extractToolInfo(record2);
|
|
@@ -170408,8 +171330,9 @@ function buildToolFingerprints(messages) {
|
|
|
170408
171330
|
if (!callId)
|
|
170409
171331
|
continue;
|
|
170410
171332
|
try {
|
|
170411
|
-
const fingerprint = `${info.toolName}:${JSON.stringify(info.args)}`;
|
|
170412
|
-
|
|
171333
|
+
const fingerprint = `${ownerMsgId}:${info.toolName}:${JSON.stringify(info.args)}`;
|
|
171334
|
+
const compositeKey = `${ownerMsgId}\x00${callId}`;
|
|
171335
|
+
fingerprints.set(compositeKey, fingerprint);
|
|
170413
171336
|
} catch {}
|
|
170414
171337
|
}
|
|
170415
171338
|
}
|
|
@@ -170515,7 +171438,7 @@ async function runPostTransformPhase(args) {
|
|
|
170515
171438
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
170516
171439
|
const pendingCountBefore = pendingOps.length;
|
|
170517
171440
|
const tApply = performance.now();
|
|
170518
|
-
didMutateFromPendingOperations = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags,
|
|
171441
|
+
didMutateFromPendingOperations = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTags, undefined, pendingOps);
|
|
170519
171442
|
const pendingCountAfter = getPendingOps(args.db, args.sessionId).length;
|
|
170520
171443
|
if (pendingCountBefore > 0 && pendingCountAfter === 0) {
|
|
170521
171444
|
clearPersistedStickyTurnReminder(args.db, args.sessionId);
|
|
@@ -170546,8 +171469,8 @@ async function runPostTransformPhase(args) {
|
|
|
170546
171469
|
logTransformTiming(args.sessionId, "watermarkCleanup", t6);
|
|
170547
171470
|
}
|
|
170548
171471
|
const t7 = performance.now();
|
|
170549
|
-
const clearedReasoning = clearOldReasoning(args.messages, args.reasoningByMessage, args.messageTagNumbers, args.clearReasoningAge
|
|
170550
|
-
stripClearedReasoning(args.messages
|
|
171472
|
+
const clearedReasoning = clearOldReasoning(args.messages, args.reasoningByMessage, args.messageTagNumbers, args.clearReasoningAge);
|
|
171473
|
+
stripClearedReasoning(args.messages);
|
|
170551
171474
|
const strippedInline = stripInlineThinking(args.messages, args.messageTagNumbers, args.clearReasoningAge);
|
|
170552
171475
|
if (clearedReasoning > 0 || strippedInline > 0) {
|
|
170553
171476
|
let maxTag = 0;
|
|
@@ -170817,6 +171740,9 @@ function createTransform(deps) {
|
|
|
170817
171740
|
const resolvedSessionId = sessionId;
|
|
170818
171741
|
logTransformTiming(sessionId, "findSessionId", startTime, `messages=${messages.length}`);
|
|
170819
171742
|
const db = deps.db;
|
|
171743
|
+
if (deps.client !== undefined) {
|
|
171744
|
+
scheduleReconciliation(db, sessionId, readRawSessionMessages);
|
|
171745
|
+
}
|
|
170820
171746
|
const tUserMsg = performance.now();
|
|
170821
171747
|
const currentTurnId = findLastUserMessageId(messages);
|
|
170822
171748
|
logTransformTiming(sessionId, "findLastUserMessageId", tUserMsg);
|
|
@@ -171038,13 +171964,17 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
171038
171964
|
}
|
|
171039
171965
|
}
|
|
171040
171966
|
const t1 = performance.now();
|
|
171041
|
-
const
|
|
171042
|
-
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}`);
|
|
171043
171973
|
let didMutateFromFlushedStatuses = false;
|
|
171044
171974
|
if (taggingSucceeded) {
|
|
171045
171975
|
try {
|
|
171046
171976
|
const t2 = performance.now();
|
|
171047
|
-
didMutateFromFlushedStatuses = applyFlushedStatuses(sessionId, db, targets,
|
|
171977
|
+
didMutateFromFlushedStatuses = applyFlushedStatuses(sessionId, db, targets, targetsSliceTags);
|
|
171048
171978
|
logTransformTiming(sessionId, "applyFlushedStatuses", t2);
|
|
171049
171979
|
batch?.finalize();
|
|
171050
171980
|
logTransformTiming(sessionId, "batchFinalize:flushed", t2);
|
|
@@ -171060,12 +171990,10 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
171060
171990
|
const t3 = performance.now();
|
|
171061
171991
|
const strippedStructuralNoise = stripStructuralNoise(messages);
|
|
171062
171992
|
logTransformTiming(sessionId, "stripStructuralNoise", t3, `strippedParts=${strippedStructuralNoise}`);
|
|
171063
|
-
const currentSessionModel = deps.liveModelBySession?.get(sessionId) ?? findLastAssistantModel(messages) ?? undefined;
|
|
171064
|
-
const skipTypedReasoningCleanup = modelRequiresInterleavedReasoning(currentSessionModel);
|
|
171065
171993
|
const persistedReasoningWatermark = sessionMeta?.clearedReasoningThroughTag ?? 0;
|
|
171066
171994
|
if (persistedReasoningWatermark > 0) {
|
|
171067
171995
|
const tReplay = performance.now();
|
|
171068
|
-
const replayed = replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark
|
|
171996
|
+
const replayed = replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark);
|
|
171069
171997
|
const replayedInline = replayStrippedInlineThinking(messages, messageTagNumbers, persistedReasoningWatermark);
|
|
171070
171998
|
if (replayed > 0 || replayedInline > 0) {
|
|
171071
171999
|
sessionLog(sessionId, `reasoning replay: cleared=${replayed} inlineStripped=${replayedInline} (watermark=${persistedReasoningWatermark})`);
|
|
@@ -171074,27 +172002,22 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
171074
172002
|
}
|
|
171075
172003
|
if (!deps.ctxReduceEnabled && !reducedMode && deps.cavemanTextCompression?.enabled) {
|
|
171076
172004
|
const tCavemanReplay = performance.now();
|
|
171077
|
-
const replayedCaveman = replayCavemanCompression(sessionId, db, targets,
|
|
172005
|
+
const replayedCaveman = replayCavemanCompression(sessionId, db, targets, targetsSliceTags);
|
|
171078
172006
|
if (replayedCaveman > 0) {
|
|
171079
172007
|
sessionLog(sessionId, `caveman replay: re-applied ${replayedCaveman} text tags`);
|
|
171080
172008
|
}
|
|
171081
172009
|
logTransformTiming(sessionId, "replayCavemanCompression", tCavemanReplay);
|
|
171082
172010
|
}
|
|
171083
172011
|
const t4 = performance.now();
|
|
171084
|
-
const strippedClearedReasoning = stripClearedReasoning(messages
|
|
172012
|
+
const strippedClearedReasoning = stripClearedReasoning(messages);
|
|
171085
172013
|
logTransformTiming(sessionId, "stripClearedReasoning", t4, `strippedParts=${strippedClearedReasoning}`);
|
|
171086
172014
|
const tMergeStrip = performance.now();
|
|
171087
|
-
const strippedMergedReasoning =
|
|
172015
|
+
const strippedMergedReasoning = stripReasoningFromMergedAssistants(messages);
|
|
171088
172016
|
if (strippedMergedReasoning > 0) {
|
|
171089
172017
|
sessionLog(sessionId, `stripped ${strippedMergedReasoning} reasoning parts from merged assistants (anthropic groupIntoBlocks workaround)`);
|
|
171090
172018
|
}
|
|
171091
172019
|
logTransformTiming(sessionId, "stripReasoningFromMergedAssistants", tMergeStrip, `strippedParts=${strippedMergedReasoning}`);
|
|
171092
|
-
|
|
171093
|
-
for (const tag of tags) {
|
|
171094
|
-
if (tag.status === "dropped" && tag.tagNumber > watermark) {
|
|
171095
|
-
watermark = tag.tagNumber;
|
|
171096
|
-
}
|
|
171097
|
-
}
|
|
172020
|
+
const watermark = getMaxDroppedTagNumber(db, sessionId);
|
|
171098
172021
|
const contextUsage = contextUsageEarly;
|
|
171099
172022
|
const schedulerDecision = schedulerDecisionEarly;
|
|
171100
172023
|
const rawGetNotifParams = deps.getNotificationParams;
|
|
@@ -171144,7 +172067,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
171144
172067
|
sessionId,
|
|
171145
172068
|
db,
|
|
171146
172069
|
messages,
|
|
171147
|
-
tags,
|
|
172070
|
+
tags: activeTags,
|
|
171148
172071
|
targets,
|
|
171149
172072
|
reasoningByMessage,
|
|
171150
172073
|
messageTagNumbers,
|
|
@@ -171170,7 +172093,6 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
|
|
|
171170
172093
|
watermark,
|
|
171171
172094
|
forceMaterializationPercentage: FORCE_MATERIALIZE_PERCENTAGE,
|
|
171172
172095
|
hasRecentReduceCall,
|
|
171173
|
-
skipTypedReasoningCleanup,
|
|
171174
172096
|
projectPath: deps.projectPath,
|
|
171175
172097
|
autoSearch: deps.autoSearch,
|
|
171176
172098
|
cavemanTextCompression: deps.ctxReduceEnabled === false && !reducedMode ? deps.cavemanTextCompression : undefined
|
|
@@ -171539,6 +172461,7 @@ function createEventHandler2(deps) {
|
|
|
171539
172461
|
sessionLog(info.sessionID, `event message.removed: invalidating state for message ${info.messageID}`);
|
|
171540
172462
|
try {
|
|
171541
172463
|
const cleanup = cleanupRemovedMessageState(deps, info.sessionID, info.messageID);
|
|
172464
|
+
scheduleClearAndReindex(deps.db, info.sessionID, readRawSessionMessages);
|
|
171542
172465
|
deps.tagger.cleanup(info.sessionID);
|
|
171543
172466
|
sessionLog(info.sessionID, "event message.removed: invalidated tagger session cache");
|
|
171544
172467
|
if (cleanup.clearedNudgePlacement) {
|
|
@@ -171657,7 +172580,7 @@ function createNudger(config2) {
|
|
|
171657
172580
|
}
|
|
171658
172581
|
const largest = formatLargestTags(topNFn(db, sessionId, 3));
|
|
171659
172582
|
const protectedCount = config2.protected_tags;
|
|
171660
|
-
const activeTags =
|
|
172583
|
+
const activeTags = preloadedTags ? preloadedTags.filter((t) => t.status === "active") : getActiveTagsBySession(db, sessionId);
|
|
171661
172584
|
const highestProtected = activeTags.map((t) => t.tagNumber).sort((a, b) => b - a).slice(0, protectedCount)[0];
|
|
171662
172585
|
const protectedHint = highestProtected ? ` Tags §${highestProtected}§ and above are protected (last ${protectedCount}) — You MUST NOT try to reduce those.` : "";
|
|
171663
172586
|
const oldToolHint = formatOldToolTags(activeTags, protectedCount, 5);
|
|
@@ -171748,7 +172671,7 @@ function estimateProjectedPercentage(db, sessionId, contextUsage, preloadedTags)
|
|
|
171748
172671
|
if (pendingDrops.length === 0) {
|
|
171749
172672
|
return null;
|
|
171750
172673
|
}
|
|
171751
|
-
const activeTags =
|
|
172674
|
+
const activeTags = preloadedTags ? preloadedTags.filter((t) => t.status === "active") : getActiveTagsBySession(db, sessionId);
|
|
171752
172675
|
const totalActiveBytes = activeTags.reduce((sum, t) => sum + t.byteSize, 0);
|
|
171753
172676
|
if (totalActiveBytes === 0) {
|
|
171754
172677
|
return null;
|
|
@@ -171821,6 +172744,7 @@ function clearSidebarSnapshotCache(sessionId) {
|
|
|
171821
172744
|
// src/hooks/magic-context/hook-handlers.ts
|
|
171822
172745
|
init_logger();
|
|
171823
172746
|
init_note_nudger();
|
|
172747
|
+
await init_read_session_chunk();
|
|
171824
172748
|
var TOOL_HEAVY_TURN_REMINDER_THRESHOLD = 5;
|
|
171825
172749
|
var TOOL_HEAVY_TURN_REMINDER_TEXT = `
|
|
171826
172750
|
|
|
@@ -171873,6 +172797,14 @@ function createEventHook(args) {
|
|
|
171873
172797
|
return async (input) => {
|
|
171874
172798
|
await args.eventHandler(input);
|
|
171875
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
|
+
}
|
|
171876
172808
|
const assistantInfo = getMessageUpdatedAssistantInfo(input.event.properties);
|
|
171877
172809
|
if (assistantInfo?.providerID && assistantInfo?.modelID) {
|
|
171878
172810
|
const previous = args.liveModelBySession.get(assistantInfo.sessionID);
|
|
@@ -171894,6 +172826,9 @@ function createEventHook(args) {
|
|
|
171894
172826
|
const sessionId = resolveSessionId(properties);
|
|
171895
172827
|
if (!sessionId)
|
|
171896
172828
|
return;
|
|
172829
|
+
if (input.event.type !== "session.deleted") {
|
|
172830
|
+
scheduleReconciliation(args.db, sessionId, readRawSessionMessages);
|
|
172831
|
+
}
|
|
171897
172832
|
if (input.event.type === "session.deleted") {
|
|
171898
172833
|
args.liveModelBySession.delete(sessionId);
|
|
171899
172834
|
args.variantBySession.delete(sessionId);
|
|
@@ -171909,6 +172844,7 @@ function createEventHook(args) {
|
|
|
171909
172844
|
clearNoteNudgeState(args.db, sessionId);
|
|
171910
172845
|
clearAutoSearchForSession(sessionId);
|
|
171911
172846
|
clearSidebarSnapshotCache(sessionId);
|
|
172847
|
+
clearSessionTracking(sessionId);
|
|
171912
172848
|
}
|
|
171913
172849
|
};
|
|
171914
172850
|
}
|
|
@@ -171956,8 +172892,8 @@ init_send_session_notification();
|
|
|
171956
172892
|
|
|
171957
172893
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
171958
172894
|
import { createHash as createHash4 } from "node:crypto";
|
|
171959
|
-
import { existsSync as
|
|
171960
|
-
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";
|
|
171961
172897
|
|
|
171962
172898
|
// src/agents/magic-context-prompt.ts
|
|
171963
172899
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
@@ -172070,9 +173006,9 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
172070
173006
|
function readProjectDocs(directory) {
|
|
172071
173007
|
const sections = [];
|
|
172072
173008
|
for (const filename of DOC_FILES) {
|
|
172073
|
-
const filePath =
|
|
173009
|
+
const filePath = join21(directory, filename);
|
|
172074
173010
|
try {
|
|
172075
|
-
if (
|
|
173011
|
+
if (existsSync12(filePath)) {
|
|
172076
173012
|
const content = readFileSync8(filePath, "utf-8").trim();
|
|
172077
173013
|
if (content.length > 0) {
|
|
172078
173014
|
sections.push(`<${filename}>
|
|
@@ -172185,7 +173121,7 @@ ${items}
|
|
|
172185
173121
|
log(`[magic-context] key file path escapes project root, skipping: ${entry.filePath}`);
|
|
172186
173122
|
continue;
|
|
172187
173123
|
}
|
|
172188
|
-
if (!
|
|
173124
|
+
if (!existsSync12(absPath))
|
|
172189
173125
|
continue;
|
|
172190
173126
|
let realPath;
|
|
172191
173127
|
try {
|
|
@@ -172730,8 +173666,14 @@ function truncateError(name2, code, message, maxLen = 240) {
|
|
|
172730
173666
|
|
|
172731
173667
|
// src/plugin/rpc-handlers.ts
|
|
172732
173668
|
init_project_identity();
|
|
173669
|
+
init_storage_memory();
|
|
173670
|
+
init_tool_definition_tokens();
|
|
172733
173671
|
await init_storage();
|
|
172734
173672
|
init_read_session_formatting();
|
|
173673
|
+
await __promiseAll([
|
|
173674
|
+
init_inject_compartments(),
|
|
173675
|
+
init_read_session_db()
|
|
173676
|
+
]);
|
|
172735
173677
|
|
|
172736
173678
|
// src/hooks/magic-context/tokenizer-calibration.ts
|
|
172737
173679
|
var CALIBRATION_TABLE = [
|
|
@@ -172938,7 +173880,7 @@ function resolveConfigValue(cfg, key, modelKey, defaultValue) {
|
|
|
172938
173880
|
}
|
|
172939
173881
|
return defaultValue;
|
|
172940
173882
|
}
|
|
172941
|
-
function buildSidebarSnapshot(db, sessionId, directory, liveSessionState) {
|
|
173883
|
+
function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens) {
|
|
172942
173884
|
const empty = {
|
|
172943
173885
|
sessionId,
|
|
172944
173886
|
usagePercentage: 0,
|
|
@@ -173023,6 +173965,20 @@ ${c.content}
|
|
|
173023
173965
|
const cached2 = meta3.memory_block_cache;
|
|
173024
173966
|
if (typeof cached2 === "string" && cached2.length > 0) {
|
|
173025
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
|
+
}
|
|
173026
173982
|
}
|
|
173027
173983
|
}
|
|
173028
173984
|
let lastDreamerRunAt = null;
|
|
@@ -173041,8 +173997,24 @@ ${c.content}
|
|
|
173041
173997
|
let activeProviderID;
|
|
173042
173998
|
let activeModelID;
|
|
173043
173999
|
if (liveSessionState) {
|
|
173044
|
-
|
|
173045
|
-
|
|
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
|
+
}
|
|
173046
174018
|
if (model) {
|
|
173047
174019
|
activeProviderID = model.providerID;
|
|
173048
174020
|
activeModelID = model.modelID;
|
|
@@ -173091,8 +174063,8 @@ ${c.content}
|
|
|
173091
174063
|
return empty;
|
|
173092
174064
|
}
|
|
173093
174065
|
}
|
|
173094
|
-
function buildStatusDetail(db, sessionId, directory, modelKey, config2, liveSessionState) {
|
|
173095
|
-
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);
|
|
173096
174068
|
const detail = {
|
|
173097
174069
|
...base,
|
|
173098
174070
|
tagCounter: 0,
|
|
@@ -173208,13 +174180,14 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
173208
174180
|
const { directory, config: config2, liveSessionState } = args;
|
|
173209
174181
|
const rawConfig = config2;
|
|
173210
174182
|
const getNotificationParams = (sessionId) => getLiveNotificationParams(sessionId, liveSessionState.liveModelBySession, liveSessionState.variantBySession, liveSessionState.agentBySession);
|
|
174183
|
+
const injectionBudgetTokens = config2.memory?.injection_budget_tokens;
|
|
173211
174184
|
rpcServer.handle("sidebar-snapshot", async (params) => {
|
|
173212
174185
|
const sessionId = String(params.sessionId ?? "");
|
|
173213
174186
|
const dir = String(params.directory ?? directory);
|
|
173214
174187
|
const db = getDb();
|
|
173215
174188
|
if (!db || !sessionId)
|
|
173216
174189
|
return { error: "unavailable" };
|
|
173217
|
-
return buildSidebarSnapshot(db, sessionId, dir, liveSessionState);
|
|
174190
|
+
return buildSidebarSnapshot(db, sessionId, dir, liveSessionState, injectionBudgetTokens);
|
|
173218
174191
|
});
|
|
173219
174192
|
rpcServer.handle("status-detail", async (params) => {
|
|
173220
174193
|
const sessionId = String(params.sessionId ?? "");
|
|
@@ -173223,7 +174196,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
173223
174196
|
const db = getDb();
|
|
173224
174197
|
if (!db || !sessionId)
|
|
173225
174198
|
return { error: "unavailable" };
|
|
173226
|
-
return buildStatusDetail(db, sessionId, dir, modelKey, rawConfig, liveSessionState);
|
|
174199
|
+
return buildStatusDetail(db, sessionId, dir, modelKey, rawConfig, liveSessionState, injectionBudgetTokens);
|
|
173227
174200
|
});
|
|
173228
174201
|
rpcServer.handle("compartment-count", async (params) => {
|
|
173229
174202
|
const sessionId = String(params.sessionId ?? "");
|
|
@@ -174236,13 +175209,13 @@ import { dirname as dirname5 } from "node:path";
|
|
|
174236
175209
|
|
|
174237
175210
|
// src/shared/rpc-utils.ts
|
|
174238
175211
|
import { createHash as createHash5 } from "node:crypto";
|
|
174239
|
-
import { join as
|
|
175212
|
+
import { join as join22 } from "node:path";
|
|
174240
175213
|
function projectHash(directory) {
|
|
174241
175214
|
const normalized = directory.replace(/\/+$/, "");
|
|
174242
175215
|
return createHash5("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
174243
175216
|
}
|
|
174244
175217
|
function rpcPortFilePath(storageDir, directory) {
|
|
174245
|
-
return
|
|
175218
|
+
return join22(storageDir, "rpc", projectHash(directory), "port");
|
|
174246
175219
|
}
|
|
174247
175220
|
|
|
174248
175221
|
// src/shared/rpc-server.ts
|
|
@@ -174438,7 +175411,7 @@ var plugin = async (ctx) => {
|
|
|
174438
175411
|
refreshModelLimitsFromApi(ctx.client);
|
|
174439
175412
|
setInterval(() => {
|
|
174440
175413
|
refreshModelLimitsFromApi(ctx.client);
|
|
174441
|
-
},
|
|
175414
|
+
}, 60 * 60 * 1000);
|
|
174442
175415
|
}
|
|
174443
175416
|
if (conflictResult?.hasConflict) {
|
|
174444
175417
|
sendConflictWarning(ctx.client, ctx.directory, conflictResult);
|