@cortexkit/opencode-magic-context 0.49.29 → 0.49.31

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 (82) hide show
  1. package/dist/auto-search-worker.js +1 -1
  2. package/dist/chunk-embedding-write-worker.js +1 -1
  3. package/dist/{context-836j3vte.js → context-9a0f8mzh.js} +294 -41
  4. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +3 -3
  5. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
  6. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  7. package/dist/features/magic-context/dreamer/verify.d.ts +13 -17
  8. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  9. package/dist/features/magic-context/storage-native-replay.d.ts +2 -0
  10. package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -1
  11. package/dist/features/magic-context/work-metrics.d.ts.map +1 -1
  12. package/dist/hooks/magic-context/apply-operations.d.ts +11 -1
  13. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  14. package/dist/hooks/magic-context/history-boundary-repair.d.ts +1 -1
  15. package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -1
  16. package/dist/hooks/magic-context/strip-content.d.ts +1 -1
  17. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  18. package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
  19. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +2 -0
  21. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/transform.d.ts +11 -0
  23. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  24. package/dist/{index-wyt5m81v.js → index-0bjktrjt.js} +3 -3
  25. package/dist/{index-zhgqgxtt.js → index-0fe4q77z.js} +7 -5
  26. package/dist/{index-wpcdk76y.js → index-22e7khnr.js} +37 -29
  27. package/dist/{index-a1h316s9.js → index-3jmx3fae.js} +1 -1
  28. package/dist/{index-tx68g9nc.js → index-4s4zq97n.js} +1 -1
  29. package/dist/{index-h4s5jk7f.js → index-hbt0sbv2.js} +1 -1
  30. package/dist/{index-q9zvphbq.js → index-kmayq4kq.js} +39 -7
  31. package/dist/{index-bps8vn9r.js → index-qathsvz2.js} +5 -3
  32. package/dist/{index-wvffze8y.js → index-vtz789ex.js} +1 -1
  33. package/dist/{index-093c4g1c.js → index-y6ynjghv.js} +2 -2
  34. package/dist/index.js +13 -13
  35. package/dist/{message-index-bounded-7qsn4fd3.js → message-index-bounded-zq7a5nm6.js} +2 -2
  36. package/dist/migration-worker.js +1 -1
  37. package/dist/raw-ordinal-warmup-worker.js +2 -2
  38. package/dist/{read-session-chunk-a5d0q3m0.js → read-session-chunk-1ndphmb8.js} +1 -1
  39. package/dist/{recomp-orchestrator-na34m4c5.js → recomp-orchestrator-ynehxbya.js} +5 -5
  40. package/dist/{search-archive-66pm17gm.js → search-archive-sr07c6aj.js} +2 -2
  41. package/dist/{search-0cd6hx7a.js → search-fbaz1m8r.js} +3 -3
  42. package/dist/shared/marker-only-text.d.ts +2 -0
  43. package/dist/shared/marker-only-text.d.ts.map +1 -0
  44. package/dist/shared/tag-transcript.d.ts +4 -1
  45. package/dist/shared/tag-transcript.d.ts.map +1 -1
  46. package/dist/shared/transcript.d.ts +3 -1
  47. package/dist/shared/transcript.d.ts.map +1 -1
  48. package/dist/{transform-postprocess-phase-27we33af.js → transform-postprocess-phase-50h70ft8.js} +5 -5
  49. package/dist/v2/auto-search-worker.js +1 -1
  50. package/dist/v2/chunk-embedding-write-worker.js +1 -1
  51. package/dist/v2/{context-g4ptae4x.js → context-cdqw9jex.js} +320 -58
  52. package/dist/v2/fold/owner.d.ts +4 -0
  53. package/dist/v2/fold/owner.d.ts.map +1 -1
  54. package/dist/v2/hidden-child-cleanup.d.ts.map +1 -1
  55. package/dist/v2/hidden-child-native.d.ts.map +1 -1
  56. package/dist/v2/hooks/context.d.ts.map +1 -1
  57. package/dist/v2/hooks/types.d.ts +3 -0
  58. package/dist/v2/hooks/types.d.ts.map +1 -1
  59. package/dist/v2/{message-index-bounded-7363502m.js → message-index-bounded-jvgz7vk9.js} +2 -2
  60. package/dist/v2/message-times.d.ts +17 -0
  61. package/dist/v2/message-times.d.ts.map +1 -0
  62. package/dist/v2/migration-worker.js +1 -1
  63. package/dist/v2/raw-ordinal-warmup-worker.js +2 -2
  64. package/dist/v2/{read-session-chunk-kkppfhft.js → read-session-chunk-djzgm4jg.js} +1 -1
  65. package/dist/v2/{recomp-orchestrator-f1df1gb8.js → recomp-orchestrator-kdxr4tx8.js} +4 -4
  66. package/dist/v2/{search-archive-v07jpw25.js → search-archive-n3dhns4r.js} +2 -2
  67. package/dist/v2/{search-2v3xyzse.js → search-q3jjw6zp.js} +3 -3
  68. package/dist/v2/{server-976dxaxh.js → server-42nebt63.js} +1 -1
  69. package/dist/v2/{server-77gznpmf.js → server-d01pe8q5.js} +1 -1
  70. package/dist/v2/{server-k9je35ev.js → server-hwag0khr.js} +1 -1
  71. package/dist/v2/{server-mxzj3r0y.js → server-rb8m4vry.js} +7 -5
  72. package/dist/v2/{server-q50ttc2g.js → server-rdjgz95f.js} +39 -7
  73. package/dist/v2/{server-w79f8ejn.js → server-rr4cbkr0.js} +1 -1
  74. package/dist/v2/server.js +2 -2
  75. package/dist/v2/store-reader.d.ts +14 -2
  76. package/dist/v2/store-reader.d.ts.map +1 -1
  77. package/dist/v2/{wrapup-orchestrator-jq33fda8.js → wrapup-orchestrator-prfvyqbb.js} +4 -4
  78. package/dist/{wrapup-orchestrator-f0xr7pft.js → wrapup-orchestrator-4zhkcsz0.js} +6 -6
  79. package/package.json +1 -1
  80. package/src/shared/marker-only-text.ts +8 -0
  81. package/src/shared/tag-transcript.ts +34 -5
  82. package/src/shared/transcript.ts +1 -1
