@cortexkit/opencode-magic-context 0.32.2 → 0.32.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 (32) 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 +395 -174
  24. package/dist/plugin/rpc-handlers.d.ts +1 -0
  25. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  26. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  27. package/dist/shared/subagent-runner.d.ts +4 -1
  28. package/dist/shared/subagent-runner.d.ts.map +1 -1
  29. package/package.json +1 -1
  30. package/src/shared/model-suggestion-retry.test.ts +41 -1
  31. package/src/shared/model-suggestion-retry.ts +47 -26
  32. package/src/shared/subagent-runner.ts +4 -0
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) {
@@ -16391,6 +16455,9 @@ function modelBodyField(spec) {
16391
16455
  }
16392
16456
 
16393
16457
  // src/shared/model-suggestion-retry.ts
16458
+ function copyPromptArgs(args, body) {
16459
+ return { ...args, body: { ...body } };
16460
+ }
16394
16461
  function extractMessage(error51) {
16395
16462
  if (typeof error51 === "string")
16396
16463
  return error51;
@@ -16504,40 +16571,41 @@ function shortErr(error51) {
16504
16571
  return extractMessage(error51);
16505
16572
  }
16506
16573
  async function attemptOnce(client, args, timeoutMs, signal, callContext, label) {
16574
+ const originalBody = { ...args.body };
16575
+ const attemptArgs = copyPromptArgs(args, originalBody);
16507
16576
  try {
16508
- await promptWithTimeout(client, args, timeoutMs, signal);
16577
+ await promptWithTimeout(client, attemptArgs, timeoutMs, signal);
16509
16578
  return;
16510
16579
  } catch (error51) {
16511
16580
  if (isNonRetryable(error51, signal))
16512
16581
  throw error51;
16513
16582
  const suggestion = parseModelSuggestion(error51);
16514
- if (!suggestion || !args.body.model) {
16583
+ if (!suggestion || !originalBody.model) {
16515
16584
  throw error51;
16516
16585
  }
16517
16586
  log(`[${callContext}] ${label}: model not found, retrying with suggestion`, {
16518
16587
  original: `${suggestion.providerID}/${suggestion.modelID}`,
16519
16588
  suggested: suggestion.suggestion
16520
16589
  });
16521
- await promptWithTimeout(client, {
16522
- ...args,
16523
- body: {
16524
- ...args.body,
16525
- model: {
16526
- providerID: suggestion.providerID,
16527
- modelID: suggestion.suggestion
16528
- }
16590
+ await promptWithTimeout(client, copyPromptArgs(args, {
16591
+ ...originalBody,
16592
+ model: {
16593
+ providerID: suggestion.providerID,
16594
+ modelID: suggestion.suggestion
16529
16595
  }
16530
- }, timeoutMs, signal);
16596
+ }), timeoutMs, signal);
16531
16597
  }
16532
16598
  }
16533
16599
  async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
16534
16600
  const timeoutMs = options.timeoutMs ?? 300000;
16535
16601
  const callContext = options.callContext ?? "subagent";
16536
16602
  const fallbacks = options.fallbackModels ?? [];
16537
- const explicitPrimaryLabel = args.body.model?.providerID && args.body.model.modelID ? `${args.body.model.providerID}/${args.body.model.modelID}` : "primary";
16603
+ const baseBody = { ...args.body };
16604
+ const baseArgs = copyPromptArgs(args, baseBody);
16605
+ const explicitPrimaryLabel = baseBody.model?.providerID && baseBody.model.modelID ? `${baseBody.model.providerID}/${baseBody.model.modelID}` : "primary";
16538
16606
  let lastError = null;
16539
16607
  try {
16540
- await attemptOnce(client, args, timeoutMs, options.signal, callContext, explicitPrimaryLabel);
16608
+ await attemptOnce(client, baseArgs, timeoutMs, options.signal, callContext, explicitPrimaryLabel);
16541
16609
  return;
16542
16610
  } catch (error51) {
16543
16611
  lastError = error51;
@@ -16555,10 +16623,10 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
16555
16623
  continue;
16556
16624
  }
16557
16625
  const label = `${parsed.providerID}/${parsed.modelID}`;
16558
- const attemptArgs = {
16559
- ...args,
16560
- body: { ...args.body, model: parsed }
16561
- };
16626
+ const attemptArgs = copyPromptArgs(baseArgs, {
16627
+ ...baseBody,
16628
+ model: parsed
16629
+ });
16562
16630
  try {
16563
16631
  await attemptOnce(client, attemptArgs, timeoutMs, options.signal, callContext, label);
16564
16632
  log(`[${callContext}] fallback succeeded with ${label} (attempt ${i + 2}/${fallbacks.length + 1})`);
@@ -16586,17 +16654,19 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
16586
16654
  const timeoutMs = options.timeoutMs ?? 300000;
16587
16655
  const callContext = options.callContext ?? "subagent";
16588
16656
  const fallbacks = options.fallbackModels ?? [];
16589
- const explicitPrimaryLabel = args.body.model?.providerID && args.body.model.modelID ? `${args.body.model.providerID}/${args.body.model.modelID}` : "primary";
16657
+ const baseBody = { ...args.body };
16658
+ const baseArgs = copyPromptArgs(args, baseBody);
16659
+ const explicitPrimaryLabel = baseBody.model?.providerID && baseBody.model.modelID ? `${baseBody.model.providerID}/${baseBody.model.modelID}` : "primary";
16590
16660
  const totalAttempts = fallbacks.length + 1;
16591
16661
  let firstError = null;
16592
16662
  let lastError = null;
16593
16663
  try {
16594
- return await attemptAndValidate(client, args, timeoutMs, options.signal, callContext, {
16664
+ return await attemptAndValidate(client, baseArgs, timeoutMs, options.signal, callContext, {
16595
16665
  label: explicitPrimaryLabel,
16596
16666
  attemptIndex: 0,
16597
16667
  isFallback: false,
16598
16668
  totalAttempts,
16599
- model: args.body.model
16669
+ model: baseBody.model
16600
16670
  }, options);
16601
16671
  } catch (error51) {
16602
16672
  firstError = error51;
@@ -16615,10 +16685,10 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
16615
16685
  continue;
16616
16686
  }
16617
16687
  const label = `${parsed.providerID}/${parsed.modelID}`;
16618
- const attemptArgs = {
16619
- ...args,
16620
- body: { ...args.body, model: parsed }
16621
- };
16688
+ const attemptArgs = copyPromptArgs(baseArgs, {
16689
+ ...baseBody,
16690
+ model: parsed
16691
+ });
16622
16692
  const attempt = {
16623
16693
  label,
16624
16694
  attemptIndex: i + 1,
@@ -151678,7 +151748,7 @@ var init_project_identity2 = __esm(() => {
151678
151748
  });
151679
151749
 
151680
151750
  // src/features/magic-context/workspaces.ts
151681
- import { createHash as createHash2 } from "node:crypto";
151751
+ import { createHash as createHash3 } from "node:crypto";
151682
151752
  function tableExists(db, tableName) {
151683
151753
  const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name = ? LIMIT 1").get(tableName);
151684
151754
  return Boolean(row);
@@ -151862,7 +151932,7 @@ function computeWorkspaceEpochFingerprint(db, identities) {
151862
151932
  const canonical = uniqueSorted(identities.filter((identity) => identity.length > 0));
151863
151933
  const epochs = getEpochMap(db, canonical);
151864
151934
  const shareCategories = selectWorkspaceShareCategories(db, canonical);
151865
- const hash2 = createHash2("sha256");
151935
+ const hash2 = createHash3("sha256");
151866
151936
  hash2.update("share_categories", "utf8");
151867
151937
  hash2.update("\x00");
151868
151938
  hash2.update(shareCategories === null ? "NO_WORKSPACE" : JSON.stringify(shareCategories), "utf8");
@@ -153501,7 +153571,7 @@ var init_migrations = __esm(() => {
153501
153571
  });
153502
153572
 
153503
153573
  // src/features/magic-context/project-docs-hash.ts
153504
- import { createHash as createHash3 } from "node:crypto";
153574
+ import { createHash as createHash4 } from "node:crypto";
153505
153575
  import { lstatSync, readFileSync as readFileSync6, statSync as statSync3 } from "node:fs";
153506
153576
  import path4 from "node:path";
153507
153577
  function canonicalizeDocContent(raw) {
@@ -153591,7 +153661,7 @@ function hashCanonicalPieces(hashPieces) {
153591
153661
  if (hashPieces.length === 0) {
153592
153662
  return "";
153593
153663
  }
153594
- return createHash3("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
153664
+ return createHash4("sha256").update(hashPieces.join(PROJECT_DOCS_DELIMITER), "utf8").digest("hex");
153595
153665
  }
153596
153666
  function readProjectDocsCanonical(projectDirectory) {
153597
153667
  const canonicalDirectory = path4.resolve(projectDirectory);
@@ -153671,13 +153741,13 @@ function stableStringify(value, seen = new WeakSet) {
153671
153741
  }
153672
153742
 
153673
153743
  // src/features/magic-context/tool-definition-tokens.ts
153674
- import { createHash as createHash4 } from "node:crypto";
153744
+ import { createHash as createHash5 } from "node:crypto";
153675
153745
  function keyFor(providerID, modelID, agentName) {
153676
153746
  const agent = agentName && agentName.length > 0 ? agentName : "default";
153677
153747
  return `${providerID}/${modelID}/${agent}`;
153678
153748
  }
153679
153749
  function fingerprintFor(description, parameters) {
153680
- return createHash4("sha256").update(description).update("\x00").update(stableStringify(parameters)).digest("hex");
153750
+ return createHash5("sha256").update(description).update("\x00").update(stableStringify(parameters)).digest("hex");
153681
153751
  }
153682
153752
  function setDatabase(db) {
153683
153753
  persistenceDb = db;
@@ -155326,10 +155396,10 @@ var init_storage_db = __esm(async () => {
155326
155396
  });
155327
155397
 
155328
155398
  // src/features/magic-context/storage-embedding-measurements.ts
155329
- import { createHash as createHash5 } from "node:crypto";
155399
+ import { createHash as createHash6 } from "node:crypto";
155330
155400
  function normalizedQueryHash(query) {
155331
155401
  const normalized = query.trim().replace(/\s+/g, " ").toLowerCase();
155332
- return createHash5("sha256").update(normalized).digest("hex");
155402
+ return createHash6("sha256").update(normalized).digest("hex");
155333
155403
  }
155334
155404
  function recordEmbeddingMeasurement(db, input) {
155335
155405
  const queryTextHash = normalizedQueryHash(input.queryText);
@@ -168888,13 +168958,13 @@ var init_embedding_cache = __esm(() => {
168888
168958
  });
168889
168959
 
168890
168960
  // src/features/magic-context/memory/normalize-hash.ts
168891
- import { createHash as createHash7 } from "node:crypto";
168961
+ import { createHash as createHash8 } from "node:crypto";
168892
168962
  function normalizeMemoryContent(content) {
168893
168963
  return content.toLowerCase().replace(/\s+/g, " ").trim();
168894
168964
  }
168895
168965
  function computeNormalizedHash(content) {
168896
168966
  const normalized = normalizeMemoryContent(content);
168897
- return createHash7("md5").update(normalized).digest("hex");
168967
+ return createHash8("md5").update(normalized).digest("hex");
168898
168968
  }
168899
168969
  var init_normalize_hash = () => {};
168900
168970
 
@@ -170617,7 +170687,7 @@ var init_recursive_text_splitter = __esm(() => {
170617
170687
  });
170618
170688
 
170619
170689
  // src/features/magic-context/compartment-chunk-embedding.ts
170620
- import { createHash as createHash9 } from "node:crypto";
170690
+ import { createHash as createHash10 } from "node:crypto";
170621
170691
  function getLoadFtsRowsStatement(db) {
170622
170692
  let stmt = loadFtsRowsStatements.get(db);
170623
170693
  if (!stmt) {
@@ -170728,7 +170798,7 @@ function parseCanonicalLineRange(line) {
170728
170798
  return { start, end };
170729
170799
  }
170730
170800
  function hashChunkText(text) {
170731
- return createHash9("sha256").update(text).digest("hex");
170801
+ return createHash10("sha256").update(text).digest("hex");
170732
170802
  }
170733
170803
  function vectorBlob2(vector) {
170734
170804
  return new Uint8Array(vector.buffer, vector.byteOffset, vector.byteLength);
@@ -171138,7 +171208,7 @@ function cosineSimilarity(a, b) {
171138
171208
  }
171139
171209
 
171140
171210
  // src/features/magic-context/memory/embedding-synapse.ts
171141
- import { createHash as createHash10 } from "node:crypto";
171211
+ import { createHash as createHash11 } from "node:crypto";
171142
171212
  function isPermanentSynapseCode(code) {
171143
171213
  return code === "artifact_invalid" || code === "substitution_rejected" || code === "not_certified" || code === "probe_required" || code === "idempotency_conflict" || code === "schema_violation";
171144
171214
  }
@@ -171202,7 +171272,7 @@ function wait(ms) {
171202
171272
  return new Promise((resolve4) => setTimeout(resolve4, ms));
171203
171273
  }
171204
171274
  function sha256(value) {
171205
- return createHash10("sha256").update(value).digest("hex");
171275
+ return createHash11("sha256").update(value).digest("hex");
171206
171276
  }
171207
171277
  function stableJson(value) {
171208
171278
  if (Array.isArray(value))
@@ -172684,7 +172754,7 @@ var init_sweep_coordinator = __esm(() => {
172684
172754
  });
172685
172755
 
172686
172756
  // src/features/magic-context/project-embedding-registry.ts
172687
- import { createHash as createHash11, randomUUID as randomUUID4 } from "node:crypto";
172757
+ import { createHash as createHash12, randomUUID as randomUUID4 } from "node:crypto";
172688
172758
  function markProjectLoadUntrusted(projectIdentity) {
172689
172759
  untrustedLoadProjects.add(projectIdentity);
172690
172760
  }
@@ -172849,10 +172919,10 @@ function stableStringify2(value) {
172849
172919
  return JSON.stringify(value);
172850
172920
  }
172851
172921
  function sha256Prefix(value, length = 16) {
172852
- return createHash11("sha256").update(value).digest("hex").slice(0, length);
172922
+ return createHash12("sha256").update(value).digest("hex").slice(0, length);
172853
172923
  }
172854
172924
  function contentSha256(value) {
172855
- return createHash11("sha256").update(value).digest("hex");
172925
+ return createHash12("sha256").update(value).digest("hex");
172856
172926
  }
172857
172927
  function getRuntimeFingerprint(config2) {
172858
172928
  if (config2.provider === "off") {
@@ -181623,6 +181693,19 @@ var init_compartment_embedding = __esm(() => {
181623
181693
 
181624
181694
  // src/hooks/magic-context/compaction-marker-manager.ts
181625
181695
  import { join as join18 } from "node:path";
181696
+ function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
181697
+ const tagNumber = getTagNumberByMessageId(db, sessionId, `${summaryMessageId}:p0`);
181698
+ if (tagNumber !== null)
181699
+ updateTagStatus(db, sessionId, tagNumber, "dropped");
181700
+ }
181701
+ function persistMarkerStateAndDropReplacedTag(db, sessionId, state, replacedSummaryMessageId) {
181702
+ db.transaction(() => {
181703
+ setPersistedCompactionMarkerState(db, sessionId, state);
181704
+ if (replacedSummaryMessageId !== null) {
181705
+ dropMarkerSummaryTag(db, sessionId, replacedSummaryMessageId);
181706
+ }
181707
+ })();
181708
+ }
181626
181709
  function validatePendingTarget(db, sessionId, pending) {
181627
181710
  const ocMessage = getOpenCodeMessageById(sessionId, pending.endMessageId);
181628
181711
  if (!ocMessage) {
@@ -181690,6 +181773,7 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory) {
181690
181773
  error: new Error(`no user boundary found at or before endMessageId ${pending.endMessageId} (ordinal ${pending.ordinal}); preserving existing marker`)
181691
181774
  };
181692
181775
  }
181776
+ const removedSummaryMessageId = existing?.summaryMessageId ?? null;
181693
181777
  if (existing) {
181694
181778
  const removed = removeCompactionMarker(existing);
181695
181779
  if (!removed) {
@@ -181714,17 +181798,15 @@ function applyDeferredCompactionMarker(db, sessionId, pending, directory) {
181714
181798
  error: new Error(`injectCompactionMarker returned null for ordinal ${pending.ordinal}; will retry`)
181715
181799
  };
181716
181800
  }
181717
- setPersistedCompactionMarkerState(db, sessionId, {
181801
+ persistMarkerStateAndDropReplacedTag(db, sessionId, {
181718
181802
  ...result,
181719
181803
  boundaryOrdinal: pending.ordinal,
181720
181804
  targetEndMessageId: pending.endMessageId
181721
- });
181805
+ }, removedSummaryMessageId);
181722
181806
  sessionLog(sessionId, `compaction-marker drain: applied at ordinal ${pending.ordinal}, boundary user msg ${result.boundaryMessageId}`);
181723
181807
  return {
181724
181808
  kind: "applied",
181725
- markerOrdinal: pending.ordinal,
181726
- summaryMessageId: result.summaryMessageId,
181727
- boundaryMessageId: result.boundaryMessageId
181809
+ markerOrdinal: pending.ordinal
181728
181810
  };
181729
181811
  } catch (err) {
181730
181812
  const error51 = err instanceof Error ? err : new Error(String(err));
@@ -181742,6 +181824,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
181742
181824
  return false;
181743
181825
  }
181744
181826
  const existing = getPersistedCompactionMarkerState(db, sessionId);
181827
+ const removedSummaryMessageId = existing?.summaryMessageId ?? null;
181745
181828
  if (existing) {
181746
181829
  if (existingMarkerAlreadyCoversTarget(sessionId, existing, lastCompartmentEnd, targetEndMessageId)) {
181747
181830
  return true;
@@ -181758,7 +181841,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
181758
181841
  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
181842
  return false;
181760
181843
  }
181761
- setPersistedCompactionMarkerState(db, sessionId, null);
181844
+ persistMarkerStateAndDropReplacedTag(db, sessionId, null, removedSummaryMessageId);
181762
181845
  sessionLog(sessionId, `compaction-marker: removed old boundary at ordinal ${existing.boundaryOrdinal}, moving to ${lastCompartmentEnd}`);
181763
181846
  }
181764
181847
  const result = injectCompactionMarker({
@@ -181770,11 +181853,11 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
181770
181853
  resolvedBoundary: boundary
181771
181854
  });
181772
181855
  if (result) {
181773
- setPersistedCompactionMarkerState(db, sessionId, {
181856
+ persistMarkerStateAndDropReplacedTag(db, sessionId, {
181774
181857
  ...result,
181775
181858
  boundaryOrdinal: lastCompartmentEnd,
181776
181859
  targetEndMessageId
181777
- });
181860
+ }, removedSummaryMessageId);
181778
181861
  sessionLog(sessionId, `compaction-marker: injected at ordinal ${lastCompartmentEnd}, boundary user msg ${result.boundaryMessageId}`);
181779
181862
  return true;
181780
181863
  }
@@ -181849,6 +181932,7 @@ var MARKER_SUMMARY_TEXT = "[Compacted by magic-context — session history is ma
181849
181932
  var init_compaction_marker_manager = __esm(async () => {
181850
181933
  init_compartment_storage();
181851
181934
  init_storage_meta_persisted();
181935
+ init_storage_tags();
181852
181936
  init_data_path();
181853
181937
  init_logger();
181854
181938
  await __promiseAll([
@@ -184097,7 +184181,7 @@ function softRefreshCachedM1(options) {
184097
184181
  }
184098
184182
  function prependM0M1Messages(sessionId, messages, m0Text, m1Text) {
184099
184183
  messages.unshift({
184100
- info: { role: "user", sessionID: sessionId },
184184
+ info: { role: "user", sessionID: sessionId, syntheticHead: true },
184101
184185
  parts: [
184102
184186
  {
184103
184187
  type: "text",
@@ -184106,7 +184190,7 @@ function prependM0M1Messages(sessionId, messages, m0Text, m1Text) {
184106
184190
  }
184107
184191
  ]
184108
184192
  }, {
184109
- info: { role: "user", sessionID: sessionId },
184193
+ info: { role: "user", sessionID: sessionId, syntheticHead: true },
184110
184194
  parts: [{ type: "text", text: m1Text, synthetic: true }]
184111
184195
  });
184112
184196
  }
@@ -190914,6 +190998,7 @@ init_magic_context();
190914
190998
 
190915
190999
  // src/config/transform-mode.ts
190916
191000
  var warnedShadowProjects = new Set;
191001
+ var warnedCavemanProjects = new Set;
190917
191002
  var RUST_REQUIRES_USER_SUBC_WARNING = "rust mode requires user-level subc configuration; running ts.";
190918
191003
  var SHADOW_TRANSFORM_WARNING = 'shadow_transform is ignored while transform_mode is "rust" (a session cannot shadow itself); shadow disabled for these sessions.';
190919
191004
  var CAVEMAN_RUST_WARNING = "caveman_text_compression is TS-only and inert in rust mode.";
@@ -190933,7 +191018,11 @@ function resolveTransformMode(args) {
190933
191018
  }
190934
191019
  }
190935
191020
  if (args.configured === "rust" && args.cavemanCompressionEnabled) {
190936
- warnings.push(CAVEMAN_RUST_WARNING);
191021
+ const projectKey = args.projectKey ?? "<unspecified-project>";
191022
+ if (!warnedCavemanProjects.has(projectKey)) {
191023
+ warnedCavemanProjects.add(projectKey);
191024
+ warnings.push(CAVEMAN_RUST_WARNING);
191025
+ }
190937
191026
  }
190938
191027
  return { mode: args.configured, warnings };
190939
191028
  }
@@ -192131,7 +192220,7 @@ await init_storage_db();
192131
192220
  // src/features/magic-context/v22-deferred-backfill.ts
192132
192221
  init_logger();
192133
192222
  init_project_identity();
192134
- import { createHash as createHash6 } from "node:crypto";
192223
+ import { createHash as createHash7 } from "node:crypto";
192135
192224
  import { realpathSync as realpathSync2 } from "node:fs";
192136
192225
  import path5 from "node:path";
192137
192226
 
@@ -192193,7 +192282,7 @@ function computeLegacyRustDirIdentity(rawProjectPath) {
192193
192282
  } catch {
192194
192283
  canonical = path5.isAbsolute(rawProjectPath) ? rawProjectPath : path5.join(process.cwd(), rawProjectPath);
192195
192284
  }
192196
- return `dir:${createHash6("sha256").update(canonical, "utf8").digest("hex")}`;
192285
+ return `dir:${createHash7("sha256").update(canonical, "utf8").digest("hex")}`;
192197
192286
  }
192198
192287
  function upsertRekeyMap(db, oldProjectPath, newProjectPath, rekeyedAt) {
192199
192288
  db.prepare(`INSERT INTO v22_identity_rekey_map (old_project_path, new_project_path, rekeyed_at)
@@ -195670,7 +195759,7 @@ function recordRetrospectiveWindowProcessed(db, projectPath, windowKey) {
195670
195759
  init_task_config();
195671
195760
 
195672
195761
  // src/features/magic-context/dreamer/task-executor.ts
195673
- import { createHash as createHash13 } from "node:crypto";
195762
+ import { createHash as createHash14 } from "node:crypto";
195674
195763
  import { existsSync as existsSync20 } from "node:fs";
195675
195764
 
195676
195765
  // src/agents/dreamer.ts
@@ -196965,7 +197054,7 @@ function throwIfAborted2(signal) {
196965
197054
  }
196966
197055
 
196967
197056
  // src/features/magic-context/smart-notes/compiler.ts
196968
- import { createHash as createHash12 } from "node:crypto";
197057
+ import { createHash as createHash13 } from "node:crypto";
196969
197058
  init_shared();
196970
197059
  init_assistant_message_extractor();
196971
197060
  init_logger();
@@ -197373,7 +197462,7 @@ function manifestAdvisoryWarnings(code, manifest) {
197373
197462
  return warnings;
197374
197463
  }
197375
197464
  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");
197465
+ return createHash13("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
197377
197466
  }
197378
197467
  function extractJsonObject(output) {
197379
197468
  const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
@@ -199842,7 +199931,7 @@ function parseFrictionGateVerdict(verdict) {
199842
199931
  }
199843
199932
  function computeRetrospectiveWindowKey(flagged) {
199844
199933
  const anchors = flagged.map((message) => `${message.sessionId}:${message.ts}`).sort().join("|");
199845
- return createHash13("sha256").update(anchors).digest("hex").slice(0, 32);
199934
+ return createHash14("sha256").update(anchors).digest("hex").slice(0, 32);
199846
199935
  }
199847
199936
  function renderFrictionWindow(messages, flaggedOrdinals, radius = 2) {
199848
199937
  const flagged = new Set(flaggedOrdinals);
@@ -201114,7 +201203,7 @@ init_logger();
201114
201203
  // src/plugin/embedding-bootstrap-helpers.ts
201115
201204
  init_embedding();
201116
201205
  init_logger();
201117
- import { createHash as createHash14 } from "node:crypto";
201206
+ import { createHash as createHash15 } from "node:crypto";
201118
201207
  var EMBEDDING_AFFECTING_KEYS = new Set([
201119
201208
  "embedding.api_key",
201120
201209
  "embedding.endpoint",
@@ -201160,7 +201249,7 @@ var EMBEDDING_WARNING_TERMS = [
201160
201249
  ];
201161
201250
  var loggedFailureSignatures = new Map;
201162
201251
  function sha256Prefix2(value, length = 16) {
201163
- return createHash14("sha256").update(value).digest("hex").slice(0, length);
201252
+ return createHash15("sha256").update(value).digest("hex").slice(0, length);
201164
201253
  }
201165
201254
  function warningLooksEmbeddingRelated(message) {
201166
201255
  const lower = message.toLowerCase();
@@ -201450,7 +201539,18 @@ function resolveTrustedContextLimit(providerID, modelID, ctx) {
201450
201539
  return detected;
201451
201540
  return fromModelsDev;
201452
201541
  }
201453
- return detected;
201542
+ if (detected !== undefined) {
201543
+ return detected;
201544
+ }
201545
+ if (modelKey && ctx?.db && ctx.sessionID) {
201546
+ try {
201547
+ const persisted = loadPersistedUsage(ctx.db, ctx.sessionID);
201548
+ if (persisted?.lastObservedModelKey === modelKey && isSaneLimit(persisted.lastUsageContextLimit)) {
201549
+ return persisted.lastUsageContextLimit;
201550
+ }
201551
+ } catch {}
201552
+ }
201553
+ return;
201454
201554
  }
201455
201555
  function resolveCacheTtl(cacheTtl, modelKey) {
201456
201556
  if (typeof cacheTtl === "string") {
@@ -204170,15 +204270,15 @@ function verdictFromToolsMap(tools) {
204170
204270
  function resolveCtxReduceAvailabilityFromMessages(sessionId, messages) {
204171
204271
  const cached2 = availabilityBySession.get(sessionId);
204172
204272
  if (cached2 !== undefined)
204173
- return cached2;
204273
+ return { callable: cached2, frozen: true };
204174
204274
  for (const message of messages) {
204175
204275
  if (message.info?.role !== "user")
204176
204276
  continue;
204177
204277
  const verdict = verdictFromToolsMap(message.info.tools) ?? true;
204178
204278
  availabilityBySession.set(sessionId, verdict);
204179
- return verdict;
204279
+ return { callable: verdict, frozen: true };
204180
204280
  }
204181
- return true;
204281
+ return { callable: true, frozen: false };
204182
204282
  }
204183
204283
  function resolveCtxReduceAvailability(sessionId) {
204184
204284
  const cached2 = availabilityBySession.get(sessionId);
@@ -205184,9 +205284,9 @@ function loadContextUsage(contextUsageMap, db, sessionId) {
205184
205284
  }
205185
205285
  return { percentage: 0, inputTokens: 0 };
205186
205286
  }
205187
- function resolveSchedulerDecision(scheduler, sessionMeta, contextUsage, sessionId, modelKey) {
205287
+ function resolveSchedulerDecision(scheduler, sessionMeta, contextUsage, sessionId, modelKey, contextLimit) {
205188
205288
  try {
205189
- const schedulerDecision = scheduler.shouldExecute(sessionMeta, contextUsage, undefined, sessionId, modelKey);
205289
+ const schedulerDecision = scheduler.shouldExecute(sessionMeta, contextUsage, undefined, sessionId, modelKey, contextLimit);
205190
205290
  sessionLog(sessionId, `transform scheduler: percentage=${contextUsage.percentage.toFixed(1)}% inputTokens=${contextUsage.inputTokens} cacheTtl=${sessionMeta.cacheTtl} lastResponseTime=${sessionMeta.lastResponseTime} decision=${schedulerDecision}`);
205191
205291
  return schedulerDecision;
205192
205292
  } catch (error51) {
@@ -205216,6 +205316,34 @@ function messageInfo2(value) {
205216
205316
  return {};
205217
205317
  return isRecord3(value.info) ? value.info : value;
205218
205318
  }
205319
+ function newestUserMessage(messages) {
205320
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
205321
+ if (messageInfo2(messages[index]).role === "user")
205322
+ return messages[index];
205323
+ }
205324
+ return;
205325
+ }
205326
+ function isSyntheticUserMessage(message) {
205327
+ if (!message || messageInfo2(message).role !== "user" || !Array.isArray(message.parts)) {
205328
+ return false;
205329
+ }
205330
+ return message.parts.length > 0 && message.parts.every((part) => isRecord3(part) && (part.synthetic === true || part.ignored === true));
205331
+ }
205332
+ function observeSyntheticTurn(state, messages) {
205333
+ const newest = newestUserMessage(messages);
205334
+ const info = messageInfo2(newest);
205335
+ const messageId2 = typeof info.id === "string" ? info.id : null;
205336
+ const synthetic = isSyntheticUserMessage(newest);
205337
+ const isNewMessage = messageId2 === null || messageId2 !== state.lastObservedUserMessageId;
205338
+ if (!synthetic) {
205339
+ state.syntheticTurnCount = 0;
205340
+ state.syntheticLoopBreakerLogged = false;
205341
+ } else if (isNewMessage) {
205342
+ state.syntheticTurnCount += 1;
205343
+ }
205344
+ state.lastObservedUserMessageId = messageId2;
205345
+ return synthetic;
205346
+ }
205219
205347
  function assertNativeBoundary(output, sessionId, boundaryId) {
205220
205348
  const first = output.find((message) => messageInfo2(message).role !== "system");
205221
205349
  const info = messageInfo2(first);
@@ -205265,7 +205393,10 @@ function ensureState(states, sessionId) {
205265
205393
  lastAckedSeq: 0,
205266
205394
  lastAckedWatermarks: null,
205267
205395
  idOrdinalMemoGeneration: 0,
205268
- idOrdinalMemo: new Map
205396
+ idOrdinalMemo: new Map,
205397
+ syntheticTurnCount: 0,
205398
+ lastObservedUserMessageId: null,
205399
+ syntheticLoopBreakerLogged: false
205269
205400
  };
205270
205401
  states.set(sessionId, state);
205271
205402
  }
@@ -205337,6 +205468,7 @@ function buildTransformBody(args) {
205337
205468
  mid_turn: args.midTurn,
205338
205469
  model_key: args.modelKey,
205339
205470
  provider_id: args.providerId,
205471
+ tool_present: args.passInputs.tool_present === true,
205340
205472
  effective_execute_threshold: args.passInputs.effective_execute_threshold,
205341
205473
  history_budget_tokens: args.passInputs.history_budget_tokens,
205342
205474
  clear_reasoning_age: args.passInputs.clear_reasoning_age,
@@ -205440,6 +205572,12 @@ function createRustModeTransform(deps, options) {
205440
205572
  const run = async (sessionId, messages, output, sessionMeta) => {
205441
205573
  const state = ensureState(states, sessionId);
205442
205574
  state.passCount += 1;
205575
+ const syntheticTurn = observeSyntheticTurn(state, messages);
205576
+ const syntheticLoopBlocked = syntheticTurn && state.syntheticTurnCount >= 3;
205577
+ if (syntheticLoopBlocked && !state.syntheticLoopBreakerLogged) {
205578
+ state.syntheticLoopBreakerLogged = true;
205579
+ sessionLog(sessionId, "RUST LOOP BREAKER: suppressing host directives after three consecutive synthetic turns until a real user message arrives");
205580
+ }
205443
205581
  const inputCount = messages.length;
205444
205582
  let decision = "error";
205445
205583
  let servedFrom = "none";
@@ -205462,6 +205600,8 @@ function createRustModeTransform(deps, options) {
205462
205600
  }
205463
205601
  }
205464
205602
  const rawMessages = messages.slice();
205603
+ const reduceAvailability = resolveCtxReduceAvailability(sessionId);
205604
+ const toolPresent = reduceAvailability.frozen && reduceAvailability.callable;
205465
205605
  try {
205466
205606
  const { directory } = await getSessionDirectory(deps, sessionId);
205467
205607
  const model = modelFromMessages(messages) ?? findLastAssistantModelFromOpenCodeDb(sessionId);
@@ -205487,7 +205627,8 @@ function createRustModeTransform(deps, options) {
205487
205627
  clear_reasoning_age: deps.clearReasoningAge,
205488
205628
  cache_ttl: sessionMeta.cacheTtl,
205489
205629
  mid_turn: midTurn,
205490
- is_subagent: sessionMeta.isSubagent
205630
+ is_subagent: sessionMeta.isSubagent,
205631
+ tool_present: toolPresent
205491
205632
  };
205492
205633
  const resolved = await resolveOrdinalsForModule({
205493
205634
  sessionId,
@@ -205592,7 +205733,11 @@ function createRustModeTransform(deps, options) {
205592
205733
  state.parked = false;
205593
205734
  state.passesSincePark = 0;
205594
205735
  const directiveText = directiveTextOf(response);
205595
- if (directiveText) {
205736
+ if (syntheticTurn) {
205737
+ try {
205738
+ casChannel2NudgeState(deps.db, sessionId, "pending", "");
205739
+ } catch {}
205740
+ } else if (directiveText) {
205596
205741
  try {
205597
205742
  casChannel2NudgeState(deps.db, sessionId, "", "pending");
205598
205743
  await maybeDeliverChannel2(sessionId, {
@@ -206355,6 +206500,8 @@ function hasToolPartWithCallId(message, callId) {
206355
206500
  return false;
206356
206501
  }
206357
206502
  function isReplayableAssistantAnchor(message) {
206503
+ if (message.info.summary === true)
206504
+ return false;
206358
206505
  return message.info.error === undefined || message.info.error === null;
206359
206506
  }
206360
206507
  function appendReminderToUserMessage(message, reminder) {
@@ -207075,6 +207222,8 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
207075
207222
  };
207076
207223
  }
207077
207224
  // src/hooks/magic-context/transform-postprocess-phase.ts
207225
+ init_storage_meta_persisted();
207226
+ init_storage_tags();
207078
207227
  init_logger();
207079
207228
  await init_storage();
207080
207229
 
@@ -207149,7 +207298,7 @@ init_storage_memory_fts();
207149
207298
  // src/features/magic-context/search-measurement.ts
207150
207299
  init_embedding();
207151
207300
  init_storage_embedding_measurements();
207152
- import { createHash as createHash15 } from "node:crypto";
207301
+ import { createHash as createHash16 } from "node:crypto";
207153
207302
  function resultId(result) {
207154
207303
  switch (result.source) {
207155
207304
  case "memory":
@@ -207232,7 +207381,7 @@ async function recordShadowMeasurement(args) {
207232
207381
  });
207233
207382
  }
207234
207383
  function sha2562(value) {
207235
- return createHash15("sha256").update(value).digest("hex");
207384
+ return createHash16("sha256").update(value).digest("hex");
207236
207385
  }
207237
207386
 
207238
207387
  // src/features/magic-context/search.ts
@@ -208937,7 +209086,7 @@ function readFilePath(target) {
208937
209086
  init_tag_content_primitives();
208938
209087
 
208939
209088
  // src/hooks/magic-context/todo-view.ts
208940
- import { createHash as createHash16 } from "node:crypto";
209089
+ import { createHash as createHash17 } from "node:crypto";
208941
209090
  var TODO_STATUS_PENDING = "pending";
208942
209091
  var TODO_STATUS_IN_PROGRESS = "in_progress";
208943
209092
  var TODO_STATUS_COMPLETED = "completed";
@@ -209005,7 +209154,7 @@ function buildSyntheticTodoPart(stateJson) {
209005
209154
  };
209006
209155
  }
209007
209156
  function computeSyntheticCallId(stateJson) {
209008
- const hash2 = createHash16("sha256").update(stateJson).digest("hex").slice(0, 16);
209157
+ const hash2 = createHash17("sha256").update(stateJson).digest("hex").slice(0, 16);
209009
209158
  return `${SYNTHETIC_CALL_ID_PREFIX}${hash2}`;
209010
209159
  }
209011
209160
  function parseTodoState(stateJson) {
@@ -209085,28 +209234,98 @@ var degradedCacheCountBySession = new BoundedSessionMap(100);
209085
209234
  function resetDegradedCacheCount(sessionId) {
209086
209235
  degradedCacheCountBySession.delete(sessionId);
209087
209236
  }
209088
- function injectDeferredCompactionSummaryRepresentation(args) {
209089
- if (args.messages.some((message) => message.info.id === args.summaryMessageId)) {
209237
+ function isSyntheticHeadMessage(message) {
209238
+ if (message.info.syntheticHead !== true)
209239
+ return false;
209240
+ if (message.info.id !== undefined)
209090
209241
  return false;
209242
+ if (message.info.role !== "user")
209243
+ return false;
209244
+ const parts = message.parts;
209245
+ if (parts.length === 0)
209246
+ return false;
209247
+ return parts.every((part) => part.synthetic === true);
209248
+ }
209249
+ var TODO_HEAD_ANCHOR_ID = "__magic_context_todo_head__";
209250
+ function injectSyntheticTodoAtHead(messages, sessionId, part) {
209251
+ let headEnd = 0;
209252
+ while (headEnd < messages.length && isSyntheticHeadMessage(messages[headEnd])) {
209253
+ headEnd += 1;
209091
209254
  }
209092
- const summaryTagNumber = args.tagger.assignTag(args.sessionId, `${args.summaryMessageId}:p0`, "message", byteSize(MARKER_SUMMARY_TEXT), args.db, 0, null, 0, null, () => ({
209255
+ const existing = messages[headEnd];
209256
+ if (existing?.info.id === TODO_HEAD_ANCHOR_ID) {
209257
+ injectToolPartIntoAssistantById(messages, TODO_HEAD_ANCHOR_ID, part);
209258
+ return TODO_HEAD_ANCHOR_ID;
209259
+ }
209260
+ messages.splice(headEnd, 0, {
209261
+ info: {
209262
+ id: TODO_HEAD_ANCHOR_ID,
209263
+ role: "assistant",
209264
+ sessionID: sessionId
209265
+ },
209266
+ parts: [part]
209267
+ });
209268
+ return TODO_HEAD_ANCHOR_ID;
209269
+ }
209270
+ function injectPersistedTodoAnchor(messages, sessionId, messageId2, part) {
209271
+ if (injectToolPartIntoAssistantById(messages, messageId2, part))
209272
+ return true;
209273
+ if (messageId2 !== TODO_HEAD_ANCHOR_ID)
209274
+ return false;
209275
+ injectSyntheticTodoAtHead(messages, sessionId, part);
209276
+ return true;
209277
+ }
209278
+ function dropMarkerSummaryTag2(db, sessionId, summaryMessageId) {
209279
+ const tagNumber = getTagNumberByMessageId(db, sessionId, `${summaryMessageId}:p0`);
209280
+ if (tagNumber !== null)
209281
+ updateTagStatus(db, sessionId, tagNumber, "dropped");
209282
+ }
209283
+ function reconcileMarkerRepresentation(messages, persistedMarkerState, options) {
209284
+ const retainedMessages = [];
209285
+ const staleSummaryIds = new Set;
209286
+ for (const message of messages) {
209287
+ if (message.info.summary !== true) {
209288
+ retainedMessages.push(message);
209289
+ continue;
209290
+ }
209291
+ const messageId2 = message.info.id;
209292
+ if (typeof messageId2 === "string" && messageId2 !== persistedMarkerState?.summaryMessageId) {
209293
+ staleSummaryIds.add(messageId2);
209294
+ }
209295
+ }
209296
+ if (staleSummaryIds.size > 0) {
209297
+ options.db.transaction(() => {
209298
+ for (const messageId2 of staleSummaryIds) {
209299
+ dropMarkerSummaryTag2(options.db, options.sessionId, messageId2);
209300
+ }
209301
+ })();
209302
+ }
209303
+ const removedSummary = retainedMessages.length !== messages.length;
209304
+ if (removedSummary)
209305
+ messages.splice(0, messages.length, ...retainedMessages);
209306
+ if (persistedMarkerState === null)
209307
+ return removedSummary;
209308
+ const summaryTagNumber = options.tagger.assignTag(options.sessionId, `${persistedMarkerState.summaryMessageId}:p0`, "message", byteSize(MARKER_SUMMARY_TEXT), options.db, 0, null, 0, null, () => ({
209093
209309
  tokenCount: estimateTokens(MARKER_SUMMARY_TEXT),
209094
209310
  inputTokenCount: null,
209095
209311
  reasoningTokenCount: null
209096
209312
  }));
209097
- const summaryText = args.ctxReduceCallable ? prependTag(summaryTagNumber, MARKER_SUMMARY_TEXT) : MARKER_SUMMARY_TEXT;
209313
+ const summaryText = options.ctxReduceAvailability.frozen && options.ctxReduceAvailability.callable ? prependTag(summaryTagNumber, MARKER_SUMMARY_TEXT) : MARKER_SUMMARY_TEXT;
209098
209314
  const summaryMessage = {
209099
209315
  info: {
209100
- id: args.summaryMessageId,
209316
+ id: persistedMarkerState.summaryMessageId,
209101
209317
  role: "assistant",
209102
- sessionID: args.sessionId,
209318
+ sessionID: options.sessionId,
209103
209319
  summary: true,
209104
209320
  finish: "stop"
209105
209321
  },
209106
209322
  parts: [{ type: "text", text: summaryText }]
209107
209323
  };
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);
209324
+ let retainedTailStart = 0;
209325
+ while (retainedTailStart < messages.length && isSyntheticHeadMessage(messages[retainedTailStart])) {
209326
+ retainedTailStart += 1;
209327
+ }
209328
+ messages.splice(retainedTailStart, 0, summaryMessage);
209110
209329
  return true;
209111
209330
  }
209112
209331
  function pendingMarkerCoveredByConsumedBoundary(pending, injection) {
@@ -209488,6 +209707,53 @@ async function runPostTransformPhase(args) {
209488
209707
  }
209489
209708
  }
209490
209709
  logTransformTiming(args.sessionId, "pp.nudgeAndSticky", tNudgeBlock);
209710
+ const explicitRebuildHappened = args.historyRefreshExplicitBeforePrepare && args.rebuiltHistoryFromInitialPrepare;
209711
+ const materializationSatisfied = !deferredMaterializationWasPending || explicitMaterializedSuccessfully || deferredMaterializedSuccessfully;
209712
+ const historyWasConsumedThisPass = args.historyRebuiltThisPass && (args.canConsumeDeferredLate || args.phaseJustAwaitedPublication || explicitRebuildHappened) && materializationSatisfied;
209713
+ let suppressV12HistoryDrain = false;
209714
+ if (historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart) {
209715
+ const pending = getPendingCompactionMarkerState(args.db, args.sessionId);
209716
+ if (pending) {
209717
+ if (!pendingMarkerCoveredByConsumedBoundary(pending, args.pendingCompartmentInjection)) {
209718
+ suppressV12HistoryDrain = true;
209719
+ sessionLog(args.sessionId, `compaction-marker drain: pending ordinal ${pending.ordinal} is newer than consumed boundary ${args.pendingCompartmentInjection?.compartmentEndMessage ?? "<none>"}; preserving deferred history refresh signal`);
209720
+ } else {
209721
+ const outcome = applyDeferredCompactionMarker(args.db, args.sessionId, pending, args.sessionDirectory);
209722
+ switch (outcome.kind) {
209723
+ case "applied":
209724
+ case "already-current":
209725
+ case "stale-skip":
209726
+ if (clearPendingCompactionMarkerAfterSuccessfulDrain({
209727
+ db: args.db,
209728
+ sessionId: args.sessionId,
209729
+ pending,
209730
+ deferredHistoryRefreshSessions: args.deferredHistoryRefreshSessions
209731
+ }) === "cas-lost-newer-pending") {
209732
+ suppressV12HistoryDrain = true;
209733
+ }
209734
+ break;
209735
+ case "retryable-failure":
209736
+ args.passOutcome?.record("compaction-marker-drain-failure");
209737
+ sessionLog(args.sessionId, "compaction-marker drain: retryable failure; preserving deferred history refresh signal", outcome.error);
209738
+ suppressV12HistoryDrain = true;
209739
+ break;
209740
+ }
209741
+ }
209742
+ }
209743
+ }
209744
+ reconcileMarkerRepresentation(args.messages, getPersistedCompactionMarkerState(args.db, args.sessionId), {
209745
+ db: args.db,
209746
+ sessionId: args.sessionId,
209747
+ tagger: args.tagger,
209748
+ ctxReduceAvailability: args.ctxReduceAvailability
209749
+ });
209750
+ const deferredHistoryDrainEligible = historyWasConsumedThisPass && args.deferredHistoryWasPendingAtPassStart && !suppressV12HistoryDrain;
209751
+ if (deferredHistoryDrainEligible) {
209752
+ args.deferredHistoryRefreshSessions.delete(args.sessionId);
209753
+ }
209754
+ if ((explicitMaterializedSuccessfully || deferredMaterializedSuccessfully) && deferredMaterializationAtPassStart) {
209755
+ args.deferredMaterializationSessions.delete(args.sessionId);
209756
+ }
209491
209757
  const tNoteAndTodo = performance.now();
209492
209758
  const noteReadStillVisible = args.fullFeatureMode ? hasVisibleNoteReadCall(args.messages) : false;
209493
209759
  const deferredNoteText = args.fullFeatureMode ? peekNoteNudgeText(args.db, args.sessionId, args.currentTurnId, args.projectPath, noteReadStillVisible) : null;
@@ -209512,29 +209778,22 @@ async function runPostTransformPhase(args) {
209512
209778
  if (persistedAnchor) {
209513
209779
  clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
209514
209780
  }
209515
- } else if (persistedAnchor && persistedAnchor.callId === part.callID && injectToolPartIntoAssistantById(args.messages, persistedAnchor.messageId, part)) {
209781
+ } else if (persistedAnchor && persistedAnchor.callId === part.callID && injectPersistedTodoAnchor(args.messages, args.sessionId, persistedAnchor.messageId, part)) {
209516
209782
  if (persistedAnchor.stateJson.length === 0) {
209517
209783
  setPersistedTodoSyntheticAnchor(args.db, args.sessionId, persistedAnchor.callId, persistedAnchor.messageId, args.sessionMeta.lastTodoState);
209518
209784
  }
209519
209785
  } 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
- }
209786
+ const anchoredMessageId = injectToolPartIntoLatestAssistant(args.messages, part) ?? injectSyntheticTodoAtHead(args.messages, args.sessionId, part);
209787
+ setPersistedTodoSyntheticAnchor(args.db, args.sessionId, part.callID, anchoredMessageId, args.sessionMeta.lastTodoState);
209526
209788
  }
209527
209789
  } else if (persistedAnchor && persistedAnchor.stateJson.length > 0) {
209528
209790
  const part = buildSyntheticTodoPart(persistedAnchor.stateJson);
209529
209791
  if (part !== null && part.callID === persistedAnchor.callId) {
209530
- injectToolPartIntoAssistantById(args.messages, persistedAnchor.messageId, part);
209792
+ injectPersistedTodoAnchor(args.messages, args.sessionId, persistedAnchor.messageId, part);
209531
209793
  }
209532
209794
  }
209533
209795
  }
209534
209796
  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
209797
  if (args.compartmentInjectionRebuiltFromDb && args.pendingCompartmentInjection) {
209539
209798
  if (args.pendingCompartmentInjection.compartmentEndMessageId === null) {
209540
209799
  const nextCount = (degradedCacheCountBySession.get(args.sessionId) ?? 0) + 1;
@@ -209546,54 +209805,6 @@ async function runPostTransformPhase(args) {
209546
209805
  degradedCacheCountBySession.delete(args.sessionId);
209547
209806
  }
209548
209807
  }
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
209808
  if (args.fullFeatureMode && isCacheBustingPass && args.m0M1 && (!!args.m0M1.projectPath || !!args.m0M1.projectDirectory)) {
209598
209809
  checkM0MutationDriftAndSignal({
209599
209810
  db: args.db,
@@ -209823,7 +210034,8 @@ function createTransform(deps) {
209823
210034
  }
209824
210035
  const reducedMode = sessionMeta.isSubagent;
209825
210036
  const fullFeatureMode = !reducedMode;
209826
- const ctxReduceCallable = resolveCtxReduceAvailabilityFromMessages(sessionId, messages);
210037
+ const ctxReduceAvailability = resolveCtxReduceAvailabilityFromMessages(sessionId, messages);
210038
+ const ctxReduceCallable = ctxReduceAvailability.callable;
209827
210039
  let sessionDirectory = deps.directory ?? "";
209828
210040
  let sessionDirectoryResolvedFromHost = false;
209829
210041
  const cachedDirectory = deps.sessionDirectoryBySession?.get(sessionId);
@@ -209973,7 +210185,7 @@ function createTransform(deps) {
209973
210185
  tokensConfig: deps.executeThresholdTokens,
209974
210186
  contextLimit: emergencyCeilingLimit
209975
210187
  }) / 100)) : undefined;
209976
- const schedulerDecisionEarly = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId));
210188
+ const schedulerDecisionEarly = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId), resolvedContextLimit);
209977
210189
  const midTurn = isMidTurn(deps, resolvedSessionId);
209978
210190
  const bypassReason = detectMidTurnBypassReason({
209979
210191
  contextUsage: contextUsageEarly,
@@ -210329,7 +210541,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
210329
210541
  reasoningByMessage,
210330
210542
  messageTagNumbers,
210331
210543
  tagger: deps.tagger,
210332
- ctxReduceCallable,
210544
+ ctxReduceAvailability,
210333
210545
  batch,
210334
210546
  contextUsage,
210335
210547
  schedulerDecision,
@@ -211660,7 +211872,7 @@ function createToolExecuteAfterHook(args) {
211660
211872
  init_send_session_notification();
211661
211873
 
211662
211874
  // src/hooks/magic-context/system-prompt-hash.ts
211663
- import { createHash as createHash17 } from "node:crypto";
211875
+ import { createHash as createHash18 } from "node:crypto";
211664
211876
 
211665
211877
  // src/agents/magic-context-prompt.ts
211666
211878
  init_language_directive();
@@ -211864,7 +212076,7 @@ function createSystemPromptHashHandler(deps) {
211864
212076
  return;
211865
212077
  if (!availability.frozen)
211866
212078
  return;
211867
- const currentHash = createHash17("md5").update(systemContent).digest("hex");
212079
+ const currentHash = createHash18("md5").update(systemContent).digest("hex");
211868
212080
  if (!sessionMetaEarly) {
211869
212081
  return;
211870
212082
  }
@@ -212939,7 +213151,13 @@ init_decay_render();
212939
213151
  init_read_session_formatting();
212940
213152
  await init_inject_compartments();
212941
213153
  function computeM0BlockTokens(db, sessionId, args) {
212942
- const { m0Text, projectIdentity, injectionBudgetTokens, memoryBlockCount } = args;
213154
+ const {
213155
+ m0Text,
213156
+ projectIdentity,
213157
+ injectionBudgetTokens,
213158
+ memoryBlockCount,
213159
+ compartmentTokensOverride
213160
+ } = args;
212943
213161
  const docsBlock = extractM0Block(m0Text, "project-docs");
212944
213162
  const docsTokens = docsBlock ? estimateTokens(docsBlock) : 0;
212945
213163
  const profileBlock = extractM0Block(m0Text, "user-profile");
@@ -212953,7 +213171,9 @@ function computeM0BlockTokens(db, sessionId, args) {
212953
213171
  }
212954
213172
  let compartmentTokens = 0;
212955
213173
  const historyBlock = extractM0Block(m0Text, "session-history");
212956
- if (historyBlock) {
213174
+ if (typeof compartmentTokensOverride === "number" && Number.isFinite(compartmentTokensOverride) && compartmentTokensOverride >= 0) {
213175
+ compartmentTokens = compartmentTokensOverride;
213176
+ } else if (historyBlock) {
212957
213177
  compartmentTokens = estimateTokens(historyBlock);
212958
213178
  } else {
212959
213179
  try {
@@ -213124,7 +213344,8 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
213124
213344
  m0Text,
213125
213345
  projectIdentity,
213126
213346
  injectionBudgetTokens,
213127
- memoryBlockCount
213347
+ memoryBlockCount,
213348
+ compartmentTokensOverride: moduleStatus?.compartment_tokens
213128
213349
  });
213129
213350
  const compartmentTokens = m0Blocks.compartmentTokens;
213130
213351
  const factTokens = m0Blocks.factTokens;
@@ -214510,7 +214731,7 @@ Mark discardable once processed: large outputs you've summarized, repeated or re
214510
214731
  Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
214511
214732
  Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
214512
214733
  // src/tools/ctx-reduce/tools.ts
214513
- import { createHash as createHash18 } from "node:crypto";
214734
+ import { createHash as createHash19 } from "node:crypto";
214514
214735
  import { tool as tool4 } from "@opencode-ai/plugin";
214515
214736
 
214516
214737
  // src/features/magic-context/range-parser.ts
@@ -214577,11 +214798,11 @@ function createCtxReduceTool(deps) {
214577
214798
  const stableId = `oc-${sessionId}-${callId}`;
214578
214799
  if (Buffer.byteLength(stableId) <= 128)
214579
214800
  return stableId;
214580
- return `oc-${createHash18("sha256").update(stableId).digest("hex")}`;
214801
+ return `oc-${createHash19("sha256").update(stableId).digest("hex")}`;
214581
214802
  }
214582
214803
  fallbackCommandSequence += 1;
214583
214804
  const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
214584
- return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash18("sha256").update(monotonicId).digest("hex")}`;
214805
+ return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash19("sha256").update(monotonicId).digest("hex")}`;
214585
214806
  };
214586
214807
  return tool4({
214587
214808
  description: CTX_REDUCE_DESCRIPTION,
@@ -214998,11 +215219,11 @@ import {
214998
215219
  import { dirname as dirname9 } from "node:path";
214999
215220
 
215000
215221
  // src/shared/rpc-utils.ts
215001
- import { createHash as createHash19 } from "node:crypto";
215222
+ import { createHash as createHash20 } from "node:crypto";
215002
215223
  import { join as join21 } from "node:path";
215003
215224
  function projectHash(directory) {
215004
215225
  const normalized = directory.replace(/\/+$/, "");
215005
- return createHash19("sha256").update(normalized).digest("hex").slice(0, 16);
215226
+ return createHash20("sha256").update(normalized).digest("hex").slice(0, 16);
215006
215227
  }
215007
215228
  function rpcPortDir(storageDir, directory) {
215008
215229
  return join21(storageDir, "rpc", projectHash(directory));