@cortexkit/pi-magic-context 0.49.19 → 0.49.20

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 (59) hide show
  1. package/dist/auto-search-worker.js +48 -9
  2. package/dist/chunk-embedding-write-worker.js +29 -22
  3. package/dist/{compaction-marker-candidates-wjzqbspm.js → compaction-marker-candidates-fnm47jat.js} +3 -3
  4. package/dist/compaction-marker-candidates-worker.js +2 -2
  5. package/dist/compartment-chunk-embedding-81qesfjs.js +64 -0
  6. package/dist/embedding-backfill-56e871c6.js +24 -0
  7. package/dist/embedding-worker-process.js +2 -2
  8. package/dist/embedding-worker.js +5 -5
  9. package/dist/historian-calibration-extension.js +1 -1
  10. package/dist/index-54wmg4rj.js +82 -0
  11. package/dist/{index-xnch62s6.js → index-5n5zxs8e.js} +314 -127
  12. package/dist/{index-msqrs4nf.js → index-5vgt1zeh.js} +5 -5
  13. package/dist/{index-qpq6w67c.js → index-6kb2xpw7.js} +2 -2
  14. package/dist/{index-58mj0dzc.js → index-af9t637y.js} +68 -16
  15. package/dist/{index-z2rkv0mb.js → index-b8am7tns.js} +4 -4
  16. package/dist/{index-rhprywn6.js → index-bttctq07.js} +23 -5
  17. package/dist/{index-e1rza8gp.js → index-dzem6gn9.js} +1 -1
  18. package/dist/{index-2mmy81qt.js → index-e19qtjj0.js} +468 -18
  19. package/dist/{index-7bqrfyny.js → index-fgs78jyd.js} +12 -15
  20. package/dist/{index-d4dt19md.js → index-hqw0rt9k.js} +1 -1
  21. package/dist/{index-rrwv9y2k.js → index-hws5f0z9.js} +1 -1
  22. package/dist/{index-f18ec69t.js → index-jn44h81p.js} +1 -1
  23. package/dist/{index-ek9zvs4f.js → index-jt0g3hn0.js} +37 -25
  24. package/dist/{index-d8gc0112.js → index-jxjr7kz9.js} +3 -3
  25. package/dist/{index-rc1dez8m.js → index-kqb3d8bs.js} +9 -5
  26. package/dist/{index-sqt2haap.js → index-mtvvhcw4.js} +10 -10
  27. package/dist/{index-1kcfwk9c.js → index-my0dn413.js} +1 -1
  28. package/dist/{index-apgwdby5.js → index-n4wyxcgr.js} +1 -1
  29. package/dist/{index-g7p75667.js → index-p63nwn5v.js} +2 -2
  30. package/dist/{index-svgkv4g2.js → index-qerzchrs.js} +2 -2
  31. package/dist/{index-vktahpdj.js → index-rfyvax95.js} +9 -3
  32. package/dist/{index-yygsh681.js → index-rgfb753z.js} +3 -3
  33. package/dist/{index-dtp1efvf.js → index-tb3d9trm.js} +2 -2
  34. package/dist/{index-vmcgew7x.js → index-v2epyzbm.js} +75 -57
  35. package/dist/{index-ym6nh2gk.js → index-vdy273xw.js} +107 -20
  36. package/dist/{index-jrap43gc.js → index-w1avzkdt.js} +1 -1
  37. package/dist/{index-wveb51es.js → index-zhwwp8zz.js} +63 -8
  38. package/dist/index.js +978 -235
  39. package/dist/{logger-dygt96rn.js → logger-shetp43v.js} +1 -1
  40. package/dist/{message-fts-rowid-map-cvpy2dmb.js → message-fts-rowid-map-bpexnsdj.js} +6 -5
  41. package/dist/{message-index-bounded-66saeq5j.js → message-index-bounded-d4r3weh0.js} +14 -13
  42. package/dist/{message-index-rc2x41k4.js → message-index-mvag9crh.js} +14 -13
  43. package/dist/{message-time-backfill-ssshbdy8.js → message-time-backfill-kc10yrcj.js} +3 -3
  44. package/dist/migration-worker.js +12 -11
  45. package/dist/{project-embedding-registry-vf1ncptn.js → project-embedding-registry-cfrg952x.js} +13 -12
  46. package/dist/raw-ordinal-warmup-worker.js +136 -101
  47. package/dist/{read-session-chunk-h5bzj91r.js → read-session-chunk-7g4zvpd8.js} +9 -8
  48. package/dist/{read-session-raw-9s3xn7fc.js → read-session-raw-0fsjh10f.js} +4 -3
  49. package/dist/{safe-notification-target-2rkvkmw8.js → safe-notification-target-zcpchea6.js} +2 -2
  50. package/dist/search-archive-qbhp7e89.js +21 -0
  51. package/dist/{search-wh7b9zht.js → search-hp4g3g9v.js} +22 -21
  52. package/dist/{sqlite-fsp0sf3r.js → sqlite-d67n6dtr.js} +1 -1
  53. package/dist/{storage-memory-yxxc5v4n.js → storage-memory-9g882j7a.js} +2 -2
  54. package/dist/{storage-tags-1kets0q8.js → storage-tags-m2qcp1g2.js} +7 -5
  55. package/dist/subagent-entry.js +26 -25
  56. package/dist/tag-snapshot-worker-pi.js +22 -14
  57. package/package.json +1 -1
  58. package/dist/embedding-backfill-vwag34t0.js +0 -23
  59. package/dist/search-archive-4817pqev.js +0 -20
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  log2,
19
19
  sessionLog2,
20
20
  flushLogger2
21
- } from "./index-7bqrfyny.js";
21
+ } from "./index-fgs78jyd.js";
22
22
  import {
23
23
  COMPACTION_ENABLED_PATH,
24
24
  isDreamerRunnable,
@@ -249,7 +249,7 @@ import {
249
249
  registerTodoStateLifecycle,
250
250
  syncCtxMemoryToolEnabled,
251
251
  registerMagicContextTools
252
- } from "./index-ek9zvs4f.js";
252
+ } from "./index-jt0g3hn0.js";
253
253
  import"./index-4knyh1kt.js";
254
254
  import {
255
255
  canonicalModelIdentity,
@@ -290,7 +290,7 @@ import {
290
290
  openCurrentDatabase,
291
291
  openDatabaseAsync,
292
292
  closeDatabase
293
- } from "./index-sqt2haap.js";
293
+ } from "./index-mtvvhcw4.js";
294
294
  import {
295
295
  pruneMissingProjectIdentities,
296
296
  setHomeProjectPermission,
@@ -302,7 +302,7 @@ import {
302
302
  resolveProjectIdentityForSession,
303
303
  beginBootQuietPeriod,
304
304
  scheduleAfterBootQuiet
305
- } from "./index-g7p75667.js";
305
+ } from "./index-p63nwn5v.js";
306
306
  import {
307
307
  detectThinkingBindingMismatch,
308
308
  detectLatestTurnThinkingMismatch,
@@ -396,6 +396,7 @@ import {
396
396
  addProcessedImageStrippedIds,
397
397
  getPendingCompactionMarkerState,
398
398
  getCompactionMarkerHealth,
399
+ loadPostprocessReplaySnapshot,
399
400
  clearPendingCompactionMarkerStateIf,
400
401
  getPendingPiCompactionMarkerState,
401
402
  setPendingPiCompactionMarkerState,
@@ -462,7 +463,7 @@ import {
462
463
  getRawSessionTagKeysThrough2,
463
464
  getLegacyProtectedTailStartOrdinal2,
464
465
  readSessionChunk2
465
- } from "./index-wveb51es.js";
466
+ } from "./index-zhwwp8zz.js";
466
467
  import {
467
468
  UNKNOWN_FIT_RATIO,
468
469
  hasMeasuredDecisionCalibration,
@@ -549,7 +550,7 @@ import {
549
550
  getToolTagNumberByOwner2,
550
551
  getNullOwnerToolTag2,
551
552
  adoptNullOwnerToolTag2
552
- } from "./index-rhprywn6.js";
553
+ } from "./index-bttctq07.js";
553
554
  import {
554
555
  textMentionsRecentCommit,
555
556
  hasMeaningfulUserText2,
@@ -561,7 +562,7 @@ import {
561
562
  estimateTokens,
562
563
  estimateFixedPromptTokens,
563
564
  normalizeText
564
- } from "./index-1kcfwk9c.js";
565
+ } from "./index-my0dn413.js";
565
566
  import {
566
567
  inRootAsyncContext2,
567
568
  Database2,
@@ -574,7 +575,7 @@ import {
574
575
  isTransientSqliteError2,
575
576
  withAsyncPrivilegedWriter2,
576
577
  indexCoordinationInput2
577
- } from "./index-rrwv9y2k.js";
578
+ } from "./index-hws5f0z9.js";
578
579
  import {
579
580
  stableStringify,
580
581
  closeQuietly,
@@ -582,14 +583,15 @@ import {
582
583
  observeTemporalDecisions,
583
584
  freezeTemporalDecisions,
584
585
  tagIdentityRevisionKey
585
- } from "./index-jrap43gc.js";
586
+ } from "./index-w1avzkdt.js";
586
587
  import {
587
588
  piHarnessKindFromExecutable
588
- } from "./index-apgwdby5.js";
589
+ } from "./index-n4wyxcgr.js";
589
590
  import {
590
591
  BoundedSessionMap,
591
592
  LkgRecoveryFenceError,
592
593
  clearLkgFenceProcessState,
594
+ takeLkgRecoveryLockSweepPage,
593
595
  lkgFenceRequiresRebuild,
594
596
  lkgRecoveryFenceUnclean,
595
597
  ownsLkgDirtyFence,
@@ -611,7 +613,7 @@ import {
611
613
  indexSingleMessage2,
612
614
  indexMessagesAfterOrdinal2,
613
615
  sweepOrphanedOpenCodeMessageIndexesCooperatively2
614
- } from "./index-ym6nh2gk.js";
616
+ } from "./index-vdy273xw.js";
615
617
  import {
616
618
  resolveOpenCodeDbPath,
617
619
  assertOpenCodeStoreGeneration,
@@ -621,24 +623,27 @@ import {
621
623
  claimOpenCodeDbDiagnosticOnce
622
624
  } from "./index-8976mezv.js";
623
625
  import"./index-399p688g.js";
626
+ import {
627
+ createWorkerShutdown
628
+ } from "./index-54wmg4rj.js";
624
629
  import {
625
630
  runSessionWarmupWorker,
626
631
  RAW_SUMMARY_TEXT_MAX_CHARS2
627
- } from "./index-vktahpdj.js";
632
+ } from "./index-rfyvax95.js";
628
633
  import {
629
634
  formatSynapseLaneDescriptor
630
- } from "./index-d8gc0112.js";
631
- import"./index-yygsh681.js";
635
+ } from "./index-jxjr7kz9.js";
636
+ import"./index-rgfb753z.js";
632
637
  import {
633
- buildCanonicalChunkTextFromFts,
634
- buildCompartmentSummaryFallbackText,
635
- canonicalizeInMemoryChunkTextForEmbedding,
636
- chunkCanonicalText,
637
- chunkEmbeddingWindowsAreCurrent,
638
- replaceCompartmentChunkEmbeddings,
639
- deleteChunkEmbedBackoffForSession,
640
- chunkWindowSourceKey
641
- } from "./index-xnch62s6.js";
638
+ buildCanonicalChunkTextFromFts2,
639
+ buildCompartmentSummaryFallbackText2,
640
+ canonicalizeInMemoryChunkTextForEmbedding2,
641
+ chunkCanonicalText2,
642
+ chunkEmbeddingWindowsAreCurrent2,
643
+ replaceCompartmentChunkEmbeddings2,
644
+ deleteChunkEmbedBackoffForSession2,
645
+ chunkWindowSourceKey2
646
+ } from "./index-5n5zxs8e.js";
642
647
  import {
643
648
  recordSessionProjectIdentity,
644
649
  GIT_SWEEP_LEASE_RENEWAL_MS,
@@ -647,7 +652,7 @@ import {
647
652
  markGitSweepSuccessAndRelease,
648
653
  parkGitSweepNonIndexable,
649
654
  releaseGitSweepLease
650
- } from "./index-svgkv4g2.js";
655
+ } from "./index-qerzchrs.js";
651
656
  import {
652
657
  embedPauseBySession,
653
658
  embedRunStateBySession,
@@ -673,7 +678,7 @@ import {
673
678
  embedSessionCompartmentChunks2,
674
679
  getEmbeddingCoverageStatus2,
675
680
  getAutoEmbeddingSessionCoverage2
676
- } from "./index-vmcgew7x.js";
681
+ } from "./index-v2epyzbm.js";
677
682
  import {
678
683
  rememberV1HiddenRun
679
684
  } from "./index-6x556c2q.js";
@@ -688,7 +693,7 @@ import {
688
693
  expandWorkspaceIdentitySetWithAliases,
689
694
  sourceNameForMemory,
690
695
  computeWorkspaceEpochFingerprint
691
- } from "./index-msqrs4nf.js";
696
+ } from "./index-5vgt1zeh.js";
692
697
  import {
693
698
  configureContextDatabasePragmas2
694
699
  } from "./index-fapenpch.js";
@@ -738,7 +743,7 @@ import {
738
743
  normalizeVerificationFiles,
739
744
  indexCommitsForProject,
740
745
  embedUnembeddedCommits
741
- } from "./index-58mj0dzc.js";
746
+ } from "./index-af9t637y.js";
742
747
  import {
743
748
  setEmbeddingSessionBusy2,
744
749
  isEmbeddingHostBusy2
@@ -762,18 +767,20 @@ import {
762
767
  setMemoryClassification2,
763
768
  archiveMemory2,
764
769
  getMemoryCountsByStatus2
765
- } from "./index-e1rza8gp.js";
770
+ } from "./index-dzem6gn9.js";
766
771
  import {
767
772
  invalidateMemory2
768
773
  } from "./index-yhzhdp3m.js";
769
774
  import {
770
775
  pushNotification2
771
776
  } from "./index-q1yc6bs0.js";
772
- import"./index-2mmy81qt.js";
777
+ import {
778
+ getCachedLocalEmbeddingPooling
779
+ } from "./index-e19qtjj0.js";
773
780
  import {
774
781
  cosineSimilarity
775
- } from "./index-z2rkv0mb.js";
776
- import"./index-qpq6w67c.js";
782
+ } from "./index-b8am7tns.js";
783
+ import"./index-6kb2xpw7.js";
777
784
  import {
778
785
  DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS,
779
786
  buildHiddenAgentRegistrations,
@@ -795,10 +802,10 @@ import {
795
802
  drainPiTagSnapshotSession,
796
803
  assertPiTagSnapshotReady,
797
804
  ensurePiTagSnapshotReady
798
- } from "./index-rc1dez8m.js";
799
- import"./index-f18ec69t.js";
805
+ } from "./index-kqb3d8bs.js";
806
+ import"./index-jn44h81p.js";
800
807
  import"./index-1cvyaw9a.js";
801
- import"./index-dtp1efvf.js";
808
+ import"./index-tb3d9trm.js";
802
809
  import {
803
810
  __toESM
804
811
  } from "./index-22jkk6wg.js";
