@cortexkit/pi-magic-context 0.49.20 → 0.49.22

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-jt0g3hn0.js → index-2bx7ge3x.js} +60 -18
  11. package/dist/{index-hws5f0z9.js → index-2qtx0q6h.js} +213 -4
  12. package/dist/{index-5vgt1zeh.js → index-3c3ztwgc.js} +2 -2
  13. package/dist/{index-rgfb753z.js → index-579m1751.js} +2 -2
  14. package/dist/{index-kqb3d8bs.js → index-5j6vwg4z.js} +148 -11
  15. package/dist/{index-6kb2xpw7.js → index-6wdwv3a6.js} +1 -1
  16. package/dist/{index-rfyvax95.js → index-at6py2k3.js} +1 -1
  17. package/dist/{index-bxmf4dhr.js → index-ccanzg8p.js} +2367 -1243
  18. package/dist/{index-mtvvhcw4.js → index-dbgg6hsf.js} +24 -10
  19. package/dist/{index-af9t637y.js → index-ftvm2acc.js} +121 -38
  20. package/dist/{index-zhwwp8zz.js → index-gqjxy2p7.js} +14 -4
  21. package/dist/{index-jxjr7kz9.js → index-gwxaz0z5.js} +2 -4
  22. package/dist/{index-p63nwn5v.js → index-hxp6q5f8.js} +1 -1
  23. package/dist/{index-qerzchrs.js → index-j3pz3a1b.js} +1 -1
  24. package/dist/{index-bttctq07.js → index-n8e5e9fp.js} +6 -3
  25. package/dist/{index-b8am7tns.js → index-pe5gz5c4.js} +4 -4
  26. package/dist/{index-tb3d9trm.js → index-st4gwt64.js} +1 -1
  27. package/dist/{index-5n5zxs8e.js → index-vx6f7wff.js} +2 -2
  28. package/dist/{index-v2epyzbm.js → index-w1twp2kp.js} +9 -7
  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 +239 -209
  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
@@ -235,6 +235,8 @@ import {
235
235
  loadPiConfigDetailed,
236
236
  unregisterPiProjectEmbeddings,
237
237
  ensureProjectRegisteredFromPiDirectory,
238
+ neutralizeOmpMentions,
239
+ restoreOmpMentions,
238
240
  resolvePiHarnessDetection,
239
241
  resolvePiHarnessKind,
240
242
  resolvePiOrdinalAlignment,
@@ -249,7 +251,7 @@ import {
249
251
  registerTodoStateLifecycle,
250
252
  syncCtxMemoryToolEnabled,
251
253
  registerMagicContextTools
252
- } from "./index-jt0g3hn0.js";
254
+ } from "./index-2bx7ge3x.js";
253
255
  import"./index-4knyh1kt.js";
254
256
  import {
255
257
  canonicalModelIdentity,
@@ -267,7 +269,7 @@ import {
267
269
  DEFAULT_HISTORIAN_TIMEOUT_MS,
268
270
  DREAM_TASK_PROMOTION_DEFAULTS,
269
271
  LIVE_RELOAD_CONFIG_PATHS
270
- } from "./index-bxmf4dhr.js";
272
+ } from "./index-ccanzg8p.js";
271
273
  import {
272
274
  FAIL_CLOSED_DOCTOR_COMMAND,
273
275
  formatFailClosedBlockingMessage,
@@ -290,7 +292,7 @@ import {
290
292
  openCurrentDatabase,
291
293
  openDatabaseAsync,
292
294
  closeDatabase
293
- } from "./index-mtvvhcw4.js";
295
+ } from "./index-dbgg6hsf.js";
294
296
  import {
295
297
  pruneMissingProjectIdentities,
296
298
  setHomeProjectPermission,
@@ -302,7 +304,7 @@ import {
302
304
  resolveProjectIdentityForSession,
303
305
  beginBootQuietPeriod,
304
306
  scheduleAfterBootQuiet
305
- } from "./index-p63nwn5v.js";
307
+ } from "./index-hxp6q5f8.js";
306
308
  import {
307
309
  detectThinkingBindingMismatch,
308
310
  detectLatestTurnThinkingMismatch,
@@ -463,7 +465,7 @@ import {
463
465
  getRawSessionTagKeysThrough2,
464
466
  getLegacyProtectedTailStartOrdinal2,
465
467
  readSessionChunk2
466
- } from "./index-zhwwp8zz.js";
468
+ } from "./index-gqjxy2p7.js";
467
469
  import {
468
470
  UNKNOWN_FIT_RATIO,
469
471
  hasMeasuredDecisionCalibration,
@@ -550,7 +552,7 @@ import {
550
552
  getToolTagNumberByOwner2,
551
553
  getNullOwnerToolTag2,
552
554
  adoptNullOwnerToolTag2
553
- } from "./index-bttctq07.js";
555
+ } from "./index-n8e5e9fp.js";
554
556
  import {
555
557
  textMentionsRecentCommit,
556
558
  hasMeaningfulUserText2,
@@ -567,6 +569,7 @@ import {
567
569
  inRootAsyncContext2,
568
570
  Database2,
569
571
  getSqliteDatabasePath2,
572
+ withSqliteTurnDeadline2,
570
573
  withSqliteBackgroundWriter2,
571
574
  withSqliteTransformPass2,
572
575
  withoutSqliteTransformPass2,
@@ -575,7 +578,7 @@ import {
575
578
  isTransientSqliteError2,
576
579
  withAsyncPrivilegedWriter2,
577
580
  indexCoordinationInput2
578
- } from "./index-hws5f0z9.js";
581
+ } from "./index-2qtx0q6h.js";
579
582
  import {
580
583
  stableStringify,
581
584
  closeQuietly,
@@ -613,7 +616,7 @@ import {
613
616
  indexSingleMessage2,
614
617
  indexMessagesAfterOrdinal2,
615
618
  sweepOrphanedOpenCodeMessageIndexesCooperatively2
616
- } from "./index-vdy273xw.js";
619
+ } from "./index-wgmhk91m.js";
617
620
  import {
618
621
  resolveOpenCodeDbPath,
619
622
  assertOpenCodeStoreGeneration,
@@ -629,11 +632,11 @@ import {
629
632
  import {
630
633
  runSessionWarmupWorker,
631
634
  RAW_SUMMARY_TEXT_MAX_CHARS2
632
- } from "./index-rfyvax95.js";
635
+ } from "./index-at6py2k3.js";
633
636
  import {
634
637
  formatSynapseLaneDescriptor
635
- } from "./index-jxjr7kz9.js";
636
- import"./index-rgfb753z.js";
638
+ } from "./index-gwxaz0z5.js";
639
+ import"./index-579m1751.js";
637
640
  import {
638
641
  buildCanonicalChunkTextFromFts2,
639
642
  buildCompartmentSummaryFallbackText2,
@@ -643,7 +646,7 @@ import {
643
646
  replaceCompartmentChunkEmbeddings2,
644
647
  deleteChunkEmbedBackoffForSession2,
645
648
  chunkWindowSourceKey2
646
- } from "./index-5n5zxs8e.js";
649
+ } from "./index-vx6f7wff.js";
647
650
  import {
648
651
  recordSessionProjectIdentity,
649
652
  GIT_SWEEP_LEASE_RENEWAL_MS,
@@ -652,7 +655,7 @@ import {
652
655
  markGitSweepSuccessAndRelease,
653
656
  parkGitSweepNonIndexable,
654
657
  releaseGitSweepLease
655
- } from "./index-qerzchrs.js";
658
+ } from "./index-j3pz3a1b.js";
656
659
  import {
657
660
  embedPauseBySession,
658
661
  embedRunStateBySession,
@@ -678,7 +681,7 @@ import {
678
681
  embedSessionCompartmentChunks2,
679
682
  getEmbeddingCoverageStatus2,
680
683
  getAutoEmbeddingSessionCoverage2
681
- } from "./index-v2epyzbm.js";
684
+ } from "./index-w1twp2kp.js";
682
685
  import {
683
686
  rememberV1HiddenRun
684
687
  } from "./index-6x556c2q.js";
@@ -693,7 +696,7 @@ import {
693
696
  expandWorkspaceIdentitySetWithAliases,
694
697
  sourceNameForMemory,
695
698
  computeWorkspaceEpochFingerprint
696
- } from "./index-5vgt1zeh.js";
699
+ } from "./index-3c3ztwgc.js";
697
700
  import {
698
701
  configureContextDatabasePragmas2
699
702
  } from "./index-fapenpch.js";
