@cortexkit/pi-magic-context 0.49.20 → 0.49.21

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 (48) hide show
  1. package/dist/auto-search-worker.js +6 -6
  2. package/dist/chunk-embedding-write-worker.js +9 -9
  3. package/dist/{compaction-marker-candidates-fnm47jat.js → compaction-marker-candidates-p1kqkqhq.js} +2 -2
  4. package/dist/compaction-marker-candidates-worker.js +2 -2
  5. package/dist/{compartment-chunk-embedding-81qesfjs.js → compartment-chunk-embedding-y01m95c2.js} +5 -5
  6. package/dist/{embedding-backfill-56e871c6.js → embedding-backfill-2vh6m3bg.js} +11 -11
  7. package/dist/embedding-worker-process.js +1 -1
  8. package/dist/embedding-worker.js +4 -4
  9. package/dist/{index-dzem6gn9.js → index-29nw7n1r.js} +1 -1
  10. package/dist/{index-hws5f0z9.js → index-2qtx0q6h.js} +213 -4
  11. package/dist/{index-5vgt1zeh.js → index-3c3ztwgc.js} +2 -2
  12. package/dist/{index-rgfb753z.js → index-579m1751.js} +2 -2
  13. package/dist/{index-kqb3d8bs.js → index-5j6vwg4z.js} +148 -11
  14. package/dist/{index-6kb2xpw7.js → index-6wdwv3a6.js} +1 -1
  15. package/dist/{index-rfyvax95.js → index-at6py2k3.js} +1 -1
  16. package/dist/{index-bxmf4dhr.js → index-ccanzg8p.js} +2367 -1243
  17. package/dist/{index-mtvvhcw4.js → index-dbgg6hsf.js} +24 -10
  18. package/dist/{index-af9t637y.js → index-ftvm2acc.js} +121 -38
  19. package/dist/{index-zhwwp8zz.js → index-gqjxy2p7.js} +14 -4
  20. package/dist/{index-jxjr7kz9.js → index-gwxaz0z5.js} +2 -4
  21. package/dist/{index-p63nwn5v.js → index-hxp6q5f8.js} +1 -1
  22. package/dist/{index-qerzchrs.js → index-j3pz3a1b.js} +1 -1
  23. package/dist/{index-bttctq07.js → index-n8e5e9fp.js} +6 -3
  24. package/dist/{index-b8am7tns.js → index-pe5gz5c4.js} +4 -4
  25. package/dist/{index-tb3d9trm.js → index-st4gwt64.js} +1 -1
  26. package/dist/{index-5n5zxs8e.js → index-vx6f7wff.js} +2 -2
  27. package/dist/{index-v2epyzbm.js → index-w1twp2kp.js} +9 -7
  28. package/dist/{index-jt0g3hn0.js → index-w6r3ggnp.js} +35 -17
  29. package/dist/{index-vdy273xw.js → index-wgmhk91m.js} +10 -4
  30. package/dist/{index-e19qtjj0.js → index-wqpjhx1p.js} +35 -4
  31. package/dist/index.js +224 -206
  32. package/dist/{message-fts-rowid-map-bpexnsdj.js → message-fts-rowid-map-59y476bk.js} +3 -3
  33. package/dist/{message-index-mvag9crh.js → message-index-3snxf11x.js} +9 -9
  34. package/dist/{message-index-bounded-d4r3weh0.js → message-index-bounded-4ngt600v.js} +9 -9
  35. package/dist/{message-time-backfill-kc10yrcj.js → message-time-backfill-e3r8ddh1.js} +1 -1
  36. package/dist/migration-worker.js +6 -6
  37. package/dist/{project-embedding-registry-cfrg952x.js → project-embedding-registry-hfyzs654.js} +10 -10
  38. package/dist/raw-ordinal-warmup-worker.js +8 -8
  39. package/dist/{read-session-chunk-7g4zvpd8.js → read-session-chunk-5dmc77q2.js} +5 -5
  40. package/dist/{read-session-raw-0fsjh10f.js → read-session-raw-yxv2fv34.js} +2 -2
  41. package/dist/{search-archive-qbhp7e89.js → search-archive-3daj5ttc.js} +6 -6
  42. package/dist/{search-hp4g3g9v.js → search-jhfh3tsj.js} +17 -17
  43. package/dist/{sqlite-d67n6dtr.js → sqlite-v89bj0yy.js} +7 -1
  44. package/dist/{storage-memory-9g882j7a.js → storage-memory-0ndn65fm.js} +2 -2
  45. package/dist/{storage-tags-m2qcp1g2.js → storage-tags-r48vxthe.js} +2 -2
  46. package/dist/subagent-entry.js +22 -21
  47. package/dist/tag-snapshot-worker-pi.js +8 -8
  48. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -249,7 +249,7 @@ import {
249
249
  registerTodoStateLifecycle,
250
250
  syncCtxMemoryToolEnabled,
251
251
  registerMagicContextTools
252
- } from "./index-jt0g3hn0.js";
252
+ } from "./index-w6r3ggnp.js";
253
253
  import"./index-4knyh1kt.js";
