@cortexkit/pi-magic-context 0.24.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +108 -63
- package/dist/subagent-entry.js +33 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -146668,15 +146668,22 @@ function ownerMessageIdForTagRow(row) {
|
|
|
146668
146668
|
}
|
|
146669
146669
|
return row.message_id.replace(CONTENT_ID_SUFFIX, "");
|
|
146670
146670
|
}
|
|
146671
|
-
function getActiveTagTokenAggregate(db, sessionId) {
|
|
146672
|
-
const
|
|
146671
|
+
function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
|
|
146672
|
+
const toolOutputExpr = protectedTags > 0 ? `COALESCE(SUM(CASE WHEN type = 'tool' AND tag_number < (
|
|
146673
|
+
SELECT tag_number FROM tags
|
|
146674
|
+
WHERE session_id = ? AND status = 'active'
|
|
146675
|
+
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
146676
|
+
) THEN COALESCE(token_count, 0) ELSE 0 END), 0)` : `COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)`;
|
|
146677
|
+
const sql = `SELECT
|
|
146673
146678
|
COALESCE(SUM(CASE WHEN type != 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)
|
|
146674
146679
|
+ COALESCE(SUM(COALESCE(reasoning_token_count, 0)), 0) AS conversation,
|
|
146675
146680
|
COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) + COALESCE(input_token_count, 0) ELSE 0 END), 0) AS tool_call,
|
|
146676
|
-
|
|
146681
|
+
${toolOutputExpr} AS tool_output,
|
|
146677
146682
|
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
146678
146683
|
FROM tags
|
|
146679
|
-
WHERE session_id = ? AND status = 'active'
|
|
146684
|
+
WHERE session_id = ? AND status = 'active'`;
|
|
146685
|
+
const params = protectedTags > 0 ? [sessionId, protectedTags - 1, sessionId] : [sessionId];
|
|
146686
|
+
const row = db.prepare(sql).get(...params);
|
|
146680
146687
|
return {
|
|
146681
146688
|
conversation: row?.conversation ?? 0,
|
|
146682
146689
|
toolCall: row?.tool_call ?? 0,
|
|
@@ -166293,6 +166300,7 @@ init_logger();
|
|
|
166293
166300
|
// ../plugin/src/features/magic-context/compartment-chunk-embedding.ts
|
|
166294
166301
|
import { createHash as createHash8 } from "node:crypto";
|
|
166295
166302
|
var DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS = 512;
|
|
166303
|
+
var CHUNK_WINDOW_SAFETY_RATIO = 0.9;
|
|
166296
166304
|
var loadFtsRowsStatements = new WeakMap;
|
|
166297
166305
|
var existingHashStatements = new WeakMap;
|
|
166298
166306
|
var existingHashByProjectStatements = new WeakMap;
|
|
@@ -166528,9 +166536,10 @@ function chunkCanonicalText(canonicalText, startOrdinal, endOrdinal, maxInputTok
|
|
|
166528
166536
|
if (lines.length === 0 || endOrdinal < startOrdinal)
|
|
166529
166537
|
return [];
|
|
166530
166538
|
const normalizedMax = normalizeCompartmentChunkMaxInputTokens(maxInputTokens);
|
|
166539
|
+
const effectiveMax = Math.max(1, Math.floor(normalizedMax * CHUNK_WINDOW_SAFETY_RATIO));
|
|
166531
166540
|
const fullText = lines.join(`
|
|
166532
166541
|
`);
|
|
166533
|
-
if (estimateTokens(fullText) <=
|
|
166542
|
+
if (estimateTokens(fullText) <= effectiveMax) {
|
|
166534
166543
|
return [
|
|
166535
166544
|
{
|
|
166536
166545
|
windowIndex: 0,
|
|
@@ -166568,7 +166577,7 @@ function chunkCanonicalText(canonicalText, startOrdinal, endOrdinal, maxInputTok
|
|
|
166568
166577
|
const lineStart = range?.start ?? startOrdinal;
|
|
166569
166578
|
const lineEnd = range?.end ?? lineStart;
|
|
166570
166579
|
const lineTokens = estimateTokens(line);
|
|
166571
|
-
if (currentLines.length > 0 && currentTokens + lineTokens >
|
|
166580
|
+
if (currentLines.length > 0 && currentTokens + lineTokens > effectiveMax) {
|
|
166572
166581
|
flush2();
|
|
166573
166582
|
}
|
|
166574
166583
|
if (currentLines.length === 0) {
|
|
@@ -167168,6 +167177,13 @@ function blockedEmbeddingEndpointReason(endpoint) {
|
|
|
167168
167177
|
function normalizeEndpoint2(endpoint) {
|
|
167169
167178
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
167170
167179
|
}
|
|
167180
|
+
function embeddingModelsMatch(served, requested) {
|
|
167181
|
+
const a = served.trim().toLowerCase();
|
|
167182
|
+
const b = requested.trim().toLowerCase();
|
|
167183
|
+
if (a.length === 0 || b.length === 0)
|
|
167184
|
+
return true;
|
|
167185
|
+
return a === b || a.includes(b) || b.includes(a);
|
|
167186
|
+
}
|
|
167171
167187
|
var FAILURE_THRESHOLD = 3;
|
|
167172
167188
|
var FAILURE_WINDOW_MS = 60000;
|
|
167173
167189
|
var OPEN_DURATION_MS = 5 * 60000;
|
|
@@ -167185,6 +167201,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167185
167201
|
failureTimes = [];
|
|
167186
167202
|
circuitOpenUntil = 0;
|
|
167187
167203
|
openLogged = false;
|
|
167204
|
+
modelMismatchLogged = false;
|
|
167188
167205
|
halfOpenProbeInFlight = false;
|
|
167189
167206
|
constructor(options) {
|
|
167190
167207
|
this.endpoint = normalizeEndpoint2(options.endpoint);
|
|
@@ -167283,6 +167300,15 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167283
167300
|
this.recordFailure(isProbe);
|
|
167284
167301
|
return Array.from({ length: texts.length }, () => null);
|
|
167285
167302
|
}
|
|
167303
|
+
const servedModel = typeof body.model === "string" ? body.model : "";
|
|
167304
|
+
if (this.model && servedModel && !embeddingModelsMatch(servedModel, this.model)) {
|
|
167305
|
+
if (!this.modelMismatchLogged) {
|
|
167306
|
+
log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". The endpoint likely substituted a loaded model; load/select "${this.model}" on the endpoint, or set embedding.model to the served model.`);
|
|
167307
|
+
this.modelMismatchLogged = true;
|
|
167308
|
+
}
|
|
167309
|
+
this.recordFailure(isProbe);
|
|
167310
|
+
return Array.from({ length: texts.length }, () => null);
|
|
167311
|
+
}
|
|
167286
167312
|
const items = Array.isArray(body.data) ? body.data : [];
|
|
167287
167313
|
const results = Array.from({ length: texts.length }, (_, index) => {
|
|
167288
167314
|
const embedding = items[index]?.embedding;
|
|
@@ -167765,7 +167791,7 @@ function getChunkEmbeddingModelId(config2, providerIdentity) {
|
|
|
167765
167791
|
}
|
|
167766
167792
|
const chunkIdentity = {
|
|
167767
167793
|
providerIdentity,
|
|
167768
|
-
chunkerVersion:
|
|
167794
|
+
chunkerVersion: 2,
|
|
167769
167795
|
maxInputTokens: normalizeCompartmentChunkMaxInputTokens("max_input_tokens" in config2 ? config2.max_input_tokens : undefined),
|
|
167770
167796
|
truncate: config2.provider === "openai-compatible" ? config2.truncate ?? "" : ""
|
|
167771
167797
|
};
|
|
@@ -170305,6 +170331,51 @@ function computePiWorkMetrics(sessionEntries) {
|
|
|
170305
170331
|
return { newWorkTokens, totalInputTokens };
|
|
170306
170332
|
}
|
|
170307
170333
|
|
|
170334
|
+
// ../plugin/src/hooks/magic-context/system-injection-stripper.ts
|
|
170335
|
+
var SYSTEM_INJECTION_MARKERS = [
|
|
170336
|
+
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
170337
|
+
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
170338
|
+
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
170339
|
+
"[Category+Skill Reminder]",
|
|
170340
|
+
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
170341
|
+
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
170342
|
+
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
170343
|
+
"Unstable background agent appears idle",
|
|
170344
|
+
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
170345
|
+
];
|
|
170346
|
+
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
170347
|
+
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
170348
|
+
function stripSystemInjection(text) {
|
|
170349
|
+
let hasInjection = false;
|
|
170350
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
170351
|
+
if (text.includes(marker)) {
|
|
170352
|
+
hasInjection = true;
|
|
170353
|
+
break;
|
|
170354
|
+
}
|
|
170355
|
+
}
|
|
170356
|
+
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
170357
|
+
hasInjection = true;
|
|
170358
|
+
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
170359
|
+
if (!hasInjection)
|
|
170360
|
+
return null;
|
|
170361
|
+
let cleaned = text;
|
|
170362
|
+
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
170363
|
+
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
170364
|
+
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
170365
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
170366
|
+
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
170367
|
+
continue;
|
|
170368
|
+
const idx = cleaned.indexOf(marker);
|
|
170369
|
+
if (idx === -1)
|
|
170370
|
+
continue;
|
|
170371
|
+
const blockEnd = cleaned.indexOf(`
|
|
170372
|
+
|
|
170373
|
+
`, idx + marker.length);
|
|
170374
|
+
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
170375
|
+
}
|
|
170376
|
+
return cleaned.trim();
|
|
170377
|
+
}
|
|
170378
|
+
|
|
170308
170379
|
// ../plugin/src/hooks/magic-context/apply-operations.ts
|
|
170309
170380
|
var USER_DROP_PREVIEW_CHARS = 250;
|
|
170310
170381
|
var RECENT_TOOL_SKELETON_WINDOW = 20;
|
|
@@ -170314,6 +170385,10 @@ function buildReplacementContent(tagId, target) {
|
|
|
170314
170385
|
return `[dropped §${tagId}§]`;
|
|
170315
170386
|
}
|
|
170316
170387
|
const currentContent = target.getContent?.() ?? "";
|
|
170388
|
+
const strippedInjection = stripSystemInjection(currentContent);
|
|
170389
|
+
if (strippedInjection !== null && stripTagPrefix(strippedInjection).trim().length === 0) {
|
|
170390
|
+
return `[dropped §${tagId}§]`;
|
|
170391
|
+
}
|
|
170317
170392
|
const originalText = stripTagPrefix(currentContent);
|
|
170318
170393
|
if (originalText.length <= USER_DROP_PREVIEW_CHARS) {
|
|
170319
170394
|
return `[truncated §${tagId}§]
|
|
@@ -171922,8 +171997,8 @@ var CHANNEL1_SENTINEL = "<system-reminder>";
|
|
|
171922
171997
|
var TOKENS_PER_BYTE = 0.25;
|
|
171923
171998
|
var CHANNEL1_FLOOR_TOKENS = 1e4;
|
|
171924
171999
|
var CHANNEL1_REFIRE_FLOOR_TOKENS = 1e4;
|
|
171925
|
-
function channel1RefireTokens(
|
|
171926
|
-
const scaled = Math.round(0.05 * Math.max(0,
|
|
172000
|
+
function channel1RefireTokens(workingWindowTokens) {
|
|
172001
|
+
const scaled = Math.round(0.05 * Math.max(0, workingWindowTokens));
|
|
171927
172002
|
return Math.max(CHANNEL1_REFIRE_FLOOR_TOKENS, scaled);
|
|
171928
172003
|
}
|
|
171929
172004
|
var S_GENTLE = 0.2;
|
|
@@ -171939,7 +172014,7 @@ function toolOutputTokens(output) {
|
|
|
171939
172014
|
return Math.round(byteSize(output) * TOKENS_PER_BYTE);
|
|
171940
172015
|
}
|
|
171941
172016
|
function decideChannel1(input) {
|
|
171942
|
-
const { undroppedTokens, pressure,
|
|
172017
|
+
const { undroppedTokens, pressure, workingWindowTokens, hasRecentReduce } = input;
|
|
171943
172018
|
const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
|
|
171944
172019
|
const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
|
|
171945
172020
|
const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
|
|
@@ -171954,7 +172029,7 @@ function decideChannel1(input) {
|
|
|
171954
172029
|
return quiet();
|
|
171955
172030
|
if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
|
|
171956
172031
|
return quiet();
|
|
171957
|
-
const budget =
|
|
172032
|
+
const budget = workingWindowTokens > 0 ? workingWindowTokens : undroppedTokens || 1;
|
|
171958
172033
|
const severity = undroppedTokens / budget * pressure;
|
|
171959
172034
|
if (severity < S_GENTLE)
|
|
171960
172035
|
return quiet();
|
|
@@ -171966,7 +172041,7 @@ function decideChannel1(input) {
|
|
|
171966
172041
|
else
|
|
171967
172042
|
level = "gentle";
|
|
171968
172043
|
if (lastLevel === "") {
|
|
171969
|
-
if (undroppedTokens < lastNudge + channel1RefireTokens(
|
|
172044
|
+
if (undroppedTokens < lastNudge + channel1RefireTokens(workingWindowTokens)) {
|
|
171970
172045
|
return quiet();
|
|
171971
172046
|
}
|
|
171972
172047
|
} else if (LEVEL_RANK[level] <= LEVEL_RANK[lastLevel]) {
|
|
@@ -172011,13 +172086,13 @@ function buildChannel1Reminder(level, undroppedTokens) {
|
|
|
172011
172086
|
let body;
|
|
172012
172087
|
switch (level) {
|
|
172013
172088
|
case "gentle":
|
|
172014
|
-
body = `You have ~${amount} tokens of tool output you have not reduced. ` + `
|
|
172089
|
+
body = `You have ~${amount} tokens of tool output you have not reduced. ` + `When you are done with earlier outputs, dropping them with ctx_reduce keeps context lean.`;
|
|
172015
172090
|
break;
|
|
172016
172091
|
case "firm":
|
|
172017
|
-
body = `~${amount} tokens of unreduced tool output
|
|
172092
|
+
body = `~${amount} tokens of unreduced tool output has built up. ` + `At your next natural stopping point, consider dropping what you have already processed with ctx_reduce.`;
|
|
172018
172093
|
break;
|
|
172019
172094
|
case "urgent":
|
|
172020
|
-
body = `~${amount} tokens of unreduced tool output remain
|
|
172095
|
+
body = `~${amount} tokens of unreduced tool output remain, and a large span of this session will be comparted before long. ` + `Consider dropping spent outputs with ctx_reduce so the archived span is the part that matters.`;
|
|
172021
172096
|
break;
|
|
172022
172097
|
}
|
|
172023
172098
|
return `
|
|
@@ -174336,10 +174411,11 @@ function maybeChannel1ReminderForToolResult(args) {
|
|
|
174336
174411
|
contextLimit: state.contextLimit,
|
|
174337
174412
|
executeThresholdPercentage: state.executeThresholdPercentage
|
|
174338
174413
|
});
|
|
174414
|
+
const workingWindowTokens = Math.round(state.contextLimit * state.executeThresholdPercentage / 100);
|
|
174339
174415
|
const decision = decideChannel1({
|
|
174340
174416
|
undroppedTokens,
|
|
174341
174417
|
pressure,
|
|
174342
|
-
|
|
174418
|
+
workingWindowTokens,
|
|
174343
174419
|
lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
|
|
174344
174420
|
lastNudgeLevel: getLastNudgeLevel(db, sessionId),
|
|
174345
174421
|
hasRecentReduce: false
|
|
@@ -174574,51 +174650,6 @@ function planEmergencyDrop(input) {
|
|
|
174574
174650
|
};
|
|
174575
174651
|
}
|
|
174576
174652
|
|
|
174577
|
-
// ../plugin/src/hooks/magic-context/system-injection-stripper.ts
|
|
174578
|
-
var SYSTEM_INJECTION_MARKERS = [
|
|
174579
|
-
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
174580
|
-
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
174581
|
-
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
174582
|
-
"[Category+Skill Reminder]",
|
|
174583
|
-
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
174584
|
-
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
174585
|
-
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
174586
|
-
"Unstable background agent appears idle",
|
|
174587
|
-
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
174588
|
-
];
|
|
174589
|
-
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
174590
|
-
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
174591
|
-
function stripSystemInjection(text) {
|
|
174592
|
-
let hasInjection = false;
|
|
174593
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
174594
|
-
if (text.includes(marker)) {
|
|
174595
|
-
hasInjection = true;
|
|
174596
|
-
break;
|
|
174597
|
-
}
|
|
174598
|
-
}
|
|
174599
|
-
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
174600
|
-
hasInjection = true;
|
|
174601
|
-
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
174602
|
-
if (!hasInjection)
|
|
174603
|
-
return null;
|
|
174604
|
-
let cleaned = text;
|
|
174605
|
-
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
174606
|
-
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
174607
|
-
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
174608
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
174609
|
-
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
174610
|
-
continue;
|
|
174611
|
-
const idx = cleaned.indexOf(marker);
|
|
174612
|
-
if (idx === -1)
|
|
174613
|
-
continue;
|
|
174614
|
-
const blockEnd = cleaned.indexOf(`
|
|
174615
|
-
|
|
174616
|
-
`, idx + marker.length);
|
|
174617
|
-
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
174618
|
-
}
|
|
174619
|
-
return cleaned.trim();
|
|
174620
|
-
}
|
|
174621
|
-
|
|
174622
174653
|
// src/heuristic-cleanup-pi.ts
|
|
174623
174654
|
init_logger();
|
|
174624
174655
|
var DEDUP_SAFE_TOOLS = new Set([
|
|
@@ -181738,7 +181769,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181738
181769
|
let tailToolTokens;
|
|
181739
181770
|
let liveTailTokens;
|
|
181740
181771
|
try {
|
|
181741
|
-
const agg = getActiveTagTokenAggregate(options.db, sessionId);
|
|
181772
|
+
const agg = getActiveTagTokenAggregate(options.db, sessionId, options.protectedTags ?? 20);
|
|
181742
181773
|
tailToolTokens = agg.toolOutput;
|
|
181743
181774
|
liveTailTokens = agg.conversation + agg.toolCall;
|
|
181744
181775
|
} catch {
|
|
@@ -182091,6 +182122,15 @@ Historian previously failed ${failureState.failureCount} time(s), so Magic Conte
|
|
|
182091
182122
|
const trigger = checkCompartmentTrigger(db, sessionId, sessionMeta, usage, 0, triggerInputs.executeThresholdPercentage, triggerInputs.triggerBudget, triggerInputs.clearReasoningAge, triggerInputs.commitClusterTrigger, args.activeTags, boundaryContextLimit);
|
|
182092
182123
|
if (!trigger.shouldFire) {
|
|
182093
182124
|
sessionLog(sessionId, `historian trigger eval: shouldFire=false (no trigger condition met)`);
|
|
182125
|
+
try {
|
|
182126
|
+
const overflowState = getOverflowState(db, sessionId);
|
|
182127
|
+
if (overflowState.needsEmergencyRecovery && usage.percentage < FORCE_MATERIALIZATION_PERCENTAGE && !inFlightHistorian.has(sessionId) && !hasRunnableCompartmentWindow(boundarySnapshot)) {
|
|
182128
|
+
clearEmergencyRecovery(db, sessionId);
|
|
182129
|
+
sessionLog(sessionId, `historian: disarming stale emergency recovery — real pressure ${usage.percentage.toFixed(1)}% with no runnable compartment window (would otherwise bump to 95% every pass)`);
|
|
182130
|
+
}
|
|
182131
|
+
} catch (err) {
|
|
182132
|
+
sessionLog(sessionId, `historian: emergency-recovery disarm check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
182133
|
+
}
|
|
182094
182134
|
return;
|
|
182095
182135
|
}
|
|
182096
182136
|
triggered = true;
|
|
@@ -184471,6 +184511,11 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
184471
184511
|
fallbackModelId: ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined
|
|
184472
184512
|
}, parsed.kind === "partial" ? { range: parsed.range } : {});
|
|
184473
184513
|
if (result.published) {
|
|
184514
|
+
try {
|
|
184515
|
+
clearEmergencyRecovery(deps.db, sessionId);
|
|
184516
|
+
} catch (recoveryError) {
|
|
184517
|
+
sessionLog(sessionId, `/ctx-recomp: clearEmergencyRecovery failed (continuing): ${describeError(recoveryError).brief}`);
|
|
184518
|
+
}
|
|
184474
184519
|
try {
|
|
184475
184520
|
stagePiRecompMarker({ db: deps.db, sessionId, ctx });
|
|
184476
184521
|
} catch (markerError) {
|
|
@@ -185124,7 +185169,7 @@ function formatThresholdPercent(value) {
|
|
|
185124
185169
|
// package.json
|
|
185125
185170
|
var package_default = {
|
|
185126
185171
|
name: "@cortexkit/pi-magic-context",
|
|
185127
|
-
version: "0.24.
|
|
185172
|
+
version: "0.24.1",
|
|
185128
185173
|
type: "module",
|
|
185129
185174
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
185130
185175
|
main: "dist/index.js",
|
package/dist/subagent-entry.js
CHANGED
|
@@ -158702,6 +158702,7 @@ init_logger();
|
|
|
158702
158702
|
// ../plugin/src/features/magic-context/compartment-chunk-embedding.ts
|
|
158703
158703
|
import { createHash as createHash4 } from "node:crypto";
|
|
158704
158704
|
var DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS = 512;
|
|
158705
|
+
var CHUNK_WINDOW_SAFETY_RATIO = 0.9;
|
|
158705
158706
|
var loadFtsRowsStatements = new WeakMap;
|
|
158706
158707
|
var existingHashStatements = new WeakMap;
|
|
158707
158708
|
var existingHashByProjectStatements = new WeakMap;
|
|
@@ -158937,9 +158938,10 @@ function chunkCanonicalText(canonicalText, startOrdinal, endOrdinal, maxInputTok
|
|
|
158937
158938
|
if (lines.length === 0 || endOrdinal < startOrdinal)
|
|
158938
158939
|
return [];
|
|
158939
158940
|
const normalizedMax = normalizeCompartmentChunkMaxInputTokens(maxInputTokens);
|
|
158941
|
+
const effectiveMax = Math.max(1, Math.floor(normalizedMax * CHUNK_WINDOW_SAFETY_RATIO));
|
|
158940
158942
|
const fullText = lines.join(`
|
|
158941
158943
|
`);
|
|
158942
|
-
if (estimateTokens(fullText) <=
|
|
158944
|
+
if (estimateTokens(fullText) <= effectiveMax) {
|
|
158943
158945
|
return [
|
|
158944
158946
|
{
|
|
158945
158947
|
windowIndex: 0,
|
|
@@ -158977,7 +158979,7 @@ function chunkCanonicalText(canonicalText, startOrdinal, endOrdinal, maxInputTok
|
|
|
158977
158979
|
const lineStart = range?.start ?? startOrdinal;
|
|
158978
158980
|
const lineEnd = range?.end ?? lineStart;
|
|
158979
158981
|
const lineTokens = estimateTokens(line);
|
|
158980
|
-
if (currentLines.length > 0 && currentTokens + lineTokens >
|
|
158982
|
+
if (currentLines.length > 0 && currentTokens + lineTokens > effectiveMax) {
|
|
158981
158983
|
flush2();
|
|
158982
158984
|
}
|
|
158983
158985
|
if (currentLines.length === 0) {
|
|
@@ -159587,6 +159589,13 @@ function blockedEmbeddingEndpointReason(endpoint) {
|
|
|
159587
159589
|
function normalizeEndpoint3(endpoint) {
|
|
159588
159590
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
159589
159591
|
}
|
|
159592
|
+
function embeddingModelsMatch(served, requested) {
|
|
159593
|
+
const a = served.trim().toLowerCase();
|
|
159594
|
+
const b = requested.trim().toLowerCase();
|
|
159595
|
+
if (a.length === 0 || b.length === 0)
|
|
159596
|
+
return true;
|
|
159597
|
+
return a === b || a.includes(b) || b.includes(a);
|
|
159598
|
+
}
|
|
159590
159599
|
var FAILURE_THRESHOLD = 3;
|
|
159591
159600
|
var FAILURE_WINDOW_MS = 60000;
|
|
159592
159601
|
var OPEN_DURATION_MS = 5 * 60000;
|
|
@@ -159604,6 +159613,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
159604
159613
|
failureTimes = [];
|
|
159605
159614
|
circuitOpenUntil = 0;
|
|
159606
159615
|
openLogged = false;
|
|
159616
|
+
modelMismatchLogged = false;
|
|
159607
159617
|
halfOpenProbeInFlight = false;
|
|
159608
159618
|
constructor(options) {
|
|
159609
159619
|
this.endpoint = normalizeEndpoint3(options.endpoint);
|
|
@@ -159702,6 +159712,15 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
159702
159712
|
this.recordFailure(isProbe);
|
|
159703
159713
|
return Array.from({ length: texts.length }, () => null);
|
|
159704
159714
|
}
|
|
159715
|
+
const servedModel = typeof body.model === "string" ? body.model : "";
|
|
159716
|
+
if (this.model && servedModel && !embeddingModelsMatch(servedModel, this.model)) {
|
|
159717
|
+
if (!this.modelMismatchLogged) {
|
|
159718
|
+
log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". The endpoint likely substituted a loaded model; load/select "${this.model}" on the endpoint, or set embedding.model to the served model.`);
|
|
159719
|
+
this.modelMismatchLogged = true;
|
|
159720
|
+
}
|
|
159721
|
+
this.recordFailure(isProbe);
|
|
159722
|
+
return Array.from({ length: texts.length }, () => null);
|
|
159723
|
+
}
|
|
159705
159724
|
const items = Array.isArray(body.data) ? body.data : [];
|
|
159706
159725
|
const results = Array.from({ length: texts.length }, (_, index) => {
|
|
159707
159726
|
const embedding = items[index]?.embedding;
|
|
@@ -160300,7 +160319,7 @@ function getChunkEmbeddingModelId(config2, providerIdentity) {
|
|
|
160300
160319
|
}
|
|
160301
160320
|
const chunkIdentity = {
|
|
160302
160321
|
providerIdentity,
|
|
160303
|
-
chunkerVersion:
|
|
160322
|
+
chunkerVersion: 2,
|
|
160304
160323
|
maxInputTokens: normalizeCompartmentChunkMaxInputTokens("max_input_tokens" in config2 ? config2.max_input_tokens : undefined),
|
|
160305
160324
|
truncate: config2.provider === "openai-compatible" ? config2.truncate ?? "" : ""
|
|
160306
160325
|
};
|
|
@@ -168667,15 +168686,22 @@ function ownerMessageIdForTagRow(row) {
|
|
|
168667
168686
|
}
|
|
168668
168687
|
return row.message_id.replace(CONTENT_ID_SUFFIX, "");
|
|
168669
168688
|
}
|
|
168670
|
-
function getActiveTagTokenAggregate(db, sessionId) {
|
|
168671
|
-
const
|
|
168689
|
+
function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
|
|
168690
|
+
const toolOutputExpr = protectedTags > 0 ? `COALESCE(SUM(CASE WHEN type = 'tool' AND tag_number < (
|
|
168691
|
+
SELECT tag_number FROM tags
|
|
168692
|
+
WHERE session_id = ? AND status = 'active'
|
|
168693
|
+
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
168694
|
+
) THEN COALESCE(token_count, 0) ELSE 0 END), 0)` : `COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)`;
|
|
168695
|
+
const sql = `SELECT
|
|
168672
168696
|
COALESCE(SUM(CASE WHEN type != 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)
|
|
168673
168697
|
+ COALESCE(SUM(COALESCE(reasoning_token_count, 0)), 0) AS conversation,
|
|
168674
168698
|
COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) + COALESCE(input_token_count, 0) ELSE 0 END), 0) AS tool_call,
|
|
168675
|
-
|
|
168699
|
+
${toolOutputExpr} AS tool_output,
|
|
168676
168700
|
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
168677
168701
|
FROM tags
|
|
168678
|
-
WHERE session_id = ? AND status = 'active'
|
|
168702
|
+
WHERE session_id = ? AND status = 'active'`;
|
|
168703
|
+
const params = protectedTags > 0 ? [sessionId, protectedTags - 1, sessionId] : [sessionId];
|
|
168704
|
+
const row = db.prepare(sql).get(...params);
|
|
168679
168705
|
return {
|
|
168680
168706
|
conversation: row?.conversation ?? 0,
|
|
168681
168707
|
toolCall: row?.tool_call ?? 0,
|
package/package.json
CHANGED