@cortexkit/pi-magic-context 0.49.7 → 0.49.9

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 (52) hide show
  1. package/dist/auto-search-worker.js +6 -6
  2. package/dist/{compaction-marker-candidates-tqcq5n00.js → compaction-marker-candidates-n4dphyz4.js} +3 -3
  3. package/dist/compaction-marker-candidates-worker.js +2 -2
  4. package/dist/embedding-backfill-chva00z3.js +20 -0
  5. package/dist/embedding-worker-process.js +6 -2
  6. package/dist/embedding-worker.js +6 -5
  7. package/dist/historian-calibration-extension.js +3 -2
  8. package/dist/{index-6q5mx0cz.js → index-243wh86p.js} +38 -28
  9. package/dist/{index-0j0zqb4t.js → index-3veejgp8.js} +1 -1
  10. package/dist/{index-0vrkp1jq.js → index-43zqh10z.js} +1 -1
  11. package/dist/{index-r56xgha8.js → index-4pxydwvg.js} +1 -1
  12. package/dist/{index-7mm27xdc.js → index-4vj37yw9.js} +4 -3
  13. package/dist/{index-8ye22z7k.js → index-6e3yv1jt.js} +4 -4
  14. package/dist/index-6x556c2q.js +19 -0
  15. package/dist/{index-dj8hpkz7.js → index-729kkhmf.js} +4 -3
  16. package/dist/{index-gc2749rx.js → index-8yjhda46.js} +9 -6
  17. package/dist/{index-fhv6ydkq.js → index-9vzkrnrf.js} +32 -12
  18. package/dist/{index-7ptxvfc5.js → index-asrxgdt4.js} +33 -10
  19. package/dist/{index-34zacc0h.js → index-fdxzpnbj.js} +2 -2
  20. package/dist/{index-0eg59y8d.js → index-g13fb2sj.js} +5 -5
  21. package/dist/{index-gqsfhksw.js → index-gqxsds3q.js} +6 -3
  22. package/dist/{index-x3dcnxh0.js → index-gycf3sp7.js} +5 -1
  23. package/dist/{index-0ww9cgfd.js → index-h160xxaq.js} +9 -9
  24. package/dist/{index-dj784nyr.js → index-hy44m6jc.js} +1 -1
  25. package/dist/{index-290tzwp1.js → index-kh3jt7t9.js} +1 -1
  26. package/dist/{index-8jpqq2yk.js → index-ns319t8e.js} +14 -13
  27. package/dist/{index-0d8zqccx.js → index-qc8e13wc.js} +22 -22
  28. package/dist/{index-mrsarsbh.js → index-rkwh9kce.js} +25 -24
  29. package/dist/{index-21v1kfs7.js → index-szh001qb.js} +6 -3
  30. package/dist/{index-cyrnv16r.js → index-ta0ed2nc.js} +2 -0
  31. package/dist/{index-mcgehvgw.js → index-ttxsmaj5.js} +31 -16
  32. package/dist/{index-a7fj661j.js → index-v26j81w6.js} +5 -5
  33. package/dist/{index-6vjj0555.js → index-x7426vy4.js} +242 -16
  34. package/dist/index.js +502 -149
  35. package/dist/{logger-j6tecd1h.js → logger-qg51hmp7.js} +1 -1
  36. package/dist/{message-index-bounded-e5bv8gzm.js → message-index-bounded-y1c88n9a.js} +15 -14
  37. package/dist/{message-index-8rxj3cxh.js → message-index-ejaa9may.js} +15 -14
  38. package/dist/{message-time-backfill-hmekd2jj.js → message-time-backfill-q9s88zdv.js} +3 -3
  39. package/dist/migration-worker.js +10 -10
  40. package/dist/{project-embedding-registry-z5m4eh3d.js → project-embedding-registry-bxawck58.js} +11 -11
  41. package/dist/raw-ordinal-warmup-worker.js +6 -6
  42. package/dist/{read-session-chunk-sp5adk01.js → read-session-chunk-4094zemt.js} +10 -9
  43. package/dist/{read-session-raw-s14c7nf3.js → read-session-raw-hm7ptnrh.js} +3 -3
  44. package/dist/{safe-notification-target-vn9kpmv4.js → safe-notification-target-62ty6rvp.js} +2 -2
  45. package/dist/{search-hgfaqytc.js → search-hsr95vex.js} +22 -21
  46. package/dist/{sqlite-f8kh2n10.js → sqlite-adjpy399.js} +3 -1
  47. package/dist/{storage-memory-yf7r98vz.js → storage-memory-axnsk5t1.js} +2 -2
  48. package/dist/{storage-tags-0xk95neb.js → storage-tags-zh23ynsh.js} +5 -5
  49. package/dist/subagent-entry.js +25 -24
  50. package/package.json +1 -1
  51. package/dist/embedding-backfill-vygvr2x4.js +0 -20
  52. /package/dist/{index-zh1jw8qp.js → index-xmdkde4v.js} +0 -0
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  log2,
16
16
  sessionLog2,
17
17
  flushLogger2
18
- } from "./index-x3dcnxh0.js";
18
+ } from "./index-gycf3sp7.js";
19
19
  import {
20
20
  COMPACTION_ENABLED_PATH,
21
21
  isDreamerRunnable,
@@ -250,7 +250,7 @@ import {
250
250
  registerTodoStateLifecycle,
251
251
  syncCtxMemoryToolEnabled,
252
252
  registerMagicContextTools
253
- } from "./index-mrsarsbh.js";
253
+ } from "./index-rkwh9kce.js";
254
254
  import {
255
255
  canonicalModelIdentity,
256
256
  piModelRefToCanonical,
@@ -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-cyrnv16r.js";
270
+ } from "./index-ta0ed2nc.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-6q5mx0cz.js";
293
+ } from "./index-243wh86p.js";
294
294
  import {
295
295
  setHomeProjectPermission,
296
296
  ProjectIdentityError,
@@ -301,7 +301,7 @@ import {
301
301
  resolveProjectIdentityForSession,
302
302
  beginBootQuietPeriod,
303
303
  scheduleAfterBootQuiet
304
- } from "./index-gqsfhksw.js";
304
+ } from "./index-gqxsds3q.js";
305
305
  import {
306
306
  detectThinkingBindingMismatch,
307
307
  detectLatestTurnThinkingMismatch,
@@ -438,8 +438,10 @@ import {
438
438
  reasoningBudgetCutoff,
439
439
  reasoningTextAndOpaque,
440
440
  opaqueThinkingCost,
441
+ estimatePartImageTokens,
441
442
  SKELETON_REAL_INPUT_MAX_BYTES,
442
443
  toolInputStringBytes,
444
+ hasRawMessageProvider2,
443
445
  setRawMessageProvider2,
444
446
  withRawMessageProvider2,
445
447
  cleanUserText2,
@@ -458,7 +460,7 @@ import {
458
460
  getRawSessionTagKeysThrough2,
459
461
  getLegacyProtectedTailStartOrdinal2,
460
462
  readSessionChunk2
461
- } from "./index-fhv6ydkq.js";
463
+ } from "./index-9vzkrnrf.js";
462
464
  import {
463
465
  UNKNOWN_FIT_RATIO,
464
466
  hasMeasuredDecisionCalibration,
@@ -475,10 +477,14 @@ import {
475
477
  stripTagPrefix,
476
478
  peelLeadingMcTagNotation,
477
479
  prependTag,
480
+ rememberCurrentToolOutputCount,
481
+ currentReclaimableToolOutputCount,
478
482
  isRecord,
479
483
  TEXT_TAG_IDENTITY_MARKER,
480
484
  PI_FALLBACK_PREFIXES_JSON,
481
485
  contentTagOwnerMessageId,
486
+ TailHygieneJsonMemo,
487
+ piJsonHash,
482
488
  estimateImageTokensFromDataUrl,
483
489
  normalizeTodoStateJson,
484
490
  buildSyntheticTodoPart,
@@ -491,7 +497,6 @@ import {
491
497
  CHANNEL1_FLOOR_TOKENS,
492
498
  decideChannel1,
493
499
  evaluateChannel2,
494
- reclaimableToolOutputCount,
495
500
  buildChannel2Reminder,
496
501
  buildChannel1Reminder,
497
502
  planEmergencyDrop,
@@ -541,7 +546,7 @@ import {
541
546
  getToolTagNumberByOwner2,
542
547
  getNullOwnerToolTag2,
543
548
  adoptNullOwnerToolTag2
544
- } from "./index-6vjj0555.js";
549
+ } from "./index-x7426vy4.js";
545
550
  import {
546
551
  textMentionsRecentCommit,
547
552
  hasMeaningfulUserText2,
@@ -553,8 +558,9 @@ import {
553
558
  estimateTokens,
554
559
  estimateFixedPromptTokens,
555
560
  normalizeText
556
- } from "./index-r56xgha8.js";
561
+ } from "./index-4pxydwvg.js";
557
562
  import {
563
+ inRootAsyncContext2,
558
564
  Database2,
559
565
  getSqliteDatabasePath2,
560
566
  withSqliteBackgroundWriter2,
@@ -565,7 +571,7 @@ import {
565
571
  isTransientSqliteError2,
566
572
  withAsyncPrivilegedWriter2,
567
573
  indexCoordinationInput2
568
- } from "./index-7ptxvfc5.js";
574
+ } from "./index-asrxgdt4.js";
569
575
  import {
570
576
  stableStringify,
571
577
  closeQuietly,
@@ -577,7 +583,7 @@ import {
577
583
  tagRevisionKey,
578
584
  tagIdentityRevisionKey,
579
585
  TAG_INSERT_CONFLICT_ROWS
580
- } from "./index-mcgehvgw.js";
586
+ } from "./index-ttxsmaj5.js";
581
587
  import {
582
588
  resolveOpenCodeDbPath,
583
589
  assertOpenCodeStoreGeneration,
@@ -590,10 +596,10 @@ import"./index-399p688g.js";
590
596
  import {
591
597
  runSessionWarmupWorker,
592
598
  RAW_SUMMARY_TEXT_MAX_CHARS2
593
- } from "./index-7mm27xdc.js";
599
+ } from "./index-4vj37yw9.js";
594
600
  import {
595
601
  piHarnessKindFromExecutable
596
- } from "./index-0j0zqb4t.js";
602
+ } from "./index-3veejgp8.js";
597
603
  import {
598
604
  BoundedSessionMap,
599
605
  LkgRecoveryFenceError,
@@ -616,13 +622,13 @@ import {
616
622
  indexSingleMessage2,
617
623
  indexMessagesAfterOrdinal2,
618
624
  sweepOrphanedOpenCodeMessageIndexes2
619
- } from "./index-0ww9cgfd.js";
625
+ } from "./index-h160xxaq.js";
620
626
  import {
621
627
  formatSynapseLaneDescriptor
622
- } from "./index-21v1kfs7.js";
628
+ } from "./index-szh001qb.js";
623
629
  import {
624
630
  sameProjectDirectory
625
- } from "./index-34zacc0h.js";
631
+ } from "./index-fdxzpnbj.js";
626
632
  import {
627
633
  buildCanonicalChunkTextFromFts,
628
634
  buildCompartmentSummaryFallbackText,
@@ -632,7 +638,7 @@ import {
632
638
  replaceCompartmentChunkEmbeddings,
633
639
  deleteChunkEmbedBackoffForSession,
634
640
  chunkWindowSourceKey
635
- } from "./index-8ye22z7k.js";
641
+ } from "./index-6e3yv1jt.js";
636
642
  import {
637
643
  recordSessionProjectIdentity,
638
644
  GIT_SWEEP_LEASE_RENEWAL_MS,
@@ -657,7 +663,10 @@ import {
657
663
  embedSessionCompartmentChunks2,
658
664
  getEmbeddingCoverageStatus2,
659
665
  getAutoEmbeddingSessionCoverage2
660
- } from "./index-0d8zqccx.js";
666
+ } from "./index-qc8e13wc.js";
667
+ import {
668
+ rememberV1HiddenRun
669
+ } from "./index-6x556c2q.js";
661
670
  import {
662
671
  V2_MEMORY_CATEGORIES
663
672
  } from "./index-135e8hvg.js";
@@ -669,7 +678,7 @@ import {
669
678
  expandWorkspaceIdentitySetWithAliases,
670
679
  sourceNameForMemory,
671
680
  computeWorkspaceEpochFingerprint
672
- } from "./index-0eg59y8d.js";
681
+ } from "./index-g13fb2sj.js";
673
682
  import {
674
683
  configureContextDatabasePragmas2
675
684
  } from "./index-fapenpch.js";
