@cortexkit/opencode-magic-context 0.15.2 → 0.15.4

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 (51) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +12 -2
  3. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  4. package/dist/features/magic-context/resolve-subagent-fallback.d.ts +40 -0
  5. package/dist/features/magic-context/resolve-subagent-fallback.d.ts.map +1 -0
  6. package/dist/features/magic-context/storage-meta-persisted.d.ts +7 -0
  7. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  8. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  9. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  10. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  11. package/dist/features/magic-context/storage.d.ts +1 -1
  12. package/dist/features/magic-context/storage.d.ts.map +1 -1
  13. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  14. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/compartment-runner-types.d.ts +13 -0
  16. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  17. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  18. package/dist/hooks/magic-context/hook-handlers.d.ts +71 -2
  19. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/hook.d.ts +3 -0
  21. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/live-session-state.d.ts +19 -0
  23. package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/system-prompt-hash.d.ts +17 -1
  25. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  26. package/dist/hooks/magic-context/tokenizer-calibration.d.ts +85 -0
  27. package/dist/hooks/magic-context/tokenizer-calibration.d.ts.map +1 -0
  28. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +4 -0
  29. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +8 -1
  31. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/transform.d.ts +17 -1
  33. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  34. package/dist/index.js +396 -51
  35. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  36. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  37. package/dist/plugin/sidebar-snapshot-cache.d.ts +19 -0
  38. package/dist/plugin/sidebar-snapshot-cache.d.ts.map +1 -0
  39. package/dist/shared/conflict-detector.d.ts.map +1 -1
  40. package/dist/shared/rpc-types.d.ts +0 -9
  41. package/dist/shared/rpc-types.d.ts.map +1 -1
  42. package/dist/tui/data/context-db.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/src/shared/conflict-detector.test.ts +189 -0
  45. package/src/shared/conflict-detector.ts +68 -7
  46. package/src/shared/rpc-types.ts +0 -9
  47. package/src/tui/data/context-db.ts +66 -4
  48. package/src/tui/index.tsx +0 -3
  49. package/src/tui/slots/sidebar-content.tsx +0 -15
  50. package/dist/plugin/tui-action-consumer.d.ts +0 -15
  51. package/dist/plugin/tui-action-consumer.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -147829,7 +147829,15 @@ function readUserCompaction() {
147829
147829
  }
147830
147830
  function checkDcpPlugin(directory) {
147831
147831
  const plugins = collectPluginEntries(directory);
147832
- return plugins.some((p) => p.includes("opencode-dcp"));
147832
+ return plugins.some((p) => matchesPackageName(p, DCP_PACKAGE_NAMES));
147833
+ }
147834
+ function matchesPackageName(entry, canonicalNames) {
147835
+ if (entry.startsWith("file:") || entry.startsWith("http:") || entry.startsWith("https:") || entry.startsWith("/") || entry.startsWith("./") || entry.startsWith("../")) {
147836
+ return false;
147837
+ }
147838
+ const lastAt = entry.lastIndexOf("@");
147839
+ const nameOnly = lastAt > 0 ? entry.slice(0, lastAt) : entry;
147840
+ return canonicalNames.has(nameOnly);
147833
147841
  }
147834
147842
  function collectPluginEntries(directory) {
147835
147843
  const plugins = [];
@@ -147862,7 +147870,7 @@ function checkOmoHooks(directory) {
147862
147870
  anthropicRecovery: false
147863
147871
  };
147864
147872
  const plugins = collectPluginEntries(directory);
147865
- const hasOmo = plugins.some((p) => p.includes("oh-my-opencode") || p.includes("oh-my-openagent") || p.includes("@code-yeongyu/"));
147873
+ const hasOmo = plugins.some((p) => matchesPackageName(p, OMO_PACKAGE_NAMES));
147866
147874
  if (!hasOmo)
147867
147875
  return result;
147868
147876
  const disabledHooks = readOmoDisabledHooks(directory);
@@ -147914,9 +147922,12 @@ function formatConflictShort(result) {
147914
147922
  return lines.join(`
147915
147923
  `);
147916
147924
  }
147925
+ var DCP_PACKAGE_NAMES, OMO_PACKAGE_NAMES;
147917
147926
  var init_conflict_detector = __esm(() => {
147918
147927
  init_jsonc_parser();
147919
147928
  init_opencode_config_dir();
147929
+ DCP_PACKAGE_NAMES = new Set(["@tarquinen/opencode-dcp"]);
147930
+ OMO_PACKAGE_NAMES = new Set(["oh-my-opencode", "oh-my-openagent"]);
147920
147931
  });
147921
147932
 
147922
147933
  // src/plugin/conflict-warning-hook.ts
@@ -149462,7 +149473,21 @@ class OpenAICompatibleEmbeddingProvider {
149462
149473
  this.recordFailure(isProbe);
149463
149474
  return Array.from({ length: texts.length }, () => null);
149464
149475
  }
149465
- const body = await response.json();
149476
+ const rawBody = await response.text();
149477
+ if (rawBody.trim().length === 0) {
149478
+ log(`[magic-context] openai-compatible embedding request returned empty body (status=${response.status}, content-type=${response.headers.get("content-type") ?? "none"})`);
149479
+ this.recordFailure(isProbe);
149480
+ return Array.from({ length: texts.length }, () => null);
149481
+ }
149482
+ let body;
149483
+ try {
149484
+ body = JSON.parse(rawBody);
149485
+ } catch (parseError) {
149486
+ const snippet = rawBody.slice(0, 200).replace(/\s+/g, " ");
149487
+ log(`[magic-context] openai-compatible embedding response was not JSON (status=${response.status}, ${rawBody.length}B body, snippet="${snippet}"):`, parseError instanceof Error ? parseError.message : parseError);
149488
+ this.recordFailure(isProbe);
149489
+ return Array.from({ length: texts.length }, () => null);
149490
+ }
149466
149491
  const items = Array.isArray(body.data) ? body.data : [];
149467
149492
  const results = Array.from({ length: texts.length }, (_, index) => {
149468
149493
  const embedding = items[index]?.embedding;
@@ -151291,6 +151316,14 @@ function recordOverflowDetected(db, sessionId, reportedLimit) {
151291
151316
  }
151292
151317
  })();
151293
151318
  }
