@cortexkit/pi-magic-context 0.49.0 → 0.49.1

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 (31) hide show
  1. package/dist/auto-search-worker.js +3 -3
  2. package/dist/{embedding-backfill-b71dvfs8.js → embedding-backfill-scywarbn.js} +7 -7
  3. package/dist/embedding-worker-process.js +29 -0
  4. package/dist/embedding-worker.js +5 -5
  5. package/dist/index-0j0zqb4t.js +712 -0
  6. package/dist/{index-hwqb3s7f.js → index-0rasmwm8.js} +5 -5
  7. package/dist/{index-bejpsj10.js → index-27jh224p.js} +1 -1
  8. package/dist/{index-ehybv5nr.js → index-28vnkyy7.js} +1129 -2990
  9. package/dist/{index-r024r8da.js → index-4gfq5t09.js} +16 -1
  10. package/dist/{index-vf38qhee.js → index-81nthk8j.js} +44 -1
  11. package/dist/{index-yzcjxnt2.js → index-b2anqqad.js} +422 -6
  12. package/dist/{index-1evzceyw.js → index-cyrnv16r.js} +314 -1072
  13. package/dist/index-fqb1bddn.js +4947 -0
  14. package/dist/{index-041ex0cj.js → index-g7hndmqm.js} +20 -34
  15. package/dist/index-gc2749rx.js +1168 -0
  16. package/dist/{index-t7xfqtg6.js → index-p5zesr4e.js} +22 -718
  17. package/dist/{index-yarjn32j.js → index-r874cgmv.js} +38 -36
  18. package/dist/{index-3mgf68pn.js → index-rd53pk0h.js} +1 -1
  19. package/dist/{index-904reqtg.js → index-rdtgp48t.js} +6 -4
  20. package/dist/index.js +1159 -1126
  21. package/dist/{message-index-bounded-qz5dz2se.js → message-index-bounded-110sb4fm.js} +6 -5
  22. package/dist/migration-worker.js +6 -5
  23. package/dist/{project-embedding-registry-ky7wrkr1.js → project-embedding-registry-64t0mw8y.js} +6 -6
  24. package/dist/raw-ordinal-warmup-worker.js +1 -1
  25. package/dist/{read-session-chunk-24sd89tf.js → read-session-chunk-rvmc25n5.js} +3 -2
  26. package/dist/{search-jbh28nwy.js → search-7z3w8pmz.js} +15 -14
  27. package/dist/subagent-entry.js +17 -16
  28. package/package.json +3 -3
  29. package/dist/index-3rea6zd9.js +0 -2396
  30. package/dist/index-bgmv2kaf.js +0 -290
  31. /package/dist/{index-5prbx026.js → index-2pp04pmg.js} +0 -0