@@ -77,7 +77,6 @@ import {
77
77
  isCompartmentLeaseHeld,
78
78
  queueM0Mutation,
79
79
  getMaxM0MutationId,
80
- getCompartments,
81
80
  getLastCompartmentEndMessage,
82
81
  getLastCompartmentEndMessageId,
83
82
  getUncoveredCompartmentEndsThrough,
@@ -305,7 +304,7 @@ import {
305
304
  startCompartmentAgent,
306
305
  setRecompStarting2,
307
306
  setRecompTerminal2
308
- } from "./server-q50ttc2g.js";
307
+ } from "./server-rdjgz95f.js";
309
308
  import {
310
309
  resolveHistorianModel2
311
310
  } from "./server-5kym00ag.js";
@@ -330,7 +329,7 @@ import {
330
329
  openDatabaseAsync,
331
330
  isDatabasePersisted,
332
331
  getDatabasePersistenceError
333
- } from "./server-77gznpmf.js";
332
+ } from "./server-d01pe8q5.js";
334
333
  import {
335
334
  pruneMissingProjectIdentities,
336
335
  setHomeProjectPermission,
@@ -482,6 +481,7 @@ import {
482
481
  } from "./server-3mz2qh5a.js";
483
482
  import {
484
483
  stableStringify,
484
+ getTableColumnNames,
485
485
  getTemporalDecisions,
486
486
  observeTemporalDecisions,
487
487
  freezeTemporalDecisions,
@@ -702,7 +702,7 @@ import {
702
702
  readRawSessionMessageById2,
703
703
  readSessionChunk2,
704
704
  readRawSessionSeedTail2
705
- } from "./server-mxzj3r0y.js";
705
+ } from "./server-rb8m4vry.js";
706
706
  import {
707
707
  BoundedSessionMap,
708
708
  recordToolDefinitionSet,
@@ -717,7 +717,7 @@ import {
717
717
  isMessageIndexReconciledThrough,
718
718
  clearIndexedMessages,
719
719
  indexMessagesAfterOrdinal
720
- } from "./server-k9je35ev.js";
720
+ } from "./server-hwag0khr.js";
721
721
  import"./server-awr8qa4c.js";
722
722
  import {
723
723
  embedPauseBySession,
@@ -916,14 +916,14 @@ import {
916
916
  resolveMemoriesByIdsForSearch2,
917
917
  unifiedSearch2,
918
918
  formatSearchResults2
919
- } from "./server-976dxaxh.js";
919
+ } from "./server-42nebt63.js";
920
920
  import {
921
921
  resolvePromptContext2
922
922
  } from "./server-fmsr7v69.js";
923
923
  import"./server-kaqs6h31.js";
924
924
  import {
925
925
  renderSearchArchiveOffThread2
926
- } from "./server-w79f8ejn.js";
926
+ } from "./server-rr4cbkr0.js";
927
927
  import {
928
928
  compareSemverCore
929
929
  } from "./server-84w6rvvf.js";
@@ -3381,6 +3381,26 @@ class EmergencyFailClosedError extends Error {
3381
3381
  }
3382
3382
 
3383
3383
  // src/hooks/magic-context/history-boundary-repair.ts
