@cortexkit/opencode-magic-context 0.32.2 → 0.32.3

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 (26) hide show
  1. package/dist/config/transform-mode.d.ts.map +1 -1
  2. package/dist/features/magic-context/compaction-marker.d.ts +2 -2
  3. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  4. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +7 -15
  5. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  6. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +1 -1
  7. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
  8. package/dist/hooks/magic-context/event-resolvers.d.ts +12 -6
  9. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  10. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  11. package/dist/hooks/magic-context/m0-token-breakdown.d.ts +2 -0
  12. package/dist/hooks/magic-context/m0-token-breakdown.d.ts.map +1 -1
  13. package/dist/hooks/magic-context/rust-mode-transform.d.ts +3 -0
  14. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/shadow-sender.d.ts.map +1 -1
  16. package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
  17. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  18. package/dist/hooks/magic-context/transform-context-state.d.ts +1 -1
  19. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +11 -18
  21. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  23. package/dist/index.js +365 -150
  24. package/dist/plugin/rpc-handlers.d.ts +1 -0
  25. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  26. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -15646,25 +15646,28 @@ function closeQuietly(db) {
15646
15646
  }
15647
15647
 
15648
15648
  // src/features/magic-context/compaction-marker.ts
15649
+ import { createHash } from "node:crypto";
15649
15650
  import { existsSync as existsSync6 } from "node:fs";
15650
15651
  import { join as join3 } from "node:path";