@@ -814,7 +821,7 @@ import {
814
821
  import {
815
822
  logSlowWriteTransaction,
816
823
  WriteTransactionSteps
817
- } from "./index-d4dt19md.js";
824
+ } from "./index-hqw0rt9k.js";
818
825
  import {
819
826
  setStoragePrivatePermissionEnforcement,
820
827
  ensureStorageDirectorySync,
@@ -1207,6 +1214,9 @@ function resolveHarnessBlock(container, harness) {
1207
1214
  const selected = harness === "omp" ? container?.omp ?? container?.pi : container?.[harness];
1208
1215
  return asRecord(selected);
1209
1216
  }
1217
+ function sourceHarness(container, harness) {
1218
+ return harness === "omp" && container?.omp == null ? "pi" : harness;
1219
+ }
1210
1220
  function normalizeModelEntry(entry, harness) {
1211
1221
  if (typeof entry === "string") {
1212
1222
  const model = readString(entry);
@@ -1253,13 +1263,19 @@ function resolveHistorianModel(config, harness) {
1253
1263
  const block = resolveHarnessBlock(historian, harness);
1254
1264
  if (!block)
1255
1265
  return { fallbacks: [] };
1266
+ const source = `historian.${sourceHarness(historian, harness)}`;
1267
+ const primary = resolvePrimaryEntry({
1268
+ entry: block.model,
1269
+ defaultQualifier: block[harness === "opencode" ? "variant" : "thinking_level"],
1270
+ harness
1271
+ });
1272
+ const fallbacks = resolveFallbackEntries(block.fallback_models, harness);
1256
1273
  return {
1257
- primary: resolvePrimaryEntry({
1258
- entry: block.model,
1259
- defaultQualifier: block[harness === "opencode" ? "variant" : "thinking_level"],
1260
- harness
1261
- }),
1262
- fallbacks: resolveFallbackEntries(block.fallback_models, harness)
1274
+ primary: primary ? { ...primary, sourceConfigKey: `${source}.model` } : undefined,
1275
+ fallbacks: fallbacks.map((entry) => ({
1276
+ ...entry,
1277
+ sourceConfigKey: `${source}.fallback_models`
1278
+ }))
1263
1279
  };
1264
1280
  }
1265
1281
  function resolveDreamerTaskModel(args) {
@@ -1278,15 +1294,25 @@ function resolveDreamerTaskModel(args) {
1278
1294
  const taskQualifier = taskBlock?.[args.harness === "opencode" ? "variant" : "thinking_level"];
1279
1295
  const harnessQualifier = harnessBlock[args.harness === "opencode" ? "variant" : "thinking_level"] ?? normalizeModelEntry(harnessBlock.model, args.harness)?.qualifier;
1280
1296
  const taskHasModel = taskBlock !== undefined && hasOwn(taskBlock, "model");
1297
+ const taskHasFallbacks = taskBlock !== undefined && hasOwn(taskBlock, "fallback_models");
1281
1298
  const primarySource = taskHasModel ? taskBlock?.model : harnessBlock.model;
1282
- const fallbackSource = taskBlock !== undefined && hasOwn(taskBlock, "fallback_models") ? taskBlock.fallback_models : harnessBlock.fallback_models;
1299
+ const fallbackSource = taskHasFallbacks ? taskBlock?.fallback_models : harnessBlock.fallback_models;
1300
+ const source = `dreamer.${sourceHarness(dreamer, args.harness)}`;
1301
+ const primary = resolvePrimaryEntry({
1302
+ entry: primarySource,
1303
+ defaultQualifier: taskQualifier ?? harnessQualifier,
1304
+ harness: args.harness
1305
+ });
1306
+ const fallbacks = resolveFallbackEntries(fallbackSource, args.harness);
1283
1307
  return {
1284
- primary: resolvePrimaryEntry({
1285
- entry: primarySource,
1286
- defaultQualifier: taskQualifier ?? harnessQualifier,
1287
- harness: args.harness
1288
- }),
1289
- fallbacks: resolveFallbackEntries(fallbackSource, args.harness),
1308
+ primary: primary ? {
1309
+ ...primary,
1310
+ sourceConfigKey: taskHasModel ? `${source}.tasks.${args.task}.model` : `${source}.model`
1311
+ } : undefined,
1312
+ fallbacks: fallbacks.map((entry) => ({
1313
+ ...entry,
1314
+ sourceConfigKey: taskHasFallbacks ? `${source}.tasks.${args.task}.fallback_models` : `${source}.fallback_models`
1315
+ })),
1290
1316
  schedule: readString(schedulingTask?.schedule),
1291
1317
  timeoutMinutes: typeof taskBlock?.timeout_minutes === "number" ? taskBlock.timeout_minutes : undefined,
1292
1318
  promotionThreshold: typeof schedulingTask?.promotion_threshold === "number" ? schedulingTask.promotion_threshold : undefined
@@ -1306,6 +1332,7 @@ function buildDreamTaskRuntimeConfigs(dreamer, harness, language, smartNotesEnab
1306
1332
  schedule: resolved.schedule ?? "",
1307
1333
  model: resolved.primary,
1308
1334
  fallbackModels: resolved.fallbacks,
1335
+ modelConfigKey: resolved.primary?.sourceConfigKey ?? resolved.fallbacks[0]?.sourceConfigKey,
1309
1336
  thinkingLevel: harness === "pi" ? resolved.primary?.qualifier : undefined,
1310
1337
  language,
1311
1338
  timeoutMinutes: resolved.timeoutMinutes ?? 20,
@@ -3520,7 +3547,7 @@ function startHostStallProfilerSwitch() {
3520
3547
  // package.json
3521
3548
  var package_default = {
3522
3549
  name: "@cortexkit/pi-magic-context",
3523
- version: "0.49.19",
3550
+ version: "0.49.20",
3524
3551
  type: "module",
3525
3552
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3526
3553
  main: "dist/index.js",
@@ -4961,7 +4988,7 @@ async function promptWithTimeout(client, args, timeoutMs, signal, transport, fir
4961
4988
  if (!activity.monitored || activity.received)
4962
4989
  return;
4963
4990
  silent = true;
4964
- controller.abort();
4991
+ controller.abort(new ModelProducedNoOutputError(firstOutputTimeoutMs));
4965
4992
  }, firstOutputTimeoutMs) : undefined;
4966
4993
  const timeoutError = () => silent && firstOutputTimeoutMs !== undefined ? new ModelProducedNoOutputError(firstOutputTimeoutMs) : new Error(`prompt timed out after ${timeoutMs}ms`);
4967
4994
  const onExternalAbort = () => controller.abort();
@@ -5374,6 +5401,152 @@ function normalizeSDKResponse(response, fallback, options) {
5374
5401
  return fallback;
5375
5402
  }
5376
5403
  // ../plugin/src/features/magic-context/subagent-token-capture.ts
5404
+ var warnedUnknownModels = new Set;
5405
+ var loggedModelReroutes = new Set;
5406
+ var MAX_SUBAGENT_INVOCATION_ERROR_CHARS = 1000;
5407
+ var invocationErrorDetails = new WeakMap;
5408
+ function annotateSubagentInvocationError(error, details) {
5409
+ if (error && typeof error === "object") {
5410
+ const previous = invocationErrorDetails.get(error) ?? {};
5411
+ invocationErrorDetails.set(error, {
5412
+ ...previous,
5413
+ ...details,
5414
+ hostError: details.hostError ?? previous.hostError
5415
+ });
5416
+ }
5417
+ return error;
5418
+ }
5419
+ function errorDetailsOf(error) {
5420
+ const seen = new Set;
5421
+ const visit = (value, depth) => {
5422
+ if (!value || typeof value !== "object" || depth > 4 || seen.has(value))
5423
+ return {};
5424
+ seen.add(value);
5425
+ const direct = invocationErrorDetails.get(value) ?? {};
5426
+ const record = value;
5427
+ const nested = visit(record.hostError, depth + 1);
5428
+ const cause = visit(record.cause, depth + 1);
5429
+ return {
5430
+ ...cause,
5431
+ ...nested,
5432
+ ...direct,
5433
+ hostError: direct.hostError ?? nested.hostError ?? cause.hostError ?? record.hostError
5434
+ };
5435
+ };
5436
+ return visit(error, 0);
5437
+ }
5438
+ function modelRef(value) {
5439
+ const reference = typeof value === "string" ? value : value?.model;
5440
+ return typeof reference === "string" && reference.trim().length > 0 ? reference.trim() : undefined;
5441
+ }
5442
+ function splitModelRef(value) {
5443
+ if (!value)
5444
+ return { providerId: null, modelId: null };
5445
+ const slash = value.indexOf("/");
5446
+ return slash > 0 && slash < value.length - 1 ? { providerId: value.slice(0, slash), modelId: value.slice(slash + 1) } : { providerId: null, modelId: value };
5447
+ }
5448
+ function cleanOneLine(value) {
5449
+ const oneLine = sanitizeDiagnosticText(value).replaceAll("\r", " ").replaceAll(`
5450
+ `, " ").replaceAll("\t", " ").replace(/\s+/g, " ").trim();
5451
+ return oneLine.length <= MAX_SUBAGENT_INVOCATION_ERROR_CHARS ? oneLine : `${oneLine.slice(0, MAX_SUBAGENT_INVOCATION_ERROR_CHARS - 1)}…`;
5452
+ }
5453
+ function recordMessage(error) {
5454
+ if (typeof error === "string")
5455
+ return error;
5456
+ if (!error || typeof error !== "object")
5457
+ return String(error ?? "");
5458
+ const record = error;
5459
+ const data = record.data && typeof record.data === "object" ? record.data : undefined;
5460
+ const message = typeof data?.message === "string" ? data.message : typeof record.message === "string" ? record.message : typeof record.description === "string" ? record.description : "";
5461
+ const name = typeof record.name === "string" ? record.name : typeof record.type === "string" ? record.type : "";
5462
+ return [name, message].filter(Boolean).join(": ") || "The host reported an error without a message.";
5463
+ }
5464
+ function modelNotFoundDetail(error, attemptedModel) {
5465
+ const seen = new Set;
5466
+ const visit = (value, depth) => {
5467
+ if (typeof value === "string") {
5468
+ const modelMatch = value.match(/model not found:\s*(.+?)(?=(?:\.?\s*did you mean|$))/i);
5469
+ if (!modelMatch)
5470
+ return null;
5471
+ const model = modelMatch[1].trim().replace(/[.,;(]+$/, "");
5472
+ const suggestion = value.match(/did you mean:?\s*\(?\s*([^?);]+)/i)?.[1]?.trim();
5473
+ const message = `Model not found: ${model}${suggestion ? ` (did you mean ${suggestion}?)` : ""}`;
5474
+ return { model, ...suggestion ? { suggestion } : {}, message };
5475
+ }
5476
+ if (!value || typeof value !== "object" || depth > 4 || seen.has(value))
5477
+ return null;
5478
+ seen.add(value);
5479
+ const record = value;
5480
+ const data = record.data && typeof record.data === "object" ? record.data : undefined;
5481
+ const modelRecord = data?.model ?? record.model;
5482
+ const modelId = (typeof data?.modelID === "string" ? data.modelID : undefined) ?? (typeof modelRecord?.modelID === "string" ? modelRecord.modelID : undefined) ?? (typeof modelRecord?.id === "string" ? modelRecord.id : undefined);
5483
+ const providerId = (typeof data?.providerID === "string" ? data.providerID : undefined) ?? (typeof modelRecord?.providerID === "string" ? modelRecord.providerID : undefined);
5484
+ const suggestions = data?.suggestions;
5485
+ const suggestion = Array.isArray(suggestions) && typeof suggestions[0] === "string" ? suggestions[0] : typeof data?.suggestion === "string" ? data.suggestion : undefined;
5486
+ const rawMessage = recordMessage(value);
5487
+ const fromMessage = visit(rawMessage, depth + 1);
5488
+ if (fromMessage)
5489
+ return fromMessage.suggestion || !suggestion ? fromMessage : {
5490
+ ...fromMessage,
5491
+ suggestion,
5492
+ message: `Model not found: ${fromMessage.model} (did you mean ${suggestion}?)`
5493
+ };
5494
+ const name = `${String(record.name ?? "")} ${String(record.type ?? "")}`;
5495
+ if (/ProviderModelNotFoundError|model not found/i.test(name) && modelId) {
5496
+ const model = providerId ? `${providerId}/${modelId}` : modelId;
5497
+ const detail = `Model not found: ${model}${suggestion ? ` (did you mean ${suggestion}?)` : ""}`;
5498
+ return { model, ...suggestion ? { suggestion } : {}, message: detail };
5499
+ }
5500
+ for (const key of ["data", "error", "cause", "hostError"]) {
5501
+ const match = visit(record[key], depth + 1);
5502
+ if (match)
5503
+ return match;
5504
+ }
5505
+ return null;
5506
+ };
5507
+ const found = visit(error, 0);
5508
+ if (!found && attemptedModel && (typeof error === "string" && /ProviderModelNotFoundError/i.test(error) || error !== null && typeof error === "object" && /ProviderModelNotFoundError/i.test(`${String(error.name ?? "")} ${String(error.type ?? "")}`))) {
5509
+ return { model: attemptedModel, message: `Model not found: ${attemptedModel}` };
5510
+ }
5511
+ return found;
5512
+ }
5513
+ function hostLabel(harness) {
5514
+ switch (harness) {
5515
+ case "opencode2":
5516
+ return "OpenCode 2";
5517
+ case "opencode":
5518
+ return "OpenCode";
5519
+ case "pi":
5520
+ return "Pi";
5521
+ case "omp":
5522
+ return "Oh My Pi";
5523
+ }
5524
+ }
5525
+ function invocationErrorText(input, details, attemptedModel) {
5526
+ if (input.error == null && input.hostError == null && details.hostError == null)
5527
+ return null;
5528
+ const rawHostError = input.hostError ?? details.hostError;
5529
+ const modelError = modelNotFoundDetail(rawHostError ?? input.error, attemptedModel);
5530
+ if (modelError) {
5531
+ return cleanOneLine(`No reply: ${hostLabel(input.harness)} refused the model: ${modelError.message}`);
5532
+ }
5533
+ if (rawHostError != null) {
5534
+ return cleanOneLine(`No reply: ${hostLabel(input.harness)} reported a child-session error: ${recordMessage(rawHostError)}`);
5535
+ }
5536
+ return cleanOneLine(describeError(input.error).brief);
5537
+ }
5538
+ function warnUnknownModel(input, details, attemptedModel, modelConfigKey) {
5539
+ if (!attemptedModel)
5540
+ return;
5541
+ const issue = modelNotFoundDetail(input.hostError ?? details.hostError ?? input.error, attemptedModel);
5542
+ if (!issue || warnedUnknownModels.has(attemptedModel))
5543
+ return;
5544
+ if (!modelConfigKey)
5545
+ return;
5546
+ warnedUnknownModels.add(attemptedModel);
5547
+ const suggestion = issue.suggestion ? `provider suggests ${cleanOneLine(issue.suggestion)}` : "provider gave no model suggestion";
5548
+ log2(`[magic-context] WARNING: ${modelConfigKey} configured ${attemptedModel}, but ${hostLabel(input.harness)} does not know that model; ${suggestion}`);
5549
+ }
5377
5550
  function asNumber(value) {
5378
5551
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
5379
5552
  }
@@ -5444,8 +5617,11 @@ function sumTokensFromChildMessages(messages) {
5444
5617
  function findLastAssistantModel(messages) {
5445
5618
  for (let index = messages.length - 1;index >= 0; index -= 1) {
5446
5619
  const message = messages[index];
5447
- if (isAssistantMessage(message))
5448
- return modelFromMessage(message);
5620
+ if (isAssistantMessage(message)) {
5621
+ const model = modelFromMessage(message);
5622
+ if (model.providerId || model.modelId)
5623
+ return model;
5624
+ }
5449
5625
  }
5450
5626
  return { providerId: null, modelId: null };
5451
5627
  }
@@ -5454,10 +5630,25 @@ function recordChildInvocation(input) {
5454
5630
  return null;
5455
5631
  const tokens = input.tokens ?? sumTokensFromChildMessages(input.messages ?? []);
5456
5632
  const observedModel = findLastAssistantModel(input.messages ?? []);
5633
+ const details = errorDetailsOf(input.error);
5634
+ const attemptedModel = details.attemptedModel ?? modelRef(input.attemptedModel);
5635
+ const attemptConfig = [input.attemptedModel, ...input.configuredModels ?? []].find((candidate) => modelRef(candidate) === attemptedModel);
5636
+ const modelConfigKey = details.modelConfigKey ?? input.modelConfigKey ?? (typeof attemptConfig === "object" ? attemptConfig?.sourceConfigKey : undefined);
5637
+ const attemptedParts = splitModelRef(attemptedModel);
5457
5638
  const model = {
5458
- providerId: input.providerId ?? observedModel.providerId,
5459
- modelId: input.modelId ?? observedModel.modelId
5639
+ providerId: observedModel.providerId ?? input.providerId ?? attemptedParts.providerId,
5640
+ modelId: observedModel.modelId ?? input.modelId ?? attemptedParts.modelId
5460
5641
  };
5642
+ const reportedModelRef = observedModel.providerId && observedModel.modelId ? `${observedModel.providerId}/${observedModel.modelId}` : input.providerId && input.modelId ? `${input.providerId}/${input.modelId}` : undefined;
5643
+ if (attemptedModel && reportedModelRef && attemptedModel !== reportedModelRef && (observedModel.providerId !== null || input.providerId !== undefined)) {
5644
+ const rerouteKey = `${input.harness}\x00${attemptedModel}\x00${reportedModelRef}`;
5645
+ if (!loggedModelReroutes.has(rerouteKey)) {
5646
+ loggedModelReroutes.add(rerouteKey);
5647
+ sessionLog2(input.parentSessionId, `subagent model rerouted by host: attempted=${attemptedModel} reported=${reportedModelRef}`);
5648
+ }
5649
+ }
5650
+ warnUnknownModel(input, details, attemptedModel, modelConfigKey);
5651
+ const errorText = invocationErrorText(input, details, attemptedModel);
5461
5652
  try {
5462
5653
  return recordSubagentInvocation(input.db, {
5463
5654
  sessionId: input.parentSessionId,
@@ -5473,7 +5664,7 @@ function recordChildInvocation(input) {
5473
5664
  outputTokens: tokens.output,
5474
5665
  cacheReadTokens: tokens.cacheRead,
5475
5666
  cacheWriteTokens: tokens.cacheWrite,
5476
- error: input.error ? describeError(input.error).brief : null,
5667
+ error: errorText,
5477
5668
  parentInvocationId: input.parentInvocationId ?? null
5478
5669
  });
5479
5670
  } catch (error) {
@@ -5501,6 +5692,17 @@ var HOST_SESSION_ERROR = Symbol("promptAsyncHostSessionError");
5501
5692
  function isHostSessionError(error) {
5502
5693
  return error !== null && typeof error === "object" && error[HOST_SESSION_ERROR] === true;
5503
5694
  }
5695
+ function hostSessionErrorOf(error) {
5696
+ if (!isHostSessionError(error))
5697
+ return;
5698
+ return error.hostError;
5699
+ }
5700
+ function requestModelRef(request) {
5701
+ const model = request.body?.model;
5702
+ if (model && typeof model.providerID === "string" && typeof model.modelID === "string")
5703
+ return `${model.providerID}/${model.modelID}`;
5704
+ return;
5705
+ }
5504
5706
  function supportsPromptAsync(client) {
5505
5707
  const session = sessionApi(client);
5506
5708
  return typeof session?.promptAsync === "function" && typeof session?.status === "function" && typeof session?.messages === "function";
@@ -5655,11 +5857,29 @@ async function promptAsyncAndWaitForIdle(client, request, options = {}) {
5655
5857
  const initialBaseline = new Set(completionBaseline);
5656
5858
  activeSessionErrors.set(sessionId, undefined);
5657
5859
  try {
5658
- const sent = await session.promptAsync?.(request);
5860
+ let sent;
5861
+ try {
5862
+ sent = await session.promptAsync?.(request);
5863
+ } catch (error) {
5864
+ annotateSubagentInvocationError(error, {
5865
+ attemptedModel: requestModelRef(request),
5866
+ modelConfigKey: options.modelConfigKey,
5867
+ hostError: error
5868
+ });
5869
+ throw error;
5870
+ }
5659
5871
  if (sent && typeof sent === "object" && "error" in sent) {
5660
5872
  const rejection = sent.error;
5661
5873
  if (rejection) {
5662
- throw new Error(`prompt_async was rejected: ${describeRejection(rejection)}`);
5874
+ const error = new Error(`prompt_async was rejected: ${describeRejection(rejection)}`, {
5875
+ cause: rejection
5876
+ });
5877
+ annotateSubagentInvocationError(error, {
5878
+ attemptedModel: requestModelRef(request),
5879
+ modelConfigKey: options.modelConfigKey,
5880
+ hostError: rejection
5881
+ });
5882
+ throw error;
5663
5883
  }
5664
5884
  }
5665
5885
  let sentAt = Date.now();
@@ -5674,7 +5894,13 @@ async function promptAsyncAndWaitForIdle(client, request, options = {}) {
5674
5894
  Object.assign(error, {
5675
5895
  name: "DreamerProviderOutputFailureError",
5676
5896
  transient: true,
5677
- [HOST_SESSION_ERROR]: true
5897
+ [HOST_SESSION_ERROR]: true,
5898
+ hostError
5899
+ });
5900
+ annotateSubagentInvocationError(error, {
5901
+ attemptedModel: requestModelRef(request),
5902
+ modelConfigKey: options.modelConfigKey,
5903
+ hostError
5678
5904
  });
5679
5905
  throw error;
5680
5906
  }
@@ -9238,6 +9464,8 @@ function resolveHiddenCompletionExecutor(executor, client, db, directory, entryP
9238
9464
  }
9239
9465
  function createV1HiddenCompletionExecutor(client, db, directory) {
9240
9466
  const historianChildren = new Set;
9467
+ const hostErrors = new Map;
9468
+ const runIdentities = new Map;
9241
9469
  return {
9242
9470
  capabilities: { tools: true, harness: "opencode" },
9243
9471
  async open(run) {
@@ -9254,23 +9482,49 @@ function createV1HiddenCompletionExecutor(client, db, directory) {
9254
9482
  preferResponseOnMissingData: true
9255
9483
  });
9256
9484
  const id = typeof created?.id === "string" ? created.id : "";
9257
- if (id)
9485
+ if (id) {
9258
9486
  rememberV1HiddenRun(id, run);
9487
+ runIdentities.set(id, run);
9488
+ }
9259
9489
  if (id && run.kind !== "dreamer-task") {
9260
9490
  historianChildren.add(id);
9261
9491
  rememberHistorianOutputCap(id, run.maxOutputTokens);
9262
9492
  }
9263
- return { id, childSessionId: id || undefined };
9493
+ const configured = toModelEntry(run.model);
9494
+ return {
9495
+ id,
9496
+ childSessionId: id || undefined,
9497
+ ...configured ? { attemptedModel: configured.model } : {},
9498
+ ...configured?.sourceConfigKey ? { modelConfigKey: configured.sourceConfigKey } : {}
9499
+ };
9264
9500
  },
9265
9501
  async attempt(handle, request) {
9266
9502
  if (!client)
9267
9503
  throw new Error("Hidden completion client is unavailable");
9504
+ const identity = runIdentities.get(handle.id);
9505
+ const requestedModel = request.body?.model;
9506
+ const requestedRef = requestedModel && typeof requestedModel.providerID === "string" && typeof requestedModel.modelID === "string" ? `${requestedModel.providerID}/${requestedModel.modelID}` : undefined;
9507
+ const matchingConfigured = (identity?.configuredModels ?? []).map(toModelEntry).find((entry) => entry?.model === requestedRef);
9508
+ const configured = matchingConfigured ?? (requestedRef && identity?.model && toModelEntry(identity.model)?.model === requestedRef ? toModelEntry(identity.model) : toModelEntry(identity?.model));
9509
+ handle.attemptedModel = requestedRef ?? configured?.model ?? handle.attemptedModel;
9510
+ handle.modelConfigKey = configured?.sourceConfigKey ?? handle.modelConfigKey;
9268
9511
  if (supportsPromptAsync(client)) {
9269
9512
  try {
9270
- await promptAsyncAndWaitForIdle(client, request);
9513
+ await promptAsyncAndWaitForIdle(client, request, {
9514
+ modelConfigKey: handle.modelConfigKey
9515
+ });
9271
9516
  } catch (error) {
9272
- if (historianChildren.has(handle.id) && isHostSessionError(error))
9273
- return;
9517
+ if (isHostSessionError(error)) {
9518
+ const hostError = hostSessionErrorOf(error);
9519
+ hostErrors.set(handle.id, hostError);
9520
+ annotateSubagentInvocationError(error, {
9521
+ attemptedModel: handle.attemptedModel,
9522
+ modelConfigKey: handle.modelConfigKey,
9523
+ hostError
9524
+ });
9525
+ if (historianChildren.has(handle.id))
9526
+ return;
9527
+ }
9274
9528
  throw error;
9275
9529
  }
9276
9530
  return;
@@ -9288,9 +9542,16 @@ function createV1HiddenCompletionExecutor(client, db, directory) {
9288
9542
  preferResponseOnMissingData: true
9289
9543
  });
9290
9544
  const assistantFailure = extractLatestAssistantFailure(messages);
9545
+ const hostError = hostErrors.get(handle.id);
9291
9546
  if (assistantFailure) {
9292
9547
  const finish = assistantFailure.finish ? ` (finish=${assistantFailure.finish})` : "";
9293
- throw new Error(`Historian host recorded an assistant error${finish}: ${describeAssistantFailure(assistantFailure.error)}`);
9548
+ const error = new Error(`Historian host recorded an assistant error${finish}: ${describeAssistantFailure(assistantFailure.error)}`, hostError === undefined ? undefined : { cause: hostError });
9549
+ annotateSubagentInvocationError(error, {
9550
+ attemptedModel: handle.attemptedModel,
9551
+ modelConfigKey: handle.modelConfigKey,
9552
+ hostError
9553
+ });
9554
+ throw error;
9294
9555
  }
9295
9556
  const text = extractLatestAssistantText(messages);
9296
9557
  const latest = Array.isArray(messages) ? messages.filter((message) => isRecord(message) && isRecord(message.info) && message.info.role === "assistant").sort((left, right) => historianMessageCreatedAt(right) - historianMessageCreatedAt(left))[0] : undefined;
@@ -9301,13 +9562,18 @@ function createV1HiddenCompletionExecutor(client, db, directory) {
9301
9562
  reasoning: text ? null : extractLatestHistorianReasoning(messages),
9302
9563
  lengthCapped: hasLengthCappedOutput(messages),
9303
9564
  usage: sumTokensFromChildMessages(messages),
9304
- tokenLog: runTokenLog(info.tokens, undefined, info.finish ?? info.finish_reason ?? info.finishReason)
9565
+ tokenLog: runTokenLog(info.tokens, undefined, info.finish ?? info.finish_reason ?? info.finishReason),
9566
+ attemptedModel: handle.attemptedModel,
9567
+ modelConfigKey: handle.modelConfigKey,
9568
+ ...hostError === undefined ? {} : { hostError }
9305
9569
  };
9306
9570
  },
9307
9571
  async close(handle, settlement) {
9308
9572
  if (handle?.id) {
9309
9573
  rememberV1HiddenRun(handle.id, undefined);
9310
9574
  historianChildren.delete(handle.id);
9575
+ hostErrors.delete(handle.id);
9576
+ runIdentities.delete(handle.id);
9311
9577
  forgetHistorianOutputCap(handle.id);
9312
9578
  }
9313
9579
  if (!client)
@@ -9462,7 +9728,8 @@ async function runHistorianPrompt(args) {
9462
9728
  if (invocationRecorded)
9463
9729
  return null;
9464
9730
  invocationRecorded = true;
9465
- const actualModelRef = completion?.providerId && completion.modelId ? `${completion.providerId}/${completion.modelId}` : null;
9731
+ const configuredModel = toModelEntry(modelOverride);
9732
+ const actualModelRef = completion?.providerId && completion.modelId ? `${completion.providerId}/${completion.modelId}` : handle?.attemptedModel ?? configuredModel?.model ?? null;
9466
9733
  const usedConfiguredFallback = actualModelRef !== null && (fallbackModels ?? []).some((candidate) => toModelEntry(candidate)?.model === actualModelRef);
9467
9734
  return recordChildInvocation({
9468
9735
  db: openDatabase(),
@@ -9478,6 +9745,10 @@ async function runHistorianPrompt(args) {
9478
9745
  providerId: completion.providerId,
9479
9746
  modelId: completion.modelId
9480
9747
  } : {},
9748
+ attemptedModel: handle?.attemptedModel ?? modelOverride,
9749
+ configuredModels: fallbackModels,
9750
+ modelConfigKey: handle?.modelConfigKey ?? configuredModel?.sourceConfigKey,
9751
+ hostError: params.hostError ?? completion?.hostError,
9481
9752
  error: params.error,
9482
9753
  parentInvocationId: agentId === HISTORIAN_EDITOR_AGENT ? parentInvocationId ?? null : null
9483
9754
  });
@@ -9591,7 +9862,8 @@ async function runHistorianPrompt(args) {
9591
9862
  const invocationId = recordInvocation({
9592
9863
  status: emptyError ? "empty" : "completed",
9593
9864
  messages: completion.messages,
9594
- error: emptyError
9865
+ error: emptyError,
9866
+ hostError: completion.hostError
9595
9867
  });
9596
9868
  if (emptyError && (!reasoningResult || lengthCapped)) {
9597
9869
  return {
@@ -10414,7 +10686,9 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
10414
10686
  status: "completed",
10415
10687
  tokens: run.output.usage,
10416
10688
  providerId: run.output.providerId,
10417
- modelId: run.output.modelId
10689
+ modelId: run.output.modelId,
10690
+ attemptedModel: args.model,
10691
+ configuredModels: args.fallbackModels
10418
10692
  });
10419
10693
  }
10420
10694
  stage = "apply";
@@ -10606,6 +10880,7 @@ async function runHiddenSingleShotPrompt(args) {
10606
10880
  });
10607
10881
  }).catch(() => {});
10608
10882
  const handle = await raceWithSignal(opening, args.signal);
10883
+ let completion;
10609
10884
  args.onOpened?.(handle.id);
10610
10885
  let promptSettled = false;
10611
10886
  try {
@@ -10627,7 +10902,10 @@ async function runHiddenSingleShotPrompt(args) {
10627
10902
  ...args.signal ? { signal: args.signal } : {},
10628
10903
  fallbackModels: args.fallbackModels,
10629
10904
  callContext: args.callContext,
10630
- fetchOutput: () => args.executor.collect(handle, 50),
10905
+ fetchOutput: async () => {
10906
+ completion = await args.executor.collect(handle, 50);
10907
+ return completion;
10908
+ },
10631
10909
  validateOutput: (completion) => {
10632
10910
  const tokens = completion.tokenLog ?? runTokenLog(undefined);
10633
10911
  sessionLog2(args.parentSessionId ?? "dreamer", `${args.callContext} response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
@@ -10643,6 +10921,12 @@ async function runHiddenSingleShotPrompt(args) {
10643
10921
  promptSettled = true;
10644
10922
  return { validated: run.validated, completion: run.output, childSessionId: handle.id };
10645
10923
  } catch (error) {
10924
+ const configuredModel = toModelEntry(args.model);
10925
+ annotateSubagentInvocationError(error, {
10926
+ attemptedModel: completion?.attemptedModel ?? handle.attemptedModel ?? configuredModel?.model,
10927
+ modelConfigKey: completion?.modelConfigKey ?? handle.modelConfigKey ?? configuredModel?.sourceConfigKey,
10928
+ ...completion?.hostError === undefined ? {} : { hostError: completion.hostError }
10929
+ });
10646
10930
  if (args.onFailureOutput) {
10647
10931
  let timer;
10648
10932
  try {
@@ -10970,6 +11254,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
10970
11254
  startedAt,
10971
11255
  status: params.status,
10972
11256
  messages: params.messages,
11257
+ attemptedModel: args.model,
11258
+ configuredModels: args.fallbackModels,
10973
11259
  error: params.error
10974
11260
  });
10975
11261
  };
@@ -11757,6 +12043,8 @@ function recordInvocation(args, startedAt, params) {
11757
12043
  startedAt,
11758
12044
  status: params.status,
11759
12045
  messages: params.messages,
12046
+ attemptedModel: args.model,
12047
+ configuredModels: args.fallbackModels,
11760
12048
  ...params.completion && !params.completion.messages ? {
11761
12049
  tokens: params.completion.usage,
11762
12050
  providerId: params.completion.providerId,
@@ -13292,6 +13580,8 @@ Remember: output only the JSON object described by the system prompt.`;
13292
13580
  startedAt,
13293
13581
  status: params.status,
13294
13582
  messages: params.messages,
13583
+ attemptedModel: args.model,
13584
+ configuredModels: args.fallbackModels,
13295
13585
  error: params.error
13296
13586
  });
13297
13587
  };
@@ -14039,6 +14329,8 @@ async function confirmReadOnly(args, noteId, content, surfaceCondition, leaseSig
14039
14329
  startedAt,
14040
14330
  status: params.status,
14041
14331
  messages: params.messages,
14332
+ attemptedModel: args.model,
14333
+ configuredModels: args.fallbackModels,
14042
14334
  error: params.error
14043
14335
  });
14044
14336
  };
@@ -14953,12 +15245,14 @@ function recordInvocation2(args, startedAt, params) {
14953
15245
  recordChildInvocation({
14954
15246
  db: args.db,
14955
15247
  parentSessionId: args.parentSessionId,
14956
- harness: "opencode",
15248
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
14957
15249
  subagent: "dreamer",
14958
15250
  task: "map-memories",
14959
15251
  startedAt,
14960
15252
  status: params.status,
14961
15253
  messages: params.messages,
15254
+ attemptedModel: args.model,
15255
+ configuredModels: args.fallbackModels,
14962
15256
  error: params.error
14963
15257
  });
14964
15258
  }
@@ -15583,12 +15877,14 @@ function recordInvocation3(args, startedAt, params) {
15583
15877
  recordChildInvocation({
15584
15878
  db: args.db,
15585
15879
  parentSessionId: args.parentSessionId,
15586
- harness: "opencode",
15880
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
15587
15881
  subagent: "dreamer",
15588
15882
  task: "refresh-primers",
15589
15883
  startedAt,
15590
15884
  status: params.status,
15591
15885
  messages: params.messages,
15886
+ attemptedModel: args.model,
15887
+ configuredModels: args.fallbackModels,
15592
15888
  error: params.error
15593
15889
  });
15594
15890
  }
@@ -17162,12 +17458,14 @@ function recordInvocation4(args, startedAt, params) {
17162
17458
  recordChildInvocation({
17163
17459
  db: args.db,
17164
17460
  parentSessionId: args.parentSessionId,
17165
- harness: "opencode",
17461
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
17166
17462
  subagent: "dreamer",
17167
17463
  task: args.forceBroad ? "verify-broad" : "verify",
17168
17464
  startedAt,
17169
17465
  status: params.status,
17170
17466
  messages: params.messages,
17467
+ attemptedModel: args.model,
17468
+ configuredModels: args.fallbackModels,
17171
17469
  error: params.error
17172
17470
  });
17173
17471
  }
@@ -18043,6 +18341,25 @@ async function runRetrospectiveTask(config, ctx, helpers) {
18043
18341
  let childSessionId = null;
18044
18342
  let hiddenHandle = null;
18045
18343
  let promptSettled = false;
18344
+ let invocationRecorded = false;
18345
+ const recordInvocation = (status, messages, error) => {
18346
+ if (!parent || !childSessionId || invocationRecorded)
18347
+ return;
18348
+ invocationRecorded = true;
18349
+ recordChildInvocation({
18350
+ db,
18351
+ parentSessionId: parent,
18352
+ harness: deps.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
18353
+ subagent: "dreamer",
18354
+ task: config.task,
18355
+ startedAt: helpers.invocationStartedAt,
18356
+ status,
18357
+ messages,
18358
+ attemptedModel: config.model,
18359
+ configuredModels: config.fallbackModels,
18360
+ error
18361
+ });
18362
+ };
18046
18363
  try {
18047
18364
  if (deps.hiddenCompletionExecutor) {
18048
18365
  hiddenHandle = await deps.hiddenCompletionExecutor.open({
@@ -18127,18 +18444,8 @@ async function runRetrospectiveTask(config, ctx, helpers) {
18127
18444
  return { ...run, output };
18128
18445
  };
18129
18446
  const finish = (run, watermark) => {
18130
- if (parent && run) {
18131
- recordChildInvocation({
18132
- db,
18133
- parentSessionId: parent,
18134
- harness: "opencode",
18135
- subagent: "dreamer",
18136
- task: config.task,
18137
- startedAt: helpers.invocationStartedAt,
18138
- status: "completed",
18139
- messages: run.output
18140
- });
18141
- }
18447
+ if (run)
18448
+ recordInvocation("completed", run.output);
18142
18449
  return completedWindow(watermark);
18143
18450
  };
18144
18451
  const userLines = renderGateUserLines(messages);
@@ -18231,6 +18538,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
18231
18538
  log2(`[dreamer] retrospective: flagged=${flagged.length} learnings=${learnings.length} memory=${applied.memoryWritten} observations=${applied.observationsInserted} dropped=${applied.observationsDropped} rejected=${applied.rejected.length}`);
18232
18539
  return finish(deepenRun, scan.maxScannedTs);
18233
18540
  } catch (error) {
18541
+ recordInvocation(abortController.signal.aborted ? "aborted" : failedInvocationStatus(error), undefined, error);
18234
18542
  if (!detectOverflow(error).isOverflow)
18235
18543
  throw error;
18236
18544
  const failures = (activeOverflow?.failures ?? 0) + 1;
@@ -18302,6 +18610,25 @@ async function runAgenticTask(config, ctx, helpers) {
18302
18610
  let childSessionId = null;
18303
18611
  let promptSettled = false;
18304
18612
  let expiredArchived = 0;
18613
+ let invocationRecorded = false;
18614
+ const recordInvocation = (status, messages, error) => {
18615
+ if (!parent || !childSessionId || invocationRecorded)
18616
+ return;
18617
+ invocationRecorded = true;
18618
+ recordChildInvocation({
18619
+ db,
18620
+ parentSessionId: parent,
18621
+ harness: deps.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
18622
+ subagent: "dreamer",
18623
+ task,
18624
+ startedAt: invocationStartedAt,
18625
+ status,
18626
+ messages,
18627
+ attemptedModel: config.model,
18628
+ configuredModels: config.fallbackModels,
18629
+ error
18630
+ });
18631
+ };
18305
18632
  try {
18306
18633
  let curateMemories;
18307
18634
  let curateCategory;
@@ -18390,6 +18717,9 @@ async function runAgenticTask(config, ctx, helpers) {
18390
18717
  callContext: `dreamer:${task}`,
18391
18718
  metadata: { tokenBudget: config.tokenBudget, onBudgetUpdate },
18392
18719
  allowEmpty: task === "curate",
18720
+ onOpened: (sessionId) => {
18721
+ childSessionId = sessionId;
18722
+ },
18393
18723
  model: config.model,
18394
18724
  fallbackModels: config.fallbackModels,
18395
18725
  language: task === "curate" ? config.language ?? deps.language : undefined,
@@ -18505,18 +18835,7 @@ async function runAgenticTask(config, ctx, helpers) {
18505
18835
  helpers.reportProgress(curateRefused, curateRefused);
18506
18836
  log2(`[dreamer] curate safety summary: refused=${curateRefused}`);
18507
18837
  }
18508
- if (parent) {
18509
- recordChildInvocation({
18510
- db,
18511
- parentSessionId: parent,
18512
- harness: "opencode",
18513
- subagent: "dreamer",
18514
- task,
18515
- startedAt: invocationStartedAt,
18516
- status: "completed",
18517
- messages: run.output
18518
- });
18519
- }
18838
+ recordInvocation("completed", run.output);
18520
18839
  if (task === "maintain-docs" && docsHashes && changes) {
18521
18840
  try {
18522
18841
  if (run.validated === "[]") {
@@ -18570,6 +18889,9 @@ async function runAgenticTask(config, ctx, helpers) {
18570
18889
  }
18571
18890
  } : {}
18572
18891
  };
18892
+ } catch (error) {
18893
+ recordInvocation(abortController.signal.aborted ? "aborted" : failedInvocationStatus(error), undefined, error);
18894
+ throw error;
18573
18895
  } finally {
18574
18896
  heartbeat.stop();
18575
18897
  if (childSessionId)
@@ -19355,6 +19677,11 @@ async function indexSingleMessageOffThread(db, sessionId, message) {
19355
19677
  return result.inserted;
19356
19678
  }
19357
19679
  async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, options = {}) {
19680
+ if (getHarness2() === "opencode" || getHarness2() === "opencode2")
19681
+ options = {
19682
+ ...options,
19683
+ fenceLockNames: options.fenceLockNames ?? takeLkgRecoveryLockSweepPage()
19684
+ };
19358
19685
  if (getHarness2() === "opencode2")
19359
19686
  openSource = () => new Database2(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), {
19360
19687
  readonly: true,
@@ -20580,7 +20907,8 @@ class PiSubagentRunner {
20580
20907
  ...options,
20581
20908
  model: attempt?.model,
20582
20909
  thinkingLevel: attempt?.qualifier,
20583
- fallbackModels: undefined
20910
+ fallbackModels: undefined,
20911
+ accountingModelConfigKey: typeof attempt === "object" ? attempt.sourceConfigKey ?? options.accountingModelConfigKey : options.accountingModelConfigKey
20584
20912
  };
20585
20913
  const result = await this.runOnce(attemptOptions, runMode, index === 0 ? primaryModelRef : undefined);
20586
20914
  if (result.ok)
@@ -20635,6 +20963,8 @@ class PiSubagentRunner {
20635
20963
  subagent: options.accountingSubagent ?? inferAccountingSubagent(options.agent),
20636
20964
  task: options.accountingTask ?? null,
20637
20965
  startedAt: startTime,
20966
+ attemptedModel: modelRef,
20967
+ modelConfigKey: options.accountingModelConfigKey,
20638
20968
  status: result.ok ? "completed" : result.meta?.failureClass === ZEN_FREE_TIER_FAILURE ? "failed" : result.reason === "abort" ? "aborted" : result.reason === "timeout" ? "timed_out" : result.reason === "no_assistant" || result.reason === "truncated" ? "empty" : "failed",
20639
20969
  messages,
20640
20970
  providerId: hasProvider ? modelRef?.slice(0, providerSeparator) : undefined,
@@ -21184,10 +21514,11 @@ class PiSubagentRunner {
21184
21514
  if (settled)
21185
21515
  return;
21186
21516
  terminateChild(child);
21517
+ const silentCut = options.signal?.reason instanceof ModelProducedNoOutputError ? options.signal.reason : undefined;
21187
21518
  settle({
21188
21519
  ok: false,
21189
- reason: "abort",
21190
- error: "pi subagent aborted by caller",
21520
+ reason: silentCut ? "timeout" : "abort",
21521
+ error: silentCut?.message ?? "pi subagent aborted by caller",
21191
21522
  durationMs: Date.now() - startTime
21192
21523
  });
21193
21524
  };
@@ -21593,6 +21924,28 @@ function terminateChild(child) {
21593
21924
  }
21594
21925
  }
21595
21926
 
21927
+ // src/dreamer/model-activity.ts
21928
+ function piEventShowsModelOutput(event) {
21929
+ if (!isRecord(event))
21930
+ return false;
21931
+ if (event.type !== "message_update" && event.type !== "message_end")
21932
+ return false;
21933
+ const update = event.assistantMessageEvent;
21934
+ if (event.type === "message_update" && isRecord(update)) {
21935
+ if (update.type === "toolcall_start")
21936
+ return true;
21937
+ if (["text_delta", "thinking_delta", "toolcall_delta"].includes(String(update.type)) && typeof update.delta === "string" && update.delta.length > 0)
21938
+ return true;
21939
+ }
21940
+ const message = event.message;
21941
+ if (!isRecord(message) || message.role !== "assistant")
21942
+ return false;
21943
+ if (Array.isArray(message.content) && message.content.some((part) => isRecord(part) && (part.type === "toolCall" || part.type === "text" && typeof part.text === "string" && part.text.length > 0 || part.type === "thinking" && typeof part.thinking === "string" && part.thinking.length > 0)))
21944
+ return true;
21945
+ const usage = message.usage;
21946
+ return isRecord(usage) && ["input", "output", "cacheRead", "cacheWrite"].some((key) => typeof usage[key] === "number" && usage[key] > 0);
21947
+ }
21948
+
21596
21949
  // src/dreamer/primer-raw-provider-pi.ts
21597
21950
  import { join as join13 } from "node:path";
21598
21951
 
@@ -22275,7 +22628,7 @@ function extractPiTextContent(content) {
22275
22628
  }
22276
22629
 
22277
22630
  // src/dreamer/index.ts
22278
- var warnedUnknownModels = new Set;
22631
+ var warnedUnknownModels2 = new Set;
22279
22632
  var modelAvailability = new WeakMap;
22280
22633
  function validatePiDreamerModels(tasks, registry, harness = "pi") {
22281
22634
  let resolved = modelAvailability.get(registry);
@@ -22297,9 +22650,9 @@ function validatePiDreamerModels(tasks, registry, harness = "pi") {
22297
22650
  }
22298
22651
  if (available)
22299
22652
  return true;
22300
- if (!warnedUnknownModels.has(model)) {
22653
+ if (!warnedUnknownModels2.has(model)) {
22301
22654
  log2(`[dreamer] WARNING: dropping Pi model not found: ${model}`);
22302
- warnedUnknownModels.add(model);
22655
+ warnedUnknownModels2.add(model);
22303
22656
  }
22304
22657
  return false;
22305
22658
  });
@@ -22531,6 +22884,8 @@ function createPiDreamerClient(opts, onAdjunctsRefreshNeeded = opts.onAdjunctsRe
22531
22884
  const systemPrompt = extractSystemPrompt(args);
22532
22885
  const perTaskModel = extractBodyModel(args);
22533
22886
  const requestedAgent = extractBodyAgent(args) ?? "magic-context-dreamer";
22887
+ const accountingTask = accountingTaskFromTitle(dreamSession.title);
22888
+ const taskConfig = accountingTask ? buildDreamTaskRuntimeConfigs(getDreamerConfig(), opts.harness).find((entry) => entry.task === accountingTask) : undefined;
22534
22889
  const controller = new AbortController;
22535
22890
  let controllers = dreamAbortControllers.get(opts.registrationOwner);
22536
22891
  if (!controllers) {
@@ -22538,7 +22893,12 @@ function createPiDreamerClient(opts, onAdjunctsRefreshNeeded = opts.onAdjunctsRe
22538
22893
  dreamAbortControllers.set(opts.registrationOwner, controllers);
22539
22894
  }
22540
22895
  controllers.add(controller);
22896
+ noteModelActivityMonitored(args.signal ?? undefined);
22541
22897
  const runPromise = runner.run({
22898
+ onProgress: (progress) => {
22899
+ if (progress.type === "raw_event" && piEventShowsModelOutput(progress.event))
22900
+ noteModelOutputReceived(args.signal ?? undefined);
22901
+ },
22542
22902
  agent: requestedAgent,
22543
22903
  systemPrompt,
22544
22904
  userMessage,
@@ -22551,15 +22911,9 @@ function createPiDreamerClient(opts, onAdjunctsRefreshNeeded = opts.onAdjunctsRe
22551
22911
  maxOutputTokens: getMaxOutputTokens(),
22552
22912
  accountingSessionId: opts.projectIdentity,
22553
22913
  accountingSubagent: "dreamer",
22554
- accountingTask: accountingTaskFromTitle(dreamSession.title),
22555
- tokenBudget: (() => {
22556
- if (args.tokenBudget !== undefined)
22557
- return args.tokenBudget;
22558
- const task = accountingTaskFromTitle(dreamSession.title);
22559
- if (!task)
22560
- return;
22561
- return buildDreamTaskRuntimeConfigs(getDreamerConfig(), opts.harness).find((entry) => entry.task === task)?.tokenBudget;
22562
- })()
22914
+ accountingTask,
22915
+ accountingModelConfigKey: taskConfig?.modelConfigKey,
22916
+ tokenBudget: args.tokenBudget ?? taskConfig?.tokenBudget
22563
22917
  });
22564
22918
  inFlightDreams.set(runPromise, opts.registrationOwner);
22565
22919
  try {
@@ -23007,6 +23361,13 @@ Unknown task "${requested}".`,
23007
23361
  }
23008
23362
 
23009
23363
  // ../plugin/src/hooks/magic-context/auto-embed-session.ts
23364
+ function localPoolingPreflightPending(projectIdentity) {
23365
+ const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
23366
+ if (snapshot?.provider !== "local")
23367
+ return false;
23368
+ const metadata = getCachedLocalEmbeddingPooling(snapshot.model);
23369
+ return !metadata || metadata.status === "unresolved";
23370
+ }
23010
23371
  function embeddingIdentity(projectIdentity) {
23011
23372
  const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
23012
23373
  return JSON.stringify([
@@ -23027,7 +23388,8 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
23027
23388
  invalidateAutoEmbedSession(sessionId);
23028
23389
  autoEmbedIdentityBySession.set(sessionId, identity);
23029
23390
  }
23030
- if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0))
23391
+ const poolingPreflightPending = localPoolingPreflightPending(deps.projectIdentity);
23392
+ if (embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0) || autoEmbedAttemptedBySession.has(sessionId) && !poolingPreflightPending)
23031
23393
  return;
23032
23394
  const controller = new AbortController;
23033
23395
  embedRunStateBySession.set(sessionId, controller);
@@ -23037,6 +23399,7 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
23037
23399
  let started = false;
23038
23400
  let reason = "error";
23039
23401
  let registeredIdentity = identity;
23402
+ let poolingPendingAfterRegistration = poolingPreflightPending;
23040
23403
  try {
23041
23404
  await new Promise((resolve) => setTimeout(resolve, 0));
23042
23405
  if (controller.signal.aborted)
@@ -23044,6 +23407,7 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
23044
23407
  await deps.ensureRegistered();
23045
23408
  if (controller.signal.aborted)
23046
23409
  return;
23410
+ poolingPendingAfterRegistration = localPoolingPreflightPending(deps.projectIdentity);
23047
23411
  markActive();
23048
23412
  registeredIdentity = embeddingIdentity(deps.projectIdentity);
23049
23413
  autoEmbedIdentityBySession.set(sessionId, registeredIdentity);
@@ -23051,7 +23415,9 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
23051
23415
  if (controller.signal.aborted || !coverage.enabled)
23052
23416
  return;
23053
23417
  if (coverage.embedded === coverage.total) {
23054
- complete = true;
23418
+ complete = !poolingPendingAfterRegistration;
23419
+ if (!complete)
23420
+ retryDelay = 60000;
23055
23421
  return;
23056
23422
  }
23057
23423
  const model = getProjectEmbeddingSnapshot2(deps.projectIdentity)?.model;
@@ -23060,8 +23426,11 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
23060
23426
  const outcome = await embedSessionCompartmentChunks2(deps.db, deps.projectIdentity, sessionId, { signal: controller.signal, automatic: true });
23061
23427
  reason = outcome.status;
23062
23428
  const after = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
23063
- complete = after.enabled && after.embedded === after.total;
23064
- if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
23429
+ complete = after.enabled && after.embedded === after.total && !poolingPendingAfterRegistration;
23430
+ if (poolingPendingAfterRegistration) {
23431
+ retryDelay = 60000;
23432
+ reason = "pooling metadata unavailable";
23433
+ } else if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
23065
23434
  retryDelay = 60000;
23066
23435
  if (outcome.status === "nothing" || outcome.status === "done")
23067
23436
  reason = "deferred";
@@ -23334,7 +23703,9 @@ function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity) {
23334
23703
  maybeAutoEmbedSessionBackfill({
23335
23704
  db: deps.db,
23336
23705
  projectIdentity,
23337
- ensureRegistered: () => ensureProjectRegisteredFromPiDirectory(projectDir, deps.db)
23706
+ ensureRegistered: () => ensureProjectRegisteredFromPiDirectory(projectDir, deps.db, {
23707
+ preflightLocalPooling: true
23708
+ })
23338
23709
  }, sessionId);
23339
23710
  }
23340
23711
 
@@ -24348,7 +24719,8 @@ function capturePendingDropEligibility(targets, protectedTagIds) {
24348
24719
  eligible.add(number);
24349
24720
  } else {
24350
24721
  const content = target.getContent?.();
24351
- if (typeof content === "string" && content.length > `[dropped §${number}§]`.length)
24722
+ const replacement = `[dropped §${number}§]`;
24723
+ if (typeof content === "string" && content.length > replacement.length && target.canSetContent?.(replacement) !== false)
24352
24724
  eligible.add(number);
24353
24725
  }
24354
24726
  }
@@ -24635,12 +25007,16 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
24635
25007
  }
24636
25008
  } else if (target) {
24637
25009
  const replacement = buildReplacementContent(pendingOp.tagId);
25010
+ if (target.canSetContent?.(replacement) === false) {
25011
+ reject("content_unchanged");
25012
+ continue;
25013
+ }
24638
25014
  persistDrop();
24639
25015
  mutations.push(() => {
24640
25016
  const priorContent = target.getContent?.();
24641
25017
  const changed = target.setContent(replacement);
24642
- record(changed);
24643
25018
  if (changed) {
25019
+ record(true);
24644
25020
  const originalCharacters = typeof priorContent === "string" ? priorContent.length : tagById.get(pendingOp.tagId)?.byteSize ?? replacement.length;
24645
25021
  onTagReduced?.({
24646
25022
  tagNumber: pendingOp.tagId,
@@ -24731,7 +25107,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
24731
25107
 
24732
25108
  // ../plugin/src/hooks/magic-context/cache-busting-signals.ts
24733
25109
  function hasReclaimRide(signals) {
24734
- return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true;
25110
+ return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true || signals.executeReclaim === true;
24735
25111
  }
24736
25112
  function prefixMutationPermitted(gate) {
24737
25113
  return !gate.signedThinkingHold || gate.firstRender || gate.idleExpiry || gate.emergency;
@@ -24744,7 +25120,8 @@ var RECLAIM_RIDE_NAMES = [
24744
25120
  "force",
24745
25121
  "explicitFlush",
24746
25122
  "publishedHistory",
24747
- "subagentExecute"
25123
+ "subagentExecute",
25124
+ "executeReclaim"
24748
25125
  ];
24749
25126
  function reclaimRideLabel(signals) {
24750
25127
  const active = RECLAIM_RIDE_NAMES.filter((name) => signals[name]);
@@ -24977,6 +25354,140 @@ function rearmChannel2AfterMeasuredCollapse(input) {
24977
25354
  return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
24978
25355
  }
24979
25356
 
25357
+ // ../plugin/src/hooks/magic-context/postprocess-read-cache.ts
25358
+ var connections = new WeakMap;
25359
+ function snapshot(db, sessionId) {
25360
+ const transaction = db;
25361
+ try {
25362
+ if (transaction.inTransaction || transaction.isTransaction) {
25363
+ connections.delete(db);
25364
+ return { version: -1, changes: -1 };
25365
+ }
25366
+ } catch {
25367
+ connections.delete(db);
25368
+ return { version: -1, changes: -1 };
25369
+ }
25370
+ let connection = connections.get(db);
25371
+ if (!connection) {
25372
+ connection = {
25373
+ stamp: db.prepare("SELECT total_changes() AS changes, data_version AS version FROM pragma_data_version"),
25374
+ sessions: new BoundedSessionMap(100)
25375
+ };
25376
+ connections.set(db, connection);
25377
+ }
25378
+ const stamp = connection.stamp.get();
25379
+ const previous = connection.sessions.get(sessionId);
25380
+ if (previous?.version === stamp.version && previous.changes === stamp.changes) {
25381
+ return previous;
25382
+ }
25383
+ const value = { ...stamp };
25384
+ connection.sessions.set(sessionId, value);
25385
+ return value;
25386
+ }
25387
+ function postprocessReplaySnapshot(db, sessionId) {
25388
+ const state = snapshot(db, sessionId);
25389
+ const replay = state.replay ??= loadPostprocessReplaySnapshot(db, sessionId);
25390
+ return {
25391
+ ...replay,
25392
+ staleReduceStrippedIds: new Set(replay.staleReduceStrippedIds),
25393
+ processedImageStrippedIds: new Set(replay.processedImageStrippedIds),
25394
+ processedImageMarkers: new Map(replay.processedImageMarkers),
25395
+ strippedPlaceholderIds: new Set(replay.strippedPlaceholderIds),
25396
+ hiddenSeamPlaceholderIds: new Set(replay.hiddenSeamPlaceholderIds),
25397
+ mergedReasoningStrippedIds: new Set(replay.mergedReasoningStrippedIds),
25398
+ trailingBlankDecisions: new Map(replay.trailingBlankDecisions),
25399
+ noteNudgeAnchors: structuredClone(replay.noteNudgeAnchors),
25400
+ autoSearchHintDecisions: structuredClone(replay.autoSearchHintDecisions),
25401
+ todoSyntheticAnchor: structuredClone(replay.todoSyntheticAnchor),
25402
+ pendingCompactionMarker: structuredClone(replay.pendingCompactionMarker),
25403
+ compactionMarker: structuredClone(replay.compactionMarker)
25404
+ };
25405
+ }
25406
+
25407
+ // ../plugin/src/hooks/magic-context/execute-reclaim.ts
25408
+ var NAMESPACE2 = "executeReclaim";
25409
+ var failedWrites = new WeakMap;
25410
+ function readExecuteReclaimState(db, sessionId) {
25411
+ return parseState2(postprocessReplaySnapshot(db, sessionId).executeReclaim);
25412
+ }
25413
+ function parseState2(lane) {
25414
+ const value = lane;
25415
+ return {
25416
+ heldPasses: typeof value?.heldPasses === "number" ? Math.max(0, value.heldPasses) : 0,
25417
+ floorOrdinal: typeof value?.floorOrdinal === "number" ? value.floorOrdinal : null,
25418
+ floorPromptId: typeof value?.floorPromptId === "string" ? value.floorPromptId : null
25419
+ };
25420
+ }
25421
+ function writeExecuteReclaimState(db, sessionId, patch) {
25422
+ if (failedWrites.get(db)?.has(sessionId))
25423
+ return false;
25424
+ try {
25425
+ const current = readExecuteReclaimState(db, sessionId);
25426
+ if (JSON.stringify(current) === JSON.stringify({ ...current, ...patch }))
25427
+ return true;
25428
+ if (!updateReplayDocument(db, sessionId, (doc) => {
25429
+ const previous = parseState2(doc[NAMESPACE2]);
25430
+ const state = { ...previous, ...patch };
25431
+ if (JSON.stringify(previous) === JSON.stringify(state))
25432
+ return false;
25433
+ doc.version = 2;
25434
+ doc[NAMESPACE2] = state;
25435
+ return true;
25436
+ }))
25437
+ throw new Error("Could not persist execute reclaim state");
25438
+ return true;
25439
+ } catch (error) {
25440
+ let failed = failedWrites.get(db);
25441
+ if (!failed)
25442
+ failedWrites.set(db, failed = new Set);
25443
+ failed.add(sessionId);
25444
+ sessionLog2(sessionId, `execute reclaim state persistence failed; retaining existing policy: ${String(error)}`);
25445
+ return false;
25446
+ }
25447
+ }
25448
+ function clearExecuteReclaimState(db, sessionId) {
25449
+ writeExecuteReclaimState(db, sessionId, {
25450
+ heldPasses: 0,
25451
+ floorOrdinal: null,
25452
+ floorPromptId: null
25453
+ });
25454
+ }
25455
+ function maintainExecuteFloorMark(db, sessionId, promptId, belowExecute) {
25456
+ failedWrites.get(db)?.delete(sessionId);
25457
+ const state = readExecuteReclaimState(db, sessionId);
25458
+ if (state.floorOrdinal !== null && (belowExecute || promptId !== null && promptId !== state.floorPromptId)) {
25459
+ writeExecuteReclaimState(db, sessionId, { floorOrdinal: null, floorPromptId: null });
25460
+ }
25461
+ }
25462
+ function estimateExecuteReclaimTokens(args) {
25463
+ const eligible = capturePendingDropEligibility(args.targets, args.protectedTagIds);
25464
+ const queued = new Set(args.pendingOps.filter((op) => op.operation === "drop").map((op) => op.tagId));
25465
+ const candidates = args.tags.filter((tag) => tag.status === "active" && queued.has(tag.tagNumber) && eligible.has(tag.tagNumber));
25466
+ const preparationTargets = new Map;
25467
+ for (const tag of candidates) {
25468
+ const target = args.targets.get(tag.tagNumber);
25469
+ if (target?.prepareDrop)
25470
+ preparationTargets.set(tag.tagNumber, target);
25471
+ }
25472
+ const prepared = preparationTargets.size === 0 ? new Set : args.probePreparation?.(preparationTargets) ?? new Set([...preparationTargets].filter(([, target]) => target.prepareDrop?.() !== false).map(([number]) => number));
25473
+ const seed = sessionDecisionCalibration(args.db, args.sessionId);
25474
+ return candidates.reduce((total, tag) => {
25475
+ if (preparationTargets.has(tag.tagNumber) && !prepared.has(tag.tagNumber))
25476
+ return total;
25477
+ const ratio = tag.type === "tool" ? seed.toolsRatio : seed.proseRatio;
25478
+ return total + Math.max(0, (tag.tokenCount ?? Math.ceil(tag.byteSize / 4)) * ratio);
25479
+ }, 0);
25480
+ }
25481
+ function originateExecuteReclaim(args) {
25482
+ if (failedWrites.get(args.db)?.has(args.sessionId))
25483
+ return false;
25484
+ const state = readExecuteReclaimState(args.db, args.sessionId);
25485
+ const heldPasses = args.primaryExecute && args.reclaimableTokens > 0 && !args.alreadyBusting ? state.heldPasses + 1 : 0;
25486
+ if (!writeExecuteReclaimState(args.db, args.sessionId, { heldPasses }))
25487
+ return false;
25488
+ return args.primaryExecute && !args.alreadyBusting && !args.summaryCanCome && args.reclaimableTokens > 0 && (args.usableWindow > 0 && args.reclaimableTokens >= args.usableWindow * 0.02 || heldPasses >= 3);
25489
+ }
25490
+
24980
25491
  // ../plugin/src/hooks/magic-context/file-token-coverage.ts
24981
25492
  function omitIncompleteFileTokenTotals(db, sessionId, messages, totals) {
24982
25493
  const filesByMessage = new Map;
@@ -25364,7 +25875,8 @@ function resolveProtectedTailBoundary(ctx) {
25364
25875
  break;
25365
25876
  }
25366
25877
  livePromptFloor.ordinal = lastMeaningfulUserOrdinal || null;
25367
- if (lastMeaningfulUserOrdinal >= offset) {
25878
+ livePromptFloor.messageId = boundaryMessageId(index, lastMeaningfulUserOrdinal);
25879
+ if (!ctx.liftLivePromptFloor && lastMeaningfulUserOrdinal >= offset) {
25368
25880
  protectedTailStart = Math.min(protectedTailStart, lastMeaningfulUserOrdinal);
25369
25881
  }
25370
25882
  }
@@ -25492,6 +26004,7 @@ function resolveBoundaryContext(args) {
25492
26004
  protectedTailPolicyVersion: meta.protectedTailPolicyVersion,
25493
26005
  migrationFloorActive,
25494
26006
  emergencyTailScale: args.emergencyTailScale,
26007
+ liftLivePromptFloor: args.liftLivePromptFloor,
25495
26008
  providerShapeVersion: args.providerShapeVersion ?? "opencode-v1",
25496
26009
  cacheNamespace: args.cacheNamespace ?? `opencode:${args.sessionId}`,
25497
26010
  storedTokenTotalsForMessages,
@@ -25873,7 +26386,7 @@ function resolveBoundaryContextLimit(usage, fallbackContextLimit) {
25873
26386
  }
25874
26387
  return 128000;
25875
26388
  }
25876
- function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0) {
26389
+ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0, liftLivePromptFloor = false) {
25877
26390
  return withRawSessionMessageCache2(() => {
25878
26391
  try {
25879
26392
  const memoryPrimed = inMemoryTail ? primeInMemoryTailRawMessageCache2({
@@ -25903,7 +26416,8 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
25903
26416
  executeThresholdPercentage,
25904
26417
  usage,
25905
26418
  usageSource: "live",
25906
- taggerFloor
26419
+ taggerFloor,
26420
+ liftLivePromptFloor
25907
26421
  });
25908
26422
  const hasProtectedEligibleHead = boundary.offset < Math.min(boundary.protectedTailStart, boundary.eligibleEndOrdinal);
25909
26423
  if (!hasProtectedEligibleHead) {
@@ -25939,7 +26453,10 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
25939
26453
  function formatProjectedPostDropPercentage(value) {
25940
26454
  return value === null ? "none" : `${value.toFixed(1)}%`;
25941
26455
  }
25942
- function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds) {
26456
+ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds, primaryExecute = false) {
26457
+ if (usage.percentage < executeThresholdPercentage) {
26458
+ writeExecuteReclaimState(db, sessionId, { floorOrdinal: null, floorPromptId: null });
26459
+ }
25943
26460
  if (sessionMeta.compartmentInProgress) {
25944
26461
  sessionLog2(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
25945
26462
  return { shouldFire: false };
@@ -25992,7 +26509,22 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
25992
26509
  resolvedInMemoryTail = undefined;
25993
26510
  }
25994
26511
  }
25995
- const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor);
26512
+ let tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor);
26513
+ const markState = readExecuteReclaimState(db, sessionId);
26514
+ const mark = markState.floorOrdinal;
26515
+ const livePromptOrdinal = tailInfo.boundarySnapshot?.diagnostics?.livePromptFloor.ordinal;
26516
+ let consumedFloorMark = false;
26517
+ if (mark !== null) {
26518
+ const consumed = writeExecuteReclaimState(db, sessionId, {
26519
+ floorOrdinal: null,
26520
+ floorPromptId: null
26521
+ });
26522
+ if (consumed && mark === livePromptOrdinal && markState.floorPromptId === tailInfo.boundarySnapshot?.diagnostics?.livePromptFloor.messageId && usage.percentage >= executeThresholdPercentage) {
26523
+ consumedFloorMark = true;
26524
+ sessionLog2(sessionId, `compartment trigger: live-prompt floor mark consumed at ${mark}`);
26525
+ tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor, true);
26526
+ }
26527
+ }
25996
26528
  if (!tailInfo.hasNewRawHistory) {
25997
26529
  try {
25998
26530
  const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
@@ -26076,7 +26608,21 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
26076
26608
  return { shouldFire: false };
26077
26609
  }
26078
26610
  if (!tailInfo.hasProtectedEligibleHead || !tailInfo.isMeaningful) {
26079
- sessionLog2(sessionId, `compartment trigger: not firing at ${usage.percentage.toFixed(1)}% because unsummarized tail from ${tailInfo.nextStartOrdinal} is too small`);
26611
+ let floorOnly = false;
26612
+ const boundary = tailInfo.boundarySnapshot;
26613
+ const floor = boundary?.diagnostics?.livePromptFloor;
26614
+ if (!consumedFloorMark && floor?.ordinal && floor.from > floor.to) {
26615
+ const withoutFloor = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor, true);
26616
+ floorOnly = withoutFloor.hasProtectedEligibleHead && withoutFloor.isMeaningful;
26617
+ if (floorOnly && primaryExecute && usage.percentage >= executeThresholdPercentage && writeExecuteReclaimState(db, sessionId, {
26618
+ floorOrdinal: floor.ordinal,
26619
+ floorPromptId: floor.messageId ?? null
26620
+ })) {
26621
+ sessionLog2(sessionId, `compartment trigger: live-prompt floor mark set at ${floor.ordinal}`);
26622
+ }
26623
+ }
26624
+ const refusal = floorOnly ? `no eligible head (live-prompt floor at ${floor?.ordinal})` : tailInfo.hasProtectedEligibleHead ? "below meaningfulness" : "no eligible head";
26625
+ sessionLog2(sessionId, `compartment trigger: not firing at ${usage.percentage.toFixed(1)}% — ${refusal}; offset=${tailInfo.nextStartOrdinal} protectedStart=${boundary?.protectedTailStart ?? "none"} eligibleEnd=${boundary?.eligibleEndOrdinal ?? "none"} rawTokens=${tailInfo.trueRawEligibleTokens} chunkTokens=${tailInfo.tokenEstimate}`);
26080
26626
  return { shouldFire: false };
26081
26627
  }
26082
26628
  sessionLog2(sessionId, `compartment trigger: proactive fire at ${usage.percentage.toFixed(1)}% (floor=${proactiveTriggerPercentage}% projected post-drop=${formatProjectedPostDropPercentage(projectedPostDropPercentage)} target=${relativePostDropTarget.toFixed(1)}%)`);
@@ -26245,6 +26791,9 @@ function latestAssistantTurnStart(messages) {
26245
26791
  function latestAssistantTurnMessages(messages) {
26246
26792
  return new Set(messages.slice(latestAssistantTurnStart(messages)));
26247
26793
  }
26794
+ function isAnthropicThinkingPart(part, familyRoute) {
26795
+ return isRecord(part) && THINKING_TYPES.has(String(part.type ?? part.kind)) && (familyRoute || isRecord(part.metadata) && isRecord(part.metadata.anthropic));
26796
+ }
26248
26797
  function hasActiveAnthropicThinkingTurn(messages, provider, model) {
26249
26798
  const familyRoute = isAnthropicFamilyRoute(provider, model);
26250
26799
  for (const message of messages.slice(latestAssistantTurnStart(messages))) {
@@ -26253,7 +26802,7 @@ function hasActiveAnthropicThinkingTurn(messages, provider, model) {
26253
26802
  const parts = content(message);
26254
26803
  if (!Array.isArray(parts))
26255
26804
  continue;
26256
- if (parts.some((part) => isRecord(part) && THINKING_TYPES.has(String(part.type ?? part.kind)) && (familyRoute || isRecord(part.metadata) && isRecord(part.metadata.anthropic))))
26805
+ if (parts.some((part) => isAnthropicThinkingPart(part, familyRoute)))
26257
26806
  return true;
26258
26807
  }
26259
26808
  return false;
@@ -28022,7 +28571,8 @@ ${trimmedBody}…
28022
28571
  return wrapped;
28023
28572
  }
28024
28573
  function selectAutoSearchResults(results, threshold) {
28025
- return results.filter((result) => (result.relevanceScore ?? result.score) >= threshold);
28574
+ const relevance = (result) => result.relevanceScore ?? result.score;
28575
+ return results.filter((result) => relevance(result) >= threshold).sort((left, right) => relevance(right) - relevance(left));
28026
28576
  }
28027
28577
 
28028
28578
  // ../plugin/src/hooks/magic-context/auto-search-worker-client.ts
@@ -28115,6 +28665,13 @@ function retryUnpublishedAutoSearchNoHint(db, sessionId, messageId, startedAt) {
28115
28665
  }
28116
28666
  return true;
28117
28667
  }
28668
+
28669
+ class AutoSearchBusyError extends Error {
28670
+ constructor() {
28671
+ super("an earlier auto-search of this session is still running");
28672
+ this.name = "AutoSearchBusyError";
28673
+ }
28674
+ }
28118
28675
  async function searchAutoHint(db, sessionId, projectPath, query, options, entry = new URL(new URL(import.meta.url).pathname.endsWith(".ts") ? "./auto-search-worker.ts" : "./auto-search-worker.js", import.meta.url)) {
28119
28676
  return executeAutoSearchWorker(db, sessionId, projectPath, query, options, entry, "search");
28120
28677
  }
@@ -28123,14 +28680,19 @@ var searchWorkers = new WeakMap;
28123
28680
  var liveSearchWorkers = new Set;
28124
28681
  var MAX_IDLE_SEARCH_WORKERS = 4;
28125
28682
  var SEARCH_WORKER_IDLE_MS = 5 * 60000;
28683
+ var DETACHED_SEARCH_LIMIT_MS = 30000;
28684
+ var AUTO_SEARCH_WORKER_CLOSE_DEADLINE_MS = 2000;
28126
28685
  var workersCreated = 0;
28127
28686
  var workersReused = 0;
28687
+ var searchesSkippedBusy = 0;
28128
28688
  async function acquireSearchWorker(db, key, entry, input, signal) {
28129
28689
  const pool = searchWorkers.get(db) ?? new Map;
28130
28690
  searchWorkers.set(db, pool);
28131
28691
  while (!signal.aborted) {
28132
28692
  let slot = pool.get(key);
28133
28693
  if (slot?.busy) {
28694
+ if (input.job === "search" && (slot.detached || slot.busySessionId === input.sessionId))
28695
+ return "busy";
28134
28696
  const current = slot;
28135
28697
  await new Promise((resolve) => {
28136
28698
  const done = () => {
@@ -28139,6 +28701,8 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
28139
28701
  };
28140
28702
  signal.addEventListener("abort", done, { once: true });
28141
28703
  current.busy?.then(done);
28704
+ if (!current.detached)
28705
+ current.detachedSignal?.then(done);
28142
28706
  if (signal.aborted)
28143
28707
  done();
28144
28708
  });
@@ -28147,14 +28711,16 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
28147
28711
  const fresh = !slot;
28148
28712
  if (!slot) {
28149
28713
  const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: { ...input, persistent: true } }));
28714
+ const shutdown = createWorkerShutdown(worker, "auto-search", AUTO_SEARCH_WORKER_CLOSE_DEADLINE_MS);
28150
28715
  slot = {
28151
28716
  worker,
28152
28717
  dispose() {
28718
+ this.disposed = true;
28153
28719
  clearTimeout(this.idleTimer);
28154
28720
  if (pool.get(key) === this)
28155
28721
  pool.delete(key);
28156
28722
  liveSearchWorkers.delete(this);
28157
- worker.terminate();
28723
+ shutdown.close();
28158
28724
  worker.unref();
28159
28725
  }
28160
28726
  };
@@ -28168,9 +28734,14 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
28168
28734
  workersReused++;
28169
28735
  clearTimeout(slot.idleTimer);
28170
28736
  const current = slot;
28737
+ current.busySessionId = input.sessionId;
28738
+ current.detached = false;
28171
28739
  current.busy = new Promise((resolve) => {
28172
28740
  current.release = resolve;
28173
28741
  });
28742
+ current.detachedSignal = new Promise((resolve) => {
28743
+ current.markDetached = resolve;
28744
+ });
28174
28745
  current.worker.ref();
28175
28746
  return { slot: current, fresh };
28176
28747
  }
@@ -28179,6 +28750,9 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
28179
28750
  function queueAutoSearchBackfill(db, sessionId, projectPath, query) {
28180
28751
  if (isEmbeddingHostBusy2())
28181
28752
  return Promise.resolve();
28753
+ const snapshot = getProjectEmbeddingSnapshot2(projectPath);
28754
+ if (!snapshot?.enabled || !snapshot.features.memoryEnabled)
28755
+ return Promise.resolve();
28182
28756
  const key = `${sessionId}\x00${projectPath}`;
28183
28757
  const pending = pendingBackfills.get(db) ?? new Map;
28184
28758
  pendingBackfills.set(db, pending);
@@ -28226,6 +28800,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
28226
28800
  signal: deadlineSignal,
28227
28801
  readMessages: _readMessages,
28228
28802
  searchMessageHistory: _searchMessageHistory,
28803
+ stepTimings: _stepTimings,
28229
28804
  ...serializable
28230
28805
  } = options;
28231
28806
  const lifecycle = registerAutoSearchWork(sessionId);
@@ -28261,30 +28836,55 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
28261
28836
  lifecycle.done();
28262
28837
  return [];
28263
28838
  }
28839
+ if (lease === "busy") {
28840
+ lifecycle.done();
28841
+ searchesSkippedBusy++;
28842
+ throw new AutoSearchBusyError;
28843
+ }
28264
28844
  const { slot, fresh } = lease;
28265
28845
  const worker = slot.worker;
28846
+ const detachable = job === "search" && entry.href === defaultAutoSearchWorkerEntry().href;
28847
+ const startedAt = performance.now();
28848
+ let detachedAt;
28849
+ let ownerVectorMs;
28850
+ let abandonTimer;
28266
28851
  return new Promise((resolve, reject) => {
28267
28852
  let settled = false;
28268
- const finish = (results, error) => {
28853
+ let released = false;
28854
+ const settle = (results, error) => {
28269
28855
  if (settled)
28270
28856
  return;
28271
28857
  settled = true;
28858
+ if (error)
28859
+ reject(error);
28860
+ else
28861
+ resolve(results);
28862
+ };
28863
+ const release = (dispose) => {
28864
+ if (released)
28865
+ return;
28866
+ released = true;
28867
+ clearTimeout(abandonTimer);
28272
28868
  signal?.removeEventListener("abort", abort);
28273
28869
  lifecycle.signal.removeEventListener("abort", abort);
28274
28870
  lifecycle.done();
28275
28871
  worker.off("message", onMessage);
28276
28872
  worker.off("error", onError);
28277
28873
  worker.off("exit", onExit);
28278
- if (error || signal.aborted || entry.href !== defaultAutoSearchWorkerEntry().href)
28874
+ if (dispose || !detachable)
28279
28875
  slot.dispose();
28280
- else {
28876
+ else if (!slot.disposed) {
28281
28877
  slot.idleTimer = setTimeout(() => slot.dispose(), SEARCH_WORKER_IDLE_MS);
28282
28878
  slot.idleTimer.unref?.();
28283
28879
  }
28284
- const release = slot.release;
28880
+ const free = slot.release;
28285
28881
  slot.busy = undefined;
28286
28882
  slot.release = undefined;
28287
- release?.();
28883
+ slot.busySessionId = undefined;
28884
+ slot.detached = false;
28885
+ slot.detachedSignal = undefined;
28886
+ slot.markDetached = undefined;
28887
+ free?.();
28288
28888
  const reusable = liveSearchWorkers.delete(slot);
28289
28889
  if (reusable)
28290
28890
  liveSearchWorkers.add(slot);
@@ -28292,51 +28892,82 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
28292
28892
  for (const prior of idle.slice(0, Math.max(0, idle.length - MAX_IDLE_SEARCH_WORKERS)))
28293
28893
  prior.dispose();
28294
28894
  worker.unref();
28295
- if (error)
28296
- reject(error);
28297
- else
28298
- resolve(results);
28299
28895
  };
28300
- const abort = () => finish([]);
28896
+ const finish = (results, error) => {
28897
+ settle(results, error);
28898
+ release(Boolean(error) || signal.aborted);
28899
+ };
28900
+ const abort = () => {
28901
+ if (lifecycle.signal.aborted || !detachable) {
28902
+ finish([]);
28903
+ return;
28904
+ }
28905
+ if (settled)
28906
+ return;
28907
+ detachedAt = performance.now();
28908
+ slot.detached = true;
28909
+ slot.markDetached?.();
28910
+ settle([]);
28911
+ abandonTimer = setTimeout(() => {
28912
+ log2(`[auto-search] session ${sessionId}: search still running ${DETACHED_SEARCH_LIMIT_MS} ms after its deadline; disposing its worker (owner vector wait ${formatMs(ownerVectorMs)})`);
28913
+ release(true);
28914
+ }, DETACHED_SEARCH_LIMIT_MS);
28915
+ abandonTimer.unref?.();
28916
+ };
28301
28917
  signal?.addEventListener("abort", abort, { once: true });
28302
28918
  lifecycle.signal.addEventListener("abort", abort, { once: true });
28303
28919
  const onError = (error) => finish([], error);
28304
28920
  const onExit = (code) => finish([], new Error(`auto-search worker exited (${code})`));
28305
28921
  const onMessage = async (reply) => {
28306
- if (settled)
28922
+ if (released)
28307
28923
  return;
28308
- if (reply.kind === "result") {
28924
+ if (reply.kind === "result" || reply.kind === "error") {
28925
+ if (detachedAt !== undefined) {
28926
+ logLateSearch(sessionId, performance.now() - detachedAt, detachedAt - startedAt, ownerVectorMs, reply.kind === "result" ? reply.timings : undefined, reply.kind === "error");
28927
+ release(reply.kind === "error");
28928
+ return;
28929
+ }
28930
+ if (reply.kind === "error") {
28931
+ finish([], new Error(reply.error));
28932
+ return;
28933
+ }
28309
28934
  if (snapshot && getProjectEmbeddingSnapshot2(projectPath)?.generation !== snapshot.generation)
28310
28935
  finish([]);
28311
28936
  else
28312
28937
  finish(reply.results);
28313
28938
  return;
28314
28939
  }
28315
- if (reply.kind === "error") {
28316
- finish([], new Error(reply.error));
28317
- return;
28318
- }
28319
28940
  if (reply.kind === "messages" || reply.kind === "accepted")
28320
28941
  return;
28321
28942
  const response = { id: reply.id };
28322
- try {
28943
+ if (!signal.aborted) {
28944
+ const requestedAt = performance.now();
28945
+ try {
28946
+ if (reply.kind === "query")
28947
+ response.result = await (job === "backfill" ? embedTextForProject2(projectPath, reply.text, signal, "query") : boundedHintEmbedding(embedQuery, reply.text, signal)) ?? null;
28948
+ else {
28949
+ const passage = await embedBatchForProject2(projectPath, reply.texts, signal, reply.purpose);
28950
+ const current = getProjectEmbeddingSnapshot2(projectPath);
28951
+ response.passage = passage && current ? {
28952
+ ...passage,
28953
+ providerIdentity: current.providerIdentity,
28954
+ runtimeFingerprint: current.runtimeFingerprint,
28955
+ dimensions: passage.vectors.find((vector) => vector !== null)?.length ?? null
28956
+ } : null;
28957
+ }
28958
+ } catch (error) {
28959
+ response.error = error instanceof Error ? error.message : String(error);
28960
+ }
28323
28961
  if (reply.kind === "query")
28324
- response.result = await (job === "backfill" ? embedTextForProject2(projectPath, reply.text, signal, "query") : boundedHintEmbedding(embedQuery, reply.text, signal)) ?? null;
28325
- else {
28326
- const passage = await embedBatchForProject2(projectPath, reply.texts, signal, reply.purpose);
28327
- const current = getProjectEmbeddingSnapshot2(projectPath);
28328
- response.passage = passage && current ? {
28329
- ...passage,
28330
- providerIdentity: current.providerIdentity,
28331
- runtimeFingerprint: current.runtimeFingerprint,
28332
- dimensions: passage.vectors.find((vector) => vector !== null)?.length ?? null
28333
- } : null;
28962
+ ownerVectorMs = performance.now() - requestedAt;
28963
+ if (signal.aborted) {
28964
+ response.result = undefined;
28965
+ response.passage = undefined;
28966
+ response.error = undefined;
28334
28967
  }
28335
- } catch (error) {
28336
- response.error = error instanceof Error ? error.message : String(error);
28337
28968
  }
28338
28969
  response.embeddingHostBusy = isEmbeddingHostBusy2();
28339
- if (!settled && !signal?.aborted) {
28970
+ if (!released) {
28340
28971
  try {
28341
28972
  worker.postMessage(response);
28342
28973
  } catch (error) {
@@ -28358,6 +28989,15 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
28358
28989
  }
28359
28990
  });
28360
28991
  }
28992
+ function formatMs(value) {
28993
+ return value === undefined ? "n/a" : `${Math.round(value)} ms`;
28994
+ }
28995
+ function logLateSearch(sessionId, lateMs, waitedMs, ownerVectorMs, timings, failed) {
28996
+ const steps = timings?.steps;
28997
+ const warm = timings?.lastPoolWarm;
28998
+ const pool = warm ? `last pool refresh ${warm.outcome} in ${formatMs(warm.totalMs)} (probe ${formatMs(warm.probeMs)}, read ${formatMs(warm.readMs)}, decode ${formatMs(warm.decodeMs)}, ${warm.probedRows} rows probed, ${warm.decodedRows} decoded)` : "no pool refresh yet";
28999
+ log2(`[auto-search] session ${sessionId}: deadline passed after ${formatMs(waitedMs)}; the search ${failed ? "failed" : "finished"} ${formatMs(lateMs)} later. Steps: message FTS ${formatMs(steps?.messageMs)}, vector wait ${formatMs(steps?.vectorWaitMs)} (owner embedding ${formatMs(ownerVectorMs)}), chunk lane ${formatMs(steps?.chunkMs)} (pool ${steps?.chunkPool ?? "n/a"}), other lanes ${formatMs(steps?.otherLanesMs)}, job ${formatMs(timings?.jobMs)}; ${pool}`);
29000
+ }
28361
29001
  async function boundedHintEmbedding(embed, text, signal) {
28362
29002
  const controller = new AbortController;
28363
29003
  const combined = AbortSignal.any([signal, controller.signal]);
@@ -28581,7 +29221,8 @@ async function runAutoSearchHintForPi(args) {
28581
29221
  },
28582
29222
  isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
28583
29223
  visibleMemoryIds: options.visibleMemoryIds ?? null,
28584
- sources: ["memory", "message", "git_commit"]
29224
+ sources: ["memory", "message", "git_commit"],
29225
+ chunkPoolWarmOnly: true
28585
29226
  };
28586
29227
  return searchAutoHint(db, sessionId, options.projectPath, rawPrompt, {
28587
29228
  ...searchOptions,
@@ -28593,6 +29234,11 @@ async function runAutoSearchHintForPi(args) {
28593
29234
  args.passGuard?.assert();
28594
29235
  if (lifecycleSignal.aborted)
28595
29236
  return messages;
29237
+ if (error instanceof AutoSearchBusyError) {
29238
+ sessionLog2(sessionId, "auto-search: an earlier search of this session is still running, skipping hint for this turn");
29239
+ persistAutoSearchSkip(db, sessionId, userMsgId);
29240
+ return messages;
29241
+ }
28596
29242
  log2(`[auto-search] unified search failed for session ${sessionId} (no-hint frozen for this turn): ${error instanceof Error ? error.message : String(error)}`);
28597
29243
  await writeNoHintAndReconcile("error");
28598
29244
  return messages;
@@ -28644,7 +29290,7 @@ ${hintText}`;
28644
29290
  if (outcome.decision.decision === "hint") {
28645
29291
  appendHintToUserMessage(userMsg, outcome.decision.text);
28646
29292
  }
28647
- sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top score ${results[0].score.toFixed(3)})`);
29293
+ sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top relevance ${(results[0].relevanceScore ?? results[0].score).toFixed(3)})`);
28648
29294
  return messages;
28649
29295
  } finally {
28650
29296
  if (!lifecycleSignal.aborted && results !== null) {
@@ -28680,19 +29326,19 @@ async function embedAndStoreCompartmentChunks(db, sessionId, projectPath, compar
28680
29326
  const maxInputTokens = getProjectEmbeddingMaxInputTokens2(projectPath);
28681
29327
  for (const compartment of compartments) {
28682
29328
  try {
28683
- const fromMemory = compartment.sourceChunkText ? canonicalizeInMemoryChunkTextForEmbedding(compartment.sourceChunkText, compartment.startMessage, compartment.endMessage) : "";
28684
- const mappedText = fromMemory ? fromMemory : buildCanonicalChunkTextFromFts(db, sessionId, compartment.startMessage, compartment.endMessage);
29329
+ const fromMemory = compartment.sourceChunkText ? canonicalizeInMemoryChunkTextForEmbedding2(compartment.sourceChunkText, compartment.startMessage, compartment.endMessage) : "";
29330
+ const mappedText = fromMemory ? fromMemory : buildCanonicalChunkTextFromFts2(db, sessionId, compartment.startMessage, compartment.endMessage);
28685
29331
  if (mappedText === null)
28686
29332
  continue;
28687
- const canonicalText = mappedText || buildCompartmentSummaryFallbackText(db, compartment.id);
29333
+ const canonicalText = mappedText || buildCompartmentSummaryFallbackText2(db, compartment.id);
28688
29334
  if (canonicalText.length === 0)
28689
29335
  continue;
28690
- const windows = chunkCanonicalText(canonicalText, compartment.startMessage, compartment.endMessage, maxInputTokens);
29336
+ const windows = chunkCanonicalText2(canonicalText, compartment.startMessage, compartment.endMessage, maxInputTokens);
28691
29337
  if (windows.length === 0)
28692
29338
  continue;
28693
- const windowSourceKey = chunkWindowSourceKey(canonicalText, compartment.startMessage, compartment.endMessage, maxInputTokens);
29339
+ const windowSourceKey = chunkWindowSourceKey2(canonicalText, compartment.startMessage, compartment.endMessage, maxInputTokens);
28694
29340
  const currentModelId = getProjectChunkEmbeddingModelId2(projectPath);
28695
- if (currentModelId !== "off" && chunkEmbeddingWindowsAreCurrent(db, compartment.id, currentModelId, windows, projectPath)) {
29341
+ if (currentModelId !== "off" && chunkEmbeddingWindowsAreCurrent2(db, compartment.id, currentModelId, windows, projectPath)) {
28696
29342
  continue;
28697
29343
  }
28698
29344
  const result = await embedItemsForProject2(projectPath, windows.map((window) => ({
@@ -28702,7 +29348,7 @@ async function embedAndStoreCompartmentChunks(db, sessionId, projectPath, compar
28702
29348
  })), undefined, db, sessionId);
28703
29349
  if (!result)
28704
29350
  continue;
28705
- if (chunkEmbeddingWindowsAreCurrent(db, compartment.id, currentModelId, windows, projectPath)) {
29351
+ if (chunkEmbeddingWindowsAreCurrent2(db, compartment.id, currentModelId, windows, projectPath)) {
28706
29352
  continue;
28707
29353
  }
28708
29354
  const rows = [];
@@ -28720,7 +29366,7 @@ async function embedAndStoreCompartmentChunks(db, sessionId, projectPath, compar
28720
29366
  });
28721
29367
  }
28722
29368
  if (rows.length === windows.length) {
28723
- replaceCompartmentChunkEmbeddings(db, rows, windowSourceKey);
29369
+ replaceCompartmentChunkEmbeddings2(db, rows, windowSourceKey);
28724
29370
  enqueueShadowEmbeddingItems2(projectPath, "chunk", [String(compartment.id)]);
28725
29371
  }
28726
29372
  } catch (error) {
@@ -29489,7 +30135,8 @@ ${chunkText}`,
29489
30135
  maxOutputTokens,
29490
30136
  onProgress: buildProgressLogger("first"),
29491
30137
  accountingSessionId: sessionId,
29492
- accountingSubagent: "historian"
30138
+ accountingSubagent: "historian",
30139
+ accountingModelConfigKey: deps.modelConfigKey
29493
30140
  }
29494
30141
  });
29495
30142
  let validatedPass = await validateHistorianResult(firstResult, sessionId, chunk, priorCompartments, sequenceOffset);
@@ -29549,6 +30196,7 @@ ${chunkText}`,
29549
30196
  onProgress: buildProgressLogger("fallback"),
29550
30197
  accountingSessionId: sessionId,
29551
30198
  accountingSubagent: "historian",
30199
+ accountingModelConfigKey: candidate.sourceConfigKey ?? deps.modelConfigKey,
29552
30200
  accountingTask: "fallback"
29553
30201
  }
29554
30202
  });
@@ -29600,7 +30248,8 @@ ${chunkText}`,
29600
30248
  maxOutputTokens,
29601
30249
  onProgress: buildProgressLogger("editor"),
29602
30250
  accountingSessionId: sessionId,
29603
- accountingSubagent: "historian_editor"
30251
+ accountingSubagent: "historian_editor",
30252
+ accountingModelConfigKey: deps.modelConfigKey
29604
30253
  }
29605
30254
  });
29606
30255
  const editorPass = await validateHistorianResult(editorResult, sessionId, chunk, priorCompartments, sequenceOffset);
@@ -31655,7 +32304,7 @@ function promoteRecompStagingWithM0Mutation(db, sessionId, holderId) {
31655
32304
  finished = true;
31656
32305
  return null;
31657
32306
  }
31658
- deleteChunkEmbedBackoffForSession(db, sessionId);
32307
+ deleteChunkEmbedBackoffForSession2(db, sessionId);
31659
32308
  db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
31660
32309
  db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
31661
32310
  insertRecompCompartmentRows(db, sessionId, staging.compartments, now);
@@ -32563,7 +33212,7 @@ function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = f
32563
33212
  if (marker && clearPendingPiCompactionMarkerStateIf(db, sessionId, marker, null))
32564
33213
  clearedMarker = marker;
32565
33214
  }
32566
- deleteChunkEmbedBackoffForSession(db, sessionId);
33215
+ deleteChunkEmbedBackoffForSession2(db, sessionId);
32567
33216
  queueM0Mutation(db, { sessionId, mutationType: "recomp_boundary_change" });
32568
33217
  clearCachedM0M1(db, sessionId);
32569
33218
  db.exec("COMMIT");
@@ -34521,7 +35170,7 @@ function isSentinelPart(part) {
34521
35170
 
34522
35171
  // src/pi-append-compaction.ts
34523
35172
  var loggedIncompatibleHost = false;
34524
- var failedWrites = new WeakMap;
35173
+ var failedWrites2 = new WeakMap;
34525
35174
  function adaptPiAppendCompaction(sessionManager) {
34526
35175
  if (!sessionManager || typeof sessionManager !== "object")
34527
35176
  return;
@@ -34529,7 +35178,7 @@ function adaptPiAppendCompaction(sessionManager) {
34529
35178
  const append = host.appendCompaction;
34530
35179
  if (typeof append !== "function")
34531
35180
  return;
34532
- if (failedWrites.has(host))
35181
+ if (failedWrites2.has(host))
34533
35182
  return;
34534
35183
  const harness = resolvePiHarnessKind();
34535
35184
  if ((harness === "omp" ? append.length !== 4 && append.length !== 7 : append.length !== 5 && append.length !== 6) || typeof host.getEntry !== "function") {
@@ -34541,7 +35190,7 @@ function adaptPiAppendCompaction(sessionManager) {
34541
35190
  }
34542
35191
  const getEntry = host.getEntry.bind(host);
34543
35192
  return (summary, firstKeptEntryId, tokensBefore, details, fromHook) => {
34544
- const previousFailure = failedWrites.get(host);
35193
+ const previousFailure = failedWrites2.get(host);
34545
35194
  if (previousFailure)
34546
35195
  throw previousFailure;
34547
35196
  let id;
@@ -34559,7 +35208,7 @@ function adaptPiAppendCompaction(sessionManager) {
34559
35208
  }
34560
35209
  } catch {
34561
35210
  const error = new Error("Compaction marker read-back failed; writes disabled for this session manager until restart");
34562
- failedWrites.set(host, error);
35211
+ failedWrites2.set(host, error);
34563
35212
  log2(`ERROR: compaction marker read-back failed harness=${harness} compactionId=${typeof id === "string" ? id : "<missing>"} expectedFirstKept=${firstKeptEntryId}; further writes disabled for this session manager until restart; leaving marker pending`);
34564
35213
  throw error;
34565
35214
  }
@@ -44124,6 +44773,20 @@ function registerPiContextHandler(pi, baseOptions) {
44124
44773
  elapsedMs: performance.now() - fitInputStart,
44125
44774
  extra: inputForFitReclaim ? "snapshot" : "no-snapshot"
44126
44775
  });
44776
+ if (!options.compactionOff && !sessionMeta.isSubagent) {
44777
+ let promptId = null;
44778
+ for (let i = event.messages.length - 1;i >= 0; i--) {
44779
+ const message = event.messages[i];
44780
+ if (message?.role !== "user")
44781
+ continue;
44782
+ const parts = typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content;
44783
+ if (!hasMeaningfulUserText2(parts))
44784
+ continue;
44785
+ promptId = entryIds?.[i] ?? null;
44786
+ break;
44787
+ }
44788
+ maintainExecuteFloorMark(options.db, sessionId, promptId, usagePercentage < effectiveExecuteThresholdPercentage);
44789
+ }
44127
44790
  const pipelineArgs = {
44128
44791
  recoveryPrefix: recovery.prefix,
44129
44792
  recoveryRebuildReason: recovery.rebuildReason,
@@ -44225,6 +44888,65 @@ function registerPiContextHandler(pi, baseOptions) {
44225
44888
  };
44226
44889
  if (!options.compactionOff)
44227
44890
  assertPiTagSnapshotReady(options.db, sessionId);
44891
+ let historianEvaluatedThisPass = false;
44892
+ const historian = options.historian;
44893
+ const scheduleHistorian = (result) => {
44894
+ if (historianEvaluatedThisPass)
44895
+ return;
44896
+ historianEvaluatedThisPass = true;
44897
+ const tHistorianScheduling = performance.now();
44898
+ budget.stage = "historian scheduling";
44899
+ if (historian && !options.compactionOff && budget.remainingWork() > 0) {
44900
+ guardSqliteTransformPass2({
44901
+ assert: budget.assert,
44902
+ remainingMs: budget.remainingWork
44903
+ });
44904
+ try {
44905
+ budget.assert();
44906
+ maybeFireHistorian({
44907
+ startGuard: () => {
44908
+ if (!budget.completed)
44909
+ budget.assertOwner();
44910
+ if (budget.abandoned || budget.remainingWork() === 0)
44911
+ throw new PiContextDeadlineError(budget.diagnostic());
44912
+ },
44913
+ pi,
44914
+ ctx,
44915
+ sessionId,
44916
+ db: options.db,
44917
+ historian,
44918
+ isFirstContextPassForSession,
44919
+ activeTags: result.activeTags,
44920
+ eligiblePendingDropTagIds: result.eligiblePendingDropTagIds,
44921
+ rawMessageProvider,
44922
+ ordinalAlignment: ordinalAlignment(),
44923
+ taggerFloor,
44924
+ sessionMeta,
44925
+ piUsage,
44926
+ pressureSnapshot: {
44927
+ percentage: usagePercentage,
44928
+ inputTokens: usageInputTokens
44929
+ },
44930
+ minimumPercentage: usagePercentage,
44931
+ liveIsRawBranchEstimate: piLiveUsageIsRawBranchEstimate,
44932
+ historianStateSnapshot: historianStateForPass,
44933
+ publishedHistoryRide: isCacheBusting,
44934
+ primaryExecute: schedulerDecision === "execute" && !sessionMeta.isSubagent,
44935
+ signedThinkingHeld: result.strictThinkingKept
44936
+ });
44937
+ } catch (error) {
44938
+ budget.assertOutcome();
44939
+ sessionLog2(sessionId, `historian scheduling skipped: ${String(error)}`);
44940
+ } finally {
44941
+ guardSqliteTransformPass2({
44942
+ assert: budget.assertOutcome,
44943
+ remainingMs: budget.remainingOutcome
44944
+ });
44945
+ }
44946
+ }
44947
+ logTransformTiming(sessionId, "historianScheduling", tHistorianScheduling);
44948
+ };
44949
+ pipelineArgs.evaluateHistorianBeforeReclaim = scheduleHistorian;
44228
44950
  let result = await budget.waitMandatory(runPipeline(pipelineArgs));
44229
44951
  observePipelineResultForTests(sessionId, result);
44230
44952
  logTransformTiming(sessionId, "runPipeline", tRunPipeline);
@@ -44256,57 +44978,7 @@ function registerPiContextHandler(pi, baseOptions) {
44256
44978
  }, piDecisionSnapshotNewestAssistant, budget.assertDecisionPublication);
44257
44979
  } : undefined;
44258
44980
  logTransformTiming(sessionId, "transformDecisionAndReuseState", tTransformDecision);
44259
- const tHistorianScheduling = performance.now();
44260
- const historian = options.historian;
44261
- budget.stage = "historian scheduling";
44262
- if (historian && !options.compactionOff && budget.remainingWork() > 0) {
44263
- guardSqliteTransformPass2({
44264
- assert: budget.assert,
44265
- remainingMs: budget.remainingWork
44266
- });
44267
- try {
44268
- budget.assert();
44269
- maybeFireHistorian({
44270
- startGuard: () => {
44271
- if (!budget.completed)
44272
- budget.assertOwner();
44273
- if (budget.abandoned || budget.remainingWork() === 0)
44274
- throw new PiContextDeadlineError(budget.diagnostic());
44275
- },
44276
- pi,
44277
- ctx,
44278
- sessionId,
44279
- db: options.db,
44280
- historian,
44281
- isFirstContextPassForSession,
44282
- activeTags: result.activeTags,
44283
- eligiblePendingDropTagIds: result.eligiblePendingDropTagIds,
44284
- rawMessageProvider,
44285
- ordinalAlignment: ordinalAlignment(),
44286
- taggerFloor,
44287
- sessionMeta,
44288
- piUsage,
44289
- pressureSnapshot: {
44290
- percentage: usagePercentage,
44291
- inputTokens: usageInputTokens
44292
- },
44293
- minimumPercentage: usagePercentage,
44294
- liveIsRawBranchEstimate: piLiveUsageIsRawBranchEstimate,
44295
- historianStateSnapshot: historianStateForPass,
44296
- publishedHistoryRide: isCacheBusting,
44297
- signedThinkingHeld: result.strictThinkingKept
44298
- });
44299
- } catch (error) {
44300
- budget.assertOutcome();
44301
- sessionLog2(sessionId, `historian scheduling skipped: ${String(error)}`);
44302
- } finally {
44303
- guardSqliteTransformPass2({
44304
- assert: budget.assertOutcome,
44305
- remainingMs: budget.remainingOutcome
44306
- });
44307
- }
44308
- }
44309
- logTransformTiming(sessionId, "historianScheduling", tHistorianScheduling);
44981
+ scheduleHistorian(result);
44310
44982
  const tPostTransform = performance.now();
44311
44983
  let outputMessages = result.messages;
44312
44984
  let assertTailHygieneLastWriter;
@@ -45135,6 +45807,7 @@ function spawnPiHistorianRun(args) {
45135
45807
  runner: historian.runner,
45136
45808
  signal: controller.signal,
45137
45809
  historianModel: historian.model,
45810
+ modelConfigKey: historian.modelConfigKey,
45138
45811
  fallbackModels: historian.fallbackModels,
45139
45812
  fallbackModelId,
45140
45813
  historianChunkTokens: historian.historianChunkTokens,
@@ -45457,7 +46130,7 @@ Historian previously failed ${failureCount} time(s), so Magic Context is retryin
45457
46130
  idleExpiry: false,
45458
46131
  emergency: usage.percentage >= historianForceMaterializationPercentage
45459
46132
  }
45460
- }, args.eligiblePendingDropTagIds);
46133
+ }, args.eligiblePendingDropTagIds, args.primaryExecute === true);
45461
46134
  if (!trigger.shouldFire) {
45462
46135
  sessionLog2(sessionId, `historian trigger eval: shouldFire=false (no trigger condition met)`);
45463
46136
  try {
@@ -45557,7 +46230,7 @@ function captureReasoningMutationRollback(messages) {
45557
46230
  async function runCompactionOffPipeline(args) {
45558
46231
  let injectionResult = null;
45559
46232
  const transcript = [...args.messages];
45560
- let headChangedUnderSignedTurn = false;
46233
+ let headChangedUnderSignedThinking = false;
45561
46234
  if (args.injection) {
45562
46235
  const state = {
45563
46236
  sessionId: args.sessionId,
@@ -45579,10 +46252,16 @@ async function runCompactionOffPipeline(args) {
45579
46252
  if (servedBeforeFirstRender !== undefined) {
45580
46253
  const headCount = injectionResult?.syntheticLeadingCount ?? 0;
45581
46254
  const head = JSON.stringify(args.messages.slice(0, headCount));
45582
- headChangedUnderSignedTurn = servedBeforeFirstRender === null || JSON.stringify(servedBeforeFirstRender.slice(0, headCount)) !== head;
46255
+ headChangedUnderSignedThinking = servedBeforeFirstRender === null || JSON.stringify(servedBeforeFirstRender.slice(0, headCount)) !== head;
46256
+ } else if (!signedTurnHoldsHead && args.reasoningClearing?.prefixBound === true && (injectionResult?.m0Materialized === true || injectionResult?.m1RenderedCoverage != null)) {
46257
+ const served = args.readLastServedMessages?.() ?? null;
46258
+ const headCount = injectionResult?.syntheticLeadingCount ?? 0;
46259
+ headChangedUnderSignedThinking = served === null || JSON.stringify(served.slice(0, headCount)) !== JSON.stringify(args.messages.slice(0, headCount));
46260
+ if (headChangedUnderSignedThinking)
46261
+ sessionLog2(args.sessionId, "compaction-off fold changed the head: stripping signed thinking");
45583
46262
  }
45584
46263
  }
45585
- if (headChangedUnderSignedTurn)
46264
+ if (headChangedUnderSignedThinking)
45586
46265
  applyPiProactiveThinkingStrip({
45587
46266
  db: args.db,
45588
46267
  sessionId: args.sessionId,
@@ -45896,6 +46575,7 @@ async function runPipeline(args) {
45896
46575
  logTransformTiming(args.sessionId, "injectTemporalMarkers", tTemporal);
45897
46576
  }
45898
46577
  let nativeRemovalInputs;
46578
+ let probingExecuteRemoval = false;
45899
46579
  try {
45900
46580
  nativeRemovalInputs = getNativeReplayState(args.db, args.sessionId).toolInputs;
45901
46581
  } catch {}
@@ -45907,7 +46587,7 @@ async function runPipeline(args) {
45907
46587
  sessionId: args.sessionId,
45908
46588
  callId,
45909
46589
  saved: nativeRemovalInputs,
45910
- canApply: isCacheBustingPass
46590
+ canApply: isCacheBustingPass || probingExecuteRemoval
45911
46591
  }),
45912
46592
  authorizeToolRemovals: (callIds) => preparePiToolRemovalMeasurements({
45913
46593
  db: args.db,
@@ -45939,6 +46619,7 @@ async function runPipeline(args) {
45939
46619
  const heldIdleExpiryRebuild = protectedSignedPrefix && piHardSignals?.cacheExpired === true;
45940
46620
  const systemPrefixChangedThisPass = !prefixPreflightContended && effectiveSystemChangedThisPass;
45941
46621
  const rideSignals = {
46622
+ executeReclaim: false,
45942
46623
  subagentExecute: args.sessionMeta.isSubagent && args.schedulerDecision === "execute",
45943
46624
  hardFold: foldBustsServedPrefixThisPass || systemPrefixChangedThisPass || firstRenderBust || heldIdleExpiryRebuild || isCacheBustingPass,
45944
46625
  force: (args.forceMaterialization === true || emergencyDropEligible) && (args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0),
@@ -46051,11 +46732,14 @@ async function runPipeline(args) {
46051
46732
  }
46052
46733
  }
46053
46734
  }
46054
- if (args.temporalAwareness && isCacheBustingPass && !protectedSignedPrefix) {
46735
+ const applyTemporalOnRide = () => {
46736
+ if (!args.temporalAwareness || !isCacheBustingPass || protectedSignedPrefix)
46737
+ return;
46055
46738
  temporalDecisions = freezeTemporalDecisions(args.db, args.sessionId, temporalCandidates);
46056
46739
  if (injectPiTemporalMarkers(args.messages, temporalDecisions, stableIdResolver) > 0)
46057
46740
  recordFirstApplicationWireEdit(true);
46058
- }
46741
+ };
46742
+ applyTemporalOnRide();
46059
46743
  logPiUnresolvedIdentities(args.sessionId, [
46060
46744
  ...guardPiToolAllocations(args.db, args.sessionId, args.messages, stableIdResolver, args.tagger, fallbackIndex.guardIndexes),
46061
46745
  ...guardPiMessageAllocations(args.db, args.sessionId, entryFingerprintByMessageId)
@@ -46205,6 +46889,62 @@ async function runPipeline(args) {
46205
46889
  const protectionWindowForPass = getProtectionWindowForSession(args.db, args.sessionId, protectionFloorResolution.floor);
46206
46890
  const protectedTagNumbersForPass = usesTokenProtection ? protectionWindowForPass.protectedTagNumbers : newestActiveTagNumbersByCount(getActiveTagsBySession2(args.db, args.sessionId), args.protectedTags);
46207
46891
  const pendingOperationTags = pendingOps.length > 0 ? getTagsForPendingOperations2(args.db, args.sessionId, pendingOps.map((operation) => operation.tagId), usesTokenProtection ? 0 : args.protectedTags, RECENT_TOOL_SKELETON_WINDOW) : [];
46892
+ if (!args.sessionMeta.isSubagent && args.schedulerDecision === "execute") {
46893
+ args.evaluateHistorianBeforeReclaim?.({
46894
+ activeTags: getActiveTagsBySession2(args.db, args.sessionId),
46895
+ eligiblePendingDropTagIds,
46896
+ strictThinkingKept: protectedSignedPrefix
46897
+ });
46898
+ }
46899
+ rideSignals.executeReclaim = originateExecuteReclaim({
46900
+ db: args.db,
46901
+ sessionId: args.sessionId,
46902
+ primaryExecute: !args.sessionMeta.isSubagent && args.schedulerDecision === "execute" && args.contextUsage.percentage < forceMaterializationPercentage,
46903
+ alreadyBusting: isCacheBustingPass || identityRebuild,
46904
+ summaryCanCome: args.sessionMeta.compartmentInProgress || inFlightHistorian.has(args.sessionId) || (prefixPreflightContended || protectedSignedPrefix) && (deferredHistoryRefreshSessions.has(args.sessionId) || deferredMaterializationSessions.has(args.sessionId) || historyRefreshSessions.has(args.sessionId)) || readExecuteReclaimState(args.db, args.sessionId).floorOrdinal !== null,
46905
+ reclaimableTokens: estimateExecuteReclaimTokens({
46906
+ db: args.db,
46907
+ sessionId: args.sessionId,
46908
+ pendingOps,
46909
+ tags: pendingOperationTags,
46910
+ targets: newTargets,
46911
+ protectedTagIds: new Set([
46912
+ ...protectedTagNumbersForPass,
46913
+ ...protectedToolTags
46914
+ ]),
46915
+ probePreparation: (targets) => {
46916
+ const saved = nativeRemovalInputs;
46917
+ const rollback = Symbol("execute removal probe");
46918
+ const allowed = new Set;
46919
+ try {
46920
+ nativeRemovalInputs = saved && new Map(saved);
46921
+ probingExecuteRemoval = true;
46922
+ args.db.transaction(() => {
46923
+ for (const [number, target] of targets) {
46924
+ if (target.prepareDrop?.() !== false)
46925
+ allowed.add(number);
46926
+ }
46927
+ throw rollback;
46928
+ }).immediate();
46929
+ } catch (error) {
46930
+ if (error !== rollback)
46931
+ allowed.clear();
46932
+ } finally {
46933
+ nativeRemovalInputs = saved;
46934
+ probingExecuteRemoval = false;
46935
+ }
46936
+ return allowed;
46937
+ }
46938
+ }),
46939
+ usableWindow: args.usableSoft ?? args.contextUsage.inputTokens / (args.contextUsage.percentage / 100)
46940
+ });
46941
+ if (rideSignals.executeReclaim) {
46942
+ isCacheBustingPass = reclaimRidePermitted(rideSignals, ridePermissionGate);
46943
+ publishedWorkDrainAllowed = isCacheBustingPass;
46944
+ shouldRunHeuristics ||= isCacheBustingPass && args.heuristics !== undefined;
46945
+ stripUnheldSignedTurnOnBust();
46946
+ applyTemporalOnRide();
46947
+ }
46208
46948
  const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
46209
46949
  const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
46210
46950
  const shouldApplyPendingOps = publishedWorkDrainAllowed;
@@ -46937,6 +47677,8 @@ async function runPipeline(args) {
46937
47677
  servedTagNumbers.add(tag.tagNumber);
46938
47678
  }
46939
47679
  }
47680
+ if (bustedThisPass)
47681
+ clearExecuteReclaimState(args.db, args.sessionId);
46940
47682
  return {
46941
47683
  messages: outputMessages,
46942
47684
  recoveryNormalized,
@@ -51097,6 +51839,7 @@ function resolveHistorianFromConfig(config, harness = PI_HARNESS_KIND, modelRegi
51097
51839
  return {
51098
51840
  runner: new PiSubagentRunner,
51099
51841
  model,
51842
+ modelConfigKey: resolved.primary?.sourceConfigKey,
51100
51843
  fallbackModels,
51101
51844
  historianChunkTokens,
51102
51845
  historianContextLimit: resolveKnownHistorianContextLimit(model),