254
254
  import {
255
255
  canonicalModelIdentity,
@@ -267,7 +267,7 @@ import {
267
267
  DEFAULT_HISTORIAN_TIMEOUT_MS,
268
268
  DREAM_TASK_PROMOTION_DEFAULTS,
269
269
  LIVE_RELOAD_CONFIG_PATHS
270
- } from "./index-bxmf4dhr.js";
270
+ } from "./index-ccanzg8p.js";
271
271
  import {
272
272
  FAIL_CLOSED_DOCTOR_COMMAND,
273
273
  formatFailClosedBlockingMessage,
@@ -290,7 +290,7 @@ import {
290
290
  openCurrentDatabase,
291
291
  openDatabaseAsync,
292
292
  closeDatabase
293
- } from "./index-mtvvhcw4.js";
293
+ } from "./index-dbgg6hsf.js";
294
294
  import {
295
295
  pruneMissingProjectIdentities,
296
296
  setHomeProjectPermission,
@@ -302,7 +302,7 @@ import {
302
302
  resolveProjectIdentityForSession,
303
303
  beginBootQuietPeriod,
304
304
  scheduleAfterBootQuiet
305
- } from "./index-p63nwn5v.js";
305
+ } from "./index-hxp6q5f8.js";
306
306
  import {
307
307
  detectThinkingBindingMismatch,
308
308
  detectLatestTurnThinkingMismatch,
@@ -463,7 +463,7 @@ import {
463
463
  getRawSessionTagKeysThrough2,
464
464
  getLegacyProtectedTailStartOrdinal2,
465
465
  readSessionChunk2
466
- } from "./index-zhwwp8zz.js";
466
+ } from "./index-gqjxy2p7.js";
467
467
  import {
468
468
  UNKNOWN_FIT_RATIO,
469
469
  hasMeasuredDecisionCalibration,
@@ -550,7 +550,7 @@ import {
550
550
  getToolTagNumberByOwner2,
551
551
  getNullOwnerToolTag2,
552
552
  adoptNullOwnerToolTag2
553
- } from "./index-bttctq07.js";
553
+ } from "./index-n8e5e9fp.js";
554
554
  import {
555
555
  textMentionsRecentCommit,
556
556
  hasMeaningfulUserText2,
@@ -567,6 +567,7 @@ import {
567
567
  inRootAsyncContext2,
568
568
  Database2,
569
569
  getSqliteDatabasePath2,
570
+ withSqliteTurnDeadline2,
570
571
  withSqliteBackgroundWriter2,
571
572
  withSqliteTransformPass2,
572
573
  withoutSqliteTransformPass2,
@@ -575,7 +576,7 @@ import {
575
576
  isTransientSqliteError2,
576
577
  withAsyncPrivilegedWriter2,
577
578
  indexCoordinationInput2
578
- } from "./index-hws5f0z9.js";
579
+ } from "./index-2qtx0q6h.js";
579
580
  import {
580
581
  stableStringify,
581
582
  closeQuietly,
@@ -613,7 +614,7 @@ import {
613
614
  indexSingleMessage2,
614
615
  indexMessagesAfterOrdinal2,
615
616
  sweepOrphanedOpenCodeMessageIndexesCooperatively2
616
- } from "./index-vdy273xw.js";
617
+ } from "./index-wgmhk91m.js";
617
618
  import {
618
619
  resolveOpenCodeDbPath,
619
620
  assertOpenCodeStoreGeneration,
@@ -629,11 +630,11 @@ import {
629
630
  import {
630
631
  runSessionWarmupWorker,
631
632
  RAW_SUMMARY_TEXT_MAX_CHARS2
632
- } from "./index-rfyvax95.js";
633
+ } from "./index-at6py2k3.js";
633
634
  import {
634
635
  formatSynapseLaneDescriptor
635
- } from "./index-jxjr7kz9.js";
636
- import"./index-rgfb753z.js";
636
+ } from "./index-gwxaz0z5.js";
637
+ import"./index-579m1751.js";
637
638
  import {
638
639
  buildCanonicalChunkTextFromFts2,
639
640
  buildCompartmentSummaryFallbackText2,
@@ -643,7 +644,7 @@ import {
643
644
  replaceCompartmentChunkEmbeddings2,
644
645
  deleteChunkEmbedBackoffForSession2,
645
646
  chunkWindowSourceKey2
646
- } from "./index-5n5zxs8e.js";
647
+ } from "./index-vx6f7wff.js";
647
648
  import {
648
649
  recordSessionProjectIdentity,
649
650
  GIT_SWEEP_LEASE_RENEWAL_MS,
@@ -652,7 +653,7 @@ import {
652
653
  markGitSweepSuccessAndRelease,
653
654
  parkGitSweepNonIndexable,
654
655
  releaseGitSweepLease
655
- } from "./index-qerzchrs.js";
656
+ } from "./index-j3pz3a1b.js";
656
657
  import {
657
658
  embedPauseBySession,
658
659
  embedRunStateBySession,
@@ -678,7 +679,7 @@ import {
678
679
  embedSessionCompartmentChunks2,
679
680
  getEmbeddingCoverageStatus2,
680
681
  getAutoEmbeddingSessionCoverage2
681
- } from "./index-v2epyzbm.js";
682
+ } from "./index-w1twp2kp.js";
682
683
  import {
683
684
  rememberV1HiddenRun
684
685
  } from "./index-6x556c2q.js";
@@ -693,7 +694,7 @@ import {
693
694
  expandWorkspaceIdentitySetWithAliases,
694
695
  sourceNameForMemory,
695
696
  computeWorkspaceEpochFingerprint
696
- } from "./index-5vgt1zeh.js";
697
+ } from "./index-3c3ztwgc.js";
697
698
  import {
698
699
  configureContextDatabasePragmas2
699
700
  } from "./index-fapenpch.js";
@@ -743,7 +744,7 @@ import {
743
744
  normalizeVerificationFiles,
744
745
  indexCommitsForProject,
745
746
  embedUnembeddedCommits
746
- } from "./index-af9t637y.js";
747
+ } from "./index-ftvm2acc.js";
747
748
  import {
748
749
  setEmbeddingSessionBusy2,
749
750
  isEmbeddingHostBusy2
@@ -767,7 +768,7 @@ import {
767
768
  setMemoryClassification2,
768
769
  archiveMemory2,
769
770
  getMemoryCountsByStatus2
770
- } from "./index-dzem6gn9.js";
771
+ } from "./index-29nw7n1r.js";
771
772
  import {
772
773
  invalidateMemory2
773
774
  } from "./index-yhzhdp3m.js";
@@ -776,11 +777,11 @@ import {
776
777
  } from "./index-q1yc6bs0.js";
