@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 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 row = db.prepare(`SELECT
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
- COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0) AS tool_output,
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'`).get(sessionId);
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) <= normalizedMax) {
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 > normalizedMax) {
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: 1,
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(historyBudgetTokens) {
171926
- const scaled = Math.round(0.05 * Math.max(0, historyBudgetTokens));
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, historyBudgetTokens, hasRecentReduce } = input;
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 = historyBudgetTokens > 0 ? historyBudgetTokens : undroppedTokens || 1;
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(historyBudgetTokens)) {
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. ` + `Once you are done with earlier outputs, drop them with ctx_reduce to keep context lean.`;
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 is accumulating. ` + `Drop what you have already processed with ctx_reduce before continuing.`;
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. ` + `A large span of this session will be comparted soon; drop spent outputs with ctx_reduce first so the archived span is the part that matters.`;
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
- historyBudgetTokens: state.historyBudgetTokens,
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.0",
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",
@@ -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) <= normalizedMax) {
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 > normalizedMax) {
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: 1,
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 row = db.prepare(`SELECT
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
- COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0) AS tool_output,
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'`).get(sessionId);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.24.0",
3
+ "version": "0.24.1",
4
4
  "type": "module",
5
5
  "description": "Pi coding agent extension for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",