package/dist/index.js CHANGED
@@ -27,9 +27,6 @@ import {
27
27
  detectConfigFile,
28
28
  MIN_PLAUSIBLE_CONTEXT_LIMIT,
29
29
  catalogOutputReserve,
30
- reloadWindowOverlay,
31
- getWindowOverlay,
32
- resolveWindowOverlayFacts,
33
30
  deriveWindowGeometry,
34
31
  hasTrustedAbsoluteWall,
35
32
  applyProvenInputFloor,
@@ -45,101 +42,6 @@ import {
45
42
  cortexKitProjectConfigBasePath,
46
43
  migrateMagicContextConfigLocations,
47
44
  getProtectedTokensTierOverrides,
48
- MAX_EXECUTE_THRESHOLD,
49
- escalationBands,
50
- decodeMergedReasoningParts,
51
- HYGIENE_PROVIDER_UNITS_VERSION,
52
- sessionDecisionCalibration,
53
- transitionSessionHygieneUnits,
54
- computeProtectionWindow,
55
- readEpochFloorSnapshot,
56
- getProtectionWindowForSession,
57
- ensureSessionMetaRow,
58
- persistCachedM0,
59
- clearCachedM0M1,
60
- isRustMarkerAdmissionFenced,
61
- ReplayDocumentError,
62
- readReplayEnvelope,
63
- updateReplayDocument,
64
- isProviderOverflowFailClosedProven,
65
- describeProtectedTailDrainBudgetSkip,
66
- loadProtectedTailMeta,
67
- markProtectedTailPolicyV3Seeded,
68
- recordProtectedTailPublicationFloor,
69
- recordProtectedTailNoEligibleHead,
70
- getWrapupInProgressState,
71
- isWrapupInProgress,
72
- acquireWrapupInProgress,
73
- updateWrapupInProgress,
74
- releaseWrapupInProgress,
75
- resolveCompactionModeRecord,
76
- getCompactionModeRecord,
77
- setCompactionModeRecord,
78
- getProtectedTailDrainBudgetSkip,
79
- reserveProtectedTailDrainTokens,
80
- clearEmergencyDrainLatch,
81
- recordHistorianDrainFailure,
82
- clearHistorianDrainFailure,
83
- rollbackProtectedTailDrainReservation,
84
- clearPersistedReasoningWatermark,
85
- getEmergencyInputSample,
86
- setEmergencyDropSample,
87
- clearEmergencyDropSample,
88
- getLastNudgeUndropped,
89
- setLastNudgeUndropped,
90
- getChannel1NudgeState,
91
- setChannel1NudgeState,
92
- markChannel1PostReduceGracePending,
93
- captureChannel1PostReduceGraceBaseline,
94
- getChannel2NudgeState,
95
- getChannel2NudgeClaim,
96
- setChannel2NudgeState,
97
- casChannel2NudgeState,
98
- claimChannel2NudgeState,
99
- casChannel2NudgeClaim,
100
- getPersistedNoteNudge,
101
- setPersistedNoteNudgeTrigger,
102
- setPersistedNoteNudgeTriggerMessageId,
103
- getNoteNudgeAnchors,
104
- getAutoSearchHintDecisions,
105
- deliverNoteNudgeAtomic,
106
- appendAutoSearchHintDecision,
107
- pruneNoteNudgeAnchors,
108
- queueAutoSearchHintDecisionRetirement,
109
- flushAutoSearchHintDecisionRetirement,
110
- getPersistedTodoSyntheticAnchor,
111
- setPersistedTodoSyntheticAnchor,
112
- clearPersistedTodoSyntheticAnchor,
113
- getNoteLastReadAt,
114
- getHistorianFailureState,
115
- incrementHistorianFailure,
116
- clearHistorianFailureState,
117
- getOverflowState,
118
- recordOverflowDetected,
119
- clearEmergencyRecovery,
120
- clearDetectedContextLimit,
121
- getStrippedPlaceholderIds,
122
- applyStrippedPlaceholderDelta,
123
- THINKING_BINDING_RECOVERY_FROZEN_PREFIX,
124
- THINKING_BINDING_STRIP_ORDER_END_MARKER,
125
- thinkingBindingRecoveryFrozenId,
126
- getThinkingBindingRecoveryTarget,
127
- armThinkingBindingRecovery,
128
- clearThinkingBindingRecoveryIf,
129
- getMergedReasoningStrippedIds,
130
- addMergedReasoningStrippedIds,
131
- getProcessedImageStrippedIds,
132
- addProcessedImageStrippedIds,
133
- getPendingCompactionMarkerState,
134
- getCompactionMarkerHealth,
135
- clearPendingCompactionMarkerStateIf,
136
- getPendingPiCompactionMarkerState,
137
- setPendingPiCompactionMarkerState,
138
- clearPendingPiCompactionMarkerStateIf,
139
- getSessionsWithPendingPiMarker,
140
- setSessionWorkMetrics,
141
- getSessionWorkMetrics,
142
- resolveEpochFloorForPass,
143
45
  rememberUnpublishedAutoSearchNoHint,
144
46
  getUnpublishedAutoSearchNoHint,
145
47
  forgetUnpublishedAutoSearchNoHint,
@@ -182,9 +84,23 @@ import {
182
84
  getUncoveredCompartmentEndThrough,
183
85
  isPartialCompartmentEnd,
184
86
  readProjectDocsCanonical,
185
- BoundedSessionMap,
186
87
  providerResponseFailed,
187
88
  isSuccessfulProviderCompletion,
89
+ requestPendingMaterialization,
90
+ pendingMaterializationOrigin,
91
+ clearPendingMaterialization,
92
+ recordSystemRefreshOwnership,
93
+ recordSystemPromptForRequest,
94
+ recordHeldHeadForRequest,
95
+ bindSystemPromptResponse,
96
+ acknowledgeSystemPromptDelivery,
97
+ deferDeliveredSystemRefresh,
98
+ clearSystemPromptDelivery,
99
+ saveLkgSlotToDb,
100
+ loadPersistedLkgSlot,
101
+ drainStaleLkgSlots,
102
+ createDbLkgPersistence,
103
+ replayLkg,
188
104
  registerLkgPersistence,
189
105
  LKG_SNAPSHOT_ARRAY,
190
106
  LKG_SNAPSHOT_OBJECT,
@@ -208,7 +124,6 @@ import {
208
124
  getInMemorySlot,
209
125
  getSlot,
210
126
  dropSlot,
211
- noteEntry,
212
127
  TOOL_SWEEP_SCOPED_MARKER,
213
128
  encodePiContentDecision,
214
129
  decodePiContentDecision,
@@ -331,8 +246,14 @@ import {
331
246
  registerTodoStateLifecycle,
332
247
  syncCtxMemoryToolEnabled,
333
248
  registerMagicContextTools
334
- } from "./index-ehybv5nr.js";
249
+ } from "./index-28vnkyy7.js";
335
250
  import {
251
+ canonicalModelIdentity,
252
+ piModelRefToCanonical,
253
+ resolveModelRefForPi,
254
+ modelRefLookupOrder,
255
+ ompModelRefToCanonical,
256
+ resolveModelRefForOmp,
336
257
  isValidLanguageCode,
337
258
  withContentLanguageDirective,
338
259
  parseCron,
@@ -342,15 +263,7 @@ import {
342
263
  DEFAULT_HISTORIAN_TIMEOUT_MS,
343
264
  DREAM_TASK_PROMOTION_DEFAULTS,
344
265
  LIVE_RELOAD_CONFIG_PATHS
345
- } from "./index-1evzceyw.js";
346
- import {
347
- canonicalModelIdentity,
348
- piModelRefToCanonical,
349
- resolveModelRefForPi,
350
- modelRefLookupOrder,
351
- ompModelRefToCanonical,
352
- resolveModelRefForOmp
353
- } from "./index-bgmv2kaf.js";
266
+ } from "./index-cyrnv16r.js";
354
267
  import {
355
268
  FAIL_CLOSED_DOCTOR_COMMAND,
356
269
  formatFailClosedBlockingMessage,
@@ -358,7 +271,6 @@ import {
358
271
  isFailClosedBlockingError,
359
272
  shouldBypassFailClosedBlock,
360
273
  createFailClosedController,
361
- piHarnessKindFromExecutable,
362
274
  getErrorMessage,
363
275
  describeError,
364
276
  startBootDeadline,
@@ -374,9 +286,8 @@ import {
374
286
  openCurrentDatabase,
375
287
  openDatabaseAsync,
376
288
  closeDatabase
377
- } from "./index-t7xfqtg6.js";
289
+ } from "./index-p5zesr4e.js";
378
290
  import {
379
- sameProjectDirectory,
380
291
  setHomeProjectPermission,
381
292
  ProjectIdentityError,
382
293
  resolveProjectIdentityStrict,
@@ -386,12 +297,106 @@ import {
386
297
  resolveProjectIdentityForSession,
387
298
  beginBootQuietPeriod,
388
299
  scheduleAfterBootQuiet
389
- } from "./index-041ex0cj.js";
300
+ } from "./index-g7hndmqm.js";
390
301
  import {
391
302
  detectThinkingBindingMismatch,
392
303
  detectLatestTurnThinkingMismatch,
393
304
  isPrefixBoundThinkingModel,
394
305
  detectOverflow,
306
+ MAX_EXECUTE_THRESHOLD,
307
+ escalationBands,
308
+ decodeMergedReasoningParts,
309
+ HYGIENE_PROVIDER_UNITS_VERSION,
310
+ sessionDecisionCalibration,
311
+ transitionSessionHygieneUnits,
312
+ computeProtectionWindow,
313
+ readEpochFloorSnapshot,
314
+ getProtectionWindowForSession,
315
+ ensureSessionMetaRow,
316
+ persistCachedM0,
317
+ clearCachedM0M1,
318
+ ReplayDocumentError,
319
+ readReplayEnvelope,
320
+ updateReplayDocument,
321
+ isProviderOverflowFailClosedProven,
322
+ describeProtectedTailDrainBudgetSkip,
323
+ loadProtectedTailMeta,
324
+ markProtectedTailPolicyV3Seeded,
325
+ recordProtectedTailPublicationFloor,
326
+ recordProtectedTailNoEligibleHead,
327
+ getWrapupInProgressState,
328
+ isWrapupInProgress,
329
+ acquireWrapupInProgress,
330
+ updateWrapupInProgress,
331
+ releaseWrapupInProgress,
332
+ resolveCompactionModeRecord,
333
+ getCompactionModeRecord,
334
+ setCompactionModeRecord,
335
+ getProtectedTailDrainBudgetSkip,
336
+ reserveProtectedTailDrainTokens,
337
+ clearEmergencyDrainLatch,
338
+ recordHistorianDrainFailure,
339
+ clearHistorianDrainFailure,
340
+ rollbackProtectedTailDrainReservation,
341
+ clearPersistedReasoningWatermark,
342
+ getEmergencyInputSample,
343
+ setEmergencyDropSample,
344
+ clearEmergencyDropSample,
345
+ getLastNudgeUndropped,
346
+ setLastNudgeUndropped,
347
+ getChannel1NudgeState,
348
+ setChannel1NudgeState,
349
+ markChannel1PostReduceGracePending,
350
+ captureChannel1PostReduceGraceBaseline,
351
+ getChannel2NudgeState,
352
+ getChannel2NudgeClaim,
353
+ setChannel2NudgeState,
354
+ casChannel2NudgeState,
355
+ claimChannel2NudgeState,
356
+ casChannel2NudgeClaim,
357
+ getPersistedNoteNudge,
358
+ setPersistedNoteNudgeTrigger,
359
+ setPersistedNoteNudgeTriggerMessageId,
360
+ getNoteNudgeAnchors,
361
+ getAutoSearchHintDecisions,
362
+ deliverNoteNudgeAtomic,
363
+ appendAutoSearchHintDecision,
364
+ pruneNoteNudgeAnchors,
365
+ queueAutoSearchHintDecisionRetirement,
366
+ flushAutoSearchHintDecisionRetirement,
367
+ getPersistedTodoSyntheticAnchor,
368
+ setPersistedTodoSyntheticAnchor,
369
+ clearPersistedTodoSyntheticAnchor,
370
+ getNoteLastReadAt,
371
+ getHistorianFailureState,
372
+ incrementHistorianFailure,
373
+ clearHistorianFailureState,
374
+ getOverflowState,
375
+ recordOverflowDetected,
376
+ clearEmergencyRecovery,
377
+ clearDetectedContextLimit,
378
+ getStrippedPlaceholderIds,
379
+ applyStrippedPlaceholderDelta,
380
+ THINKING_BINDING_RECOVERY_FROZEN_PREFIX,
381
+ THINKING_BINDING_STRIP_ORDER_END_MARKER,
382
+ thinkingBindingRecoveryFrozenId,
383
+ getThinkingBindingRecoveryTarget,
384
+ armThinkingBindingRecovery,
385
+ clearThinkingBindingRecoveryIf,
386
+ getMergedReasoningStrippedIds,
387
+ addMergedReasoningStrippedIds,
388
+ getProcessedImageStrippedIds,
389
+ addProcessedImageStrippedIds,
390
+ getPendingCompactionMarkerState,
391
+ getCompactionMarkerHealth,
392
+ clearPendingCompactionMarkerStateIf,
393
+ getPendingPiCompactionMarkerState,
394
+ setPendingPiCompactionMarkerState,
395
+ clearPendingPiCompactionMarkerStateIf,
396
+ getSessionsWithPendingPiMarker,
397
+ setSessionWorkMetrics,
398
+ getSessionWorkMetrics,
399
+ resolveEpochFloorForPass,
395
400
  retreatPastHostUnservedRows,
396
401
  completedToolArcCrossesBoundary,
397
402
  estimateTrueRawMessageTokens,
@@ -416,6 +421,16 @@ import {
416
421
  modelAcceptsEmptyContent,
417
422
  isAnthropicFamilyRoute,
418
423
  variantChangeBustsProviderCache,
424
+ isInActiveAnthropicTurn,
425
+ activeAnthropicTurnStart,
426
+ hasAnthropicReasoning,
427
+ findLatestAssistantReasoningMutationExemptMessage,
428
+ DEFAULT_KEEP_REASONING_TOKENS,
429
+ resolveKeepReasoningTokens,
430
+ reasoningStepCost,
431
+ reasoningBudgetCutoff,
432
+ reasoningTextAndOpaque,
433
+ opaqueThinkingCost,
419
434
  SKELETON_REAL_INPUT_MAX_BYTES,
420
435
  toolInputStringBytes,
421
436
  setRawMessageProvider2,
@@ -435,7 +450,7 @@ import {
435
450
  getRawSessionTagKeysThrough2,
436
451
  getLegacyProtectedTailStartOrdinal2,
437
452
  readSessionChunk2
438
- } from "./index-3rea6zd9.js";
453
+ } from "./index-fqb1bddn.js";
439
454
  import {
440
455
  UNKNOWN_FIT_RATIO,
441
456
  hasMeasuredDecisionCalibration,
@@ -567,20 +582,17 @@ import {
567
582
  RAW_SUMMARY_TEXT_MAX_CHARS2
568
583
  } from "./index-vakawmbc.js";
569
584
  import {
570
- formatSynapseLaneDescriptor
571
- } from "./index-21v1kfs7.js";
572
- import"./index-r024r8da.js";
573
- import {
574
- buildCanonicalChunkTextFromFts,
575
- buildCompartmentSummaryFallbackText,
576
- canonicalizeInMemoryChunkTextForEmbedding,
577
- chunkCanonicalText,
578
- chunkEmbeddingWindowsAreCurrent,
579
- replaceCompartmentChunkEmbeddings,
580
- deleteChunkEmbedBackoffForSession,
581
- chunkWindowSourceKey
582
- } from "./index-bejpsj10.js";
585
+ piHarnessKindFromExecutable
586
+ } from "./index-0j0zqb4t.js";
583
587
  import {
588
+ BoundedSessionMap,
589
+ LkgRecoveryFenceError,
590
+ clearLkgFenceProcessState,
591
+ lkgFenceRequiresRebuild,
592
+ lkgRecoveryFenceUnclean,
593
+ ownsLkgDirtyFence,
594
+ invalidateCleanLkgRecoveryFence,
595
+ markLkgRecoveryDirty,
584
596
  readSessionActivity,
585
597
  observeSessionActivity,
586
598
  backfillSessionActivity,
@@ -594,10 +606,25 @@ import {
594
606
  indexSingleMessage,
595
607
  indexMessagesAfterOrdinal,
596
608
  sweepOrphanedOpenCodeMessageIndexes
597
- } from "./index-yzcjxnt2.js";
609
+ } from "./index-b2anqqad.js";
610
+ import {
611
+ formatSynapseLaneDescriptor
612
+ } from "./index-21v1kfs7.js";
613
+ import {
614
+ sameProjectDirectory
615
+ } from "./index-4gfq5t09.js";
616
+ import {
617
+ buildCanonicalChunkTextFromFts,
618
+ buildCompartmentSummaryFallbackText,
619
+ canonicalizeInMemoryChunkTextForEmbedding,
620
+ chunkCanonicalText,
621
+ chunkEmbeddingWindowsAreCurrent,
622
+ replaceCompartmentChunkEmbeddings,
623
+ deleteChunkEmbedBackoffForSession,
624
+ chunkWindowSourceKey
625
+ } from "./index-27jh224p.js";
598
626
  import {
599
627
  recordSessionProjectIdentity,
600
- drainBackgroundBatches,
601
628
  GIT_SWEEP_LEASE_RENEWAL_MS,
602
629
  acquireGitSweepLease,
603
630
  renewGitSweepLease,
@@ -620,21 +647,19 @@ import {
620
647
  embedSessionCompartmentChunks2,
621
648
  getEmbeddingCoverageStatus2,
622
649
  getAutoEmbeddingSessionCoverage2
623
- } from "./index-yarjn32j.js";
650
+ } from "./index-r874cgmv.js";
624
651
  import {
625
652
  V2_MEMORY_CATEGORIES
626
653
  } from "./index-135e8hvg.js";
627
654
  import {
628
655
  unescapeXml,
629
656
  parseCompartmentOutput,
630
- layoutLkgPrefix,
631
- assembleLkgPrefix,
632
657
  resolveWorkspaceShareCategories,
633
658
  resolveWorkspaceIdentitySet,
634
659
  expandWorkspaceIdentitySetWithAliases,
635
660
  sourceNameForMemory,
636
661
  computeWorkspaceEpochFingerprint
637
- } from "./index-3mgf68pn.js";
662
+ } from "./index-rd53pk0h.js";
638
663
  import {
639
664
  configureContextDatabasePragmas2
640
665
  } from "./index-fapenpch.js";
@@ -684,7 +709,7 @@ import {
684
709
  normalizeVerificationFiles,
685
710
  indexCommitsForProject,
686
711
  embedUnembeddedCommits
687
- } from "./index-hwqb3s7f.js";
712
+ } from "./index-0rasmwm8.js";
688
713
  import {
689
714
  setEmbeddingSessionBusy2,
690
715
  isEmbeddingHostBusy2
@@ -715,9 +740,10 @@ import {
715
740
  import {
716
741
  pushNotification2
717
742
  } from "./index-q1yc6bs0.js";
743
+ import"./index-gc2749rx.js";
718
744
  import {
719
745
  cosineSimilarity
720
- } from "./index-904reqtg.js";
746
+ } from "./index-rdtgp48t.js";
721
747
  import {
722
748
  buildHiddenAgentRegistrations,
723
749
  logTemperatureDecision,
@@ -732,6 +758,9 @@ import {
732
758
  import {
733
759
  computeNormalizedHash
734
760
  } from "./index-9x1f96r8.js";
761
+ import {
762
+ normalizeProtectedToolName
763
+ } from "./index-674f6qs2.js";
735
764
  import {
736
765
  logSlowWriteTransaction,
737
766
  WriteTransactionSteps
@@ -741,10 +770,7 @@ import {
741
770
  ensureStorageDirectorySync,
742
771
  writeStorageFileSync,
743
772
  writeStorageFileAtomicSync
744
- } from "./index-vf38qhee.js";
745
- import {
746
- normalizeProtectedToolName
747
- } from "./index-674f6qs2.js";
773
+ } from "./index-81nthk8j.js";
748
774
 
749
775
  // src/index.ts
750
776
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
@@ -2573,6 +2599,24 @@ function shouldKeepSubagents() {
2573
2599
  return keepSubagents;
2574
2600
  }
2575
2601
 
2602
+ // ../plugin/src/standalone-plugin-marker.ts
2603
+ var markerSymbol = Symbol.for("cortexkit.standalone-plugins");
2604
+ function registerStandalonePluginMarker(version) {
2605
+ try {
2606
+ const globals = globalThis;
2607
+ let registry = globals[markerSymbol];
2608
+ if (registry === undefined) {
2609
+ registry = new Map;
2610
+ globals[markerSymbol] = registry;
2611
+ }
2612
+ registry.set("magic-context", { version });
2613
+ } catch (error) {
2614
+ try {
2615
+ log2("could not register the standalone plugin marker", error);
2616
+ } catch {}
2617
+ }
2618
+ }
2619
+
2576
2620
  // ../plugin/src/shared/host-stall-profiler.ts
2577
2621
  import * as path7 from "node:path";
2578
2622
 
@@ -3366,6 +3410,112 @@ function startHostStallProfilerSwitch() {
3366
3410
  log2("[magic-context] host stall profiler: could not start the enable-file switch", error);
3367
3411
  }
3368
3412
  }
3413
+ // package.json
3414
+ var package_default = {
3415
+ name: "@cortexkit/pi-magic-context",
3416
+ version: "0.49.1",
3417
+ type: "module",
3418
+ description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3419
+ main: "dist/index.js",
3420
+ license: "MIT",
3421
+ author: "ualtinok",
3422
+ keywords: [
3423
+ "pi",
3424
+ "pi-coding-agent",
3425
+ "omp",
3426
+ "oh-my-pi",
3427
+ "extension",
3428
+ "context",
3429
+ "memory",
3430
+ "magic-context",
3431
+ "ai",
3432
+ "llm"
3433
+ ],
3434
+ repository: {
3435
+ type: "git",
3436
+ url: "https://github.com/cortexkit/magic-context",
3437
+ directory: "packages/pi-plugin"
3438
+ },
3439
+ files: [
3440
+ "dist",
3441
+ "README.md"
3442
+ ],
3443
+ "//": "The build intentionally bundles typebox (no --external typebox) and keeps it a regular dependency. OMP's extension loader rewrites every bare `typebox` import to its own omptype-based shim, whose schemas are callable objects rather than JSON Schema; they fail structuredClone during tool registration, so an external typebox import stops Magic Context loading on OMP. src/typebox-bundling.test.ts guards this.",
3444
+ scripts: {
3445
+ build: "bun ../../scripts/check-bun.mjs && tsc -p ../retina-local-fs/tsconfig.build.json && bun ../../scripts/clean-dist-chunks.mjs dist index.js subagent-entry.js historian-calibration-extension.js embedding-worker-process.js raw-ordinal-warmup-worker.js transformers-web.js transformers-node-wasm.js && bun build ../plugin/src/features/magic-context/memory/transformers-web-entry.ts --outfile dist/transformers-web.js --target browser --format esm --external onnxruntime-web && bun ../plugin/scripts/build-transformers-node-wasm.ts dist && bun build src/index.ts src/subagent-entry.ts src/historian-calibration-extension.ts ../plugin/src/features/magic-context/memory/embedding-worker.ts ../plugin/src/features/magic-context/memory/embedding-worker-process.ts ../plugin/src/features/magic-context/migration-worker.ts ../plugin/src/hooks/magic-context/auto-search-worker.ts ../plugin/src/hooks/magic-context/raw-ordinal-warmup-worker.ts --outdir dist --entry-naming '[name].[ext]' --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @oh-my-pi/pi-coding-agent --external @earendil-works/pi-tui --external onnxruntime-node --external onnxruntime-web --external sharp --external bun:ffi --external node:sqlite",
3446
+ "build:e2e-argv": `bun ../../scripts/clean-dist-chunks.mjs ../../tests/docker/.generated subagent-runner-e2e.mjs && bun build src/subagent-runner.ts --outdir ../../tests/docker/.generated --entry-naming 'subagent-runner-e2e.mjs' --splitting --target node --format esm --external node:sqlite && node --input-type=module -e 'const { __test } = await import("../../tests/docker/.generated/subagent-runner-e2e.mjs"); if (typeof __test.buildArgs !== "function" || typeof __test.resolvePiInvocation !== "function") throw new Error("argv renderer exports missing"); console.log("Node argv renderer: 2 exports loaded")'`,
3447
+ typecheck: "tsc -p ../retina-local-fs/tsconfig.build.json && tsc --noEmit",
3448
+ test: "bun ../../scripts/check-bun.mjs && bun install --frozen-lockfile && BUN_JSC_useOMGJIT=0 bun test --parallel=4 --timeout 30000",
3449
+ "test:serial": "bun ../../scripts/check-bun.mjs && bun install --frozen-lockfile && BUN_JSC_useOMGJIT=0 bun test --parallel=1 --timeout 30000",
3450
+ lint: "bun ../../scripts/check-bun.mjs && biome check src",
3451
+ "lint:fix": "biome check --write src",
3452
+ format: "biome format --write src",
3453
+ "format:check": "biome format src",
3454
+ clean: "bun ../../scripts/clean-dist-chunks.mjs dist index.js subagent-entry.js historian-calibration-extension.js embedding-worker.js embedding-worker-process.js migration-worker.js raw-ordinal-warmup-worker.js transformers-web.js transformers-node-wasm.js",
3455
+ prepublishOnly: "bun run build"
3456
+ },
3457
+ "//test": "Test runs cap file-isolated workers at four (one for test:serial) and disable JSC's optimizing WebAssembly tier so per-file isolation does not pay its compilation cost on every file. These are not production settings and do not change host process engine options.",
3458
+ dependencies: {
3459
+ "@cortexkit/subc-client": "0.11.1",
3460
+ "@jitl/quickjs-singlefile-cjs-release-asyncify": "0.32.0",
3461
+ "ai-tokenizer": "^1.0.6",
3462
+ "comment-json": "^5.0.0",
3463
+ "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c",
3464
+ "quickjs-emscripten": "^0.32.0",
3465
+ zod: "^4.1.8"
3466
+ },
3467
+ optionalDependencies: {
3468
+ "onnxruntime-node": "1.30.0",
3469
+ sharp: "^0.35.0"
3470
+ },
3471
+ devDependencies: {
3472
+ "@biomejs/biome": "^2.5.1",
3473
+ "@earendil-works/pi-ai": "0.83.0",
3474
+ "@earendil-works/pi-coding-agent": "0.83.0",
3475
+ "@earendil-works/pi-tui": "0.83.0",
3476
+ "@huggingface/transformers": "^4.3.0",
3477
+ "@types/better-sqlite3": "^7.6.13",
3478
+ "@types/bun": "^1.3.10",
3479
+ "@types/node": "^22.20.0",
3480
+ "pi-agent-core-087": "npm:@earendil-works/pi-agent-core@0.87.1",
3481
+ "pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
3482
+ "pi-coding-agent-086": "npm:@earendil-works/pi-coding-agent@0.86.0",
3483
+ "pi-coding-agent-087": "npm:@earendil-works/pi-coding-agent@0.87.1",
3484
+ typebox: "^1.3.1",
3485
+ typescript: "^5.8.0"
3486
+ },
3487
+ peerDependencies: {
3488
+ "@earendil-works/pi-coding-agent": "*",
3489
+ "@earendil-works/pi-tui": "*",
3490
+ typebox: "*"
3491
+ },
3492
+ peerDependenciesMeta: {
3493
+ "@earendil-works/pi-coding-agent": {
3494
+ optional: true
3495
+ },
3496
+ "@earendil-works/pi-tui": {
3497
+ optional: true
3498
+ },
3499
+ typebox: {
3500
+ optional: true
3501
+ }
3502
+ },
3503
+ exports: {
3504
+ ".": {
3505
+ import: "./dist/index.js"
3506
+ }
3507
+ },
3508
+ pi: {
3509
+ extensions: [
3510
+ "./dist/index.js"
3511
+ ]
3512
+ },
3513
+ omp: {
3514
+ extensions: [
3515
+ "./dist/index.js"
3516
+ ]
3517
+ }
3518
+ };
3369
3519
 
3370
3520
  // src/clone-inheritance.ts
3371
3521
  import { readFile } from "node:fs/promises";
@@ -10259,7 +10409,7 @@ function getAsyncModule() {
10259
10409
  await beforeModuleLoad();
10260
10410
  const [{ default: singlefileAsyncifyVariant }, { newQuickJSAsyncWASMModuleFromVariant }] = await importPluginModule(() => Promise.all([
10261
10411
  import("./index-e7vx3byk.js").then((m)=>__toESM(m.default,1)),
10262
- import("./index-5prbx026.js")
10412
+ import("./index-2pp04pmg.js")
10263
10413
  ]));
10264
10414
  const module = await newQuickJSAsyncWASMModuleFromVariant(singlefileAsyncifyVariant);
10265
10415
  return module;
@@ -16131,284 +16281,6 @@ function clearDreamerTickFailure(db) {
16131
16281
  db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(DREAMER_TICK_FAILURE_KEY);
16132
16282
  }
16133
16283
 
16134
- // ../plugin/src/hooks/magic-context/lkg-persist.ts
16135
- import { createHash as createHash11 } from "node:crypto";
16136
- function parseStringArray(value) {
16137
- if (typeof value !== "string")
16138
- return null;
16139
- let parsed;
16140
- try {
16141
- parsed = JSON.parse(value);
16142
- } catch {
16143
- return null;
16144
- }
16145
- if (!Array.isArray(parsed))
16146
- return null;
16147
- const result = [];
16148
- for (const entry of parsed) {
16149
- if (typeof entry !== "string" || entry.length === 0)
16150
- return null;
16151
- result.push(entry);
16152
- }
16153
- return result;
16154
- }
16155
- function parseNullableString(value) {
16156
- if (value === null || value === undefined)
16157
- return null;
16158
- return typeof value === "string" ? value : undefined;
16159
- }
16160
- function parseNullableInteger(value) {
16161
- if (value === null || value === undefined)
16162
- return;
16163
- return typeof value === "number" && Number.isSafeInteger(value) ? value : undefined;
16164
- }
16165
- function parsePersistedLkgSlot(row) {
16166
- if (!row || typeof row !== "object")
16167
- return;
16168
- const record = row;
16169
- const jsonPrefix = record.json_prefix;
16170
- const lastInputMessageId = record.last_input_message_id;
16171
- const capturedAt = record.captured_at;
16172
- let inputIdsRaw = record.input_id_seq;
16173
- let piOutputEntryIds;
16174
- if (typeof inputIdsRaw === "string") {
16175
- try {
16176
- const metadata = JSON.parse(inputIdsRaw);
16177
- if (metadata && !Array.isArray(metadata) && metadata.version === 1 && Array.isArray(metadata.piOutputEntryIds)) {
16178
- if (!metadata.piOutputEntryIds.every((id) => id === null || typeof id === "string" && id.length > 0))
16179
- return;
16180
- piOutputEntryIds = metadata.piOutputEntryIds;
16181
- inputIdsRaw = JSON.stringify(metadata.inputIds);
16182
- }
16183
- } catch {
16184
- return;
16185
- }
16186
- }
16187
- const inputIdSeq = parseStringArray(inputIdsRaw);
16188
- const inputContentDigests = parseStringArray(record.input_content_digests);
16189
- const modelKey = parseNullableString(record.model_key);
16190
- const providerKey = parseNullableString(record.provider_key);
16191
- if (typeof jsonPrefix !== "string" || typeof lastInputMessageId !== "string" || lastInputMessageId.length === 0 || typeof capturedAt !== "number" || !Number.isFinite(capturedAt) || inputIdSeq === null || inputContentDigests === null || inputContentDigests.length !== inputIdSeq.length || modelKey === undefined || providerKey === undefined) {
16192
- return;
16193
- }
16194
- if (piOutputEntryIds) {
16195
- try {
16196
- const output = JSON.parse(jsonPrefix);
16197
- const inputs = new Set(inputIdSeq);
16198
- if (!Array.isArray(output) || output.length !== piOutputEntryIds.length || piOutputEntryIds.some((id) => id !== null && !inputs.has(id)))
16199
- return;
16200
- } catch {
16201
- return;
16202
- }
16203
- }
16204
- let inputContentSignatures;
16205
- if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
16206
- const parsed = parseStringArray(record.input_content_signatures);
16207
- if (parsed === null || parsed.length !== inputIdSeq.length)
16208
- return;
16209
- inputContentSignatures = parsed;
16210
- }
16211
- const slot = {
16212
- jsonPrefix,
16213
- inputIdSeq,
16214
- inputContentDigests,
16215
- lastInputMessageId,
16216
- modelKey,
16217
- providerKey,
16218
- capturedAt
16219
- };
16220
- if (inputContentSignatures)
16221
- slot.inputContentSignatures = inputContentSignatures;
16222
- if (piOutputEntryIds)
16223
- slot.piOutputEntryIds = piOutputEntryIds;
16224
- const rowVersion = parseNullableInteger(record.row_version);
16225
- if (rowVersion !== undefined)
16226
- slot.rowVersion = rowVersion;
16227
- const captureSequence = parseNullableInteger(record.capture_sequence);
16228
- if (captureSequence !== undefined)
16229
- slot.captureSequence = captureSequence;
16230
- return slot;
16231
- }
16232
- var persistedFingerprints = new WeakMap;
16233
- var PERSISTED_FINGERPRINT_MAX_SESSIONS = 1000;
16234
- function rememberFingerprint(db, sessionId, fingerprint) {
16235
- let saved = persistedFingerprints.get(db);
16236
- if (!saved) {
16237
- saved = new Map;
16238
- persistedFingerprints.set(db, saved);
16239
- }
16240
- saved.delete(sessionId);
16241
- if (saved.size >= PERSISTED_FINGERPRINT_MAX_SESSIONS) {
16242
- const oldest = saved.keys().next().value;
16243
- if (oldest !== undefined)
16244
- saved.delete(oldest);
16245
- }
16246
- saved.set(sessionId, fingerprint);
16247
- }
16248
- function slotFingerprint(slot) {
16249
- return createHash11("sha256").update(JSON.stringify([
16250
- slot.jsonPrefix,
16251
- slot.inputIdSeq,
16252
- slot.inputContentDigests,
16253
- slot.inputContentSignatures,
16254
- slot.piOutputEntryIds,
16255
- slot.lastInputMessageId,
16256
- slot.modelKey,
16257
- slot.providerKey,
16258
- slot.rowVersion,
16259
- slot.captureSequence
16260
- ])).digest("hex");
16261
- }
16262
- function saveLkgSlotToDb(db, sessionId, slot, publishMetadata) {
16263
- const fingerprint = slotFingerprint(slot);
16264
- if (!publishMetadata && persistedFingerprints.get(db)?.get(sessionId) === fingerprint)
16265
- return true;
16266
- const layout = layoutLkgPrefix(slot.jsonPrefix);
16267
- try {
16268
- db.transaction(() => {
16269
- const storedHashes = new Map;
16270
- for (const row of db.prepare("SELECT chunk, hash FROM lkg_slot_chunks WHERE session_id = ?").all(sessionId)) {
16271
- storedHashes.set(row.chunk, row.hash);
16272
- }
16273
- const upsertChunk = db.prepare(`INSERT INTO lkg_slot_chunks (session_id, chunk, hash, body) VALUES (?, ?, ?, ?)
16274
- ON CONFLICT(session_id, chunk) DO UPDATE SET hash = excluded.hash, body = excluded.body`);
16275
- for (let index = 0;index < layout.chunks.length; index += 1) {
16276
- if (storedHashes.get(index) === layout.chunkHashes[index])
16277
- continue;
16278
- upsertChunk.run(sessionId, index, layout.chunkHashes[index], layout.chunks[index]);
16279
- }
16280
- db.prepare("DELETE FROM lkg_slot_chunks WHERE session_id = ? AND chunk >= ?").run(sessionId, layout.chunks.length);
16281
- db.prepare(`INSERT INTO lkg_slots (
16282
- session_id, json_prefix_chars, json_prefix_chunks, json_prefix_hash,
16283
- input_id_seq, input_content_digests, input_content_signatures,
16284
- last_input_message_id, model_key, provider_key,
16285
- captured_at, row_version, capture_sequence
16286
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
16287
- ON CONFLICT(session_id) DO UPDATE SET
16288
- json_prefix_chars = excluded.json_prefix_chars,
16289
- json_prefix_chunks = excluded.json_prefix_chunks,
16290
- json_prefix_hash = excluded.json_prefix_hash,
16291
- input_id_seq = excluded.input_id_seq,
16292
- input_content_digests = excluded.input_content_digests,
16293
- input_content_signatures = excluded.input_content_signatures,
16294
- last_input_message_id = excluded.last_input_message_id,
16295
- model_key = excluded.model_key,
16296
- provider_key = excluded.provider_key,
16297
- captured_at = excluded.captured_at,
16298
- row_version = excluded.row_version,
16299
- capture_sequence = excluded.capture_sequence`).run(sessionId, layout.chars, layout.chunks.length, layout.hash, JSON.stringify(slot.piOutputEntryIds ? {
16300
- version: 1,
16301
- inputIds: slot.inputIdSeq,
16302
- piOutputEntryIds: slot.piOutputEntryIds
16303
- } : slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
16304
- publishMetadata?.();
16305
- }).immediate();
16306
- rememberFingerprint(db, sessionId, fingerprint);
16307
- return true;
16308
- } catch (error) {
16309
- if (!publishMetadata)
16310
- sessionLog2(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
16311
- return false;
16312
- }
16313
- }
16314
- function clearPersistedLkgSlot(db, sessionId) {
16315
- try {
16316
- clearPersistedLkgSlotStrict(db, sessionId);
16317
- } catch (error) {
16318
- sessionLog2(sessionId, "LKG snapshot durable clear failed:", error);
16319
- }
16320
- }
16321
- function clearPersistedLkgSlotStrict(db, sessionId) {
16322
- db.transaction(() => {
16323
- db.prepare("DELETE FROM lkg_slot_chunks WHERE session_id = ?").run(sessionId);
16324
- db.prepare("DELETE FROM lkg_slots WHERE session_id = ?").run(sessionId);
16325
- }).immediate();
16326
- persistedFingerprints.get(db)?.delete(sessionId);
16327
- }
16328
- function loadPersistedLkgSlot(db, sessionId) {
16329
- if (isRustMarkerAdmissionFenced(db, sessionId))
16330
- return;
16331
- let row;
16332
- let chunkRows;
16333
- try {
16334
- ({ row, chunkRows } = db.transaction(() => {
16335
- const slotRow = db.prepare("SELECT * FROM lkg_slots WHERE session_id = ?").get(sessionId);
16336
- if (!slotRow)
16337
- return { row: undefined, chunkRows: [] };
16338
- const slices = db.prepare("SELECT chunk, hash, body FROM lkg_slot_chunks WHERE session_id = ? ORDER BY chunk").all(sessionId);
16339
- return { row: slotRow, chunkRows: slices };
16340
- }).deferred());
16341
- } catch (error) {
16342
- sessionLog2(sessionId, "LKG snapshot durable load failed:", error);
16343
- return;
16344
- }
16345
- if (!row)
16346
- return;
16347
- const prefix = assembleLkgPrefix({
16348
- chars: row.json_prefix_chars,
16349
- chunks: row.json_prefix_chunks,
16350
- hash: row.json_prefix_hash
16351
- }, chunkRows);
16352
- const slot = prefix ? parsePersistedLkgSlot({ ...row, json_prefix: prefix.jsonPrefix }) : undefined;
16353
- if (!prefix || !slot) {
16354
- if (!prefix)
16355
- sessionLog2(sessionId, "LKG snapshot slices failed verification; slot cleared");
16356
- clearPersistedLkgSlot(db, sessionId);
16357
- return;
16358
- }
16359
- return slot;
16360
- }
16361
- function pruneStaleLkgSlotsBatch(db, now) {
16362
- const previousTimeout = db.prepare("PRAGMA busy_timeout").get();
16363
- const cutoff = now - 7 * 24 * 60 * 60 * 1000;
16364
- const stale = `captured_at < ? AND NOT EXISTS (
16365
- SELECT 1 FROM session_projects sp
16366
- WHERE sp.session_id = lkg_slots.session_id AND sp.updated_at >= ?
16367
- )`;
16368
- const slot = db.prepare(`SELECT session_id FROM lkg_slots WHERE ${stale} LIMIT 1`).get(cutoff, cutoff);
16369
- const chunks = db.prepare(`SELECT rowid FROM lkg_slot_chunks c WHERE
16370
- session_id = ? OR NOT EXISTS (SELECT 1 FROM lkg_slots s WHERE s.session_id = c.session_id)
16371
- LIMIT 25`).all(slot?.session_id ?? "");
16372
- if (!slot && chunks.length === 0)
16373
- return { slots: 0, chunks: 0 };
16374
- try {
16375
- db.exec("PRAGMA busy_timeout = 0");
16376
- let transactionStartedAt = 0;
16377
- const changes = db.transaction(() => {
16378
- transactionStartedAt = performance.now();
16379
- const removed = slot ? db.prepare(`DELETE FROM lkg_slots WHERE session_id = ? AND ${stale}`).run(slot.session_id, cutoff, cutoff).changes : 0;
16380
- const removeChunk = db.prepare(`DELETE FROM lkg_slot_chunks WHERE rowid = ? AND NOT EXISTS (
16381
- SELECT 1 FROM lkg_slots s WHERE s.session_id = lkg_slot_chunks.session_id
16382
- )`);
16383
- let removedChunks = 0;
16384
- for (const { rowid } of chunks)
16385
- removedChunks += removeChunk.run(rowid).changes;
16386
- return { slots: removed, chunks: removedChunks };
16387
- }).immediate();
16388
- logSlowWriteTransaction("lkg_stale_gc", transactionStartedAt);
16389
- if (changes.slots && slot)
16390
- persistedFingerprints.get(db)?.delete(slot.session_id);
16391
- return changes;
16392
- } finally {
16393
- db.exec(`PRAGMA busy_timeout = ${Number(previousTimeout.timeout) || 0}`);
16394
- }
16395
- }
16396
- async function drainStaleLkgSlots(db, now = Date.now(), budgetMs = 2000) {
16397
- let removed = 0;
16398
- await drainBackgroundBatches(() => {
16399
- const batch = pruneStaleLkgSlotsBatch(db, now);
16400
- removed += batch.slots;
16401
- return batch.slots + batch.chunks > 0;
16402
- }, { budgetMs });
16403
- return removed;
16404
- }
16405
- function createDbLkgPersistence(db) {
16406
- return {
16407
- load: (sessionId) => loadPersistedLkgSlot(db, sessionId),
16408
- clear: (sessionId) => clearPersistedLkgSlot(db, sessionId)
16409
- };
16410
- }
16411
-
16412
16284
  // ../plugin/src/plugin/dream-timer.ts
16413
16285
  var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
16414
16286
  var GIT_COMMIT_BACKLOG_DRAIN_MAX_MS = 5 * 60 * 1000;
@@ -17300,13 +17172,33 @@ function resolveModelRefForTarget(ref, targetHarness) {
17300
17172
  return targetHarness === "omp" ? resolveModelRefForOmp(ref) : resolveModelRefForPi(ref);
17301
17173
  }
17302
17174
  var configuredSubagentExtensions;
17175
+ var PI_NON_LOCAL_EXTENSION_PREFIXES = [
17176
+ "npm:",
17177
+ "git:",
17178
+ "github:",
17179
+ "http:",
17180
+ "https:",
17181
+ "ssh:",
17182
+ "builtin:"
17183
+ ];
17303
17184
  function configurePiSubagentExtensions(extensions) {
17304
17185
  configuredSubagentExtensions = extensions?.slice();
17305
17186
  }
17306
17187
  function resolveSubagentExtensionEntry(entry, targetHarness) {
17307
17188
  const trimmed = entry.trim();
17308
17189
  const isNpmSource = trimmed.startsWith("npm:");
17309
- return !isNpmSource && !isAbsolute(trimmed) ? resolvePath(getHostAgentSettingsDir(targetHarness), trimmed) : trimmed;
17190
+ const isPiSource = PI_NON_LOCAL_EXTENSION_PREFIXES.some((prefix) => trimmed.startsWith(prefix));
17191
+ if (isNpmSource || targetHarness === "pi" && isPiSource)
17192
+ return trimmed;
17193
+ let normalized = trimmed;
17194
+ if (normalized === "~") {
17195
+ normalized = homedir();
17196
+ } else if (normalized.startsWith("~/") || process.platform === "win32" && normalized.startsWith("~\\")) {
17197
+ normalized = join10(homedir(), normalized.slice(2));
17198
+ } else if (/^file:\/\//.test(normalized)) {
17199
+ normalized = fileURLToPath(normalized);
17200
+ }
17201
+ return isAbsolute(normalized) ? normalized : resolvePath(getHostAgentSettingsDir(targetHarness), normalized);
17310
17202
  }
17311
17203
  var PI_READ_ONLY_BUILTINS = ["read", "grep", "find", "ls"];
17312
17204
  var PI_AFT_READ_TOOLS = ["aft_outline", "aft_zoom", "aft_search"];
@@ -21013,6 +20905,15 @@ var canonicalReasons = new Set([
21013
20905
  "project_memory_epoch",
21014
20906
  "ttl_idle",
21015
20907
  "explicit_flush",
20908
+ "user_flush",
20909
+ "fit_retry",
20910
+ "pending_materialization",
20911
+ "variant_change",
20912
+ "recomp",
20913
+ "boundary_repair",
20914
+ "host_history_change",
20915
+ "thinking_hold",
20916
+ "mutation_drift",
21016
20917
  "max_mutation_id",
21017
20918
  "first_render",
21018
20919
  "pressure_refold",
@@ -22549,168 +22450,6 @@ function isHistorianDrainBudgetSpent(args) {
22549
22450
  return true;
22550
22451
  }
22551
22452
 
22552
- // ../plugin/src/hooks/magic-context/active-anthropic-turn.ts
22553
- function isInActiveAnthropicTurn(messages, index, anthropic) {
22554
- const start = activeAnthropicTurnStart(messages, anthropic);
22555
- return start !== undefined && index >= start;
22556
- }
22557
- function activeAnthropicTurnStart(messages, anthropic) {
22558
- if (!anthropic)
22559
- return;
22560
- for (let user = messages.length - 1;user >= 0; user--) {
22561
- const message = messages[user];
22562
- if (!isRecord(message))
22563
- continue;
22564
- const info = isRecord(message.info) ? message.info : message;
22565
- if (info.role !== "user" || info.synthetic === true || message.synthetic === true)
22566
- continue;
22567
- const id = typeof info.id === "string" ? info.id : "";
22568
- if (id.startsWith("synth-user-"))
22569
- continue;
22570
- const parts = Array.isArray(message.parts) ? message.parts : Array.isArray(message.content) ? message.content : [];
22571
- if (parts.length > 0 && parts.every((part) => isRecord(part) && (part.synthetic === true || part.ignored === true || ["tool_result", "toolResult", "tool-result"].includes(String(part.type)))))
22572
- continue;
22573
- return user + 1;
22574
- }
22575
- return;
22576
- }
22577
- function hasAnthropicReasoning(messages) {
22578
- return messages.some((message) => {
22579
- if (!isRecord(message))
22580
- return false;
22581
- const info = isRecord(message.info) ? message.info : message;
22582
- if (isAnthropicFamilyRoute(typeof info.providerID === "string" ? info.providerID : typeof info.provider === "string" ? info.provider : undefined, typeof info.modelID === "string" ? info.modelID : typeof info.model === "string" ? info.model : undefined))
22583
- return true;
22584
- const parts = Array.isArray(message.parts) ? message.parts : [];
22585
- return parts.some((part) => isRecord(part) && isRecord(part.metadata) && isRecord(part.metadata.anthropic));
22586
- });
22587
- }
22588
-
22589
- // ../plugin/src/hooks/magic-context/strip-content.ts
22590
- var METADATA_PART_TYPES = new Set([
22591
- "step-start",
22592
- "step-finish",
22593
- "snapshot",
22594
- "patch",
22595
- "agent",
22596
- "retry",
22597
- "subtask",
22598
- "compaction"
22599
- ]);
22600
- var CLEARED_REASONING_TYPES = new Set(["thinking", "reasoning"]);
22601
- var REASONING_IGNORED_PART_TYPES = new Set([
22602
- "step-start",
22603
- "step-finish",
22604
- "snapshot",
22605
- "patch",
22606
- "agent",
22607
- "retry",
22608
- "subtask",
22609
- "compaction"
22610
- ]);
22611
- var REASONING_PART_TYPES = new Set(["reasoning", "thinking", "redacted_thinking"]);
22612
- function hasReasoningReplayContent(message) {
22613
- return message.parts.some((part) => {
22614
- if (!isRecord(part) || part.ignored === true)
22615
- return false;
22616
- const type = typeof part.type === "string" ? part.type : "";
22617
- if (REASONING_IGNORED_PART_TYPES.has(type))
22618
- return false;
22619
- return type !== "text" || typeof part.text !== "string" || part.text.trim().length > 0;
22620
- });
22621
- }
22622
- function findLatestAssistantReasoningMutationExemptMessage(messages) {
22623
- for (let index = messages.length - 1;index >= 0; index -= 1) {
22624
- const message = messages[index];
22625
- if (message.info.role === "assistant" && hasReasoningReplayContent(message))
22626
- return message;
22627
- }
22628
- return;
22629
- }
22630
-
22631
- // ../plugin/src/hooks/magic-context/reasoning-budget.ts
22632
- var DEFAULT_KEEP_REASONING_TOKENS = 1e4;
22633
- var UNKNOWN_REASONING_STEP_TOKENS = 1000;
22634
- function resolveKeepReasoningTokens(config, modelKey) {
22635
- const values = config && typeof config === "object" ? Object.assign(Object.create(null), config) : undefined;
22636
- return typeof config === "number" ? config : resolveModelConfigValue(values, modelKey)?.value ?? values?.default ?? DEFAULT_KEEP_REASONING_TOKENS;
22637
- }
22638
- function reasoningStepCost(reported, textEstimate, opaque) {
22639
- if (reported !== undefined && Number.isFinite(reported) && reported > 0)
22640
- return reported;
22641
- if (textEstimate > 0)
22642
- return Math.ceil(textEstimate);
22643
- return opaque ? UNKNOWN_REASONING_STEP_TOKENS : 0;
22644
- }
22645
- function reasoningBudgetCutoff(steps, budget) {
22646
- const cost = (step) => step.alreadyRemoved ? 0 : typeof step.cost === "function" ? step.cost() : step.cost;
22647
- let kept = 0;
22648
- let upperBound = Number.POSITIVE_INFINITY;
22649
- for (const step of steps) {
22650
- if (!step.exempt)
22651
- continue;
22652
- kept += cost(step);
22653
- if (step.tag > 0)
22654
- upperBound = Math.min(upperBound, step.tag - 1);
22655
- }
22656
- for (let index = steps.length - 1;index >= 0; index--) {
22657
- const step = steps[index];
22658
- if (step.exempt || step.alreadyRemoved)
22659
- continue;
22660
- const tokens = cost(step);
22661
- if (kept + tokens <= budget) {
22662
- kept += tokens;
22663
- if (step.tag > 0)
22664
- upperBound = Math.min(upperBound, step.tag - 1);
22665
- continue;
22666
- }
22667
- let tag = step.tag;
22668
- for (let older = index - 1;tag <= 0 && older >= 0; older--)
22669
- tag = steps[older].tag;
22670
- return Math.max(0, Math.min(tag, upperBound));
22671
- }
22672
- return 0;
22673
- }
22674
- function reasoningTextAndOpaque(parts) {
22675
- let text = "";
22676
- let inlineText = "";
22677
- let opaque = false;
22678
- let hasReasoning = false;
22679
- const detailText = new Set;
22680
- for (const part of parts) {
22681
- if (!isRecord(part))
22682
- continue;
22683
- if (part.ignored === true)
22684
- continue;
22685
- if (isRecord(part.metadata)) {
22686
- const router = part.metadata.openrouter;
22687
- if (isRecord(router) && Array.isArray(router.reasoning_details) && router.reasoning_details.length > 0) {
22688
- hasReasoning = true;
22689
- opaque = true;
22690
- for (const detail of router.reasoning_details) {
22691
- if (!isRecord(detail))
22692
- continue;
22693
- if (detail.type === "reasoning.text" && typeof detail.text === "string")
22694
- detailText.add(detail.text);
22695
- if (detail.type === "reasoning.summary" && typeof detail.summary === "string")
22696
- detailText.add(detail.summary);
22697
- }
22698
- }
22699
- }
22700
- if (["reasoning", "thinking", "redacted_thinking"].includes(String(part.type))) {
22701
- hasReasoning = true;
22702
- const visible = part.type === "redacted_thinking" || part.redacted === true ? "" : typeof part.thinking === "string" ? part.thinking : typeof part.text === "string" ? part.text : "";
22703
- if (visible !== "[cleared]")
22704
- text += visible;
22705
- opaque ||= part.type === "redacted_thinking" || part.redacted === true || visible === "" && (part.metadata !== undefined || part.signature !== undefined || part.thinkingSignature !== undefined);
22706
- } else if (part.type === "text" && typeof part.text === "string") {
22707
- for (const match of part.text.matchAll(/<(?:thinking|think)>([\s\S]*?)<\/(?:thinking|think)>/gi))
22708
- inlineText += match[1];
22709
- }
22710
- }
22711
- return { text: text || [...detailText].join(""), inlineText, opaque, hasReasoning };
22712
- }
22713
-
22714
22453
  // ../plugin/src/hooks/magic-context/compartment-trigger.ts
22715
22454
  var PROACTIVE_TRIGGER_OFFSET_PERCENTAGE = 2;
22716
22455
  var POST_DROP_TARGET_RATIO = 0.75;
@@ -23655,9 +23394,9 @@ function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
23655
23394
  }
23656
23395
 
23657
23396
  // ../plugin/src/shared/tag-transcript.ts
23658
- import { createHash as createHash12 } from "node:crypto";
23397
+ import { createHash as createHash11 } from "node:crypto";
23659
23398
  function textIdentityDigest(value) {
23660
- return createHash12("sha256").update(value).digest("hex");
23399
+ return createHash11("sha256").update(value).digest("hex");
23661
23400
  }
23662
23401
  function buildContentDerivedTextIds(messageId, parts) {
23663
23402
  const sources = parts.filter((part) => part.kind === "text").map((part) => stripTagPrefix(part.getText() ?? ""));
@@ -31632,6 +31371,17 @@ class PiContextBudget {
31632
31371
  abandoned = false;
31633
31372
  completed = false;
31634
31373
  failureReason;
31374
+ signal;
31375
+ cancelled = false;
31376
+ isCancelled(error) {
31377
+ return this.cancelled || this.signal?.aborted === true || !this.signal && typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
31378
+ }
31379
+ cancel() {
31380
+ this.cancelled = true;
31381
+ this.abandoned = true;
31382
+ this.completed = false;
31383
+ this.failureReason = undefined;
31384
+ }
31635
31385
  assertOwner = () => {};
31636
31386
  constructor(startedAt = performance.now(), now = () => performance.now()) {
31637
31387
  this.startedAt = startedAt;
@@ -31649,6 +31399,7 @@ class PiContextBudget {
31649
31399
  }
31650
31400
  assertOutcome = () => {
31651
31401
  this.assertOwner();
31402
+ this.signal?.throwIfAborted();
31652
31403
  if (this.abandoned || this.elapsed() >= PI_CONTEXT_BUDGET.outcomeMs)
31653
31404
  throw new PiContextDeadlineError(this.diagnostic());
31654
31405
  };
@@ -31658,6 +31409,7 @@ class PiContextBudget {
31658
31409
  throw new PiContextDeadlineError(this.diagnostic());
31659
31410
  };
31660
31411
  assertDecisionPublication = () => {
31412
+ this.signal?.throwIfAborted();
31661
31413
  if (!this.completed)
31662
31414
  this.assertOwner();
31663
31415
  if (this.abandoned || !this.completed && this.elapsed() >= PI_CONTEXT_BUDGET.outcomeMs)
@@ -31667,17 +31419,33 @@ class PiContextBudget {
31667
31419
  return `stage=${this.stage} elapsed=${Math.round(this.elapsed())}ms recovery=${this.recovery}`;
31668
31420
  }
31669
31421
  waitUntil = async (pending, assert, remaining) => {
31670
- assert();
31422
+ try {
31423
+ assert();
31424
+ } catch (error) {
31425
+ pending.catch(() => {});
31426
+ throw error;
31427
+ }
31671
31428
  let timer;
31429
+ let onAbort;
31672
31430
  try {
31673
31431
  return await Promise.race([
31674
31432
  pending,
31433
+ ...this.signal ? [
31434
+ new Promise((_, reject) => {
31435
+ onAbort = () => reject(this.signal?.reason);
31436
+ this.signal?.addEventListener("abort", onAbort, {
31437
+ once: true
31438
+ });
31439
+ })
31440
+ ] : [],
31675
31441
  new Promise((_, reject) => {
31676
31442
  timer = setTimeout(() => reject(new PiContextDeadlineError(this.diagnostic())), remaining());
31677
31443
  })
31678
31444
  ]);
31679
31445
  } finally {
31680
31446
  clearTimeout(timer);
31447
+ if (onAbort)
31448
+ this.signal?.removeEventListener("abort", onAbort);
31681
31449
  assert();
31682
31450
  }
31683
31451
  };
@@ -31706,7 +31474,6 @@ function resolvePiWindowGeometry(args) {
31706
31474
  output: args.model?.maxTokens
31707
31475
  }, {
31708
31476
  providerLimit: observedWindow === undefined ? undefined : { context: observedWindow },
31709
- overlay: resolveWindowOverlayFacts(providerID, modelID, getWindowOverlay()),
31710
31477
  contextCap: isSaneLimit2(args.detectedContextLimit) ? args.detectedContextLimit : undefined,
31711
31478
  outputReserveOverride,
31712
31479
  harness: "pi"
@@ -31850,6 +31617,298 @@ function isOmpUnmanagedCaptureRequest(payload) {
31850
31617
  return last?.role === "user" && firstText(last.content, request.textType)?.startsWith(CAPTURE_PREFIX) === true;
31851
31618
  }
31852
31619
 
31620
+ // src/pi-dispatch-identity.ts
31621
+ var MAX_NODES = 1e5;
31622
+ var MAX_STRING_UNITS = 32 * 1024 * 1024;
31623
+ var MAX_DEPTH = 128;
31624
+ function piConversationFields(payload) {
31625
+ try {
31626
+ if (!payload || typeof payload !== "object")
31627
+ return;
31628
+ const body = payload;
31629
+ let conversation;
31630
+ let anthropic = false;
31631
+ if (Array.isArray(body.messages) && body.input === undefined) {
31632
+ conversation = { messages: body.messages, system: body.system };
31633
+ anthropic = typeof body.system === "string" || Array.isArray(body.system);
31634
+ } else if ((Array.isArray(body.input) || typeof body.input === "string") && body.messages === undefined) {
31635
+ conversation = {
31636
+ input: body.input,
31637
+ instructions: body.instructions,
31638
+ previous_response_id: body.previous_response_id,
31639
+ conversation: body.conversation,
31640
+ prompt: body.prompt
31641
+ };
31642
+ } else
31643
+ return;
31644
+ const fields = [];
31645
+ const seen = new WeakSet;
31646
+ let nodes = 0;
31647
+ let strings = 0;
31648
+ const visit = (value, position, depth) => {
31649
+ if (++nodes > MAX_NODES || depth > MAX_DEPTH)
31650
+ throw new Error("conversation structure limit");
31651
+ if (typeof value === "string") {
31652
+ strings += value.length;
31653
+ if (strings > MAX_STRING_UNITS)
31654
+ throw new Error("conversation string limit");
31655
+ fields.push(LKG_SNAPSHOT_STRING, value);
31656
+ } else if (value === null)
31657
+ fields.push(LKG_SNAPSHOT_NULL);
31658
+ else if (typeof value === "number")
31659
+ fields.push(LKG_SNAPSHOT_NUMBER, value);
31660
+ else if (typeof value === "boolean")
31661
+ fields.push(LKG_SNAPSHOT_BOOLEAN, value);
31662
+ else if (!value || typeof value !== "object")
31663
+ fields.push(LKG_SNAPSHOT_UNDEFINED);
31664
+ else {
31665
+ if (seen.has(value))
31666
+ throw new Error("cyclic conversation");
31667
+ seen.add(value);
31668
+ if (Array.isArray(value)) {
31669
+ if (anthropic && (position === "content" || position === "system") && value.length === 1) {
31670
+ const block = value[0];
31671
+ if (block && typeof block === "object" && block.type === "text" && typeof block.text === "string" && Object.keys(block).every((key) => key === "type" || key === "text" || key === "cache_control")) {
31672
+ visit(block.text, "other", depth + 1);
31673
+ seen.delete(value);
31674
+ return;
31675
+ }
31676
+ }
31677
+ fields.push(LKG_SNAPSHOT_ARRAY, value.length);
31678
+ for (const item of value)
31679
+ visit(item, position === "messages" ? "message" : anthropic && (position === "content" || position === "system") ? "block" : "other", depth + 1);
31680
+ } else {
31681
+ const entries = Object.entries(value).filter(([key, child]) => child !== undefined && typeof child !== "function" && typeof child !== "symbol" && !(anthropic && position === "block" && key === "cache_control"));
31682
+ for (const [key] of entries)
31683
+ strings += key.length;
31684
+ if (strings > MAX_STRING_UNITS)
31685
+ throw new Error("conversation key limit");
31686
+ entries.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
31687
+ fields.push(LKG_SNAPSHOT_OBJECT, entries.length);
31688
+ for (const [key, child] of entries) {
31689
+ fields.push(LKG_SNAPSHOT_KEY, key);
31690
+ visit(child, position === "root" && key === "messages" ? "messages" : position === "root" && key === "system" ? "system" : position === "message" && key === "content" ? "content" : "other", depth + 1);
31691
+ }
31692
+ }
31693
+ seen.delete(value);
31694
+ }
31695
+ };
31696
+ visit(conversation, "root", 0);
31697
+ return fields;
31698
+ } catch {
31699
+ return;
31700
+ }
31701
+ }
31702
+ function piManagedSignature(messages) {
31703
+ for (const message of messages.slice(0, 8)) {
31704
+ if (!message || typeof message !== "object")
31705
+ continue;
31706
+ const content = message.content;
31707
+ const text = typeof content === "string" ? content : Array.isArray(content) ? content.find((part) => part?.type === "text" && typeof part.text === "string")?.text : undefined;
31708
+ if (!text)
31709
+ continue;
31710
+ const marker = /^(<session-history>|<session-history-since>|<memory>|§\d+§)/.exec(text)?.[0];
31711
+ return marker ?? text.slice(0, 128);
31712
+ }
31713
+ return;
31714
+ }
31715
+ function piHasManagedSignature(payload, signature) {
31716
+ if (!signature || !payload || typeof payload !== "object")
31717
+ return false;
31718
+ const body = payload;
31719
+ if (typeof body.input === "string" && body.messages === undefined)
31720
+ return body.input.slice(0, 4096).includes(signature);
31721
+ const messages = Array.isArray(body.messages) ? body.messages : Array.isArray(body.input) ? body.input : undefined;
31722
+ if (!messages)
31723
+ return false;
31724
+ for (const message of messages.slice(0, 8)) {
31725
+ if (!message || typeof message !== "object")
31726
+ continue;
31727
+ const content = message.content;
31728
+ if (typeof content === "string" && content.slice(0, 4096).includes(signature))
31729
+ return true;
31730
+ if (!Array.isArray(content))
31731
+ continue;
31732
+ for (const block of content.slice(0, 32)) {
31733
+ if (block && ["text", "input_text", "output_text"].includes(block.type) && typeof block.text === "string" && block.text.slice(0, 4096).includes(signature))
31734
+ return true;
31735
+ }
31736
+ }
31737
+ return false;
31738
+ }
31739
+
31740
+ // src/pi-dispatch-structure.ts
31741
+ var MAX_MESSAGES = 1e5;
31742
+ function object(value) {
31743
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
31744
+ }
31745
+ function messageStructure(value) {
31746
+ const message = object(value);
31747
+ if (!message)
31748
+ return;
31749
+ const role = [
31750
+ "custom",
31751
+ "hookMessage",
31752
+ "developer",
31753
+ "branchSummary",
31754
+ "compactionSummary",
31755
+ "bashExecution",
31756
+ "pythonExecution"
31757
+ ].includes(String(message.role)) ? "user" : message.role;
31758
+ if (role !== "user" && role !== "assistant" && role !== "toolResult")
31759
+ return;
31760
+ const row = { role, calls: [], results: [] };
31761
+ if (typeof message.timestamp === "number")
31762
+ row.timestamp = message.timestamp;
31763
+ if (role === "toolResult") {
31764
+ if (typeof message.toolCallId !== "string")
31765
+ return;
31766
+ row.results.push(message.toolCallId);
31767
+ }
31768
+ if (role === "assistant" && Array.isArray(message.content)) {
31769
+ for (const value of message.content) {
31770
+ const block = object(value);
31771
+ if (block?.type !== "toolCall" && block?.type !== "tool_use")
31772
+ continue;
31773
+ if (typeof block.id !== "string")
31774
+ return;
31775
+ row.calls.push(block.id);
31776
+ }
31777
+ }
31778
+ return row;
31779
+ }
31780
+ function piPreparedStructure(messages) {
31781
+ if (!messages.length || messages.length > MAX_MESSAGES)
31782
+ return;
31783
+ const rows = [];
31784
+ for (const message of messages) {
31785
+ const source = object(message);
31786
+ if ((source?.role === "bashExecution" || source?.role === "pythonExecution") && source.excludeFromContext === true)
31787
+ continue;
31788
+ const row = messageStructure(message);
31789
+ if (!row)
31790
+ return;
31791
+ rows.push(row);
31792
+ }
31793
+ return { messages: rows };
31794
+ }
31795
+ function payloadStructure(payload) {
31796
+ const body = object(payload);
31797
+ if (!body)
31798
+ return;
31799
+ if (body.messages === undefined && typeof body.input === "string")
31800
+ return [{ role: "user", calls: [], results: [] }];
31801
+ const responses = body.messages === undefined && Array.isArray(body.input);
31802
+ const messages = responses ? body.input : body.messages;
31803
+ if (!Array.isArray(messages) || messages.length > MAX_MESSAGES)
31804
+ return;
31805
+ const rows = [];
31806
+ for (const value of messages) {
31807
+ const message = object(value);
31808
+ if (!message)
31809
+ return;
31810
+ if (!responses && rows.length === 0 && (message.role === "system" || message.role === "developer"))
31811
+ continue;
31812
+ if (responses && message.type === "reasoning")
31813
+ continue;
31814
+ if (responses && ["function_call", "custom_tool_call", "computer_call"].includes(String(message.type))) {
31815
+ if (typeof message.call_id !== "string")
31816
+ return;
31817
+ let assistant = rows.at(-1);
31818
+ if (assistant?.role !== "assistant") {
31819
+ assistant = { role: "assistant", calls: [], results: [] };
31820
+ rows.push(assistant);
31821
+ }
31822
+ assistant.calls.push(message.call_id);
31823
+ continue;
31824
+ }
31825
+ if (responses && [
31826
+ "function_call_output",
31827
+ "custom_tool_call_output",
31828
+ "computer_call_output"
31829
+ ].includes(String(message.type))) {
31830
+ if (typeof message.call_id !== "string")
31831
+ return;
31832
+ rows.push({ role: "toolResult", calls: [], results: [message.call_id] });
31833
+ continue;
31834
+ }
31835
+ if (message.role === "tool") {
31836
+ if (typeof message.tool_call_id !== "string")
31837
+ return;
31838
+ rows.push({
31839
+ role: "toolResult",
31840
+ calls: [],
31841
+ results: [message.tool_call_id]
31842
+ });
31843
+ continue;
31844
+ }
31845
+ if (message.role === "user" && Array.isArray(message.content)) {
31846
+ const results = message.content.filter((block) => object(block)?.type === "tool_result");
31847
+ if (results.length) {
31848
+ for (const block of results) {
31849
+ if (typeof block.tool_use_id !== "string")
31850
+ return;
31851
+ rows.push({
31852
+ role: "toolResult",
31853
+ calls: [],
31854
+ results: [block.tool_use_id]
31855
+ });
31856
+ }
31857
+ continue;
31858
+ }
31859
+ }
31860
+ const row = messageStructure(message);
31861
+ if (!row)
31862
+ return;
31863
+ if (Array.isArray(message.tool_calls)) {
31864
+ for (const call of message.tool_calls) {
31865
+ if (typeof call?.id !== "string")
31866
+ return;
31867
+ row.calls.push(call.id);
31868
+ }
31869
+ }
31870
+ if (responses && row.role === "assistant" && rows.at(-1)?.role === "assistant") {
31871
+ rows[rows.length - 1].calls.push(...row.calls);
31872
+ } else
31873
+ rows.push(row);
31874
+ }
31875
+ return rows;
31876
+ }
31877
+ function wireId(id, anthropic, responses) {
31878
+ if (anthropic)
31879
+ return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
31880
+ if (responses) {
31881
+ const callId = id.split(/[\n|]/, 1)[0];
31882
+ return /^[a-zA-Z0-9_-]{1,64}$/.test(callId) ? callId : undefined;
31883
+ }
31884
+ return id;
31885
+ }
31886
+ function piMatchesPreparedStructure(payload, prepared) {
31887
+ try {
31888
+ const rows = payloadStructure(payload);
31889
+ if (!rows || !prepared || rows.length !== prepared.messages.length)
31890
+ return false;
31891
+ const body = payload;
31892
+ const anthropic = typeof body.system === "string" || Array.isArray(body.system);
31893
+ const responses = body.messages === undefined && Array.isArray(body.input);
31894
+ for (let i = 0;i < rows.length; i++) {
31895
+ const expected = prepared.messages[i];
31896
+ const actual = rows[i];
31897
+ if (actual.role !== expected.role || actual.calls.length !== expected.calls.length || actual.results.length !== expected.results.length || actual.timestamp !== undefined && actual.timestamp !== expected.timestamp)
31898
+ return false;
31899
+ for (let j = 0;j < actual.calls.length; j++)
31900
+ if (actual.calls[j] !== wireId(expected.calls[j], anthropic, responses))
31901
+ return false;
31902
+ for (let j = 0;j < actual.results.length; j++)
31903
+ if (actual.results[j] !== wireId(expected.results[j], anthropic, responses))
31904
+ return false;
31905
+ }
31906
+ return true;
31907
+ } catch {
31908
+ return false;
31909
+ }
31910
+ }
31911
+
31853
31912
  // src/pi-context-refusal.ts
31854
31913
  var ENTRY_TYPE = "magic-context-turn-refused";
31855
31914
  var RETRY_MESSAGE = "Magic Context could not safely prepare this turn; send your message again.";
@@ -31867,6 +31926,26 @@ function clearPiContextReceipt(sessionId) {
31867
31926
  for (const receipts of receiptMaps)
31868
31927
  receipts.delete(sessionId);
31869
31928
  }
31929
+ function createPiContextOwnershipGuards(operations, key, active, budget, owner) {
31930
+ const sideTurn = budget.sideTurn;
31931
+ const signal = budget.signal;
31932
+ const isOwned = () => sideTurn ? operations.get(key) === owner : operations.get(key) === active && active.pass === budget;
31933
+ const isCurrent = () => isOwned() && (sideTurn || !active.ended);
31934
+ const assertOwner = () => {
31935
+ if (!isCurrent())
31936
+ throw new PiContextSupersededError("Pi context pass superseded: no longer valid for this operation", active.ended ? "agent_end" : operations.get(key) !== (sideTurn ? owner : active) ? "operation replacement or cache eviction" : "newer context pass");
31937
+ signal?.throwIfAborted();
31938
+ };
31939
+ return { isOwned, isCurrent, assertOwner };
31940
+ }
31941
+ function releasePiOperationPayloads(operation) {
31942
+ operation.inputKeys = undefined;
31943
+ operation.inputMessages = undefined;
31944
+ operation.inputBranch = undefined;
31945
+ operation.dispatchFields = undefined;
31946
+ operation.managedSignature = undefined;
31947
+ operation.preparedStructure = undefined;
31948
+ }
31870
31949
  function operationKey(ctx) {
31871
31950
  return ctx.sessionManager?.getSessionId?.() ?? ctx.sessionManager ?? "no-session";
31872
31951
  }
@@ -31894,6 +31973,69 @@ function endBelongsToEarlierRun(operation, event) {
31894
31973
  return false;
31895
31974
  return operation.inputKeys.some((key) => !ended.has(key));
31896
31975
  }
31976
+ function messageSnapshots(messages) {
31977
+ const snapshots = [];
31978
+ for (const message of messages) {
31979
+ const id = messageKey(message);
31980
+ const fields = lkgContentFields(message);
31981
+ if (!id || !fields)
31982
+ return;
31983
+ snapshots.push({ id, fields });
31984
+ }
31985
+ return snapshots.length ? snapshots : undefined;
31986
+ }
31987
+ function inputBranch(ctx, inputs) {
31988
+ try {
31989
+ const branch = ctx.sessionManager.getBranch();
31990
+ const entries = branch.filter((entry) => entry.type === "message" || entry.type === "custom_message");
31991
+ const anchorId = entries.at(-1)?.id;
31992
+ const native = messageSnapshots(entries.map((entry) => {
31993
+ if (entry.type === "message")
31994
+ return entry.message;
31995
+ const attribution = entry.attribution;
31996
+ const timestamp = new Date(entry.timestamp).getTime();
31997
+ if (!Number.isFinite(timestamp) || !entry.customType || typeof entry.content !== "string" && !Array.isArray(entry.content) || attribution !== undefined && attribution !== "agent" && attribution !== "user")
31998
+ return;
31999
+ return {
32000
+ role: "custom",
32001
+ customType: entry.customType,
32002
+ content: entry.content,
32003
+ display: entry.display,
32004
+ details: entry.details,
32005
+ attribution,
32006
+ timestamp
32007
+ };
32008
+ }));
32009
+ inputs ??= native;
32010
+ if (!anchorId || !native || !inputs || native.length > inputs.length || exactReusablePrefix(native, inputs) !== native.length)
32011
+ return;
32012
+ return {
32013
+ anchorId,
32014
+ anchorIndex: native.length - 1,
32015
+ entryIds: entries.map((entry) => entry.id),
32016
+ messages: inputs
32017
+ };
32018
+ } catch {
32019
+ return;
32020
+ }
32021
+ }
32022
+ function dispatchedEndBelongsToEarlierRun(operation, event, ctx) {
32023
+ if (!operation.dispatched || !operation.started || !operation.ready || !operation.pass?.completed || operation.refused || operation.pass.abandoned || !operation.inputBranch)
32024
+ return false;
32025
+ try {
32026
+ if (ctx.isIdle() !== false)
32027
+ return false;
32028
+ const current = inputBranch(ctx);
32029
+ const prepared = operation.inputBranch;
32030
+ if (!current || current.entryIds[prepared.anchorIndex] !== prepared.anchorId || current.messages.length !== prepared.messages.length || exactReusablePrefix(current.messages, prepared.messages) !== prepared.messages.length)
32031
+ return false;
32032
+ const messages = event?.messages;
32033
+ const ended = Array.isArray(messages) ? messageSnapshots(messages) : undefined;
32034
+ return !!(ended && ended.length <= prepared.anchorIndex && ended.length < prepared.messages.length && exactReusablePrefix(prepared.messages, ended) === ended.length);
32035
+ } catch {
32036
+ return false;
32037
+ }
32038
+ }
31897
32039
  function inputMessageKeys(event) {
31898
32040
  try {
31899
32041
  const messages = event.messages;
@@ -31915,6 +32057,7 @@ function registerPiGuardedContext(pi, handler, options = {}) {
31915
32057
  const sideSessions = new Map;
31916
32058
  receiptMaps.add(operations);
31917
32059
  const newOperation = () => ({
32060
+ retainedAfterEnd: false,
31918
32061
  dispatched: false,
31919
32062
  started: false,
31920
32063
  ready: false,
@@ -31943,6 +32086,7 @@ function registerPiGuardedContext(pi, handler, options = {}) {
31943
32086
  budget.recovery = budget.recovery === "not attempted" ? "no managed result; refused" : budget.recovery;
31944
32087
  const identityConflict = findPiTagIdentityConflict2(reason);
31945
32088
  const message = identityConflict ? `${identityConflict.message}. ${budget.diagnostic()}` : `${RETRY_MESSAGE} ${budget.diagnostic()} (${reason instanceof Error ? reason.message : String(reason)})`;
32089
+ log2("[magic-context][pi] CONTEXT REFUSED", message);
31946
32090
  try {
31947
32091
  ctx.ui?.notify(message, "error");
31948
32092
  } catch (error) {
@@ -31980,7 +32124,9 @@ function registerPiGuardedContext(pi, handler, options = {}) {
31980
32124
  log2(`[magic-context][pi] OMP context counts session=${String(key)} side_contexts=${counts.sides} context_passes=${counts.contexts} dispatch_fence=${counts.sides ? "latched off" : "on"}`);
31981
32125
  const operation = operations.get(key);
31982
32126
  if (operation) {
31983
- if (endBelongsToEarlierRun(operation, event)) {
32127
+ if (endBelongsToEarlierRun(operation, event) || lifecycleSeen.starts > lifecycleSeen.ends && dispatchedEndBelongsToEarlierRun(operation, event, ctx)) {
32128
+ if (operation.dispatched)
32129
+ operation.retainedAfterEnd = true;
31984
32130
  if (lifecycleSeen.starts <= lifecycleSeen.ends)
31985
32131
  operation.started = false;
31986
32132
  log2(`[magic-context][pi] agent_end attributed to an earlier run; keeping the latest context pass session=${String(key)} ${operation.pass?.diagnostic() ?? ""}`);
@@ -31988,9 +32134,18 @@ function registerPiGuardedContext(pi, handler, options = {}) {
31988
32134
  }
31989
32135
  operation.ended = true;
31990
32136
  operation.ready = false;
32137
+ releasePiOperationPayloads(operation);
31991
32138
  }
31992
32139
  });
31993
32140
  pi.on("before_provider_request", (event, ctx) => {
32141
+ const cancelledOperation = operations.get(operationKey(ctx));
32142
+ const signal = ctx.signal;
32143
+ if (signal ? signal.aborted : cancelledOperation?.pass?.isCancelled()) {
32144
+ cancelledOperation?.pass?.cancel();
32145
+ if (cancelledOperation)
32146
+ cancelledOperation.ready = false;
32147
+ return;
32148
+ }
31994
32149
  if (options.compactionOff?.(ctx))
31995
32150
  return;
31996
32151
  const payload = event.payload;
@@ -32018,6 +32173,10 @@ function registerPiGuardedContext(pi, handler, options = {}) {
32018
32173
  const isCurrent = () => operations.get(key) === active;
32019
32174
  const capture = isOmpUnmanagedCaptureRequest(payload);
32020
32175
  const budget = (capture ? undefined : active.pass) ?? new PiContextBudget;
32176
+ if (active.refused && active.pass === budget) {
32177
+ ctx.abort();
32178
+ return;
32179
+ }
32021
32180
  let refusalOrigin;
32022
32181
  try {
32023
32182
  if (capture)
@@ -32032,8 +32191,32 @@ function registerPiGuardedContext(pi, handler, options = {}) {
32032
32191
  }
32033
32192
  if (!budget.completed || !active.ready || active.refused || budget.abandoned)
32034
32193
  throw new Error("context pass ran without a managed context receipt");
32194
+ if (!piHasManagedSignature(payload, active.managedSignature))
32195
+ throw new Error("provider request does not match this pass's managed dispatch (missing current receipt signature)");
32196
+ const fields = piConversationFields(payload);
32197
+ if (!fields)
32198
+ throw new Error("provider conversation identity could not be established");
32199
+ if (!piMatchesPreparedStructure(payload, active.preparedStructure))
32200
+ throw new Error("provider request does not match this pass's managed dispatch (prepared turn structure)");
32201
+ if (active.dispatched) {
32202
+ if (!active.dispatchFields || exactReusablePrefix([{ id: "conversation", fields }], [{ id: "conversation", fields: active.dispatchFields }]) !== 1)
32203
+ throw new Error("provider request does not match this pass's managed dispatch");
32204
+ }
32205
+ if (!active.dispatched && active.inputMessages && (!active.inputBranch || active.inputBranch.anchorIndex < active.inputMessages.length - 1)) {
32206
+ const previous = active.inputBranch;
32207
+ const persisted = inputBranch(ctx, active.inputMessages);
32208
+ if (!previous || persisted && persisted.anchorIndex > previous.anchorIndex && persisted.entryIds[previous.anchorIndex] === previous.anchorId)
32209
+ active.inputBranch = persisted;
32210
+ }
32211
+ if (!active.dispatched)
32212
+ active.dispatchFields = fields;
32035
32213
  active.dispatched = true;
32036
32214
  } catch (error) {
32215
+ if (signal ? signal.aborted : budget.isCancelled(error)) {
32216
+ budget.cancel();
32217
+ active.ready = false;
32218
+ return;
32219
+ }
32037
32220
  active.refused = true;
32038
32221
  budget.stage = refusalOrigin ? `provider dispatch (origin=${refusalOrigin}; context stage=${budget.stage})` : "provider dispatch";
32039
32222
  refuse(ctx, budget, error, isCurrent);
@@ -32045,6 +32228,7 @@ function registerPiGuardedContext(pi, handler, options = {}) {
32045
32228
  if (fenceEnabled && isOmpDumpContext())
32046
32229
  return { messages: event.messages };
32047
32230
  const budget = new PiContextBudget;
32231
+ budget.signal = event.signal ?? ctx.signal;
32048
32232
  budget.sideTurn = fenceEnabled && isOmpSideContext(event);
32049
32233
  const key = operationKey(ctx);
32050
32234
  if (fenceEnabled) {
@@ -32057,7 +32241,7 @@ function registerPiGuardedContext(pi, handler, options = {}) {
32057
32241
  if (budget.sideTurn && ++counts.sides === 1)
32058
32242
  log2(`[magic-context][pi] OMP dispatch fence disabled for session ${String(key)}: verified ephemeral context; session-wide abort cannot distinguish provider operations (side_contexts=${counts.sides} context_passes=${counts.contexts})`);
32059
32243
  }
32060
- const owner = operations.get(key);
32244
+ const owner = budget.sideTurn ? operations.get(key) : undefined;
32061
32245
  let operation = operations.get(key);
32062
32246
  if (budget.sideTurn || !operation || operation.ended || !fenceEnabled) {
32063
32247
  operation = newOperation();
@@ -32066,26 +32250,38 @@ function registerPiGuardedContext(pi, handler, options = {}) {
32066
32250
  }
32067
32251
  const active = operation;
32068
32252
  active.pass = budget;
32069
- active.inputKeys = undefined;
32253
+ releasePiOperationPayloads(active);
32254
+ active.retainedAfterEnd = false;
32070
32255
  active.dispatched = false;
32071
32256
  active.ready = false;
32072
32257
  active.refused = false;
32073
- const isOwned = () => budget.sideTurn ? operations.get(key) === owner : operations.get(key) === active && active.pass === budget;
32074
- const isCurrent = () => isOwned() && (budget.sideTurn || !active.ended);
32075
- budget.assertOwner = () => {
32076
- if (!isCurrent())
32077
- throw new PiContextSupersededError("Pi context pass superseded: no longer valid for this operation", active.ended ? "agent_end" : operations.get(key) !== (budget.sideTurn ? owner : active) ? "operation replacement or cache eviction" : "newer context pass");
32078
- };
32258
+ const { isOwned, isCurrent, assertOwner } = createPiContextOwnershipGuards(operations, key, active, budget, owner);
32259
+ budget.assertOwner = assertOwner;
32079
32260
  try {
32080
- if (fenceEnabled && !budget.sideTurn)
32261
+ budget.assertOutcome();
32262
+ let inputs;
32263
+ if (fenceEnabled && !budget.sideTurn) {
32081
32264
  active.inputKeys = inputMessageKeys(event);
32265
+ inputs = messageSnapshots(event.messages);
32266
+ active.inputMessages = inputs;
32267
+ }
32082
32268
  const result = await budget.waitMandatory(Promise.resolve(withSqliteTransformPass2(() => handler(event, ctx, budget))));
32083
32269
  if (result?.messages) {
32270
+ active.managedSignature = piManagedSignature(result.messages);
32271
+ active.preparedStructure = piPreparedStructure(result.messages);
32084
32272
  budget.completed = true;
32085
32273
  active.ready = true;
32274
+ if (inputs)
32275
+ active.inputBranch = inputBranch(ctx, inputs);
32086
32276
  }
32087
32277
  return result;
32088
32278
  } catch (error) {
32279
+ if (budget.isCancelled(error)) {
32280
+ budget.cancel();
32281
+ if (isOwned())
32282
+ active.ready = false;
32283
+ return;
32284
+ }
32089
32285
  if (error instanceof PiContextSupersededError || !isCurrent()) {
32090
32286
  if (fenceEnabled && !budget.sideTurn && !sideSessions.get(key)?.sides && !options.compactionOff?.(ctx)) {
32091
32287
  const nonce = crypto.randomUUID();
@@ -32123,6 +32319,9 @@ function registerPiGuardedContext(pi, handler, options = {}) {
32123
32319
  active.refused = true;
32124
32320
  refuse(ctx, budget, error, isOwned);
32125
32321
  return { messages: event.messages };
32322
+ } finally {
32323
+ if (!fenceEnabled || budget.sideTurn)
32324
+ releasePiOperationPayloads(active);
32126
32325
  }
32127
32326
  });
32128
32327
  }
@@ -32241,342 +32440,6 @@ function createPiFallbackIndex() {
32241
32440
  };
32242
32441
  }
32243
32442
 
32244
- // ../plugin/src/hooks/magic-context/openai-compat-adjacency.ts
32245
- function assertOpenAiCompatAdjacency(messages) {
32246
- const violations = [];
32247
- for (let i = 0;i < messages.length; i++) {
32248
- const msg = messages[i];
32249
- if (msg.role !== "assistant" || !msg.tool_calls || msg.tool_calls.length === 0) {
32250
- continue;
32251
- }
32252
- const expectedIds = msg.tool_calls.map((tc) => tc.id);
32253
- const expectedSet = new Set(expectedIds);
32254
- const collected = new Map;
32255
- let j = i + 1;
32256
- while (j < messages.length && messages[j].role === "tool") {
32257
- const toolMsg = messages[j];
32258
- const id = toolMsg.tool_call_id;
32259
- if (!id) {
32260
- violations.push({
32261
- index: i,
32262
- kind: "unmatched_tool_call_id",
32263
- detail: `tool message at index ${j} missing tool_call_id`
32264
- });
32265
- } else if (!expectedSet.has(id)) {
32266
- violations.push({
32267
- index: i,
32268
- kind: "unmatched_tool_call_id",
32269
- toolCallId: id,
32270
- assistantToolCallIds: expectedIds,
32271
- detail: `tool message at index ${j} references unexpected id ${id}`
32272
- });
32273
- } else {
32274
- collected.set(id, j);
32275
- }
32276
- j++;
32277
- }
32278
- const followingRoles = messages.slice(i + 1, Math.min(messages.length, i + 4)).map((m) => m.role);
32279
- const missing = expectedIds.filter((id) => !collected.has(id));
32280
- if (missing.length > 0) {
32281
- violations.push({
32282
- index: i,
32283
- kind: "missing_tool_messages",
32284
- assistantToolCallIds: expectedIds,
32285
- followingRoles,
32286
- detail: missing.length === expectedIds.length ? `assistant at index ${i} has tool_calls but next messages are not contiguous tool role (following: ${followingRoles.join(", ") || "none"})` : `assistant at index ${i} missing tool results for: ${missing.join(", ")}`
32287
- });
32288
- if (j < messages.length && messages[j].role !== "tool") {
32289
- const last = violations[violations.length - 1];
32290
- last.detail += `; blocked by ${messages.slice(i + 1, j + 1).map((m, off) => `${m.role}[${i + 1 + off}]`).join(", ")}`;
32291
- }
32292
- }
32293
- }
32294
- for (let i = 0;i < messages.length; i++) {
32295
- if (messages[i].role !== "tool")
32296
- continue;
32297
- const id = messages[i].tool_call_id ?? "";
32298
- if (!id)
32299
- continue;
32300
- let found = false;
32301
- for (let k = i - 1;k >= 0; k--) {
32302
- const prev = messages[k];
32303
- if (prev.role === "assistant" && prev.tool_calls?.some((tc) => tc.id === id)) {
32304
- const between = messages.slice(k + 1, i);
32305
- if (between.every((m) => m.role === "tool")) {
32306
- found = true;
32307
- }
32308
- break;
32309
- }
32310
- if (prev.role === "assistant" || prev.role === "user")
32311
- break;
32312
- }
32313
- if (!found) {
32314
- violations.push({
32315
- index: i,
32316
- kind: "orphan_tool_message",
32317
- toolCallId: id,
32318
- detail: `tool message at index ${i} is not immediately after its assistant tool_calls`
32319
- });
32320
- }
32321
- }
32322
- return { ok: violations.length === 0, violations };
32323
- }
32324
-
32325
- // ../plugin/src/hooks/magic-context/lkg-replay.ts
32326
- function canonicalLkgModelKeys(modelKey, providerKey) {
32327
- const canonicalModelKey = modelKey ? piModelRefToCanonical(modelKey) : null;
32328
- const slash = canonicalModelKey?.indexOf("/") ?? -1;
32329
- return {
32330
- modelKey: canonicalModelKey,
32331
- providerKey: slash > 0 && canonicalModelKey ? canonicalModelKey.slice(0, slash) : providerKey
32332
- };
32333
- }
32334
- function recordValue(info, key) {
32335
- return info && typeof info === "object" ? info[key] : undefined;
32336
- }
32337
- function messageInfo(message) {
32338
- if (message.info && typeof message.info === "object")
32339
- return message.info;
32340
- return message;
32341
- }
32342
- function messageParts(message) {
32343
- return Array.isArray(message.parts) ? message.parts : [];
32344
- }
32345
- function messageRole(message) {
32346
- const infoRole = recordValue(messageInfo(message), "role");
32347
- if (typeof infoRole === "string")
32348
- return infoRole;
32349
- const role = recordValue(message, "role");
32350
- return typeof role === "string" ? role : undefined;
32351
- }
32352
- function messageId2(message) {
32353
- const id = recordValue(messageInfo(message), "id") ?? recordValue(message, "id");
32354
- return typeof id === "string" && id.length > 0 ? id : null;
32355
- }
32356
- function entryIdsAreValid(slot, entryIds) {
32357
- if (slot.inputIdSeq.length === 0 || entryIds.length < slot.inputIdSeq.length)
32358
- return false;
32359
- if (slot.inputIdSeq[slot.inputIdSeq.length - 1] !== slot.lastInputMessageId)
32360
- return false;
32361
- const seen = new Set;
32362
- for (const id of entryIds) {
32363
- if (!id || seen.has(id))
32364
- return false;
32365
- seen.add(id);
32366
- }
32367
- if (entryIds.indexOf(slot.lastInputMessageId) !== slot.inputIdSeq.length - 1)
32368
- return false;
32369
- for (let index = 0;index < slot.inputIdSeq.length; index += 1) {
32370
- if (entryIds[index] !== slot.inputIdSeq[index])
32371
- return false;
32372
- }
32373
- return true;
32374
- }
32375
- function entryContentIsValid(slot, entry) {
32376
- return entry.entryContentDigests.length >= slot.inputContentDigests.length && slot.inputContentDigests.every((digest, index) => isLegacyLkgDigest(digest) ? entry.entryLegacyContentDigests?.[index] === digest : entry.entryContentDigests[index] === digest);
32377
- }
32378
- function partCallIds(message) {
32379
- const ids = [];
32380
- for (const rawPart of messageParts(message)) {
32381
- if (!rawPart || typeof rawPart !== "object")
32382
- continue;
32383
- const part = rawPart;
32384
- if (part.type !== "tool" && part.type !== "tool_use")
32385
- continue;
32386
- const callId = part.callID ?? part.callId ?? part.id;
32387
- if (typeof callId === "string" && callId.length > 0)
32388
- ids.push(callId);
32389
- }
32390
- return ids;
32391
- }
32392
- function partResultIds(message) {
32393
- const ids = [];
32394
- for (const rawPart of messageParts(message)) {
32395
- if (!rawPart || typeof rawPart !== "object")
32396
- continue;
32397
- const part = rawPart;
32398
- if (part.type !== "tool_result" && part.type !== "tool-result")
32399
- continue;
32400
- const callId = part.tool_call_id ?? part.tool_use_id ?? part.callID ?? part.callId;
32401
- if (typeof callId === "string" && callId.length > 0)
32402
- ids.push(callId);
32403
- }
32404
- return ids;
32405
- }
32406
- function partIsReasoning(part) {
32407
- return Boolean(part && typeof part === "object" && part.type === "reasoning");
32408
- }
32409
- function partIsAnthropicThinking(part) {
32410
- if (!part || typeof part !== "object")
32411
- return false;
32412
- const type = part.type;
32413
- return type === "thinking" || type === "reasoning" || type === "redacted_thinking";
32414
- }
32415
- function partEndsAnthropicAssistantRun(part) {
32416
- if (!part || typeof part !== "object")
32417
- return false;
32418
- const value = part;
32419
- if (value.type !== "tool" || value.providerExecuted === true || !value.state || typeof value.state !== "object") {
32420
- return false;
32421
- }
32422
- const status = value.state.status;
32423
- return status === "completed" || status === "error";
32424
- }
32425
- function partIsOpenCodeStepMetadata(part) {
32426
- if (!part || typeof part !== "object")
32427
- return false;
32428
- const type = part.type;
32429
- return type === "step-start" || type === "step-finish";
32430
- }
32431
- function validateAnthropicReasoningRuns(messages) {
32432
- let index = 0;
32433
- while (index < messages.length) {
32434
- if (messageRole(messages[index]) !== "assistant") {
32435
- index += 1;
32436
- continue;
32437
- }
32438
- let firstMessageInRun = null;
32439
- let sawOtherContent = false;
32440
- while (index < messages.length && messageRole(messages[index]) === "assistant") {
32441
- for (const part of messageParts(messages[index])) {
32442
- if (partEndsAnthropicAssistantRun(part)) {
32443
- firstMessageInRun = null;
32444
- sawOtherContent = false;
32445
- } else if (!partIsOpenCodeStepMetadata(part)) {
32446
- if (firstMessageInRun === null)
32447
- firstMessageInRun = index;
32448
- if (partIsAnthropicThinking(part)) {
32449
- if (sawOtherContent || index !== firstMessageInRun)
32450
- return false;
32451
- } else {
32452
- sawOtherContent = true;
32453
- }
32454
- }
32455
- }
32456
- index += 1;
32457
- }
32458
- }
32459
- return true;
32460
- }
32461
- function validateLkgSeamBoundary(prefix, tail) {
32462
- const last = prefix[prefix.length - 1];
32463
- const first = tail[0];
32464
- if (!last || !first)
32465
- return true;
32466
- const lastCalls = partCallIds(last);
32467
- if (lastCalls.length === 0)
32468
- return true;
32469
- const firstCalls = new Set([...partCallIds(first), ...partResultIds(first)]);
32470
- if (messageRole(first) === "tool" || lastCalls.some((callId) => firstCalls.has(callId)))
32471
- return false;
32472
- return !messageParts(last).some((part) => {
32473
- if (!part || typeof part !== "object")
32474
- return false;
32475
- const value = part;
32476
- if (value.type !== "tool")
32477
- return false;
32478
- const state = value.state;
32479
- return !state || typeof state !== "object" || state.status !== "completed";
32480
- });
32481
- }
32482
- function validateLkgSeam(prefix, tail, providerKey) {
32483
- const all = [...prefix, ...tail];
32484
- const ids = new Set;
32485
- const calls = new Set;
32486
- const results = new Set;
32487
- for (const message of all) {
32488
- const id = messageId2(message);
32489
- if (id !== null) {
32490
- if (ids.has(id))
32491
- return false;
32492
- ids.add(id);
32493
- }
32494
- for (const callId of partCallIds(message)) {
32495
- if (calls.has(callId))
32496
- return false;
32497
- calls.add(callId);
32498
- }
32499
- for (const callId of partResultIds(message)) {
32500
- if (results.has(callId))
32501
- return false;
32502
- results.add(callId);
32503
- }
32504
- if (messageRole(message) !== "assistant" && messageParts(message).some(partIsReasoning))
32505
- return false;
32506
- if (providerKey !== "anthropic" && messageParts(message).some((part) => {
32507
- if (!part || typeof part !== "object")
32508
- return false;
32509
- const value = part;
32510
- return (value.type === "text" || value.type === "reasoning") && value.text === "";
32511
- }))
32512
- return false;
32513
- }
32514
- if (!validateLkgSeamBoundary(prefix, tail))
32515
- return false;
32516
- const wireCandidates = all.map((message) => message);
32517
- if (wireCandidates.every((message) => typeof message.role === "string")) {
32518
- const adjacency = assertOpenAiCompatAdjacency(wireCandidates);
32519
- if (!adjacency.ok)
32520
- return false;
32521
- const wireCallIds = new Set;
32522
- for (const wireMessage of wireCandidates) {
32523
- for (const call of wireMessage.tool_calls ?? []) {
32524
- if (wireCallIds.has(call.id))
32525
- return false;
32526
- wireCallIds.add(call.id);
32527
- }
32528
- }
32529
- }
32530
- return true;
32531
- }
32532
- function replayLkg(args) {
32533
- const slot = getSlot(args.sessionId);
32534
- if (!slot)
32535
- return { ok: false, reason: "lkg_invalidated_reshape" };
32536
- const requestedModelKeys = canonicalLkgModelKeys(args.modelKey, args.providerKey);
32537
- const capturedModelKeys = canonicalLkgModelKeys(slot.modelKey, slot.providerKey);
32538
- if (capturedModelKeys.modelKey !== requestedModelKeys.modelKey || capturedModelKeys.providerKey !== requestedModelKeys.providerKey) {
32539
- dropSlot(args.sessionId, "lkg_model_mismatch");
32540
- return { ok: false, reason: "lkg_model_mismatch" };
32541
- }
32542
- const entry = args.entry ?? noteEntry(args.sessionId, args.messages);
32543
- if (!entry || entry.anchorIndex !== slot.inputIdSeq.length - 1 || !entryIdsAreValid(slot, entry.entryInputIds)) {
32544
- dropSlot(args.sessionId, "lkg_invalidated_reshape");
32545
- return { ok: false, reason: "lkg_invalidated_reshape" };
32546
- }
32547
- if (!entryContentIsValid(slot, entry)) {
32548
- dropSlot(args.sessionId, "lkg_content_mismatch");
32549
- return { ok: false, reason: "lkg_content_mismatch" };
32550
- }
32551
- let prefix;
32552
- try {
32553
- const parsed = JSON.parse(slot.jsonPrefix);
32554
- if (!Array.isArray(parsed))
32555
- throw new Error("prefix is not an array");
32556
- prefix = parsed;
32557
- } catch {
32558
- dropSlot(args.sessionId, "lkg_seam_invalid");
32559
- return { ok: false, reason: "lkg_seam_invalid" };
32560
- }
32561
- const replayed = [...prefix, ...entry.pristineTail];
32562
- args.prepareReplay?.(replayed);
32563
- if (!args.skipSeamValidation) {
32564
- if (!validateLkgSeamBoundary(prefix, entry.pristineTail)) {
32565
- dropSlot(args.sessionId, "lkg_unsafe_seam");
32566
- return { ok: false, reason: "lkg_unsafe_seam" };
32567
- }
32568
- if (!validateLkgSeam(prefix, entry.pristineTail, requestedModelKeys.providerKey)) {
32569
- dropSlot(args.sessionId, "lkg_seam_invalid");
32570
- return { ok: false, reason: "lkg_seam_invalid" };
32571
- }
32572
- }
32573
- if (requestedModelKeys.providerKey === "anthropic" && !validateAnthropicReasoningRuns(replayed)) {
32574
- dropSlot(args.sessionId, "lkg_anthropic_reasoning_run_invalid");
32575
- return { ok: false, reason: "lkg_anthropic_reasoning_run_invalid" };
32576
- }
32577
- return { ok: true, messages: replayed };
32578
- }
32579
-
32580
32443
  // src/pi-lkg.ts
32581
32444
  var piLkgSessionStates = new Map;
32582
32445
  function completedProviderUsage(message) {
@@ -32633,6 +32496,7 @@ function clearPiLkgSessionState(sessionId) {
32633
32496
  if (state)
32634
32497
  state.captureSequence += 1;
32635
32498
  piLkgSessionStates.delete(sessionId);
32499
+ clearLkgFenceProcessState(sessionId);
32636
32500
  }
32637
32501
 
32638
32502
  class PiLkgUncapturable extends Error {
@@ -32853,6 +32717,50 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
32853
32717
  }
32854
32718
  return state;
32855
32719
  };
32720
+ const recoveryFor = (snapshot) => {
32721
+ const state = stateFor(snapshot.sessionId);
32722
+ const prefix = state.recoveryPrefix;
32723
+ if (!prefix) {
32724
+ const slot = getSlot(snapshot.sessionId);
32725
+ return lkgRecoveryFenceUnclean(snapshot.sessionId) || slot && lkgFenceRequiresRebuild(snapshot.sessionId, state.acceptedInputs ? slot : loadPersistedLkgSlot(db, snapshot.sessionId) ?? slot, !!state.acceptedInputs) ? { rebuildReason: "lkg_restart_rebuild" } : {};
32726
+ }
32727
+ const durableSlot = loadPersistedLkgSlot(db, snapshot.sessionId) ?? getSlot(snapshot.sessionId);
32728
+ if (snapshot.preparationFailure || !durableSlot || !ownsLkgDirtyFence(snapshot.sessionId, prefix.fenceRevision) || prefix.modelKey !== snapshot.modelKey || prefix.providerKey !== snapshot.providerKey || JSON.stringify(prefix.systemEntries) !== JSON.stringify(snapshot.systemEntries) || exactReusablePrefix(snapshot.inputs, prefix.inputs) !== prefix.inputs.length)
32729
+ return { rebuildReason: "lkg_recovery_input_rebuild" };
32730
+ return { prefix };
32731
+ };
32732
+ const noteRecovery = (snapshot, messages) => {
32733
+ const state = stateFor(snapshot.sessionId);
32734
+ const anchor = snapshot.replayAnchorInputIndex;
32735
+ const slot = getSlot(snapshot.sessionId);
32736
+ if (snapshot.preparationFailure || anchor === null || !slot?.piOutputEntryIds)
32737
+ throw new PiLkgUncapturable("lkg_output_mapping_unavailable", "Cannot retain recovered output ownership");
32738
+ const surviving = new Set(snapshot.inputs.map((input) => input.id));
32739
+ const outputEntryIds = [
32740
+ ...slot.piOutputEntryIds.filter((id) => id === null || surviving.has(id)),
32741
+ ...snapshot.inputs.slice(anchor + 1).map((input) => input.id)
32742
+ ];
32743
+ if (outputEntryIds.length !== messages.length)
32744
+ throw new PiLkgUncapturable("lkg_output_mapping_unavailable", "Recovered output ownership does not match the served array");
32745
+ state.recoveryPrefix = {
32746
+ fenceRevision: markLkgRecoveryDirty({
32747
+ sessionId: snapshot.sessionId,
32748
+ slot,
32749
+ processLocalProof: !!state.acceptedInputs,
32750
+ ownDirtyRevision: state.recoveryPrefix?.fenceRevision
32751
+ }),
32752
+ modelKey: snapshot.modelKey,
32753
+ providerKey: snapshot.providerKey,
32754
+ systemEntries: snapshot.systemEntries,
32755
+ inputs: snapshot.inputs,
32756
+ json: JSON.stringify(messages),
32757
+ outputEntryIds,
32758
+ untaggedInputIds: new Set([
32759
+ ...state.recoveryPrefix?.untaggedInputIds ?? [],
32760
+ ...snapshot.inputs.slice(anchor + 1).map((input) => input.id)
32761
+ ])
32762
+ };
32763
+ };
32856
32764
  const beginPass = (args) => {
32857
32765
  const snapped = snapshotInputs(args.messages, args.entryIds, omitsRootBookkeeping(args));
32858
32766
  const slot = getSlot(args.sessionId);
@@ -32949,7 +32857,8 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
32949
32857
  modelKey: piModelRefToCanonical(request.modelKey).toLowerCase(),
32950
32858
  inputTokens: request.usage.inputTokens,
32951
32859
  envelopeSignature: request.envelopeSignature,
32952
- appendedMessages
32860
+ appendedMessages,
32861
+ previousMessages: JSON.parse(request.jsonPrefix)
32953
32862
  };
32954
32863
  };
32955
32864
  const replay = (snapshot, parentOf) => {
@@ -33169,7 +33078,10 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
33169
33078
  if (args.publishServedNumbers) {
33170
33079
  if (lkgSlotRejection(plan.sessionId, slot))
33171
33080
  throw new PiLkgUncapturable("lkg_slot_rejected", "LKG slot rejected the Pi snapshot");
33172
- if (!saveLkgSlotToDb(db, plan.sessionId, slot, args.publishServedNumbers)) {
33081
+ if (!saveLkgSlotToDb(db, plan.sessionId, slot, args.publishServedNumbers, {
33082
+ rebuild: args.releaseRecovery,
33083
+ retainDirtyRevision: !args.releaseRecovery ? state.recoveryPrefix?.fenceRevision : undefined
33084
+ })) {
33173
33085
  throw new Error("Pi LKG/served publication failed");
33174
33086
  }
33175
33087
  args.assertCurrentPass?.();
@@ -33179,7 +33091,18 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
33179
33091
  }
33180
33092
  state.acceptedInputs = plan.inputs;
33181
33093
  state.acceptedSlot = slot;
33182
- const persisted = args.publishServedNumbers ? true : saveLkgSlotToDb(db, plan.sessionId, slot);
33094
+ if (state.recoveryPrefix) {
33095
+ state.recoveryPrefix = args.releaseRecovery ? undefined : {
33096
+ ...state.recoveryPrefix,
33097
+ inputs: plan.inputs,
33098
+ json: plan.jsonPrefix,
33099
+ outputEntryIds: ownership ?? state.recoveryPrefix.outputEntryIds
33100
+ };
33101
+ }
33102
+ const persisted = args.publishServedNumbers ? true : saveLkgSlotToDb(db, plan.sessionId, slot, undefined, {
33103
+ rebuild: args.releaseRecovery,
33104
+ retainDirtyRevision: state.recoveryPrefix?.fenceRevision
33105
+ });
33183
33106
  state.syncCaptureRequired = !persisted;
33184
33107
  if (args.publishServedNumbers)
33185
33108
  noteCapturedRequest();
@@ -33226,6 +33149,8 @@ function createPiLkgCoordinator(db, scheduleCapture = (capture) => setImmediate(
33226
33149
  return state.outputSnapshot ?? undefined;
33227
33150
  };
33228
33151
  return {
33152
+ noteRecovery,
33153
+ recoveryFor,
33229
33154
  beginPass(args) {
33230
33155
  return {
33231
33156
  ...beginPass(args),
@@ -33290,7 +33215,7 @@ function resolvePiLkgOutputEntryIds(messages, syntheticLeadingCount, entryId) {
33290
33215
  }
33291
33216
 
33292
33217
  // src/pi-lkg-fit-envelope.ts
33293
- import { createHash as createHash13 } from "node:crypto";
33218
+ import { createHash as createHash12 } from "node:crypto";
33294
33219
  function readPiLkgFitEnvelope(ctx, pi, modelKey, frozen, wireSchema) {
33295
33220
  try {
33296
33221
  if (!modelKey || typeof pi.getAllTools !== "function")
@@ -33352,7 +33277,7 @@ function readPiLkgFitEnvelope(ctx, pi, modelKey, frozen, wireSchema) {
33352
33277
  refusalToolDefinitionTokens,
33353
33278
  toolDefinitionsMeasured: refusalToolDefinitionTokens !== undefined,
33354
33279
  envelopeBytes: Buffer.byteLength(envelopeJson),
33355
- envelopeSignature: activeNames ? createHash13("sha256").update(envelopeJson).update(JSON.stringify(activeNames)).digest("hex") : undefined,
33280
+ envelopeSignature: activeNames ? createHash12("sha256").update(envelopeJson).update(JSON.stringify(activeNames)).digest("hex") : undefined,
33356
33281
  calibration
33357
33282
  };
33358
33283
  } catch {
@@ -33361,13 +33286,13 @@ function readPiLkgFitEnvelope(ctx, pi, modelKey, frozen, wireSchema) {
33361
33286
  }
33362
33287
 
33363
33288
  // src/pi-message-identity.ts
33364
- import { createHash as createHash16 } from "node:crypto";
33289
+ import { createHash as createHash15 } from "node:crypto";
33365
33290
 
33366
33291
  // src/pi-tool-identity.ts
33367
- import { createHash as createHash15 } from "node:crypto";
33292
+ import { createHash as createHash14 } from "node:crypto";
33368
33293
 
33369
33294
  // src/served-array-ledger.ts
33370
- import { createHash as createHash14 } from "node:crypto";
33295
+ import { createHash as createHash13 } from "node:crypto";
33371
33296
  import { readFileSync as readFileSync11, statSync as statSync6 } from "node:fs";
33372
33297
  import * as path12 from "node:path";
33373
33298
 
@@ -33527,7 +33452,7 @@ function getPiLastServedArray(sessionId) {
33527
33452
  return previous ? `[${previous.serializedMessages.join(",")}]` : undefined;
33528
33453
  }
33529
33454
  function sha256(value) {
33530
- return createHash14("sha256").update(value).digest("hex");
33455
+ return createHash13("sha256").update(value).digest("hex");
33531
33456
  }
33532
33457
  function safeSessionFileStem(sessionId) {
33533
33458
  const readable = sessionId.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 96);
@@ -33644,20 +33569,21 @@ function capturePiServedArray(sessionId, messages, options = {}) {
33644
33569
  const digest = sha256(serializedArray);
33645
33570
  const storageDir = options.storageDir ?? getMagicContextStorageDir();
33646
33571
  identityPersistenceFailed = true;
33647
- const previousNumbers = getPiServedTagNumbers(sessionId, storageDir);
33572
+ const previousNumbers = options.recoveryWithoutTagState ? new Set : getPiServedTagNumbers(sessionId, storageDir);
33573
+ const managedNumbers = options.recoveryWithoutTagState ? [] : options.servedTagNumbers ?? [];
33648
33574
  identityPersistenceFailed = false;
33649
33575
  const served = new Set(previousNumbers);
33650
- if (options.db) {
33576
+ if (options.db && !options.recoveryWithoutTagState) {
33651
33577
  identityPersistenceFailed = true;
33652
33578
  for (const number of readPiCommittedServedNumbers(options.db, sessionId))
33653
33579
  served.add(number);
33654
- for (const number of options.servedTagNumbers ?? []) {
33580
+ for (const number of managedNumbers) {
33655
33581
  if (!served.has(number))
33656
33582
  throw new PiServedIdentityError(new Error("Pi identities have no committed LKG"));
33657
33583
  }
33658
33584
  identityPersistenceFailed = false;
33659
33585
  }
33660
- for (const number of options.servedTagNumbers ?? []) {
33586
+ for (const number of managedNumbers) {
33661
33587
  if (Number.isSafeInteger(number) && number > 0)
33662
33588
  served.add(number);
33663
33589
  }
@@ -33797,7 +33723,7 @@ function readPiServedCachedArray(sessionId) {
33797
33723
  const memory = getPiLastServedArray(sessionId);
33798
33724
  const slot = memory === undefined ? getSlot(sessionId) : undefined;
33799
33725
  const jsonPrefix = memory ?? slot?.jsonPrefix;
33800
- if (jsonPrefix === undefined || createHash15("sha256").update(jsonPrefix).digest("hex") !== getPiLastServedDigest(sessionId))
33726
+ if (jsonPrefix === undefined || createHash14("sha256").update(jsonPrefix).digest("hex") !== getPiLastServedDigest(sessionId))
33801
33727
  return;
33802
33728
  let parsed;
33803
33729
  try {
@@ -33821,7 +33747,7 @@ function piMessageEntryFingerprint(message) {
33821
33747
  const m = message;
33822
33748
  if (typeof m.role !== "string")
33823
33749
  return null;
33824
- const contentHash = createHash16("sha256").update(stableStringify(m.content)).digest("hex");
33750
+ const contentHash = createHash15("sha256").update(stableStringify(m.content)).digest("hex");
33825
33751
  return JSON.stringify([
33826
33752
  typeof m.responseId === "string" ? m.responseId : null,
33827
33753
  typeof m.timestamp === "number" || typeof m.timestamp === "string" ? m.timestamp : null,
@@ -34226,6 +34152,7 @@ function tokenizePiMessages(messages, options) {
34226
34152
  }
34227
34153
  if (!Array.isArray(content))
34228
34154
  continue;
34155
+ let opaqueCounted = false;
34229
34156
  for (const part of content) {
34230
34157
  if (!part || typeof part !== "object")
34231
34158
  continue;
@@ -34234,14 +34161,15 @@ function tokenizePiMessages(messages, options) {
34234
34161
  case "text":
34235
34162
  if (typeof p.text === "string")
34236
34163
  conversation += estimateTokens(p.text);
34237
- if (typeof p.textSignature === "string")
34238
- conversation += estimateTokens(p.textSignature);
34239
34164
  break;
34240
34165
  case "thinking":
34241
- if (typeof p.thinking === "string")
34166
+ case "redacted_thinking":
34167
+ if (!p.redacted && typeof p.thinking === "string")
34242
34168
  conversation += estimateTokens(p.thinking);
34243
- if (typeof p.thinkingSignature === "string")
34244
- conversation += estimateTokens(p.thinkingSignature);
34169
+ if (!opaqueCounted && (p.redacted || p.type === "redacted_thinking" || !p.thinking && p.thinkingSignature)) {
34170
+ opaqueCounted = true;
34171
+ conversation += opaqueThinkingCost(msg.usage?.reasoning, msg.usage?.output).tokens;
34172
+ }
34245
34173
  break;
34246
34174
  case "image":
34247
34175
  conversation += 1200;
@@ -34305,7 +34233,11 @@ function tokenizePiMessages(messages, options) {
34305
34233
  function buildTokenCacheFingerprint(value) {
34306
34234
  const message = value;
34307
34235
  const role = typeof message.role === "string" ? message.role : null;
34308
- const fingerprint = [role];
34236
+ const fingerprint = [
34237
+ role,
34238
+ String(message.usage?.reasoning ?? ""),
34239
+ String(message.usage?.output ?? "")
34240
+ ];
34309
34241
  if (role !== "user" && role !== "assistant" && role !== "toolResult") {
34310
34242
  return fingerprint;
34311
34243
  }
@@ -34335,7 +34267,8 @@ function buildTokenCacheFingerprint(value) {
34335
34267
  fingerprint.push("text", typeof part.text === "string" ? part.text : null, typeof part.textSignature === "string" ? part.textSignature : null);
34336
34268
  break;
34337
34269
  case "thinking":
34338
- fingerprint.push("thinking", typeof part.thinking === "string" ? part.thinking : null, typeof part.thinkingSignature === "string" ? part.thinkingSignature : null);
34270
+ case "redacted_thinking":
34271
+ fingerprint.push(part.type, String(part.redacted ?? false), typeof part.thinking === "string" ? part.thinking : null, typeof part.thinkingSignature === "string" ? part.thinkingSignature : null);
34339
34272
  break;
34340
34273
  case "image":
34341
34274
  fingerprint.push("image");
@@ -34349,6 +34282,39 @@ function buildTokenCacheFingerprint(value) {
34349
34282
  }
34350
34283
  return fingerprint;
34351
34284
  }
34285
+ function piOpaqueThinkingFallbackSteps(messages) {
34286
+ return messages.filter((raw) => {
34287
+ if (!raw || typeof raw !== "object")
34288
+ return false;
34289
+ const message = raw;
34290
+ return opaqueThinkingCost(message.usage?.reasoning, message.usage?.output).fallback && Array.isArray(message.content) && message.content.some((p) => p && (p.type === "redacted_thinking" || p.type === "thinking" && (p.redacted || !p.thinking && p.thinkingSignature)));
34291
+ }).length;
34292
+ }
34293
+ function piFitMessageBytes(raw) {
34294
+ const message = raw;
34295
+ const opaque = Array.isArray(message.content) && message.content.some((p) => p && (p.type === "redacted_thinking" || p.type === "thinking" && (p.redacted || !p.thinking && p.thinkingSignature)));
34296
+ if (!opaque && (!Array.isArray(message.content) || !message.content.some((part) => part && (part.type === "thinking" && part.thinkingSignature !== undefined || part.type === "text" && part.textSignature !== undefined))))
34297
+ return Buffer.byteLength(JSON.stringify(raw));
34298
+ const content = Array.isArray(message.content) ? message.content.map((part) => {
34299
+ if (!part || typeof part !== "object")
34300
+ return part;
34301
+ if (part.type === "redacted_thinking" || part.type === "thinking" && part.redacted)
34302
+ return { type: part.type, redacted: true };
34303
+ if (part.type === "thinking") {
34304
+ const plain = { ...part };
34305
+ delete plain.thinkingSignature;
34306
+ return plain;
34307
+ }
34308
+ if (part.type === "text") {
34309
+ const plain = { ...part };
34310
+ delete plain.textSignature;
34311
+ return plain;
34312
+ }
34313
+ return part;
34314
+ }) : undefined;
34315
+ const bytes = Buffer.byteLength(JSON.stringify(content ? { ...message, content } : raw));
34316
+ return bytes + (opaque ? 4 * opaqueThinkingCost(message.usage?.reasoning, message.usage?.output).tokens : 0);
34317
+ }
34352
34318
  function tokenCacheFingerprintsEqual(left, right) {
34353
34319
  if (left.length !== right.length)
34354
34320
  return false;
@@ -34441,7 +34407,7 @@ function estimatePiOutgoingInputTokens(messages, observed, measuredPrefix, conte
34441
34407
  if (!message || typeof message !== "object")
34442
34408
  return false;
34443
34409
  const m = message;
34444
- return ["user", "assistant", "toolResult"].includes(m.role ?? "") && (typeof m.content === "string" || Array.isArray(m.content) && m.content.every((p) => p && typeof p === "object" && ["text", "thinking", "toolCall"].includes(String(p.type))));
34410
+ return ["user", "assistant", "toolResult"].includes(m.role ?? "") && (typeof m.content === "string" || Array.isArray(m.content) && m.content.every((p) => p && typeof p === "object" && ["text", "thinking", "redacted_thinking", "toolCall"].includes(String(p.type))));
34445
34411
  });
34446
34412
  if (!complete)
34447
34413
  return { tokens: 0, trusted: false };
@@ -34458,9 +34424,7 @@ function estimatePiOutgoingInputTokens(messages, observed, measuredPrefix, conte
34458
34424
  for (const part of message.content) {
34459
34425
  for (const value of [
34460
34426
  part.text,
34461
- part.thinking,
34462
- part.thinkingSignature,
34463
- part.textSignature,
34427
+ part.redacted ? undefined : part.thinking,
34464
34428
  part.name
34465
34429
  ])
34466
34430
  if (typeof value === "string")
@@ -34485,7 +34449,7 @@ function estimatePiOutgoingInputTokens(messages, observed, measuredPrefix, conte
34485
34449
  tools: observed.toolDefinitionTokens
34486
34450
  }, observed.calibration ?? calibrationForModelKey(observed.modelKey), true);
34487
34451
  const fit = observed.calibration ?? calibrationForModelKey(observed.modelKey);
34488
- const upper = envelope + Math.max(UNKNOWN_FIT_RATIO, fit.toolsRatio, fit.proseRatio) * Buffer.byteLength(JSON.stringify(priced));
34452
+ const upper = envelope + Math.max(UNKNOWN_FIT_RATIO, fit.toolsRatio, fit.proseRatio) * priced.reduce((sum, message) => sum + piFitMessageBytes(message), 0);
34489
34453
  if (upper <= contextLimit)
34490
34454
  return {
34491
34455
  tokens: upper,
@@ -34500,9 +34464,7 @@ function estimatePiOutgoingInputTokens(messages, observed, measuredPrefix, conte
34500
34464
  return tokenCountUsesByteBound(content);
34501
34465
  return content.some((part) => [
34502
34466
  part.text,
34503
- part.thinking,
34504
- part.thinkingSignature,
34505
- part.textSignature,
34467
+ part.redacted ? undefined : part.thinking,
34506
34468
  part.name,
34507
34469
  part.arguments === undefined ? undefined : JSON.stringify(part.arguments)
34508
34470
  ].some((value) => typeof value === "string" && tokenCountUsesByteBound(value)));
@@ -34511,7 +34473,7 @@ function estimatePiOutgoingInputTokens(messages, observed, measuredPrefix, conte
34511
34473
  return {
34512
34474
  tokens: providerMass({
34513
34475
  system: observed.systemTokens,
34514
- tools: observed.toolDefinitionTokens + Buffer.byteLength(JSON.stringify(messages))
34476
+ tools: observed.toolDefinitionTokens + messages.reduce((sum, message) => sum + piFitMessageBytes(message), 0)
34515
34477
  }, observed.calibration ?? calibrationForModelKey(observed.modelKey), true),
34516
34478
  trusted: true,
34517
34479
  refusalGrade: false,
@@ -34531,9 +34493,7 @@ function estimatePiOutgoingInputTokens(messages, observed, measuredPrefix, conte
34531
34493
  return !tokenCountUsesByteBound(content);
34532
34494
  return content.every((part) => [
34533
34495
  part.text,
34534
- part.thinking,
34535
- part.thinkingSignature,
34536
- part.textSignature,
34496
+ part.redacted ? undefined : part.thinking,
34537
34497
  part.name,
34538
34498
  part.arguments === undefined ? undefined : JSON.stringify(part.arguments)
34539
34499
  ].every((value) => typeof value !== "string" || !tokenCountUsesByteBound(value)));
@@ -34566,12 +34526,7 @@ function assertPiRawFallbackFits(messages, contextLimit, log, cause, observed, m
34566
34526
  let serializationFailed = false;
34567
34527
  try {
34568
34528
  for (const message of pricedMessages) {
34569
- const serialized = JSON.stringify(message);
34570
- if (typeof serialized !== "string") {
34571
- serializationFailed = true;
34572
- break;
34573
- }
34574
- bytes += Buffer.byteLength(serialized) + 1;
34529
+ bytes += piFitMessageBytes(message) + 1;
34575
34530
  if (baseInputTokens + Math.ceil(bytes / 4) > contextLimit)
34576
34531
  break;
34577
34532
  }
@@ -34587,7 +34542,7 @@ function assertPiRawFallbackFits(messages, contextLimit, log, cause, observed, m
34587
34542
  if (!message || typeof message !== "object")
34588
34543
  return false;
34589
34544
  const m = message;
34590
- return ["user", "assistant", "toolResult"].includes(m.role ?? "") && (typeof m.content === "string" || Array.isArray(m.content) && m.content.every((p) => p !== null && typeof p === "object" && ["text", "thinking", "toolCall"].includes(String(p.type))));
34545
+ return ["user", "assistant", "toolResult"].includes(m.role ?? "") && (typeof m.content === "string" || Array.isArray(m.content) && m.content.every((p) => p !== null && typeof p === "object" && ["text", "thinking", "redacted_thinking", "toolCall"].includes(String(p.type))));
34591
34546
  });
34592
34547
  const raw = tokenizePiMessages([...pricedMessages]);
34593
34548
  if (!hasTokenizerForFit()) {
@@ -35016,8 +34971,13 @@ function applyPiProactiveThinkingStrip(args) {
35016
34971
  if (protectedMessages.has(args.messages[index]))
35017
34972
  continue;
35018
34973
  const entryId = args.entryIds[index];
35019
- if (!entryId || !hasThinkingPart(args.messages[index]))
34974
+ if (!hasThinkingPart(args.messages[index]))
35020
34975
  continue;
34976
+ if (!entryId) {
34977
+ if (args.requirePersistence)
34978
+ throw new Error("Cannot persist thinking omission without a stable entry id");
34979
+ continue;
34980
+ }
35021
34981
  entryIds.push(entryId);
35022
34982
  indices.push(index);
35023
34983
  }
@@ -35033,6 +34993,8 @@ function applyPiProactiveThinkingStrip(args) {
35033
34993
  persisted = false;
35034
34994
  }
35035
34995
  if (!persisted) {
34996
+ if (args.requirePersistence)
34997
+ throw new Error("Cannot persist thinking omissions before recovery prefix rebuild");
35036
34998
  reportBindingRecovery(args.sessionId, args.report, "proactive thinking strip: persistence failed; serving the thinking unchanged");
35037
34999
  return null;
35038
35000
  }
@@ -35763,7 +35725,97 @@ function stripPiProcessedImages(args) {
35763
35725
  }
35764
35726
 
35765
35727
  // src/system-prompt.ts
35766
- import { createHash as createHash17 } from "node:crypto";
35728
+ import { createHash as createHash16 } from "node:crypto";
35729
+
35730
+ // ../plugin/src/hooks/magic-context/system-prompt-dates.ts
35731
+ function replaceHostDates(prompt, replace) {
35732
+ const fields = /<(plugin-env|environment|env)>[\s\S]*?<\/\1>|Today's date: [^\r\n<]+/g;
35733
+ return prompt.replace(fields, (block) => block.replace(/(^[\t ]*(?:Date|Today's date):[\t ]*)([^\r\n<]+)/gm, (_line, label, date) => `${label}${replace(date)}`));
35734
+ }
35735
+ function systemPromptDates(prompt, sticky) {
35736
+ const values = [];
35737
+ replaceHostDates(prompt, (date) => {
35738
+ values.push(date);
35739
+ return date;
35740
+ });
35741
+ const prior = sticky ? JSON.parse(sticky) : [];
35742
+ let index = 0;
35743
+ const stable = replaceHostDates(prompt, (date) => prior[index++] ?? date);
35744
+ return { live: values.length ? JSON.stringify(values) : undefined, stable };
35745
+ }
35746
+
35747
+ // src/system-prompt-delivery-pi.ts
35748
+ var requests = new BoundedSessionMap(1000);
35749
+ function beginPiSystemPromptRequest(db, sessionId, modelKey, branch) {
35750
+ acknowledgePiPendingSystemPromptResponses(sessionId);
35751
+ const request = {
35752
+ kind: "v2",
35753
+ startedAt: Date.now(),
35754
+ previousResponseId: undefined,
35755
+ modelKey: piModelRefToCanonical(modelKey)
35756
+ };
35757
+ requests.set(sessionId, { request, branch, replies: [] });
35758
+ recordSystemPromptForRequest(sessionId, request, getOrCreateSessionMeta(db, sessionId).systemPromptHash, db);
35759
+ }
35760
+ function recordPiHeldSystemHead(sessionId, deferRefresh) {
35761
+ recordHeldHeadForRequest(sessionId, requests.get(sessionId)?.request, deferRefresh);
35762
+ }
35763
+ function acknowledgePiSystemPromptResponse(sessionId, message) {
35764
+ const saved = requests.get(sessionId);
35765
+ if (!saved?.branch || !message || typeof message !== "object" || message.role !== "assistant")
35766
+ return;
35767
+ if (!saved.replies.includes(message)) {
35768
+ if (saved.replies.length === 32)
35769
+ saved.replies.shift();
35770
+ saved.replies.push(message);
35771
+ }
35772
+ acknowledgePiPendingSystemPromptResponses(sessionId);
35773
+ }
35774
+ function acknowledgePiPendingSystemPromptResponses(sessionId) {
35775
+ const saved = requests.get(sessionId);
35776
+ if (!saved?.branch)
35777
+ return;
35778
+ let entries;
35779
+ try {
35780
+ entries = saved.branch.readBranch();
35781
+ } catch {
35782
+ return;
35783
+ }
35784
+ if (!entries)
35785
+ return;
35786
+ for (const value of entries) {
35787
+ if (!value || typeof value !== "object")
35788
+ continue;
35789
+ const entry = value;
35790
+ if (entry.type !== "message" || !entry.id || entry.parentId !== saved.branch.parentId || !entry.message || !saved.replies.includes(entry.message))
35791
+ continue;
35792
+ const reply = entry.message;
35793
+ if (!reply.provider || !reply.model || typeof reply.timestamp !== "number")
35794
+ continue;
35795
+ const completion = { finish: reply.stopReason, error: reply.errorMessage };
35796
+ if (!isSuccessfulProviderCompletion(completion) && !providerResponseFailed(completion))
35797
+ continue;
35798
+ const response = {
35799
+ sessionId,
35800
+ request: saved.request,
35801
+ responseId: entry.id,
35802
+ createdAt: reply.timestamp,
35803
+ modelKey: piModelRefToCanonical(`${reply.provider}/${reply.model}`),
35804
+ ...completion,
35805
+ v2: true
35806
+ };
35807
+ bindSystemPromptResponse(sessionId, saved.request, response);
35808
+ acknowledgeSystemPromptDelivery(response);
35809
+ requests.delete(sessionId);
35810
+ return;
35811
+ }
35812
+ }
35813
+ function clearPiSystemPromptDelivery(sessionId) {
35814
+ requests.delete(sessionId);
35815
+ clearSystemPromptDelivery(sessionId);
35816
+ }
35817
+
35818
+ // src/system-prompt.ts
35767
35819
  var MAGIC_CONTEXT_MARKER = "## Magic Context";
35768
35820
  var stickyDateBySession = new Map;
35769
35821
  function buildMagicContextBlock(opts) {
@@ -35778,7 +35830,6 @@ function composeMagicContextSystemPrompt(basePrompt, block) {
35778
35830
 
35779
35831
  ${block}` : basePrompt;
35780
35832
  }
35781
- var DATE_PATTERN = /Today's date: .+/;
35782
35833
  function processSystemPromptForCache(args) {
35783
35834
  const { db, sessionId, systemPrompt, isCacheBusting } = args;
35784
35835
  let sessionMeta;
@@ -35790,11 +35841,13 @@ function processSystemPromptForCache(args) {
35790
35841
  const previousHash = sessionMeta?.systemPromptHash ?? "";
35791
35842
  const isFirstHash = previousHash === "" || previousHash === "0";
35792
35843
  let frozenPrompt = systemPrompt;
35793
- const dateMatch = systemPrompt.match(DATE_PATTERN);
35794
- const liveDate = dateMatch ? dateMatch[0] : null;
35844
+ if (isFirstHash)
35845
+ stickyDateBySession.delete(sessionId);
35795
35846
  const stickyDate = stickyDateBySession.get(sessionId);
35796
- const stableCandidate = liveDate && stickyDate && liveDate !== stickyDate ? systemPrompt.replace(DATE_PATTERN, stickyDate) : systemPrompt;
35797
- const stableCandidateHash = createHash17("md5").update(promptSurfaceHashMaterial(stableCandidate, args.promptSurfacePreset)).digest("hex");
35847
+ const dates = systemPromptDates(systemPrompt, stickyDate);
35848
+ const liveDate = dates.live;
35849
+ const stableCandidate = dates.stable;
35850
+ const stableCandidateHash = createHash16("md5").update(promptSurfaceHashMaterial(stableCandidate, args.promptSurfacePreset)).digest("hex");
35798
35851
  const contentOrPresetChanged = !isFirstHash && stableCandidateHash !== previousHash;
35799
35852
  const idleCacheExpired = sessionMeta !== undefined && computeHardCacheExpired(sessionMeta.cacheTtl, sessionMeta.lastResponseTime, Date.now());
35800
35853
  const dateMayAdvance = isCacheBusting || idleCacheExpired || contentOrPresetChanged;
@@ -35805,11 +35858,11 @@ function processSystemPromptForCache(args) {
35805
35858
  stickyDateBySession.set(sessionId, liveDate);
35806
35859
  sessionLog2(sessionId, `system prompt date updated: ${stickyDate} → ${liveDate} (cache-busting pass)`);
35807
35860
  } else {
35808
- frozenPrompt = systemPrompt.replace(DATE_PATTERN, stickyDate);
35861
+ frozenPrompt = stableCandidate;
35809
35862
  sessionLog2(sessionId, `system prompt date frozen: real=${liveDate}, using=${stickyDate} (cache-stable pass)`);
35810
35863
  }
35811
35864
  }
35812
- const currentHash = createHash17("md5").update(promptSurfaceHashMaterial(frozenPrompt, args.promptSurfacePreset)).digest("hex");
35865
+ const currentHash = createHash16("md5").update(promptSurfaceHashMaterial(frozenPrompt, args.promptSurfacePreset)).digest("hex");
35813
35866
  const hashChanged = !isFirstHash && currentHash !== previousHash;
35814
35867
  if (hashChanged) {
35815
35868
  sessionLog2(sessionId, `system prompt hash changed: ${previousHash} → ${currentHash} (len=${frozenPrompt.length})`);
@@ -35834,6 +35887,7 @@ function processSystemPromptForCache(args) {
35834
35887
  };
35835
35888
  }
35836
35889
  function clearPiSystemPromptSession(sessionId) {
35890
+ clearPiSystemPromptDelivery(sessionId);
35837
35891
  stickyDateBySession.delete(sessionId);
35838
35892
  }
35839
35893
 
@@ -36453,6 +36507,21 @@ var systemPromptRefreshSessions = new Set;
36453
36507
  var pendingMaterializationSessions = new Set;
36454
36508
  var deferredHistoryRefreshSessions = new Set;
36455
36509
  var deferredMaterializationSessions = new Set;
36510
+ function signalPiSystemHashChange(sessionId, hash) {
36511
+ recordSystemRefreshOwnership(sessionId, hash, !historyRefreshSessions.has(sessionId), historyRefreshSessions, pendingMaterializationSessions);
36512
+ signalPiHistoryRefresh(sessionId);
36513
+ signalPiSystemPromptRefresh(sessionId);
36514
+ if (!pendingMaterializationSessions.has(sessionId))
36515
+ signalPiPendingMaterialization(sessionId, "system_hash");
36516
+ }
36517
+ function deferPiDeliveredSystemRefresh(sessionId, ownsHistory) {
36518
+ deferDeliveredSystemRefresh({
36519
+ historyRefreshSessions,
36520
+ pendingMaterializationSessions,
36521
+ deferredHistoryRefreshSessions,
36522
+ deferredMaterializationSessions
36523
+ }, sessionId, ownsHistory);
36524
+ }
36456
36525
  var sessionsByProject = new Map;
36457
36526
  var lastSeenProjectIdentityBySession = new Map;
36458
36527
  var persistedProjectIdentityBySession = new Map;
@@ -36464,14 +36533,24 @@ var lastHeuristicsTurnIdBySession = new Map;
36464
36533
  var routinePressureAppliedBySession = new Map;
36465
36534
  var firstContextPassSeenBySession = new Set;
36466
36535
  var contextPassGeneration = new Map;
36536
+ function createPiContextGenerationGuard(assertOperation, passSessionId, generation, sideTurn, signal) {
36537
+ return () => {
36538
+ assertOperation();
36539
+ if (!sideTurn && passSessionId && contextPassGeneration.get(passSessionId) !== generation)
36540
+ throw new PiContextSupersededError("Pi context pass superseded by a newer context generation", "context generation");
36541
+ signal?.throwIfAborted();
36542
+ };
36543
+ }
36467
36544
 
36468
36545
  class PiLkgAdmissionReplay extends Error {
36469
36546
  messages;
36470
36547
  recovery;
36471
- constructor(messages, recovery = "fitting LKG before writer retries") {
36548
+ trigger;
36549
+ constructor(messages, recovery = "fitting LKG before writer retries", trigger = "writer_busy") {
36472
36550
  super("Saved request served before writer wait");
36473
36551
  this.messages = messages;
36474
36552
  this.recovery = recovery;
36553
+ this.trigger = trigger;
36475
36554
  }
36476
36555
  }
36477
36556
  var liveModelBySession = new Map;
@@ -36646,8 +36725,8 @@ function signalPiHistoryRefresh(sessionId) {
36646
36725
  function signalPiSystemPromptRefresh(sessionId) {
36647
36726
  systemPromptRefreshSessions.add(sessionId);
36648
36727
  }
36649
- function signalPiPendingMaterialization(sessionId) {
36650
- pendingMaterializationSessions.add(sessionId);
36728
+ function signalPiPendingMaterialization(sessionId, origin = "user_flush") {
36729
+ requestPendingMaterialization(pendingMaterializationSessions, sessionId, origin);
36651
36730
  }
36652
36731
  function clearPiM0Cache(db, sessionId, reason) {
36653
36732
  clearM0M1PiCache(db, sessionId, reason);
@@ -36774,7 +36853,7 @@ function hasPendingMaterialization(sessionId) {
36774
36853
  }
36775
36854
  function consumePendingMaterialization(sessionId) {
36776
36855
  const wasSet = pendingMaterializationSessions.has(sessionId);
36777
- pendingMaterializationSessions.delete(sessionId);
36856
+ clearPendingMaterialization(pendingMaterializationSessions, sessionId);
36778
36857
  return wasSet;
36779
36858
  }
36780
36859
  function resolveSessionId2(ctx) {
@@ -38047,7 +38126,7 @@ function registerPiContextHandler(pi, baseOptions) {
38047
38126
  sessionLog2(sessionId, `variant changed (${event.previousLevel} -> ${event.level}), triggering flush`);
38048
38127
  historyRefreshSessions.add(sessionId);
38049
38128
  systemPromptRefreshSessions.add(sessionId);
38050
- pendingMaterializationSessions.add(sessionId);
38129
+ requestPendingMaterialization(pendingMaterializationSessions, sessionId, "variant_change");
38051
38130
  lastHeuristicsTurnIdBySession.delete(sessionId);
38052
38131
  return;
38053
38132
  }
@@ -38061,14 +38140,8 @@ function registerPiContextHandler(pi, baseOptions) {
38061
38140
  const generation = Symbol();
38062
38141
  if (passSessionId && !budget.sideTurn)
38063
38142
  contextPassGeneration.set(passSessionId, generation);
38064
- const signal = event.signal ?? ctx.signal;
38065
- const assertOperation = budget.assertOwner;
38066
- budget.assertOwner = () => {
38067
- assertOperation();
38068
- if (!budget.sideTurn && passSessionId && contextPassGeneration.get(passSessionId) !== generation)
38069
- throw new PiContextSupersededError("Pi context pass superseded by a newer context generation", "context generation");
38070
- signal?.throwIfAborted();
38071
- };
38143
+ const signal = budget.signal;
38144
+ budget.assertOwner = createPiContextGenerationGuard(budget.assertOwner, passSessionId, generation, budget.sideTurn, signal);
38072
38145
  let assertCurrentPass = budget.assert;
38073
38146
  const guardAwait = budget.wait;
38074
38147
  const passGuard = { assert: assertCurrentPass, wait: guardAwait };
@@ -38114,6 +38187,11 @@ function registerPiContextHandler(pi, baseOptions) {
38114
38187
  rawMessageCount = event.messages.length;
38115
38188
  const fullWireMessageCount = rawMessageCount;
38116
38189
  const options = baseOptions.resolveForProject?.(projectDirectory) ?? baseOptions;
38190
+ const deliveryModelKey = resolvePiContextModelKey(ctx);
38191
+ if (!budget.sideTurn && deliveryModelKey) {
38192
+ const parentId = ctx.sessionManager.getLeafId?.();
38193
+ beginPiSystemPromptRequest(options.db, sessionId, deliveryModelKey, parentId === null || typeof parentId === "string" ? { parentId, readBranch: () => ctx.sessionManager.getBranch() } : undefined);
38194
+ }
38117
38195
  const schedulerConfig = options.scheduler ?? DEFAULT_SCHEDULER_CONFIG;
38118
38196
  const scheduler = schedulerFor(options);
38119
38197
  lkgCompactionOff = options.compactionOff === true;
@@ -38167,6 +38245,7 @@ function registerPiContextHandler(pi, baseOptions) {
38167
38245
  transport: ctx.model?.transport
38168
38246
  });
38169
38247
  lkgPassSnapshot = snapshot;
38248
+ const recovery = budget.sideTurn || lkgCompactionOff ? {} : lkgCoordinator.recoveryFor(snapshot);
38170
38249
  const lkgInputFields = new WeakMap(snapshot.inputs.flatMap((input) => {
38171
38250
  const message = event.messages[input.messageIndex];
38172
38251
  return message && typeof message === "object" ? [[message, input.fields]] : [];
@@ -38195,7 +38274,7 @@ function registerPiContextHandler(pi, baseOptions) {
38195
38274
  rawContextWindow: piUsage?.contextWindow,
38196
38275
  detectedContextLimit: state.detectedContextLimit
38197
38276
  })?.usableHard;
38198
- if (lkgCompactionOff || lkgEmergencyRecoveryArmed || isProviderOverflowFailClosedProven(sessionId))
38277
+ if (lkgCompactionOff || recovery.rebuildReason || lkgEmergencyRecoveryArmed || isProviderOverflowFailClosedProven(sessionId))
38199
38278
  return;
38200
38279
  const replay = lkgCoordinator.replay(snapshot, (id) => ctx.sessionManager.getEntry?.(id)?.parentId);
38201
38280
  if (!replay.ok)
@@ -38490,7 +38569,7 @@ function registerPiContextHandler(pi, baseOptions) {
38490
38569
  }
38491
38570
  if (stableIdSchemeCutover && !options.compactionOff) {
38492
38571
  schedulerDecision = "execute";
38493
- signalPiPendingMaterialization(sessionId);
38572
+ signalPiPendingMaterialization(sessionId, "tag_identity_repair");
38494
38573
  sessionLog2(sessionId, `stable-id scheme cutover: stored=${storedStableIdScheme} < current=${PI_STABLE_ID_SCHEME} — forcing execute+materialize this pass`);
38495
38574
  }
38496
38575
  const tBoundaryChecks = performance.now();
@@ -38560,6 +38639,8 @@ function registerPiContextHandler(pi, baseOptions) {
38560
38639
  assertCurrentPass();
38561
38640
  const inputForThinkingFit = isPrefixBoundThinkingModel(ctx.model?.provider, ctx.model?.id) ? structuredClone(event.messages) : null;
38562
38641
  const pipelineArgs = {
38642
+ recoveryPrefix: recovery.prefix,
38643
+ recoveryRebuildReason: recovery.rebuildReason,
38563
38644
  assertCurrentPass,
38564
38645
  db: options.db,
38565
38646
  tagger,
@@ -38641,12 +38722,12 @@ function registerPiContextHandler(pi, baseOptions) {
38641
38722
  return;
38642
38723
  }
38643
38724
  logPiLkgRecovery(sessionId, "Pi held identity rebuild: replaying the served prefix and retaining the pending repair");
38644
- throw new PiLkgAdmissionReplay(replay.messages, "held tag-identity rebuild: replaying the served prefix");
38725
+ throw new PiLkgAdmissionReplay(replay.messages, "held tag-identity rebuild: replaying the served prefix", "held_identity_repair");
38645
38726
  }
38646
38727
  };
38647
38728
  let result = await budget.waitMandatory(runPipeline(pipelineArgs));
38648
38729
  logTransformTiming(sessionId, "runPipeline", tRunPipeline);
38649
- if (result.identityRebuilt)
38730
+ if (result.identityRebuilt || result.lkgFrozenReleaseReason)
38650
38731
  schedulerDecision = "execute";
38651
38732
  const postPipelineStart = performance.now();
38652
38733
  const tTransformDecision = performance.now();
@@ -38669,7 +38750,8 @@ function registerPiContextHandler(pi, baseOptions) {
38669
38750
  droppedTokens: result.droppedTokens,
38670
38751
  droppedCount: result.droppedCount,
38671
38752
  inputTokens: usageInputTokens,
38672
- bustedThisPass: true
38753
+ bustedThisPass: true,
38754
+ lkgFrozenReleaseReason: result.lkgFrozenReleaseReason
38673
38755
  }, piDecisionSnapshotNewestAssistant, budget.assertDecisionPublication);
38674
38756
  } : undefined;
38675
38757
  logTransformTiming(sessionId, "transformDecisionAndReuseState", tTransformDecision);
@@ -38838,15 +38920,38 @@ function registerPiContextHandler(pi, baseOptions) {
38838
38920
  entryIds: outputEntryIds,
38839
38921
  provider: lkgProviderKey ?? undefined,
38840
38922
  model: ctx.model?.id,
38841
- cacheBustingPass: result.signedPrefixRewritten || result.prefixBustPermitted && !result.strictThinkingKept && (isCacheBusting || result.prefixRebuildAlreadyPriced || result.executedWorkThisPass && (result.prefixEditBesidesReasoningTrim || hostEditBeforeNewestThinking)),
38923
+ cacheBustingPass: !!recovery.rebuildReason || result.signedPrefixRewritten || result.prefixBustPermitted && !result.strictThinkingKept && (isCacheBusting || result.prefixRebuildAlreadyPriced || result.executedWorkThisPass && (result.prefixEditBesidesReasoningTrim || hostEditBeforeNewestThinking)),
38842
38924
  stripActiveTurn: result.signedPrefixRewritten,
38925
+ requirePersistence: !!recovery.rebuildReason,
38843
38926
  report: (line) => sessionLog2(sessionId, line)
38844
38927
  });
38845
38928
  } catch (err) {
38929
+ if (recovery.rebuildReason)
38930
+ throw err;
38846
38931
  sessionLog2(sessionId, `proactive thinking strip failed: ${err instanceof Error ? err.message : String(err)}`);
38847
38932
  }
38848
38933
  }
38849
38934
  logTransformTiming(sessionId, "thinkingBinding", tThinkingBinding);
38935
+ if (recovery.prefix && !result.recoveryNormalized) {
38936
+ const priorIds = new Set(recovery.prefix.inputs.map((input) => input.id));
38937
+ const newIds = new Set(snapshot.inputs.filter((input) => !priorIds.has(input.id)).map((input) => input.id));
38938
+ const suffix = outputMessages.filter((message) => {
38939
+ const id = result.postCommitEntryIdByRef.get(message) ?? result.lkgEntryIdByRef.get(message);
38940
+ return id !== undefined && newIds.has(id);
38941
+ });
38942
+ const prefix = JSON.parse(recovery.prefix.json);
38943
+ const recoveredEntryIds = new Map(result.postCommitEntryIdByRef);
38944
+ prefix.forEach((message, index) => {
38945
+ const id = recovery.prefix?.outputEntryIds[index];
38946
+ if (id)
38947
+ recoveredEntryIds.set(message, id);
38948
+ });
38949
+ result.postCommitEntryIdByRef = recoveredEntryIds;
38950
+ outputMessages = [...prefix, ...suffix];
38951
+ result.syntheticLeadingCount = recovery.prefix.outputEntryIds.findIndex((id) => id !== null);
38952
+ if (result.syntheticLeadingCount < 0)
38953
+ result.syntheticLeadingCount = prefix.length;
38954
+ }
38850
38955
  const tChannelAccounting = performance.now();
38851
38956
  try {
38852
38957
  const sessionMetaForCh1 = sessionMeta;
@@ -38968,7 +39073,8 @@ function registerPiContextHandler(pi, baseOptions) {
38968
39073
  runPiDebugAssertion(assertTailHygieneLastWriter);
38969
39074
  if (!options.compactionOff && (result.executedWorkThisPass || isCacheBusting || schedulerDecision === "execute")) {
38970
39075
  const envelope = readPiLkgFitEnvelope(ctx, pi, resolvePiContextModelKey(ctx), sessionDecisionCalibration(options.db, sessionId), toolWireSchema);
38971
- let estimate = estimatePiOutgoingInputTokens(outputMessages, envelope, lkgPassSnapshot ? lkgCoordinator.measureOutgoingPrefix(lkgPassSnapshot, outputMessages, (id) => ctx.sessionManager.getEntry?.(id)?.parentId) : undefined, rawFallbackLimit);
39076
+ const measuredPrefix = lkgPassSnapshot ? lkgCoordinator.measureOutgoingPrefix(lkgPassSnapshot, outputMessages, (id) => ctx.sessionManager.getEntry?.(id)?.parentId) : undefined;
39077
+ let estimate = estimatePiOutgoingInputTokens(outputMessages, envelope, measuredPrefix, rawFallbackLimit);
38972
39078
  if (inputForThinkingFit && result.strictThinkingKept && rawFallbackLimit && estimate.refusalGrade && (estimate.refusalTokens ?? estimate.tokens) > rawFallbackLimit) {
38973
39079
  result = await budget.waitMandatory(runPipeline({
38974
39080
  ...pipelineArgs,
@@ -38994,6 +39100,16 @@ function registerPiContextHandler(pi, baseOptions) {
38994
39100
  });
38995
39101
  estimate = estimatePiOutgoingInputTokens(outputMessages, envelope, undefined, rawFallbackLimit);
38996
39102
  }
39103
+ const opaqueFallbackSteps = piOpaqueThinkingFallbackSteps(outputMessages);
39104
+ if (opaqueFallbackSteps > 0)
39105
+ sessionLog2(sessionId, `opaque thinking fallback: steps=${opaqueFallbackSteps} tokensPerStep=1000 (native usage unavailable; telemetry only)`);
39106
+ if (measuredPrefix?.previousMessages?.some((raw) => {
39107
+ const message = raw;
39108
+ return Array.isArray(message.content) && message.content.some((part) => part.thinkingSignature);
39109
+ })) {
39110
+ const previous = estimatePiOutgoingInputTokens(measuredPrefix.previousMessages, envelope);
39111
+ sessionLog2(sessionId, `thinking estimate drift: estimate=${previous.tokens} provider=${measuredPrefix.inputTokens} ratio=${(previous.tokens / measuredPrefix.inputTokens).toFixed(4)} (previous served request; telemetry only)`);
39112
+ }
38997
39113
  if (result.signedPrefixRewritten && rawFallbackLimit && estimate.refusalGrade && (estimate.refusalTokens ?? estimate.tokens) > rawFallbackLimit)
38998
39114
  throw contextRefusalError("The request remains over the model window after stripping signed thinking and reclaiming context");
38999
39115
  const refusal = outgoingContextRefusal(estimate, rawFallbackLimit, protectedToolTokenCount(getActiveTagsBySession2(options.db, sessionId), options.protectedTools, envelope ? calibrationForModelKey(envelope.modelKey) : undefined));
@@ -39026,10 +39142,18 @@ function registerPiContextHandler(pi, baseOptions) {
39026
39142
  snapshot: lkgPassSnapshot,
39027
39143
  outputMessages,
39028
39144
  outputEntryIds: resolvePiLkgOutputEntryIds(outputMessages, result.syntheticLeadingCount, (message) => result.postCommitEntryIdByRef.get(message) ?? result.lkgEntryIdByRef.get(message)),
39029
- cacheBusting: result.bustedThisPass
39145
+ cacheBusting: result.bustedThisPass,
39146
+ releaseRecovery: result.recoveryNormalized || !!recovery.rebuildReason
39030
39147
  });
39031
39148
  numbersCommitted = true;
39032
39149
  } catch (error) {
39150
+ if (error instanceof LkgRecoveryFenceError)
39151
+ throw new PiServedIdentityError(error);
39152
+ try {
39153
+ invalidateCleanLkgRecoveryFence(sessionId, () => loadPersistedLkgSlot(options.db, sessionId));
39154
+ } catch (fenceError) {
39155
+ throw new PiServedIdentityError(fenceError);
39156
+ }
39033
39157
  budget.assertOutcome();
39034
39158
  clearPiLkgSessionState(sessionId);
39035
39159
  if (error instanceof PiLkgUncapturable) {
@@ -39076,8 +39200,12 @@ function registerPiContextHandler(pi, baseOptions) {
39076
39200
  }
39077
39201
  budget.assertOutcome();
39078
39202
  publishTransformDecision?.();
39203
+ if (!budget.sideTurn && result.strictThinkingKept && !result.signedPrefixRewritten && !result.materialized)
39204
+ recordPiHeldSystemHead(sessionId, (ownsHistory) => deferPiDeliveredSystemRefresh(sessionId, ownsHistory));
39079
39205
  return { messages: outputMessages };
39080
39206
  } catch (err) {
39207
+ if (budget.isCancelled(err))
39208
+ throw err;
39081
39209
  budget.assertOutcome();
39082
39210
  budget.stage = "recovery";
39083
39211
  if (err instanceof PiServedIdentityError) {
@@ -39087,9 +39215,11 @@ function registerPiContextHandler(pi, baseOptions) {
39087
39215
  }
39088
39216
  if (err instanceof PiLkgAdmissionReplay && sessionIdForError) {
39089
39217
  budget.assertOutcome();
39218
+ if (lkgPassSnapshot && err.trigger === "writer_busy")
39219
+ lkgCoordinator.noteRecovery(lkgPassSnapshot, err.messages);
39090
39220
  if (!budget.sideTurn)
39091
39221
  captureServedEvidence(sessionIdForError, err.messages, {
39092
- db: baseOptions.db,
39222
+ recoveryWithoutTagState: true,
39093
39223
  assertCurrentPass: budget.assertOutcome
39094
39224
  });
39095
39225
  budget.assertOutcome();
@@ -39116,7 +39246,10 @@ function registerPiContextHandler(pi, baseOptions) {
39116
39246
  const failureLabel = transientStorageFailure ? "TRANSIENT STORAGE FAILURE" : "DEGRADED PASS";
39117
39247
  if (replayOrRefuse && sessionIdForError && lkgPassSnapshot && !lkgCompactionOff && !lkgEmergencyRecoveryArmed) {
39118
39248
  try {
39119
- const replay = lkgCoordinator.replay(lkgPassSnapshot, (id) => ctx.sessionManager.getEntry?.(id)?.parentId);
39249
+ const replay = lkgCoordinator.recoveryFor(lkgPassSnapshot).rebuildReason ? {
39250
+ ok: false,
39251
+ reason: lkgPassSnapshot.replayFailure ?? "lkg_recovery_unproven"
39252
+ } : lkgCoordinator.replay(lkgPassSnapshot, (id) => ctx.sessionManager.getEntry?.(id)?.parentId);
39120
39253
  if (replay.ok) {
39121
39254
  assertPiRawFallbackFits(replay.messages, rawFallbackLimit, (line) => {
39122
39255
  if (sessionIdForError)
@@ -39125,9 +39258,10 @@ function registerPiContextHandler(pi, baseOptions) {
39125
39258
  const reason = piStorageErrorReason(err);
39126
39259
  logPiLkgRecovery(sessionIdForError, `${failureLabel} ${reason}: LKG replay served ${replay.messages.length} messages instead of raw ${rawMessageCount}`);
39127
39260
  budget.assertOutcome();
39261
+ lkgCoordinator.noteRecovery(lkgPassSnapshot, replay.messages);
39128
39262
  if (!budget.sideTurn)
39129
39263
  captureServedEvidence(sessionIdForError, replay.messages, {
39130
- db: baseOptions.db,
39264
+ recoveryWithoutTagState: true,
39131
39265
  assertCurrentPass: budget.assertOutcome
39132
39266
  });
39133
39267
  budget.assertOutcome();
@@ -39781,7 +39915,7 @@ async function runPipeline(args) {
39781
39915
  parts: (message) => Array.isArray(message?.content) ? message.content : []
39782
39916
  });
39783
39917
  if (thinkingRecovery.ended)
39784
- signalPiPendingMaterialization(args.sessionId);
39918
+ signalPiPendingMaterialization(args.sessionId, "thinking_hold");
39785
39919
  let restoreOriginals;
39786
39920
  let activeThinkingTurn = hasActiveAnthropicThinkingTurn(args.messages, args.resolvedProviderID, args.resolvedModelID);
39787
39921
  let protectedSignedPrefix = activeThinkingTurn && args.reasoningClearing?.prefixBound === true;
@@ -39798,7 +39932,8 @@ async function runPipeline(args) {
39798
39932
  model: args.resolvedModelID,
39799
39933
  cacheBustingPass: true,
39800
39934
  stripActiveTurn: true,
39801
- persistOnly: true
39935
+ persistOnly: true,
39936
+ requirePersistence: !!args.recoveryRebuildReason
39802
39937
  });
39803
39938
  if (activeThinkingTurn && !result)
39804
39939
  throw new Error("Cannot persist signed thinking omission before prefix rewrite");
@@ -39806,7 +39941,7 @@ async function runPipeline(args) {
39806
39941
  activeThinkingTurn = false;
39807
39942
  protectedSignedPrefix = false;
39808
39943
  };
39809
- if (args.forceSignedRebuildForFit && protectedSignedPrefix)
39944
+ if (args.recoveryRebuildReason || args.forceSignedRebuildForFit && protectedSignedPrefix)
39810
39945
  stripForPrefixRewrite();
39811
39946
  const realStableId = (msg, index) => resolvePiRealStableId(msg, index, args.entryIds, args.entryIdByRef ?? undefined);
39812
39947
  const passFallbackIds = settlePiFallbackOccurrences(args.db, args.sessionId, piContentFallbackIds(args.messages, realStableId));
@@ -40164,6 +40299,8 @@ async function runPipeline(args) {
40164
40299
  ...message,
40165
40300
  parts: message.parts
40166
40301
  }));
40302
+ const recoveryNormalized = !!args.recoveryPrefix && (foldBustsServedPrefixThisPass || firstRenderBust || identityRebuild);
40303
+ const taggingView = args.recoveryPrefix && !recoveryNormalized ? mutationView.filter((message) => !args.recoveryPrefix?.untaggedInputIds.has(message.info.id ?? "")) : mutationView;
40167
40304
  let tagTextTokenCache = piTagTextTokenCacheBySession.get(args.sessionId);
40168
40305
  if (!tagTextTokenCache) {
40169
40306
  tagTextTokenCache = new Map;
@@ -40176,7 +40313,7 @@ async function runPipeline(args) {
40176
40313
  }
40177
40314
  const { targets } = runPersistedReplayStage("tagging-persistence-failure", () => args.tagger.cleanup(args.sessionId), () => {
40178
40315
  args.assertCurrentPass?.();
40179
- return tagTranscript(args.sessionId, { ...transcript, messages: mutationView }, args.tagger, args.db, {
40316
+ return tagTranscript(args.sessionId, { ...transcript, messages: taggingView }, args.tagger, args.db, {
40180
40317
  skipPrefixInjection: !ctxReduceCallable,
40181
40318
  entryFingerprintByMessageId,
40182
40319
  reuseMessageIds: textIdentityPlan.reusableMessageIds,
@@ -40310,7 +40447,7 @@ async function runPipeline(args) {
40310
40447
  shouldRunReasoningCleanup: args.reasoningClearing !== undefined && shouldRunHeuristics
40311
40448
  });
40312
40449
  if (shouldApplyPendingOps) {
40313
- const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : foldBustsServedPrefixThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `${reclaimRideLabel(rideSignals)} (scheduler=${args.schedulerDecision})`;
40450
+ const applyReason = hasPendingMaterializeSignal ? `pending_materialization origin=${pendingMaterializationOrigin(pendingMaterializationSessions, args.sessionId)}` : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : foldBustsServedPrefixThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `${reclaimRideLabel(rideSignals)} (scheduler=${args.schedulerDecision})`;
40314
40451
  const pendingOpsDepth = getPendingOpsCount(args.db, args.sessionId);
40315
40452
  const pendingDecisionLog = `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOpsDepth === null ? "not loaded (deferred pass)" : pendingOpsDepth} context=${args.contextUsage.percentage.toFixed(1)}%`;
40316
40453
  sessionLog2(args.sessionId, pendingDecisionLog);
@@ -40655,7 +40792,7 @@ async function runPipeline(args) {
40655
40792
  db: args.db,
40656
40793
  sessionId: args.sessionId,
40657
40794
  activeTags,
40658
- targets: newTargets,
40795
+ targets,
40659
40796
  legacyReminderTagNumbers: textIdentityPlan.legacyReminderTagNumbers,
40660
40797
  cacheBusting: isCacheBustingPass
40661
40798
  });
@@ -40912,7 +41049,7 @@ async function runPipeline(args) {
40912
41049
  }
40913
41050
  }
40914
41051
  const materializeReason = identityRebuild ? PI_TAG_IDENTITY_REPAIR_REASON : injectionResult?.m0Reason ?? null;
40915
- const bustedThisPass = identityRebuild || firstRenderBust || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || materialized || historyWasConsumedThisPass;
41052
+ const bustedThisPass = !!args.recoveryRebuildReason || recoveryNormalized || identityRebuild || firstRenderBust || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || materialized || historyWasConsumedThisPass;
40916
41053
  const calibrationBustReason = identityRebuild ? PI_TAG_IDENTITY_REPAIR_REASON : materialized || firstRenderBust ? "fold" : args.forceMaterialization ? "force" : pendingOpsDidMutate ? "flush" : historyWasConsumedThisPass ? "refresh" : args.schedulerDecision === "execute" ? "execute" : "unknown";
40917
41054
  const activeCalibration = sessionDecisionCalibration(args.db, args.sessionId, {
40918
41055
  bustPermitted: bustedThisPass,
@@ -40952,6 +41089,8 @@ async function runPipeline(args) {
40952
41089
  }
40953
41090
  return {
40954
41091
  messages: outputMessages,
41092
+ recoveryNormalized,
41093
+ lkgFrozenReleaseReason: args.recoveryRebuildReason ?? (recoveryNormalized ? "recovery_tail_normalized" : undefined),
40955
41094
  prefixBustPermitted: isCacheBustingPass,
40956
41095
  prefixMutationAllowed,
40957
41096
  strictThinkingKept: protectedSignedPrefix,
@@ -40972,7 +41111,7 @@ async function runPipeline(args) {
40972
41111
  emergency,
40973
41112
  bustedThisPass,
40974
41113
  agentDropsAppliedThisPass: pendingOpsDidMutate,
40975
- prefixEditBesidesReasoningTrim: prefixEditBesidesReasoningTrim || firstRenderBust || args.isCacheBusting || hasPendingMaterializeSignal || deferredMaterializationConsumedThisPass || foldBustsServedPrefixThisPass || publishedM1RefreshedThisPass || materialized || historyWasConsumedThisPass || pendingOpsDidMutate || autoReclaimDidMutateThisPass || emergency,
41114
+ prefixEditBesidesReasoningTrim: !!args.recoveryRebuildReason || prefixEditBesidesReasoningTrim || firstRenderBust || args.isCacheBusting || hasPendingMaterializeSignal || deferredMaterializationConsumedThisPass || foldBustsServedPrefixThisPass || publishedM1RefreshedThisPass || materialized || historyWasConsumedThisPass || pendingOpsDidMutate || autoReclaimDidMutateThisPass || emergency,
40976
41115
  targetCount: targets.size,
40977
41116
  reasoningWatermark: args.sessionMeta.clearedReasoningThroughTag ?? 0,
40978
41117
  activeTags,
@@ -41199,7 +41338,7 @@ function appendReminderToPiUserMessage(message, reminder) {
41199
41338
  function clearPiCompactionOffInMemoryState(sessionId) {
41200
41339
  historyRefreshSessions.delete(sessionId);
41201
41340
  deferredHistoryRefreshSessions.delete(sessionId);
41202
- pendingMaterializationSessions.delete(sessionId);
41341
+ clearPendingMaterialization(pendingMaterializationSessions, sessionId);
41203
41342
  deferredMaterializationSessions.delete(sessionId);
41204
41343
  clearPiChannel1State(sessionId);
41205
41344
  }
@@ -41212,7 +41351,7 @@ function clearContextHandlerSession(sessionId) {
41212
41351
  clearAutoSearchForPiSession(sessionId);
41213
41352
  lastEmergencyNotificationAtMs.delete(sessionId);
41214
41353
  historyRefreshSessions.delete(sessionId);
41215
- pendingMaterializationSessions.delete(sessionId);
41354
+ clearPendingMaterialization(pendingMaterializationSessions, sessionId);
41216
41355
  systemPromptRefreshSessions.delete(sessionId);
41217
41356
  deferredHistoryRefreshSessions.delete(sessionId);
41218
41357
  deferredMaterializationSessions.delete(sessionId);
@@ -43880,112 +44019,6 @@ function buildStatusViewFor(check, options) {
43880
44019
  }, check.versions, options);
43881
44020
  }
43882
44021
  }
43883
- // package.json
43884
- var package_default = {
43885
- name: "@cortexkit/pi-magic-context",
43886
- version: "0.49.0",
43887
- type: "module",
43888
- description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
43889
- main: "dist/index.js",
43890
- license: "MIT",
43891
- author: "ualtinok",
43892
- keywords: [
43893
- "pi",
43894
- "pi-coding-agent",
43895
- "omp",
43896
- "oh-my-pi",
43897
- "extension",
43898
- "context",
43899
- "memory",
43900
- "magic-context",
43901
- "ai",
43902
- "llm"
43903
- ],
43904
- repository: {
43905
- type: "git",
43906
- url: "https://github.com/cortexkit/magic-context",
43907
- directory: "packages/pi-plugin"
43908
- },
43909
- files: [
43910
- "dist",
43911
- "README.md"
43912
- ],
43913
- "//": "The build intentionally bundles typebox (no --external typebox) and keeps it a regular dependency. OMP's extension loader rewrites every bare `typebox` import to its own omptype-based shim, whose schemas are callable objects rather than JSON Schema; they fail structuredClone during tool registration, so an external typebox import stops Magic Context loading on OMP. src/typebox-bundling.test.ts guards this.",
43914
- scripts: {
43915
- build: "bun ../../scripts/check-bun.mjs && tsc -p ../retina-local-fs/tsconfig.build.json && bun ../../scripts/clean-dist-chunks.mjs dist index.js subagent-entry.js historian-calibration-extension.js raw-ordinal-warmup-worker.js transformers-web.js transformers-node-wasm.js && bun build ../plugin/src/features/magic-context/memory/transformers-web-entry.ts --outfile dist/transformers-web.js --target browser --format esm --external onnxruntime-web && bun ../plugin/scripts/build-transformers-node-wasm.ts dist && bun build src/index.ts src/subagent-entry.ts src/historian-calibration-extension.ts ../plugin/src/features/magic-context/memory/embedding-worker.ts ../plugin/src/features/magic-context/migration-worker.ts ../plugin/src/hooks/magic-context/auto-search-worker.ts ../plugin/src/hooks/magic-context/raw-ordinal-warmup-worker.ts --outdir dist --entry-naming '[name].[ext]' --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @oh-my-pi/pi-coding-agent --external @earendil-works/pi-tui --external onnxruntime-node --external onnxruntime-web --external sharp --external node:sqlite",
43916
- "build:e2e-argv": `bun ../../scripts/clean-dist-chunks.mjs ../../tests/docker/.generated subagent-runner-e2e.mjs && bun build src/subagent-runner.ts --outdir ../../tests/docker/.generated --entry-naming 'subagent-runner-e2e.mjs' --splitting --target node --format esm --external node:sqlite && node --input-type=module -e 'const { __test } = await import("../../tests/docker/.generated/subagent-runner-e2e.mjs"); if (typeof __test.buildArgs !== "function" || typeof __test.resolvePiInvocation !== "function") throw new Error("argv renderer exports missing"); console.log("Node argv renderer: 2 exports loaded")'`,
43917
- typecheck: "tsc -p ../retina-local-fs/tsconfig.build.json && tsc --noEmit",
43918
- test: "bun ../../scripts/check-bun.mjs && bun install --frozen-lockfile && BUN_JSC_useOMGJIT=0 bun test --parallel=4 --timeout 30000",
43919
- "test:serial": "bun ../../scripts/check-bun.mjs && bun install --frozen-lockfile && BUN_JSC_useOMGJIT=0 bun test --parallel=1 --timeout 30000",
43920
- lint: "bun ../../scripts/check-bun.mjs && biome check src",
43921
- "lint:fix": "biome check --write src",
43922
- format: "biome format --write src",
43923
- "format:check": "biome format src",
43924
- clean: "bun ../../scripts/clean-dist-chunks.mjs dist index.js subagent-entry.js historian-calibration-extension.js embedding-worker.js migration-worker.js raw-ordinal-warmup-worker.js transformers-web.js transformers-node-wasm.js",
43925
- prepublishOnly: "bun run build"
43926
- },
43927
- "//test": "Test runs cap file-isolated workers at four (one for test:serial) and disable JSC's optimizing WebAssembly tier so per-file isolation does not pay its compilation cost on every file. These are not production settings and do not change host process engine options.",
43928
- dependencies: {
43929
- "@cortexkit/subc-client": "0.11.1",
43930
- "@jitl/quickjs-singlefile-cjs-release-asyncify": "0.32.0",
43931
- "ai-tokenizer": "^1.0.6",
43932
- "comment-json": "^5.0.0",
43933
- "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c",
43934
- "quickjs-emscripten": "^0.32.0",
43935
- zod: "^4.1.8"
43936
- },
43937
- optionalDependencies: {
43938
- "onnxruntime-node": "1.30.0",
43939
- sharp: "^0.35.0"
43940
- },
43941
- devDependencies: {
43942
- "@biomejs/biome": "^2.5.1",
43943
- "@earendil-works/pi-ai": "0.83.0",
43944
- "@earendil-works/pi-coding-agent": "0.83.0",
43945
- "@earendil-works/pi-tui": "0.83.0",
43946
- "@huggingface/transformers": "^4.3.0",
43947
- "@types/better-sqlite3": "^7.6.13",
43948
- "@types/bun": "^1.3.10",
43949
- "@types/node": "^22.20.0",
43950
- "pi-agent-core-087": "npm:@earendil-works/pi-agent-core@0.87.1",
43951
- "pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
43952
- "pi-coding-agent-086": "npm:@earendil-works/pi-coding-agent@0.86.0",
43953
- "pi-coding-agent-087": "npm:@earendil-works/pi-coding-agent@0.87.1",
43954
- typebox: "^1.3.1",
43955
- typescript: "^5.8.0"
43956
- },
43957
- peerDependencies: {
43958
- "@earendil-works/pi-coding-agent": "*",
43959
- "@earendil-works/pi-tui": "*",
43960
- typebox: "*"
43961
- },
43962
- peerDependenciesMeta: {
43963
- "@earendil-works/pi-coding-agent": {
43964
- optional: true
43965
- },
43966
- "@earendil-works/pi-tui": {
43967
- optional: true
43968
- },
43969
- typebox: {
43970
- optional: true
43971
- }
43972
- },
43973
- exports: {
43974
- ".": {
43975
- import: "./dist/index.js"
43976
- }
43977
- },
43978
- pi: {
43979
- extensions: [
43980
- "./dist/index.js"
43981
- ]
43982
- },
43983
- omp: {
43984
- extensions: [
43985
- "./dist/index.js"
43986
- ]
43987
- }
43988
- };
43989
44022
 
43990
44023
  // src/dialogs/status-dialog.ts
43991
44024
  var REFRESH_INTERVAL_MS = 1000;
@@ -45498,6 +45531,7 @@ function withTimeout(p, ms) {
45498
45531
  }
45499
45532
 
45500
45533
  // src/index.ts
45534
+ registerStandalonePluginMarker(package_default.version);
45501
45535
  var PI_HARNESS_DETECTION = await resolvePiHarnessDetection();
45502
45536
  var PI_HARNESS_KIND = PI_HARNESS_DETECTION.kind;
45503
45537
  var PREFIX2 = `[magic-context][${PI_HARNESS_KIND}]`;
@@ -45743,6 +45777,7 @@ function resolvePiPressureContextLimit(args) {
45743
45777
  }) ?? 0;
45744
45778
  }
45745
45779
  async function persistPiPressureFromMessageEnd(args) {
45780
+ acknowledgePiSystemPromptResponse(args.sessionId, args.message);
45746
45781
  if (piMessageAnchorsLiveUsage(args.message)) {
45747
45782
  recordPiLiveUsageClassification(args.sessionId, false);
45748
45783
  } else if (typeof args.piTokensIsRawBranchEstimate === "boolean") {
@@ -45970,7 +46005,6 @@ async function src_default(pi) {
45970
46005
  info("plugin DISABLED via config (enabled: false) — skipping registration");
45971
46006
  return;
45972
46007
  }
45973
- reloadWindowOverlay(bootConfig.config.models?.window_overlay_path);
45974
46008
  setStoragePrivatePermissionEnforcement(bootConfig.config.storage.enforce_private_permissions);
45975
46009
  setSqlitePragmaConfig({
45976
46010
  cacheSizeMb: bootConfig.config.sqlite.cache_size_mb,
@@ -46754,9 +46788,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
46754
46788
  promptSurfacePreset: promptSurface.preset
46755
46789
  });
46756
46790
  if (result.hashChanged) {
46757
- signalPiHistoryRefresh(sessionId);
46758
- signalPiSystemPromptRefresh(sessionId);
46759
- signalPiPendingMaterialization(sessionId);
46791
+ signalPiSystemHashChange(sessionId, result.currentHash);
46760
46792
  }
46761
46793
  if (isCacheBusting) {
46762
46794
  clearSystemPromptRefresh(sessionId);
@@ -46772,6 +46804,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
46772
46804
  });
46773
46805
  info("registered before_agent_start system prompt injector");
46774
46806
  pi.on("agent_end", (event, ctx) => {
46807
+ acknowledgePiPendingSystemPromptResponses(ctx.sessionManager.getSessionId());
46775
46808
  setEmbeddingSessionBusy2(ctx.sessionManager.getSessionId(), false);
46776
46809
  log2("agent_end: returning synchronously (background work continues)");
46777
46810
  try {