3384
+ function readStoreBoundaries(db, sessionId) {
3385
+ const columns = getTableColumnNames(db, "compartments");
3386
+ const numbers = ["id", "sequence", "start_message", "end_message", "created_at"];
3387
+ const strings = ["session_id", "start_message_id", "end_message_id", "title", "content"];
3388
+ const predicates = [...numbers, ...strings].every((column) => columns.has(column)) ? [
3389
+ ...numbers.map((column) => `typeof(${column}) IN ('integer', 'real')`),
3390
+ ...strings.map((column) => `typeof(${column}) = 'text'`)
3391
+ ] : ["0"];
3392
+ for (const column of ["p1", "p2", "p3", "p4", "episode_type"]) {
3393
+ if (columns.has(column))
3394
+ predicates.push(`typeof(${column}) IN ('text', 'null')`);
3395
+ }
3396
+ for (const column of ["importance", "legacy"]) {
3397
+ if (columns.has(column))
3398
+ predicates.push(`typeof(${column}) IN ('integer', 'real', 'null')`);
3399
+ }
3400
+ return db.prepare(`SELECT sequence, ${columns.has("end_message_id") ? "end_message_id" : "NULL"} AS endMessageId
3401
+ FROM compartments WHERE session_id = ? AND ${predicates.join(" AND ")}
3402
+ ORDER BY sequence ASC`).all(sessionId);
3403
+ }
3384
3404
  function readBaseline(db, sessionId) {
3385
3405
  const row = db.prepare("SELECT cached_m0_bytes IS NOT NULL AS hasM0, cached_m0_last_baseline_end_message_id AS boundary FROM session_meta WHERE session_id = ?").get(sessionId);
3386
3406
  return {
@@ -3447,7 +3467,7 @@ function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = f
3447
3467
  }
3448
3468
  function repairMissingHistoryBoundary(args) {
3449
3469
  const { db, sessionId, isInHostStore, scope = "store" } = args;
3450
- const compartments = scope === "active-branch" ? db.prepare("SELECT sequence, COALESCE(end_message_id, '') AS endMessageId FROM compartments WHERE session_id = ? ORDER BY sequence").all(sessionId) : getCompartments(db, sessionId);
3470
+ const compartments = scope === "active-branch" ? db.prepare("SELECT sequence, COALESCE(end_message_id, '') AS endMessageId FROM compartments WHERE session_id = ? ORDER BY sequence").all(sessionId) : readStoreBoundaries(db, sessionId);
3451
3471
  let latestIndex = compartments.length - 1;
3452
3472
  while (latestIndex >= 0 && !compartments[latestIndex]?.endMessageId)
3453
3473
  latestIndex -= 1;
@@ -3491,7 +3511,7 @@ function repairMissingHistoryBoundary(args) {
3491
3511
  let dropped;
3492
3512
  let anchorForDrop = anchor;
3493
3513
  try {
3494
- if (scope === "active-branch" && anchor) {
3514
+ if (anchor) {
3495
3515
  const row = db.prepare("SELECT end_message AS endMessage FROM compartments WHERE session_id = ? AND sequence = ?").get(sessionId, anchor.sequence);
3496
3516
  if (!row)
3497
3517
  return { kind: "unresolved", reason: "busy", missingEndMessageId: missing };
@@ -7620,6 +7640,7 @@ function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options =
7620
7640
  });
7621
7641
  };
7622
7642
  const rows = readRows(db);
7643
+ options.prepareRemovals?.(rows);
7623
7644
  const converted = new Map;
7624
7645
  for (const row of rows) {
7625
7646
  const target = targets.get(row.tagNumber);
@@ -11970,6 +11991,7 @@ async function runPostTransformPhase(args) {
11970
11991
  emergencyReclaimedTokens,
11971
11992
  droppedCount,
11972
11993
  emergency,
11994
+ prefixMutationPermitted: isCacheBustingPass,
11973
11995
  bustedThisPass,
11974
11996
  prefixTrimStatus: deliveredPrefix?.prefixTrimStatus ?? null,
11975
11997
  thinkingBindingRecovery,
@@ -19636,6 +19658,15 @@ function createTransform(deps) {
19636
19658
  db,
19637
19659
  sessionID: sessionId
19638
19660
  }) : undefined;
19661
+ const hostEstimate = deps.hostInputEstimate?.(sessionId);
19662
+ const hostOverWindow = fullFeatureMode && !compactionOff && resolvedContextLimit !== undefined && resolvedContextLimit > 0 && hostEstimate !== undefined && Number.isFinite(hostEstimate.tokens) && Number.isFinite(hostEstimate.pressureTokens) && hostEstimate.tokens > resolvedContextLimit;
19663
+ if (hostOverWindow) {
19664
+ contextUsageEarly = {
19665
+ inputTokens: Math.max(contextUsageEarly.inputTokens, hostEstimate.pressureTokens),
19666
+ percentage: Math.max(100, contextUsageEarly.percentage, hostEstimate.pressureTokens / resolvedContextLimit * 100)
19667
+ };
19668
+ usagePercentageSynthetic = true;
19669
+ }
19639
19670
  let unmanagedOverWindowPass = null;
19640
19671
  const unmanagedOverWindowCarried = unmanagedOverWindowSessions.has(sessionId);
19641
19672
  if (fullFeatureMode && !compactionOff && typeof resolvedContextLimit === "number" && resolvedContextLimit > 0 && (unmanagedOverWindowCarried || isFirstTransformPassForSession && getLastCompartmentEndMessage(db, sessionId) < 0 && getMaxDroppedTagNumber2(db, sessionId) === 0)) {
@@ -20178,7 +20209,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20178
20209
  bustReason: calibrationBustReason,
20179
20210
  onAdopt: (message) => sessionLog2(sessionId, message)
20180
20211
  });
20181
- let contextUsageFromEstimate = false;
20212
+ let contextUsageFromEstimate = hostOverWindow;
20182
20213
  if (contextUsage.inputTokens <= 0 && protectionCacheBustingPass) {
20183
20214
  const overflowRecoveryPass = usagePercentageSynthetic || emergencyRecoveryArmed;
20184
20215
  const savedProviderReading = overflowRecoveryPass ? null : savedProviderReadingForPass({
@@ -20732,6 +20763,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20732
20763
  sessionId,
20733
20764
  systemPromptHash: sessionMeta.systemPromptHash
20734
20765
  });
20766
+ deps.onPassPermission?.(sessionId, postTransformResult.prefixMutationPermitted);
20735
20767
  };
20736
20768
  const timedTransform = (input, output) => withTransformTimingSummary(() => transform(input, output));
20737
20769
  return Object.assign(timedTransform, {
@@ -22381,6 +22413,13 @@ WHERE session_id = ?
22381
22413
  AND (time_created > ? OR (time_created = ? AND id > ?))
22382
22414
  ORDER BY time_created, id`;
22383
22415
  var V2_ASSISTANT_USAGE_ROWS_AFTER_SQL = `
22416
+ WITH newer AS (
22417
+ SELECT id, seq, data FROM session_message
22418
+ WHERE session_id = ? AND type = 'assistant' AND data IS NOT NULL AND seq > ?
22419
+ UNION ALL
22420
+ SELECT id, seq, data FROM session_message
22421
+ WHERE session_id = ? AND type = 'assistant' AND data IS NOT NULL AND seq = ? AND id > ?
22422
+ )
22384
22423
  SELECT
22385
22424
  json_extract(data, '$.agent') AS agent,
22386
22425
  seq AS time_created,
@@ -22389,14 +22428,10 @@ SELECT
22389
22428
  + COALESCE(json_extract(data, '$.tokens.cache.read'), 0)
22390
22429
  + COALESCE(json_extract(data, '$.tokens.cache.write'), 0) AS prompt,
22391
22430
  COALESCE(json_extract(data, '$.tokens.output'), 0) AS output
22392
- FROM session_message
22393
- WHERE session_id = ?
22394
- AND type = 'assistant'
22395
- AND data IS NOT NULL
22396
- AND (seq > ? OR (seq = ? AND id > ?))
22431
+ FROM newer
22397
22432
  ORDER BY seq, id`;
22398
22433
  function readAssistantUsageRowsAfter(openCodeDb, sessionId, afterTimeCreated, afterId, generation = "v1") {
22399
- const rows = openCodeDb.prepare(generation === "v2" ? V2_ASSISTANT_USAGE_ROWS_AFTER_SQL : ASSISTANT_USAGE_ROWS_AFTER_SQL).all(sessionId, afterTimeCreated, afterTimeCreated, afterId);
22434
+ const rows = openCodeDb.prepare(generation === "v2" ? V2_ASSISTANT_USAGE_ROWS_AFTER_SQL : ASSISTANT_USAGE_ROWS_AFTER_SQL).all(...generation === "v2" ? [sessionId, afterTimeCreated, sessionId, afterTimeCreated, afterId] : [sessionId, afterTimeCreated, afterTimeCreated, afterId]);
22400
22435
  return rows.map((r) => ({
22401
22436
  agent: r.agent ?? null,
22402
22437
  timeCreated: Number(r.time_created ?? 0),
@@ -23987,7 +24022,7 @@ function registerRpcHandlers(rpcServer, args) {
23987
24022
  const db = readDatabase();
23988
24023
  if (!db)
23989
24024
  return { ok: false, error: "db unavailable" };
23990
- const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-f1df1gb8.js"));
24025
+ const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-kdxr4tx8.js"));
23991
24026
  const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-x5nzy34v.js"));
23992
24027
  log2(`[rpc] recomp requested for session ${sessionId}`);
23993
24028
  if (!args.client && !args.hiddenCompletionExecutor) {
@@ -24072,7 +24107,7 @@ function registerRpcHandlers(rpcServer, args) {
24072
24107
  const db = readDatabase();
24073
24108
  if (!db)
24074
24109
  return { ok: false, error: "db unavailable" };
24075
- const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-jq33fda8.js"));
24110
+ const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-prfvyqbb.js"));
24076
24111
  const model = liveSessionState.liveModelBySession.get(sessionId);
24077
24112
  const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
24078
24113
  const ctx = {
@@ -25185,8 +25220,14 @@ class FoldOwner {
25185
25220
  async observe(args) {
25186
25221
  return this.serial(args.sessionID, async () => {
25187
25222
  let state = await this.read(args.sessionID);
25223
+ if (state?.rendered && state.rendered.id !== args.rendered.id)
25224
+ state = undefined;
25188
25225
  let changed = !state;
25189
- const renderedSha = foldDigest(JSON.stringify(args.rendered));
25226
+ const observedSha = foldDigest(JSON.stringify(args.rendered));
25227
+ const rendered = structuredClone(args.rendered);
25228
+ if (state?.withoutRecentContext && state.withoutRecentContext === rendered.id)
25229
+ stripCheckpointRecentContext(rendered, args.summary);
25230
+ const renderedSha = foldDigest(JSON.stringify(rendered));
25190
25231
  if (!state) {
25191
25232
  args.onHard("boot_recovery");
25192
25233
  state = {
@@ -25197,10 +25238,10 @@ class FoldOwner {
25197
25238
  };
25198
25239
  }
25199
25240
  const reason = args.cutSeq < state.watermark ? "host_cut_before_watermark" : state.submittedSha !== foldDigest(args.summary) || state.renderedSha && state.renderedSha !== renderedSha ? "host_rerender" : undefined;
25200
- if (reason && state.rejectedSha !== renderedSha) {
25241
+ if (reason && state.rejectedSha !== observedSha) {
25201
25242
  args.onHard(reason);
25202
25243
  state.reason = reason;
25203
- state.rejectedSha = renderedSha;
25244
+ state.rejectedSha = observedSha;
25204
25245
  changed = true;
25205
25246
  }
25206
25247
  if (state.cutSeq === undefined && args.cutSeq >= state.watermark) {
@@ -25208,7 +25249,7 @@ class FoldOwner {
25208
25249
  changed = true;
25209
25250
  }
25210
25251
  if (!state.rendered && reason !== "host_cut_before_watermark") {
25211
- state.rendered = structuredClone(args.rendered);
25252
+ state.rendered = rendered;
25212
25253
  state.renderedSha = renderedSha;
25213
25254
  state.renderedSummary = args.summary;
25214
25255
  changed = true;
@@ -25218,6 +25259,50 @@ class FoldOwner {
25218
25259
  return state;
25219
25260
  });
25220
25261
  }
25262
+ async stripRecentContext(sessionID, checkpointID) {
25263
+ return this.serial(sessionID, async () => {
25264
+ const state = await this.read(sessionID);
25265
+ if (!state?.rendered || state.rendered.id !== checkpointID)
25266
+ return;
25267
+ if (state.withoutRecentContext === checkpointID)
25268
+ return state;
25269
+ if (!stripCheckpointRecentContext(state.rendered, state.renderedSummary ?? state.submitted))
25270
+ return state;
25271
+ state.withoutRecentContext = checkpointID;
25272
+ state.renderedSha = foldDigest(JSON.stringify(state.rendered));
25273
+ await this.storage.set(this.key(sessionID), state);
25274
+ return state;
25275
+ });
25276
+ }
25277
+ }
25278
+ function stripCheckpointRecentContext(message, summary) {
25279
+ let changed = false;
25280
+ for (const part of message.content) {
25281
+ if (part.type !== "text" || typeof part.text !== "string")
25282
+ continue;
25283
+ const summaryStart = part.text.indexOf("<summary>");
25284
+ if (summaryStart < 0)
25285
+ continue;
25286
+ const summaryText = part.text.indexOf(summary, summaryStart + "<summary>".length);
25287
+ if (summaryText < 0)
25288
+ continue;
25289
+ const start = part.text.indexOf("</summary>", summaryText + summary.length) + "</summary>".length;
25290
+ const end = part.text.lastIndexOf("</conversation-checkpoint>");
25291
+ if (start < "</summary>".length || end < start)
25292
+ continue;
25293
+ const suffix = part.text.slice(start, end);
25294
+ if (!/^\s*<recent-context>[\s\S]*<\/recent-context>\s*$/.test(suffix))
25295
+ continue;
25296
+ part.text = `${part.text.slice(0, start)}
25297
+ ${part.text.slice(end)}`;
25298
+ changed = true;
25299
+ }
25300
+ if (changed && message.metadata && typeof message.metadata === "object") {
25301
+ const metadata = { ...message.metadata };
25302
+ delete metadata.recent;
25303
+ message.metadata = metadata;
25304
+ }
25305
+ return changed;
25221
25306
  }
25222
25307
 
25223
25308
  // src/v2/fold/memory-cache.ts
@@ -26862,6 +26947,7 @@ function createNativeHiddenChildren(host, removeSession, options) {
26862
26947
  const inFlight = removing.get(child.id);
26863
26948
  if (inFlight)
26864
26949
  return inFlight;
26950
+ options.log(`[magic-context] hidden child ${child.id} removing`);
26865
26951
  const done = (async () => {
26866
26952
  try {
26867
26953
  let timer;
@@ -26876,6 +26962,7 @@ function createNativeHiddenChildren(host, removeSession, options) {
26876
26962
  if (timer)
26877
26963
  clearTimeout(timer);
26878
26964
  }
26965
+ options.log(`[magic-context] hidden child ${child.id} removed`);
26879
26966
  } catch (error) {
26880
26967
  if (isSessionNotFound(error))
26881
26968
  return;
@@ -26887,14 +26974,19 @@ function createNativeHiddenChildren(host, removeSession, options) {
26887
26974
  removing.set(child.id, done);
26888
26975
  return done;
26889
26976
  };
26890
- const confirmPlacement = async (sessionID, parentID) => {
26977
+ const noteCreated = (sessionID, role, parentID) => {
26978
+ options.log(`[magic-context] hidden child ${sessionID} created role=${role} parent=${parentID} keep_subagents=${options.keepSubagents}`);
26979
+ };
26980
+ const confirmPlacement = async (sessionID, parentID, role) => {
26891
26981
  let stored;
26892
26982
  try {
26893
26983
  stored = await host.get({ sessionID });
26894
26984
  } catch (error) {
26985
+ noteCreated(sessionID, role, "unknown");
26895
26986
  options.log(`[magic-context] could not read back hidden child ${sessionID} to confirm its parent: ${errorText(error)}`);
26896
26987
  return;
26897
26988
  }
26989
+ noteCreated(sessionID, role, stored.parentID ?? "none");
26898
26990
  const directory = stored.location?.directory;
26899
26991
  if (options.directory !== undefined && directory !== undefined && !sameProjectDirectory(directory, options.directory)) {
26900
26992
  throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", `hidden child ${sessionID} is bound to ${directory}, not to this instance's ${options.directory}. Reopen the parent session in ${directory}, then run /ctx-recomp so its owning instance can rebuild history.`, true);
@@ -26923,11 +27015,13 @@ function createNativeHiddenChildren(host, removeSession, options) {
26923
27015
  };
26924
27016
  if (parentID) {
26925
27017
  try {
26926
- await confirmPlacement(created.id, parentID);
27018
+ await confirmPlacement(created.id, parentID, role);
26927
27019
  } catch (error) {
26928
27020
  await remove(child);
26929
27021
  throw error;
26930
27022
  }
27023
+ } else {
27024
+ noteCreated(created.id, role, "none");
26931
27025
  }
26932
27026
  return child;
26933
27027
  };
@@ -26936,16 +27030,22 @@ function createNativeHiddenChildren(host, removeSession, options) {
26936
27030
  open: create,
26937
27031
  create,
26938
27032
  retire(child) {
26939
- if (!kept(child))
27033
+ if (kept(child)) {
27034
+ options.log(`[magic-context] hidden child ${child.id} kept (keep_subagents)`);
27035
+ } else {
26940
27036
  remove(child);
27037
+ }
26941
27038
  },
26942
27039
  async finish(child, retired) {
26943
27040
  if (retired) {
26944
27041
  await removing.get(child.id);
26945
27042
  return;
26946
27043
  }
26947
- if (!kept(child))
27044
+ if (kept(child)) {
27045
+ options.log(`[magic-context] hidden child ${child.id} kept (keep_subagents)`);
27046
+ } else {
26948
27047
  await remove(child);
27048
+ }
26949
27049
  },
26950
27050
  updateModel: (child, model) => ({ ...child, model }),
26951
27051
  markEverSettled: (child) => ({ ...child, ever_settled: true })
@@ -26992,6 +27092,7 @@ async function cleanupLegacyHiddenChildren(db, remove, note, options = {}) {
26992
27092
  timer = setTimeout(() => reject(new Error("session.remove timed out")), Math.min(options.timeoutMs ?? 1000, Math.max(1, deadline - now())));
26993
27093
  })
26994
27094
  ]);
27095
+ note(`[magic-context] legacy hidden child ${child.id} removed`);
26995
27096
  } catch (error) {
26996
27097
  if (!isSessionNotFound(error))
26997
27098
  throw error;
@@ -27899,6 +28000,96 @@ class HiddenModelActivity {
27899
28000
  }
27900
28001
  }
27901
28002
 
28003
+ // src/v2/message-times.ts
28004
+ function isSettled(entry, readAt) {
28005
+ return (entry.version.type === "user" || entry.time.completed !== undefined) && typeof entry.version.updated === "number" && Number.isFinite(entry.version.updated) && entry.version.updated <= readAt - 1000;
28006
+ }
28007
+ function sameVersion(a, b) {
28008
+ return a.type === b.type && a.seq === b.seq && a.created === b.created && a.updated === b.updated;
28009
+ }
28010
+
28011
+ class V2MessageTimesCache {
28012
+ capacity;
28013
+ sessions = new Map;
28014
+ constructor(capacity = 64) {
28015
+ this.capacity = capacity;
28016
+ }
28017
+ delete(sessionID) {
28018
+ this.sessions.delete(sessionID);
28019
+ }
28020
+ deleteMessage(sessionID, messageID) {
28021
+ this.sessions.get(sessionID)?.entries.delete(messageID);
28022
+ }
28023
+ clear() {
28024
+ this.sessions.clear();
28025
+ }
28026
+ pass(sessionID) {
28027
+ const previous = this.sessions.get(sessionID);
28028
+ const current = { entries: new Map };
28029
+ this.sessions.delete(sessionID);
28030
+ this.sessions.set(sessionID, current);
28031
+ while (this.sessions.size > this.capacity) {
28032
+ const oldest = this.sessions.keys().next().value;
28033
+ if (oldest === undefined)
28034
+ break;
28035
+ this.sessions.delete(oldest);
28036
+ }
28037
+ const passTimes = new Map;
28038
+ return (reader, ids) => {
28039
+ const missing = [...new Set(ids)].filter((id) => !passTimes.has(id));
28040
+ if (missing.length > 0) {
28041
+ const readAt = Date.now();
28042
+ const identity = reader.hostIdentity();
28043
+ current.identity = identity;
28044
+ const reusable = previous?.identity === identity ? previous.entries : undefined;
28045
+ const known = [];
28046
+ const refresh = [];
28047
+ let first = Infinity;
28048
+ let last = -Infinity;
28049
+ for (const id of missing) {
28050
+ const entry = reusable?.get(id);
28051
+ if (entry && isSettled(entry, readAt)) {
28052
+ known.push(id);
28053
+ first = Math.min(first, entry.version.seq);
28054
+ last = Math.max(last, entry.version.seq);
28055
+ } else
28056
+ refresh.push(id);
28057
+ }
28058
+ const versions = reader.messageTimeVersions(sessionID, known, { first, last });
28059
+ for (const id of known) {
28060
+ const version = versions.get(id);
28061
+ const cached = reusable?.get(id);
28062
+ if (!version) {
28063
+ passTimes.set(id, null);
28064
+ } else if (cached && sameVersion(cached.version, version) && (version.type === "user" || cached.time.completed !== undefined)) {
28065
+ current.entries.set(id, cached);
28066
+ passTimes.set(id, cached.time);
28067
+ } else
28068
+ refresh.push(id);
28069
+ }
28070
+ const times = reader.messageTimes(sessionID, refresh, versions);
28071
+ for (const id of refresh) {
28072
+ const time = times.get(id);
28073
+ const version = versions.get(id);
28074
+ passTimes.set(id, time ?? null);
28075
+ if (time && version) {
28076
+ const entry = { version, time };
28077
+ if (isSettled(entry, readAt))
28078
+ current.entries.set(id, entry);
28079
+ }
28080
+ }
28081
+ }
28082
+ const result = new Map;
28083
+ for (const id of ids) {
28084
+ const time = passTimes.get(id);
28085
+ if (time)
28086
+ result.set(id, { ...time });
28087
+ }
28088
+ return result;
28089
+ };
28090
+ }
28091
+ }
28092
+
27902
28093
  // src/v2/hooks/channel2.ts
27903
28094
  import { randomBytes as randomBytes2 } from "node:crypto";
27904
28095
  var pendingCandidates = new WeakMap;
@@ -32071,7 +32262,6 @@ function parseMapMemoriesManifest(text) {
32071
32262
  }
32072
32263
  function validateMapMemoriesManifest(text, expectedIds) {
32073
32264
  const parsed = parseMapMemoriesManifest(text);
32074
- assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "mappings", "memory");
32075
32265
  assertNoDuplicateManifestIds(parsed.filter((entry) => expectedIds.has(entry.id)).map((entry) => entry.id), "mappings");
32076
32266
  return parsed;
32077
32267
  }
