@cortexkit/magic-context 0.49.23 → 0.49.25

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.
Files changed (2) hide show
  1. package/dist/index.js +262 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -25260,6 +25260,29 @@ function getOpenCodeV2ActiveGeneration(slot) {
25260
25260
  return;
25261
25261
  }
25262
25262
  }
25263
+ function openCodeV2SlotSpec(spec, platform = process.platform) {
25264
+ if (platform !== "win32")
25265
+ return spec;
25266
+ return Array.from(spec, (char) => '<>:"|?*'.includes(char) || char.charCodeAt(0) < 32 ? "_" : char).join("");
25267
+ }
25268
+ function getOpenCodePluginInstallRoots(hostGeneration, config, npmCacheDir = getOpenCodeV2NpmCacheDir(), platform = process.platform) {
25269
+ const configured = openCodeV2SlotSpec(readConfiguredOpenCodePluginSpec(config), platform);
25270
+ const v2 = listOpenCodeV2PluginCacheSlots(npmCacheDir).sort((a, b) => Number(b.spec === configured) - Number(a.spec === configured)).map((slot) => getOpenCodeV2ActiveGeneration(slot.slot)).filter((generation) => generation !== undefined);
25271
+ const v1 = getOpenCodePluginCacheRoots();
25272
+ return hostGeneration === "v2" ? [...v2, ...v1] : [...v1, ...v2];
25273
+ }
25274
+ function getOpenCodeLoadedPluginInstallRoots(hostGeneration, config, npmCacheDir = getOpenCodeV2NpmCacheDir(), platform = process.platform) {
25275
+ let loaded;
25276
+ if (hostGeneration === "v2") {
25277
+ const configured = openCodeV2SlotSpec(readConfiguredOpenCodePluginSpec(config), platform);
25278
+ const generation = getOpenCodeV2ActiveGeneration(getOpenCodeV2PluginCacheSlot(npmCacheDir, configured));
25279
+ loaded = generation === undefined ? [] : [generation];
25280
+ } else {
25281
+ loaded = getOpenCodePluginCacheRoots();
25282
+ }
25283
+ const others = getOpenCodePluginInstallRoots(hostGeneration, config, npmCacheDir, platform).filter((root) => !loaded.includes(root));
25284
+ return { loaded, others };
25285
+ }
25263
25286
  function readOpenCodeV2CachedPluginVersion(slot) {
25264
25287
  const generation = getOpenCodeV2ActiveGeneration(slot);
25265
25288
  if (!generation)
@@ -33114,6 +33137,51 @@ var init_read_session_formatting = __esm(() => {
33114
33137
  PROMPT_TOKEN_COUNT_BYTES = 8 * 1024 * 1024;
33115
33138
  });
33116
33139
 
33140
+ // ../plugin/src/shared/bounded-session-map.ts
33141
+ class BoundedSessionMap {
33142
+ maxEntries;
33143
+ store = new Map;
33144
+ constructor(maxEntries) {
33145
+ if (!Number.isFinite(maxEntries) || maxEntries < 1) {
33146
+ throw new Error(`BoundedSessionMap: maxEntries must be >= 1, got ${maxEntries}`);
33147
+ }
33148
+ this.maxEntries = maxEntries;
33149
+ }
33150
+ get(sessionId) {
33151
+ const value = this.store.get(sessionId);
33152
+ if (value === undefined)
33153
+ return;
33154
+ this.store.delete(sessionId);
33155
+ this.store.set(sessionId, value);
33156
+ return value;
33157
+ }
33158
+ peek(sessionId) {
33159
+ return this.store.get(sessionId);
33160
+ }
33161
+ has(sessionId) {
33162
+ return this.store.has(sessionId);
33163
+ }
33164
+ set(sessionId, value) {
33165
+ if (this.store.has(sessionId)) {
33166
+ this.store.delete(sessionId);
33167
+ } else if (this.store.size >= this.maxEntries) {
33168
+ const oldest = this.store.keys().next().value;
33169
+ if (oldest !== undefined)
33170
+ this.store.delete(oldest);
33171
+ }
33172
+ this.store.set(sessionId, value);
33173
+ }
33174
+ delete(sessionId) {
33175
+ return this.store.delete(sessionId);
33176
+ }
33177
+ clear() {
33178
+ this.store.clear();
33179
+ }
33180
+ get size() {
33181
+ return this.store.size;
33182
+ }
33183
+ }
33184
+
33117
33185
  // ../plugin/src/shared/stable-json.ts
33118
33186
  function stableStringify(value, seen = new WeakSet) {
33119
33187
  const pieces = [];
@@ -33168,36 +33236,122 @@ function writeStable(value, seen, write) {
33168
33236
  }
33169
33237
 
33170
33238
  // ../plugin/src/features/magic-context/tool-definition-tokens.ts
33239
+ function agentKey(agentName) {
33240
+ return agentName && agentName.length > 0 ? agentName : "default";
33241
+ }
33171
33242
  function keyFor(providerID, modelID, agentName) {
33172
- const agent = agentName && agentName.length > 0 ? agentName : "default";
33173
- return `${providerID}/${modelID}/${agent}`;
33243
+ return `${providerID}/${modelID}/${agentKey(agentName)}`;
33244
+ }
33245
+ function routeFor(providerID, modelID, agentName) {
33246
+ const key = keyFor(providerID, modelID, agentName);
33247
+ let route = routes.get(key);
33248
+ if (!route) {
33249
+ route = {
33250
+ providerID,
33251
+ modelID,
33252
+ agentName: agentKey(agentName),
33253
+ tools: new Map,
33254
+ live: false,
33255
+ clock: 0,
33256
+ lastWallAt: Date.now(),
33257
+ oldestFireAt: Number.POSITIVE_INFINITY,
33258
+ retired: new Map,
33259
+ legacyRows: new Set
33260
+ };
33261
+ routes.set(key, route);
33262
+ }
33263
+ return { key, route };
33264
+ }
33265
+ function advanceClock(route) {
33266
+ const now = Date.now();
33267
+ const gap = Math.min(Math.max(now - route.lastWallAt, 0), MAX_ACTIVITY_GAP_MS);
33268
+ route.clock += gap;
33269
+ route.lastWallAt = Math.max(route.lastWallAt, now);
33270
+ return route.clock;
33271
+ }
33272
+ function readWindowedSince(db) {
33273
+ try {
33274
+ const row = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(WINDOWED_SINCE_KEY);
33275
+ if (!row)
33276
+ return;
33277
+ const value = Number(row.value);
33278
+ return Number.isFinite(value) ? value : undefined;
33279
+ } catch {
33280
+ return;
33281
+ }
33282
+ }
33283
+ function markWindowed() {
33284
+ if (windowedSince !== undefined || !persistenceDb)
33285
+ return;
33286
+ try {
33287
+ persistenceDb.prepare("INSERT OR IGNORE INTO schema_migrations_meta (key, value) VALUES (?, ?)").run(WINDOWED_SINCE_KEY, String(boundAt));
33288
+ windowedSince = readWindowedSince(persistenceDb);
33289
+ } catch {}
33174
33290
  }
33175
33291
  function setDatabase(db) {
33292
+ const rebound = persistenceDb !== null && persistenceDb !== db;
33176
33293
  persistenceDb = db;
33294
+ boundAt = Date.now();
33177
33295
  cachedInsertStmt = null;
33296
+ cachedDeleteStmt = null;
33297
+ if (rebound) {
33298
+ for (const route of routes.values()) {
33299
+ for (const slot of route.tools.values()) {
33300
+ slot.persisted = false;
33301
+ slot.writeFailedAt = undefined;
33302
+ }
33303
+ for (const retired of route.retired.values())
33304
+ retired.rowKept = false;
33305
+ route.legacyRows.clear();
33306
+ }
33307
+ }
33308
+ windowedSince = readWindowedSince(db);
33309
+ if (windowedSince !== undefined)
33310
+ return;
33311
+ try {
33312
+ if (!db.prepare("SELECT 1 FROM tool_definition_measurements LIMIT 1").get())
33313
+ markWindowed();
33314
+ } catch {}
33178
33315
  }
33179
33316
  function loadToolDefinitionMeasurements(db) {
33180
33317
  let rows = [];
33181
33318
  try {
33182
- rows = db.prepare("SELECT provider_id, model_id, agent_name, tool_id, token_count FROM tool_definition_measurements").all();
33319
+ rows = db.prepare("SELECT provider_id, model_id, agent_name, tool_id, token_count, recorded_at FROM tool_definition_measurements").all();
33183
33320
  } catch {
33184
33321
  return;
33185
33322
  }
33323
+ const since = readWindowedSince(db);
33324
+ const loadedAt = new Map;
33186
33325
  for (const row of rows) {
33187
- const key = keyFor(row.provider_id, row.model_id, row.agent_name);
33188
- let inner = measurements.get(key);
33189
- if (!inner) {
33190
- inner = new Map;
33191
- measurements.set(key, inner);
33192
- }
33193
- inner.set(row.tool_id, row.token_count);
33326
+ const { route } = routeFor(row.provider_id, row.model_id, row.agent_name);
33327
+ if (route.live)
33328
+ continue;
33329
+ let now = loadedAt.get(route);
33330
+ if (now === undefined) {
33331
+ now = advanceClock(route);
33332
+ loadedAt.set(route, now);
33333
+ }
33334
+ const legacy = since === undefined || !(Number(row.recorded_at) >= since);
33335
+ route.tools.set(row.tool_id, {
33336
+ tokens: row.token_count,
33337
+ fingerprint: undefined,
33338
+ lastFireAt: now,
33339
+ legacy,
33340
+ persisted: !legacy
33341
+ });
33342
+ route.oldestFireAt = Math.min(route.oldestFireAt, now);
33343
+ if (legacy)
33344
+ route.legacyRows.add(row.tool_id);
33345
+ else
33346
+ route.legacyRows.delete(row.tool_id);
33194
33347
  }
33195
33348
  }
33196
- var measurements, fingerprints, persistenceDb = null, cachedInsertStmt = null;
33349
+ var ACTIVITY_WINDOW_MS, MAX_ACTIVITY_GAP_MS = 60000, WINDOWED_SINCE_KEY = "tool_definition_measurements:windowed_since", routes, sessionFlights, persistenceDb = null, windowedSince, boundAt = 0, cachedInsertStmt = null, cachedDeleteStmt = null;
33197
33350
  var init_tool_definition_tokens = __esm(() => {
33198
33351
  init_read_session_formatting();
33199
- measurements = new Map;
33200
- fingerprints = new Map;
33352
+ ACTIVITY_WINDOW_MS = 10 * 60000;
33353
+ routes = new Map;
33354
+ sessionFlights = new BoundedSessionMap(1000);
33201
33355
  });
33202
33356
 
33203
33357
  // ../plugin/src/features/magic-context/tool-owner-backfill.ts
@@ -34245,6 +34399,73 @@ var init_historian_tool_expansions = __esm(() => {
34245
34399
  init_historian_tool_template();
34246
34400
  });
34247
34401
 
34402
+ // ../plugin/src/hooks/magic-context/ask-answer-notice.ts
34403
+ function reminderBodies(text) {
34404
+ reminderEnvelopePattern.lastIndex = 0;
34405
+ const bodies = [];
34406
+ for (const match of text.matchAll(reminderEnvelopePattern)) {
34407
+ const body = match[1];
34408
+ if (body !== undefined)
34409
+ bodies.push(body);
34410
+ }
34411
+ return bodies;
34412
+ }
34413
+ function parseAnswerBody(body) {
34414
+ const lines = body.replace(/\r\n/g, `
34415
+ `).replace(/^\n+|\n+$/g, "");
34416
+ if (!ANSWER_HEADER_PREFIX.test(lines))
34417
+ return null;
34418
+ if (lines.includes("The user dismissed this question"))
34419
+ return null;
34420
+ const framed = ANSWER_TRAILER.exec(lines);
34421
+ if (framed === null)
34422
+ return null;
34423
+ const content = framed[1] ?? "";
34424
+ const narrated = ANSWER_ANSWER_LINE.exec(content);
34425
+ if (narrated !== null) {
34426
+ const question = narrated[2] ?? "";
34427
+ const answer = content.slice(narrated[0].length);
34428
+ return closedAnswer(question, answer);
34429
+ }
34430
+ const bare = ANSWER_QUESTION_LINE.exec(content);
34431
+ if (bare !== null) {
34432
+ const question = bare[1] ?? "";
34433
+ const answer = content.slice(bare[0].length);
34434
+ return closedAnswer(question, answer);
34435
+ }
34436
+ return null;
34437
+ }
34438
+ function closedAnswer(question, answer) {
34439
+ if (question.trim().length === 0)
34440
+ return null;
34441
+ if (answer.trim().length === 0)
34442
+ return null;
34443
+ return { question, answer };
34444
+ }
34445
+ function extractAskAnswerNotices(text) {
34446
+ const notices = [];
34447
+ for (const body of reminderBodies(text)) {
34448
+ const notice = parseAnswerBody(body);
34449
+ if (notice !== null)
34450
+ notices.push(notice);
34451
+ }
34452
+ return notices;
34453
+ }
34454
+ function formatAskAnswerNotice(notice) {
34455
+ return `U (answered "${notice.question}"): ${notice.answer}`;
34456
+ }
34457
+ function askAnswerLines(text) {
34458
+ return extractAskAnswerNotices(text).map(formatAskAnswerNotice);
34459
+ }
34460
+ var ANSWER_HEADER_PREFIX, ANSWER_TRAILER, ANSWER_ANSWER_LINE, ANSWER_QUESTION_LINE, reminderEnvelopePattern;
34461
+ var init_ask_answer_notice = __esm(() => {
34462
+ ANSWER_HEADER_PREFIX = /^Inbox [^\n]* notice from user via user_answer \(user_answer\)/;
34463
+ ANSWER_TRAILER = /\n([\s\S]*?)\nThis ask is now closed; no dismiss is needed\. Continue accordingly\.$/;
34464
+ ANSWER_ANSWER_LINE = /^The user answered your parked question (\S+)\.\nQuestion: ([^\n]+)\nAnswer: /;
34465
+ ANSWER_QUESTION_LINE = /^Question: ([^\n]+)\nAnswer: /;
34466
+ reminderEnvelopePattern = /<system-reminder>([\s\S]*?)<\/system-reminder>/gi;
34467
+ });
34468
+
34248
34469
  // ../plugin/src/hooks/magic-context/host-served-rows.ts
34249
34470
  function markHostUnservedRow(target) {
34250
34471
  Object.defineProperty(target, HOST_UNSERVED_ROW, {
@@ -34939,6 +35160,9 @@ function withRawMessageProvider(sessionId, provider, fn) {
34939
35160
  function cleanUserText(text) {
34940
35161
  return stripOutsideSteeringWrappers(text, (segment) => removeSystemReminders(segment).replace(OMO_INTERNAL_INITIATOR_MARKER, "")).trim();
34941
35162
  }
35163
+ function answerLineParts(rawText) {
35164
+ return askAnswerLines(rawText).map(normalizeText).filter((value) => value.length > 0);
35165
+ }
34942
35166
  function hasMeaningfulChunkUserText(parts) {
34943
35167
  for (const part of parts) {
34944
35168
  if (part === null || typeof part !== "object")
@@ -34955,7 +35179,7 @@ function hasMeaningfulChunkUserText(parts) {
34955
35179
  continue;
34956
35180
  return true;
34957
35181
  }
34958
- return false;
35182
+ return parts.some((part) => part !== null && typeof part === "object" && part.type === "text" && typeof part.text === "string" && part.ignored !== true && askAnswerLines(part.text).length > 0);
34959
35183
  }
34960
35184
  function withRawSessionMessageCache(fn) {
34961
35185
  const outerCache = activeRawMessageCache;
@@ -35701,8 +35925,10 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
35701
35925
  }
35702
35926
  const role = compactRole(msg.role);
35703
35927
  const textParts = extractTexts(msg.parts).map((t) => msg.role === "user" ? cleanUserText(t) : t).map(normalizeText).filter((value) => value.length > 0);
35928
+ const answerParts = msg.role === "user" ? extractTexts(msg.parts).flatMap((text) => answerLineParts(text)) : [];
35929
+ const userParts = answerParts.length > 0 ? [...textParts, ...answerParts] : textParts;
35704
35930
  const allParts = options.expand === false ? [
35705
- ...textParts,
35931
+ ...userParts,
35706
35932
  ...textParts.length === 0 ? extractToolCallSummaries(msg.parts) : []
35707
35933
  ] : msg.parts.flatMap((part) => {
35708
35934
  if (expandedResults.has(part))
@@ -35711,6 +35937,9 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
35711
35937
  if (expansion !== null)
35712
35938
  return [`TC: ${expansion}`];
35713
35939
  const texts = extractTexts([part]).map((t) => msg.role === "user" ? cleanUserText(t) : t).map(normalizeText).filter(Boolean);
35940
+ if (msg.role === "user") {
35941
+ texts.push(...extractTexts([part]).flatMap((text) => answerLineParts(text)));
35942
+ }
35714
35943
  return texts.length ? texts : textParts.length === 0 ? extractToolCallSummaries([part]) : [];
35715
35944
  });
35716
35945
  const compacted = compactTextForSummary(allParts.join(" / "), msg.role);
@@ -35719,7 +35948,7 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
35719
35948
  recordFilteredNoise(meta);
35720
35949
  continue;
35721
35950
  }
35722
- const msgHasNarrative = textParts.length > 0;
35951
+ const msgHasNarrative = userParts.length > 0;
35723
35952
  if (currentBlock && currentBlock.role === role) {
35724
35953
  currentBlock.endOrdinal = msg.ordinal;
35725
35954
  currentBlock.parts.push(text);
@@ -35824,6 +36053,7 @@ var BLOCK_TOKEN_MEMO_MAX = 2048, blockTokenMemo, activeRawMessageCache = null, a
35824
36053
  var init_read_session_chunk = __esm(async () => {
35825
36054
  init_historian_tool_expansions();
35826
36055
  init_logger();
36056
+ init_ask_answer_notice();
35827
36057
  init_read_session_formatting();
35828
36058
  init_read_session_true_raw_tokens();
35829
36059
  init_system_injection_stripper();
@@ -52462,8 +52692,8 @@ async function runIssueFlow2(options = {}, deps = { collectDiagnostics }) {
52462
52692
  return 1;
52463
52693
  }
52464
52694
  }
52465
- function checkLocalEmbeddingRuntimeForDoctor(runtimePreference = "auto") {
52466
- const runtime = checkLocalEmbeddingRuntime(getOpenCodePluginCacheRoots(), process.platform, process.arch, runtimePreference);
52695
+ function checkLocalEmbeddingRuntimeForDoctor(installRoots, runtimePreference = "auto") {
52696
+ const runtime = checkLocalEmbeddingRuntime(installRoots, process.platform, process.arch, runtimePreference);
52467
52697
  if (runtime.state === "wasm-selected") {
52468
52698
  log3.warn(formatLocalEmbeddingRuntimeWasmSelected(runtime));
52469
52699
  return { issues: 0 };
@@ -52483,15 +52713,15 @@ function checkLocalEmbeddingRuntimeForDoctor(runtimePreference = "auto") {
52483
52713
  log3.success("Embedding provider: local (native runtime selected and OK; Xenova/all-MiniLM-L6-v2 bundled)");
52484
52714
  return { issues: 0 };
52485
52715
  }
52486
- async function checkEmbeddingConfig(magicContextConfigPath) {
52716
+ async function checkEmbeddingConfig(magicContextConfigPath, installRoots) {
52487
52717
  if (!existsSync49(magicContextConfigPath)) {
52488
- return checkLocalEmbeddingRuntimeForDoctor();
52718
+ return checkLocalEmbeddingRuntimeForDoctor(installRoots);
52489
52719
  }
52490
52720
  let rawText;
52491
52721
  try {
52492
52722
  const raw = loadRawConfigFile({ configPath: magicContextConfigPath, tier: "user" });
52493
52723
  if (!raw)
52494
- return checkLocalEmbeddingRuntimeForDoctor();
52724
+ return checkLocalEmbeddingRuntimeForDoctor(installRoots);
52495
52725
  rawText = raw.text;
52496
52726
  } catch {
52497
52727
  log3.warn("Could not read magic-context.jsonc for embedding check");
@@ -52516,7 +52746,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
52516
52746
  }
52517
52747
  if (provider === undefined || provider === "local") {
52518
52748
  const runtimePreference = embedding?.local_runtime === "native" || embedding?.local_runtime === "wasm" ? embedding.local_runtime : "auto";
52519
- return checkLocalEmbeddingRuntimeForDoctor(runtimePreference);
52749
+ return checkLocalEmbeddingRuntimeForDoctor(installRoots, runtimePreference);
52520
52750
  }
52521
52751
  if (provider === "synapse") {
52522
52752
  const loaded = loadPluginConfig(process.cwd());
@@ -53195,7 +53425,16 @@ async function runDoctor2(options = {}) {
53195
53425
  }
53196
53426
  } catch {}
53197
53427
  }
53198
- const embeddingCheck = await checkEmbeddingConfig(paths.magicContextConfig);
53428
+ let embeddingHostConfig = null;
53429
+ try {
53430
+ if (paths.opencodeConfigFormat !== "none")
53431
+ embeddingHostConfig = import_comment_json11.parse(readFileSync32(paths.opencodeConfig, "utf-8"));
53432
+ } catch {}
53433
+ const embeddingInstalls = getOpenCodeLoadedPluginInstallRoots(hostGeneration, embeddingHostConfig);
53434
+ const unusedInstalls = embeddingInstalls.others.filter((root) => existsSync49(root));
53435
+ if (unusedInstalls.length > 0)
53436
+ log3.info(`Local embedding runtime: checked only the copy ${hostGeneration === "v2" ? "OpenCode 2" : "OpenCode 1"} loads; other installed copies (not loaded, not checked): ${unusedInstalls.join(", ")}`);
53437
+ const embeddingCheck = await checkEmbeddingConfig(paths.magicContextConfig, embeddingInstalls.loaded);
53199
53438
  issues += embeddingCheck.issues;
53200
53439
  if (embeddingCheck.issues > 0)
53201
53440
  failCount += embeddingCheck.issues;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/magic-context",
3
- "version": "0.49.23",
3
+ "version": "0.49.25",
4
4
  "description": "Unified CLI for Magic Context — setup, doctor, and migration across OpenCode, Pi, and OMP",
5
5
  "keywords": [
6
6
  "opencode",