@@ -743,7 +746,7 @@ import {
743
746
  normalizeVerificationFiles,
744
747
  indexCommitsForProject,
745
748
  embedUnembeddedCommits
746
- } from "./index-af9t637y.js";
749
+ } from "./index-ftvm2acc.js";
747
750
  import {
748
751
  setEmbeddingSessionBusy2,
749
752
  isEmbeddingHostBusy2
@@ -767,7 +770,7 @@ import {
767
770
  setMemoryClassification2,
768
771
  archiveMemory2,
769
772
  getMemoryCountsByStatus2
770
- } from "./index-dzem6gn9.js";
773
+ } from "./index-29nw7n1r.js";
771
774
  import {
772
775
  invalidateMemory2
773
776
  } from "./index-yhzhdp3m.js";
@@ -776,11 +779,11 @@ import {
776
779
  } from "./index-q1yc6bs0.js";
777
780
  import {
778
781
  getCachedLocalEmbeddingPooling
779
- } from "./index-e19qtjj0.js";
782
+ } from "./index-wqpjhx1p.js";
780
783
  import {
781
784
  cosineSimilarity
782
- } from "./index-b8am7tns.js";
783
- import"./index-6kb2xpw7.js";
785
+ } from "./index-pe5gz5c4.js";
786
+ import"./index-6wdwv3a6.js";
784
787
  import {
785
788
  DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS,
786
789
  buildHiddenAgentRegistrations,
@@ -793,6 +796,10 @@ import {
793
796
  SUBAGENT_OUTPUT_CEILING_ENV2
794
797
  } from "./index-fa485mqs.js";
795
798
  import {
799
+ PI_CONTEXT_BUDGET,
800
+ PiContextDeadlineError,
801
+ PiContextSupersededError,
802
+ PiContextBudget,
796
803
  PiTagHydrationError,
797
804
  getPiTagSnapshotView,
798
805
  getPiActiveTagSnapshotView,
@@ -802,10 +809,10 @@ import {
802
809
  drainPiTagSnapshotSession,
803
810
  assertPiTagSnapshotReady,
804
811
  ensurePiTagSnapshotReady
805
- } from "./index-kqb3d8bs.js";
812
+ } from "./index-5j6vwg4z.js";
806
813
  import"./index-jn44h81p.js";
807
814
  import"./index-1cvyaw9a.js";
808
- import"./index-tb3d9trm.js";
815
+ import"./index-st4gwt64.js";
809
816
  import {
810
817
  __toESM
811
818
  } from "./index-22jkk6wg.js";
@@ -3547,7 +3554,7 @@ function startHostStallProfilerSwitch() {
3547
3554
  // package.json
3548
3555
  var package_default = {
3549
3556
  name: "@cortexkit/pi-magic-context",
3550
- version: "0.49.20",
3557
+ version: "0.49.22",
3551
3558
  type: "module",
3552
3559
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3553
3560
  main: "dist/index.js",
@@ -3596,7 +3603,7 @@ var package_default = {
3596
3603
  "comment-json": "^5.0.0",
3597
3604
  "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c",
3598
3605
  "quickjs-emscripten": "^0.32.0",
3599
- zod: "^4.1.8"
3606
+ zod: "^4.6.6"
3600
3607
  },
3601
3608
  optionalDependencies: {
3602
3609
  "onnxruntime-node": "1.30.0",
@@ -3612,9 +3619,12 @@ var package_default = {
3612
3619
  "@types/bun": "^1.3.10",
3613
3620
  "@types/node": "^22.20.0",
3614
3621
  "omp-coding-agent-1812": "npm:@oh-my-pi/pi-coding-agent@18.12.3",
3622
+ "omp-coding-agent-18126": "npm:@oh-my-pi/pi-coding-agent@18.12.6",
3623
+ "omp-pi-ai-171": "npm:@oh-my-pi/pi-ai@17.1.7",
3615
3624
  "omp-pi-ai-1889": "npm:@oh-my-pi/pi-ai@18.8.9",
3616
3625
  "omp-pi-ai-1811": "npm:@oh-my-pi/pi-ai@18.11.3",
3617
3626
  "omp-pi-ai-1812": "npm:@oh-my-pi/pi-ai@18.12.3",
3627
+ "omp-pi-ai-18126": "npm:@oh-my-pi/pi-ai@18.12.6",
3618
3628
  "pi-agent-core-087": "npm:@earendil-works/pi-agent-core@0.87.1",
3619
3629
  "pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
3620
3630
  "pi-ai-087": "npm:@earendil-works/pi-ai@0.87.1",
@@ -5328,7 +5338,7 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
5328
5338
  throwWithPromptFailure(failure.error, failedAttempts, args, timeoutMs, options.transport);
5329
5339
  }
5330
5340
  if (!cooledPrimary && !quota)
5331
- log2(`[${callContext}] primary (${explicitPrimaryLabel}) failed validation/prompt: ${shortErr(failure.error)}; trying ${fallbacks.length} fallback(s)`);
5341
+ log2(`[${callContext}] primary (${explicitPrimaryLabel}) failed validation/prompt: ${shortErr(failure.error)}; ${fallbacks.length} fallback(s) configured, subject to remaining budget`);
5332
5342
  }
5333
5343
  for (let i = 0;i < fallbacks.length; i += 1) {
5334
5344
  const fallback = toModelEntry(fallbacks[i]);
@@ -12285,28 +12295,35 @@ function diff(name, before, after) {
12285
12295
  rmSync(dir, { recursive: true, force: true });
12286
12296
  }
12287
12297
  }
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");
12298
+ function parseDocsProposalOutput(output) {
12291
12299
  const match = output.match(/```json\s*([\s\S]*?)```/);
12292
12300
  const parsed = JSON.parse(match?.[1] ?? output);
12293
12301
  if (!Array.isArray(parsed))
12294
12302
  throw new Error("proposal must be a JSON array");
12295
12303
  const changes = parsed;
12296
- if (!changes.length)
12297
- throw new Error("empty proposal");
12298
12304
  if (changes.some((item) => !item || !FILES.includes(item.file)))
12299
12305
  throw new Error("unknown proposal file");
12306
+ const seen = new Set;
12307
+ for (const change of changes) {
12308
+ const key = `${change.file}:${change.heading}`;
12309
+ 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))
12310
+ throw new Error(`invalid section change in ${change.file}`);
12311
+ seen.add(key);
12312
+ }
12313
+ return changes;
12314
+ }
12315
+ function validateDocsProposal(projectDir, output, budget, expected) {
12316
+ if (Object.entries(expected).some(([name, value]) => docsBaseHashes(projectDir)[name] !== value))
12317
+ throw new Error("base drifted");
12318
+ const changes = parseDocsProposalOutput(output);
12319
+ if (!changes.length)
12320
+ throw new Error("empty proposal");
12300
12321
  let tokens = 0;
12301
12322
  let diffs = "";
12302
12323
  for (const file of FILES) {
12303
12324
  const before = existsSync6(join8(projectDir, file)) ? readFileSync6(join8(projectDir, file), "utf8") : "";
12304
12325
  let after = before;
12305
- const seen = new Set;
12306
12326
  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
12327
  const section = sections(after).find((item) => item.heading === change.heading);
12311
12328
  if (change.action === "add") {
12312
12329
  if (section || !change.text.startsWith(`${change.heading}
@@ -18726,6 +18743,8 @@ async function runAgenticTask(config, ctx, helpers) {
18726
18743
  timeoutMs: Math.min(Math.max(0, deadline - Date.now()), config.timeoutMinutes * 60 * 1000),
18727
18744
  signal: abortController.signal,
18728
18745
  parse: (text, completion) => {
18746
+ if (task === "maintain-docs")
18747
+ parseDocsProposalOutput(text);
18729
18748
  if (task !== "curate")
18730
18749
  return text;
18731
18750
  const memoryOperations = inspectCurateMemoryOperations(completion.messages);
@@ -18789,6 +18808,8 @@ async function runAgenticTask(config, ctx, helpers) {
18789
18808
  if (task !== "curate") {
18790
18809
  if (!text)
18791
18810
  throw new Error("Dreamer returned no assistant output.");
18811
+ if (task === "maintain-docs")
18812
+ parseDocsProposalOutput(text);
18792
18813
  return text;
18793
18814
  }
18794
18815
  const memoryOperations = inspectCurateMemoryOperations(messages);
@@ -18838,7 +18859,7 @@ async function runAgenticTask(config, ctx, helpers) {
18838
18859
  recordInvocation("completed", run.output);
18839
18860
  if (task === "maintain-docs" && docsHashes && changes) {
18840
18861
  try {
18841
- if (run.validated === "[]") {
18862
+ if (parseDocsProposalOutput(String(run.validated)).length === 0) {
18842
18863
  helpers.recordRun("completed", null, { progress: "no corrections proposed" });
18843
18864
  return {
18844
18865
  status: "completed",
@@ -19479,6 +19500,8 @@ var RECONCILIATION_BATCH_SIZE = 100;
19479
19500
 
19480
19501
  class MagicContextMessageIndexHeapHolder {
19481
19502
  reconciledSessions = new Set;
19503
+ reconciledSnapshots = new Map;
19504
+ stalledSessions = new Set;
19482
19505
  reconciliationScheduledSessions = new Set;
19483
19506
  clearAndReindexScheduledSessions = new Map;
19484
19507
  sessionLocks = new Map;
@@ -19529,18 +19552,28 @@ function logIndexingError(sessionId, action, error) {
19529
19552
  sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
19530
19553
  log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
19531
19554
  }
19555
+ function logReconciliationStall(sessionId, reason) {
19556
+ if (heapHolder.stalledSessions.has(sessionId))
19557
+ return;
19558
+ heapHolder.stalledSessions.add(sessionId);
19559
+ sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
19560
+ }
19532
19561
  async function reconcileSessionIndex(db, sessionId, readMessages) {
19533
- if (!await sourceReady(readMessages, sessionId))
19562
+ if (!await sourceReady(readMessages, sessionId)) {
19563
+ logReconciliationStall(sessionId, "raw message reader is not ready");
19534
19564
  return false;
19565
+ }
19535
19566
  await runWithSessionLock(sessionId, async () => {
19536
- if (heapHolder.reconciledSessions.has(sessionId))
19567
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
19537
19568
  return;
19538
19569
  let fallbackSnapshot = null;
19539
19570
  try {
19540
19571
  const fullReader = typeof readMessages === "function" ? readMessages : null;
19541
- const finalWatermark = readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
19572
+ const revision = readMessages.getRevision?.(sessionId);
19573
+ const previous = heapHolder.reconciledSnapshots.get(sessionId);
19574
+ 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
19575
  let cursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
19543
- let after;
19576
+ let after = cursor === previous?.count ? previous.after : undefined;
19544
19577
  while (cursor < finalWatermark) {
19545
19578
  const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
19546
19579
  const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
@@ -19559,6 +19592,20 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
19559
19592
  }
19560
19593
  if (isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
19561
19594
  heapHolder.reconciledSessions.add(sessionId);
19595
+ if (revision !== undefined) {
19596
+ if (!after && finalWatermark > 0 && readMessages.readPage) {
19597
+ const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
19598
+ if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
19599
+ after = { timeCreated: last.createdAt, id: last.id };
19600
+ }
19601
+ heapHolder.reconciledSnapshots.set(sessionId, {
19602
+ revision,
19603
+ count: finalWatermark,
19604
+ after
19605
+ });
19606
+ }
19607
+ } else {
19608
+ logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
19562
19609
  }
19563
19610
  } finally {
19564
19611
  heapHolder.activeReconcilerBuffers.delete(sessionId);
@@ -19567,25 +19614,32 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
19567
19614
  return true;
19568
19615
  }
19569
19616
  function scheduleReconciliation(db, sessionId, readMessages) {
19570
- if (heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
19617
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
19571
19618
  return;
19572
19619
  }
19573
19620
  heapHolder.reconciliationScheduledSessions.add(sessionId);
19574
19621
  scheduleAfterBootQuiet(() => {
19575
19622
  defer(() => {
19623
+ let appendedDuringReconciliation = false;
19624
+ const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
19576
19625
  reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
19577
- if (ran)
19626
+ if (ran) {
19627
+ const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
19628
+ appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
19578
19629
  return;
19630
+ }
19579
19631
  inRootAsyncContext2(() => setTimeout(() => {
19580
19632
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
19581
19633
  scheduleReconciliation(db, sessionId, readMessages);
19582
19634
  }, PREPARE_RETRY_MS)).unref?.();
19583
19635
  }).catch((error) => {
19584
- logIndexingError(sessionId, "reconciliation", error);
19636
+ logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
19585
19637
  if (isDatabaseLockedError(error))
19586
19638
  inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
19587
19639
  }).finally(() => {
19588
19640
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
19641
+ if (appendedDuringReconciliation)
19642
+ scheduleReconciliation(db, sessionId, readMessages);
19589
19643
  });
19590
19644
  });
19591
19645
  });
@@ -19718,6 +19772,8 @@ function clearSessionTracking(sessionId) {
19718
19772
  Atomics.store(cancellation, 0, 1);
19719
19773
  heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
19720
19774
  heapHolder.reconciledSessions.delete(sessionId);
19775
+ heapHolder.reconciledSnapshots.delete(sessionId);
19776
+ heapHolder.stalledSessions.delete(sessionId);
19721
19777
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
19722
19778
  heapHolder.sessionLocks.delete(sessionId);
19723
19779
  heapHolder.activeReconcilerBuffers.delete(sessionId);
@@ -20936,6 +20992,12 @@ class PiSubagentRunner {
20936
20992
  }
20937
20993
  }
20938
20994
  async runOnce(options, runMode, modelRefOverride) {
20995
+ if (this.invocation.targetHarness === "omp") {
20996
+ options = {
20997
+ ...options,
20998
+ userMessage: neutralizeOmpMentions(options.userMessage)
20999
+ };
21000
+ }
20939
21001
  const startTime = Date.now();
20940
21002
  const zenChild = STRICT_TOOL_ALLOWLIST.has(options.agent) && isZenModel(options.model);
20941
21003
  let deferredZenStderr = "";
@@ -21291,7 +21353,7 @@ class PiSubagentRunner {
21291
21353
  rl.on("line", (line) => {
21292
21354
  if (settled || line.length === 0)
21293
21355
  return;
21294
- const parsed = parsePiEventLine(line);
21356
+ const parsed = parsePiEventLine(line, this.invocation.targetHarness);
21295
21357
  if (!parsed.ok) {
21296
21358
  if ("noise" in parsed)
21297
21359
  return;
@@ -21892,12 +21954,16 @@ function countToolCalls(messages) {
21892
21954
  }
21893
21955
  return count;
21894
21956
  }
21895
- function parsePiEventLine(line) {
21957
+ function parsePiEventLine(line, targetHarness = "pi") {
21896
21958
  if (!line.trimStart().startsWith("{")) {
21897
21959
  return { ok: false, noise: true };
21898
21960
  }
21899
21961
  try {
21900
- return { ok: true, event: JSON.parse(line) };
21962
+ const event = JSON.parse(line);
21963
+ return {
21964
+ ok: true,
21965
+ event: targetHarness === "omp" ? restoreOmpMentions(event) : event
21966
+ };
21901
21967
  } catch (error) {
21902
21968
  return {
21903
21969
  ok: false,
@@ -25107,7 +25173,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
25107
25173
 
25108
25174
  // ../plugin/src/hooks/magic-context/cache-busting-signals.ts
25109
25175
  function hasReclaimRide(signals) {
25110
- return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true || signals.executeReclaim === true;
25176
+ return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true || signals.executeReclaim === true || signals.servedShapeRepair === true;
25111
25177
  }
25112
25178
  function prefixMutationPermitted(gate) {
25113
25179
  return !gate.signedThinkingHold || gate.firstRender || gate.idleExpiry || gate.emergency;
@@ -25121,7 +25187,8 @@ var RECLAIM_RIDE_NAMES = [
25121
25187
  "explicitFlush",
25122
25188
  "publishedHistory",
25123
25189
  "subagentExecute",
25124
- "executeReclaim"
25190
+ "executeReclaim",
25191
+ "servedShapeRepair"
25125
25192
  ];
25126
25193
  function reclaimRideLabel(signals) {
25127
25194
  const active = RECLAIM_RIDE_NAMES.filter((name) => signals[name]);
@@ -27690,6 +27757,7 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
27690
27757
  db,
27691
27758
  targets,
27692
27759
  skipPrefixInjection,
27760
+ preserveTagOnlyAssistantText: options.preserveTagOnlyAssistantText,
27693
27761
  entryFingerprint: options.entryFingerprintByMessageId?.get(messageId) ?? null,
27694
27762
  reuseIdentity: reuseIdentity || contentDerivedTextIds !== undefined,
27695
27763
  timing,
@@ -28081,7 +28149,7 @@ function isRecord2(value) {
28081
28149
  function tagTextPart(args) {
28082
28150
  const identityStart = args.timing ? performance.now() : 0;
28083
28151
  const text = args.part.getText() ?? "";
28084
- if (args.message.info.role === "assistant" && stripWellFormedLeadingTagPrefix(text).trim().length === 0) {
28152
+ if (args.message.info.role === "assistant" && (stripWellFormedLeadingTagPrefix(text).trim().length === 0 || args.preserveTagOnlyAssistantText && text.includes("§") && stripPersistedAssistantText(text).length === 0)) {
28085
28153
  if (args.timing)
28086
28154
  args.timing.identity += performance.now() - identityStart;
28087
28155
  return;
@@ -28673,7 +28741,15 @@ class AutoSearchBusyError extends Error {
28673
28741
  }
28674
28742
  }
28675
28743
  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");
28744
+ const {
28745
+ rerankConfig: _rerankConfig,
28746
+ rerankClient: _rerankClient,
28747
+ rerankConnectionFile: _rerankConnectionFile,
28748
+ onRerankSkipped: _onRerankSkipped,
28749
+ captureRerankLanes: _captureRerankLanes,
28750
+ ...hintOptions
28751
+ } = options;
28752
+ return executeAutoSearchWorker(db, sessionId, projectPath, query, { ...hintOptions, explicitSearch: false, rerank: false }, entry, "search");
28677
28753
  }
28678
28754
  var pendingBackfills = new WeakMap;
28679
28755
  var searchWorkers = new WeakMap;
@@ -35216,123 +35292,6 @@ function adaptPiAppendCompaction(sessionManager) {
35216
35292
  };
35217
35293
  }
35218
35294
 
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
35295
  // src/pi-context-limit.ts
35337
35296
  var MIN_SANE_LIMIT = 16000;
35338
35297
  var MAX_SANE_LIMIT = 1e7;
@@ -36025,6 +35984,11 @@ function piHasManagedSignature(payload, signature) {
36025
35984
  return false;
36026
35985
  }
36027
35986
 
35987
+ // src/pi-dispatch-assistant-history.ts
35988
+ function piOmitsTruncatedAssistant(message) {
35989
+ return (message.stopReason === "length" || message.stopReason === "error" || message.stopReason === "aborted") && Array.isArray(message.content) && !message.content.some((block) => block?.type === "text" || block?.type === "toolCall");
35990
+ }
35991
+
36028
35992
  // src/pi-dispatch-tool-pairing.ts
36029
35993
  var RESPONSES_APIS = new Set([
36030
35994
  "openai-responses",
@@ -36074,14 +36038,14 @@ function object5(value) {
36074
36038
  function omitsAssistant(message, model, compat) {
36075
36039
  if (!Array.isArray(message.content))
36076
36040
  return false;
36041
+ if (piOmitsTruncatedAssistant(message))
36042
+ return true;
36077
36043
  let thinking = false;
36078
- let hasTextBlock = false;
36079
36044
  for (const value of message.content) {
36080
36045
  const block = object5(value);
36081
36046
  if (!block)
36082
36047
  return false;
36083
36048
  if (block.type === "text") {
36084
- hasTextBlock = true;
36085
36049
  if (typeof block.text !== "string" || block.text.trim())
36086
36050
  return false;
36087
36051
  } else if (block.type === "thinking") {
@@ -36091,8 +36055,6 @@ function omitsAssistant(message, model, compat) {
36091
36055
  } else
36092
36056
  return false;
36093
36057
  }
36094
- if (!hasTextBlock && ["length", "error", "aborted"].includes(String(message.stopReason)))
36095
- return true;
36096
36058
  if (compat.requiresReasoningContentForAllAssistantTurns === true)
36097
36059
  return false;
36098
36060
  if (!thinking)
@@ -36397,11 +36359,25 @@ ${wellFormed(text)}
36397
36359
  </think>`;
36398
36360
  return;
36399
36361
  }
36400
- function piResponsesAssistantTexts(value, model) {
36362
+ function coldReplayable(items) {
36363
+ let reasoning = false;
36364
+ for (const value of items) {
36365
+ const item = object7(value);
36366
+ if (typeof item?.encrypted_content === "string")
36367
+ return false;
36368
+ if (item?.type !== "reasoning")
36369
+ continue;
36370
+ if (!Array.isArray(item.content) || !item.content.some((part) => object7(part)?.type === "reasoning_text"))
36371
+ return false;
36372
+ reasoning = true;
36373
+ }
36374
+ return reasoning;
36375
+ }
36376
+ function piResponsesAssistantTexts(value, model, host, alternatives) {
36401
36377
  const message = object7(value);
36402
36378
  if (!message || !Array.isArray(message.content))
36403
36379
  return;
36404
- if (["length", "error", "aborted"].includes(String(message.stopReason)) && !message.content.some((value) => ["text", "toolCall"].includes(String(object7(value)?.type))))
36380
+ if (piOmitsTruncatedAssistant(message))
36405
36381
  return [];
36406
36382
  const texts = [];
36407
36383
  const blocks = [];
@@ -36444,6 +36420,13 @@ function piResponsesAssistantTexts(value, model) {
36444
36420
  const replay = [];
36445
36421
  let bound = 0;
36446
36422
  let output = false;
36423
+ const allowUnsigned = host === "omp" && message.role === "assistant" && [
36424
+ "openai-responses",
36425
+ "azure-openai-responses",
36426
+ "openai-codex-responses"
36427
+ ].includes(model?.api ?? "");
36428
+ let unsigned = false;
36429
+ let rewrittenText = false;
36447
36430
  for (const value of payload.items) {
36448
36431
  const item = object7(value);
36449
36432
  if (item?.type === "reasoning")
@@ -36467,8 +36450,14 @@ function piResponsesAssistantTexts(value, model) {
36467
36450
  } catch {
36468
36451
  return texts;
36469
36452
  }
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;
36453
+ const signed = signature?.v === 1 && typeof signature.id === "string" && item.id === signature.id && item.phase === signature.phase && part.text === block.text.replace(/^§\d+§ /u, "");
36454
+ if (!signed) {
36455
+ const stripped = stripPersistedAssistantText(part.text);
36456
+ if (!allowUnsigned || "textSignature" in block || stripped !== block.text.replace(/^§\d+§ /u, ""))
36457
+ return texts;
36458
+ unsigned = true;
36459
+ rewrittenText ||= part.text !== stripped && part.text !== block.text;
36460
+ }
36472
36461
  bound++;
36473
36462
  itemTexts.push(part.text);
36474
36463
  }
@@ -36478,7 +36467,13 @@ function piResponsesAssistantTexts(value, model) {
36478
36467
  for (const text of itemTexts)
36479
36468
  replay.push(textIdentity2(wellFormed(text), item.phase));
36480
36469
  }
36481
- return output && bound === blocks.length ? replay : texts;
36470
+ if (!output || bound !== blocks.length || unsigned && !rewrittenText)
36471
+ return texts;
36472
+ if (unsigned && alternatives) {
36473
+ alternatives.fallback = texts;
36474
+ alternatives.cold = coldReplayable(payload.items) ? replay : texts;
36475
+ }
36476
+ return replay;
36482
36477
  }
36483
36478
  function piResponsesWireTexts(value, phase) {
36484
36479
  if (phase !== undefined && phase !== null && phase !== "commentary" && phase !== "final_answer")
@@ -36720,11 +36715,10 @@ function projectMissingToolResults(messages, model, host = "omp") {
36720
36715
  const message = object8(value);
36721
36716
  if (message?.role === "assistant") {
36722
36717
  flush(message.timestamp);
36718
+ if (piOmitsTruncatedAssistant(message))
36719
+ continue;
36723
36720
  projected.push(value);
36724
36721
  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
36722
  if (message.stopReason === "aborted" || message.stopReason === "error") {
36729
36723
  aborted = new Map(calls.map((call) => [pairingId(call.id), call]));
36730
36724
  abortedTimestamp = message.timestamp;
@@ -37018,31 +37012,43 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37018
37012
  }
37019
37013
  const responsesApi = responsesLane(model?.api);
37020
37014
  let responsesMessages = responsesApi ? [] : undefined;
37015
+ const fallbackMessages = [];
37016
+ const coldMessages = [];
37017
+ let unsignedAlternatives = false;
37018
+ const appendResponse = (output, row, texts) => {
37019
+ if (!texts.length && !row.calls.length)
37020
+ return;
37021
+ const previous = output.at(-1);
37022
+ if (previous?.role === "assistant") {
37023
+ previous.calls.push(...row.calls);
37024
+ previous.wireCalls?.push(...row.wireCalls ?? []);
37025
+ previous.responseTexts?.push(...texts);
37026
+ } else
37027
+ output.push({
37028
+ ...row,
37029
+ calls: [...row.calls],
37030
+ ...row.wireCalls ? { wireCalls: [...row.wireCalls] } : {},
37031
+ responseTexts: [...texts]
37032
+ });
37033
+ };
37021
37034
  if (responsesMessages) {
37022
37035
  for (const [index, row] of byIndex) {
37023
37036
  if (row.role !== "assistant") {
37024
37037
  responsesMessages.push(row);
37038
+ fallbackMessages.push(row);
37039
+ coldMessages.push(row);
37025
37040
  continue;
37026
37041
  }
37027
- const texts = piResponsesAssistantTexts(projectedMessages[index], model);
37042
+ const alternatives = {};
37043
+ const texts = piResponsesAssistantTexts(projectedMessages[index], model, host, alternatives);
37028
37044
  if (!texts) {
37029
37045
  responsesMessages = undefined;
37030
37046
  break;
37031
37047
  }
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
- });
37048
+ unsignedAlternatives ||= alternatives.fallback !== undefined;
37049
+ appendResponse(responsesMessages, row, texts);
37050
+ appendResponse(fallbackMessages, row, alternatives.fallback ?? texts);
37051
+ appendResponse(coldMessages, row, alternatives.cold ?? texts);
37046
37052
  }
37047
37053
  }
37048
37054
  const plan = piChatHistoryPlan(projectedMessages, model);
@@ -37077,6 +37083,7 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37077
37083
  ...responsesApi && !responsesMessages ? { structuralSkipReason: "Responses history transform is not modeled" } : model?.api === "openai-completions" && !chatMessages ? { structuralSkipReason: "Chat history transform is not modeled" } : {},
37078
37084
  ...chatMessages ? { chatMessages } : {},
37079
37085
  ...responsesMessages ? { responsesMessages } : {},
37086
+ ...responsesMessages && unsignedAlternatives ? { responsesAlternatives: [fallbackMessages, coldMessages] } : {},
37080
37087
  ...model?.api ? { api: model.api } : {},
37081
37088
  ...model?.api?.startsWith("google-") ? {
37082
37089
  googleFunctionIds: object8(model.compat)?.supportsFunctionPartId === true
@@ -37393,6 +37400,10 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
37393
37400
  const chat = !!body && Array.isArray(body.messages) && (prepared?.api === "openai-completions" || body.system === undefined) && body.input === undefined && body.inferenceConfig === undefined;
37394
37401
  stage = "prepared rows";
37395
37402
  expectedRows = responses && prepared?.responsesMessages ? prepared.responsesMessages : chat && prepared?.chatMessages ? prepared.chatMessages : prepared?.messages;
37403
+ if (responses && rows && prepared?.responsesAlternatives) {
37404
+ const actual = rows;
37405
+ 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;
37406
+ }
37396
37407
  if (expectedRows && imageProjection && imageBudget)
37397
37408
  expectedRows = trimPreparedImageRows(expectedRows, imageBudget, trimmed);
37398
37409
  if (!rows || !expectedRows)
@@ -39169,7 +39180,7 @@ function registerPiGuardedContext(pi, handler, options = {}) {
39169
39180
  inputs = messageSnapshots(event.messages);
39170
39181
  active.inputMessages = inputs;
39171
39182
  }
39172
- const result = await budget.waitMandatory(Promise.resolve(withSqliteTransformPass2(() => handler(event, ctx, budget))));
39183
+ const result = await budget.waitMandatory(Promise.resolve(withSqliteTurnDeadline2(() => Math.max(0, budget.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs), () => withSqliteTransformPass2(() => handler(event, ctx, budget)))));
39173
39184
  if (result?.messages) {
39174
39185
  const prepared = preparePiDispatch(result.messages, fenceEnabled ? ctx.model : undefined, fenceEnabled);
39175
39186
  if (prepared.messages !== result.messages)
@@ -39437,13 +39448,15 @@ function recordPiUpperEstimateReclaim(db, cursor, reservation) {
39437
39448
  pendingInput.delete(cursor.sessionId);
39438
39449
  }
39439
39450
  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");
39451
+ withoutSqliteTransformPass2(() => withSqliteTurnDeadline2(() => 0, () => {
39452
+ if (!updateReplayDocument(db, cursor.sessionId, (doc) => {
39453
+ if (claimFrom(doc[KEY2], cursor.sessionId)?.reservation !== reservation)
39454
+ return false;
39455
+ delete doc[KEY2];
39456
+ return true;
39457
+ }))
39458
+ throw new Error("Could not release upper-estimate reclaim");
39459
+ }));
39447
39460
  }
39448
39461
  function resetPiUpperEstimateReclaim(db, sessionId) {
39449
39462
  if (!claimFrom(readReplayEnvelope(db, sessionId)[KEY2], sessionId))
@@ -39455,6 +39468,21 @@ function resetPiUpperEstimateReclaim(db, sessionId) {
39455
39468
  throw new Error("Could not clear upper-estimate reclaim cursor");
39456
39469
  }
39457
39470
 
39471
+ // src/pi-historian-turn-wait.ts
39472
+ var foregroundWaits = new Map;
39473
+ function inPiHistorianRootContext(sessionId, operation) {
39474
+ return inRootAsyncContext2(() => withSqliteTurnDeadline2(() => foregroundWaits.get(sessionId)?.() ?? Infinity, operation));
39475
+ }
39476
+ async function waitForPiHistorianInTurn(sessionId, remainingMs, wait) {
39477
+ foregroundWaits.set(sessionId, remainingMs);
39478
+ try {
39479
+ return await wait();
39480
+ } finally {
39481
+ if (foregroundWaits.get(sessionId) === remainingMs)
39482
+ foregroundWaits.delete(sessionId);
39483
+ }
39484
+ }
39485
+
39458
39486
  // src/pi-lkg-fit-envelope.ts
39459
39487
  import { createHash as createHash13 } from "node:crypto";
39460
39488
  function readPiLkgFitEnvelope(ctx, pi, modelKey, frozen, wireSchema) {
@@ -45365,7 +45393,7 @@ function registerPiContextHandler(pi, baseOptions) {
45365
45393
  const pending = inFlightHistorian.get(sessionId);
45366
45394
  if (pending) {
45367
45395
  budget.stage = "headless fit historian";
45368
- await budget.wait(pending);
45396
+ await waitForPiHistorianInTurn(sessionId, () => Math.max(0, budget.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs), () => budget.wait(pending));
45369
45397
  }
45370
45398
  }
45371
45399
  budget.stage = "outgoing fit reclaim";
@@ -45410,7 +45438,7 @@ function registerPiContextHandler(pi, baseOptions) {
45410
45438
  estimate = estimatePiOutgoingInputTokens(outputMessages, envelope, undefined, outgoingFitLimit);
45411
45439
  } finally {
45412
45440
  if (!reclaimCompleted && upperCursor && reservation)
45413
- withoutSqliteTransformPass2(() => releasePiUpperEstimateReclaim(options.db, upperCursor, reservation));
45441
+ releasePiUpperEstimateReclaim(options.db, upperCursor, reservation);
45414
45442
  }
45415
45443
  }
45416
45444
  }
@@ -45777,7 +45805,7 @@ function spawnPiHistorianRun(args) {
45777
45805
  const holderId = crypto3.randomUUID();
45778
45806
  const controller = new AbortController;
45779
45807
  historianAbortControllers.set(sessionId, controller);
45780
- const runPromise = inRootAsyncContext2(() => (async () => {
45808
+ const runPromise = inPiHistorianRootContext(sessionId, () => (async () => {
45781
45809
  await new Promise((resolve) => setTimeout(resolve, 0));
45782
45810
  if (controller.signal.aborted)
45783
45811
  return;
@@ -46768,6 +46796,7 @@ async function runPipeline(args) {
46768
46796
  args.assertCurrentPass?.();
46769
46797
  return tagTranscript(args.sessionId, { ...transcript, messages: taggingView }, args.tagger, args.db, {
46770
46798
  skipPrefixInjection: !ctxReduceCallable,
46799
+ preserveTagOnlyAssistantText: true,
46771
46800
  entryFingerprintByMessageId,
46772
46801
  reuseMessageIds: textIdentityPlan.reusableMessageIds,
46773
46802
  textIdentityDriftMessageIds: textIdentityPlan.driftedMessageIds,
@@ -51334,7 +51363,7 @@ function stripTagPrefixFromAssistantMessage(message) {
51334
51363
  const textPart = part;
51335
51364
  if (typeof textPart.text !== "string")
51336
51365
  continue;
51337
- const stripped = stripPersistedAssistantText(textPart.text);
51366
+ const stripped = stripPersistedAssistantText(textPart.text, message.provider === "anthropic");
51338
51367
  if (stripped !== textPart.text) {
51339
51368
  textPart.text = stripped;
51340
51369
  mutated = true;
@@ -51342,7 +51371,7 @@ function stripTagPrefixFromAssistantMessage(message) {
51342
51371
  }
51343
51372
  return mutated;
51344
51373
  }
51345
- function strippedAssistantContent(content) {
51374
+ function strippedAssistantContent(content, provider = "anthropic") {
51346
51375
  if (!Array.isArray(content))
51347
51376
  return;
51348
51377
  let copy;
@@ -51353,7 +51382,7 @@ function strippedAssistantContent(content) {
51353
51382
  }
51354
51383
  if (typeof part.text !== "string")
51355
51384
  continue;
51356
- const stripped = stripPersistedAssistantText(part.text);
51385
+ const stripped = stripPersistedAssistantText(part.text, provider === "anthropic");
51357
51386
  if (stripped === part.text)
51358
51387
  continue;
51359
51388
  copy ??= content.slice();
@@ -51370,7 +51399,7 @@ function registerOmpAssistantMessageStrip(pi, isActive) {
51370
51399
  const message = event?.message;
51371
51400
  if (message?.role !== "assistant")
51372
51401
  return;
51373
- const content = strippedAssistantContent(message.content);
51402
+ const content = strippedAssistantContent(message.content, message.provider ?? "unknown");
51374
51403
  return content === undefined ? undefined : { content };
51375
51404
  } catch {
51376
51405
  return;
@@ -51917,7 +51946,7 @@ async function src_default(pi) {
51917
51946
  let openFailureCause = null;
51918
51947
  const openStorage = async () => {
51919
51948
  try {
51920
- return await openDatabaseAsync();
51949
+ return await openDatabaseAsync({ nativeTurnDeadlines: true });
51921
51950
  } catch (error) {
51922
51951
  openFailureCause = error instanceof Error ? error.message : String(error);
51923
51952
  return null;
@@ -52318,6 +52347,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
52318
52347
  const todowriteOverlayEnabled = todowriteEnabled && bootProjectDeps.config.todowrite.overlay;
52319
52348
  registerMagicContextTools(pi, {
52320
52349
  rerankConnectionFile: config.subc?.connection_file,
52350
+ rerankConfig: config.rerank,
52321
52351
  expandTools: config.historian?.expand_tools,
52322
52352
  db,
52323
52353
  ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,