@@ -34285,8 +34475,7 @@ function parsePartialVerifyManifest(text, expectedIds) {
34285
34475
  var VERIFY_BATCH_SIZE = 5;
34286
34476
  var VERIFY_TOKENS_PER_MEMORY = 1e5;
34287
34477
  var VERIFY_RUN_TOKEN_BUDGET = 2500000;
34288
- var VERIFY_RUN_SLICE_MS = 240000;
34289
- var VERIFY_IN_FLIGHT_GRACE_MS = 120000;
34478
+ var VERIFY_BATCH_DEFAULT_MS = 240000;
34290
34479
  function verifyBatchTokenBudget(size, configured) {
34291
34480
  return Math.min(configured ?? Number.MAX_SAFE_INTEGER, size * VERIFY_TOKENS_PER_MEMORY);
34292
34481
  }
@@ -34316,8 +34505,8 @@ function validateVerifyCompletion(messages, text, expectedIds, responseText = te
34316
34505
  }
34317
34506
  var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
34318
34507
  var VERIFY_BATCH_FLOOR_MS = 30000;
34319
- function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
34320
- return Math.min(remainingMs, VERIFY_RUN_SLICE_MS);
34508
+ function computeVerifyBatchSliceMs(remainingMs, batchesRemaining) {
34509
+ return Math.min(remainingMs, Math.max(VERIFY_BATCH_DEFAULT_MS, remainingMs / Math.max(1, batchesRemaining)));
34321
34510
  }
34322
34511
  function closeBroadCycle(args, cycleStartAt) {
34323
34512
  if (!args.forceBroad || cycleStartAt === undefined)
@@ -34341,7 +34530,6 @@ async function runVerify(args) {
34341
34530
  }
34342
34531
  async function runVerifyWithCooldown(args) {
34343
34532
  const runStartedAt = Date.now();
34344
- const sliceDeadline = runStartedAt + VERIFY_RUN_SLICE_MS;
34345
34533
  const result = {
34346
34534
  verified: 0,
34347
34535
  updated: 0,
@@ -34389,12 +34577,10 @@ async function runVerifyWithCooldown(args) {
34389
34577
  try {
34390
34578
  for (let i = 0;i < batches.length; i += 1) {
34391
34579
  const now = Date.now();
34392
- const startCutoff = Math.min(args.deadline, sliceDeadline);
34393
- const hardStop = Math.min(args.deadline, sliceDeadline + VERIFY_IN_FLIGHT_GRACE_MS);
34394
- const remainingMs = Math.max(0, hardStop - now);
34395
- if (now >= startCutoff) {
34580
+ const remainingMs = Math.max(0, args.deadline - now);
34581
+ if (now >= args.deadline) {
34396
34582
  result.stopReason = "deadline";
34397
- log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — the run deadline passed ${now - startCutoff}ms ago`);
34583
+ log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — the run deadline passed ${now - args.deadline}ms ago`);
34398
34584
  break;
34399
34585
  }
34400
34586
  if (remainingMs < VERIFY_BATCH_FLOOR_MS) {
@@ -35333,7 +35519,7 @@ function createDreamTaskExecutor(deps) {
35333
35519
  return { status: "failed", transient: true, error };
35334
35520
  }
35335
35521
  const processed = result.mapped + result.independent;
35336
- if (processed > 0) {
35522
+ if (processed > 0 || result.failure === undefined) {
35337
35523
  const progress = `map-memories: committed ${processed} mapping(s) (mapped ${result.mapped}, independent ${result.independent}); ${result.remaining} remain`;
35338
35524
  recordRun("completed", null, { progress });
35339
35525
  return { status: "completed" };
@@ -53054,6 +53240,28 @@ ${baseline}
53054
53240
  draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== first));
53055
53241
  return true;
53056
53242
  }
53243
+ function estimateCheckpointRequest(draft) {
53244
+ let toolDefinitionTokens = 0;
53245
+ for (const tool of Object.values(draft.tools)) {
53246
+ const schema = JSON.stringify(tool.input);
53247
+ if (schema === undefined)
53248
+ throw new Error("Checkpoint request has an unserializable tool schema");
53249
+ toolDefinitionTokens += estimateTokens(tool.description) + estimateTokens(schema);
53250
+ }
53251
+ const estimateDraft = {
53252
+ ...draft,
53253
+ messages: draft.messages.map((message) => HEAD_IDS.some((id) => message.id === id) ? { ...message, id: undefined } : message)
53254
+ };
53255
+ return estimateFinalWireInputTokens({
53256
+ messages: adaptPayload(estimateDraft).messages,
53257
+ toolDefinitionTokens,
53258
+ systemPromptTokens: estimateTokens(JSON.stringify(draft.system)),
53259
+ providerID: draft.model.providerID,
53260
+ modelID: draft.model.id,
53261
+ agentName: draft.agent,
53262
+ sessionId: draft.sessionID
53263
+ });
53264
+ }
53057
53265
  var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
53058
53266
  var STORE_POOL_DISPOSE_WAIT_MS = 1000;
53059
53267
  function isBlockingV2TransformError(error) {
@@ -53251,6 +53459,7 @@ function coveredInstructionRows(reader, sessionID, throughSeq, model) {
53251
53459
  async function registerContext(context) {
53252
53460
  const directory = context.location.directory;
53253
53461
  const config = loadPluginConfigDetailed(directory).config;
53462
+ log2(`[magic-context] OpenCode 2 keep_subagents=${config.keep_subagents === true}`);
53254
53463
  setHomeProjectPermission(config.allow_home_project);
53255
53464
  if (!config.enabled)
53256
53465
  return;
@@ -53383,6 +53592,7 @@ async function registerContext(context) {
53383
53592
  });
53384
53593
  let hiddenAgentsReady;
53385
53594
  const readerPool = new V2StoreReaderPool;
53595
+ const messageTimesCache = new V2MessageTimesCache;
53386
53596
  const openStoreReader = () => readerPool.open(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
53387
53597
  const createHiddenExecutor = async (database) => {
53388
53598
  await cleanupLegacyOnce(database);
@@ -53746,6 +53956,12 @@ async function registerContext(context) {
53746
53956
  if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
53747
53957
  nativeFoldReplay?.onEvent(event);
53748
53958
  restoredRows.forget(sessionID);
53959
+ messageTimesCache.delete(sessionID);
53960
+ }
53961
+ if (event.type === "session.step.started" || event.type === "session.step.ended" || event.type === "session.step.failed") {
53962
+ const messageID = event.data.assistantMessageID;
53963
+ if (typeof messageID === "string")
53964
+ messageTimesCache.deleteMessage(sessionID, messageID);
53749
53965
  }
53750
53966
  if (event.type === "session.error" || event.type === "session.execution.failed") {
53751
53967
  const error = hiddenTerminalError(event);
@@ -53784,6 +54000,7 @@ async function registerContext(context) {
53784
54000
  rawProviders.get(sessionID)?.();
53785
54001
  rawProviders.delete(sessionID);
53786
54002
  usage.delete(sessionID);
54003
+ messageTimesCache.delete(sessionID);
53787
54004
  hiddenSessionErrors.delete(sessionID);
53788
54005
  storageNoticeBySession.delete(sessionID);
53789
54006
  liveModels.delete(sessionID);
@@ -53877,7 +54094,7 @@ async function registerContext(context) {
53877
54094
  await context.session.hook("compaction", async (draft) => {
53878
54095
  const hiddenSummary = hiddenChildHook.compactionSummary(draft.sessionID, draft.agent);
53879
54096
  if (hiddenSummary !== undefined) {
53880
- draft.result = { summary: hiddenSummary };
54097
+ draft.result = { summary: hiddenSummary, metadata: { keepID: undefined } };
53881
54098
  return;
53882
54099
  }
53883
54100
  if (compactionOff)
@@ -53902,7 +54119,7 @@ async function registerContext(context) {
53902
54119
  previousCut: reader.latestCompaction(draft.sessionID),
53903
54120
  summary
53904
54121
  })) {
53905
- draft.result = { summary };
54122
+ draft.result = { summary, metadata: { keepID: undefined } };
53906
54123
  return;
53907
54124
  }
53908
54125
  }
@@ -53918,7 +54135,7 @@ async function registerContext(context) {
53918
54135
  materialize: () => moduleBaseline ?? materialize(draft)
53919
54136
  });
53920
54137
  sessionLog2(draft.sessionID, `v2 compaction hook: fired answered=true source=${source}`);
53921
- draft.result = { summary: fold.submitted };
54138
+ draft.result = { summary: fold.submitted, metadata: { keepID: undefined } };
53922
54139
  } catch (cause) {
53923
54140
  await refuseBeforeProvider(context.session, draft.sessionID, "compaction-fold", cause);
53924
54141
  throw new V2ContextRefusal("Magic Context could not preserve the host checkpoint.", {
@@ -53964,6 +54181,8 @@ async function registerContext(context) {
53964
54181
  ...args.messages.filter((message) => message !== args.incoming)
53965
54182
  ];
53966
54183
  };
54184
+ const checkpointPassPermissions = new Map;
54185
+ const checkpointInputEstimates = new Map;
53967
54186
  const initializeTransform = (database) => transform ??= createTransform({
53968
54187
  ...createV2TransformFeatureDeps(config, compactionOff, directory, embeddings.ensureRegistered),
53969
54188
  cacheTtlConfig: config.cache_ttl,
@@ -53973,6 +54192,10 @@ async function registerContext(context) {
53973
54192
  tagger,
53974
54193
  ...createV2ThresholdDeps(config),
53975
54194
  contextUsageMap: usage,
54195
+ hostInputEstimate: (sessionID) => checkpointInputEstimates.get(sessionID),
54196
+ onPassPermission: (sessionID, permission) => {
54197
+ checkpointPassPermissions.set(sessionID, permission);
54198
+ },
53976
54199
  compactionOff,
53977
54200
  storeGeneration: "v2",
53978
54201
  normalizeRestoredAssistantText: (text, providerID) => stripCopiedTagNotation(text, providerID === "anthropic"),
@@ -54078,22 +54301,9 @@ async function registerContext(context) {
54078
54301
  }
54079
54302
  await dropStorageNotices(draft.messages, isMagicContextSynthetic);
54080
54303
  const hostMessagesAtEntry = [...draft.messages];
54081
- const passTimes = new Map;
54304
+ const cachedTimes = messageTimesCache.pass(draft.sessionID);
54082
54305
  const readTimes = (reader, messages) => {
54083
- const ids = timeIds(messages);
54084
- const missing = ids.filter((id) => !passTimes.has(id));
54085
- if (missing.length > 0) {
54086
- const read = reader.messageTimes(draft.sessionID, missing);
54087
- for (const id of missing)
54088
- passTimes.set(id, read.get(id) ?? null);
54089
- }
54090
- const times = new Map;
54091
- for (const id of ids) {
54092
- const time = passTimes.get(id);
54093
- if (time)
54094
- times.set(id, time);
54095
- }
54096
- return times;
54306
+ return cachedTimes(reader, timeIds(messages));
54097
54307
  };
54098
54308
  liveModels.set(draft.sessionID, {
54099
54309
  providerID: draft.model.providerID,
@@ -54407,6 +54617,21 @@ async function registerContext(context) {
54407
54617
  }
54408
54618
  const mapped = adaptPayload(draft, admitted, messageTimes, anchorTimesOnly);
54409
54619
  bindSystemDateRequestIdentity(mapped, draft);
54620
+ checkpointPassPermissions.delete(draft.sessionID);
54621
+ checkpointInputEstimates.delete(draft.sessionID);
54622
+ if (checkpoint && submitted !== undefined) {
54623
+ const projected = structuredClone(checkpoint);
54624
+ if (stripCheckpointRecentContext(projected, submitted)) {
54625
+ const estimate = estimateCheckpointRequest({
54626
+ ...draft,
54627
+ messages: [checkpoint, ...draft.messages]
54628
+ });
54629
+ checkpointInputEstimates.set(draft.sessionID, {
54630
+ tokens: estimate.tokens,
54631
+ pressureTokens: estimate.pressureTokens ?? estimate.tokens
54632
+ });
54633
+ }
54634
+ }
54410
54635
  await createMessagesTransformHandler({
54411
54636
  magicContext: { "experimental.chat.messages.transform": transform },
54412
54637
  compactionOff,
@@ -54415,6 +54640,14 @@ async function registerContext(context) {
54415
54640
  rustReplayParticipant: () => transform?.getRustReplayParticipant() ?? null
54416
54641
  })({}, mapped);
54417
54642
  mapped.commit();
54643
+ const checkpointPermission = checkpointPassPermissions.get(draft.sessionID);
54644
+ checkpointPassPermissions.delete(draft.sessionID);
54645
+ checkpointInputEstimates.delete(draft.sessionID);
54646
+ if (checkpoint?.id && checkpointPermission && replayHead === undefined) {
54647
+ const stripped = await folds.stripRecentContext(draft.sessionID, checkpoint.id);
54648
+ if (stripped?.rendered)
54649
+ checkpoint = structuredClone(stripped.rendered);
54650
+ }
54418
54651
  stageOpenCodeV2TransformDecision({
54419
54652
  sessionId: draft.sessionID,
54420
54653
  responseAfterSequence
@@ -54493,17 +54726,45 @@ async function registerContext(context) {
54493
54726
  }
54494
54727
  }
54495
54728
  };
54729
+ const refuseOversizedCheckpoint = async (draft) => {
54730
+ const hasCheckpoint = draft.messages.some((message) => message.content.some((part) => part.type === "text" && typeof part.text === "string" && part.text.startsWith("<conversation-checkpoint>")));
54731
+ const limit = draft.model.limit?.input ?? draft.model.limit?.context;
54732
+ if (!hasCheckpoint || !limit)
54733
+ return;
54734
+ let estimate;
54735
+ try {
54736
+ estimate = estimateCheckpointRequest(draft);
54737
+ } catch (cause) {
54738
+ await refuseBeforeProvider(context.session, draft.sessionID, "checkpoint-fit-estimate", cause);
54739
+ throw new V2ContextRefusal("Magic Context could not size the host checkpoint.", {
54740
+ cause
54741
+ });
54742
+ }
54743
+ if (estimate.tokens <= limit)
54744
+ return;
54745
+ await refuseBeforeProvider(context.session, draft.sessionID, "checkpoint-over-window");
54746
+ throw new V2ContextRefusal("Magic Context refused an oversized host checkpoint.");
54747
+ };
54496
54748
  await context.session.hook("context", (draft) => withSqliteTransformPass2(async () => {
54497
54749
  const anchor = generateReplayAnchor(draft.messages);
54498
- await runManagedContext(draft);
54750
+ try {
54751
+ await runManagedContext(draft);
54752
+ if (!compactionOff)
54753
+ await refuseOversizedCheckpoint(draft);
54754
+ } finally {
54755
+ checkpointInputEstimates.delete(draft.sessionID);
54756
+ checkpointPassPermissions.delete(draft.sessionID);
54757
+ }
54499
54758
  if (!compactionOff)
54500
54759
  generateReplay.capture(draft, anchor);
54501
54760
  else
54502
54761
  sessionLog2(draft.sessionID, "generate replay capture skipped: compaction-disabled");
54503
54762
  }));
54504
54763
  await context.session.hook("generate", async (draft) => {
54505
- if (!compactionOff && !deletedSessions.has(draft.sessionID))
54764
+ if (!compactionOff && !deletedSessions.has(draft.sessionID)) {
54506
54765
  generateReplay.apply(draft);
54766
+ await refuseOversizedCheckpoint(draft);
54767
+ }
54507
54768
  });
54508
54769
  withoutSqliteTransformPass2(() => warmModelLimitCacheFromCatalog(context));
54509
54770
  const rpcLiveSessionState = createV2RpcLiveSessionState({
@@ -54618,6 +54879,7 @@ async function registerContext(context) {
54618
54879
  }, 0));
54619
54880
  return {
54620
54881
  async dispose() {
54882
+ messageTimesCache.clear();
54621
54883
  usageController.abort();
54622
54884
  await hiddenCompletionExecutor?.dispose();
54623
54885
  await usageDone;