@@ -719,7 +728,7 @@ import {
719
728
  normalizeVerificationFiles,
720
729
  indexCommitsForProject,
721
730
  embedUnembeddedCommits
722
- } from "./index-8jpqq2yk.js";
731
+ } from "./index-ns319t8e.js";
723
732
  import {
724
733
  setEmbeddingSessionBusy2,
725
734
  isEmbeddingHostBusy2
@@ -743,26 +752,26 @@ import {
743
752
  setMemoryClassification2,
744
753
  archiveMemory2,
745
754
  getMemoryCountsByStatus2
746
- } from "./index-dj784nyr.js";
755
+ } from "./index-hy44m6jc.js";
747
756
  import {
748
757
  invalidateMemory2
749
758
  } from "./index-yhzhdp3m.js";
750
759
  import {
751
760
  pushNotification2
752
761
  } from "./index-q1yc6bs0.js";
753
- import"./index-gc2749rx.js";
762
+ import"./index-8yjhda46.js";
754
763
  import {
755
764
  cosineSimilarity
756
- } from "./index-a7fj661j.js";
757
- import"./index-dj8hpkz7.js";
765
+ } from "./index-v26j81w6.js";
766
+ import"./index-729kkhmf.js";
758
767
  import {
759
768
  buildHiddenAgentRegistrations,
760
769
  logTemperatureDecision,
761
770
  subagentStepCap,
762
771
  SubagentTelemetry,
763
772
  readHostSystemPrompt
764
- } from "./index-zh1jw8qp.js";
765
- import"./index-290tzwp1.js";
773
+ } from "./index-xmdkde4v.js";
774
+ import"./index-kh3jt7t9.js";
766
775
  import {
767
776
  __toESM
768
777
  } from "./index-22jkk6wg.js";