151319
+ function recordDetectedContextLimit(db, sessionId, reportedLimit) {
151320
+ if (!(reportedLimit > 0))
151321
+ return;
151322
+ db.transaction(() => {
151323
+ ensureSessionMetaRow(db, sessionId);
151324
+ db.prepare("UPDATE session_meta SET detected_context_limit = ? WHERE session_id = ?").run(reportedLimit, sessionId);
151325
+ })();
151326
+ }
151294
151327
  function clearEmergencyRecovery(db, sessionId) {
151295
151328
  db.transaction(() => {
151296
151329
  ensureSessionMetaRow(db, sessionId);
@@ -151351,6 +151384,25 @@ var init_storage_meta_persisted = __esm(() => {
151351
151384
  init_storage_meta_shared();
151352
151385
  });
151353
151386
 
151387
+ // src/features/magic-context/resolve-subagent-fallback.ts
151388
+ function resolveIsSubagentFromOpenCodeDb(sessionId) {
151389
+ try {
151390
+ return withReadOnlySessionDb((openCodeDb) => {
151391
+ const row = openCodeDb.prepare("SELECT parent_id FROM session WHERE id = ?").get(sessionId);
151392
+ if (!row)
151393
+ return null;
151394
+ return typeof row.parent_id === "string" && row.parent_id.length > 0;
151395
+ });
151396
+ } catch (error48) {
151397
+ log(`[magic-context] resolveIsSubagentFromOpenCodeDb failed for ${sessionId}:`, error48);
151398
+ return null;
151399
+ }
151400
+ }
151401
+ var init_resolve_subagent_fallback = __esm(() => {
151402
+ init_read_session_db();
151403
+ init_logger();
151404
+ });
151405
+
151354
151406
  // src/features/magic-context/storage-meta-session.ts
151355
151407
  function getOrCreateSessionMeta(db, sessionId) {
151356
151408
  const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag FROM session_meta WHERE session_id = ?").get(sessionId);
@@ -151358,7 +151410,14 @@ function getOrCreateSessionMeta(db, sessionId) {
151358
151410
  return toSessionMeta(result);
151359
151411
  }
151360
151412
  const defaults = getDefaultSessionMeta(sessionId);
151413
+ const fallbackSubagent = resolveIsSubagentFromOpenCodeDb(sessionId);
151414
+ if (fallbackSubagent === true) {
151415
+ defaults.isSubagent = true;
151416
+ }
151361
151417
  ensureSessionMetaRow(db, sessionId);
151418
+ if (fallbackSubagent === true) {
151419
+ db.prepare("UPDATE session_meta SET is_subagent = 1 WHERE session_id = ?").run(sessionId);
151420
+ }
151362
151421
  return defaults;
151363
151422
  }
151364
151423
  function updateSessionMeta(db, sessionId, updates) {
@@ -151406,6 +151465,7 @@ function clearSession(db, sessionId) {
151406
151465
  var init_storage_meta_session = __esm(() => {
151407
151466
  init_compression_depth_storage();
151408
151467
  init_message_index();
151468
+ init_resolve_subagent_fallback();
151409
151469
  init_storage_meta_shared();
151410
151470
  });
151411
151471
 
@@ -154552,7 +154612,7 @@ No new compartments or facts were written. Check the historian model/output and
154552
154612
  })();
154553
154613
  clearInjectionCache(sessionId);
154554
154614
  deps.onInjectionCacheCleared?.(sessionId);
154555
- if (deps.directory) {
154615
+ if (deps.directory && deps.memoryEnabled !== false && deps.autoPromote !== false) {
154556
154616
  promoteSessionFactsToMemory(db, sessionId, resolveProjectIdentity(deps.directory), validatedPass.facts ?? []);
154557
154617
  }
154558
154618
  const lastCompartmentEnd = lastNewEnd;
@@ -154658,7 +154718,7 @@ async function executeContextRecompInternal(deps) {
154658
154718
  clearCompressionDepth(db, sessionId);
154659
154719
  clearInjectionCache(sessionId);
154660
154720
  deps.onInjectionCacheCleared?.(sessionId);
154661
- if (deps.directory) {
154721
+ if (deps.directory && deps.memoryEnabled !== false && deps.autoPromote !== false) {
154662
154722
  promoteSessionFactsToMemory(db, sessionId, resolveProjectIdentity(deps.directory), promoted2.facts);
154663
154723
  }
154664
154724
  const lastCompartmentEnd2 = promoted2.compartments[promoted2.compartments.length - 1]?.endMessage ?? 0;
@@ -154829,7 +154889,7 @@ Nothing was written.`;
154829
154889
  deps.onInjectionCacheCleared?.(sessionId);
154830
154890
  const finalCompartments = promoted?.compartments ?? candidateCompartments;
154831
154891
  const finalFacts = promoted?.facts ?? candidateFacts;
154832
- if (deps.directory) {
154892
+ if (deps.directory && deps.memoryEnabled !== false && deps.autoPromote !== false) {
154833
154893
  promoteSessionFactsToMemory(db, sessionId, resolveProjectIdentity(deps.directory), finalFacts);
154834
154894
  }
154835
154895
  const lastCompartmentEnd = finalCompartments[finalCompartments.length - 1]?.endMessage ?? 0;
@@ -163561,7 +163621,10 @@ function createLiveSessionState() {
163561
163621
  return {
163562
163622
  liveModelBySession: new Map,
163563
163623
  variantBySession: new Map,
163564
- agentBySession: new Map
163624
+ agentBySession: new Map,
163625
+ historyRefreshSessions: new Set,
163626
+ systemPromptRefreshSessions: new Set,
163627
+ pendingMaterializationSessions: new Set
163565
163628
  };
163566
163629
  }
163567
163630
 
@@ -167438,6 +167501,8 @@ async function runCompartmentPhase(args) {
167438
167501
  historianTwoPass: args.historianTwoPass,
167439
167502
  compressorMinCompartmentRatio: args.compressorMinCompartmentRatio,
167440
167503
  compressorMaxMergeDepth: args.compressorMaxMergeDepth,
167504
+ memoryEnabled: args.memoryEnabled,
167505
+ autoPromote: args.autoPromote,
167441
167506
  onInjectionCacheCleared: args.onInjectionCacheCleared
167442
167507
  });
167443
167508
  compartmentInProgress = true;
@@ -167463,6 +167528,8 @@ async function runCompartmentPhase(args) {
167463
167528
  historianTwoPass: args.historianTwoPass,
167464
167529
  compressorMinCompartmentRatio: args.compressorMinCompartmentRatio,
167465
167530
  compressorMaxMergeDepth: args.compressorMaxMergeDepth,
167531
+ memoryEnabled: args.memoryEnabled,
167532
+ autoPromote: args.autoPromote,
167466
167533
  onInjectionCacheCleared: args.onInjectionCacheCleared
167467
167534
  });
167468
167535
  activeRun = getActiveCompartmentRun(args.sessionId);
@@ -169227,7 +169294,7 @@ function logTransformTiming(sessionId, stage, startMs, extra) {
169227
169294
  // src/hooks/magic-context/transform-postprocess-phase.ts
169228
169295
  async function runPostTransformPhase(args) {
169229
169296
  let didMutateFromPendingOperations = false;
169230
- const isExplicitFlush = args.flushedSessions.has(args.sessionId);
169297
+ const isExplicitFlush = args.pendingMaterializationSessions.has(args.sessionId);
169231
169298
  const alreadyRanThisTurn = args.currentTurnId !== null && args.lastHeuristicsTurnId.get(args.sessionId) === args.currentTurnId;
169232
169299
  const forceMaterialization = args.fullFeatureMode && args.contextUsage.percentage >= args.forceMaterializationPercentage;
169233
169300
  const activeCompartmentRun = args.canRunCompartments ? getActiveCompartmentRun(args.sessionId) : undefined;
@@ -169237,8 +169304,8 @@ async function runPostTransformPhase(args) {
169237
169304
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
169238
169305
  const hasPendingUserOps = pendingOps.length > 0;
169239
169306
  const shouldApplyPendingOps = (args.schedulerDecision === "execute" || isExplicitFlush || forceMaterialization) && (!compartmentRunning || emergencyBypassCompartmentGate);
169240
- const isCacheBustingPass = isExplicitFlush || shouldApplyPendingOps;
169241
169307
  const shouldRunHeuristics = (!compartmentRunning || emergencyBypassCompartmentGate) && (isExplicitFlush || forceMaterialization || args.schedulerDecision === "execute" && !alreadyRanThisTurn);
169308
+ const isCacheBustingPass = shouldApplyPendingOps || shouldRunHeuristics;
169242
169309
  if (shouldRunHeuristics) {
169243
169310
  const reason = isExplicitFlush ? "explicit_flush" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
169244
169311
  sessionLog(args.sessionId, `heuristics WILL RUN \u2014 reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=${args.currentTurnId}`);
@@ -169312,7 +169379,7 @@ async function runPostTransformPhase(args) {
169312
169379
  }
169313
169380
  }
169314
169381
  logTransformTiming(args.sessionId, "clearOldReasoning", t7);
169315
- args.flushedSessions.delete(args.sessionId);
169382
+ args.pendingMaterializationSessions.delete(args.sessionId);
169316
169383
  if (args.currentTurnId) {
169317
169384
  args.lastHeuristicsTurnId.set(args.sessionId, args.currentTurnId);
169318
169385
  }
@@ -169381,7 +169448,14 @@ async function runPostTransformPhase(args) {
169381
169448
  }
169382
169449
  }
169383
169450
  }
169384
- const pendingUserTurnReminder = getPersistedStickyTurnReminder(args.db, args.sessionId);
169451
+ const pendingUserTurnReminder = args.fullFeatureMode ? getPersistedStickyTurnReminder(args.db, args.sessionId) : null;
169452
+ if (!args.fullFeatureMode && isCacheBustingPass) {
169453
+ const stale = getPersistedStickyTurnReminder(args.db, args.sessionId);
169454
+ if (stale) {
169455
+ clearPersistedStickyTurnReminder(args.db, args.sessionId);
169456
+ sessionLog(args.sessionId, "sticky turn reminder cleared \u2014 subagent should not have this state (cache-busting pass)");
169457
+ }
169458
+ }
169385
169459
  if (pendingUserTurnReminder) {
169386
169460
  if (args.hasRecentReduceCall && isCacheBustingPass) {
169387
169461
  clearPersistedStickyTurnReminder(args.db, args.sessionId);
@@ -169634,7 +169708,7 @@ function createTransform(deps) {
169634
169708
  }
169635
169709
  const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens);
169636
169710
  const schedulerDecisionEarly = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId));
169637
- const isCacheBusting = deps.flushedSessions.has(sessionId);
169711
+ const isCacheBusting = deps.historyRefreshSessions.has(sessionId);
169638
169712
  if (historianFailureState.failureCount === 0) {
169639
169713
  lastEmergencyNotificationCount.delete(sessionId);
169640
169714
  }
@@ -169671,8 +169745,11 @@ function createTransform(deps) {
169671
169745
  historianTwoPass: deps.historianTwoPass,
169672
169746
  compressorMinCompartmentRatio: deps.compressorMinCompartmentRatio,
169673
169747
  compressorMaxMergeDepth: deps.compressorMaxMergeDepth,
169748
+ memoryEnabled: deps.memoryConfig?.enabled,
169749
+ autoPromote: deps.memoryConfig?.autoPromote,
169674
169750
  onInjectionCacheCleared: (sid) => {
169675
- deps.flushedSessions.add(sid);
169751
+ deps.historyRefreshSessions.add(sid);
169752
+ deps.pendingMaterializationSessions.add(sid);
169676
169753
  }
169677
169754
  });
169678
169755
  skipCompartmentAwaitForThisPass = true;
@@ -169709,6 +169786,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
169709
169786
  const tInj = performance.now();
169710
169787
  pendingCompartmentInjection = prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectIdentity, deps.memoryConfig?.injectionBudgetTokens, deps.experimentalTemporalAwareness);
169711
169788
  logTransformTiming(sessionId, "prepareCompartmentInjection", tInj);
169789
+ if (isCacheBusting) {
169790
+ deps.historyRefreshSessions.delete(sessionId);
169791
+ }
169712
169792
  }
169713
169793
  let targets = new Map;
169714
169794
  let reasoningByMessage = new Map;
@@ -169738,7 +169818,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
169738
169818
  hasRecentReduceCall = result.hasRecentReduceCall;
169739
169819
  const hadPriorCommitState = deps.commitSeenLastPass?.has(sessionId) ?? false;
169740
169820
  const sawCommitLastPass = deps.commitSeenLastPass?.get(sessionId) ?? false;
169741
- if (hadPriorCommitState && result.hasRecentCommit && !sawCommitLastPass) {
169821
+ if (fullFeatureMode && hadPriorCommitState && result.hasRecentCommit && !sawCommitLastPass) {
169742
169822
  onNoteTrigger(db, sessionId, "commit_detected");
169743
169823
  }
169744
169824
  deps.commitSeenLastPass?.set(sessionId, result.hasRecentCommit);
@@ -169834,8 +169914,11 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
169834
169914
  compressorMinCompartmentRatio: deps.compressorMinCompartmentRatio,
169835
169915
  compressorMaxMergeDepth: deps.compressorMaxMergeDepth,
169836
169916
  compressorCooldownMs: deps.compressorCooldownMs,
169917
+ memoryEnabled: deps.memoryConfig?.enabled,
169918
+ autoPromote: deps.memoryConfig?.autoPromote,
169837
169919
  onInjectionCacheCleared: (sid) => {
169838
- deps.flushedSessions.add(sid);
169920
+ deps.historyRefreshSessions.add(sid);
169921
+ deps.pendingMaterializationSessions.add(sid);
169839
169922
  }
169840
169923
  });
169841
169924
  pendingCompartmentInjection = compartmentPhase.pendingCompartmentInjection;
@@ -169861,7 +169944,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
169861
169944
  compartmentInProgress,
169862
169945
  sessionMeta,
169863
169946
  currentTurnId,
169864
- flushedSessions: deps.flushedSessions,
169947
+ pendingMaterializationSessions: deps.pendingMaterializationSessions,
169865
169948
  lastHeuristicsTurnId: deps.lastHeuristicsTurnId,
169866
169949
  autoDropToolAge: deps.autoDropToolAge,
169867
169950
  dropToolStructure: deps.dropToolStructure ?? true,
@@ -170107,6 +170190,14 @@ function createEventHandler2(deps) {
170107
170190
  if (!detection.isOverflow) {
170108
170191
  return;
170109
170192
  }
170193
+ const sessionMeta = getOrCreateSessionMeta(deps.db, errInfo.sessionID);
170194
+ if (sessionMeta.isSubagent) {
170195
+ if (typeof detection.reportedLimit === "number" && detection.reportedLimit > 0) {
170196
+ recordDetectedContextLimit(deps.db, errInfo.sessionID, detection.reportedLimit);
170197
+ }
170198
+ sessionLog(errInfo.sessionID, `overflow detected on subagent: reportedLimit=${detection.reportedLimit ?? "unknown"} pattern=${detection.matchedPattern ?? "n/a"} \u2014 recorded limit only (subagents cannot run historian)`);
170199
+ return;
170200
+ }
170110
170201
  const existing = getOverflowState(deps.db, errInfo.sessionID);
170111
170202
  recordOverflowDetected(deps.db, errInfo.sessionID, detection.reportedLimit);
170112
170203
  sessionLog(errInfo.sessionID, `overflow detected via session.error: reportedLimit=${detection.reportedLimit ?? "unknown"} pattern=${detection.matchedPattern ?? "n/a"} (previousRecovery=${existing.needsEmergencyRecovery})`);
@@ -170136,9 +170227,17 @@ function createEventHandler2(deps) {
170136
170227
  const detection = detectOverflow(info.error);
170137
170228
  if (detection.isOverflow) {
170138
170229
  try {
170139
- recordOverflowDetected(deps.db, info.sessionID, detection.reportedLimit);
170140
- sessionLog(info.sessionID, `overflow detected via message.updated: reportedLimit=${detection.reportedLimit ?? "unknown"} pattern=${detection.matchedPattern ?? "n/a"}`);
170141
- deps.onSessionCacheInvalidated?.(info.sessionID);
170230
+ const metaForOverflow = getOrCreateSessionMeta(deps.db, info.sessionID);
170231
+ if (metaForOverflow.isSubagent) {
170232
+ if (typeof detection.reportedLimit === "number" && detection.reportedLimit > 0) {
170233
+ recordDetectedContextLimit(deps.db, info.sessionID, detection.reportedLimit);
170234
+ }
170235
+ sessionLog(info.sessionID, `overflow detected on subagent via message.updated: reportedLimit=${detection.reportedLimit ?? "unknown"} pattern=${detection.matchedPattern ?? "n/a"} \u2014 recorded limit only`);
170236
+ } else {
170237
+ recordOverflowDetected(deps.db, info.sessionID, detection.reportedLimit);
170238
+ sessionLog(info.sessionID, `overflow detected via message.updated: reportedLimit=${detection.reportedLimit ?? "unknown"} pattern=${detection.matchedPattern ?? "n/a"}`);
170239
+ deps.onSessionCacheInvalidated?.(info.sessionID);
170240
+ }
170142
170241
  } catch (error48) {
170143
170242
  sessionLog(info.sessionID, "event message.updated overflow persistence failed:", error48);
170144
170243
  }
@@ -170466,6 +170565,43 @@ init_compartment_runner();
170466
170565
  init_storage();
170467
170566
  init_storage_meta();
170468
170567
  init_storage_meta_persisted();
170568
+
170569
+ // src/plugin/sidebar-snapshot-cache.ts
170570
+ var MAX_CACHED_SESSIONS = 100;
170571
+ var STALE_SNAPSHOT_AGE_MS = 5 * 60 * 1000;
170572
+ var cache = new BoundedSessionMap(MAX_CACHED_SESSIONS);
170573
+ function applyStickySnapshotCache(sessionId, fresh) {
170574
+ const now = Date.now();
170575
+ if (fresh.inputTokens > 0) {
170576
+ cache.set(sessionId, { snapshot: fresh, cachedAt: now });
170577
+ return fresh;
170578
+ }
170579
+ const cached2 = cache.peek(sessionId);
170580
+ if (!cached2) {
170581
+ return fresh;
170582
+ }
170583
+ if (now - cached2.cachedAt > STALE_SNAPSHOT_AGE_MS) {
170584
+ cache.delete(sessionId);
170585
+ return fresh;
170586
+ }
170587
+ return {
170588
+ ...fresh,
170589
+ usagePercentage: cached2.snapshot.usagePercentage,
170590
+ inputTokens: cached2.snapshot.inputTokens,
170591
+ systemPromptTokens: cached2.snapshot.systemPromptTokens,
170592
+ compartmentTokens: cached2.snapshot.compartmentTokens,
170593
+ factTokens: cached2.snapshot.factTokens,
170594
+ memoryTokens: cached2.snapshot.memoryTokens,
170595
+ conversationTokens: cached2.snapshot.conversationTokens,
170596
+ toolCallTokens: cached2.snapshot.toolCallTokens,
170597
+ toolDefinitionTokens: cached2.snapshot.toolDefinitionTokens
170598
+ };
170599
+ }
170600
+ function clearSidebarSnapshotCache(sessionId) {
170601
+ cache.delete(sessionId);
170602
+ }
170603
+
170604
+ // src/hooks/magic-context/hook-handlers.ts
170469
170605
  init_logger();
170470
170606
  init_note_nudger();
170471
170607
  var TOOL_HEAVY_TURN_REMINDER_THRESHOLD = 5;
@@ -170509,7 +170645,9 @@ function createChatMessageHook(args) {
170509
170645
  }
170510
170646
  if (previousVariant !== undefined && input.variant !== undefined && previousVariant !== input.variant) {
170511
170647
  sessionLog(sessionId, `variant changed (${previousVariant} -> ${input.variant}), triggering flush`);
170512
- args.flushedSessions.add(sessionId);
170648
+ args.historyRefreshSessions.add(sessionId);
170649
+ args.systemPromptRefreshSessions.add(sessionId);
170650
+ args.pendingMaterializationSessions.add(sessionId);
170513
170651
  args.lastHeuristicsTurnId.delete(sessionId);
170514
170652
  }
170515
170653
  };
@@ -170545,11 +170683,14 @@ function createEventHook(args) {
170545
170683
  args.agentBySession.delete(sessionId);
170546
170684
  args.recentReduceBySession.delete(sessionId);
170547
170685
  args.toolUsageSinceUserTurn.delete(sessionId);
170548
- args.flushedSessions.delete(sessionId);
170686
+ args.historyRefreshSessions.delete(sessionId);
170687
+ args.systemPromptRefreshSessions.delete(sessionId);
170688
+ args.pendingMaterializationSessions.delete(sessionId);
170549
170689
  args.lastHeuristicsTurnId.delete(sessionId);
170550
170690
  args.commitSeenLastPass?.delete(sessionId);
170551
170691
  clearNoteNudgeState(args.db, sessionId);
170552
170692
  clearAutoSearchForSession(sessionId);
170693
+ clearSidebarSnapshotCache(sessionId);
170553
170694
  }
170554
170695
  };
170555
170696
  }
@@ -170579,7 +170720,10 @@ function createToolExecuteAfterHook(args) {
170579
170720
  const todoArgs = typedInput.args;
170580
170721
  const todos = todoArgs?.todos;
170581
170722
  if (Array.isArray(todos) && todos.length > 0 && todos.every((t) => t.status === "completed" || t.status === "cancelled")) {
170582
- onNoteTrigger(args.db, typedInput.sessionID, "todos_complete");
170723
+ const sessionMeta = getOrCreateSessionMeta(args.db, typedInput.sessionID);
170724
+ if (!sessionMeta.isSubagent) {
170725
+ onNoteTrigger(args.db, typedInput.sessionID, "todos_complete");
170726
+ }
170583
170727
  }
170584
170728
  }
170585
170729
  if (typedInput.tool === "ctx_note") {
@@ -170868,8 +171012,8 @@ function createSystemPromptHashHandler(deps) {
170868
171012
  output.system.push(guidance);
170869
171013
  sessionLog(sessionId, `injected ${detectedAgent ?? "generic"} guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession})`);
170870
171014
  }
170871
- const isCacheBusting = deps.flushedSessions.has(sessionId);
170872
- if (shouldInjectDocs) {
171015
+ const isCacheBusting = deps.systemPromptRefreshSessions.has(sessionId);
171016
+ if (shouldInjectDocs && !isSubagentSession) {
170873
171017
  const hasCached = cachedDocsBySession.has(sessionId);
170874
171018
  if (!hasCached || isCacheBusting) {
170875
171019
  const docsContent = readProjectDocs(deps.directory);
@@ -170885,7 +171029,7 @@ function createSystemPromptHashHandler(deps) {
170885
171029
  output.system.push(docsBlock);
170886
171030
  }
170887
171031
  }
170888
- if (deps.experimentalUserMemories) {
171032
+ if (deps.experimentalUserMemories && !isSubagentSession) {
170889
171033
  const hasCachedProfile = cachedUserProfileBySession.has(sessionId);
170890
171034
  if (!hasCachedProfile || isCacheBusting) {
170891
171035
  const memories = getActiveUserMemories(deps.db);
@@ -170907,7 +171051,7 @@ ${items}
170907
171051
  output.system.push(profileBlock);
170908
171052
  }
170909
171053
  }
170910
- if (deps.experimentalPinKeyFiles) {
171054
+ if (deps.experimentalPinKeyFiles && !isSubagentSession) {
170911
171055
  const hasCachedKeyFiles = cachedKeyFilesBySession.has(sessionId);
170912
171056
  if (!hasCachedKeyFiles || isCacheBusting) {
170913
171057
  const keyFileEntries = getKeyFiles(deps.db, sessionId);
@@ -171005,7 +171149,9 @@ ${sections.join(`
171005
171149
  const previousHash = sessionMeta.systemPromptHash;
171006
171150
  if (previousHash !== "" && previousHash !== "0" && previousHash !== currentHash) {
171007
171151
  sessionLog(sessionId, `system prompt hash changed: ${previousHash} \u2192 ${currentHash} (len=${systemContent.length}), triggering flush`);
171008
- deps.flushedSessions.add(sessionId);
171152
+ deps.historyRefreshSessions.add(sessionId);
171153
+ deps.systemPromptRefreshSessions.add(sessionId);
171154
+ deps.pendingMaterializationSessions.add(sessionId);
171009
171155
  deps.lastHeuristicsTurnId.delete(sessionId);
171010
171156
  } else if (previousHash === "" || previousHash === "0") {
171011
171157
  sessionLog(sessionId, `system prompt hash initialized: ${currentHash} (len=${systemContent.length})`);
@@ -171019,6 +171165,9 @@ ${sections.join(`
171019
171165
  } else if (Math.abs(sessionMeta.systemPromptTokens - systemPromptTokens) > 50) {
171020
171166
  updateSessionMeta(deps.db, sessionId, { systemPromptTokens });
171021
171167
  }
171168
+ if (isCacheBusting) {
171169
+ deps.systemPromptRefreshSessions.delete(sessionId);
171170
+ }
171022
171171
  };
171023
171172
  return {
171024
171173
  handler,
@@ -171077,7 +171226,9 @@ function createMagicContextHook(deps) {
171077
171226
  let lastScheduleCheckMs = 0;
171078
171227
  const getHistorianChunkTokens = () => deriveHistorianChunkTokens(resolveHistorianContextLimit(deps.config.historian?.model));
171079
171228
  const nudgePlacements = createNudgePlacementStore(db);
171080
- const flushedSessions = new Set;
171229
+ const historyRefreshSessions = deps.liveSessionState?.historyRefreshSessions ?? new Set;
171230
+ const systemPromptRefreshSessions = deps.liveSessionState?.systemPromptRefreshSessions ?? new Set;
171231
+ const pendingMaterializationSessions = deps.liveSessionState?.pendingMaterializationSessions ?? new Set;
171081
171232
  const lastHeuristicsTurnId = new Map;
171082
171233
  const commitSeenLastPass = new Map;
171083
171234
  const variantBySession = deps.liveSessionState?.variantBySession ?? new Map;
@@ -171116,14 +171267,16 @@ function createMagicContextHook(deps) {
171116
171267
  autoDropToolAge: deps.config.auto_drop_tool_age ?? 100,
171117
171268
  dropToolStructure: deps.config.drop_tool_structure ?? true,
171118
171269
  clearReasoningAge: deps.config.clear_reasoning_age ?? 50,
171119
- flushedSessions,
171270
+ historyRefreshSessions,
171271
+ pendingMaterializationSessions,
171120
171272
  lastHeuristicsTurnId,
171121
171273
  commitSeenLastPass,
171122
171274
  client: deps.client,
171123
171275
  directory: deps.directory,
171124
171276
  memoryConfig: deps.config.memory ? {
171125
171277
  enabled: deps.config.memory.enabled,
171126
- injectionBudgetTokens: deps.config.memory.injection_budget_tokens
171278
+ injectionBudgetTokens: deps.config.memory.injection_budget_tokens,
171279
+ autoPromote: deps.config.memory.auto_promote ?? true
171127
171280
  } : undefined,
171128
171281
  getHistorianChunkTokens,
171129
171282
  historyBudgetPercentage: deps.config.history_budget_percentage,
@@ -171229,7 +171382,11 @@ function createMagicContextHook(deps) {
171229
171382
  return;
171230
171383
  return resolveContextLimit(model.providerID, model.modelID);
171231
171384
  },
171232
- onFlush: (sessionId) => flushedSessions.add(sessionId),
171385
+ onFlush: (sessionId) => {
171386
+ historyRefreshSessions.add(sessionId);
171387
+ systemPromptRefreshSessions.add(sessionId);
171388
+ pendingMaterializationSessions.add(sessionId);
171389
+ },
171233
171390
  executeRecomp: async (sessionId, options) => executeContextRecomp({
171234
171391
  client: deps.client,
171235
171392
  db,
@@ -171243,8 +171400,11 @@ function createMagicContextHook(deps) {
171243
171400
  })(),
171244
171401
  getNotificationParams: () => getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession),
171245
171402
  historianTwoPass: deps.config.historian?.two_pass === true,
171403
+ memoryEnabled: deps.config.memory?.enabled,
171404
+ autoPromote: deps.config.memory?.auto_promote ?? true,
171246
171405
  onInjectionCacheCleared: (sid) => {
171247
- flushedSessions.add(sid);
171406
+ historyRefreshSessions.add(sid);
171407
+ pendingMaterializationSessions.add(sid);
171248
171408
  }
171249
171409
  }, options),
171250
171410
  sendNotification: async (sessionId, text, params) => {
@@ -171283,7 +171443,9 @@ function createMagicContextHook(deps) {
171283
171443
  dreamerEnabled: deps.config.dreamer?.enabled === true,
171284
171444
  injectDocs: deps.config.dreamer?.inject_docs !== false,
171285
171445
  directory: deps.directory,
171286
- flushedSessions,
171446
+ historyRefreshSessions,
171447
+ systemPromptRefreshSessions,
171448
+ pendingMaterializationSessions,
171287
171449
  lastHeuristicsTurnId,
171288
171450
  experimentalUserMemories: deps.config.dreamer?.user_memories?.enabled,
171289
171451
  experimentalPinKeyFiles: deps.config.dreamer?.pin_key_files?.enabled ?? false,
@@ -171300,7 +171462,9 @@ function createMagicContextHook(deps) {
171300
171462
  agentBySession,
171301
171463
  recentReduceBySession,
171302
171464
  toolUsageSinceUserTurn,
171303
- flushedSessions,
171465
+ historyRefreshSessions,
171466
+ systemPromptRefreshSessions,
171467
+ pendingMaterializationSessions,
171304
171468
  lastHeuristicsTurnId,
171305
171469
  commitSeenLastPass,
171306
171470
  client: deps.client,
@@ -171318,7 +171482,9 @@ function createMagicContextHook(deps) {
171318
171482
  liveModelBySession,
171319
171483
  variantBySession,
171320
171484
  agentBySession,
171321
- flushedSessions,
171485
+ historyRefreshSessions,
171486
+ systemPromptRefreshSessions,
171487
+ pendingMaterializationSessions,
171322
171488
  lastHeuristicsTurnId,
171323
171489
  ctxReduceEnabled
171324
171490
  }),
@@ -171436,6 +171602,166 @@ function truncateError(name2, code, message, maxLen = 240) {
171436
171602
  init_project_identity();
171437
171603
  init_storage();
171438
171604
  init_read_session_formatting();
171605
+
171606
+ // src/hooks/magic-context/tokenizer-calibration.ts
171607
+ var CALIBRATION_TABLE = [
171608
+ { prefix: "anthropic/claude-opus-4-7", systemRatio: 1.51, toolsRatio: 1.57 },
171609
+ { prefix: "anthropic/claude-opus-4.7", systemRatio: 1.51, toolsRatio: 1.57 },
171610
+ { prefix: "anthropic/claude-opus-4-5", systemRatio: 1.02, toolsRatio: 1.16 },
171611
+ { prefix: "anthropic/claude-opus-4.5", systemRatio: 1.02, toolsRatio: 1.16 },
171612
+ { prefix: "anthropic/claude-opus-4-6", systemRatio: 1.02, toolsRatio: 1.16 },
171613
+ { prefix: "anthropic/claude-opus-4.6", systemRatio: 1.02, toolsRatio: 1.16 },
171614
+ { prefix: "anthropic/claude-sonnet-4-5", systemRatio: 1.02, toolsRatio: 1.16 },
171615
+ { prefix: "anthropic/claude-sonnet-4.5", systemRatio: 1.02, toolsRatio: 1.16 },
171616
+ { prefix: "anthropic/claude-sonnet-4-6", systemRatio: 1.02, toolsRatio: 1.14 },
171617
+ { prefix: "anthropic/claude-sonnet-4.6", systemRatio: 1.02, toolsRatio: 1.14 },
171618
+ { prefix: "anthropic/claude-haiku-4-5", systemRatio: 1.02, toolsRatio: 1.16 },
171619
+ { prefix: "anthropic/claude-haiku-4.5", systemRatio: 1.02, toolsRatio: 1.16 },
171620
+ { prefix: "openrouter/anthropic/claude-opus-4-7", systemRatio: 1.51, toolsRatio: 1.57 },
171621
+ { prefix: "openrouter/anthropic/claude-opus-4.7", systemRatio: 1.51, toolsRatio: 1.57 },
171622
+ { prefix: "github-copilot/claude-opus-4-7", systemRatio: 1.51, toolsRatio: 1.57 },
171623
+ { prefix: "github-copilot/claude-opus-4.7", systemRatio: 1.51, toolsRatio: 1.57 },
171624
+ { prefix: "openrouter/anthropic/claude-sonnet-4.6", systemRatio: 1.02, toolsRatio: 1.14 },
171625
+ { prefix: "github-copilot/claude-sonnet-4.6", systemRatio: 1.02, toolsRatio: 1.14 },
171626
+ { prefix: "github-copilot/claude-sonnet-4.5", systemRatio: 1.02, toolsRatio: 1.16 },
171627
+ { prefix: "github-copilot/claude-opus-4.5", systemRatio: 1.02, toolsRatio: 1.16 },
171628
+ { prefix: "github-copilot/claude-haiku-4.5", systemRatio: 1.02, toolsRatio: 1.16 },
171629
+ { prefix: "openai/gpt-5", systemRatio: 1, toolsRatio: 0.84 },
171630
+ { prefix: "xai/grok-4", systemRatio: 0.82, toolsRatio: 0.88 },
171631
+ { prefix: "xai/grok-code-fast", systemRatio: 0.82, toolsRatio: 0.89 },
171632
+ { prefix: "cerebras/qwen-3-235b", systemRatio: 1, toolsRatio: 1.1 },
171633
+ { prefix: "cerebras/zai-glm-4.7", systemRatio: 1, toolsRatio: 1.09 },
171634
+ { prefix: "cerebras/gpt-oss-120b", systemRatio: 0.84, toolsRatio: 0.79 },
171635
+ {
171636
+ prefix: "fireworks-ai/accounts/fireworks/models/glm-5p1",
171637
+ systemRatio: 1,
171638
+ toolsRatio: 1.06
171639
+ },
171640
+ {
171641
+ prefix: "fireworks-ai/accounts/fireworks/models/deepseek-v3p2",
171642
+ systemRatio: 1.05,
171643
+ toolsRatio: 1.09
171644
+ },
171645
+ { prefix: "opencode-go/glm-5.1", systemRatio: 1, toolsRatio: 1.06 },
171646
+ { prefix: "opencode-go/glm-5", systemRatio: 1, toolsRatio: 1.06 },
171647
+ { prefix: "opencode-go/kimi-k2.6", systemRatio: 0.87, toolsRatio: 0.86 }
171648
+ ];
171649
+ var NEUTRAL = { systemRatio: 1, toolsRatio: 1 };
171650
+ function resolveModelCalibration(providerId, modelId) {
171651
+ if (!providerId || !modelId)
171652
+ return NEUTRAL;
171653
+ const key = `${providerId}/${modelId}`.toLowerCase();
171654
+ let best = null;
171655
+ for (const entry of CALIBRATION_TABLE) {
171656
+ const prefix = entry.prefix.toLowerCase();
171657
+ if (!key.startsWith(prefix))
171658
+ continue;
171659
+ if (!best || prefix.length > best.prefix.length) {
171660
+ best = entry;
171661
+ }
171662
+ }
171663
+ return best ?? NEUTRAL;
171664
+ }
171665
+ function calibrateBuckets(input) {
171666
+ const empty = {
171667
+ systemTokens: 0,
171668
+ toolDefinitionTokens: 0,
171669
+ compartmentTokens: 0,
171670
+ factTokens: 0,
171671
+ memoryTokens: 0,
171672
+ conversationTokens: 0,
171673
+ toolCallTokens: 0
171674
+ };
171675
+ if (input.inputTokens <= 0)
171676
+ return empty;
171677
+ let calibratedSystem = Math.round(input.systemLocal * input.calibration.systemRatio);
171678
+ let calibratedToolDefs = Math.round(input.toolDefsLocal * input.calibration.toolsRatio);
171679
+ let compartments = Math.max(0, input.compartmentsLocal);
171680
+ let facts = Math.max(0, input.factsLocal);
171681
+ let memories = Math.max(0, input.memoriesLocal);
171682
+ const nonResidualTotal = calibratedSystem + calibratedToolDefs + compartments + facts + memories;
171683
+ if (nonResidualTotal > input.inputTokens) {
171684
+ const ratio = input.inputTokens / nonResidualTotal;
171685
+ calibratedSystem = Math.round(calibratedSystem * ratio);
171686
+ calibratedToolDefs = Math.round(calibratedToolDefs * ratio);
171687
+ compartments = Math.round(compartments * ratio);
171688
+ facts = Math.round(facts * ratio);
171689
+ memories = Math.round(memories * ratio);
171690
+ }
171691
+ const residualTarget = Math.max(0, input.inputTokens - calibratedSystem - calibratedToolDefs - compartments - facts - memories);
171692
+ const residualLocalSum = input.conversationLocal + input.toolCallsLocal;
171693
+ let conversation;
171694
+ let toolCalls;
171695
+ if (residualLocalSum <= 0) {
171696
+ conversation = residualTarget;
171697
+ toolCalls = 0;
171698
+ } else {
171699
+ const scale = residualTarget / residualLocalSum;
171700
+ conversation = Math.round(input.conversationLocal * scale);
171701
+ toolCalls = Math.round(input.toolCallsLocal * scale);
171702
+ }
171703
+ const provisionalSum = calibratedSystem + calibratedToolDefs + compartments + facts + memories + conversation + toolCalls;
171704
+ let delta = input.inputTokens - provisionalSum;
171705
+ if (delta !== 0) {
171706
+ if (conversation >= toolCalls) {
171707
+ const adjusted = Math.max(0, conversation + delta);
171708
+ delta -= adjusted - conversation;
171709
+ conversation = adjusted;
171710
+ } else {
171711
+ const adjusted = Math.max(0, toolCalls + delta);
171712
+ delta -= adjusted - toolCalls;
171713
+ toolCalls = adjusted;
171714
+ }
171715
+ }
171716
+ if (delta < 0) {
171717
+ const get = (name2) => {
171718
+ if (name2 === "system")
171719
+ return calibratedSystem;
171720
+ if (name2 === "toolDefs")
171721
+ return calibratedToolDefs;
171722
+ if (name2 === "compartments")
171723
+ return compartments;
171724
+ if (name2 === "facts")
171725
+ return facts;
171726
+ return memories;
171727
+ };
171728
+ const subtract = (name2, amount) => {
171729
+ if (name2 === "system")
171730
+ calibratedSystem -= amount;
171731
+ else if (name2 === "toolDefs")
171732
+ calibratedToolDefs -= amount;
171733
+ else if (name2 === "compartments")
171734
+ compartments -= amount;
171735
+ else if (name2 === "facts")
171736
+ facts -= amount;
171737
+ else
171738
+ memories -= amount;
171739
+ };
171740
+ const buckets = ["system", "toolDefs", "compartments", "facts", "memories"];
171741
+ buckets.sort((a, b) => get(b) - get(a));
171742
+ for (const name2 of buckets) {
171743
+ if (delta >= 0)
171744
+ break;
171745
+ const value = get(name2);
171746
+ if (value <= 0)
171747
+ continue;
171748
+ const adjustment = Math.min(value, -delta);
171749
+ subtract(name2, adjustment);
171750
+ delta += adjustment;
171751
+ }
171752
+ }
171753
+ return {
171754
+ systemTokens: calibratedSystem,
171755
+ toolDefinitionTokens: calibratedToolDefs,
171756
+ compartmentTokens: compartments,
171757
+ factTokens: facts,
171758
+ memoryTokens: memories,
171759
+ conversationTokens: conversation,
171760
+ toolCallTokens: toolCalls
171761
+ };
171762
+ }
171763
+
171764
+ // src/plugin/rpc-handlers.ts
171439
171765
  init_logger();
171440
171766
  init_rpc_notifications();
171441
171767
  function getDb() {
@@ -171505,8 +171831,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState) {
171505
171831
  memoryTokens: 0,
171506
171832
  conversationTokens: 0,
171507
171833
  toolCallTokens: 0,
171508
- toolDefinitionTokens: 0,
171509
- overheadTokens: 0
171834
+ toolDefinitionTokens: 0
171510
171835
  };
171511
171836
  try {
171512
171837
  const projectIdentity = resolveProjectIdentity(directory);
@@ -171580,23 +171905,37 @@ ${c.content}
171580
171905
  } catch {}
171581
171906
  }
171582
171907
  const injectedInMessages = compartmentTokens + factTokens + memoryTokens;
171583
- const conversationTokens = Math.max(0, messagesBlockTokens - injectedInMessages);
171584
- const toolCallTokens = Math.max(0, toolCallTokensRaw);
171908
+ const conversationLocal = Math.max(0, messagesBlockTokens - injectedInMessages);
171909
+ const toolCallsLocal = Math.max(0, toolCallTokensRaw);
171585
171910
  let measuredToolDefTokens = 0;
171911
+ let activeProviderID;
171912
+ let activeModelID;
171586
171913
  if (liveSessionState) {
171587
171914
  const model = liveSessionState.liveModelBySession.get(sessionId);
171588
171915
  const agent = liveSessionState.agentBySession.get(sessionId);
171589
171916
  if (model) {
171917
+ activeProviderID = model.providerID;
171918
+ activeModelID = model.modelID;
171590
171919
  measuredToolDefTokens = getMeasuredToolDefinitionTokens(model.providerID, model.modelID, agent) ?? 0;
171591
171920
  }
171592
171921
  }
171593
- const toolDefinitionTokens = measuredToolDefTokens;
171594
- const overheadTokens = Math.max(0, inputTokens - systemPromptTokens - messagesBlockTokens - toolCallTokens - measuredToolDefTokens);
171595
- return {
171922
+ const calibration = resolveModelCalibration(activeProviderID, activeModelID);
171923
+ const calibrated = calibrateBuckets({
171924
+ inputTokens,
171925
+ systemLocal: systemPromptTokens,
171926
+ toolDefsLocal: measuredToolDefTokens,
171927
+ compartmentsLocal: compartmentTokens,
171928
+ factsLocal: factTokens,
171929
+ memoriesLocal: memoryTokens,
171930
+ conversationLocal,
171931
+ toolCallsLocal,
171932
+ calibration
171933
+ });
171934
+ const fresh = {
171596
171935
  sessionId,
171597
171936
  usagePercentage,
171598
171937
  inputTokens,
171599
- systemPromptTokens,
171938
+ systemPromptTokens: calibrated.systemTokens,
171600
171939
  compartmentCount,
171601
171940
  factCount,
171602
171941
  memoryCount,
@@ -171609,14 +171948,14 @@ ${c.content}
171609
171948
  cacheTtl,
171610
171949
  lastDreamerRunAt,
171611
171950
  projectIdentity,
171612
- compartmentTokens,
171613
- factTokens,
171614
- memoryTokens,
171615
- conversationTokens,
171616
- toolCallTokens,
171617
- toolDefinitionTokens,
171618
- overheadTokens
171951
+ compartmentTokens: calibrated.compartmentTokens,
171952
+ factTokens: calibrated.factTokens,
171953
+ memoryTokens: calibrated.memoryTokens,
171954
+ conversationTokens: calibrated.conversationTokens,
171955
+ toolCallTokens: calibrated.toolCallTokens,
171956
+ toolDefinitionTokens: calibrated.toolDefinitionTokens
171619
171957
  };
171958
+ return applyStickySnapshotCache(sessionId, fresh);
171620
171959
  } catch (err) {
171621
171960
  log("[rpc] sidebar-snapshot error:", err);
171622
171961
  return empty;
@@ -171788,7 +172127,13 @@ function registerRpcHandlers(rpcServer, args) {
171788
172127
  historianChunkTokens,
171789
172128
  historianTimeoutMs: config2.historian_timeout_ms ?? DEFAULT_HISTORIAN_TIMEOUT_MS2,
171790
172129
  directory,
171791
- getNotificationParams: () => getNotificationParams(sessionId)
172130
+ memoryEnabled: config2.memory?.enabled,
172131
+ autoPromote: config2.memory?.auto_promote ?? true,
172132
+ getNotificationParams: () => getNotificationParams(sessionId),
172133
+ onInjectionCacheCleared: (sid) => {
172134
+ liveSessionState.historyRefreshSessions.add(sid);
172135
+ liveSessionState.pendingMaterializationSessions.add(sid);
172136
+ }
171792
172137
  }).then((result) => {
171793
172138
  sendIgnoredMessage2(args.client, sessionId, result, getNotificationParams(sessionId)).catch(() => {});
171794
172139
  }).catch((error48) => {