15651
- function randomBase62(length) {
15652
- const chars = [];
15653
- for (let i = 0;i < length; i++) {
15654
- chars.push(BASE62_CHARS[Math.floor(Math.random() * BASE62_CHARS.length)]);
15652
+ function deterministicBase62(seed, length) {
15653
+ let value = BigInt(`0x${createHash("sha256").update(seed).digest("hex")}`);
15654
+ const chars = Array(length);
15655
+ for (let index = length - 1;index >= 0; index -= 1) {
15656
+ chars[index] = BASE62_CHARS[Number(value % 62n)];
15657
+ value /= 62n;
15655
15658
  }
15656
15659
  return chars.join("");
15657
15660
  }
15658
- function generateId(prefix, timestampMs, counter = 0n) {
15659
- const encoded = BigInt(timestampMs) * 0x1000n + counter;
15660
- const hex3 = encoded.toString(16).padStart(14, "0");
15661
- return `${prefix}_${hex3}${randomBase62(14)}`;
15661
+ function generateId(prefix, timestampMs, counter, identity) {
15662
+ const encoded = BigInt(Math.max(0, Math.floor(timestampMs))) * 0x1000n + counter & ID_PREFIX_MASK;
15663
+ const hex3 = encoded.toString(16).padStart(ID_PREFIX_HEX_LENGTH, "0");
15664
+ return `${prefix}_${hex3}${deterministicBase62(`${prefix}\x00${identity}`, ID_SUFFIX_LENGTH)}`;
15662
15665
  }
15663
- function generateMessageId(timestampMs, counter = 0n) {
15664
- return generateId("msg", timestampMs, counter);
15666
+ function generateMessageId(timestampMs, counter = 0n, identity = "") {
15667
+ return generateId("msg", timestampMs, counter, identity);
15665
15668
  }
15666
- function generatePartId(timestampMs, counter = 0n) {
15667
- return generateId("prt", timestampMs, counter);
15669
+ function generatePartId(timestampMs, counter = 0n, identity = "") {
15670
+ return generateId("prt", timestampMs, counter, identity);
15668
15671
  }
15669
15672
  function getOpenCodeDbPath() {
15670
15673
  return join3(getDataDir(), "opencode", "opencode.db");
@@ -15763,6 +15766,38 @@ function getOpenCodeMessageById(sessionId, messageId) {
15763
15766
  const row = db.prepare(`SELECT id FROM message WHERE session_id = ? AND id = ? LIMIT 1`).get(sessionId, messageId);
15764
15767
  return row ?? null;
15765
15768
  }
15769
+ function removeLegacyMarkerLineageRows(db, args) {
15770
+ const legacySummaries = db.prepare(`SELECT m.id
15771
+ FROM message m
15772
+ WHERE m.session_id = ?
15773
+ AND m.id <> ?
15774
+ AND COALESCE(json_extract(m.data, '$.summary'), 0) = 1
15775
+ AND COALESCE(json_extract(m.data, '$.finish'), '') = 'stop'
15776
+ AND COALESCE(json_extract(m.data, '$.parentID'), '') = ?
15777
+ AND EXISTS (
15778
+ SELECT 1
15779
+ FROM part p
15780
+ WHERE p.session_id = m.session_id
15781
+ AND p.message_id = m.id
15782
+ AND COALESCE(json_extract(p.data, '$.type'), '') = 'text'
15783
+ AND COALESCE(json_extract(p.data, '$.text'), '') = ?
15784
+ )`).all(args.sessionId, args.summaryMessageId, args.boundaryMessageId, args.summaryText);
15785
+ const legacySummaryIds = legacySummaries.flatMap((row) => typeof row.id === "string" ? [row.id] : []);
15786
+ if (legacySummaryIds.length === 0)
15787
+ return;
15788
+ const deleteSummaryParts = db.prepare("DELETE FROM part WHERE session_id = ? AND message_id = ?");
15789
+ const deleteSummary = db.prepare("DELETE FROM message WHERE session_id = ? AND id = ?");
15790
+ for (const summaryMessageId of legacySummaryIds) {
15791
+ deleteSummaryParts.run(args.sessionId, summaryMessageId);
15792
+ deleteSummary.run(args.sessionId, summaryMessageId);
15793
+ }
15794
+ db.prepare(`DELETE FROM part
15795
+ WHERE session_id = ?
15796
+ AND message_id = ?
15797
+ AND id <> ?
15798
+ AND COALESCE(json_extract(data, '$.type'), '') = 'compaction'
15799
+ AND COALESCE(json_extract(data, '$.auto'), 0) = 1`).run(args.sessionId, args.boundaryMessageId, args.compactionPartId);
15800
+ }
15766
15801
  function injectCompactionMarker(args) {
15767
15802
  const db = getWritableOpenCodeDb();
15768
15803
  if (!isOpenCodeSchemaCompatible(db, getOpenCodeDbPath())) {
@@ -15774,9 +15809,10 @@ function injectCompactionMarker(args) {
15774
15809
  return null;
15775
15810
  }
15776
15811
  const boundaryTime = boundary.timeCreated;
15777
- const summaryMsgId = generateMessageId(boundaryTime + 1, 1n);
15778
- const compactionPartId = generatePartId(boundaryTime, 1n);
15779
- const summaryPartId = generatePartId(boundaryTime + 1, 2n);
15812
+ const markerIdentity = `${args.sessionId}\x00${args.endMessageId}`;
15813
+ const summaryMsgId = generateMessageId(boundaryTime + 1, 1n, `${markerIdentity}\x00summary-message`);
15814
+ const compactionPartId = generatePartId(boundaryTime, 1n, `${markerIdentity}\x00compaction-part`);
15815
+ const summaryPartId = generatePartId(boundaryTime + 1, 2n, `${markerIdentity}\x00summary-part`);
15780
15816
  const summaryMsgData = JSON.stringify({
15781
15817
  role: "assistant",
15782
15818
  parentID: boundary.id,
@@ -15793,9 +15829,36 @@ function injectCompactionMarker(args) {
15793
15829
  });
15794
15830
  try {
15795
15831
  db.transaction(() => {
15796
- db.prepare("INSERT INTO part (id, message_id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?, ?)").run(compactionPartId, boundary.id, args.sessionId, boundaryTime, boundaryTime, '{"type":"compaction","auto":true}');
15797
- db.prepare("INSERT INTO message (id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?)").run(summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, summaryMsgData);
15798
- db.prepare("INSERT INTO part (id, message_id, session_id, time_created, time_updated, data) VALUES (?, ?, ?, ?, ?, ?)").run(summaryPartId, summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, JSON.stringify({ type: "text", text: args.summaryText }));
15832
+ removeLegacyMarkerLineageRows(db, {
15833
+ sessionId: args.sessionId,
15834
+ boundaryMessageId: boundary.id,
15835
+ summaryText: args.summaryText,
15836
+ summaryMessageId: summaryMsgId,
15837
+ compactionPartId
15838
+ });
15839
+ db.prepare(`INSERT INTO part (id, message_id, session_id, time_created, time_updated, data)
15840
+ VALUES (?, ?, ?, ?, ?, ?)
15841
+ ON CONFLICT(id) DO UPDATE SET
15842
+ message_id = excluded.message_id,
15843
+ session_id = excluded.session_id,
15844
+ time_created = excluded.time_created,
15845
+ time_updated = excluded.time_updated,
15846
+ data = excluded.data`).run(compactionPartId, boundary.id, args.sessionId, boundaryTime, boundaryTime, '{"type":"compaction","auto":true}');
15847
+ db.prepare(`INSERT INTO message (id, session_id, time_created, time_updated, data)
15848
+ VALUES (?, ?, ?, ?, ?)
15849
+ ON CONFLICT(id) DO UPDATE SET
15850
+ session_id = excluded.session_id,
15851
+ time_created = excluded.time_created,
15852
+ time_updated = excluded.time_updated,
15853
+ data = excluded.data`).run(summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, summaryMsgData);
15854
+ db.prepare(`INSERT INTO part (id, message_id, session_id, time_created, time_updated, data)
15855
+ VALUES (?, ?, ?, ?, ?, ?)
15856
+ ON CONFLICT(id) DO UPDATE SET
15857
+ message_id = excluded.message_id,
15858
+ session_id = excluded.session_id,
15859
+ time_created = excluded.time_created,
15860
+ time_updated = excluded.time_updated,
15861
+ data = excluded.data`).run(summaryPartId, summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, JSON.stringify({ type: "text", text: args.summaryText }));
15799
15862
  })();
15800
15863
  log(`[magic-context] compaction-marker: injected boundary at user msg ${boundary.id} (ordinal ~${args.endOrdinal}), summary msg ${summaryMsgId}`);
15801
15864
  return {
@@ -15823,11 +15886,12 @@ function removeCompactionMarker(state) {
15823
15886
  return false;
15824
15887
  }
15825
15888
  }
15826
- var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", cachedWriteDb = null, REQUIRED_MESSAGE_COLUMNS, REQUIRED_PART_COLUMNS, cachedSchemaCompatible = null;
15889
+ var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", ID_PREFIX_HEX_LENGTH = 12, ID_SUFFIX_LENGTH = 14, ID_PREFIX_MASK, cachedWriteDb = null, REQUIRED_MESSAGE_COLUMNS, REQUIRED_PART_COLUMNS, cachedSchemaCompatible = null;
15827
15890
  var init_compaction_marker = __esm(async () => {
15828
15891
  init_data_path();
15829
15892
  init_logger();
15830
15893
  await init_sqlite();
15894
+ ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
15831
15895
  REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
15832
15896
  REQUIRED_PART_COLUMNS = [
15833
15897
  "id",
@@ -15841,7 +15905,7 @@ var init_compaction_marker = __esm(async () => {
15841
15905
 
15842
15906
  // src/features/magic-context/memory/project-identity.ts
15843
15907
  import { execFileSync } from "node:child_process";
15844
- import { createHash } from "node:crypto";
15908
+ import { createHash as createHash2 } from "node:crypto";
15845
15909
  import { existsSync as existsSync8, realpathSync, statSync as statSync2 } from "node:fs";
15846
15910
  import path3 from "node:path";
15847
15911
  function asError(error51) {
@@ -15882,7 +15946,7 @@ function getErrorStderr(error51) {
15882
15946
  }
15883
15947
  function directoryFallback(directory) {
15884
15948
  const canonical = path3.resolve(directory);
15885
- const hash2 = createHash("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
15949
+ const hash2 = createHash2("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
15886
15950
  return `dir:${hash2}`;
15887
15951
  }
15888
15952
  function assertDirectoryUsable(canonicalDirectory, rawDirectory) {
@@ -151678,7 +151742,7 @@ var init_project_identity2 = __esm(() => {
151678
151742
  });
151679
151743
 
151680
151744
  // src/features/magic-context/workspaces.ts
151681
- import { createHash as createHash2 } from "node:crypto";
151745
+ import { createHash as createHash3 } from "node:crypto";
151682
151746
  function tableExists(db, tableName) {
151683
151747
  const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name = ? LIMIT 1").get(tableName);
151684
151748
  return Boolean(row);
@@ -151862,7 +151926,7 @@ function computeWorkspaceEpochFingerprint(db, identities) {
151862
151926
  const canonical = uniqueSorted(identities.filter((identity) => identity.length > 0));
151863
151927
  const epochs = getEpochMap(db, canonical);
151864
151928
  const shareCategories = selectWorkspaceShareCategories(db, canonical);
151865
- const hash2 = createHash2("sha256");
151929
+ const hash2 = createHash3("sha256");
151866
151930
  hash2.update("share_categories", "utf8");
151867
151931
  hash2.update("\x00");
151868
151932
  hash2.update(shareCategories === null ? "NO_WORKSPACE" : JSON.stringify(shareCategories), "utf8");
@@ -153501,7 +153565,7 @@ var init_migrations = __esm(() => {
153501
153565
  });
153502
153566
 
153503
153567
  // src/features/magic-context/project-docs-hash.ts
153504
- import { createHash as createHash3 } from "node:crypto";
153568
+ import { createHash as createHash4 } from "node:crypto";
153505
153569
  import { lstatSync, readFileSync as readFileSync6, statSync as statSync3 } from "node:fs";
153506
153570
  import path4 from "node:path";
153507
153571
  function canonicalizeDocContent(raw) {
@@ -153591,7 +153655,7 @@ function hashCanonicalPieces(hashPieces) {
153591
153655
  if (hashPieces.length === 0) {
153592
153656
  return "";
153593
153657
  }
153594
- return createHash3("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
153658
+ return createHash4("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
153595
153659
  }
153596
153660
  function readProjectDocsCanonical(projectDirectory) {
153597
153661
  const canonicalDirectory = path4.resolve(projectDirectory);
@@ -153671,13 +153735,13 @@ function stableStringify(value, seen = new WeakSet) {
153671
153735
  }
153672
153736
 
153673
153737
  // src/features/magic-context/tool-definition-tokens.ts
153674
- import { createHash as createHash4 } from "node:crypto";
153738
+ import { createHash as createHash5 } from "node:crypto";
153675
153739
  function keyFor(providerID, modelID, agentName) {
153676
153740
  const agent = agentName && agentName.length > 0 ? agentName : "default";
153677
153741
  return `${providerID}/${modelID}/${agent}`;
153678
153742
  }
153679
153743
  function fingerprintFor(description, parameters) {
153680
- return createHash4("sha256").update(description).update("\x00").update(stableStringify(parameters)).digest("hex");
153744
+ return createHash5("sha256").update(description).update("\x00").update(stableStringify(parameters)).digest("hex");
153681
153745
  }
153682
153746
  function setDatabase(db) {
153683
153747
  persistenceDb = db;
@@ -155326,10 +155390,10 @@ var init_storage_db = __esm(async () => {
155326
155390
  });
155327
155391
 
155328
155392
  // src/features/magic-context/storage-embedding-measurements.ts
155329
- import { createHash as createHash5 } from "node:crypto";
155393
+ import { createHash as createHash6 } from "node:crypto";
155330
155394
  function normalizedQueryHash(query) {
155331
155395
  const normalized = query.trim().replace(/\s+/g, " ").toLowerCase();
155332
- return createHash5("sha256").update(normalized).digest("hex");
155396
+ return createHash6("sha256").update(normalized).digest("hex");
155333
155397
  }
155334
155398
  function recordEmbeddingMeasurement(db, input) {
155335
155399
  const queryTextHash = normalizedQueryHash(input.queryText);
@@ -168888,13 +168952,13 @@ var init_embedding_cache = __esm(() => {
168888
168952
  });
168889
168953
 
168890
168954
  // src/features/magic-context/memory/normalize-hash.ts
168891
- import { createHash as createHash7 } from "node:crypto";
168955
+ import { createHash as createHash8 } from "node:crypto";
168892
168956
  function normalizeMemoryContent(content) {
168893
168957
  return content.toLowerCase().replace(/\s+/g, " ").trim();
168894
168958
  }
168895
168959
  function computeNormalizedHash(content) {
168896
168960
  const normalized = normalizeMemoryContent(content);
168897
- return createHash7("md5").update(normalized).digest("hex");
168961
+ return createHash8("md5").update(normalized).digest("hex");
168898
168962
  }
168899
168963
  var init_normalize_hash = () => {};
168900
168964
 
@@ -170617,7 +170681,7 @@ var init_recursive_text_splitter = __esm(() => {
170617
170681
  });
170618
170682
 
170619
170683
  // src/features/magic-context/compartment-chunk-embedding.ts
170620
- import { createHash as createHash9 } from "node:crypto";
170684
+ import { createHash as createHash10 } from "node:crypto";
170621
170685
  function getLoadFtsRowsStatement(db) {
170622
170686
  let stmt = loadFtsRowsStatements.get(db);
170623
170687
  if (!stmt) {
@@ -170728,7 +170792,7 @@ function parseCanonicalLineRange(line) {
170728
170792
  return { start, end };
170729
170793
  }
170730
170794
  function hashChunkText(text) {
170731
- return createHash9("sha256").update(text).digest("hex");
170795
+ return createHash10("sha256").update(text).digest("hex");
170732
170796
  }
170733
170797
  function vectorBlob2(vector) {
170734
170798
  return new Uint8Array(vector.buffer, vector.byteOffset, vector.byteLength);
@@ -171138,7 +171202,7 @@ function cosineSimilarity(a, b) {
171138
171202
  }
171139
171203
 
171140
171204
  // src/features/magic-context/memory/embedding-synapse.ts
171141
- import { createHash as createHash10 } from "node:crypto";
171205
+ import { createHash as createHash11 } from "node:crypto";
171142
171206
  function isPermanentSynapseCode(code) {
171143
171207
  return code === "artifact_invalid" || code === "substitution_rejected" || code === "not_certified" || code === "probe_required" || code === "idempotency_conflict" || code === "schema_violation";
171144
171208
  }
@@ -171202,7 +171266,7 @@ function wait(ms) {
171202
171266
  return new Promise((resolve4) => setTimeout(resolve4, ms));
171203
171267
  }
171204
171268
  function sha256(value) {
171205
- return createHash10("sha256").update(value).digest("hex");
171269
+ return createHash11("sha256").update(value).digest("hex");
171206
171270
  }
171207
171271
  function stableJson(value) {
171208
171272
  if (Array.isArray(value))
@@ -172684,7 +172748,7 @@ var init_sweep_coordinator = __esm(() => {
172684
172748
  });
172685
172749
 
172686
172750
  // src/features/magic-context/project-embedding-registry.ts
172687
- import { createHash as createHash11, randomUUID as randomUUID4 } from "node:crypto";
172751
+ import { createHash as createHash12, randomUUID as randomUUID4 } from "node:crypto";
172688
172752
  function markProjectLoadUntrusted(projectIdentity) {
172689
172753
  untrustedLoadProjects.add(projectIdentity);
172690
172754
  }
@@ -172849,10 +172913,10 @@ function stableStringify2(value) {
172849
172913
  return JSON.stringify(value);
172850
172914
  }
172851
172915
  function sha256Prefix(value, length = 16) {
172852
- return createHash11("sha256").update(value).digest("hex").slice(0, length);
172916
+ return createHash12("sha256").update(value).digest("hex").slice(0, length);
172853
172917
  }
172854
172918
  function contentSha256(value) {
172855
- return createHash11("sha256").update(value).digest("hex");
172919
+ return createHash12("sha256").update(value).digest("hex");
172856
172920
  }
172857
172921
  function getRuntimeFingerprint(config2) {
172858
172922
  if (config2.provider === "off") {
@@ -181623,6 +181687,19 @@ var init_compartment_embedding = __esm(() => {
181623
181687
 
181624
181688
  // src/hooks/magic-context/compaction-marker-manager.ts
181625
181689
  import { join as join18 } from "node:path";
181690
+ function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
181691
+ const tagNumber = getTagNumberByMessageId(db, sessionId, `${summaryMessageId}:p0`);
181692
+ if (tagNumber !== null)
181693
+ updateTagStatus(db, sessionId, tagNumber, "dropped");
181694
+ }
181695
+ function persistMarkerStateAndDropReplacedTag(db, sessionId, state, replacedSummaryMessageId) {
181696
+ db.transaction(() => {
181697
+ setPersistedCompactionMarkerState(db, sessionId, state);
181698
+ if (replacedSummaryMessageId !== null) {
181699
+ dropMarkerSummaryTag(db, sessionId, replacedSummaryMessageId);
181700
+ }
181701
+ })();
181702
+ }
181626
181703
  function validatePendingTarget(db, sessionId, pending) {
181627
181704
  const ocMessage = getOpenCodeMessageById(sessionId, pending.endMessageId);
181628
181705
  if (!ocMessage) {
@@ -181690,6 +181767,7 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory) {
181690
181767
  error: new Error(`no user boundary found at or before endMessageId ${pending.endMessageId} (ordinal ${pending.ordinal}); preserving existing marker`)
181691
181768
  };
181692
181769
  }
181770
+ const removedSummaryMessageId = existing?.summaryMessageId ?? null;
181693
181771
  if (existing) {
181694
181772
  const removed = removeCompactionMarker(existing);
181695
181773
  if (!removed) {
@@ -181714,17 +181792,15 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory) {
181714
181792
  error: new Error(`injectCompactionMarker returned null for ordinal ${pending.ordinal}; will retry`)
181715
181793
  };
181716
181794
  }
181717
- setPersistedCompactionMarkerState(db, sessionId, {
181795
+ persistMarkerStateAndDropReplacedTag(db, sessionId, {
181718
181796
  ...result,
181719
181797
  boundaryOrdinal: pending.ordinal,
181720
181798
  targetEndMessageId: pending.endMessageId
181721
- });
181799
+ }, removedSummaryMessageId);
181722
181800
  sessionLog(sessionId, `compaction-marker drain: applied at ordinal ${pending.ordinal}, boundary user msg ${result.boundaryMessageId}`);
181723
181801
  return {
181724
181802
  kind: "applied",
181725
- markerOrdinal: pending.ordinal,
181726
- summaryMessageId: result.summaryMessageId,
181727
- boundaryMessageId: result.boundaryMessageId
181803
+ markerOrdinal: pending.ordinal
181728
181804
  };
181729
181805
  } catch (err) {
181730
181806
  const error51 = err instanceof Error ? err : new Error(String(err));
@@ -181742,6 +181818,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
181742
181818
  return false;
181743
181819
  }
181744
181820
  const existing = getPersistedCompactionMarkerState(db, sessionId);
181821
+ const removedSummaryMessageId = existing?.summaryMessageId ?? null;
181745
181822
  if (existing) {
181746
181823
  if (existingMarkerAlreadyCoversTarget(sessionId, existing, lastCompartmentEnd, targetEndMessageId)) {
181747
181824
  return true;
@@ -181758,7 +181835,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
181758
181835
  sessionLog(sessionId, `compaction-marker: failed to remove old boundary at ordinal ${existing.boundaryOrdinal}; preserving persisted state for retry (not injecting new marker this pass)`);
181759
181836
  return false;
181760
181837
  }
181761
- setPersistedCompactionMarkerState(db, sessionId, null);
181838
+ persistMarkerStateAndDropReplacedTag(db, sessionId, null, removedSummaryMessageId);
181762
181839
  sessionLog(sessionId, `compaction-marker: removed old boundary at ordinal ${existing.boundaryOrdinal}, moving to ${lastCompartmentEnd}`);
181763
181840
  }
181764
181841
  const result = injectCompactionMarker({
@@ -181770,11 +181847,11 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
181770
181847
  resolvedBoundary: boundary
181771
181848
  });
181772
181849
  if (result) {
181773
- setPersistedCompactionMarkerState(db, sessionId, {
181850
+ persistMarkerStateAndDropReplacedTag(db, sessionId, {
181774
181851
  ...result,
181775
181852
  boundaryOrdinal: lastCompartmentEnd,
181776
181853
  targetEndMessageId
181777
- });
181854
+ }, removedSummaryMessageId);
181778
181855
  sessionLog(sessionId, `compaction-marker: injected at ordinal ${lastCompartmentEnd}, boundary user msg ${result.boundaryMessageId}`);
181779
181856
  return true;
181780
181857
  }
@@ -181849,6 +181926,7 @@ var MARKER_SUMMARY_TEXT = "[Compacted by magic-context — session history is ma
181849
181926
  var init_compaction_marker_manager = __esm(async () => {
181850
181927
  init_compartment_storage();
181851
181928
  init_storage_meta_persisted();
181929
+ init_storage_tags();
181852
181930
  init_data_path();
181853
181931
  init_logger();
181854
181932
  await __promiseAll([
@@ -184097,7 +184175,7 @@ function softRefreshCachedM1(options) {
184097
184175
  }
184098
184176
  function prependM0M1Messages(sessionId, messages, m0Text, m1Text) {
184099
184177
  messages.unshift({
184100
- info: { role: "user", sessionID: sessionId },
184178
+ info: { role: "user", sessionID: sessionId, syntheticHead: true },
184101
184179
  parts: [
184102
184180
  {
184103
184181
  type: "text",
@@ -184106,7 +184184,7 @@ function prependM0M1Messages(sessionId, messages, m0Text, m1Text) {
184106
184184
  }
184107
184185
  ]
184108
184186
  }, {
184109
- info: { role: "user", sessionID: sessionId },
184187
+ info: { role: "user", sessionID: sessionId, syntheticHead: true },
184110
184188
  parts: [{ type: "text", text: m1Text, synthetic: true }]
184111
184189
  });
184112
184190
  }
@@ -190914,6 +190992,7 @@ init_magic_context();
190914
190992
 
190915
190993
  // src/config/transform-mode.ts
190916
190994
  var warnedShadowProjects = new Set;
190995
+ var warnedCavemanProjects = new Set;
190917
190996
  var RUST_REQUIRES_USER_SUBC_WARNING = "rust mode requires user-level subc configuration; running ts.";
190918
190997
  var SHADOW_TRANSFORM_WARNING = 'shadow_transform is ignored while transform_mode is "rust" (a session cannot shadow itself); shadow disabled for these sessions.';
190919
190998
  var CAVEMAN_RUST_WARNING = "caveman_text_compression is TS-only and inert in rust mode.";
@@ -190933,7 +191012,11 @@ function resolveTransformMode(args) {
190933
191012
  }
190934
191013
  }
190935
191014
  if (args.configured === "rust" && args.cavemanCompressionEnabled) {
190936
- warnings.push(CAVEMAN_RUST_WARNING);
191015
+ const projectKey = args.projectKey ?? "<unspecified-project>";
191016
+ if (!warnedCavemanProjects.has(projectKey)) {
191017
+ warnedCavemanProjects.add(projectKey);
191018
+ warnings.push(CAVEMAN_RUST_WARNING);
191019
+ }
190937
191020
  }
190938
191021
  return { mode: args.configured, warnings };
190939
191022
  }
@@ -192131,7 +192214,7 @@ await init_storage_db();
192131
192214
  // src/features/magic-context/v22-deferred-backfill.ts
192132
192215
  init_logger();
192133
192216
  init_project_identity();
192134
- import { createHash as createHash6 } from "node:crypto";
192217
+ import { createHash as createHash7 } from "node:crypto";
192135
192218
  import { realpathSync as realpathSync2 } from "node:fs";
192136
192219
  import path5 from "node:path";
192137
192220
 
@@ -192193,7 +192276,7 @@ function computeLegacyRustDirIdentity(rawProjectPath) {
192193
192276
  } catch {
192194
192277
  canonical = path5.isAbsolute(rawProjectPath) ? rawProjectPath : path5.join(process.cwd(), rawProjectPath);
192195
192278
  }
192196
- return `dir:${createHash6("sha256").update(canonical, "utf8").digest("hex")}`;
192279
+ return `dir:${createHash7("sha256").update(canonical, "utf8").digest("hex")}`;
192197
192280
  }
192198
192281
  function upsertRekeyMap(db, oldProjectPath, newProjectPath, rekeyedAt) {
192199
192282
  db.prepare(`INSERT INTO v22_identity_rekey_map (old_project_path, new_project_path, rekeyed_at)
@@ -195670,7 +195753,7 @@ function recordRetrospectiveWindowProcessed(db, projectPath, windowKey) {
195670
195753
  init_task_config();
195671
195754
 
195672
195755
  // src/features/magic-context/dreamer/task-executor.ts
195673
- import { createHash as createHash13 } from "node:crypto";
195756
+ import { createHash as createHash14 } from "node:crypto";
195674
195757
  import { existsSync as existsSync20 } from "node:fs";
195675
195758
 
195676
195759
  // src/agents/dreamer.ts
@@ -196965,7 +197048,7 @@ function throwIfAborted2(signal) {
196965
197048
  }
196966
197049
 
196967
197050
  // src/features/magic-context/smart-notes/compiler.ts
196968
- import { createHash as createHash12 } from "node:crypto";
197051
+ import { createHash as createHash13 } from "node:crypto";
196969
197052
  init_shared();
196970
197053
  init_assistant_message_extractor();
196971
197054
  init_logger();
@@ -197373,7 +197456,7 @@ function manifestAdvisoryWarnings(code, manifest) {
197373
197456
  return warnings;
197374
197457
  }
197375
197458
  function hashCheck(surfaceCondition, compiledCheck, manifest, checkCron) {
197376
- return createHash12("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
197459
+ return createHash13("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
197377
197460
  }
197378
197461
  function extractJsonObject(output) {
197379
197462
  const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
@@ -199842,7 +199925,7 @@ function parseFrictionGateVerdict(verdict) {
199842
199925
  }
199843
199926
  function computeRetrospectiveWindowKey(flagged) {
199844
199927
  const anchors = flagged.map((message) => `${message.sessionId}:${message.ts}`).sort().join("|");
199845
- return createHash13("sha256").update(anchors).digest("hex").slice(0, 32);
199928
+ return createHash14("sha256").update(anchors).digest("hex").slice(0, 32);
199846
199929
  }
199847
199930
  function renderFrictionWindow(messages, flaggedOrdinals, radius = 2) {
199848
199931
  const flagged = new Set(flaggedOrdinals);
@@ -201114,7 +201197,7 @@ init_logger();
201114
201197
  // src/plugin/embedding-bootstrap-helpers.ts
201115
201198
  init_embedding();
201116
201199
  init_logger();
201117
- import { createHash as createHash14 } from "node:crypto";
201200
+ import { createHash as createHash15 } from "node:crypto";
201118
201201
  var EMBEDDING_AFFECTING_KEYS = new Set([
201119
201202
  "embedding.api_key",
201120
201203
  "embedding.endpoint",
@@ -201160,7 +201243,7 @@ var EMBEDDING_WARNING_TERMS = [
201160
201243
  ];
201161
201244
  var loggedFailureSignatures = new Map;
201162
201245
  function sha256Prefix2(value, length = 16) {
201163
- return createHash14("sha256").update(value).digest("hex").slice(0, length);
201246
+ return createHash15("sha256").update(value).digest("hex").slice(0, length);
201164
201247
  }
201165
201248
  function warningLooksEmbeddingRelated(message) {
201166
201249
  const lower = message.toLowerCase();
@@ -201450,7 +201533,18 @@ function resolveTrustedContextLimit(providerID, modelID, ctx) {
201450
201533
  return detected;
201451
201534
  return fromModelsDev;
201452
201535
  }
201453
- return detected;
201536
+ if (detected !== undefined) {
201537
+ return detected;
201538
+ }
201539
+ if (modelKey && ctx?.db && ctx.sessionID) {
201540
+ try {
201541
+ const persisted = loadPersistedUsage(ctx.db, ctx.sessionID);
201542
+ if (persisted?.lastObservedModelKey === modelKey && isSaneLimit(persisted.lastUsageContextLimit)) {
201543
+ return persisted.lastUsageContextLimit;
201544
+ }
201545
+ } catch {}
201546
+ }
201547
+ return;
201454
201548
  }
201455
201549
  function resolveCacheTtl(cacheTtl, modelKey) {
201456
201550
  if (typeof cacheTtl === "string") {
@@ -204170,15 +204264,15 @@ function verdictFromToolsMap(tools) {
204170
204264
  function resolveCtxReduceAvailabilityFromMessages(sessionId, messages) {
204171
204265
  const cached2 = availabilityBySession.get(sessionId);
204172
204266
  if (cached2 !== undefined)
204173
- return cached2;
204267
+ return { callable: cached2, frozen: true };
204174
204268
  for (const message of messages) {
204175
204269
  if (message.info?.role !== "user")
204176
204270
  continue;
204177
204271
  const verdict = verdictFromToolsMap(message.info.tools) ?? true;
204178
204272
  availabilityBySession.set(sessionId, verdict);
204179
- return verdict;
204273
+ return { callable: verdict, frozen: true };
204180
204274
  }
204181
- return true;
204275
+ return { callable: true, frozen: false };
204182
204276
  }
204183
204277
  function resolveCtxReduceAvailability(sessionId) {
204184
204278
  const cached2 = availabilityBySession.get(sessionId);
@@ -205184,9 +205278,9 @@ function loadContextUsage(contextUsageMap, db, sessionId) {
205184
205278
  }
205185
205279
  return { percentage: 0, inputTokens: 0 };
205186
205280
  }
205187
- function resolveSchedulerDecision(scheduler, sessionMeta, contextUsage, sessionId, modelKey) {
205281
+ function resolveSchedulerDecision(scheduler, sessionMeta, contextUsage, sessionId, modelKey, contextLimit) {
205188
205282
  try {
205189
- const schedulerDecision = scheduler.shouldExecute(sessionMeta, contextUsage, undefined, sessionId, modelKey);
205283
+ const schedulerDecision = scheduler.shouldExecute(sessionMeta, contextUsage, undefined, sessionId, modelKey, contextLimit);
205190
205284
  sessionLog(sessionId, `transform scheduler: percentage=${contextUsage.percentage.toFixed(1)}% inputTokens=${contextUsage.inputTokens} cacheTtl=${sessionMeta.cacheTtl} lastResponseTime=${sessionMeta.lastResponseTime} decision=${schedulerDecision}`);
205191
205285
  return schedulerDecision;
205192
205286
  } catch (error51) {
@@ -205216,6 +205310,34 @@ function messageInfo2(value) {
205216
205310
  return {};
205217
205311
  return isRecord3(value.info) ? value.info : value;
205218
205312
  }
205313
+ function newestUserMessage(messages) {
205314
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
205315
+ if (messageInfo2(messages[index]).role === "user")
205316
+ return messages[index];
205317
+ }
205318
+ return;
205319
+ }
205320
+ function isSyntheticUserMessage(message) {
205321
+ if (!message || messageInfo2(message).role !== "user" || !Array.isArray(message.parts)) {
205322
+ return false;
205323
+ }
205324
+ return message.parts.length > 0 && message.parts.every((part) => isRecord3(part) && (part.synthetic === true || part.ignored === true));
205325
+ }
205326
+ function observeSyntheticTurn(state, messages) {
205327
+ const newest = newestUserMessage(messages);
205328
+ const info = messageInfo2(newest);
205329
+ const messageId2 = typeof info.id === "string" ? info.id : null;
205330
+ const synthetic = isSyntheticUserMessage(newest);
205331
+ const isNewMessage = messageId2 === null || messageId2 !== state.lastObservedUserMessageId;
205332
+ if (!synthetic) {
205333
+ state.syntheticTurnCount = 0;
205334
+ state.syntheticLoopBreakerLogged = false;
205335
+ } else if (isNewMessage) {
205336
+ state.syntheticTurnCount += 1;
205337
+ }
205338
+ state.lastObservedUserMessageId = messageId2;
205339
+ return synthetic;
205340
+ }
205219
205341
  function assertNativeBoundary(output, sessionId, boundaryId) {
205220
205342
  const first = output.find((message) => messageInfo2(message).role !== "system");
205221
205343
  const info = messageInfo2(first);
@@ -205265,7 +205387,10 @@ function ensureState(states, sessionId) {
205265
205387
  lastAckedSeq: 0,
205266
205388
  lastAckedWatermarks: null,
205267
205389
  idOrdinalMemoGeneration: 0,
205268
- idOrdinalMemo: new Map
205390
+ idOrdinalMemo: new Map,
205391
+ syntheticTurnCount: 0,
205392
+ lastObservedUserMessageId: null,
205393
+ syntheticLoopBreakerLogged: false
205269
205394
  };
205270
205395
  states.set(sessionId, state);
205271
205396
  }
@@ -205337,6 +205462,7 @@ function buildTransformBody(args) {
205337
205462
  mid_turn: args.midTurn,
205338
205463
  model_key: args.modelKey,
205339
205464
  provider_id: args.providerId,
205465
+ tool_present: args.passInputs.tool_present === true,
205340
205466
  effective_execute_threshold: args.passInputs.effective_execute_threshold,
205341
205467
  history_budget_tokens: args.passInputs.history_budget_tokens,
205342
205468
  clear_reasoning_age: args.passInputs.clear_reasoning_age,
@@ -205440,6 +205566,12 @@ function createRustModeTransform(deps, options) {
205440
205566
  const run = async (sessionId, messages, output, sessionMeta) => {
205441
205567
  const state = ensureState(states, sessionId);
205442
205568
  state.passCount += 1;
205569
+ const syntheticTurn = observeSyntheticTurn(state, messages);
205570
+ const syntheticLoopBlocked = syntheticTurn && state.syntheticTurnCount >= 3;
205571
+ if (syntheticLoopBlocked && !state.syntheticLoopBreakerLogged) {
205572
+ state.syntheticLoopBreakerLogged = true;
205573
+ sessionLog(sessionId, "RUST LOOP BREAKER: suppressing host directives after three consecutive synthetic turns until a real user message arrives");
205574
+ }
205443
205575
  const inputCount = messages.length;
205444
205576
  let decision = "error";
205445
205577
  let servedFrom = "none";
@@ -205462,6 +205594,8 @@ function createRustModeTransform(deps, options) {
205462
205594
  }
205463
205595
  }
205464
205596
  const rawMessages = messages.slice();
205597
+ const reduceAvailability = resolveCtxReduceAvailability(sessionId);
205598
+ const toolPresent = reduceAvailability.frozen && reduceAvailability.callable;
205465
205599
  try {
205466
205600
  const { directory } = await getSessionDirectory(deps, sessionId);
205467
205601
  const model = modelFromMessages(messages) ?? findLastAssistantModelFromOpenCodeDb(sessionId);
@@ -205487,7 +205621,8 @@ function createRustModeTransform(deps, options) {
205487
205621
  clear_reasoning_age: deps.clearReasoningAge,
205488
205622
  cache_ttl: sessionMeta.cacheTtl,
205489
205623
  mid_turn: midTurn,
205490
- is_subagent: sessionMeta.isSubagent
205624
+ is_subagent: sessionMeta.isSubagent,
205625
+ tool_present: toolPresent
205491
205626
  };
205492
205627
  const resolved = await resolveOrdinalsForModule({
205493
205628
  sessionId,
@@ -205592,7 +205727,11 @@ function createRustModeTransform(deps, options) {
205592
205727
  state.parked = false;
205593
205728
  state.passesSincePark = 0;
205594
205729
  const directiveText = directiveTextOf(response);
205595
- if (directiveText) {
205730
+ if (syntheticTurn) {
205731
+ try {
205732
+ casChannel2NudgeState(deps.db, sessionId, "pending", "");
205733
+ } catch {}
205734
+ } else if (directiveText) {
205596
205735
  try {
205597
205736
  casChannel2NudgeState(deps.db, sessionId, "", "pending");
205598
205737
  await maybeDeliverChannel2(sessionId, {
@@ -206355,6 +206494,8 @@ function hasToolPartWithCallId(message, callId) {
206355
206494
  return false;
206356
206495
  }
206357
206496
  function isReplayableAssistantAnchor(message) {
206497
+ if (message.info.summary === true)
206498
+ return false;
206358
206499
  return message.info.error === undefined || message.info.error === null;
206359
206500
  }
206360
206501
  function appendReminderToUserMessage(message, reminder) {
@@ -207075,6 +207216,8 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
207075
207216
  };
207076
207217
  }
207077
207218
  // src/hooks/magic-context/transform-postprocess-phase.ts
207219
+ init_storage_meta_persisted();
207220
+ init_storage_tags();
207078
207221
  init_logger();
207079
207222
  await init_storage();
207080
207223
 
@@ -207149,7 +207292,7 @@ init_storage_memory_fts();
207149
207292
  // src/features/magic-context/search-measurement.ts
207150
207293
  init_embedding();
207151
207294
  init_storage_embedding_measurements();
207152
- import { createHash as createHash15 } from "node:crypto";
207295
+ import { createHash as createHash16 } from "node:crypto";
207153
207296
  function resultId(result) {
207154
207297
  switch (result.source) {
207155
207298
  case "memory":
@@ -207232,7 +207375,7 @@ async function recordShadowMeasurement(args) {
207232
207375
  });
207233
207376
  }
207234
207377
  function sha2562(value) {
207235
- return createHash15("sha256").update(value).digest("hex");
207378
+ return createHash16("sha256").update(value).digest("hex");
207236
207379
  }
207237
207380
 
207238
207381
  // src/features/magic-context/search.ts
@@ -208937,7 +209080,7 @@ function readFilePath(target) {
208937
209080
  init_tag_content_primitives();
208938
209081
 
208939
209082
  // src/hooks/magic-context/todo-view.ts
208940
- import { createHash as createHash16 } from "node:crypto";
209083
+ import { createHash as createHash17 } from "node:crypto";
208941
209084
  var TODO_STATUS_PENDING = "pending";
208942
209085
  var TODO_STATUS_IN_PROGRESS = "in_progress";
208943
209086
  var TODO_STATUS_COMPLETED = "completed";
@@ -209005,7 +209148,7 @@ function buildSyntheticTodoPart(stateJson) {
209005
209148
  };
209006
209149
  }
209007
209150
  function computeSyntheticCallId(stateJson) {
209008
- const hash2 = createHash16("sha256").update(stateJson).digest("hex").slice(0, 16);
209151
+ const hash2 = createHash17("sha256").update(stateJson).digest("hex").slice(0, 16);
209009
209152
  return `${SYNTHETIC_CALL_ID_PREFIX}${hash2}`;
209010
209153
  }
209011
209154
  function parseTodoState(stateJson) {
@@ -209085,28 +209228,98 @@ var degradedCacheCountBySession = new BoundedSessionMap(100);
209085
209228
  function resetDegradedCacheCount(sessionId) {
209086
209229
  degradedCacheCountBySession.delete(sessionId);
209087
209230
  }
209088
- function injectDeferredCompactionSummaryRepresentation(args) {
209089
- if (args.messages.some((message) => message.info.id === args.summaryMessageId)) {
209231
+ function isSyntheticHeadMessage(message) {
209232
+ if (message.info.syntheticHead !== true)
209233
+ return false;
209234
+ if (message.info.id !== undefined)
209235
+ return false;
209236
+ if (message.info.role !== "user")
209237
+ return false;
209238
+ const parts = message.parts;
209239
+ if (parts.length === 0)
209240
+ return false;
209241
+ return parts.every((part) => part.synthetic === true);
209242
+ }
209243
+ var TODO_HEAD_ANCHOR_ID = "__magic_context_todo_head__";
209244
+ function injectSyntheticTodoAtHead(messages, sessionId, part) {
209245
+ let headEnd = 0;
209246
+ while (headEnd < messages.length && isSyntheticHeadMessage(messages[headEnd])) {
209247
+ headEnd += 1;
209248
+ }
209249
+ const existing = messages[headEnd];
209250
+ if (existing?.info.id === TODO_HEAD_ANCHOR_ID) {
209251
+ injectToolPartIntoAssistantById(messages, TODO_HEAD_ANCHOR_ID, part);
209252
+ return TODO_HEAD_ANCHOR_ID;
209253
+ }
209254
+ messages.splice(headEnd, 0, {
209255
+ info: {
209256
+ id: TODO_HEAD_ANCHOR_ID,
209257
+ role: "assistant",
209258
+ sessionID: sessionId
209259
+ },
209260
+ parts: [part]
209261
+ });
209262
+ return TODO_HEAD_ANCHOR_ID;
209263
+ }
209264
+ function injectPersistedTodoAnchor(messages, sessionId, messageId2, part) {
209265
+ if (injectToolPartIntoAssistantById(messages, messageId2, part))
209266
+ return true;
209267
+ if (messageId2 !== TODO_HEAD_ANCHOR_ID)
209090
209268
  return false;
209269
+ injectSyntheticTodoAtHead(messages, sessionId, part);
209270
+ return true;
209271
+ }
209272
+ function dropMarkerSummaryTag2(db, sessionId, summaryMessageId) {
209273
+ const tagNumber = getTagNumberByMessageId(db, sessionId, `${summaryMessageId}:p0`);
209274
+ if (tagNumber !== null)
209275
+ updateTagStatus(db, sessionId, tagNumber, "dropped");
209276
+ }
209277
+ function reconcileMarkerRepresentation(messages, persistedMarkerState, options) {
209278
+ const retainedMessages = [];
209279
+ const staleSummaryIds = new Set;
209280
+ for (const message of messages) {
209281
+ if (message.info.summary !== true) {
209282
+ retainedMessages.push(message);
209283
+ continue;
209284
+ }
209285
+ const messageId2 = message.info.id;
209286
+ if (typeof messageId2 === "string" && messageId2 !== persistedMarkerState?.summaryMessageId) {
209287
+ staleSummaryIds.add(messageId2);
209288
+ }
209289
+ }
209290
+ if (staleSummaryIds.size > 0) {
209291
+ options.db.transaction(() => {
209292
+ for (const messageId2 of staleSummaryIds) {
209293
+ dropMarkerSummaryTag2(options.db, options.sessionId, messageId2);
209294
+ }
209295
+ })();
209091
209296
  }
209092
- const summaryTagNumber = args.tagger.assignTag(args.sessionId, `${args.summaryMessageId}:p0`, "message", byteSize(MARKER_SUMMARY_TEXT), args.db, 0, null, 0, null, () => ({
209297
+ const removedSummary = retainedMessages.length !== messages.length;
209298
+ if (removedSummary)
209299
+ messages.splice(0, messages.length, ...retainedMessages);
209300
+ if (persistedMarkerState === null)
209301
+ return removedSummary;
209302
+ const summaryTagNumber = options.tagger.assignTag(options.sessionId, `${persistedMarkerState.summaryMessageId}:p0`, "message", byteSize(MARKER_SUMMARY_TEXT), options.db, 0, null, 0, null, () => ({
209093
209303
  tokenCount: estimateTokens(MARKER_SUMMARY_TEXT),
209094
209304
  inputTokenCount: null,
209095
209305
  reasoningTokenCount: null
209096
209306
  }));
209097
- const summaryText = args.ctxReduceCallable ? prependTag(summaryTagNumber, MARKER_SUMMARY_TEXT) : MARKER_SUMMARY_TEXT;
209307
+ const summaryText = options.ctxReduceAvailability.frozen && options.ctxReduceAvailability.callable ? prependTag(summaryTagNumber, MARKER_SUMMARY_TEXT) : MARKER_SUMMARY_TEXT;
209098
209308
  const summaryMessage = {
209099
209309
  info: {
209100
- id: args.summaryMessageId,
209310
+ id: persistedMarkerState.summaryMessageId,
209101
209311
  role: "assistant",
209102
- sessionID: args.sessionId,
209312
+ sessionID: options.sessionId,
209103
209313
  summary: true,
209104
209314
  finish: "stop"
209105
209315
  },
209106
209316
  parts: [{ type: "text", text: summaryText }]
209107
209317
  };
209108
- const firstTailAssistant = args.messages.findIndex((message) => message.info.role === "assistant" && message.info.summary !== true);
209109
- args.messages.splice(firstTailAssistant >= 0 ? firstTailAssistant : args.messages.length, 0, summaryMessage);
209318
+ let retainedTailStart = 0;
209319
+ while (retainedTailStart < messages.length && isSyntheticHeadMessage(messages[retainedTailStart])) {
209320
+ retainedTailStart += 1;
209321
+ }
209322
+ messages.splice(retainedTailStart, 0, summaryMessage);
209110
209323
  return true;
209111
209324
  }
209112
209325
  function pendingMarkerCoveredByConsumedBoundary(pending, injection) {
@@ -209488,6 +209701,53 @@ async function runPostTransformPhase(args) {
209488
209701
  }
209489
209702
  }
209490
209703
  logTransformTiming(args.sessionId, "pp.nudgeAndSticky", tNudgeBlock);
209704
+ const explicitRebuildHappened = args.historyRefreshExplicitBeforePrepare && args.rebuiltHistoryFromInitialPrepare;
209705
+ const materializationSatisfied = !deferredMaterializationWasPending || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully;
209706
+ const historyWasConsumedThisPass = args.historyRebuiltThisPass && (args.canConsumeDeferredLate || args.phaseJustAwaitedPublication || explicitRebuildHappened) && materializationSatisfied;
209707
+ let suppressV12HistoryDrain = false;
209708
+ if (historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart) {
209709
+ const pending = getPendingCompactionMarkerState(args.db, args.sessionId);
209710
+ if (pending) {
209711
+ if (!pendingMarkerCoveredByConsumedBoundary(pending, args.pendingCompartmentInjection)) {
209712
+ suppressV12HistoryDrain = true;
209713
+ sessionLog(args.sessionId, `compaction-marker drain: pending ordinal ${pending.ordinal} is newer than consumed boundary ${args.pendingCompartmentInjection?.compartmentEndMessage ?? "<none>"}; preserving deferred history refresh signal`);
209714
+ } else {
209715
+ const outcome = applyDeferredCompactionMarker(args.db, args.sessionId, pending, args.sessionDirectory);
209716
+ switch (outcome.kind) {
209717
+ case "applied":
209718
+ case "already-current":
209719
+ case "stale-skip":
209720
+ if (clearPendingCompactionMarkerAfterSuccessfulDrain({
209721
+ db: args.db,
209722
+ sessionId: args.sessionId,
209723
+ pending,
209724
+ deferredHistoryRefreshSessions: args.deferredHistoryRefreshSessions
209725
+ }) === "cas-lost-newer-pending") {
209726
+ suppressV12HistoryDrain = true;
209727
+ }
209728
+ break;
209729
+ case "retryable-failure":
209730
+ args.passOutcome?.record("compaction-marker-drain-failure");
209731
+ sessionLog(args.sessionId, "compaction-marker drain: retryable failure; preserving deferred history refresh signal", outcome.error);
209732
+ suppressV12HistoryDrain = true;
209733
+ break;
209734
+ }
209735
+ }
209736
+ }
209737
+ }
209738
+ reconcileMarkerRepresentation(args.messages, getPersistedCompactionMarkerState(args.db, args.sessionId), {
209739
+ db: args.db,
209740
+ sessionId: args.sessionId,
209741
+ tagger: args.tagger,
209742
+ ctxReduceAvailability: args.ctxReduceAvailability
209743
+ });
209744
+ const deferredHistoryDrainEligible = historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart && !suppressV12HistoryDrain;
209745
+ if (deferredHistoryDrainEligible) {
209746
+ args.deferredHistoryRefreshSessions.delete(args.sessionId);
209747
+ }
209748
+ if ((explicitMaterializedSuccessfully || deferredMaterializedSuccessfully) && deferredMaterializationAtPassStart) {
209749
+ args.deferredMaterializationSessions.delete(args.sessionId);
209750
+ }
209491
209751
  const tNoteAndTodo = performance.now();
209492
209752
  const noteReadStillVisible = args.fullFeatureMode ? hasVisibleNoteReadCall(args.messages) : false;
209493
209753
  const deferredNoteText = args.fullFeatureMode ? peekNoteNudgeText(args.db, args.sessionId, args.currentTurnId, args.projectPath, noteReadStillVisible) : null;
@@ -209512,29 +209772,22 @@ async function runPostTransformPhase(args) {
209512
209772
  if (persistedAnchor) {
209513
209773
  clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
209514
209774
  }
209515
- } else if (persistedAnchor && persistedAnchor.callId === part.callID && injectToolPartIntoAssistantById(args.messages, persistedAnchor.messageId, part)) {
209775
+ } else if (persistedAnchor && persistedAnchor.callId === part.callID && injectPersistedTodoAnchor(args.messages, args.sessionId, persistedAnchor.messageId, part)) {
209516
209776
  if (persistedAnchor.stateJson.length === 0) {
209517
209777
  setPersistedTodoSyntheticAnchor(args.db, args.sessionId, persistedAnchor.callId, persistedAnchor.messageId, args.sessionMeta.lastTodoState);
209518
209778
  }
209519
209779
  } else {
209520
- const anchoredMessageId = injectToolPartIntoLatestAssistant(args.messages, part);
209521
- if (anchoredMessageId) {
209522
- setPersistedTodoSyntheticAnchor(args.db, args.sessionId, part.callID, anchoredMessageId, args.sessionMeta.lastTodoState);
209523
- } else if (persistedAnchor) {
209524
- clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
209525
- }
209780
+ const anchoredMessageId = injectToolPartIntoLatestAssistant(args.messages, part) ?? injectSyntheticTodoAtHead(args.messages, args.sessionId, part);
209781
+ setPersistedTodoSyntheticAnchor(args.db, args.sessionId, part.callID, anchoredMessageId, args.sessionMeta.lastTodoState);
209526
209782
  }
209527
209783
  } else if (persistedAnchor && persistedAnchor.stateJson.length > 0) {
209528
209784
  const part = buildSyntheticTodoPart(persistedAnchor.stateJson);
209529
209785
  if (part !== null && part.callID === persistedAnchor.callId) {
209530
- injectToolPartIntoAssistantById(args.messages, persistedAnchor.messageId, part);
209786
+ injectPersistedTodoAnchor(args.messages, args.sessionId, persistedAnchor.messageId, part);
209531
209787
  }
209532
209788
  }
209533
209789
  }
209534
209790
  logTransformTiming(args.sessionId, "pp.noteAndTodoSynthesis", tNoteAndTodo);
209535
- const explicitRebuildHappened = args.historyRefreshExplicitBeforePrepare && args.rebuiltHistoryFromInitialPrepare;
209536
- const materializationSatisfied = !deferredMaterializationWasPending || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully;
209537
- const historyWasConsumedThisPass = args.historyRebuiltThisPass && (args.canConsumeDeferredLate || args.phaseJustAwaitedPublication || explicitRebuildHappened) && materializationSatisfied;
209538
209791
  if (args.compartmentInjectionRebuiltFromDb && args.pendingCompartmentInjection) {
209539
209792
  if (args.pendingCompartmentInjection.compartmentEndMessageId === null) {
209540
209793
  const nextCount = (degradedCacheCountBySession.get(args.sessionId) ?? 0) + 1;
@@ -209546,54 +209799,6 @@ async function runPostTransformPhase(args) {
209546
209799
  degradedCacheCountBySession.delete(args.sessionId);
209547
209800
  }
209548
209801
  }
209549
- let suppressV12HistoryDrain = false;
209550
- if (historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart) {
209551
- const pending = getPendingCompactionMarkerState(args.db, args.sessionId);
209552
- if (pending) {
209553
- if (!pendingMarkerCoveredByConsumedBoundary(pending, args.pendingCompartmentInjection)) {
209554
- suppressV12HistoryDrain = true;
209555
- sessionLog(args.sessionId, `compaction-marker drain: pending ordinal ${pending.ordinal} is newer than consumed boundary ${args.pendingCompartmentInjection?.compartmentEndMessage ?? "<none>"}; preserving deferred history refresh signal`);
209556
- } else {
209557
- const outcome = applyDeferredCompactionMarker(args.db, args.sessionId, pending, args.sessionDirectory);
209558
- if (outcome.kind === "applied") {
209559
- injectDeferredCompactionSummaryRepresentation({
209560
- db: args.db,
209561
- sessionId: args.sessionId,
209562
- messages: args.messages,
209563
- tagger: args.tagger,
209564
- summaryMessageId: outcome.summaryMessageId,
209565
- ctxReduceCallable: args.ctxReduceCallable
209566
- });
209567
- }
209568
- switch (outcome.kind) {
209569
- case "applied":
209570
- case "already-current":
209571
- case "stale-skip":
209572
- if (clearPendingCompactionMarkerAfterSuccessfulDrain({
209573
- db: args.db,
209574
- sessionId: args.sessionId,
209575
- pending,
209576
- deferredHistoryRefreshSessions: args.deferredHistoryRefreshSessions
209577
- }) === "cas-lost-newer-pending") {
209578
- suppressV12HistoryDrain = true;
209579
- }
209580
- break;
209581
- case "retryable-failure":
209582
- args.passOutcome?.record("compaction-marker-drain-failure");
209583
- sessionLog(args.sessionId, "compaction-marker drain: retryable failure; preserving deferred history refresh signal", outcome.error);
209584
- suppressV12HistoryDrain = true;
209585
- break;
209586
- }
209587
- }
209588
- }
209589
- }
209590
- const deferredHistoryDrainEligible = historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart && !suppressV12HistoryDrain;
209591
- if (deferredHistoryDrainEligible) {
209592
- args.deferredHistoryRefreshSessions.delete(args.sessionId);
209593
- }
209594
- if ((explicitMaterializedSuccessfully || deferredMaterializedSuccessfully) && deferredMaterializationAtPassStart) {
209595
- args.deferredMaterializationSessions.delete(args.sessionId);
209596
- }
209597
209802
  if (args.fullFeatureMode && isCacheBustingPass && args.m0M1 && (!!args.m0M1.projectPath || !!args.m0M1.projectDirectory)) {
209598
209803
  checkM0MutationDriftAndSignal({
209599
209804
  db: args.db,
@@ -209823,7 +210028,8 @@ function createTransform(deps) {
209823
210028
  }
209824
210029
  const reducedMode = sessionMeta.isSubagent;
209825
210030
  const fullFeatureMode = !reducedMode;
209826
- const ctxReduceCallable = resolveCtxReduceAvailabilityFromMessages(sessionId, messages);
210031
+ const ctxReduceAvailability = resolveCtxReduceAvailabilityFromMessages(sessionId, messages);
210032
+ const ctxReduceCallable = ctxReduceAvailability.callable;
209827
210033
  let sessionDirectory = deps.directory ?? "";
209828
210034
  let sessionDirectoryResolvedFromHost = false;
209829
210035
  const cachedDirectory = deps.sessionDirectoryBySession?.get(sessionId);
@@ -209973,7 +210179,7 @@ function createTransform(deps) {
209973
210179
  tokensConfig: deps.executeThresholdTokens,
209974
210180
  contextLimit: emergencyCeilingLimit
209975
210181
  }) / 100)) : undefined;
209976
- const schedulerDecisionEarly = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId));
210182
+ const schedulerDecisionEarly = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId), resolvedContextLimit);
209977
210183
  const midTurn = isMidTurn(deps, resolvedSessionId);
209978
210184
  const bypassReason = detectMidTurnBypassReason({
209979
210185
  contextUsage: contextUsageEarly,
@@ -210329,7 +210535,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
210329
210535
  reasoningByMessage,
210330
210536
  messageTagNumbers,
210331
210537
  tagger: deps.tagger,
210332
- ctxReduceCallable,
210538
+ ctxReduceAvailability,
210333
210539
  batch,
210334
210540
  contextUsage,
210335
210541
  schedulerDecision,
@@ -211660,7 +211866,7 @@ function createToolExecuteAfterHook(args) {
211660
211866
  init_send_session_notification();
211661
211867
 
211662
211868
  // src/hooks/magic-context/system-prompt-hash.ts
211663
- import { createHash as createHash17 } from "node:crypto";
211869
+ import { createHash as createHash18 } from "node:crypto";
211664
211870
 
211665
211871
  // src/agents/magic-context-prompt.ts
211666
211872
  init_language_directive();
@@ -211864,7 +212070,7 @@ function createSystemPromptHashHandler(deps) {
211864
212070
  return;
211865
212071
  if (!availability.frozen)
211866
212072
  return;
211867
- const currentHash = createHash17("md5").update(systemContent).digest("hex");
212073
+ const currentHash = createHash18("md5").update(systemContent).digest("hex");
211868
212074
  if (!sessionMetaEarly) {
211869
212075
  return;
211870
212076
  }
@@ -212939,7 +213145,13 @@ init_decay_render();
212939
213145
  init_read_session_formatting();
212940
213146
  await init_inject_compartments();
212941
213147
  function computeM0BlockTokens(db, sessionId, args) {
212942
- const { m0Text, projectIdentity, injectionBudgetTokens, memoryBlockCount } = args;
213148
+ const {
213149
+ m0Text,
213150
+ projectIdentity,
213151
+ injectionBudgetTokens,
213152
+ memoryBlockCount,
213153
+ compartmentTokensOverride
213154
+ } = args;
212943
213155
  const docsBlock = extractM0Block(m0Text, "project-docs");
212944
213156
  const docsTokens = docsBlock ? estimateTokens(docsBlock) : 0;
212945
213157
  const profileBlock = extractM0Block(m0Text, "user-profile");
@@ -212953,7 +213165,9 @@ function computeM0BlockTokens(db, sessionId, args) {
212953
213165
  }
212954
213166
  let compartmentTokens = 0;
212955
213167
  const historyBlock = extractM0Block(m0Text, "session-history");
212956
- if (historyBlock) {
213168
+ if (typeof compartmentTokensOverride === "number" && Number.isFinite(compartmentTokensOverride) && compartmentTokensOverride >= 0) {
213169
+ compartmentTokens = compartmentTokensOverride;
213170
+ } else if (historyBlock) {
212957
213171
  compartmentTokens = estimateTokens(historyBlock);
212958
213172
  } else {
212959
213173
  try {
@@ -213124,7 +213338,8 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
213124
213338
  m0Text,
213125
213339
  projectIdentity,
213126
213340
  injectionBudgetTokens,
213127
- memoryBlockCount
213341
+ memoryBlockCount,
213342
+ compartmentTokensOverride: moduleStatus?.compartment_tokens
213128
213343
  });
213129
213344
  const compartmentTokens = m0Blocks.compartmentTokens;
213130
213345
  const factTokens = m0Blocks.factTokens;
@@ -214510,7 +214725,7 @@ Mark discardable once processed: large outputs you've summarized, repeated or re
214510
214725
  Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
214511
214726
  Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
214512
214727
  // src/tools/ctx-reduce/tools.ts
214513
- import { createHash as createHash18 } from "node:crypto";
214728
+ import { createHash as createHash19 } from "node:crypto";
214514
214729
  import { tool as tool4 } from "@opencode-ai/plugin";
214515
214730
 
214516
214731
  // src/features/magic-context/range-parser.ts
@@ -214577,11 +214792,11 @@ function createCtxReduceTool(deps) {
214577
214792
  const stableId = `oc-${sessionId}-${callId}`;
214578
214793
  if (Buffer.byteLength(stableId) <= 128)
214579
214794
  return stableId;
214580
- return `oc-${createHash18("sha256").update(stableId).digest("hex")}`;
214795
+ return `oc-${createHash19("sha256").update(stableId).digest("hex")}`;
214581
214796
  }
214582
214797
  fallbackCommandSequence += 1;
214583
214798
  const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
214584
- return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash18("sha256").update(monotonicId).digest("hex")}`;
214799
+ return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash19("sha256").update(monotonicId).digest("hex")}`;
214585
214800
  };
214586
214801
  return tool4({
214587
214802
  description: CTX_REDUCE_DESCRIPTION,
@@ -214998,11 +215213,11 @@ import {
214998
215213
  import { dirname as dirname9 } from "node:path";
214999
215214
 
215000
215215
  // src/shared/rpc-utils.ts
215001
- import { createHash as createHash19 } from "node:crypto";
215216
+ import { createHash as createHash20 } from "node:crypto";
215002
215217
  import { join as join21 } from "node:path";
215003
215218
  function projectHash(directory) {
215004
215219
  const normalized = directory.replace(/\/+$/, "");
215005
- return createHash19("sha256").update(normalized).digest("hex").slice(0, 16);
215220
+ return createHash20("sha256").update(normalized).digest("hex").slice(0, 16);
215006
215221
  }
215007
215222
  function rpcPortDir(storageDir, directory) {
215008
215223
  return join21(storageDir, "rpc", projectHash(directory));