777
778
  import {
778
779
  getCachedLocalEmbeddingPooling
779
- } from "./index-e19qtjj0.js";
780
+ } from "./index-wqpjhx1p.js";
780
781
  import {
781
782
  cosineSimilarity
782
- } from "./index-b8am7tns.js";
783
- import"./index-6kb2xpw7.js";
783
+ } from "./index-pe5gz5c4.js";
784
+ import"./index-6wdwv3a6.js";
784
785
  import {
785
786
  DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS,
786
787
  buildHiddenAgentRegistrations,
@@ -793,6 +794,10 @@ import {
793
794
  SUBAGENT_OUTPUT_CEILING_ENV2
794
795
  } from "./index-fa485mqs.js";
795
796
  import {
797
+ PI_CONTEXT_BUDGET,
798
+ PiContextDeadlineError,
799
+ PiContextSupersededError,
800
+ PiContextBudget,
796
801
  PiTagHydrationError,
797
802
  getPiTagSnapshotView,
798
803
  getPiActiveTagSnapshotView,
@@ -802,10 +807,10 @@ import {
802
807
  drainPiTagSnapshotSession,
803
808
  assertPiTagSnapshotReady,
804
809
  ensurePiTagSnapshotReady
805
- } from "./index-kqb3d8bs.js";
810
+ } from "./index-5j6vwg4z.js";
806
811
  import"./index-jn44h81p.js";
807
812
  import"./index-1cvyaw9a.js";
808
- import"./index-tb3d9trm.js";
813
+ import"./index-st4gwt64.js";
809
814
  import {
810
815
  __toESM
811
816
  } from "./index-22jkk6wg.js";
@@ -3547,7 +3552,7 @@ function startHostStallProfilerSwitch() {
3547
3552
  // package.json
3548
3553
  var package_default = {
3549
3554
  name: "@cortexkit/pi-magic-context",
3550
- version: "0.49.20",
3555
+ version: "0.49.21",
3551
3556
  type: "module",
3552
3557
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3553
3558
  main: "dist/index.js",
@@ -3596,7 +3601,7 @@ var package_default = {
3596
3601
  "comment-json": "^5.0.0",
3597
3602
  "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c",
3598
3603
  "quickjs-emscripten": "^0.32.0",
3599
- zod: "^4.1.8"
3604
+ zod: "^4.6.6"
3600
3605
  },
3601
3606
  optionalDependencies: {
3602
3607
  "onnxruntime-node": "1.30.0",
@@ -3612,9 +3617,12 @@ var package_default = {
3612
3617
  "@types/bun": "^1.3.10",
3613
3618
  "@types/node": "^22.20.0",
3614
3619
  "omp-coding-agent-1812": "npm:@oh-my-pi/pi-coding-agent@18.12.3",
3620
+ "omp-coding-agent-18126": "npm:@oh-my-pi/pi-coding-agent@18.12.6",
3621
+ "omp-pi-ai-171": "npm:@oh-my-pi/pi-ai@17.1.7",
3615
3622
  "omp-pi-ai-1889": "npm:@oh-my-pi/pi-ai@18.8.9",
3616
3623
  "omp-pi-ai-1811": "npm:@oh-my-pi/pi-ai@18.11.3",
3617
3624
  "omp-pi-ai-1812": "npm:@oh-my-pi/pi-ai@18.12.3",
3625
+ "omp-pi-ai-18126": "npm:@oh-my-pi/pi-ai@18.12.6",
3618
3626
  "pi-agent-core-087": "npm:@earendil-works/pi-agent-core@0.87.1",
3619
3627
  "pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
3620
3628
  "pi-ai-087": "npm:@earendil-works/pi-ai@0.87.1",
@@ -5328,7 +5336,7 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
5328
5336
  throwWithPromptFailure(failure.error, failedAttempts, args, timeoutMs, options.transport);
5329
5337
  }
5330
5338
  if (!cooledPrimary && !quota)
5331
- log2(`[${callContext}] primary (${explicitPrimaryLabel}) failed validation/prompt: ${shortErr(failure.error)}; trying ${fallbacks.length} fallback(s)`);
5339
+ log2(`[${callContext}] primary (${explicitPrimaryLabel}) failed validation/prompt: ${shortErr(failure.error)}; ${fallbacks.length} fallback(s) configured, subject to remaining budget`);
5332
5340
  }
5333
5341
  for (let i = 0;i < fallbacks.length; i += 1) {
5334
5342
  const fallback = toModelEntry(fallbacks[i]);
@@ -12285,28 +12293,35 @@ function diff(name, before, after) {
12285
12293
  rmSync(dir, { recursive: true, force: true });
12286
12294
  }
12287
12295
  }
12288
- function validateDocsProposal(projectDir, output, budget, expected) {
12289
- if (Object.entries(expected).some(([name, value]) => docsBaseHashes(projectDir)[name] !== value))
12290
- throw new Error("base drifted");
12296
+ function parseDocsProposalOutput(output) {
12291
12297
  const match = output.match(/```json\s*([\s\S]*?)```/);
12292
12298
  const parsed = JSON.parse(match?.[1] ?? output);
12293
12299
  if (!Array.isArray(parsed))
12294
12300
  throw new Error("proposal must be a JSON array");
12295
12301
  const changes = parsed;
12296
- if (!changes.length)
12297
- throw new Error("empty proposal");
12298
12302
  if (changes.some((item) => !item || !FILES.includes(item.file)))
12299
12303
  throw new Error("unknown proposal file");
12304
+ const seen = new Set;
12305
+ for (const change of changes) {
12306
+ const key = `${change.file}:${change.heading}`;
12307
+ if (!["replace", "add", "remove"].includes(change.action) || typeof change.heading !== "string" || !/^#{1,6} [^\r\n]+$/.test(change.heading) || typeof change.text !== "string" || typeof change.reason !== "string" || !change.reason.trim() || /[\r\n]/.test(change.reason) || seen.has(key))
12308
+ throw new Error(`invalid section change in ${change.file}`);
12309
+ seen.add(key);
12310
+ }
12311
+ return changes;
12312
+ }
12313
+ function validateDocsProposal(projectDir, output, budget, expected) {
12314
+ if (Object.entries(expected).some(([name, value]) => docsBaseHashes(projectDir)[name] !== value))
12315
+ throw new Error("base drifted");
12316
+ const changes = parseDocsProposalOutput(output);
12317
+ if (!changes.length)
12318
+ throw new Error("empty proposal");
12300
12319
  let tokens = 0;
12301
12320
  let diffs = "";
12302
12321
  for (const file of FILES) {
12303
12322
  const before = existsSync6(join8(projectDir, file)) ? readFileSync6(join8(projectDir, file), "utf8") : "";
12304
12323
  let after = before;
12305
- const seen = new Set;
12306
12324
  for (const change of changes.filter((item) => item.file === file)) {
12307
- if (!["replace", "add", "remove"].includes(change.action) || typeof change.heading !== "string" || !/^#{1,6} [^\r\n]+$/.test(change.heading) || typeof change.text !== "string" || typeof change.reason !== "string" || !change.reason.trim() || /[\r\n]/.test(change.reason) || seen.has(change.heading))
12308
- throw new Error(`invalid section change in ${file}`);
12309
- seen.add(change.heading);
12310
12325
  const section = sections(after).find((item) => item.heading === change.heading);
12311
12326
  if (change.action === "add") {
12312
12327
  if (section || !change.text.startsWith(`${change.heading}
@@ -18726,6 +18741,8 @@ async function runAgenticTask(config, ctx, helpers) {
18726
18741
  timeoutMs: Math.min(Math.max(0, deadline - Date.now()), config.timeoutMinutes * 60 * 1000),
18727
18742
  signal: abortController.signal,
18728
18743
  parse: (text, completion) => {
18744
+ if (task === "maintain-docs")
18745
+ parseDocsProposalOutput(text);
18729
18746
  if (task !== "curate")
18730
18747
  return text;
18731
18748
  const memoryOperations = inspectCurateMemoryOperations(completion.messages);
@@ -18789,6 +18806,8 @@ async function runAgenticTask(config, ctx, helpers) {
18789
18806
  if (task !== "curate") {
18790
18807
  if (!text)
18791
18808
  throw new Error("Dreamer returned no assistant output.");
18809
+ if (task === "maintain-docs")
18810
+ parseDocsProposalOutput(text);
18792
18811
  return text;
18793
18812
  }
18794
18813
  const memoryOperations = inspectCurateMemoryOperations(messages);
@@ -18838,7 +18857,7 @@ async function runAgenticTask(config, ctx, helpers) {
18838
18857
  recordInvocation("completed", run.output);
18839
18858
  if (task === "maintain-docs" && docsHashes && changes) {
18840
18859
  try {
18841
- if (run.validated === "[]") {
18860
+ if (parseDocsProposalOutput(String(run.validated)).length === 0) {
18842
18861
  helpers.recordRun("completed", null, { progress: "no corrections proposed" });
18843
18862
  return {
18844
18863
  status: "completed",
@@ -19479,6 +19498,8 @@ var RECONCILIATION_BATCH_SIZE = 100;
19479
19498
 
19480
19499
  class MagicContextMessageIndexHeapHolder {
19481
19500
  reconciledSessions = new Set;
19501
+ reconciledSnapshots = new Map;
19502
+ stalledSessions = new Set;
19482
19503
  reconciliationScheduledSessions = new Set;
19483
19504
  clearAndReindexScheduledSessions = new Map;
19484
19505
  sessionLocks = new Map;
@@ -19529,18 +19550,28 @@ function logIndexingError(sessionId, action, error) {
19529
19550
  sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
19530
19551
  log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
19531
19552
  }
19553
+ function logReconciliationStall(sessionId, reason) {
19554
+ if (heapHolder.stalledSessions.has(sessionId))
19555
+ return;
19556
+ heapHolder.stalledSessions.add(sessionId);
19557
+ sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
19558
+ }
19532
19559
  async function reconcileSessionIndex(db, sessionId, readMessages) {
19533
- if (!await sourceReady(readMessages, sessionId))
19560
+ if (!await sourceReady(readMessages, sessionId)) {
19561
+ logReconciliationStall(sessionId, "raw message reader is not ready");
19534
19562
  return false;
19563
+ }
19535
19564
  await runWithSessionLock(sessionId, async () => {
19536
- if (heapHolder.reconciledSessions.has(sessionId))
19565
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
19537
19566
  return;
19538
19567
  let fallbackSnapshot = null;
19539
19568
  try {
19540
19569
  const fullReader = typeof readMessages === "function" ? readMessages : null;
19541
- const finalWatermark = readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
19570
+ const revision = readMessages.getRevision?.(sessionId);
19571
+ const previous = heapHolder.reconciledSnapshots.get(sessionId);
19572
+ const finalWatermark = previous && revision === previous.revision ? previous.count : revision !== undefined && readMessages.getCountAfterRevision ? previous && revision > previous.revision ? previous.count + readMessages.getCountAfterRevision(sessionId, previous.revision, revision) : readMessages.getCountAfterRevision(sessionId, -1, revision) : readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
19542
19573
  let cursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
19543
- let after;
19574
+ let after = cursor === previous?.count ? previous.after : undefined;
19544
19575
  while (cursor < finalWatermark) {
19545
19576
  const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
19546
19577
  const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
@@ -19559,6 +19590,20 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
19559
19590
  }
19560
19591
  if (isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
19561
19592
  heapHolder.reconciledSessions.add(sessionId);
19593
+ if (revision !== undefined) {
19594
+ if (!after && finalWatermark > 0 && readMessages.readPage) {
19595
+ const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
19596
+ if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
19597
+ after = { timeCreated: last.createdAt, id: last.id };
19598
+ }
19599
+ heapHolder.reconciledSnapshots.set(sessionId, {
19600
+ revision,
19601
+ count: finalWatermark,
19602
+ after
19603
+ });
19604
+ }
19605
+ } else {
19606
+ logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
19562
19607
  }
19563
19608
  } finally {
19564
19609
  heapHolder.activeReconcilerBuffers.delete(sessionId);
@@ -19567,25 +19612,32 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
19567
19612
  return true;
19568
19613
  }
19569
19614
  function scheduleReconciliation(db, sessionId, readMessages) {
19570
- if (heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
19615
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
19571
19616
  return;
19572
19617
  }
19573
19618
  heapHolder.reconciliationScheduledSessions.add(sessionId);
19574
19619
  scheduleAfterBootQuiet(() => {
19575
19620
  defer(() => {
19621
+ let appendedDuringReconciliation = false;
19622
+ const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
19576
19623
  reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
19577
- if (ran)
19624
+ if (ran) {
19625
+ const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
19626
+ appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
19578
19627
  return;
19628
+ }
19579
19629
  inRootAsyncContext2(() => setTimeout(() => {
19580
19630
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
19581
19631
  scheduleReconciliation(db, sessionId, readMessages);
19582
19632
  }, PREPARE_RETRY_MS)).unref?.();
19583
19633
  }).catch((error) => {
19584
- logIndexingError(sessionId, "reconciliation", error);
19634
+ logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
19585
19635
  if (isDatabaseLockedError(error))
19586
19636
  inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
19587
19637
  }).finally(() => {
19588
19638
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
19639
+ if (appendedDuringReconciliation)
19640
+ scheduleReconciliation(db, sessionId, readMessages);
19589
19641
  });
19590
19642
  });
19591
19643
  });
@@ -19718,6 +19770,8 @@ function clearSessionTracking(sessionId) {
19718
19770
  Atomics.store(cancellation, 0, 1);
19719
19771
  heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
19720
19772
  heapHolder.reconciledSessions.delete(sessionId);
19773
+ heapHolder.reconciledSnapshots.delete(sessionId);
19774
+ heapHolder.stalledSessions.delete(sessionId);
19721
19775
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
19722
19776
  heapHolder.sessionLocks.delete(sessionId);
19723
19777
  heapHolder.activeReconcilerBuffers.delete(sessionId);
@@ -25107,7 +25161,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
25107
25161
 
25108
25162
  // ../plugin/src/hooks/magic-context/cache-busting-signals.ts
25109
25163
  function hasReclaimRide(signals) {
25110
- return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true || signals.executeReclaim === true;
25164
+ return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true || signals.executeReclaim === true || signals.servedShapeRepair === true;
25111
25165
  }
25112
25166
  function prefixMutationPermitted(gate) {
25113
25167
  return !gate.signedThinkingHold || gate.firstRender || gate.idleExpiry || gate.emergency;
@@ -25121,7 +25175,8 @@ var RECLAIM_RIDE_NAMES = [
25121
25175
  "explicitFlush",
25122
25176
  "publishedHistory",
25123
25177
  "subagentExecute",
25124
- "executeReclaim"
25178
+ "executeReclaim",
25179
+ "servedShapeRepair"
25125
25180
  ];
25126
25181
  function reclaimRideLabel(signals) {
25127
25182
  const active = RECLAIM_RIDE_NAMES.filter((name) => signals[name]);
@@ -27690,6 +27745,7 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
27690
27745
  db,
27691
27746
  targets,
27692
27747
  skipPrefixInjection,
27748
+ preserveTagOnlyAssistantText: options.preserveTagOnlyAssistantText,
27693
27749
  entryFingerprint: options.entryFingerprintByMessageId?.get(messageId) ?? null,
27694
27750
  reuseIdentity: reuseIdentity || contentDerivedTextIds !== undefined,
27695
27751
  timing,
@@ -28081,7 +28137,7 @@ function isRecord2(value) {
28081
28137
  function tagTextPart(args) {
28082
28138
  const identityStart = args.timing ? performance.now() : 0;
28083
28139
  const text = args.part.getText() ?? "";
28084
- if (args.message.info.role === "assistant" && stripWellFormedLeadingTagPrefix(text).trim().length === 0) {
28140
+ if (args.message.info.role === "assistant" && (stripWellFormedLeadingTagPrefix(text).trim().length === 0 || args.preserveTagOnlyAssistantText && text.includes("§") && stripPersistedAssistantText(text).length === 0)) {
28085
28141
  if (args.timing)
28086
28142
  args.timing.identity += performance.now() - identityStart;
28087
28143
  return;
@@ -28673,7 +28729,15 @@ class AutoSearchBusyError extends Error {
28673
28729
  }
28674
28730
  }
28675
28731
  async function searchAutoHint(db, sessionId, projectPath, query, options, entry = new URL(new URL(import.meta.url).pathname.endsWith(".ts") ? "./auto-search-worker.ts" : "./auto-search-worker.js", import.meta.url)) {
28676
- return executeAutoSearchWorker(db, sessionId, projectPath, query, options, entry, "search");
28732
+ const {
28733
+ rerankConfig: _rerankConfig,
28734
+ rerankClient: _rerankClient,
28735
+ rerankConnectionFile: _rerankConnectionFile,
28736
+ onRerankSkipped: _onRerankSkipped,
28737
+ captureRerankLanes: _captureRerankLanes,
28738
+ ...hintOptions
28739
+ } = options;
28740
+ return executeAutoSearchWorker(db, sessionId, projectPath, query, { ...hintOptions, explicitSearch: false, rerank: false }, entry, "search");
28677
28741
  }
28678
28742
  var pendingBackfills = new WeakMap;
28679
28743
  var searchWorkers = new WeakMap;
@@ -35216,123 +35280,6 @@ function adaptPiAppendCompaction(sessionManager) {
35216
35280
  };
35217
35281
  }
35218
35282
 
35219
- // src/pi-context-budget.ts
35220
- var PI_CONTEXT_BUDGET = {
35221
- hostDeadlineMs: 30000,
35222
- hostMarginMs: 5000,
35223
- outcomeMs: 25000,
35224
- fallbackObservedMs: 4,
35225
- workMs: 21000,
35226
- writerMs: 16500,
35227
- completionReserveMs: 2000,
35228
- searchMs: 3000
35229
- };
35230
-
35231
- class PiContextDeadlineError extends Error {
35232
- }
35233
-
35234
- class PiContextSupersededError extends Error {
35235
- origin;
35236
- constructor(message, origin = "context ownership") {
35237
- super(message);
35238
- this.origin = origin;
35239
- }
35240
- }
35241
-
35242
- class PiContextBudget {
35243
- startedAt;
35244
- now;
35245
- sideTurn = false;
35246
- stage = "entry";
35247
- recovery = "not attempted";
35248
- abandoned = false;
35249
- completed = false;
35250
- failureReason;
35251
- signal;
35252
- cancelled = false;
35253
- isCancelled(error) {
35254
- return this.cancelled || this.signal?.aborted === true || !this.signal && typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
35255
- }
35256
- cancel() {
35257
- this.cancelled = true;
35258
- this.abandoned = true;
35259
- this.completed = false;
35260
- this.failureReason = undefined;
35261
- }
35262
- assertOwner = () => {};
35263
- constructor(startedAt = performance.now(), now = () => performance.now()) {
35264
- this.startedAt = startedAt;
35265
- this.now = now;
35266
- }
35267
- elapsed() {
35268
- return this.now() - this.startedAt;
35269
- }
35270
- remainingWork = () => {
35271
- return Math.max(0, PI_CONTEXT_BUDGET.workMs - this.elapsed());
35272
- };
35273
- remainingOutcome = () => Math.max(0, PI_CONTEXT_BUDGET.outcomeMs - this.elapsed());
35274
- writerAllowance() {
35275
- return Math.max(0, Math.min(PI_CONTEXT_BUDGET.writerMs, this.remainingWork() - PI_CONTEXT_BUDGET.completionReserveMs));
35276
- }
35277
- hydrationAllowance() {
35278
- return Math.max(0, Math.min(this.remainingWork() - PI_CONTEXT_BUDGET.completionReserveMs, this.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs));
35279
- }
35280
- assertOutcome = () => {
35281
- this.assertOwner();
35282
- this.signal?.throwIfAborted();
35283
- if (this.abandoned || this.elapsed() >= PI_CONTEXT_BUDGET.outcomeMs)
35284
- throw new PiContextDeadlineError(this.diagnostic());
35285
- };
35286
- assert = () => {
35287
- this.assertOutcome();
35288
- if (this.elapsed() >= PI_CONTEXT_BUDGET.workMs)
35289
- throw new PiContextDeadlineError(this.diagnostic());
35290
- };
35291
- assertDecisionPublication = () => {
35292
- this.signal?.throwIfAborted();
35293
- if (!this.completed)
35294
- this.assertOwner();
35295
- if (this.abandoned || !this.completed && this.elapsed() >= PI_CONTEXT_BUDGET.outcomeMs)
35296
- throw new PiContextDeadlineError(this.diagnostic());
35297
- };
35298
- diagnostic() {
35299
- return `stage=${this.stage} elapsed=${Math.round(this.elapsed())}ms recovery=${this.recovery}`;
35300
- }
35301
- waitUntil = async (pending, assert, remaining) => {
35302
- try {
35303
- assert();
35304
- } catch (error) {
35305
- pending.catch(() => {});
35306
- throw error;
35307
- }
35308
- let timer;
35309
- let onAbort;
35310
- try {
35311
- return await Promise.race([
35312
- pending,
35313
- ...this.signal ? [
35314
- new Promise((_, reject) => {
35315
- onAbort = () => reject(this.signal?.reason);
35316
- this.signal?.addEventListener("abort", onAbort, {
35317
- once: true
35318
- });
35319
- })
35320
- ] : [],
35321
- new Promise((_, reject) => {
35322
- timer = setTimeout(() => reject(new PiContextDeadlineError(this.diagnostic())), remaining());
35323
- })
35324
- ]);
35325
- } finally {
35326
- clearTimeout(timer);
35327
- if (onAbort)
35328
- this.signal?.removeEventListener("abort", onAbort);
35329
- assert();
35330
- }
35331
- };
35332
- wait = (pending) => this.waitUntil(pending, this.assert, () => this.remainingWork());
35333
- waitMandatory = (pending) => this.waitUntil(pending, this.assertOutcome, this.remainingOutcome);
35334
- }
35335
-
35336
35283
  // src/pi-context-limit.ts
35337
35284
  var MIN_SANE_LIMIT = 16000;
35338
35285
  var MAX_SANE_LIMIT = 1e7;
@@ -36025,6 +35972,11 @@ function piHasManagedSignature(payload, signature) {
36025
35972
  return false;
36026
35973
  }
36027
35974
 
35975
+ // src/pi-dispatch-assistant-history.ts
35976
+ function piOmitsTruncatedAssistant(message) {
35977
+ return (message.stopReason === "length" || message.stopReason === "error" || message.stopReason === "aborted") && Array.isArray(message.content) && !message.content.some((block) => block?.type === "text" || block?.type === "toolCall");
35978
+ }
35979
+
36028
35980
  // src/pi-dispatch-tool-pairing.ts
36029
35981
  var RESPONSES_APIS = new Set([
36030
35982
  "openai-responses",
@@ -36074,14 +36026,14 @@ function object5(value) {
36074
36026
  function omitsAssistant(message, model, compat) {
36075
36027
  if (!Array.isArray(message.content))
36076
36028
  return false;
36029
+ if (piOmitsTruncatedAssistant(message))
36030
+ return true;
36077
36031
  let thinking = false;
36078
- let hasTextBlock = false;
36079
36032
  for (const value of message.content) {
36080
36033
  const block = object5(value);
36081
36034
  if (!block)
36082
36035
  return false;
36083
36036
  if (block.type === "text") {
36084
- hasTextBlock = true;
36085
36037
  if (typeof block.text !== "string" || block.text.trim())
36086
36038
  return false;
36087
36039
  } else if (block.type === "thinking") {
@@ -36091,8 +36043,6 @@ function omitsAssistant(message, model, compat) {
36091
36043
  } else
36092
36044
  return false;
36093
36045
  }
36094
- if (!hasTextBlock && ["length", "error", "aborted"].includes(String(message.stopReason)))
36095
- return true;
36096
36046
  if (compat.requiresReasoningContentForAllAssistantTurns === true)
36097
36047
  return false;
36098
36048
  if (!thinking)
@@ -36397,11 +36347,25 @@ ${wellFormed(text)}
36397
36347
  </think>`;
36398
36348
  return;
36399
36349
  }
36400
- function piResponsesAssistantTexts(value, model) {
36350
+ function coldReplayable(items) {
36351
+ let reasoning = false;
36352
+ for (const value of items) {
36353
+ const item = object7(value);
36354
+ if (typeof item?.encrypted_content === "string")
36355
+ return false;
36356
+ if (item?.type !== "reasoning")
36357
+ continue;
36358
+ if (!Array.isArray(item.content) || !item.content.some((part) => object7(part)?.type === "reasoning_text"))
36359
+ return false;
36360
+ reasoning = true;
36361
+ }
36362
+ return reasoning;
36363
+ }
36364
+ function piResponsesAssistantTexts(value, model, host, alternatives) {
36401
36365
  const message = object7(value);
36402
36366
  if (!message || !Array.isArray(message.content))
36403
36367
  return;
36404
- if (["length", "error", "aborted"].includes(String(message.stopReason)) && !message.content.some((value) => ["text", "toolCall"].includes(String(object7(value)?.type))))
36368
+ if (piOmitsTruncatedAssistant(message))
36405
36369
  return [];
36406
36370
  const texts = [];
36407
36371
  const blocks = [];
@@ -36444,6 +36408,13 @@ function piResponsesAssistantTexts(value, model) {
36444
36408
  const replay = [];
36445
36409
  let bound = 0;
36446
36410
  let output = false;
36411
+ const allowUnsigned = host === "omp" && message.role === "assistant" && [
36412
+ "openai-responses",
36413
+ "azure-openai-responses",
36414
+ "openai-codex-responses"
36415
+ ].includes(model?.api ?? "");
36416
+ let unsigned = false;
36417
+ let rewrittenText = false;
36447
36418
  for (const value of payload.items) {
36448
36419
  const item = object7(value);
36449
36420
  if (item?.type === "reasoning")
@@ -36467,8 +36438,14 @@ function piResponsesAssistantTexts(value, model) {
36467
36438
  } catch {
36468
36439
  return texts;
36469
36440
  }
36470
- if (signature?.v !== 1 || typeof signature.id !== "string" || item.id !== signature.id || item.phase !== signature.phase || part.text !== block.text.replace(/^§\d+§ /u, ""))
36471
- return texts;
36441
+ const signed = signature?.v === 1 && typeof signature.id === "string" && item.id === signature.id && item.phase === signature.phase && part.text === block.text.replace(/^§\d+§ /u, "");
36442
+ if (!signed) {
36443
+ const stripped = stripPersistedAssistantText(part.text);
36444
+ if (!allowUnsigned || "textSignature" in block || stripped !== block.text.replace(/^§\d+§ /u, ""))
36445
+ return texts;
36446
+ unsigned = true;
36447
+ rewrittenText ||= part.text !== stripped && part.text !== block.text;
36448
+ }
36472
36449
  bound++;
36473
36450
  itemTexts.push(part.text);
36474
36451
  }
@@ -36478,7 +36455,13 @@ function piResponsesAssistantTexts(value, model) {
36478
36455
  for (const text of itemTexts)
36479
36456
  replay.push(textIdentity2(wellFormed(text), item.phase));
36480
36457
  }
36481
- return output && bound === blocks.length ? replay : texts;
36458
+ if (!output || bound !== blocks.length || unsigned && !rewrittenText)
36459
+ return texts;
36460
+ if (unsigned && alternatives) {
36461
+ alternatives.fallback = texts;
36462
+ alternatives.cold = coldReplayable(payload.items) ? replay : texts;
36463
+ }
36464
+ return replay;
36482
36465
  }
36483
36466
  function piResponsesWireTexts(value, phase) {
36484
36467
  if (phase !== undefined && phase !== null && phase !== "commentary" && phase !== "final_answer")
@@ -36720,11 +36703,10 @@ function projectMissingToolResults(messages, model, host = "omp") {
36720
36703
  const message = object8(value);
36721
36704
  if (message?.role === "assistant") {
36722
36705
  flush(message.timestamp);
36706
+ if (piOmitsTruncatedAssistant(message))
36707
+ continue;
36723
36708
  projected.push(value);
36724
36709
  const calls = windowCalls(message);
36725
- const truncated = ["length", "error", "aborted"].includes(String(message.stopReason));
36726
- if (truncated && Array.isArray(message.content) && !message.content.some((part) => ["toolCall", "text"].includes(String(object8(part)?.type))))
36727
- continue;
36728
36710
  if (message.stopReason === "aborted" || message.stopReason === "error") {
36729
36711
  aborted = new Map(calls.map((call) => [pairingId(call.id), call]));
36730
36712
  abortedTimestamp = message.timestamp;
@@ -37018,31 +37000,43 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37018
37000
  }
37019
37001
  const responsesApi = responsesLane(model?.api);
37020
37002
  let responsesMessages = responsesApi ? [] : undefined;
37003
+ const fallbackMessages = [];
37004
+ const coldMessages = [];
37005
+ let unsignedAlternatives = false;
37006
+ const appendResponse = (output, row, texts) => {
37007
+ if (!texts.length && !row.calls.length)
37008
+ return;
37009
+ const previous = output.at(-1);
37010
+ if (previous?.role === "assistant") {
37011
+ previous.calls.push(...row.calls);
37012
+ previous.wireCalls?.push(...row.wireCalls ?? []);
37013
+ previous.responseTexts?.push(...texts);
37014
+ } else
37015
+ output.push({
37016
+ ...row,
37017
+ calls: [...row.calls],
37018
+ ...row.wireCalls ? { wireCalls: [...row.wireCalls] } : {},
37019
+ responseTexts: [...texts]
37020
+ });
37021
+ };
37021
37022
  if (responsesMessages) {
37022
37023
  for (const [index, row] of byIndex) {
37023
37024
  if (row.role !== "assistant") {
37024
37025
  responsesMessages.push(row);
37026
+ fallbackMessages.push(row);
37027
+ coldMessages.push(row);
37025
37028
  continue;
37026
37029
  }
37027
- const texts = piResponsesAssistantTexts(projectedMessages[index], model);
37030
+ const alternatives = {};
37031
+ const texts = piResponsesAssistantTexts(projectedMessages[index], model, host, alternatives);
37028
37032
  if (!texts) {
37029
37033
  responsesMessages = undefined;
37030
37034
  break;
37031
37035
  }
37032
- if (!texts.length && !row.calls.length)
37033
- continue;
37034
- const previous = responsesMessages.at(-1);
37035
- if (previous?.role === "assistant") {
37036
- previous.calls.push(...row.calls);
37037
- previous.wireCalls?.push(...row.wireCalls ?? []);
37038
- previous.responseTexts?.push(...texts);
37039
- } else
37040
- responsesMessages.push({
37041
- ...row,
37042
- calls: [...row.calls],
37043
- ...row.wireCalls ? { wireCalls: [...row.wireCalls] } : {},
37044
- responseTexts: [...texts]
37045
- });
37036
+ unsignedAlternatives ||= alternatives.fallback !== undefined;
37037
+ appendResponse(responsesMessages, row, texts);
37038
+ appendResponse(fallbackMessages, row, alternatives.fallback ?? texts);
37039
+ appendResponse(coldMessages, row, alternatives.cold ?? texts);
37046
37040
  }
37047
37041
  }
37048
37042
  const plan = piChatHistoryPlan(projectedMessages, model);
@@ -37077,6 +37071,7 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37077
37071
  ...responsesApi && !responsesMessages ? { structuralSkipReason: "Responses history transform is not modeled" } : model?.api === "openai-completions" && !chatMessages ? { structuralSkipReason: "Chat history transform is not modeled" } : {},
37078
37072
  ...chatMessages ? { chatMessages } : {},
37079
37073
  ...responsesMessages ? { responsesMessages } : {},
37074
+ ...responsesMessages && unsignedAlternatives ? { responsesAlternatives: [fallbackMessages, coldMessages] } : {},
37080
37075
  ...model?.api ? { api: model.api } : {},
37081
37076
  ...model?.api?.startsWith("google-") ? {
37082
37077
  googleFunctionIds: object8(model.compat)?.supportsFunctionPartId === true
@@ -37393,6 +37388,10 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
37393
37388
  const chat = !!body && Array.isArray(body.messages) && (prepared?.api === "openai-completions" || body.system === undefined) && body.input === undefined && body.inferenceConfig === undefined;
37394
37389
  stage = "prepared rows";
37395
37390
  expectedRows = responses && prepared?.responsesMessages ? prepared.responsesMessages : chat && prepared?.chatMessages ? prepared.chatMessages : prepared?.messages;
37391
+ if (responses && rows && prepared?.responsesAlternatives) {
37392
+ const actual = rows;
37393
+ expectedRows = [prepared.responsesMessages, ...prepared.responsesAlternatives].find((candidate) => candidate?.length === actual.length && candidate.every((expected, index) => JSON.stringify(expected.responseTexts) === JSON.stringify(actual[index].responseTexts))) ?? expectedRows;
37394
+ }
37396
37395
  if (expectedRows && imageProjection && imageBudget)
37397
37396
  expectedRows = trimPreparedImageRows(expectedRows, imageBudget, trimmed);
37398
37397
  if (!rows || !expectedRows)
@@ -39169,7 +39168,7 @@ function registerPiGuardedContext(pi, handler, options = {}) {
39169
39168
  inputs = messageSnapshots(event.messages);
39170
39169
  active.inputMessages = inputs;
39171
39170
  }
39172
- const result = await budget.waitMandatory(Promise.resolve(withSqliteTransformPass2(() => handler(event, ctx, budget))));
39171
+ const result = await budget.waitMandatory(Promise.resolve(withSqliteTurnDeadline2(() => Math.max(0, budget.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs), () => withSqliteTransformPass2(() => handler(event, ctx, budget)))));
39173
39172
  if (result?.messages) {
39174
39173
  const prepared = preparePiDispatch(result.messages, fenceEnabled ? ctx.model : undefined, fenceEnabled);
39175
39174
  if (prepared.messages !== result.messages)
@@ -39437,13 +39436,15 @@ function recordPiUpperEstimateReclaim(db, cursor, reservation) {
39437
39436
  pendingInput.delete(cursor.sessionId);
39438
39437
  }
39439
39438
  function releasePiUpperEstimateReclaim(db, cursor, reservation) {
39440
- if (!updateReplayDocument(db, cursor.sessionId, (doc) => {
39441
- if (claimFrom(doc[KEY2], cursor.sessionId)?.reservation !== reservation)
39442
- return false;
39443
- delete doc[KEY2];
39444
- return true;
39445
- }))
39446
- throw new Error("Could not release upper-estimate reclaim");
39439
+ withoutSqliteTransformPass2(() => withSqliteTurnDeadline2(() => 0, () => {
39440
+ if (!updateReplayDocument(db, cursor.sessionId, (doc) => {
39441
+ if (claimFrom(doc[KEY2], cursor.sessionId)?.reservation !== reservation)
39442
+ return false;
39443
+ delete doc[KEY2];
39444
+ return true;
39445
+ }))
39446
+ throw new Error("Could not release upper-estimate reclaim");
39447
+ }));
39447
39448
  }
39448
39449
  function resetPiUpperEstimateReclaim(db, sessionId) {
39449
39450
  if (!claimFrom(readReplayEnvelope(db, sessionId)[KEY2], sessionId))
@@ -39455,6 +39456,21 @@ function resetPiUpperEstimateReclaim(db, sessionId) {
39455
39456
  throw new Error("Could not clear upper-estimate reclaim cursor");
39456
39457
  }
39457
39458
 
39459
+ // src/pi-historian-turn-wait.ts
39460
+ var foregroundWaits = new Map;
39461
+ function inPiHistorianRootContext(sessionId, operation) {
39462
+ return inRootAsyncContext2(() => withSqliteTurnDeadline2(() => foregroundWaits.get(sessionId)?.() ?? Infinity, operation));
39463
+ }
39464
+ async function waitForPiHistorianInTurn(sessionId, remainingMs, wait) {
39465
+ foregroundWaits.set(sessionId, remainingMs);
39466
+ try {
39467
+ return await wait();
39468
+ } finally {
39469
+ if (foregroundWaits.get(sessionId) === remainingMs)
39470
+ foregroundWaits.delete(sessionId);
39471
+ }
39472
+ }
39473
+
39458
39474
  // src/pi-lkg-fit-envelope.ts
39459
39475
  import { createHash as createHash13 } from "node:crypto";
39460
39476
  function readPiLkgFitEnvelope(ctx, pi, modelKey, frozen, wireSchema) {
@@ -45365,7 +45381,7 @@ function registerPiContextHandler(pi, baseOptions) {
45365
45381
  const pending = inFlightHistorian.get(sessionId);
45366
45382
  if (pending) {
45367
45383
  budget.stage = "headless fit historian";
45368
- await budget.wait(pending);
45384
+ await waitForPiHistorianInTurn(sessionId, () => Math.max(0, budget.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs), () => budget.wait(pending));
45369
45385
  }
45370
45386
  }
45371
45387
  budget.stage = "outgoing fit reclaim";
@@ -45410,7 +45426,7 @@ function registerPiContextHandler(pi, baseOptions) {
45410
45426
  estimate = estimatePiOutgoingInputTokens(outputMessages, envelope, undefined, outgoingFitLimit);
45411
45427
  } finally {
45412
45428
  if (!reclaimCompleted && upperCursor && reservation)
45413
- withoutSqliteTransformPass2(() => releasePiUpperEstimateReclaim(options.db, upperCursor, reservation));
45429
+ releasePiUpperEstimateReclaim(options.db, upperCursor, reservation);
45414
45430
  }
45415
45431
  }
45416
45432
  }
@@ -45777,7 +45793,7 @@ function spawnPiHistorianRun(args) {
45777
45793
  const holderId = crypto3.randomUUID();
45778
45794
  const controller = new AbortController;
45779
45795
  historianAbortControllers.set(sessionId, controller);
45780
- const runPromise = inRootAsyncContext2(() => (async () => {
45796
+ const runPromise = inPiHistorianRootContext(sessionId, () => (async () => {
45781
45797
  await new Promise((resolve) => setTimeout(resolve, 0));
45782
45798
  if (controller.signal.aborted)
45783
45799
  return;
@@ -46768,6 +46784,7 @@ async function runPipeline(args) {
46768
46784
  args.assertCurrentPass?.();
46769
46785
  return tagTranscript(args.sessionId, { ...transcript, messages: taggingView }, args.tagger, args.db, {
46770
46786
  skipPrefixInjection: !ctxReduceCallable,
46787
+ preserveTagOnlyAssistantText: true,
46771
46788
  entryFingerprintByMessageId,
46772
46789
  reuseMessageIds: textIdentityPlan.reusableMessageIds,
46773
46790
  textIdentityDriftMessageIds: textIdentityPlan.driftedMessageIds,
@@ -51334,7 +51351,7 @@ function stripTagPrefixFromAssistantMessage(message) {
51334
51351
  const textPart = part;
51335
51352
  if (typeof textPart.text !== "string")
51336
51353
  continue;
51337
- const stripped = stripPersistedAssistantText(textPart.text);
51354
+ const stripped = stripPersistedAssistantText(textPart.text, message.provider === "anthropic");
51338
51355
  if (stripped !== textPart.text) {
51339
51356
  textPart.text = stripped;
51340
51357
  mutated = true;
@@ -51342,7 +51359,7 @@ function stripTagPrefixFromAssistantMessage(message) {
51342
51359
  }
51343
51360
  return mutated;
51344
51361
  }
51345
- function strippedAssistantContent(content) {
51362
+ function strippedAssistantContent(content, provider = "anthropic") {
51346
51363
  if (!Array.isArray(content))
51347
51364
  return;
51348
51365
  let copy;
@@ -51353,7 +51370,7 @@ function strippedAssistantContent(content) {
51353
51370
  }
51354
51371
  if (typeof part.text !== "string")
51355
51372
  continue;
51356
- const stripped = stripPersistedAssistantText(part.text);
51373
+ const stripped = stripPersistedAssistantText(part.text, provider === "anthropic");
51357
51374
  if (stripped === part.text)
51358
51375
  continue;
51359
51376
  copy ??= content.slice();
@@ -51370,7 +51387,7 @@ function registerOmpAssistantMessageStrip(pi, isActive) {
51370
51387
  const message = event?.message;
51371
51388
  if (message?.role !== "assistant")
51372
51389
  return;
51373
- const content = strippedAssistantContent(message.content);
51390
+ const content = strippedAssistantContent(message.content, message.provider ?? "unknown");
51374
51391
  return content === undefined ? undefined : { content };
51375
51392
  } catch {
51376
51393
  return;
@@ -51917,7 +51934,7 @@ async function src_default(pi) {
51917
51934
  let openFailureCause = null;
51918
51935
  const openStorage = async () => {
51919
51936
  try {
51920
- return await openDatabaseAsync();
51937
+ return await openDatabaseAsync({ nativeTurnDeadlines: true });
51921
51938
  } catch (error) {
51922
51939
  openFailureCause = error instanceof Error ? error.message : String(error);
51923
51940
  return null;
@@ -52318,6 +52335,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
52318
52335
  const todowriteOverlayEnabled = todowriteEnabled && bootProjectDeps.config.todowrite.overlay;
52319
52336
  registerMagicContextTools(pi, {
52320
52337
  rerankConnectionFile: config.subc?.connection_file,
52338
+ rerankConfig: config.rerank,
52321
52339
  expandTools: config.historian?.expand_tools,
52322
52340
  db,
52323
52341
  ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,