@@ -775,7 +784,7 @@ import {
775
784
  import {
776
785
  logSlowWriteTransaction,
777
786
  WriteTransactionSteps
778
- } from "./index-0vrkp1jq.js";
787
+ } from "./index-43zqh10z.js";
779
788
  import {
780
789
  setStoragePrivatePermissionEnforcement,
781
790
  ensureStorageDirectorySync,
@@ -3330,7 +3339,7 @@ function createNodeHostStallProfiler(deps) {
3330
3339
  if (stopped || !existsSync5(enablePath))
3331
3340
  return;
3332
3341
  session = api;
3333
- api.connect();
3342
+ inRootAsyncContext2(() => api.connect());
3334
3343
  await post(api, "Profiler.enable");
3335
3344
  await post(api, "Profiler.setSamplingInterval", {
3336
3345
  interval: Math.round(options.sampleIntervalMs * 1000)
@@ -3380,7 +3389,6 @@ function createNodeHostStallProfiler(deps) {
3380
3389
  isUnavailable: () => unavailable
3381
3390
  };
3382
3391
  }
3383
-
3384
3392
  // ../plugin/src/shared/host-stall-profiler.ts
3385
3393
  function hostStallProfilerDir() {
3386
3394
  return path7.join(getMagicContextStorageDir(), HOST_PROFILER_DIRNAME);
@@ -3397,7 +3405,7 @@ function startHostStallProfilerSwitch() {
3397
3405
  now: () => performance.now(),
3398
3406
  wallNow: () => Date.now(),
3399
3407
  setInterval: (callback, ms) => {
3400
- const handle = setInterval(callback, ms);
3408
+ const handle = inRootAsyncContext2(() => setInterval(callback, ms));
3401
3409
  handle.unref?.();
3402
3410
  return handle;
3403
3411
  },
@@ -3424,7 +3432,7 @@ function startHostStallProfilerSwitch() {
3424
3432
  // package.json
3425
3433
  var package_default = {
3426
3434
  name: "@cortexkit/pi-magic-context",
3427
- version: "0.49.7",
3435
+ version: "0.49.9",
3428
3436
  type: "module",
3429
3437
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3430
3438
  main: "dist/index.js",
@@ -8967,6 +8975,8 @@ function createV1HiddenCompletionExecutor(client, db, directory) {
8967
8975
  preferResponseOnMissingData: true
8968
8976
  });
8969
8977
  const id = typeof created?.id === "string" ? created.id : "";
8978
+ if (id)
8979
+ rememberV1HiddenRun(id, run);
8970
8980
  if (id && run.kind !== "dreamer-task") {
8971
8981
  historianChildren.add(id);
8972
8982
  rememberHistorianOutputCap(id, run.maxOutputTokens);
@@ -9017,6 +9027,7 @@ function createV1HiddenCompletionExecutor(client, db, directory) {
9017
9027
  },
9018
9028
  async close(handle, settlement) {
9019
9029
  if (handle?.id) {
9030
+ rememberV1HiddenRun(handle.id, undefined);
9020
9031
  historianChildren.delete(handle.id);
9021
9032
  forgetHistorianOutputCap(handle.id);
9022
9033
  }
@@ -9697,7 +9708,7 @@ function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalOrAcquisiti
9697
9708
  }
9698
9709
  };
9699
9710
  beat();
9700
- const timer = lost ? undefined : setInterval(() => withSqliteBackgroundWriter2(beat), intervalMs);
9711
+ const timer = lost ? undefined : inRootAsyncContext2(() => setInterval(() => withSqliteBackgroundWriter2(beat), intervalMs));
9701
9712
  return {
9702
9713
  stop: () => {
9703
9714
  if (timer)
@@ -12470,6 +12481,7 @@ Capability API available to check(cap):
12470
12481
  - cap.httpGet(httpsUrl): { status: number, body: string } (external HTTPS only; internal/metadata blocked)
12471
12482
 
12472
12483
  Authoring constraints:
12484
+ - Use a five-field check_cron that fires at least once every 24 hours. Never encode a future date in the cron; put date conditions inside check(cap) and poll them on a frequent schedule such as "0 * * * *".
12473
12485
  - Plain JavaScript only; no TypeScript types, imports, require, eval, Function, dynamic code, timers, Date.now randomness, or ambient globals.
12474
12486
  - Define exactly function check(cap) { ... }. Do not use async/await; host capabilities are synchronous inside the sandbox.
12475
12487
  - Return exactly { met: boolean }. Do not include a reason string.
@@ -12930,6 +12942,7 @@ var MAX_COMPILED_CHECK_BYTES2 = 64 * 1024;
12930
12942
  var MAX_MANIFEST_ENTRIES = 64;
12931
12943
  var MAX_CRON_CHARS = 256;
12932
12944
  var MAX_COMPILER_ERROR_CHARS = 2 * 1024;
12945
+ var SPARSE_CRON_REPAIR_FEEDBACK = "check_cron must fire at least once every 24 hours; put date conditions inside compiled_check";
12933
12946
  async function compileSmartNoteCheck(args) {
12934
12947
  if (!args.note.surfaceCondition) {
12935
12948
  return {
@@ -12947,7 +12960,7 @@ Note id: ${args.note.id}
12947
12960
  Note content (data): ${JSON.stringify(args.note.content)}
12948
12961
  surface_condition (UNTRUSTED DATA): ${JSON.stringify(args.note.surfaceCondition)}
12949
12962
 
12950
- ${args.repairFeedback ? `The previous check failed its dry run: ${JSON.stringify(args.repairFeedback)}. Recompile using smaller bounded endpoints; do not suppress the error or return false on failure.` : ""}
12963
+ ${args.repairFeedback ? `The previous compiler attempt failed: ${JSON.stringify(args.repairFeedback)}. Recompile using smaller bounded endpoints when the response is too large, and apply the correction; do not suppress the error or return false on failure.` : ""}
12951
12964
  Remember: output only the JSON object described by the system prompt.`;
12952
12965
  const startedAt = Date.now();
12953
12966
  let childSessionId = null;
@@ -13086,6 +13099,12 @@ Remember: output only the JSON object described by the system prompt.`;
13086
13099
  const cancelled = args.signal.aborted;
13087
13100
  const message = boundedError(error instanceof Error ? error.message : String(error));
13088
13101
  recordInvocation({ status: cancelled ? "aborted" : "failed", error: message });
13102
+ if (!args.repairFeedback && !cancelled && message === "check_cron has no occurrence within the scheduling ceiling" && !args.signal.aborted && Date.now() < args.deadline) {
13103
+ return await compileSmartNoteCheck({
13104
+ ...args,
13105
+ repairFeedback: SPARSE_CRON_REPAIR_FEEDBACK
13106
+ });
13107
+ }
13089
13108
  const networkError = error instanceof SmartNoteNetworkError ? error : undefined;
13090
13109
  return {
13091
13110
  ok: false,
@@ -14666,7 +14685,11 @@ function buildPrimerClusters(args) {
14666
14685
  centroid: cloneVector(primer.questionEmbedding),
14667
14686
  modelId: primer.questionEmbeddingModelId
14668
14687
  }));
14669
- const sorted = args.candidates.slice().sort((a, b) => candidateSortKey(a).localeCompare(candidateSortKey(b)));
14688
+ const sorted = args.candidates.slice().sort((a, b) => {
14689
+ const left = candidateSortKey(a);
14690
+ const right = candidateSortKey(b);
14691
+ return left < right ? -1 : left > right ? 1 : 0;
14692
+ });
14670
14693
  for (const candidate of sorted) {
14671
14694
  let best = null;
14672
14695
  for (const cluster of clusters) {
@@ -18626,10 +18649,10 @@ async function sourceReady(source, sessionId) {
18626
18649
  function defer(fn) {
18627
18650
  const immediate = globalThis.setImmediate;
18628
18651
  if (typeof immediate === "function") {
18629
- immediate(fn);
18652
+ inRootAsyncContext2(() => immediate(fn));
18630
18653
  return;
18631
18654
  }
18632
- setTimeout(fn, 0);
18655
+ inRootAsyncContext2(() => setTimeout(fn, 0));
18633
18656
  }
18634
18657
  function yieldToEventLoop() {
18635
18658
  return new Promise((resolve) => defer(resolve));
@@ -18706,14 +18729,14 @@ function scheduleReconciliation(db, sessionId, readMessages) {
18706
18729
  reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
18707
18730
  if (ran)
18708
18731
  return;
18709
- setTimeout(() => {
18732
+ inRootAsyncContext2(() => setTimeout(() => {
18710
18733
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
18711
18734
  scheduleReconciliation(db, sessionId, readMessages);
18712
- }, PREPARE_RETRY_MS).unref?.();
18735
+ }, PREPARE_RETRY_MS)).unref?.();
18713
18736
  }).catch((error) => {
18714
18737
  logIndexingError(sessionId, "reconciliation", error);
18715
18738
  if (isDatabaseLockedError(error))
18716
- setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000).unref();
18739
+ inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
18717
18740
  }).finally(() => {
18718
18741
  heapHolder.reconciliationScheduledSessions.delete(sessionId);
18719
18742
  });
@@ -18728,7 +18751,7 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
18728
18751
  const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
18729
18752
  if (activeTimer)
18730
18753
  clearTimeout(activeTimer);
18731
- const timer = setTimeout(() => {
18754
+ const timer = inRootAsyncContext2(() => setTimeout(() => {
18732
18755
  heapHolder.incrementalTimers.delete(schedulingKey);
18733
18756
  heapHolder.pendingIncrementalKeys.add(schedulingKey);
18734
18757
  const indexMessage = async () => {
@@ -18772,7 +18795,7 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
18772
18795
  if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
18773
18796
  heapHolder.pendingIncrementalKeys.delete(schedulingKey);
18774
18797
  });
18775
- }, INCREMENTAL_DEBOUNCE_MS);
18798
+ }, INCREMENTAL_DEBOUNCE_MS));
18776
18799
  heapHolder.incrementalTimers.set(schedulingKey, timer);
18777
18800
  }
18778
18801
  async function indexSingleMessageOffThread(db, sessionId, message) {
@@ -18946,7 +18969,7 @@ async function startDreamScheduleTimer(args) {
18946
18969
  startupTickTimer = null;
18947
18970
  runTick("startup");
18948
18971
  });
18949
- const timer = setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS);
18972
+ const timer = inRootAsyncContext2(() => setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS));
18950
18973
  if (typeof timer === "object" && "unref" in timer) {
18951
18974
  timer.unref();
18952
18975
  }
@@ -19242,7 +19265,7 @@ async function runCompiledSmartNoteSweep(reg, db) {
19242
19265
  }
19243
19266
  }
19244
19267
  function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
19245
- const timer = setInterval(() => {
19268
+ const timer = inRootAsyncContext2(() => setInterval(() => {
19246
19269
  try {
19247
19270
  if (!renewGitSweepLease(db, projectIdentity, holderId)) {
19248
19271
  log2(`[git-commits] sweep lease renewal failed for ${projectIdentity}`);
@@ -19250,7 +19273,7 @@ function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
19250
19273
  } catch (error) {
19251
19274
  log2(`[git-commits] sweep lease renewal errored for ${projectIdentity}: ${error instanceof Error ? error.message : String(error)}`);
19252
19275
  }
19253
- }, GIT_SWEEP_LEASE_RENEWAL_MS);
19276
+ }, GIT_SWEEP_LEASE_RENEWAL_MS));
19254
19277
  timer.unref?.();
19255
19278
  return () => clearInterval(timer);
19256
19279
  }
@@ -19459,6 +19482,39 @@ import {
19459
19482
  import { createInterface } from "node:readline";
19460
19483
  import { StringDecoder } from "node:string_decoder";
19461
19484
  import { fileURLToPath } from "node:url";
19485
+
19486
+ // src/pi-zen-free-tier.ts
19487
+ var ZEN_FREE_TIER_FAILURE = "opencode_zen_free_tier";
19488
+ function isZenModel(model) {
19489
+ return model !== undefined && canonicalModelIdentity(model).startsWith("opencode/");
19490
+ }
19491
+ function isZenFreeTierRefusal(text) {
19492
+ return /\bFreeTierError\b/.test(text) || /\b403\b/.test(text) && /OpenCode's free tier can only be used from within OpenCode/i.test(text);
19493
+ }
19494
+ function zenFreeTierMessage(agent, harness) {
19495
+ const task = agent.includes("historian") ? "historian" : "dreamer";
19496
+ const host = harness === "omp" ? "Oh My Pi" : "Pi";
19497
+ return `${ZEN_FREE_TIER_FAILURE}: OpenCode Zen free models only run inside OpenCode; choose another ${task} model for ${host} (FreeTierError).`;
19498
+ }
19499
+ function classifyZenFreeTierFailure(result, model, agent, harness) {
19500
+ if (result.ok || !isZenModel(model))
19501
+ return result;
19502
+ const stderr = typeof result.meta?.stderr === "string" ? result.meta.stderr : "";
19503
+ if (!isZenFreeTierRefusal(result.error) && !isZenFreeTierRefusal(stderr))
19504
+ return result;
19505
+ return {
19506
+ ...result,
19507
+ error: zenFreeTierMessage(agent, harness),
19508
+ meta: {
19509
+ failureClass: ZEN_FREE_TIER_FAILURE,
19510
+ errorClass: "FreeTierError",
19511
+ ...typeof result.meta?.exitCode === "number" ? { exitCode: result.meta.exitCode } : {},
19512
+ ...typeof result.meta?.sawProtocolOutput === "boolean" ? { sawProtocolOutput: result.meta.sawProtocolOutput } : {}
19513
+ }
19514
+ };
19515
+ }
19516
+
19517
+ // src/subagent-runner.ts
19462
19518
  var PI_CODING_AGENT_MODULE = "@earendil-works/pi-coding-agent";
19463
19519
  var PI_CODING_AGENT_PACKAGE_NAMES = new Set([
19464
19520
  PI_CODING_AGENT_MODULE,
@@ -20010,6 +20066,9 @@ class PiSubagentRunner {
20010
20066
  }
20011
20067
  async runOnce(options, runMode, modelRefOverride) {
20012
20068
  const startTime = Date.now();
20069
+ const zenChild = STRICT_TOOL_ALLOWLIST.has(options.agent) && isZenModel(options.model);
20070
+ let deferredZenStderr = "";
20071
+ let reportedZenStderr = false;
20013
20072
  let recordedAccounting = false;
20014
20073
  const cap = subagentStepCap(options.agent);
20015
20074
  const budget = options.tokenBudget ? createDreamTokenBudget(options.tokenBudget) : undefined;
@@ -20033,7 +20092,7 @@ class PiSubagentRunner {
20033
20092
  subagent: options.accountingSubagent ?? inferAccountingSubagent(options.agent),
20034
20093
  task: options.accountingTask ?? null,
20035
20094
  startedAt: startTime,
20036
- status: result.ok ? "completed" : result.reason === "abort" ? "aborted" : result.reason === "timeout" ? "timed_out" : result.reason === "no_assistant" || result.reason === "truncated" ? "empty" : "failed",
20095
+ status: result.ok ? "completed" : result.meta?.failureClass === ZEN_FREE_TIER_FAILURE ? "failed" : result.reason === "abort" ? "aborted" : result.reason === "timeout" ? "timed_out" : result.reason === "no_assistant" || result.reason === "truncated" ? "empty" : "failed",
20037
20096
  messages,
20038
20097
  providerId: hasProvider ? modelRef?.slice(0, providerSeparator) : undefined,
20039
20098
  modelId: hasProvider ? modelRef?.slice(providerSeparator + 1) : modelRef,
@@ -20138,7 +20197,20 @@ class PiSubagentRunner {
20138
20197
  if (settled)
20139
20198
  return;
20140
20199
  settled = true;
20141
- if (isMemoryMapper) {
20200
+ if (zenChild) {
20201
+ const classified = classifyZenFreeTierFailure(result, options.model, options.agent, this.invocation.targetHarness);
20202
+ if (classified !== result && !classified.ok) {
20203
+ sessionLog2(options.accountingSessionId ?? "subagent", classified.error);
20204
+ }
20205
+ result = classified;
20206
+ if (deferredZenStderr && !reportedZenStderr) {
20207
+ emitProgress({
20208
+ type: "stderr",
20209
+ chunk: result.meta?.failureClass === ZEN_FREE_TIER_FAILURE ? zenFreeTierMessage(options.agent, this.invocation.targetHarness) : deferredZenStderr
20210
+ });
20211
+ }
20212
+ }
20213
+ if (isMemoryMapper && result.meta?.failureClass !== ZEN_FREE_TIER_FAILURE) {
20142
20214
  result = {
20143
20215
  ...result,
20144
20216
  meta: { ...result.meta, mappingMessages: [...mappingMessages] }
@@ -20168,6 +20240,12 @@ class PiSubagentRunner {
20168
20240
  const emitProgress = (event) => {
20169
20241
  if (!options.onProgress)
20170
20242
  return;
20243
+ if (zenChild && event.type === "raw_event" && isZenFreeTierRefusal(JSON.stringify(event.event))) {
20244
+ event = {
20245
+ ...event,
20246
+ event: { type: event.eventType, error: { type: "FreeTierError" } }
20247
+ };
20248
+ }
20171
20249
  try {
20172
20250
  options.onProgress(event);
20173
20251
  } catch {}
@@ -20176,7 +20254,7 @@ class PiSubagentRunner {
20176
20254
  const parentEnv = { ...process.env };
20177
20255
  delete parentEnv.MAGIC_CONTEXT_HISTORIAN_TEMPERATURE;
20178
20256
  try {
20179
- child = this.spawnImpl(this.invocation.command, [...this.invocation.prefixArgs, ...this.extraArgs, ...args], {
20257
+ child = inRootAsyncContext2(() => this.spawnImpl(this.invocation.command, [...this.invocation.prefixArgs, ...this.extraArgs, ...args], {
20180
20258
  windowsHide: true,
20181
20259
  cwd: options.cwd,
20182
20260
  env: {
@@ -20197,7 +20275,7 @@ class PiSubagentRunner {
20197
20275
  "pipe",
20198
20276
  "pipe"
20199
20277
  ]
20200
- });
20278
+ }));
20201
20279
  } catch (error) {
20202
20280
  cleanupSystemPromptFile();
20203
20281
  settle({
@@ -20281,7 +20359,17 @@ class PiSubagentRunner {
20281
20359
  if (stderr.length > 16000) {
20282
20360
  stderr = `…[truncated]${stderr.slice(-16000)}`;
20283
20361
  }
20284
- emitProgress({ type: "stderr", chunk: text });
20362
+ if (zenChild) {
20363
+ deferredZenStderr = stderr;
20364
+ if (!reportedZenStderr && isZenFreeTierRefusal(stderr)) {
20365
+ reportedZenStderr = true;
20366
+ emitProgress({
20367
+ type: "stderr",
20368
+ chunk: zenFreeTierMessage(options.agent, this.invocation.targetHarness)
20369
+ });
20370
+ }
20371
+ } else
20372
+ emitProgress({ type: "stderr", chunk: text });
20285
20373
  });
20286
20374
  child.stderr?.on("error", () => {});
20287
20375
  let finalAssistantText = null;
@@ -23402,7 +23490,7 @@ function schedulePiTransformDecisionResolve(args) {
23402
23490
  return false;
23403
23491
  pendingPiDecisionBySession.delete(args.sessionId);
23404
23492
  const token = addScheduledWriteToken(args.sessionId);
23405
- setTimeout(() => {
23493
+ inRootAsyncContext2(() => setTimeout(() => {
23406
23494
  try {
23407
23495
  if (!hasScheduledWriteToken(args.sessionId, token))
23408
23496
  return;
@@ -23422,7 +23510,7 @@ function schedulePiTransformDecisionResolve(args) {
23422
23510
  } finally {
23423
23511
  deleteScheduledWriteToken(args.sessionId, token);
23424
23512
  }
23425
- }, 0);
23513
+ }, 0));
23426
23514
  return true;
23427
23515
  }
23428
23516
  function addScheduledWriteToken(sessionId) {
@@ -25710,7 +25798,7 @@ function buildEditSupersessionReclaim(input) {
25710
25798
  seenFile.add(filePath);
25711
25799
  continue;
25712
25800
  }
25713
- if (input.recentMessageIds && (tag.toolOwnerMessageId === null || input.recentMessageIds.has(tag.toolOwnerMessageId))) {
25801
+ if (tag.tagNumber > input.watermark || input.recentMessageIds && (tag.toolOwnerMessageId === null || input.recentMessageIds.has(tag.toolOwnerMessageId))) {
25714
25802
  continue;
25715
25803
  }
25716
25804
  if (realPendingTagIds.has(tag.tagNumber))
@@ -25808,6 +25896,51 @@ function readServedTemporalDecisions(db, sessionId, runtime, messageIds) {
25808
25896
  return result;
25809
25897
  }
25810
25898
 
25899
+ // ../plugin/src/shared/reclaim-distance.ts
25900
+ var RECLAIM_DISTANCE_USER_TURNS = 3;
25901
+ var RECLAIM_DISTANCE_WINDOW_FRACTION = 0.25;
25902
+ function isReclaimUserTurn(args) {
25903
+ return args.role === "user" && !args.syntheticHead && !args.synthetic && !args.ignored && args.parts.some((part) => {
25904
+ if (part.synthetic || part.ignored)
25905
+ return false;
25906
+ if (part.kind !== "text" && part.kind !== "image" && part.kind !== "file")
25907
+ return false;
25908
+ if (part.kind !== "text")
25909
+ return true;
25910
+ return stripReclaimMcText(part.text ?? "").trim().length > 0;
25911
+ });
25912
+ }
25913
+ function stripReclaimMcText(text) {
25914
+ return text.replace(/^§\d+§\s*/, "").replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, (reminder) => /^(?:Your next step: call ctx_reduce on the outputs you've already used|Still unstamped:|Housekeeping: .* are reclaimable\. Stamp each output with ctx_reduce|.* are reclaimable\. Make a ctx_reduce pass now|.* are still unstamped\. Call ctx_reduce now)/.test(reminder.slice("<system-reminder>".length).trimStart()) ? "" : reminder).replace(/<instruction name="deferred_notes">[\s\S]*?<\/instruction>/g, "");
25915
+ }
25916
+ function farBehindToolBookmark(entries, usableWindow) {
25917
+ let newerTurns = 0;
25918
+ let newerTokens = 0;
25919
+ const farTags = [];
25920
+ let firstYoungTag = Infinity;
25921
+ const seenOutputs = new Set;
25922
+ const tokenDistance = usableWindow > 0 && Number.isFinite(usableWindow) ? usableWindow * RECLAIM_DISTANCE_WINDOW_FRACTION : Infinity;
25923
+ for (let index = entries.length - 1;index >= 0; index--) {
25924
+ const entry = entries[index];
25925
+ if (!entry)
25926
+ continue;
25927
+ const tag = entry.toolOutputTag;
25928
+ if (tag !== undefined && !seenOutputs.has(tag)) {
25929
+ seenOutputs.add(tag);
25930
+ if (newerTurns >= RECLAIM_DISTANCE_USER_TURNS || newerTokens >= tokenDistance) {
25931
+ farTags.push(tag);
25932
+ } else {
25933
+ firstYoungTag = Math.min(firstYoungTag, tag);
25934
+ }
25935
+ }
25936
+ if (entry.userTurn)
25937
+ newerTurns++;
25938
+ if (Number.isFinite(entry.tokens) && entry.tokens > 0)
25939
+ newerTokens += entry.tokens;
25940
+ }
25941
+ return farTags.reduce((bookmark, tag) => tag < firstYoungTag ? Math.max(bookmark, tag) : bookmark, 0);
25942
+ }
25943
+
25811
25944
  // ../plugin/src/hooks/magic-context/tool-reclaim.ts
25812
25945
  function buildSyntheticToolReclaimOps(input) {
25813
25946
  const watermark = Math.max(0, input.watermark);
@@ -25839,10 +25972,74 @@ function buildSyntheticToolReclaimOps(input) {
25839
25972
  }
25840
25973
  return synthetic;
25841
25974
  }
25842
- function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
25843
- const maxTagNumber = getMaxTagNumberBySession2(db, sessionId);
25844
- advanceToolReclaimWatermark(db, sessionId, maxTagNumber);
25845
- return maxTagNumber;
25975
+ function advanceToolReclaimWatermarkByDistance(db, sessionId, entries, usableWindow) {
25976
+ const bookmark = farBehindToolBookmark(entries, usableWindow);
25977
+ advanceToolReclaimWatermark(db, sessionId, bookmark);
25978
+ return bookmark;
25979
+ }
25980
+ function toolReclaimDistanceEntries(messages, targets) {
25981
+ const outputTags = new Map;
25982
+ for (const [tag, target] of targets) {
25983
+ for (const location of target.mutationParts ?? []) {
25984
+ const part = distancePart(location.part);
25985
+ if (part.kind === "tool_result" || part.kind === "tool")
25986
+ outputTags.set(location.part, tag);
25987
+ }
25988
+ }
25989
+ const entries = [];
25990
+ for (const message of messages) {
25991
+ const parts = message.parts.map(distancePart);
25992
+ let userTurn = isReclaimUserTurn({ ...message.info, parts });
25993
+ for (const [index, part] of parts.entries()) {
25994
+ const authored = isReclaimUserTurn({ role: "user", parts: [part] });
25995
+ entries.push({
25996
+ tokens: message.info.syntheticHead ? 0 : estimateTokens(stripReclaimMcText(part.text ?? "")) + part.imageTokens,
25997
+ userTurn: userTurn && authored,
25998
+ toolOutputTag: outputTags.get(message.parts[index])
25999
+ });
26000
+ if (authored)
26001
+ userTurn = false;
26002
+ }
26003
+ }
26004
+ return entries;
26005
+ }
26006
+ function distancePart(raw) {
26007
+ if (!raw || typeof raw !== "object")
26008
+ return { kind: "structural", imageTokens: 0 };
26009
+ const part = raw;
26010
+ const provenance = { synthetic: part.synthetic === true, ignored: part.ignored === true };
26011
+ if (typeof part.getText === "function") {
26012
+ const text = part.getText();
26013
+ return {
26014
+ ...provenance,
26015
+ kind: String(part.kind),
26016
+ text: typeof text === "string" ? text : undefined,
26017
+ imageTokens: typeof part.imageTokens === "function" ? Number(part.imageTokens()) : 0
26018
+ };
26019
+ }
26020
+ const metadata = { ...provenance, imageTokens: estimatePartImageTokens(raw) };
26021
+ if (part.type === "tool") {
26022
+ const state = part.state;
26023
+ return {
26024
+ ...metadata,
26025
+ kind: "tool",
26026
+ text: `${JSON.stringify(state?.input ?? {})}
26027
+ ${typeof state?.output === "string" ? state.output : JSON.stringify(state?.output ?? "")}`
26028
+ };
26029
+ }
26030
+ if (part.type === "tool_use")
26031
+ return { ...metadata, kind: "tool_use", text: JSON.stringify(part.input ?? {}) };
26032
+ if (part.type === "tool_result")
26033
+ return {
26034
+ ...metadata,
26035
+ kind: "tool_result",
26036
+ text: typeof part.content === "string" ? part.content : JSON.stringify(part.content ?? "")
26037
+ };
26038
+ return {
26039
+ ...metadata,
26040
+ kind: String(part.type),
26041
+ text: typeof part.text === "string" ? part.text : typeof part.thinking === "string" ? part.thinking : undefined
26042
+ };
25846
26043
  }
25847
26044
 
25848
26045
  // ../plugin/src/shared/recovery-reasoning-prefix.ts
@@ -26994,7 +27191,7 @@ function queueAutoSearchBackfill(db, sessionId, projectPath, query) {
26994
27191
  pending.delete(key);
26995
27192
  resolve();
26996
27193
  };
26997
- const queued = setTimeout(() => {
27194
+ const queued = inRootAsyncContext2(() => setTimeout(() => {
26998
27195
  lifecycle.signal.removeEventListener("abort", cancel);
26999
27196
  if (lifecycle.signal.aborted)
27000
27197
  return done();
@@ -27005,7 +27202,7 @@ function queueAutoSearchBackfill(db, sessionId, projectPath, query) {
27005
27202
  clearTimeout(timeout);
27006
27203
  done();
27007
27204
  });
27008
- }, 0);
27205
+ }, 0));
27009
27206
  const cancel = () => {
27010
27207
  clearTimeout(queued);
27011
27208
  done();
@@ -27052,7 +27249,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
27052
27249
  deadlineUnixMs: autoSearchDeadlineUnixMs(deadlineSignal)
27053
27250
  };
27054
27251
  return new Promise((resolve, reject) => {
27055
- const worker = new Worker(entry, { workerData: input });
27252
+ const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: input }));
27056
27253
  let settled = false;
27057
27254
  const finish = (results, error) => {
27058
27255
  if (settled)
@@ -28605,6 +28802,8 @@ ${chunkText}`,
28605
28802
  }
28606
28803
  }
28607
28804
  function piSubagentFailureReason(failure) {
28805
+ if (failure.meta?.failureClass === ZEN_FREE_TIER_FAILURE)
28806
+ return ZEN_FREE_TIER_FAILURE;
28608
28807
  if (PRODUCER_PROMPT_FIT_FAILURE_PATTERN.test(failure.error))
28609
28808
  return failure.error;
28610
28809
  if (["step_limit", "token_budget", "invalid_prompt"].includes(failure.reason)) {
@@ -28913,6 +29112,59 @@ function recordPiTransformTiming(sample) {
28913
29112
  // src/ctx-reduce-nudge-pi.ts
28914
29113
  import { randomUUID as randomUUID3 } from "node:crypto";
28915
29114
 
29115
+ // src/provider-visible-parts-pi.ts
29116
+ function isRecord4(value) {
29117
+ return value !== null && typeof value === "object" && !Array.isArray(value);
29118
+ }
29119
+ var PART_FIELDS = {
29120
+ text: ["type", "text", "textSignature"],
29121
+ thinking: ["type", "thinking", "thinkingSignature", "redacted"],
29122
+ image: ["type", "data", "mimeType"],
29123
+ toolCall: [
29124
+ "type",
29125
+ "id",
29126
+ "name",
29127
+ "arguments",
29128
+ "thoughtSignature",
29129
+ "namespace"
29130
+ ]
29131
+ };
29132
+ var MESSAGE_FIELDS = [
29133
+ "role",
29134
+ "provider",
29135
+ "api",
29136
+ "model",
29137
+ "stopReason",
29138
+ "toolCallId",
29139
+ "toolName",
29140
+ "isError"
29141
+ ];
29142
+ function pick(value, fields) {
29143
+ const view = {};
29144
+ for (const field of fields) {
29145
+ if (Object.hasOwn(value, field))
29146
+ view[field] = value[field];
29147
+ }
29148
+ return view;
29149
+ }
29150
+ function providerVisiblePiPart(value, providerApi) {
29151
+ if (providerApi === "pi-messages")
29152
+ return value;
29153
+ if (Array.isArray(value))
29154
+ return value.map((part) => providerVisiblePiPart(part, providerApi));
29155
+ if (!isRecord4(value))
29156
+ return value;
29157
+ if (typeof value.role === "string") {
29158
+ const view = pick(value, MESSAGE_FIELDS);
29159
+ if (Object.hasOwn(value, "content")) {
29160
+ view.content = Array.isArray(value.content) ? value.content.map((part) => providerVisiblePiPart(part, providerApi)) : typeof value.content === "string" ? value.content : undefined;
29161
+ }
29162
+ return view;
29163
+ }
29164
+ const type = typeof value.type === "string" ? value.type : "";
29165
+ return pick(value, Object.hasOwn(PART_FIELDS, type) ? PART_FIELDS[type] : ["type"]);
29166
+ }
29167
+
28916
29168
  // src/tail-hygiene-walk-pi.ts
28917
29169
  var TAG_PREFIX = /^§(\d+)§\s*/;
28918
29170
  var SYNTHETIC_TODO_PREFIX = "mc_synthetic_todo_";
@@ -28926,7 +29178,7 @@ function clearPiTailHygieneContentMemo() {
28926
29178
  }
28927
29179
  var FNV1A_32_OFFSET = 2166136261;
28928
29180
  var FNV1A_32_PRIME = 16777619;
28929
- function isRecord4(value) {
29181
+ function isRecord5(value) {
28930
29182
  return value !== null && typeof value === "object";
28931
29183
  }
28932
29184
  function fnv1a32(value) {
@@ -28941,7 +29193,7 @@ function safeStableStringify(value) {
28941
29193
  const seen = new Set;
28942
29194
  try {
28943
29195
  return JSON.stringify(value, (_key, current) => {
28944
- if (!isRecord4(current) || Array.isArray(current))
29196
+ if (!isRecord5(current) || Array.isArray(current))
28945
29197
  return current;
28946
29198
  if (seen.has(current))
28947
29199
  return "[Circular]";
@@ -29000,7 +29252,7 @@ function messageIdentity(message, index, stableId) {
29000
29252
  const resolved = stableId?.(message, index);
29001
29253
  if (resolved)
29002
29254
  return resolved;
29003
- if (isRecord4(message)) {
29255
+ if (isRecord5(message)) {
29004
29256
  if (typeof message.responseId === "string" && message.responseId.length > 0) {
29005
29257
  return `response:${message.responseId}`;
29006
29258
  }
@@ -29060,13 +29312,13 @@ function collectToolArcs(input) {
29060
29312
  const messageIds = input.messages.map((message, index) => messageIdentity(message, index, input.stableId));
29061
29313
  for (let messageIndex = 0;messageIndex < input.messages.length; messageIndex += 1) {
29062
29314
  const raw = input.messages[messageIndex];
29063
- if (!isRecord4(raw))
29315
+ if (!isRecord5(raw))
29064
29316
  continue;
29065
29317
  const role = raw.role;
29066
29318
  if (role === "assistant" && Array.isArray(raw.content)) {
29067
29319
  for (let partIndex = 0;partIndex < raw.content.length; partIndex += 1) {
29068
29320
  const part = raw.content[partIndex];
29069
- if (!isRecord4(part) || part.type !== "toolCall")
29321
+ if (!isRecord5(part) || part.type !== "toolCall")
29070
29322
  continue;
29071
29323
  if (typeof part.id !== "string" || part.id.length === 0)
29072
29324
  continue;
@@ -29077,7 +29329,7 @@ function collectToolArcs(input) {
29077
29329
  ownerId,
29078
29330
  ownerIndex: messageIndex,
29079
29331
  toolName: typeof part.name === "string" ? part.name : null,
29080
- sentinel: isRecord4(part.arguments) && typeof part.arguments.__magic_context_dropped__ === "string",
29332
+ sentinel: isRecord5(part.arguments) && typeof part.arguments.__magic_context_dropped__ === "string",
29081
29333
  parts: [part]
29082
29334
  };
29083
29335
  arcs.push(arc);
@@ -29109,7 +29361,7 @@ function collectToolArcs(input) {
29109
29361
  if (!Array.isArray(raw.content))
29110
29362
  continue;
29111
29363
  for (const part of raw.content) {
29112
- if (!isRecord4(part))
29364
+ if (!isRecord5(part))
29113
29365
  continue;
29114
29366
  arc.parts.push(part);
29115
29367
  arcByPart.set(part, arc);
@@ -29310,11 +29562,20 @@ function attributeTags(input, arcs, messageIds) {
29310
29562
  }
29311
29563
  return { messageTags, tagsByNumber };
29312
29564
  }
29313
- function excludedDraft(key, value) {
29565
+ var partJsonMemo = new TailHygieneJsonMemo;
29566
+ var excludedViews = new WeakMap;
29567
+ function excludedDraftForApi(key, value, providerApi) {
29568
+ let view = value !== null && typeof value === "object" ? excludedViews.get(value) : undefined;
29569
+ if (view === undefined) {
29570
+ view = providerVisiblePiPart(value, providerApi);
29571
+ if (value !== null && typeof value === "object")
29572
+ excludedViews.set(value, view);
29573
+ }
29314
29574
  return {
29315
29575
  key,
29316
29576
  kind: "excluded",
29317
- content: typeof value === "string" ? value : safeStableStringify(value),
29577
+ content: "",
29578
+ contentHash: partJsonMemo.get(key, view, () => typeof view === "string" ? partHash("excluded", view) : piJsonHash(view, () => safeStableStringify(view)), true),
29318
29579
  tokens: 0
29319
29580
  };
29320
29581
  }
@@ -29339,7 +29600,7 @@ function finalizeParts(drafts, pendingDropTagNumbers, protectedTagNumbers, newes
29339
29600
  u += uTokens;
29340
29601
  return {
29341
29602
  key: draft.key,
29342
- contentHash: partHash(draft.kind, draft.content),
29603
+ contentHash: draft.contentHash ?? partHash(draft.kind, draft.content),
29343
29604
  kind: draft.kind,
29344
29605
  tokens,
29345
29606
  uTokens,
@@ -29359,6 +29620,19 @@ function finalizeParts(drafts, pendingDropTagNumbers, protectedTagNumbers, newes
29359
29620
  };
29360
29621
  }
29361
29622
  function measurePiTailHygiene(input) {
29623
+ partJsonMemo.beginPass();
29624
+ excludedViews = new WeakMap;
29625
+ let providerApi = input.providerApi;
29626
+ if (providerApi === undefined) {
29627
+ for (let index = input.messages.length - 1;index >= 0; index--) {
29628
+ const message = input.messages[index];
29629
+ if (isRecord5(message) && message.role === "assistant" && typeof message.api === "string") {
29630
+ providerApi = message.api;
29631
+ break;
29632
+ }
29633
+ }
29634
+ }
29635
+ const excludedDraft = (key, value) => excludedDraftForApi(key, value, providerApi);
29362
29636
  const { arcs, arcByPart, messageIds } = collectToolArcs(input);
29363
29637
  const { messageTags, tagsByNumber } = attributeTags(input, arcs, messageIds);
29364
29638
  const drafts = [];
@@ -29369,7 +29643,7 @@ function measurePiTailHygiene(input) {
29369
29643
  if (messageIndex === input.messages.length - 1)
29370
29644
  newestMessagePartStart = drafts.length;
29371
29645
  const messageKey = messageIds[messageIndex] ?? `pi-message:${messageIndex}`;
29372
- if (!isRecord4(raw)) {
29646
+ if (!isRecord5(raw)) {
29373
29647
  drafts.push(excludedDraft(`${messageKey}\x00excluded`, raw));
29374
29648
  continue;
29375
29649
  }
@@ -29408,7 +29682,7 @@ function measurePiTailHygiene(input) {
29408
29682
  for (let partIndex = 0;partIndex < raw.content.length; partIndex += 1) {
29409
29683
  const part = raw.content[partIndex];
29410
29684
  const key = `${messageKey}\x00${partIndex}`;
29411
- if (!isRecord4(part)) {
29685
+ if (!isRecord5(part)) {
29412
29686
  drafts.push(excludedDraft(`${key}\x00excluded`, part));
29413
29687
  continue;
29414
29688
  }
@@ -29478,7 +29752,7 @@ function measurePiTailHygiene(input) {
29478
29752
  drafts.push(excludedDraft(`${key}\x00toolInput`, part));
29479
29753
  continue;
29480
29754
  }
29481
- const content = safeStableStringify(part.arguments);
29755
+ const content = partJsonMemo.get(`${key}\x00input`, part.arguments, () => safeStableStringify(part.arguments));
29482
29756
  if (!content) {
29483
29757
  drafts.push(excludedDraft(`${key}\x00toolInput`, part));
29484
29758
  } else {
@@ -29528,7 +29802,7 @@ function refreshPiTailHygieneBaseline(input) {
29528
29802
  })
29529
29803
  };
29530
29804
  const now = input.now ?? Date.now();
29531
- const refrozen = (mismatch) => ({
29805
+ const refrozen = (mismatch) => rememberCurrentToolOutputCount({
29532
29806
  ...freezeTailHygieneMeasurement(measured),
29533
29807
  protectedToolsPolicy,
29534
29808
  hygieneUnitsVersion: frozenCalibration.hygieneUnitsVersion,
@@ -29542,7 +29816,7 @@ function refreshPiTailHygieneBaseline(input) {
29542
29816
  channel1PostReduceGrace: input.previous?.channel1PostReduceGrace,
29543
29817
  lastPrefixMismatch: mismatch,
29544
29818
  realUserTurnCount: rawMeasured.realUserTurnCount
29545
- });
29819
+ }, measured);
29546
29820
  if (input.cacheBusting || !input.previous)
29547
29821
  return refrozen();
29548
29822
  const prefix = compareMeasuredTailPrefix(input.previous.baselineParts, measured.parts);
@@ -29556,7 +29830,7 @@ function refreshPiTailHygieneBaseline(input) {
29556
29830
  if (part.kind !== "toolOutput" || !part.protected)
29557
29831
  turnDeltaU += part.uTokens;
29558
29832
  }
29559
- return {
29833
+ return rememberCurrentToolOutputCount({
29560
29834
  ...input.previous,
29561
29835
  protectedToolsPolicy,
29562
29836
  turnDeltaU,
@@ -29566,7 +29840,7 @@ function refreshPiTailHygieneBaseline(input) {
29566
29840
  contentSignature: measured.contentSignature,
29567
29841
  lastPrefixMismatch: undefined,
29568
29842
  realUserTurnCount: rawMeasured.realUserTurnCount
29569
- };
29843
+ }, measured);
29570
29844
  }
29571
29845
  function effectivePiTailHygiene(baseline) {
29572
29846
  const t = Math.ceil(Math.max(0, baseline.baselineT + baseline.turnDeltaT));
@@ -29576,7 +29850,7 @@ function effectivePiTailHygiene(baseline) {
29576
29850
  function measurePiToolResultDelta(content) {
29577
29851
  let tokens = 0;
29578
29852
  for (const part of content) {
29579
- if (!isRecord4(part))
29853
+ if (!isRecord5(part))
29580
29854
  continue;
29581
29855
  if (part.type === "text" && typeof part.text === "string") {
29582
29856
  const text = stripChannel1ReminderSpans(part.text);
@@ -29679,7 +29953,7 @@ function maybeChannel1ReminderForToolResult(args) {
29679
29953
  }
29680
29954
  const block = {
29681
29955
  type: "text",
29682
- text: buildChannel1Reminder(decision.level, decision.undroppedTokens, reclaimableToolOutputCount(state.baselineParts), currentReclaimHints(db, sessionId, state.oldestReclaimableToolTags), decision.sticky)
29956
+ text: buildChannel1Reminder(decision.level, decision.undroppedTokens, currentReclaimableToolOutputCount(state), currentReclaimHints(db, sessionId, state.oldestReclaimableToolTags), decision.sticky)
29683
29957
  };
29684
29958
  setChannel1NudgeState(db, sessionId, {
29685
29959
  ...nextNudgeState,
@@ -29717,7 +29991,7 @@ function maybeDeliverChannel2Pi(pi, db, sessionId) {
29717
29991
  try {
29718
29992
  const message = {
29719
29993
  customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
29720
- content: buildChannel2Reminder(undropped, reclaimableToolOutputCount(baseline.baselineParts), currentReclaimHints(db, sessionId, baseline.oldestReclaimableToolTags)),
29994
+ content: buildChannel2Reminder(undropped, currentReclaimableToolOutputCount(baseline), currentReclaimHints(db, sessionId, baseline.oldestReclaimableToolTags)),
29721
29995
  display: false,
29722
29996
  details: { kind: "channel-2-ceiling-nudge" }
29723
29997
  };
@@ -30788,6 +31062,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
30788
31062
  sequenceOffset: candidateCompartments.length,
30789
31063
  dumpLabelBase: `recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
30790
31064
  timeoutMs: historianTimeoutMs,
31065
+ maxOutputTokens: deps.historianMaxOutputTokens,
30791
31066
  model: deps.model,
30792
31067
  fallbackModelId: deps.fallbackModelId,
30793
31068
  fallbackModels: deps.fallbackModels,
@@ -31302,7 +31577,6 @@ ${renderUserFacingFailure("recomp_unavailable")}`;
31302
31577
  }
31303
31578
  }
31304
31579
  }
31305
-
31306
31580
  // ../plugin/src/hooks/magic-context/compartment-runner.ts
31307
31581
  var activeRuns = new Map;
31308
31582
  function getActiveCompartmentRun(sessionId) {
@@ -31323,7 +31597,7 @@ function withPublishedCallback(deps) {
31323
31597
  };
31324
31598
  }
31325
31599
  function startLeaseRenewal(deps, holderId) {
31326
- return setInterval(() => {
31600
+ return inRootAsyncContext2(() => setInterval(() => {
31327
31601
  try {
31328
31602
  if (!renewCompartmentLease(deps.db, deps.sessionId, holderId)) {
31329
31603
  sessionLog2(deps.sessionId, "compartment lease renewal failed; publish will be skipped if holder is stale");
@@ -31331,7 +31605,7 @@ function startLeaseRenewal(deps, holderId) {
31331
31605
  } catch (err) {
31332
31606
  sessionLog2(deps.sessionId, `compartment lease renewal threw; publish will be skipped if holder is stale (${err instanceof Error ? err.message : String(err)})`);
31333
31607
  }
31334
- }, COMPARTMENT_LEASE_RENEWAL_MS);
31608
+ }, COMPARTMENT_LEASE_RENEWAL_MS));
31335
31609
  }
31336
31610
  async function executeContextRecompWithResult(deps, options = {}) {
31337
31611
  const { sessionId } = deps;
@@ -31563,6 +31837,29 @@ function trimPiMessagesToBoundary(piMessages, entryIds, cutoffMessageId, trimMut
31563
31837
  break;
31564
31838
  }
31565
31839
  }
31840
+ if (cutoffIndex < 0 && sessionId && hasRawMessageProvider2(sessionId)) {
31841
+ try {
31842
+ const branch = readRawSessionMessages2(sessionId);
31843
+ const positions = new Map(branch.map((message, index) => [message.id, index]));
31844
+ const boundaryPosition = positions.get(cutoffMessageId);
31845
+ if (boundaryPosition === undefined)
31846
+ return 0;
31847
+ let previous = -1;
31848
+ for (const [index, message] of piMessages.entries()) {
31849
+ if (isPiSystemEntry(message))
31850
+ continue;
31851
+ const id = resolveStableId(message, index, entryIds);
31852
+ const position = positions.get(id) ?? positions.get(`${SYNTH_USER_ID_PREFIX}${id}`);
31853
+ if (position === undefined || position <= previous)
31854
+ return 0;
31855
+ previous = position;
31856
+ if (position <= boundaryPosition)
31857
+ cutoffIndex = index;
31858
+ }
31859
+ } catch {
31860
+ return 0;
31861
+ }
31862
+ }
31566
31863
  if (cutoffIndex < 0)
31567
31864
  return 0;
31568
31865
  const remove = new Set;
@@ -33425,9 +33722,9 @@ class PiContextBudget {
33425
33722
  elapsed() {
33426
33723
  return this.now() - this.startedAt;
33427
33724
  }
33428
- remainingWork() {
33725
+ remainingWork = () => {
33429
33726
  return Math.max(0, PI_CONTEXT_BUDGET.workMs - this.elapsed());
33430
- }
33727
+ };
33431
33728
  remainingOutcome = () => Math.max(0, PI_CONTEXT_BUDGET.outcomeMs - this.elapsed());
33432
33729
  writerAllowance() {
33433
33730
  return Math.max(0, Math.min(PI_CONTEXT_BUDGET.writerMs, this.remainingWork() - PI_CONTEXT_BUDGET.completionReserveMs));
@@ -35625,6 +35922,7 @@ function createPiFallbackIndex() {
35625
35922
  import { createHash as createHash12, randomUUID as randomUUID4 } from "node:crypto";
35626
35923
 
35627
35924
  // src/tokenize-pi-messages.ts
35925
+ var PI_IMAGE_TOKENS = 1200;
35628
35926
  function tokenizePiMessages(messages, options) {
35629
35927
  let conversation = 0;
35630
35928
  let toolCall = 0;
@@ -35682,7 +35980,7 @@ function tokenizePiMessages(messages, options) {
35682
35980
  }
35683
35981
  break;
35684
35982
  case "image":
35685
- conversation += 1200;
35983
+ conversation += PI_IMAGE_TOKENS;
35686
35984
  break;
35687
35985
  case "toolCall":
35688
35986
  if (typeof p.name === "string")
@@ -35711,7 +36009,7 @@ function tokenizePiMessages(messages, options) {
35711
36009
  if (p.type === "text" && typeof p.text === "string") {
35712
36010
  toolCall += estimateTokens(p.text);
35713
36011
  } else if (p.type === "image") {
35714
- toolCall += 1200;
36012
+ toolCall += PI_IMAGE_TOKENS;
35715
36013
  }
35716
36014
  }
35717
36015
  }
@@ -37152,7 +37450,7 @@ function flushPiServedArrayLedger() {
37152
37450
  function scheduleFlush() {
37153
37451
  if (flushTimer)
37154
37452
  return;
37155
- flushTimer = setTimeout(flushPiServedArrayLedger, FLUSH_DELAY_MS);
37453
+ flushTimer = inRootAsyncContext2(() => setTimeout(flushPiServedArrayLedger, FLUSH_DELAY_MS));
37156
37454
  flushTimer.unref?.();
37157
37455
  }
37158
37456
  function enqueue(filePath, line, assertCurrentPass) {
@@ -38285,6 +38583,13 @@ function stripThinkingParts(message) {
38285
38583
  assistant.content = strippedContent;
38286
38584
  return before - strippedContent.length;
38287
38585
  }
38586
+
38587
+ class PiThinkingBindingRecoveryRefusal extends EmergencyFailClosedError {
38588
+ constructor() {
38589
+ super("Pi thinking-binding recovery has no valid new strip shape; this turn was not sent. Send a new message or start a new session.", { code: "pi_thinking_binding_no_valid_shape" });
38590
+ this.name = "PiThinkingBindingRecoveryRefusal";
38591
+ }
38592
+ }
38288
38593
  function applyPiThinkingBindingRecovery(args) {
38289
38594
  const protectedMessages = latestAssistantTurnMessages(args.messages);
38290
38595
  const frozenEntryIds = frozenBindingEntryIds(args.db, args.sessionId);
@@ -38294,14 +38599,17 @@ function applyPiThinkingBindingRecovery(args) {
38294
38599
  if (flagTarget) {
38295
38600
  const entryIds = new Set;
38296
38601
  for (let index = 0;index < args.messages.length; index += 1) {
38297
- if (protectedMessages.has(args.messages[index]))
38602
+ if (!hasThinkingPart(args.messages[index]))
38298
38603
  continue;
38299
38604
  const entryId = args.entryIds[index];
38300
- if (entryId && hasThinkingPart(args.messages[index]))
38301
- entryIds.add(entryId);
38605
+ if (!entryId)
38606
+ throw new PiThinkingBindingRecoveryRefusal;
38607
+ entryIds.add(entryId);
38302
38608
  }
38303
38609
  const newEntryIds = [...entryIds].filter((id) => !frozenEntryIds.has(id));
38304
- if (newEntryIds.length === 0 || addMergedReasoningStrippedIds(args.db, args.sessionId, [
38610
+ if (newEntryIds.length === 0)
38611
+ throw new PiThinkingBindingRecoveryRefusal;
38612
+ if (addMergedReasoningStrippedIds(args.db, args.sessionId, [
38305
38613
  ...newEntryIds.map(thinkingBindingRecoveryFrozenId),
38306
38614
  ...args.endOfPassOrder ? [THINKING_BINDING_STRIP_ORDER_END_MARKER] : []
38307
38615
  ])) {
@@ -38309,7 +38617,8 @@ function applyPiThinkingBindingRecovery(args) {
38309
38617
  frozenEntryIds.add(id);
38310
38618
  applied = { flagTarget, entryIds: [...entryIds] };
38311
38619
  reportBindingRecovery(args.sessionId, args.report, `thinking-binding recovery consumed on context pass target=${flagTarget} entries=${applied.entryIds.length} [${applied.entryIds.join(",")}]`);
38312
- }
38620
+ } else
38621
+ throw new PiThinkingBindingRecoveryRefusal;
38313
38622
  }
38314
38623
  const restoringActiveTurn = latestThinkingRecoveryCoversActiveTurn({
38315
38624
  db: args.db,
@@ -38326,6 +38635,12 @@ function applyPiThinkingBindingRecovery(args) {
38326
38635
  }
38327
38636
  return applied;
38328
38637
  }
38638
+ function hasUnfrozenPiThinking(args) {
38639
+ return isPrefixBoundThinkingModel(args.provider, args.model) && args.messages.some((message, index) => {
38640
+ const entryId = args.entryIds[index];
38641
+ return hasThinkingPart(message) && (!entryId || !args.frozen.has(entryId));
38642
+ });
38643
+ }
38329
38644
  function applyPiProactiveThinkingStrip(args) {
38330
38645
  if (!args.cacheBustingPass)
38331
38646
  return null;
@@ -39582,6 +39897,12 @@ function createOpaqueTranscriptMessage(working, index, sessionId, _markDirty, en
39582
39897
  function createPiUserStringPart(working, messageIndex, markDirty) {
39583
39898
  return {
39584
39899
  kind: "text",
39900
+ get synthetic() {
39901
+ return working[messageIndex].synthetic;
39902
+ },
39903
+ get ignored() {
39904
+ return working[messageIndex].ignored;
39905
+ },
39585
39906
  id: undefined,
39586
39907
  getText() {
39587
39908
  const msg = working[messageIndex];
@@ -39621,6 +39942,12 @@ function createPiUserArrayPart(working, messageIndex, partIndex, markDirty) {
39621
39942
  const kind = classifyContent(part);
39622
39943
  return {
39623
39944
  kind,
39945
+ synthetic: msg.synthetic || part?.synthetic,
39946
+ ignored: msg.ignored || part?.ignored,
39947
+ imageTokens() {
39948
+ const current = working[messageIndex].content;
39949
+ return Array.isArray(current) && current[partIndex]?.type === "image" ? PI_IMAGE_TOKENS : 0;
39950
+ },
39624
39951
  id: undefined,
39625
39952
  getText() {
39626
39953
  const current = working[messageIndex].content;
@@ -39827,6 +40154,9 @@ function createPiToolResultPart(working, messageIndex, partIndex, markDirty) {
39827
40154
  return {
39828
40155
  kind,
39829
40156
  id: msg.toolCallId,
40157
+ imageTokens() {
40158
+ return working[messageIndex].content[partIndex]?.type === "image" ? PI_IMAGE_TOKENS : 0;
40159
+ },
39830
40160
  remove() {
39831
40161
  return markToolRemoval(working, messageIndex, partIndex);
39832
40162
  },
@@ -39971,6 +40301,15 @@ var afterFallbackAdoptionForTests;
39971
40301
  var pendingDecisionLogObserverForTests;
39972
40302
  var mutationGateObserverForTests;
39973
40303
  var lkgRecoveryLogObserverForTests;
40304
+ var pipelineResultObserverForTests;
40305
+ function observePipelineResultForTests(sessionId, result) {
40306
+ pipelineResultObserverForTests?.(sessionId, {
40307
+ prefixBustPermitted: result.prefixBustPermitted,
40308
+ bustedThisPass: result.bustedThisPass,
40309
+ identityRebuilt: result.identityRebuilt,
40310
+ signedPrefixRewritten: result.signedPrefixRewritten
40311
+ });
40312
+ }
39974
40313
  var variantChangeLogObserverForTests;
39975
40314
  var beforePipelineForTests;
39976
40315
  function logPiLkgRecovery(sessionId, message) {
@@ -41627,7 +41966,7 @@ function registerPiContextHandler(pi, baseOptions) {
41627
41966
  const passGuard = { assert: assertCurrentPass, wait: guardAwait };
41628
41967
  guardSqliteTransformPass2({
41629
41968
  assert: assertCurrentPass,
41630
- remainingMs: () => budget.remainingWork()
41969
+ remainingMs: budget.remainingWork
41631
41970
  });
41632
41971
  budget.stage = "schema";
41633
41972
  const toolWireSchema = await guardAwait(loadPiToolWireSchema());
@@ -42162,6 +42501,7 @@ function registerPiContextHandler(pi, baseOptions) {
42162
42501
  protectedTokens: options.protectedTokens,
42163
42502
  protectedTokenTierOverrides: options.protectedTokenTierOverrides,
42164
42503
  usableSoft: windowGeometry?.usableSoft ?? usageContextLimit ?? 200000,
42504
+ reclaimUsableWindow: windowGeometry?.usableSoft ?? usageContextLimit ?? 0,
42165
42505
  heuristics: options.heuristics,
42166
42506
  emergencyCeilingTokens,
42167
42507
  injection: options.injection ? {
@@ -42233,6 +42573,7 @@ function registerPiContextHandler(pi, baseOptions) {
42233
42573
  }
42234
42574
  };
42235
42575
  let result = await budget.waitMandatory(runPipeline(pipelineArgs));
42576
+ observePipelineResultForTests(sessionId, result);
42236
42577
  logTransformTiming(sessionId, "runPipeline", tRunPipeline);
42237
42578
  if (result.identityRebuilt || result.lkgFrozenReleaseReason)
42238
42579
  schedulerDecision = "execute";
@@ -42268,7 +42609,7 @@ function registerPiContextHandler(pi, baseOptions) {
42268
42609
  if (historian && !options.compactionOff && budget.remainingWork() > 0) {
42269
42610
  guardSqliteTransformPass2({
42270
42611
  assert: budget.assert,
42271
- remainingMs: () => budget.remainingWork()
42612
+ remainingMs: budget.remainingWork
42272
42613
  });
42273
42614
  try {
42274
42615
  budget.assert();
@@ -42348,7 +42689,7 @@ function registerPiContextHandler(pi, baseOptions) {
42348
42689
  if (options.autoSearch?.enabled && !options.compactionOff && result.prefixMutationAllowed && budget.remainingWork() > PI_CONTEXT_BUDGET.searchMs) {
42349
42690
  guardSqliteTransformPass2({
42350
42691
  assert: budget.assert,
42351
- remainingMs: () => budget.remainingWork()
42692
+ remainingMs: budget.remainingWork
42352
42693
  });
42353
42694
  try {
42354
42695
  outputMessages = await guardAwait(runAutoSearchHintForPi({
@@ -42408,7 +42749,7 @@ function registerPiContextHandler(pi, baseOptions) {
42408
42749
  hostEditBeforeNewestThinking = stickyBefore === null || [...stickyAfter].some((key) => !stickyBefore.has(key)) || JSON.stringify(getPersistedTodoSyntheticAnchor(options.db, sessionId)) !== todoAnchorBefore;
42409
42750
  } catch {}
42410
42751
  const outputEntryIds = resolvePiLkgOutputEntryIds(outputMessages, result.syntheticLeadingCount, (message) => result.lkgEntryIdByRef.get(message) ?? result.postCommitEntryIdByRef.get(message) ?? bindingEntryIdByRef.get(message)).map((entryId) => entryId ?? undefined);
42411
- const thinkingBindingRecoveryApplied = bindingStripOrder === "end" && !result.signedPrefixRewritten ? applyPiThinkingBindingRecovery({
42752
+ const thinkingBindingRecoveryApplied = bindingStripOrder === "end" && (!result.signedPrefixRewritten || !result.prefixBustPermitted) ? applyPiThinkingBindingRecovery({
42412
42753
  db: options.db,
42413
42754
  sessionId,
42414
42755
  messages: outputMessages,
@@ -42430,7 +42771,7 @@ function registerPiContextHandler(pi, baseOptions) {
42430
42771
  entryIds: outputEntryIds,
42431
42772
  provider: lkgProviderKey ?? undefined,
42432
42773
  model: ctx.model?.id,
42433
- cacheBustingPass: !!recovery.rebuildReason || result.signedPrefixRewritten || result.prefixBustPermitted && !result.strictThinkingKept && (isCacheBusting || result.prefixRebuildAlreadyPriced || result.executedWorkThisPass && (result.prefixEditBesidesReasoningTrim || hostEditBeforeNewestThinking)),
42774
+ cacheBustingPass: result.prefixBustPermitted && !result.strictThinkingKept && (result.signedPrefixRewritten || isCacheBusting || result.prefixRebuildAlreadyPriced || result.executedWorkThisPass && (result.prefixEditBesidesReasoningTrim || hostEditBeforeNewestThinking)),
42434
42775
  stripActiveTurn: result.signedPrefixRewritten,
42435
42776
  requirePersistence: !!recovery.rebuildReason,
42436
42777
  report: (line) => sessionLog2(sessionId, line)
@@ -42473,6 +42814,7 @@ function registerPiContextHandler(pi, baseOptions) {
42473
42814
  const previousBaseline = getPiChannel1Baseline(sessionId);
42474
42815
  const baseline = refreshPiTailHygieneBaseline({
42475
42816
  messages: outputMessages,
42817
+ providerApi: ctx.model?.api,
42476
42818
  tags,
42477
42819
  tagCacheKey: result.channelBaselineSnapshot.tagCacheKey,
42478
42820
  protectedTagNumbers,
@@ -42612,6 +42954,7 @@ function registerPiContextHandler(pi, baseOptions) {
42612
42954
  percentage: Math.max(95, pipelineArgs.contextUsage.percentage)
42613
42955
  }
42614
42956
  }));
42957
+ observePipelineResultForTests(sessionId, result);
42615
42958
  fitReclaimedThisPass = true;
42616
42959
  inputForFitReclaim = undefined;
42617
42960
  outputMessages = result.messages;
@@ -42623,7 +42966,7 @@ function registerPiContextHandler(pi, baseOptions) {
42623
42966
  entryIds: retryIds.map((id) => id ?? undefined),
42624
42967
  provider: ctx.model?.provider,
42625
42968
  model: ctx.model?.id,
42626
- cacheBustingPass: true,
42969
+ cacheBustingPass: result.prefixBustPermitted,
42627
42970
  stripActiveTurn: true
42628
42971
  });
42629
42972
  estimate = estimatePiOutgoingInputTokens(outputMessages, envelope, undefined, rawFallbackLimit);
@@ -42724,6 +43067,7 @@ function registerPiContextHandler(pi, baseOptions) {
42724
43067
  }
42725
43068
  }));
42726
43069
  outputMessages = result.messages;
43070
+ observePipelineResultForTests(sessionId, result);
42727
43071
  injectTodo();
42728
43072
  if (upperCursor)
42729
43073
  recordPiUpperEstimateReclaim(options.db, currentUpperCursor() ?? upperCursor, reservation);
@@ -42735,7 +43079,7 @@ function registerPiContextHandler(pi, baseOptions) {
42735
43079
  entryIds: resolvePiLkgOutputEntryIds(outputMessages, result.syntheticLeadingCount, (message) => result.lkgEntryIdByRef.get(message) ?? result.postCommitEntryIdByRef.get(message)).map((id) => id ?? undefined),
42736
43080
  provider: ctx.model?.provider,
42737
43081
  model: ctx.model?.id,
42738
- cacheBustingPass: result.bustedThisPass,
43082
+ cacheBustingPass: result.prefixBustPermitted,
42739
43083
  stripActiveTurn: result.signedPrefixRewritten
42740
43084
  });
42741
43085
  estimate = estimatePiOutgoingInputTokens(outputMessages, envelope, undefined, outgoingFitLimit);
@@ -42758,7 +43102,7 @@ function registerPiContextHandler(pi, baseOptions) {
42758
43102
  budget.assertOutcome();
42759
43103
  guardSqliteTransformPass2({
42760
43104
  assert: budget.assertOutcome,
42761
- remainingMs: () => Math.max(0, PI_CONTEXT_BUDGET.outcomeMs - budget.elapsed())
43105
+ remainingMs: budget.remainingOutcome
42762
43106
  });
42763
43107
  if (!budget.sideTurn && !lkgCompactionOff && lkgPassSnapshot && (rawMessageCount > 0 || result.servedTagNumbers?.size)) {
42764
43108
  let hostEnvelopeSignature;
@@ -43027,7 +43371,7 @@ function resolveHistoryBudgetTokensForPi(args) {
43027
43371
  }) / 100) * historyBudgetPercentage);
43028
43372
  }
43029
43373
  function startPiCompartmentLeaseRenewal(db, sessionId, holderId) {
43030
- return setInterval(() => {
43374
+ return inRootAsyncContext2(() => setInterval(() => {
43031
43375
  try {
43032
43376
  if (!renewCompartmentLease(db, sessionId, holderId)) {
43033
43377
  sessionLog2(sessionId, "compartment lease renewal failed; publish will be skipped if holder is stale");
@@ -43035,7 +43379,7 @@ function startPiCompartmentLeaseRenewal(db, sessionId, holderId) {
43035
43379
  } catch (err) {
43036
43380
  sessionLog2(sessionId, `compartment lease renewal threw; publish will be skipped if holder is stale (${err instanceof Error ? err.message : String(err)})`);
43037
43381
  }
43038
- }, COMPARTMENT_LEASE_RENEWAL_MS);
43382
+ }, COMPARTMENT_LEASE_RENEWAL_MS));
43039
43383
  }
43040
43384
  function ensureRunnablePiBoundaryForTests(snapshot) {
43041
43385
  if (true) {
@@ -43095,7 +43439,7 @@ function spawnPiHistorianRun(args) {
43095
43439
  const holderId = crypto3.randomUUID();
43096
43440
  const controller = new AbortController;
43097
43441
  historianAbortControllers.set(sessionId, controller);
43098
- const runPromise = withoutSqliteTransformPass2(() => (async () => {
43442
+ const runPromise = inRootAsyncContext2(() => (async () => {
43099
43443
  await new Promise((resolve) => setTimeout(resolve, 0));
43100
43444
  if (controller.signal.aborted)
43101
43445
  return;
@@ -43607,29 +43951,37 @@ async function runPipeline(args) {
43607
43951
  let activeThinkingTurn = hasActiveAnthropicThinkingTurn(args.messages, args.resolvedProviderID, args.resolvedModelID);
43608
43952
  let protectedSignedPrefix = activeThinkingTurn && args.reasoningClearing?.prefixBound === true;
43609
43953
  let rewritingSignedPrefix = false;
43954
+ let isCacheBustingPass = args.recoveryRebuildReason === "lkg_recovery_input_rebuild" || (!!args.recoveryRebuildReason || args.forceSignedRebuildForFit === true) && hasUnfrozenPiThinking({
43955
+ messages: args.messages,
43956
+ entryIds: args.messages.map((message, index) => args.lkgEntryIds?.[index] ?? resolvePiRealStableId(message, index, args.entryIds, args.entryIdByRef ?? undefined)),
43957
+ frozen: frozenBindingEntryIds(args.db, args.sessionId),
43958
+ provider: args.resolvedProviderID,
43959
+ model: args.resolvedModelID
43960
+ });
43610
43961
  let workingForRewrite;
43611
- const stripForPrefixRewrite = () => {
43962
+ const stripForPrefixRewrite = (permitRewrite = true) => {
43963
+ isCacheBustingPass ||= permitRewrite;
43612
43964
  const messages = workingForRewrite ?? args.messages;
43613
43965
  const result = applyPiProactiveThinkingStrip({
43614
43966
  db: args.db,
43615
43967
  sessionId: args.sessionId,
43616
43968
  messages,
43617
- entryIds: messages.map((message, index) => resolvePiStableId(message, index, args.entryIds, args.entryIdByRef ?? undefined)),
43969
+ entryIds: messages.map((message, index) => args.lkgEntryIds?.[index] ?? resolvePiRealStableId(message, index, args.entryIds, args.entryIdByRef ?? undefined)),
43618
43970
  provider: args.resolvedProviderID,
43619
43971
  model: args.resolvedModelID,
43620
- cacheBustingPass: true,
43972
+ cacheBustingPass: isCacheBustingPass,
43621
43973
  stripActiveTurn: true,
43622
43974
  persistOnly: true,
43623
43975
  requirePersistence: !!args.recoveryRebuildReason
43624
43976
  });
43625
- if (activeThinkingTurn && !result)
43977
+ if (activeThinkingTurn && isCacheBustingPass && !result)
43626
43978
  throw new Error("Cannot persist signed thinking omission before prefix rewrite");
43627
43979
  rewritingSignedPrefix = true;
43628
43980
  activeThinkingTurn = false;
43629
43981
  protectedSignedPrefix = false;
43630
43982
  };
43631
43983
  if (args.recoveryRebuildReason || args.forceSignedRebuildForFit && protectedSignedPrefix)
43632
- stripForPrefixRewrite();
43984
+ stripForPrefixRewrite(isCacheBustingPass);
43633
43985
  const realStableId = (msg, index) => resolvePiRealStableId(msg, index, args.entryIds, args.entryIdByRef ?? undefined);
43634
43986
  const passFallbackIds = settlePiFallbackOccurrences(args.db, args.sessionId, piContentFallbackIds(args.messages, realStableId));
43635
43987
  const stableIdResolver = (msg, index) => realStableId(msg, index) ?? passFallbackIds[index] ?? resolvePiStableId(msg, index);
@@ -43864,13 +44216,13 @@ async function runPipeline(args) {
43864
44216
  const heldIdleExpiryRebuild = protectedSignedPrefix && piHardSignals?.cacheExpired === true;
43865
44217
  const rideSignals = {
43866
44218
  subagentExecute: args.sessionMeta.isSubagent && args.schedulerDecision === "execute",
43867
- hardFold: foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild,
44219
+ hardFold: foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || isCacheBustingPass,
43868
44220
  force: (args.forceMaterialization === true || emergencyDropEligible) && (args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0),
43869
44221
  explicitFlush: hasPendingMaterializeSignal || deferredMaterializeEligible && !prefixPreflightContended,
43870
44222
  publishedHistory: !prefixPreflightContended && (args.isCacheBusting || publishedM1RefreshedThisPass || canConsumeDeferredLate && deferredHistoryWasPendingAtPassStart)
43871
44223
  };
43872
44224
  let prefixMutationAllowed = !protectedSignedPrefix || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible;
43873
- let isCacheBustingPass = prefixMutationAllowed && hasReclaimRide(rideSignals);
44225
+ isCacheBustingPass = prefixMutationAllowed && hasReclaimRide(rideSignals);
43874
44226
  let publishedWorkDrainAllowed = isCacheBustingPass;
43875
44227
  const usesTokenProtection = args.protectedTokenTierOverrides !== undefined || args.protectedTokens !== undefined;
43876
44228
  const resolveProtectionFloor = () => resolveEpochFloorForPass(args.db, args.sessionId, {
@@ -43881,7 +44233,7 @@ async function runPipeline(args) {
43881
44233
  onRejectedProjectOverride: (warning) => sessionLog2(args.sessionId, warning)
43882
44234
  });
43883
44235
  let protectionFloorResolution = resolveProtectionFloor();
43884
- let shouldRunHeuristics = args.heuristics !== undefined && isCacheBustingPass && (rideSignals.publishedHistory || args.forceMaterialization === true || hasPendingMaterializeSignal || deferredMaterializeEligible || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || rideSignals.subagentExecute || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
44236
+ let shouldRunHeuristics = args.heuristics !== undefined && isCacheBustingPass && (rideSignals.publishedHistory || args.forceMaterialization === true || hasPendingMaterializeSignal || deferredMaterializeEligible || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || args.recoveryRebuildReason !== undefined && isCacheBustingPass || rideSignals.subagentExecute || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
43885
44237
  let unavoidableCarriedIdentityRebuild = false;
43886
44238
  if (protectedSignedPrefix && readPiIdentityRebuilds(args.db, args.sessionId).length > 0) {
43887
44239
  args.tryReplayHeldIdentityRebuild?.();
@@ -44114,6 +44466,7 @@ async function runPipeline(args) {
44114
44466
  const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
44115
44467
  const shouldReadPendingOps = !args.compactionOff && (publishedWorkDrainAllowed || args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass || firstRenderBust);
44116
44468
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
44469
+ const reclaimDistance = isCacheBustingPass ? toolReclaimDistanceEntries(mutationView, targets) : [];
44117
44470
  const protectedToolTags = protectedToolTagNumbers(getActiveTagsBySession2(args.db, args.sessionId), args.protectedTools);
44118
44471
  for (const number of identityAdoption.protectedTagNumbers)
44119
44472
  protectedToolTags.add(number);
@@ -44428,6 +44781,7 @@ async function runPipeline(args) {
44428
44781
  }
44429
44782
  }
44430
44783
  const editReclaim = buildEditSupersessionReclaim({
44784
+ watermark: reclaimMeta.toolReclaimWatermark ?? 0,
44431
44785
  db: args.db,
44432
44786
  sessionId: args.sessionId,
44433
44787
  targets: newTargets,
@@ -44555,7 +44909,7 @@ async function runPipeline(args) {
44555
44909
  setEmergencyDropSample(args.db, args.sessionId, args.contextUsage.inputTokens);
44556
44910
  }
44557
44911
  if (toolReclaimApplicationOpportunity) {
44558
- advanceToolReclaimWatermarkToCurrentMax(args.db, args.sessionId);
44912
+ advanceToolReclaimWatermarkByDistance(args.db, args.sessionId, reclaimDistance, args.reclaimUsableWindow ?? 0);
44559
44913
  }
44560
44914
  if (autoReclaimTargetCount > 0) {
44561
44915
  sessionLog2(args.sessionId, `tool reclaim auto-drop: targets=${autoReclaimTargetCount} mutated=${autoReclaimDidMutate}`);
@@ -44855,7 +45209,7 @@ async function runPipeline(args) {
44855
45209
  prefixMutationAllowed,
44856
45210
  strictThinkingKept: protectedSignedPrefix,
44857
45211
  signedPrefixRewritten: rewritingSignedPrefix,
44858
- prefixRebuildAlreadyPriced: firstRenderBust || heldIdleExpiryRebuild,
45212
+ prefixRebuildAlreadyPriced: firstRenderBust || heldIdleExpiryRebuild || !!args.recoveryRebuildReason && isCacheBustingPass,
44859
45213
  identityRebuilt: identityRebuild,
44860
45214
  servedTagNumbers,
44861
45215
  heuristicsExecuted,
@@ -45246,6 +45600,7 @@ function createPiHistorianClient(args) {
45246
45600
  model: modelOverride?.model ?? args.model,
45247
45601
  fallbackModels: modelOverride ? undefined : args.fallbackModels,
45248
45602
  timeoutMs: args.timeoutMs,
45603
+ maxOutputTokens: args.maxOutputTokens,
45249
45604
  cwd: args.directory,
45250
45605
  thinkingLevel: modelOverride ? modelOverride.qualifier : args.thinkingLevel,
45251
45606
  accountingSessionId: args.accountingSessionId,
@@ -45660,6 +46015,7 @@ Recomp started. Rebuilding the compressed history from raw session history now;
45660
46015
  systemPrompt: withContentLanguageDirective(COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, currentDeps.language, { preserveUserQuotes: true }),
45661
46016
  fallbackModels: currentDeps.historianFallbacks,
45662
46017
  timeoutMs: currentDeps.historianTimeoutMs,
46018
+ maxOutputTokens: currentDeps.historianMaxOutputTokens,
45663
46019
  thinkingLevel: currentDeps.historianThinkingLevel,
45664
46020
  directory: cwd,
45665
46021
  accountingSessionId: sessionId,
@@ -46073,7 +46429,7 @@ function formatThresholdPercent(value) {
46073
46429
  }
46074
46430
 
46075
46431
  // ../plugin/src/shared/status-view-check.ts
46076
- function isRecord5(value) {
46432
+ function isRecord6(value) {
46077
46433
  return typeof value === "object" && value !== null && !Array.isArray(value);
46078
46434
  }
46079
46435
  function isNumber(value) {
@@ -46151,28 +46507,28 @@ class OptionalFields {
46151
46507
  }
46152
46508
  }
46153
46509
  function isWindowGeometry(value) {
46154
- if (!isRecord5(value) || !isNumber(value.usableSoft) || !isRecord5(value.derivation))
46510
+ if (!isRecord6(value) || !isNumber(value.usableSoft) || !isRecord6(value.derivation))
46155
46511
  return false;
46156
46512
  const derivation = value.derivation;
46157
46513
  return isNumber(derivation.window) && isNumber(derivation.reserve) && isString(derivation.reserveSource);
46158
46514
  }
46159
46515
  function isTailHygiene(value) {
46160
- return isRecord5(value) && isNumber(value.u) && isNumber(value.t) && isNumber(value.severity) && isBoolean(value.evaluable);
46516
+ return isRecord6(value) && isNumber(value.u) && isNumber(value.t) && isNumber(value.severity) && isBoolean(value.evaluable);
46161
46517
  }
46162
46518
  function isCompactionMarker(value) {
46163
- return isRecord5(value) && (value.code === null || value.code === "MC-C11") && isNumber(value.attempts) && (value.lastError === null || isString(value.lastError));
46519
+ return isRecord6(value) && (value.code === null || value.code === "MC-C11") && isNumber(value.attempts) && (value.lastError === null || isString(value.lastError));
46164
46520
  }
46165
46521
  function isTickFailure(value) {
46166
- return isRecord5(value) && isString(value.stage) && isNumber(value.at);
46522
+ return isRecord6(value) && isString(value.stage) && isNumber(value.at);
46167
46523
  }
46168
46524
  function isConfigParseFailure(value) {
46169
- return isRecord5(value);
46525
+ return isRecord6(value);
46170
46526
  }
46171
46527
  function isConfigReloadFailure(value) {
46172
- return isRecord5(value) && isString(value.path) && isString(value.message);
46528
+ return isRecord6(value) && isString(value.path) && isString(value.message);
46173
46529
  }
46174
46530
  function isUnconfirmedMigrationHolders(value) {
46175
- return isRecord5(value) && Array.isArray(value.pids) && value.pids.every(isNumber) && isNumber(value.fromVersion) && isNumber(value.toVersion);
46531
+ return isRecord6(value) && Array.isArray(value.pids) && value.pids.every(isNumber) && isNumber(value.fromVersion) && isNumber(value.toVersion);
46176
46532
  }
46177
46533
  function isNullableNumber(value) {
46178
46534
  return value === null || isNumber(value);
@@ -46184,7 +46540,7 @@ function isCacheTtlSource(value) {
46184
46540
  return isString(value);
46185
46541
  }
46186
46542
  function checkStatusViewSource(candidate) {
46187
- if (!isRecord5(candidate))
46543
+ if (!isRecord6(candidate))
46188
46544
  return { ok: false, fields: ["(the payload is not an object)"] };
46189
46545
  const missing = [];
46190
46546
  const numbers = {};
@@ -46223,7 +46579,7 @@ function checkStatusViewSource(candidate) {
46223
46579
  lastDreamerRunAt: optional.read("lastDreamerRunAt", isNullableNumber),
46224
46580
  dreamerUnsupportedTasks: optional.readArray("dreamerUnsupportedTasks", isString),
46225
46581
  dreamerSkipped: optional.readArray("dreamerSkipped", isString),
46226
- dreamerFailures: optional.readArray("dreamerFailures", (value) => isRecord5(value) && isString(value.task) && isString(value.error)),
46582
+ dreamerFailures: optional.readArray("dreamerFailures", (value) => isRecord6(value) && isString(value.task) && isString(value.error)),
46227
46583
  dreamerTickFailure: optional.read("dreamerTickFailure", (value) => value === null || isTickFailure(value)),
46228
46584
  sessionNoteCount: optional.read("sessionNoteCount", isNumber),
46229
46585
  readySmartNoteCount: optional.read("readySmartNoteCount", isNumber),
@@ -46885,14 +47241,14 @@ class StatusDialogComponent {
46885
47241
  this.detailRefresh = new PiStatusDetailRefresh(props.pi, props.ctx, props.deps, props.sessionId);
46886
47242
  this.detail = this.detailRefresh.refresh();
46887
47243
  openStatusDialogs.add(this);
46888
- this.refreshTimer = setInterval(() => {
47244
+ this.refreshTimer = inRootAsyncContext2(() => setInterval(() => {
46889
47245
  if (this.closed)
46890
47246
  return;
46891
47247
  try {
46892
47248
  this.detail = this.detailRefresh.refresh();
46893
47249
  this.props.tui.requestRender();
46894
47250
  } catch {}
46895
- }, REFRESH_INTERVAL_MS);
47251
+ }, REFRESH_INTERVAL_MS));
46896
47252
  }
46897
47253
  handleInput(data) {
46898
47254
  if (this.closed)
@@ -47807,7 +48163,7 @@ No runnable wrapup boundary is available yet; wrapped up 0 messages into 0 compa
47807
48163
  }
47808
48164
  return true;
47809
48165
  };
47810
- const renewal = setInterval(() => {
48166
+ const renewal = inRootAsyncContext2(() => setInterval(() => {
47811
48167
  try {
47812
48168
  renewWrapupMarker({
47813
48169
  lastCompartmentEnd: getLastCompartmentEndMessage(deps.db, sessionId)
@@ -47815,7 +48171,7 @@ No runnable wrapup boundary is available yet; wrapped up 0 messages into 0 compa
47815
48171
  } catch (err) {
47816
48172
  sessionLog2(sessionId, `[pi] /ctx-wrapup marker renewal failed: ${err instanceof Error ? err.message : String(err)}`);
47817
48173
  }
47818
- }, 60000);
48174
+ }, 60000));
47819
48175
  const stopRenewal = () => clearInterval(renewal);
47820
48176
  deps.shutdownSignal?.addEventListener("abort", stopRenewal, { once: true });
47821
48177
  try {
@@ -47890,13 +48246,13 @@ Chunk ${chunkIndex}: wrapping messages ${plan.snapshot.offset}-${plan.snapshot.e
47890
48246
  break;
47891
48247
  }
47892
48248
  const leaseHolder = leaseResult.holderId;
47893
- const leaseRenewal = setInterval(() => {
48249
+ const leaseRenewal = inRootAsyncContext2(() => setInterval(() => {
47894
48250
  try {
47895
48251
  renewCompartmentLease(deps.db, sessionId, leaseHolder);
47896
48252
  } catch (err) {
47897
48253
  sessionLog2(sessionId, `[pi] /ctx-wrapup compartment lease renewal failed: ${err instanceof Error ? err.message : String(err)}`);
47898
48254
  }
47899
- }, COMPARTMENT_LEASE_RENEWAL_MS);
48255
+ }, COMPARTMENT_LEASE_RENEWAL_MS));
47900
48256
  const stopLeaseRenewal = () => clearInterval(leaseRenewal);
47901
48257
  deps.shutdownSignal?.addEventListener("abort", stopLeaseRenewal, {
47902
48258
  once: true
@@ -47930,6 +48286,7 @@ Chunk ${chunkIndex}: wrapping messages ${plan.snapshot.offset}-${plan.snapshot.e
47930
48286
  }).snapshot,
47931
48287
  currentContextLimit: contextLimit,
47932
48288
  historianTimeoutMs: deps.historianTimeoutMs,
48289
+ maxOutputTokens: deps.historianMaxOutputTokens,
47933
48290
  thinkingLevel: deps.historianThinkingLevel,
47934
48291
  memoryEnabled: deps.memoryEnabled,
47935
48292
  autoPromote: deps.autoPromote,
@@ -48283,6 +48640,18 @@ async function bootPiRuntimeWithDeadline(args) {
48283
48640
  return { status: "timed_out", lateAdoption };
48284
48641
  }
48285
48642
 
48643
+ // src/pi-historian-command-options.ts
48644
+ function buildPiHistorianCommandOptions(historian, config) {
48645
+ return {
48646
+ historianModel: historian?.model,
48647
+ historianChunkTokens: historian?.historianChunkTokens ?? deriveHistorianChunkTokens(resolveHistorianContextLimit(historian?.model)),
48648
+ historianFallbacks: historian?.fallbackModels,
48649
+ historianTimeoutMs: historian?.timeoutMs ?? config.historian_timeout_ms,
48650
+ historianMaxOutputTokens: historian?.maxOutputTokens,
48651
+ historianThinkingLevel: historian?.thinkingLevel
48652
+ };
48653
+ }
48654
+
48286
48655
  // src/stale-build-notice.ts
48287
48656
  function bindStaleBuildNotice(ctx, moduleUrl) {
48288
48657
  registerStalePluginBuildHost({
@@ -49412,11 +49781,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
49412
49781
  registerCtxRecompCommand(pi, {
49413
49782
  db,
49414
49783
  runner: recompRunner,
49415
- historianModel: bootProjectDeps.historianConfig?.model,
49416
- historianChunkTokens: deriveHistorianChunkTokens(resolveHistorianContextLimit(bootProjectDeps.historianConfig?.model)),
49417
- historianFallbacks: bootProjectDeps.historianConfig?.fallbackModels,
49418
- historianTimeoutMs: bootProjectDeps.config.historian_timeout_ms,
49419
- historianThinkingLevel: bootProjectDeps.historianConfig?.thinkingLevel,
49784
+ ...buildPiHistorianCommandOptions(bootProjectDeps.historianConfig, bootProjectDeps.config),
49420
49785
  language: bootProjectDeps.config.language,
49421
49786
  memoryEnabled: bootProjectDeps.config.memory.enabled,
49422
49787
  autoPromote: bootProjectDeps.config.memory.auto_promote,
@@ -49428,11 +49793,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
49428
49793
  return {
49429
49794
  db,
49430
49795
  runner: recompRunner,
49431
- historianModel: historian?.model,
49432
- historianChunkTokens: historian?.historianChunkTokens ?? deriveHistorianChunkTokens(resolveHistorianContextLimit(historian?.model)),
49433
- historianFallbacks: historian?.fallbackModels,
49434
- historianTimeoutMs: historian?.timeoutMs ?? current.config.historian_timeout_ms,
49435
- historianThinkingLevel: historian?.thinkingLevel,
49796
+ ...buildPiHistorianCommandOptions(historian, current.config),
49436
49797
  language: current.config.language,
49437
49798
  memoryEnabled: current.config.memory.enabled,
49438
49799
  autoPromote: fresh.memory.auto_promote,
@@ -49445,11 +49806,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
49445
49806
  shutdownSignal: commandLifecycleController.signal,
49446
49807
  db,
49447
49808
  runner: wrapupRunner,
49448
- historianModel: bootProjectDeps.historianConfig?.model,
49449
- historianChunkTokens: deriveHistorianChunkTokens(resolveHistorianContextLimit(bootProjectDeps.historianConfig?.model)),
49450
- historianFallbacks: bootProjectDeps.historianConfig?.fallbackModels,
49451
- historianTimeoutMs: bootProjectDeps.config.historian_timeout_ms,
49452
- historianThinkingLevel: bootProjectDeps.historianConfig?.thinkingLevel,
49809
+ ...buildPiHistorianCommandOptions(bootProjectDeps.historianConfig, bootProjectDeps.config),
49453
49810
  language: bootProjectDeps.config.language,
49454
49811
  memoryEnabled: bootProjectDeps.config.memory.enabled,
49455
49812
  autoPromote: bootProjectDeps.config.memory.auto_promote,
@@ -49464,11 +49821,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
49464
49821
  return {
49465
49822
  db,
49466
49823
  runner: wrapupRunner,
49467
- historianModel: historian?.model,
49468
- historianChunkTokens: historian?.historianChunkTokens ?? deriveHistorianChunkTokens(resolveHistorianContextLimit(historian?.model)),
49469
- historianFallbacks: historian?.fallbackModels,
49470
- historianTimeoutMs: historian?.timeoutMs ?? current.config.historian_timeout_ms,
49471
- historianThinkingLevel: historian?.thinkingLevel,
49824
+ ...buildPiHistorianCommandOptions(historian, current.config),
49472
49825
  language: current.config.language,
49473
49826
  memoryEnabled: current.config.memory.enabled,
49474
49827
  autoPromote: fresh.memory.auto_promote,