@cortexkit/pi-magic-context 0.49.30 → 0.49.31

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.
package/dist/index.js CHANGED
@@ -139,6 +139,7 @@ import {
139
139
  decodePiContentDecision,
140
140
  getPiContentDecisions,
141
141
  freezePiContentDecision,
142
+ withNativeReplayWriteBarrier,
142
143
  getNativeReplayState,
143
144
  saveNativeToolInputs,
144
145
  addNativeReasoningIds,
@@ -262,7 +263,7 @@ import {
262
263
  registerTodoStateLifecycle,
263
264
  syncCtxMemoryToolEnabled,
264
265
  registerMagicContextTools
265
- } from "./index-gxjppvsh.js";
266
+ } from "./index-2nryd8ye.js";
266
267
  import"./index-4knyh1kt.js";
267
268
  import {
268
269
  canonicalModelIdentity,
@@ -304,7 +305,7 @@ import {
304
305
  openCurrentDatabase,
305
306
  openDatabaseAsync,
306
307
  closeDatabase
307
- } from "./index-y5x5wt5t.js";
308
+ } from "./index-xvqcqg0r.js";
308
309
  import {
309
310
  sameProjectDirectory,
310
311
  pruneMissingProjectIdentities,
@@ -329,6 +330,7 @@ import {
329
330
  HYGIENE_PROVIDER_UNITS_VERSION,
330
331
  sessionDecisionCalibration,
331
332
  transitionSessionHygieneUnits,
333
+ rowWindowMass,
332
334
  computeProtectionWindow,
333
335
  readEpochFloorSnapshot,
334
336
  getProtectionWindowForSession,
@@ -481,7 +483,7 @@ import {
481
483
  getRawSessionTagKeysThrough2,
482
484
  getLegacyProtectedTailStartOrdinal2,
483
485
  readSessionChunk2
484
- } from "./index-n2ayqhbx.js";
486
+ } from "./index-34e3mm36.js";
485
487
  import {
486
488
  UNKNOWN_FIT_RATIO,
487
489
  hasMeasuredDecisionCalibration,
@@ -682,7 +684,7 @@ import {
682
684
  isMessageIndexReconciledThrough,
683
685
  indexSingleMessage,
684
686
  indexMessagesAfterOrdinal
685
- } from "./index-74bc8ts8.js";
687
+ } from "./index-yddeb86g.js";
686
688
  import {
687
689
  rememberV1HiddenRun
688
690
  } from "./index-6x556c2q.js";
@@ -747,7 +749,7 @@ import {
747
749
  normalizeVerificationFiles,
748
750
  indexCommitsForProject,
749
751
  embedUnembeddedCommits
750
- } from "./index-0cq3g9y5.js";
752
+ } from "./index-bpd654bz.js";
751
753
  import {
752
754
  setEmbeddingSessionBusy2,
753
755
  isEmbeddingHostBusy2
@@ -803,7 +805,7 @@ import {
803
805
  PiContextSupersededError,
804
806
  PiContextBudget,
805
807
  PiTagHydrationError,
806
- getPiTagSnapshotView,
808
+ getPiPassTagSnapshotView,
807
809
  getPiActiveTagSnapshotView,
808
810
  readPiFallbackTagRows,
809
811
  prewarmPiTagSnapshot,
@@ -811,10 +813,10 @@ import {
811
813
  drainPiTagSnapshotSession,
812
814
  assertPiTagSnapshotReady,
813
815
  ensurePiTagSnapshotReady
814
- } from "./index-2pnhk4gc.js";
816
+ } from "./index-v40sm8q6.js";
815
817
  import"./index-jn44h81p.js";
816
818
  import"./index-1cvyaw9a.js";
817
- import"./index-5qh6z3sn.js";
819
+ import"./index-sr1ss4f8.js";
818
820
  import {
819
821
  __toESM
820
822
  } from "./index-22jkk6wg.js";
@@ -3559,7 +3561,7 @@ function startHostStallProfilerSwitch() {
3559
3561
  // package.json
3560
3562
  var package_default = {
3561
3563
  name: "@cortexkit/pi-magic-context",
3562
- version: "0.49.30",
3564
+ version: "0.49.31",
3563
3565
  type: "module",
3564
3566
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3565
3567
  main: "dist/index.js",
@@ -3625,12 +3627,14 @@ var package_default = {
3625
3627
  "@types/node": "^22.20.0",
3626
3628
  "omp-coding-agent-1812": "npm:@oh-my-pi/pi-coding-agent@18.12.3",
3627
3629
  "omp-coding-agent-18126": "npm:@oh-my-pi/pi-coding-agent@18.12.6",
3630
+ "omp-coding-agent-18132": "npm:@oh-my-pi/pi-coding-agent@18.13.2",
3628
3631
  "omp-pi-ai-171": "npm:@oh-my-pi/pi-ai@17.1.7",
3629
3632
  "omp-pi-ai-1889": "npm:@oh-my-pi/pi-ai@18.8.9",
3630
3633
  "omp-pi-ai-1811": "npm:@oh-my-pi/pi-ai@18.11.3",
3631
3634
  "omp-pi-ai-1812": "npm:@oh-my-pi/pi-ai@18.12.3",
3632
3635
  "omp-pi-ai-18126": "npm:@oh-my-pi/pi-ai@18.12.6",
3633
3636
  "omp-pi-ai-1813": "npm:@oh-my-pi/pi-ai@18.13.0",
3637
+ "omp-pi-ai-18132": "npm:@oh-my-pi/pi-ai@18.13.2",
3634
3638
  "pi-agent-core-087": "npm:@earendil-works/pi-agent-core@0.87.1",
3635
3639
  "pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
3636
3640
  "pi-ai-087": "npm:@earendil-works/pi-ai@0.87.1",
@@ -14762,7 +14766,6 @@ function parseMapMemoriesManifest(text) {
14762
14766
  }
14763
14767
  function validateMapMemoriesManifest(text, expectedIds) {
14764
14768
  const parsed = parseMapMemoriesManifest(text);
14765
- assertParsedManifestNonEmpty(parsed.length, expectedIds.size, text, "mappings", "memory");
14766
14769
  assertNoDuplicateManifestIds(parsed.filter((entry) => expectedIds.has(entry.id)).map((entry) => entry.id), "mappings");
14767
14770
  return parsed;
14768
14771
  }
@@ -16949,8 +16952,7 @@ function parsePartialVerifyManifest(text, expectedIds) {
16949
16952
  var VERIFY_BATCH_SIZE = 5;
16950
16953
  var VERIFY_TOKENS_PER_MEMORY = 1e5;
16951
16954
  var VERIFY_RUN_TOKEN_BUDGET = 2500000;
16952
- var VERIFY_RUN_SLICE_MS = 240000;
16953
- var VERIFY_IN_FLIGHT_GRACE_MS = 120000;
16955
+ var VERIFY_BATCH_DEFAULT_MS = 240000;
16954
16956
  function verifyBatchTokenBudget(size, configured) {
16955
16957
  return Math.min(configured ?? Number.MAX_SAFE_INTEGER, size * VERIFY_TOKENS_PER_MEMORY);
16956
16958
  }
@@ -16980,8 +16982,8 @@ function validateVerifyCompletion(messages, text, expectedIds, responseText = te
16980
16982
  }
16981
16983
  var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
16982
16984
  var VERIFY_BATCH_FLOOR_MS = 30000;
16983
- function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
16984
- return Math.min(remainingMs, VERIFY_RUN_SLICE_MS);
16985
+ function computeVerifyBatchSliceMs(remainingMs, batchesRemaining) {
16986
+ return Math.min(remainingMs, Math.max(VERIFY_BATCH_DEFAULT_MS, remainingMs / Math.max(1, batchesRemaining)));
16985
16987
  }
16986
16988
  function closeBroadCycle(args, cycleStartAt) {
16987
16989
  if (!args.forceBroad || cycleStartAt === undefined)
@@ -17005,7 +17007,6 @@ async function runVerify(args) {
17005
17007
  }
17006
17008
  async function runVerifyWithCooldown(args) {
17007
17009
  const runStartedAt = Date.now();
17008
- const sliceDeadline = runStartedAt + VERIFY_RUN_SLICE_MS;
17009
17010
  const result = {
17010
17011
  verified: 0,
17011
17012
  updated: 0,
@@ -17053,12 +17054,10 @@ async function runVerifyWithCooldown(args) {
17053
17054
  try {
17054
17055
  for (let i = 0;i < batches.length; i += 1) {
17055
17056
  const now = Date.now();
17056
- const startCutoff = Math.min(args.deadline, sliceDeadline);
17057
- const hardStop = Math.min(args.deadline, sliceDeadline + VERIFY_IN_FLIGHT_GRACE_MS);
17058
- const remainingMs = Math.max(0, hardStop - now);
17059
- if (now >= startCutoff) {
17057
+ const remainingMs = Math.max(0, args.deadline - now);
17058
+ if (now >= args.deadline) {
17060
17059
  result.stopReason = "deadline";
17061
- log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — the run deadline passed ${now - startCutoff}ms ago`);
17060
+ log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — the run deadline passed ${now - args.deadline}ms ago`);
17062
17061
  break;
17063
17062
  }
17064
17063
  if (remainingMs < VERIFY_BATCH_FLOOR_MS) {
@@ -17997,7 +17996,7 @@ function createDreamTaskExecutor(deps) {
17997
17996
  return { status: "failed", transient: true, error };
17998
17997
  }
17999
17998
  const processed = result.mapped + result.independent;
18000
- if (processed > 0) {
17999
+ if (processed > 0 || result.failure === undefined) {
18001
18000
  const progress = `map-memories: committed ${processed} mapping(s) (mapped ${result.mapped}, independent ${result.independent}); ${result.remaining} remain`;
18002
18001
  recordRun("completed", null, { progress });
18003
18002
  return { status: "completed" };
@@ -22427,7 +22426,7 @@ function normalizePiUserEntry(entry, sessionId, ordinal, followsAssistantReply)
22427
22426
  return null;
22428
22427
  if (message.role !== "user" || typeof message.timestamp !== "number")
22429
22428
  return null;
22430
- const text = extractPiTextContent(message.content).trim();
22429
+ const text = cleanUserText2(extractPiTextContent(message.content));
22431
22430
  if (!text)
22432
22431
  return null;
22433
22432
  return {
@@ -22461,7 +22460,7 @@ function extractPiTextContent(content) {
22461
22460
  if (part === null || typeof part !== "object")
22462
22461
  return [];
22463
22462
  const record = part;
22464
- return record.type === "text" && typeof record.text === "string" ? [record.text] : [];
22463
+ return record.synthetic !== true && record.type === "text" && typeof record.text === "string" ? [record.text] : [];
22465
22464
  }).join(`
22466
22465
  `);
22467
22466
  }
@@ -24957,6 +24956,7 @@ function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options =
24957
24956
  });
24958
24957
  };
24959
24958
  const rows = readRows(db);
24959
+ options.prepareRemovals?.(rows);
24960
24960
  const converted = new Map;
24961
24961
  for (const row of rows) {
24962
24962
  const target = targets.get(row.tagNumber);
@@ -25188,6 +25188,15 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
25188
25188
  }
25189
25189
  return didMutateMessage;
25190
25190
  }
25191
+ function prepareFlushedToolRemovals(targets, tags) {
25192
+ for (const tag of tags) {
25193
+ if (tag.status !== "dropped" || tag.type !== "tool")
25194
+ continue;
25195
+ if (tag.dropMode != null && tag.dropMode !== "full")
25196
+ continue;
25197
+ targets.get(tag.tagNumber)?.prepareReplayDrop?.();
25198
+ }
25199
+ }
25191
25200
  function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
25192
25201
  let didMutateMessage = false;
25193
25202
  const tags = preloadedTags ?? getDroppedTagsByNumbers2(db, sessionId, [...targets.keys()]);
@@ -27884,7 +27893,7 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
27884
27893
  skipPrefixInjection,
27885
27894
  preserveTagOnlyAssistantText: options.preserveTagOnlyAssistantText,
27886
27895
  entryFingerprint: options.entryFingerprintByMessageId?.get(messageId) ?? null,
27887
- reuseIdentity: reuseIdentity || contentDerivedTextIds !== undefined,
27896
+ reuseIdentity: reuseIdentity || options.reuseTextMessageIds?.has(messageId) === true || contentDerivedTextIds !== undefined,
27888
27897
  timing,
27889
27898
  textIdentitySourceCache: options.textIdentitySourceCache,
27890
27899
  textTokenCache: options.textTokenCache
@@ -27953,7 +27962,11 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
27953
27962
  if (timing)
27954
27963
  timing.identity += performance.now() - identityStart;
27955
27964
  } else {
27956
- const accounting = readAggregateToolAccounting(part, timing, options.toolTokenCache, tokenCacheKey);
27965
+ const accounting = readAggregateToolAccounting(part, timing, options.toolTokenCache, tokenCacheKey, {
27966
+ byteSize: existing.maxByteSize,
27967
+ tokenCount: existing.maxTokenCount,
27968
+ inputTokenCount: existing.inputTokenCount
27969
+ });
27957
27970
  text = accounting.text;
27958
27971
  if (part.kind === "tool_result") {
27959
27972
  applyGrownToolResultAccounting({
@@ -28035,7 +28048,7 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
28035
28048
  if (timing)
28036
28049
  timing.identity += performance.now() - identityStart;
28037
28050
  } else {
28038
- const accounting = readAggregateToolAccounting(part, timing, options.toolTokenCache, tokenCacheKey);
28051
+ const accounting = readAggregateToolAccounting(part, timing, options.toolTokenCache, tokenCacheKey, tagger.getToolTagAccounting(sessionId, callId, messageId));
28039
28052
  text = accounting.text;
28040
28053
  const outputByteSize = part.kind === "tool_result" ? accounting.byteSize : 0;
28041
28054
  const outputTokenCount = part.kind === "tool_result" ? accounting.tokenCount : 0;
@@ -28131,12 +28144,14 @@ function applyGrownToolResultAccounting(args) {
28131
28144
  updateTagTokenCount2(args.db, args.sessionId, args.aggregate.tagId, tokenCount);
28132
28145
  syncToolAggregateAccounting(args.tagger, args.sessionId, args.aggregate);
28133
28146
  }
28134
- function readAggregateToolAccounting(part, timing, tokenCache, tokenCacheKey) {
28147
+ function readAggregateToolAccounting(part, timing, tokenCache, tokenCacheKey, persisted) {
28135
28148
  const text = part.getText() ?? "";
28136
28149
  const byteSize = getToolPartByteSize(part, text);
28137
- const metadata = part.getToolMetadata();
28150
+ const metadata = part.getToolMetadata({
28151
+ skipInputTokenCount: persisted?.inputTokenCount != null
28152
+ });
28138
28153
  let tokenCount = 0;
28139
- if (part.kind === "tool_result") {
28154
+ if (part.kind === "tool_result" && (!persisted || persisted.tokenCount === null || byteSize > persisted.byteSize)) {
28140
28155
  const tokenStart = timing ? performance.now() : 0;
28141
28156
  tokenCount = getCachedToolPartTokenCount(part, text, tokenCache, tokenCacheKey);
28142
28157
  if (timing)
@@ -28523,6 +28538,12 @@ function buildAggregateTarget(tagId, occurrences, requiresToolArcSkeleton, conve
28523
28538
  return any ? "truncated" : "absent";
28524
28539
  },
28525
28540
  prepareDrop: () => !occurrences.some((occ) => occ.part.canRemove?.() === "defer"),
28541
+ prepareReplayDrop: () => {
28542
+ if (complete() && !requiresToolArcSkeleton) {
28543
+ for (const occ of occurrences)
28544
+ occ.part.canRemove?.();
28545
+ }
28546
+ },
28526
28547
  canDrop: () => complete() && !occurrences.some((occ) => occ.part.hasUserAnswer?.()),
28527
28548
  requiresToolArcSkeleton,
28528
28549
  readInput() {
@@ -31359,7 +31380,8 @@ function tagAttribution(input) {
31359
31380
  if (!cached) {
31360
31381
  removed.length = 0;
31361
31382
  added.length = 0;
31362
- added.push(...input.tags);
31383
+ for (const tag of input.tags)
31384
+ added.push(tag);
31363
31385
  cached = {
31364
31386
  tags: input.tags,
31365
31387
  messageTags: new Map,
@@ -31448,7 +31470,10 @@ function attributeTags(input, arcs, messageIds) {
31448
31470
  exactToolTags,
31449
31471
  orphanTagsByCall,
31450
31472
  boundsByOwner
31451
- } = tagAttribution(input);
31473
+ } = tagAttribution({
31474
+ ...input,
31475
+ tags: attributionProjection(input, arcs, messageIds)
31476
+ });
31452
31477
  const messageIndexById = new Map;
31453
31478
  for (let index = 0;index < messageIds.length; index += 1) {
31454
31479
  const id = input.stableId?.(input.messages[index], index);
@@ -31511,6 +31536,61 @@ function attributeTags(input, arcs, messageIds) {
31511
31536
  }
31512
31537
  return { messageTags, tagsByNumber };
31513
31538
  }
31539
+ var attributionProjections = new WeakMap;
31540
+ function attributionProjection(input, arcs, messageIds) {
31541
+ const owners = new Set(messageIds);
31542
+ const calls = new Set;
31543
+ const numbers = new Set;
31544
+ for (const arc of arcs) {
31545
+ owners.add(arc.ownerId);
31546
+ calls.add(arc.callId);
31547
+ }
31548
+ const notePrefix = (text) => {
31549
+ for (const candidate of [text, stripChannel1ReminderSpans(text)]) {
31550
+ const match = candidate.trimStart().match(TAG_PREFIX);
31551
+ if (match)
31552
+ numbers.add(Number(match[1]));
31553
+ }
31554
+ };
31555
+ for (let index = 0;index < input.messages.length; index++) {
31556
+ const id = input.stableId?.(input.messages[index], index);
31557
+ if (id)
31558
+ owners.add(id);
31559
+ const message = input.messages[index];
31560
+ if (!isRecord5(message))
31561
+ continue;
31562
+ if (typeof message.content === "string")
31563
+ notePrefix(message.content);
31564
+ else if (Array.isArray(message.content)) {
31565
+ for (const part of message.content)
31566
+ if (isRecord5(part) && typeof part.text === "string")
31567
+ notePrefix(part.text);
31568
+ }
31569
+ }
31570
+ const cacheable = input.tagCacheKey !== undefined;
31571
+ const cached = cacheable ? attributionProjections.get(input.tags) : undefined;
31572
+ const content = cacheable ? input.messages.map(safeStableStringify) : undefined;
31573
+ if (cached && cached.messageIds.length === messageIds.length && messageIds.every((id, index) => id === cached.messageIds[index]) && content?.length === cached.content.length && content.every((value, index) => value === cached.content[index]) && owners.size === cached.owners.size && [...owners].every((owner) => cached.owners.has(owner)) && calls.size === cached.calls.size && [...calls].every((call) => cached.calls.has(call)) && numbers.size === cached.numbers.size && [...numbers].every((number) => cached.numbers.has(number)))
31574
+ return cached.projection;
31575
+ const projection = input.tags.filter((tag) => {
31576
+ if (numbers.has(tag.tagNumber))
31577
+ return true;
31578
+ const owner = messageIdForTag(tag);
31579
+ if (owner !== null && owners.has(owner))
31580
+ return true;
31581
+ return tag.type === "tool" && tag.toolOwnerMessageId === null && calls.has(tag.messageId);
31582
+ });
31583
+ if (cacheable && content)
31584
+ attributionProjections.set(input.tags, {
31585
+ messageIds,
31586
+ content,
31587
+ owners,
31588
+ calls,
31589
+ numbers,
31590
+ projection
31591
+ });
31592
+ return projection;
31593
+ }
31514
31594
  var partJsonMemo = new TailHygieneJsonMemo;
31515
31595
  var excludedViews = new WeakMap;
31516
31596
  function excludedDraftForApi(key, value, providerApi) {
@@ -35221,6 +35301,76 @@ function canRemoveNativeToolCall(message, toolCallId) {
35221
35301
  var NATIVE_TOOL_REMOVAL_MARKER = '{"__magic_context_remove_tool_arc__":true}';
35222
35302
 
35223
35303
  // src/native-replay-state-pi.ts
35304
+ var removalBatches = new WeakMap;
35305
+
35306
+ class PiToolRemovalBatchError extends Error {
35307
+ constructor(cause) {
35308
+ super("Native tool removal batch could not be persisted", { cause });
35309
+ }
35310
+ }
35311
+ function withPiToolRemovalBatch(args, edit) {
35312
+ let sessions = removalBatches.get(args.db);
35313
+ const enclosing = sessions?.get(args.sessionId);
35314
+ if (enclosing)
35315
+ return edit(enclosing.flush);
35316
+ if (!sessions) {
35317
+ sessions = new Map;
35318
+ removalBatches.set(args.db, sessions);
35319
+ }
35320
+ let publishing = false;
35321
+ const batch = {
35322
+ saved: args.saved,
35323
+ planned: new Map(args.saved),
35324
+ requested: new Map,
35325
+ pending: new Map,
35326
+ flushed: false,
35327
+ flush() {
35328
+ if (batch.flushed)
35329
+ return;
35330
+ batch.persistPending();
35331
+ batch.flushed = true;
35332
+ },
35333
+ persistPending() {
35334
+ if (publishing || batch.pending.size === 0)
35335
+ return;
35336
+ const connection = args.db;
35337
+ if (connection.inTransaction !== true && connection.isTransaction !== true)
35338
+ throw new Error("Native removal publication requires a caller-owned transaction");
35339
+ try {
35340
+ publishing = true;
35341
+ saveNativeToolInputs(args.db, args.sessionId, batch.pending);
35342
+ batch.pending.clear();
35343
+ } catch (cause) {
35344
+ throw new PiToolRemovalBatchError(cause);
35345
+ } finally {
35346
+ publishing = false;
35347
+ }
35348
+ }
35349
+ };
35350
+ sessions.set(args.sessionId, batch);
35351
+ try {
35352
+ const result = withNativeReplayWriteBarrier(args.db, args.sessionId, batch.persistPending, () => edit(batch.flush));
35353
+ if (batch.requested.size > 0 && !batch.flushed)
35354
+ throw new Error("Native removal markers were not flushed in the caller's transaction");
35355
+ const saved = args.saved;
35356
+ if (saved && batch.requested.size > 0) {
35357
+ const prior = new Map([...batch.requested.keys()].map((id) => [id, saved.get(id)]));
35358
+ args.rollbackObservations?.push(() => {
35359
+ for (const [id, value] of prior) {
35360
+ if (value === undefined)
35361
+ saved.delete(id);
35362
+ else
35363
+ saved.set(id, value);
35364
+ }
35365
+ });
35366
+ for (const [id, marker] of batch.requested)
35367
+ saved.set(id, marker);
35368
+ }
35369
+ return result;
35370
+ } finally {
35371
+ sessions.delete(args.sessionId);
35372
+ }
35373
+ }
35224
35374
  function applyNativeToolInputReplayPi(args, saved) {
35225
35375
  if (saved.size === 0 && (!args.canApply || args.changes.size === 0))
35226
35376
  return 0;
@@ -35332,6 +35482,12 @@ function applyNativeReasoningReplayPi(args, saved) {
35332
35482
  function preparePiToolRemovalMeasurements(args) {
35333
35483
  if (!args.saved || !args.canApply)
35334
35484
  return;
35485
+ const batch = removalBatches.get(args.db)?.get(args.sessionId);
35486
+ if (batch?.saved === args.saved) {
35487
+ for (const callId of args.callIds)
35488
+ authorizePiToolRemoval({ ...args, callId });
35489
+ return;
35490
+ }
35335
35491
  const requested = new Map;
35336
35492
  for (const callId of args.callIds) {
35337
35493
  if (args.saved.get(callId) !== NATIVE_TOOL_REMOVAL_MARKER)
@@ -35347,9 +35503,54 @@ function preparePiToolRemovalMeasurements(args) {
35347
35503
  args.saved.set(callId, marker);
35348
35504
  } catch {}
35349
35505
  }
35506
+ function preparePiToolRemovalChecks(args) {
35507
+ if (!args.db?.inTransaction || args.rows.length === 0)
35508
+ return;
35509
+ const occurrences = new Map;
35510
+ for (const raw of args.messages) {
35511
+ if (!raw || typeof raw !== "object")
35512
+ continue;
35513
+ const message = raw;
35514
+ if (message.role !== "assistant" || !Array.isArray(message.content))
35515
+ continue;
35516
+ for (const rawPart of message.content) {
35517
+ if (!rawPart || typeof rawPart !== "object")
35518
+ continue;
35519
+ const part = rawPart;
35520
+ if (part.type === "toolCall" && typeof part.id === "string")
35521
+ occurrences.set(part.id, (occurrences.get(part.id) ?? 0) + 1);
35522
+ }
35523
+ }
35524
+ const requested = [];
35525
+ for (const row of args.rows) {
35526
+ if (row.callId === null || occurrences.get(row.callId) !== 1)
35527
+ continue;
35528
+ const target = args.targets.get(row.tagNumber);
35529
+ if (target?.requiresToolArcSkeleton || target?.canDrop?.() !== true)
35530
+ continue;
35531
+ if (!target.mutationParts?.some(({ part }) => part !== null && typeof part === "object" && ("kind" in part) && part.kind === "tool_use" && ("id" in part) && part.id === row.callId))
35532
+ continue;
35533
+ requested.push(row.callId);
35534
+ }
35535
+ if (requested.length)
35536
+ args.prepare(requested);
35537
+ }
35350
35538
  function authorizePiToolRemoval(args) {
35351
35539
  if (!args.saved)
35352
35540
  return false;
35541
+ const batch = removalBatches.get(args.db)?.get(args.sessionId);
35542
+ if (batch?.saved === args.saved) {
35543
+ if (batch.planned.get(args.callId) === NATIVE_TOOL_REMOVAL_MARKER)
35544
+ return true;
35545
+ if (!args.canApply)
35546
+ return false;
35547
+ if (batch.flushed)
35548
+ throw new Error("Tool removal requested after lane publication");
35549
+ batch.planned.set(args.callId, NATIVE_TOOL_REMOVAL_MARKER);
35550
+ batch.requested.set(args.callId, NATIVE_TOOL_REMOVAL_MARKER);
35551
+ batch.pending.set(args.callId, NATIVE_TOOL_REMOVAL_MARKER);
35552
+ return true;
35553
+ }
35353
35554
  if (args.saved.get(args.callId) === NATIVE_TOOL_REMOVAL_MARKER)
35354
35555
  return true;
35355
35556
  if (!args.canApply)
@@ -35406,6 +35607,57 @@ function isSentinelPart(part) {
35406
35607
  return p.type === "text" && typeof p.text === "string" && (p.text === "" || p.text === WHOLE_MESSAGE_PLACEHOLDER_TEXT);
35407
35608
  }
35408
35609
 
35610
+ // src/pass-tag-projection-pi.ts
35611
+ function projectPiReplayDrops(transcript, metadata) {
35612
+ const owners = new Set;
35613
+ const addresses = new Set;
35614
+ const calls = new Set;
35615
+ const prefixes = new Set;
35616
+ for (const message of transcript.messages) {
35617
+ owners.add(message.info.id ?? "");
35618
+ let ordinal = 0;
35619
+ for (const part of message.parts) {
35620
+ if (part.kind === "text") {
35621
+ addresses.add(`${message.info.id}:p${ordinal++}`);
35622
+ const prefix = /^§(\d+)§\s/.exec(part.getText() ?? "");
35623
+ if (prefix)
35624
+ prefixes.add(Number(prefix[1]));
35625
+ } else if ((part.kind === "tool_use" || part.kind === "tool_result") && part.id)
35626
+ calls.add(part.id);
35627
+ }
35628
+ }
35629
+ const numbers = new Set;
35630
+ for (const tag of metadata) {
35631
+ if (tag.status !== "dropped")
35632
+ continue;
35633
+ if (prefixes.has(tag.tagNumber) || (tag.type === "tool" ? calls.has(tag.messageId) && (tag.toolOwnerMessageId === null || tag.toolOwnerMessageId === "" || owners.has(tag.toolOwnerMessageId)) : addresses.has(tag.messageId)))
35634
+ numbers.add(tag.tagNumber);
35635
+ }
35636
+ return metadata.filter((tag) => tag.status === "dropped" && numbers.has(tag.tagNumber));
35637
+ }
35638
+ function protectedPiPassTagNumbers(rows, floor, toolsRatio = 1) {
35639
+ if (!(toolsRatio >= 0) || rows.some((row) => !Number.isFinite(row.tagNumber)))
35640
+ return computeProtectionWindow(rows, floor, toolsRatio).protectedTagNumbers;
35641
+ const numbers = [];
35642
+ let group;
35643
+ let groups = 0;
35644
+ let mass = 0;
35645
+ for (let index = rows.length - 1;index >= 0; index--) {
35646
+ const row = rows[index];
35647
+ if (row?.type !== "tool")
35648
+ continue;
35649
+ if (row.tagNumber !== group) {
35650
+ if (groups >= 3 && Math.ceil(mass * toolsRatio) >= floor)
35651
+ break;
35652
+ group = row.tagNumber;
35653
+ groups++;
35654
+ numbers.push(row.tagNumber);
35655
+ }
35656
+ mass += rowWindowMass(row);
35657
+ }
35658
+ return new Set(numbers.reverse());
35659
+ }
35660
+
35409
35661
  // src/pi-append-compaction.ts
35410
35662
  var loggedIncompatibleHost = false;
35411
35663
  var failedWrites2 = new WeakMap;
@@ -36562,23 +36814,113 @@ function piMatchesChatImages(content, urls) {
36562
36814
  return true;
36563
36815
  }
36564
36816
 
36565
- // src/pi-dispatch-image-budget.ts
36817
+ // src/pi-dispatch-date-reminder.ts
36566
36818
  function object8(value) {
36567
36819
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
36568
36820
  }
36821
+ function piDateReminderText(value, cwd) {
36822
+ if (typeof value !== "string")
36823
+ return false;
36824
+ const match = /^<system-reminder>\nToday: (\d{4}-\d{2}-\d{2}); current working directory: '([^\r\n<>§]+)'\. Do not repeat this information in your reply\.\n<\/system-reminder>$/u.exec(value);
36825
+ if (!match)
36826
+ return false;
36827
+ const [, date, path] = match;
36828
+ if ([...path].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127))
36829
+ return false;
36830
+ const parsed = new Date(`${date}T00:00:00Z`);
36831
+ if (!Number.isFinite(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== date)
36832
+ return false;
36833
+ if (!/^(?:\/|[A-Za-z]:\/)/u.test(path) || path.includes("\\"))
36834
+ return false;
36835
+ return cwd === undefined || path === cwd.replace(/\\/gu, "/");
36836
+ }
36837
+ function piDateReminderWireText(content, cwd) {
36838
+ if (typeof content === "string")
36839
+ return piDateReminderText(content, cwd) ? content : undefined;
36840
+ if (!Array.isArray(content) || content.length !== 1)
36841
+ return;
36842
+ const block = object8(content[0]);
36843
+ const cache = object8(block?.cache_control);
36844
+ if (block?.type !== "text" || !cache || cache.type !== "ephemeral" || Object.keys(block).some((key) => !["type", "text", "cache_control"].includes(key)) || Object.keys(cache).some((key) => !["type", "ttl", "scope"].includes(key)) || cache.ttl !== undefined && cache.ttl !== "5m" && cache.ttl !== "1h" || cache.scope !== undefined && cache.scope !== "global")
36845
+ return;
36846
+ return piDateReminderText(block.text, cwd) ? block.text : undefined;
36847
+ }
36848
+ var PI_DATE_REMINDER_APIS = new Set([
36849
+ "anthropic-messages",
36850
+ "openai-completions",
36851
+ "openai-responses",
36852
+ "azure-openai-responses",
36853
+ "openai-codex-responses",
36854
+ "bedrock-converse-stream",
36855
+ "google-generative-ai",
36856
+ "google-vertex",
36857
+ "google-gemini-cli",
36858
+ "ollama-chat"
36859
+ ]);
36860
+ function singleText(value, type) {
36861
+ if (!Array.isArray(value) || value.length !== 1)
36862
+ return;
36863
+ const part = object8(value[0]);
36864
+ return part && (type === undefined ? Object.keys(part).length === 1 : part.type === type && Object.keys(part).length === 2) ? part.text : undefined;
36865
+ }
36866
+ function piWithoutDateReminders(payload, api, cwd, developerRole, includesPreparedFirstUser) {
36867
+ const body = object8(payload);
36868
+ if (!body)
36869
+ return;
36870
+ const google = api.startsWith("google-");
36871
+ const envelope = google ? object8(body.request) ?? body : body;
36872
+ const field = google ? "contents" : api.endsWith("responses") ? "input" : "messages";
36873
+ const messages = envelope[field];
36874
+ if (!Array.isArray(messages))
36875
+ return;
36876
+ let firstUser = false;
36877
+ let removed = false;
36878
+ const kept = [];
36879
+ for (const value of messages) {
36880
+ const row = object8(value);
36881
+ if (!row)
36882
+ return;
36883
+ const text = google ? singleText(row.parts) : api === "bedrock-converse-stream" ? singleText(row.content) : api.endsWith("responses") ? singleText(row.content, "input_text") ?? (api === "openai-codex-responses" ? row.content : undefined) : row.content;
36884
+ if (piDateReminderText(text, cwd)) {
36885
+ const keys = google ? ["role", "parts"] : api.endsWith("responses") ? ["role", "content", "type"] : ["role", "content"];
36886
+ const role = api === "ollama-chat" ? "system" : api === "openai-completions" && developerRole ? "developer" : "user";
36887
+ if (!firstUser || row.role !== role || Object.keys(row).some((key) => !keys.includes(key)) || row.type !== undefined && row.type !== "message")
36888
+ return;
36889
+ if (!removed) {
36890
+ const prefix = { ...envelope, [field]: kept };
36891
+ if (!includesPreparedFirstUser(google && body.request !== undefined ? { ...body, request: prefix } : prefix))
36892
+ return;
36893
+ }
36894
+ removed = true;
36895
+ continue;
36896
+ }
36897
+ if (row.role === "user" && (typeof row.content === "string" || Array.isArray(row.content) && row.content.some((part) => object8(part)?.type === "input_text" || object8(part)?.type === "text" || typeof object8(part)?.text === "string") || Array.isArray(row.parts) && row.parts.some((part) => typeof object8(part)?.text === "string")))
36898
+ firstUser = true;
36899
+ kept.push(value);
36900
+ }
36901
+ if (!removed)
36902
+ return;
36903
+ const filtered = { ...envelope, [field]: kept };
36904
+ return google && body.request !== undefined ? { ...body, request: filtered } : filtered;
36905
+ }
36906
+
36907
+ // src/pi-dispatch-image-budget.ts
36908
+ function object9(value) {
36909
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
36910
+ }
36569
36911
  function piImageBudgetPlan(model) {
36570
- if (!model?.input?.includes("image") || object8(model.compat)?.stripImageInput === true)
36912
+ if (!model?.input?.includes("image") || object9(model.compat)?.stripImageInput === true)
36571
36913
  return;
36572
36914
  return {
36573
36915
  count: 0,
36574
36916
  api: model.api,
36575
36917
  rows: new Map,
36576
- hoistToolImages: model.api?.startsWith("google-") === true && object8(model.compat)?.multimodalFunctionResponse !== true || model.api === "bedrock-converse-stream" && model.requiresToolResultImageHoisting === true,
36918
+ hoistToolImages: model.api?.startsWith("google-") === true && object9(model.compat)?.multimodalFunctionResponse !== true || model.api === "bedrock-converse-stream" && model.requiresToolResultImageHoisting === true,
36577
36919
  hoistErrorImages: model.api === "anthropic-messages" || model.api === "bedrock-converse-stream"
36578
36920
  };
36579
36921
  }
36580
36922
  function inputImage(block, api) {
36581
- const file = object8(block.providerFile);
36923
+ const file = object9(block.providerFile);
36582
36924
  if (api === "ollama-chat")
36583
36925
  return { kind: "bytes", value: String(block.data ?? "") };
36584
36926
  if ((api?.endsWith("responses") && file?.provider === "openai" || api === "anthropic-messages" && file?.provider === "anthropic") && typeof file?.id === "string")
@@ -36598,7 +36940,7 @@ function piRecordImages(plan, row, source) {
36598
36940
  return;
36599
36941
  const images = [];
36600
36942
  for (const value of source.content) {
36601
- const block = object8(value);
36943
+ const block = object9(value);
36602
36944
  if (block?.type === "image")
36603
36945
  images.push(inputImage(block, plan.api));
36604
36946
  }
@@ -36624,20 +36966,20 @@ function piWireImages(content, ollamaImages) {
36624
36966
  return [];
36625
36967
  const images = [];
36626
36968
  for (const value of content) {
36627
- const block = object8(value);
36969
+ const block = object9(value);
36628
36970
  if (!block)
36629
36971
  continue;
36630
- const source = object8(block.source);
36631
- const inline = object8(block.inlineData);
36632
- const file = object8(block.fileData);
36633
- const bedrock = object8(block.image);
36972
+ const source = object9(block.source);
36973
+ const inline = object9(block.inlineData);
36974
+ const file = object9(block.fileData);
36975
+ const bedrock = object9(block.image);
36634
36976
  if (block.type === "image_url" || block.type === "input_image") {
36635
36977
  if (typeof block.file_id === "string")
36636
36978
  images.push({ kind: "file", value: block.file_id });
36637
36979
  else
36638
36980
  images.push({
36639
36981
  kind: "url",
36640
- value: String(typeof block.image_url === "string" ? block.image_url : object8(block.image_url)?.url)
36982
+ value: String(typeof block.image_url === "string" ? block.image_url : object9(block.image_url)?.url)
36641
36983
  });
36642
36984
  } else if (block.type === "image") {
36643
36985
  if (source?.type === "file")
@@ -36661,7 +37003,7 @@ function piWireImages(content, ollamaImages) {
36661
37003
  else if (bedrock)
36662
37004
  images.push({
36663
37005
  kind: "data",
36664
- value: String(object8(bedrock.source)?.bytes),
37006
+ value: String(object9(bedrock.source)?.bytes),
36665
37007
  mime: `image/${bedrock.format}`
36666
37008
  });
36667
37009
  }
@@ -36683,11 +37025,11 @@ function piMatchesImages(actual, expected) {
36683
37025
  return true;
36684
37026
  }
36685
37027
  function piWireImageCount(payload) {
36686
- const body = object8(payload);
37028
+ const body = object9(payload);
36687
37029
  const visit = (value) => {
36688
37030
  if (Array.isArray(value))
36689
37031
  return value.reduce((n, item) => n + visit(item), 0);
36690
- const block = object8(value);
37032
+ const block = object9(value);
36691
37033
  if (!block)
36692
37034
  return 0;
36693
37035
  if (["image", "image_url", "input_image"].includes(String(block.type)) || block.inlineData || block.fileData || block.image)
@@ -36701,12 +37043,12 @@ function piWireImageCount(payload) {
36701
37043
  block.response
36702
37044
  ].reduce((n, item) => n + visit(item), Array.isArray(block.images) ? block.images.length : 0);
36703
37045
  };
36704
- return visit(body?.messages ?? body?.input ?? body?.contents ?? object8(body?.request)?.contents);
37046
+ return visit(body?.messages ?? body?.input ?? body?.contents ?? object9(body?.request)?.contents);
36705
37047
  }
36706
37048
 
36707
37049
  // src/pi-dispatch-responses-history.ts
36708
37050
  var MAX_TEXT_UNITS = 32 * 1024 * 1024;
36709
- function object9(value) {
37051
+ function object10(value) {
36710
37052
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
36711
37053
  }
36712
37054
  function wellFormed2(text) {
@@ -36721,7 +37063,7 @@ function textIdentity2(text, phase) {
36721
37063
  function signaturePhase(block) {
36722
37064
  try {
36723
37065
  if (typeof block.textSignature === "string") {
36724
- const signature = object9(JSON.parse(block.textSignature));
37066
+ const signature = object10(JSON.parse(block.textSignature));
36725
37067
  if (signature?.v === 1 && typeof signature.id === "string")
36726
37068
  return signature.phase;
36727
37069
  }
@@ -36743,19 +37085,19 @@ ${wellFormed2(text)}
36743
37085
  function coldReplayable(items) {
36744
37086
  let reasoning = false;
36745
37087
  for (const value of items) {
36746
- const item = object9(value);
37088
+ const item = object10(value);
36747
37089
  if (typeof item?.encrypted_content === "string")
36748
37090
  return false;
36749
37091
  if (item?.type !== "reasoning")
36750
37092
  continue;
36751
- if (!Array.isArray(item.content) || !item.content.some((part) => object9(part)?.type === "reasoning_text"))
37093
+ if (!Array.isArray(item.content) || !item.content.some((part) => object10(part)?.type === "reasoning_text"))
36752
37094
  return false;
36753
37095
  reasoning = true;
36754
37096
  }
36755
37097
  return reasoning;
36756
37098
  }
36757
37099
  function piResponsesAssistantTexts(value, model, host, alternatives) {
36758
- const message = object9(value);
37100
+ const message = object10(value);
36759
37101
  if (!message || !Array.isArray(message.content))
36760
37102
  return;
36761
37103
  if (piOmitsTruncatedAssistant(message))
@@ -36765,7 +37107,7 @@ function piResponsesAssistantTexts(value, model, host, alternatives) {
36765
37107
  const sameModel = model !== undefined && typeof model.api === "string" && typeof model.id === "string" && typeof model.provider === "string" && message.api === model.api && message.model === model.id && message.provider === model.provider;
36766
37108
  let units = 0;
36767
37109
  for (const value of message.content) {
36768
- const block = object9(value);
37110
+ const block = object10(value);
36769
37111
  if (block?.type === "toolCall")
36770
37112
  continue;
36771
37113
  if (block?.type === "thinking") {
@@ -36775,7 +37117,7 @@ function piResponsesAssistantTexts(value, model, host, alternatives) {
36775
37117
  return;
36776
37118
  if (!block.thinking.trim())
36777
37119
  continue;
36778
- const compat = object9(model.compat);
37120
+ const compat = object10(model.compat);
36779
37121
  if (block.summary === false && (compat?.requiresReasoningContentForToolCalls === true || compat?.requiresReasoningContentForAllAssistantTurns === true))
36780
37122
  return;
36781
37123
  const text = demotedThinking(block.thinking, model);
@@ -36795,7 +37137,7 @@ function piResponsesAssistantTexts(value, model, host, alternatives) {
36795
37137
  texts.push(textIdentity2(wellFormed2(block.text), sameModel ? signaturePhase(block) : undefined));
36796
37138
  blocks.push(block);
36797
37139
  }
36798
- const payload = object9(message.providerPayload);
37140
+ const payload = object10(message.providerPayload);
36799
37141
  if (message.api !== model?.api || typeof model?.id !== "string" || typeof model?.provider !== "string" || message.model !== model?.id || (payload?.provider ?? message.provider) !== model?.provider || payload?.type !== "openaiResponsesHistory" || payload.dt !== true || !Array.isArray(payload.items))
36800
37142
  return texts;
36801
37143
  const replay = [];
@@ -36809,7 +37151,7 @@ function piResponsesAssistantTexts(value, model, host, alternatives) {
36809
37151
  let unsigned = false;
36810
37152
  let rewrittenText = false;
36811
37153
  for (const value of payload.items) {
36812
- const item = object9(value);
37154
+ const item = object10(value);
36813
37155
  if (item?.type === "reasoning")
36814
37156
  continue;
36815
37157
  if (item?.type === "function_call" || item?.type === "custom_tool_call") {
@@ -36820,14 +37162,14 @@ function piResponsesAssistantTexts(value, model, host, alternatives) {
36820
37162
  return texts;
36821
37163
  const itemTexts = [];
36822
37164
  for (const value of item.content) {
36823
- const part = object9(value);
37165
+ const part = object10(value);
36824
37166
  const block = blocks[bound];
36825
37167
  if (!block || part?.type !== "output_text" || typeof part.text !== "string")
36826
37168
  return texts;
36827
37169
  let signature;
36828
37170
  try {
36829
37171
  if (typeof block.textSignature === "string")
36830
- signature = object9(JSON.parse(block.textSignature));
37172
+ signature = object10(JSON.parse(block.textSignature));
36831
37173
  } catch {
36832
37174
  return texts;
36833
37175
  }
@@ -36837,7 +37179,7 @@ function piResponsesAssistantTexts(value, model, host, alternatives) {
36837
37179
  if (!allowUnsigned || "textSignature" in block || stripped !== block.text.replace(/^§\d+§ /u, ""))
36838
37180
  return texts;
36839
37181
  unsigned = true;
36840
- rewrittenText ||= part.text !== stripped && part.text !== block.text;
37182
+ rewrittenText ||= part.text !== stripped;
36841
37183
  }
36842
37184
  bound++;
36843
37185
  itemTexts.push(part.text);
@@ -36866,7 +37208,7 @@ function piResponsesWireTexts(value, phase) {
36866
37208
  const texts = [];
36867
37209
  let units = 0;
36868
37210
  for (const partValue of value) {
36869
- const part = object9(partValue);
37211
+ const part = object10(partValue);
36870
37212
  if (part?.type !== "output_text" || typeof part.text !== "string")
36871
37213
  return;
36872
37214
  units += part.text.length;
@@ -36878,6 +37220,7 @@ function piResponsesWireTexts(value, phase) {
36878
37220
  }
36879
37221
 
36880
37222
  // src/pi-dispatch-structure.ts
37223
+ var dateReminderPlans = new WeakMap;
36881
37224
  var MAX_MESSAGES = 1e5;
36882
37225
  var ORPHAN_NOTE = Symbol("prepared orphan tool result");
36883
37226
  var ANTHROPIC_CONTINUE_PAD_TEXT = "Continue.";
@@ -36904,11 +37247,11 @@ var TRANSFORM_MESSAGES_APIS = new Set([
36904
37247
  "devin-agent",
36905
37248
  "apple-foundation-models"
36906
37249
  ]);
36907
- function object10(value) {
37250
+ function object11(value) {
36908
37251
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
36909
37252
  }
36910
37253
  function messageStructure(value) {
36911
- const message = object10(value);
37254
+ const message = object11(value);
36912
37255
  if (!message)
36913
37256
  return;
36914
37257
  const role = [
@@ -36937,7 +37280,7 @@ function messageStructure(value) {
36937
37280
  }
36938
37281
  if (role === "assistant" && Array.isArray(message.content)) {
36939
37282
  for (const value of message.content) {
36940
- const block = object10(value);
37283
+ const block = object11(value);
36941
37284
  if (block?.type !== "toolCall" && block?.type !== "tool_use")
36942
37285
  continue;
36943
37286
  if (typeof block.id !== "string")
@@ -36953,7 +37296,7 @@ function windowCalls(message) {
36953
37296
  if (!Array.isArray(message.content))
36954
37297
  return [];
36955
37298
  return message.content.flatMap((value) => {
36956
- const block = object10(value);
37299
+ const block = object11(value);
36957
37300
  return block?.type === "toolCall" && typeof block.id === "string" ? [
36958
37301
  {
36959
37302
  id: block.id,
@@ -36963,7 +37306,7 @@ function windowCalls(message) {
36963
37306
  });
36964
37307
  }
36965
37308
  function duplicateSuffix(model) {
36966
- const compat = object10(model?.compat);
37309
+ const compat = object11(model?.compat);
36967
37310
  if (model?.api === "openai-completions") {
36968
37311
  if (compat?.requiresMistralToolIds === true)
36969
37312
  return { prefix: "dup", max: 9 };
@@ -36980,7 +37323,7 @@ function appendDuplicateSuffix(id, suffix, max) {
36980
37323
  }
36981
37324
  function projectMissingToolResults(messages, model, host = "omp") {
36982
37325
  const input = messages.filter((value) => {
36983
- const message = object10(value);
37326
+ const message = object11(value);
36984
37327
  return !((message?.role === "bashExecution" || message?.role === "pythonExecution") && message.excludeFromContext === true);
36985
37328
  });
36986
37329
  if (host === "pi")
@@ -36995,7 +37338,7 @@ function projectMissingToolResults(messages, model, host = "omp") {
36995
37338
  const realResults = new Map;
36996
37339
  const validToolUseIds = new Set;
36997
37340
  const deduplicated = input.map((value, index) => {
36998
- const message = object10(value);
37341
+ const message = object11(value);
36999
37342
  if (message?.role === "toolResult" && typeof message.toolCallId === "string") {
37000
37343
  let key = pairingId(message.toolCallId);
37001
37344
  let output = value;
@@ -37022,7 +37365,7 @@ function projectMissingToolResults(messages, model, host = "omp") {
37022
37365
  const touched = new Set;
37023
37366
  let changed = false;
37024
37367
  const content = message.content.map((part) => {
37025
- const block = object10(part);
37368
+ const block = object11(part);
37026
37369
  if (block?.type !== "toolCall" || typeof block.id !== "string")
37027
37370
  return part;
37028
37371
  const key = pairingId(block.id);
@@ -37101,7 +37444,7 @@ function projectMissingToolResults(messages, model, host = "omp") {
37101
37444
  };
37102
37445
  for (let index = 0;index < deduplicated.length; index++) {
37103
37446
  const value = deduplicated[index];
37104
- const message = object10(value);
37447
+ const message = object11(value);
37105
37448
  if (message?.role === "assistant") {
37106
37449
  flush(message.timestamp);
37107
37450
  if (piOmitsTruncatedAssistant(message))
@@ -37142,7 +37485,7 @@ function projectMissingToolResults(messages, model, host = "omp") {
37142
37485
  if (pending.some((call) => !answered.has(pairingId(call.id))) || aborted.size > 0)
37143
37486
  continue;
37144
37487
  const parts = message.content.flatMap((value) => {
37145
- const part = object10(value);
37488
+ const part = object11(value);
37146
37489
  return part?.type === "text" && typeof part.text === "string" && part.text.trim() ? [part.text] : [];
37147
37490
  });
37148
37491
  if (!parts.length)
@@ -37170,11 +37513,11 @@ function projectUnmodeledToolResults(messages) {
37170
37513
  return pipe > 0 ? id.slice(0, pipe) : id;
37171
37514
  };
37172
37515
  for (const value of messages) {
37173
- const message = object10(value);
37516
+ const message = object11(value);
37174
37517
  if (message?.role !== "assistant" || !Array.isArray(message.content))
37175
37518
  continue;
37176
37519
  for (const value of message.content) {
37177
- const block = object10(value);
37520
+ const block = object11(value);
37178
37521
  if (block?.type !== "toolCall" || typeof block.id !== "string")
37179
37522
  continue;
37180
37523
  if ([
@@ -37190,7 +37533,7 @@ function projectUnmodeledToolResults(messages) {
37190
37533
  const pairingId = (id) => !opaqueIds.has(id) && responsesComponents.has(component(id)) ? component(id) : id;
37191
37534
  const lastResult = new Map;
37192
37535
  messages.forEach((value, index) => {
37193
- const message = object10(value);
37536
+ const message = object11(value);
37194
37537
  if (message?.role === "toolResult" && typeof message.toolCallId === "string")
37195
37538
  lastResult.set(pairingId(message.toolCallId), index);
37196
37539
  });
@@ -37221,7 +37564,7 @@ function projectUnmodeledToolResults(messages) {
37221
37564
  };
37222
37565
  for (let index = 0;index < messages.length; index++) {
37223
37566
  const value = messages[index];
37224
- const message = object10(value);
37567
+ const message = object11(value);
37225
37568
  if ((message?.role === "bashExecution" || message?.role === "pythonExecution") && message.excludeFromContext === true)
37226
37569
  continue;
37227
37570
  if (message?.role !== "toolResult")
@@ -37263,7 +37606,7 @@ function projectPiToolResults(messages) {
37263
37606
  held.length = 0;
37264
37607
  };
37265
37608
  for (const value of messages) {
37266
- const message = object10(value);
37609
+ const message = object11(value);
37267
37610
  const role = message?.role;
37268
37611
  if (role === "assistant") {
37269
37612
  close(message?.timestamp);
@@ -37291,23 +37634,26 @@ function projectPiToolResults(messages) {
37291
37634
  close();
37292
37635
  return projected;
37293
37636
  }
37294
- function preparePiDispatch(messages, model, omp) {
37637
+ function preparePiDispatch(messages, model, omp, cwd) {
37295
37638
  let output = messages;
37296
37639
  const structure = buildPiPreparedStructure(messages, model, omp ? (index, source) => {
37297
- if (object10(source.providerPayload)?.type !== "openaiResponsesHistory")
37640
+ if (object11(source.providerPayload)?.type !== "openaiResponsesHistory")
37298
37641
  return;
37299
37642
  if (output === messages)
37300
37643
  output = messages.slice();
37301
37644
  const { providerPayload: _payload, ...copy } = source;
37302
37645
  output[index] = copy;
37303
37646
  } : undefined, omp ? "omp" : "pi");
37647
+ const reminders = structure && dateReminderPlans.get(structure);
37648
+ if (reminders)
37649
+ reminders.cwd = cwd;
37304
37650
  return { messages: output, structure };
37305
37651
  }
37306
37652
  function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37307
37653
  if (!messages.length || messages.length > MAX_MESSAGES)
37308
37654
  return;
37309
37655
  for (let index = 0;index < messages.length; index++) {
37310
- const source = object10(messages[index]);
37656
+ const source = object11(messages[index]);
37311
37657
  if (source?.role === "user" || source?.role === "compactionSummary")
37312
37658
  prepareUser?.(index, source);
37313
37659
  }
@@ -37319,11 +37665,12 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37319
37665
  const toolIds = new Map;
37320
37666
  const responsesToolIds = new Map;
37321
37667
  const byIndex = new Map;
37668
+ let firstUserRow;
37322
37669
  const imageBudget = piImageBudgetPlan(model);
37323
37670
  let valid = true;
37324
37671
  for (let index = 0;index < projectedMessages.length; index++) {
37325
37672
  const message = projectedMessages[index];
37326
- const source = object10(message);
37673
+ const source = object11(message);
37327
37674
  if (rows.length === 0 && (source?.role === "system" || source?.role === "developer"))
37328
37675
  continue;
37329
37676
  if ((source?.role === "bashExecution" || source?.role === "pythonExecution") && source.excludeFromContext === true)
@@ -37347,7 +37694,7 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37347
37694
  "azure-openai-responses",
37348
37695
  "openai-codex-responses"
37349
37696
  ].includes(model?.api ?? "") && (source?.role === "user" || source?.role === "developer") && (typeof source.content === "string" ? !source.content.trim() : Array.isArray(source.content) && !source.content.some((value) => {
37350
- const block = object10(value);
37697
+ const block = object11(value);
37351
37698
  return block?.type === "image" || block?.type === "text" && typeof block.text === "string" && block.text.trim();
37352
37699
  })))
37353
37700
  continue;
@@ -37379,6 +37726,8 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37379
37726
  row.wireResults = row.results.map((id) => toolIds.has(id) ? toolIds.get(id) : responsesToolIds.get(id.split("|", 1)[0]));
37380
37727
  }
37381
37728
  rows.push(row);
37729
+ if (source?.role === "user")
37730
+ firstUserRow ??= row;
37382
37731
  byIndex.set(index, row);
37383
37732
  piRecordImages(imageBudget, row, source);
37384
37733
  }
@@ -37389,12 +37738,12 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37389
37738
  const positionedRows = [...byIndex];
37390
37739
  for (let position = positionedRows.length - 1;position >= 0; position--) {
37391
37740
  const [index, row] = positionedRows[position];
37392
- const source = object10(projectedMessages[index]);
37741
+ const source = object11(projectedMessages[index]);
37393
37742
  if (!source)
37394
37743
  return;
37395
37744
  const content = source.content;
37396
37745
  const parts = typeof content === "string" ? [{ type: "text", text: content }] : content;
37397
- const textOnly = Array.isArray(parts) && parts.every((part) => object10(part)?.type === "text" && typeof object10(part)?.text === "string");
37746
+ const textOnly = Array.isArray(parts) && parts.every((part) => object11(part)?.type === "text" && typeof object11(part)?.text === "string");
37398
37747
  const systemTexts = () => {
37399
37748
  const texts = parts.map((part) => part.text);
37400
37749
  return model?.api === "anthropic-messages" ? texts.filter((text) => text.trim()).map((text) => new TextDecoder().decode(new TextEncoder().encode(text))) : texts;
@@ -37402,7 +37751,7 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37402
37751
  if (piIsDeveloperHistory(source) && source.attribution !== "user") {
37403
37752
  const previous = rows[position - 1];
37404
37753
  const next = rows[position + 1];
37405
- const anthropicPromotable = model?.api === "anthropic-messages" && object10(model.compat)?.supportsMidConversationSystem === true && textOnly;
37754
+ const anthropicPromotable = model?.api === "anthropic-messages" && object11(model.compat)?.supportsMidConversationSystem === true && textOnly;
37406
37755
  if (anthropicPromotable)
37407
37756
  promotable.set(row, systemTexts());
37408
37757
  if (model?.api === "ollama-chat" || anthropicPromotable && (previous?.role === "user" || previous?.role === "toolResult") && (!next || next.role === "assistant"))
@@ -37493,7 +37842,7 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37493
37842
  }
37494
37843
  return [row];
37495
37844
  });
37496
- return {
37845
+ const prepared = {
37497
37846
  messages: rows,
37498
37847
  ...imageBudget?.count ? { imageBudget } : {},
37499
37848
  ...responsesApi && !responsesMessages ? { structuralSkipReason: "Responses history transform is not modeled" } : model?.api === "openai-completions" && !chatMessages ? { structuralSkipReason: "Chat history transform is not modeled" } : {},
@@ -37504,9 +37853,17 @@ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
37504
37853
  ...modelsContinuePad ? { anthropicContinuePad: true } : {},
37505
37854
  ...modelsContinuePad && baseRows.some((row) => row.optionalThinking) ? { anthropicOptional: { rows: baseRows, promotable } } : {},
37506
37855
  ...model?.api?.startsWith("google-") ? {
37507
- googleFunctionIds: object10(model.compat)?.supportsFunctionPartId === true
37856
+ googleFunctionIds: object11(model.compat)?.supportsFunctionPartId === true
37508
37857
  } : {}
37509
37858
  };
37859
+ if (host === "omp" && PI_DATE_REMINDER_APIS.has(model?.api ?? ""))
37860
+ dateReminderPlans.set(prepared, {
37861
+ ...modelsContinuePad ? { plan: { rows: baseRows, promotable } } : {},
37862
+ firstUser: firstUserRow ? baseRows.indexOf(firstUserRow) : -1,
37863
+ midConversationSystem: object11(model?.compat)?.supportsMidConversationSystem === true,
37864
+ developerRole: object11(model?.compat)?.supportsDeveloperRole === true
37865
+ });
37866
+ return prepared;
37510
37867
  }
37511
37868
  function responsesLane(api) {
37512
37869
  return [
@@ -37516,7 +37873,7 @@ function responsesLane(api) {
37516
37873
  ].includes(api ?? "");
37517
37874
  }
37518
37875
  function payloadStructure(payload, ollama = false, responsesItems = false, imageProjection = false) {
37519
- const body = object10(payload);
37876
+ const body = object11(payload);
37520
37877
  if (!body)
37521
37878
  return;
37522
37879
  const google = piGoogleConversation(payload);
@@ -37531,12 +37888,12 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
37531
37888
  return;
37532
37889
  const rows = [];
37533
37890
  for (const value of messages) {
37534
- const message = object10(value);
37891
+ const message = object11(value);
37535
37892
  if (!message)
37536
37893
  return;
37537
37894
  if (rows.length === 0 && (message.role === "system" || message.role === "developer"))
37538
37895
  continue;
37539
- if (message.role === "system" && Array.isArray(message.content) && message.content.every((block) => ["tool_addition", "tool_removal"].includes(String(object10(block)?.type))))
37896
+ if (message.role === "system" && Array.isArray(message.content) && message.content.every((block) => ["tool_addition", "tool_removal"].includes(String(object11(block)?.type))))
37540
37897
  continue;
37541
37898
  if (responses && message.type === "reasoning")
37542
37899
  continue;
@@ -37593,7 +37950,7 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
37593
37950
  continue;
37594
37951
  }
37595
37952
  if (message.role === "user" && Array.isArray(message.content)) {
37596
- const results = message.content.filter((block) => object10(block)?.type === "tool_result" || bedrock && object10(block)?.toolResult);
37953
+ const results = message.content.filter((block) => object11(block)?.type === "tool_result" || bedrock && object11(block)?.toolResult);
37597
37954
  if (results.length) {
37598
37955
  for (const block of results) {
37599
37956
  const id = bedrock ? block.toolResult?.toolUseId : block.tool_use_id;
@@ -37640,11 +37997,11 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
37640
37997
  }
37641
37998
  if (Array.isArray(message.tool_calls)) {
37642
37999
  for (const call of message.tool_calls) {
37643
- const source = object10(call);
38000
+ const source = object11(call);
37644
38001
  if (!source)
37645
38002
  return;
37646
38003
  if (source.id === undefined && ollama) {
37647
- const fn = object10(source.function);
38004
+ const fn = object11(source.function);
37648
38005
  if (typeof fn?.name !== "string")
37649
38006
  return;
37650
38007
  row.calls.push("");
@@ -37680,7 +38037,7 @@ function googleStructure(contents, imageProjection = false) {
37680
38037
  return;
37681
38038
  const rows = [];
37682
38039
  for (const value of contents) {
37683
- const message = object10(value);
38040
+ const message = object11(value);
37684
38041
  if (!message || !Array.isArray(message.parts))
37685
38042
  return;
37686
38043
  if (message.role !== "user" && message.role !== "model")
@@ -37695,11 +38052,11 @@ function googleStructure(contents, imageProjection = false) {
37695
38052
  };
37696
38053
  const results = [];
37697
38054
  for (const value of message.parts) {
37698
- const part = object10(value);
38055
+ const part = object11(value);
37699
38056
  if (!part)
37700
38057
  return;
37701
38058
  if (part.functionCall) {
37702
- const call = object10(part.functionCall);
38059
+ const call = object11(part.functionCall);
37703
38060
  if (row.role !== "assistant" || typeof call?.name !== "string" || call.id !== undefined && typeof call.id !== "string")
37704
38061
  return;
37705
38062
  row.calls.push(call.id ?? "");
@@ -37707,7 +38064,7 @@ function googleStructure(contents, imageProjection = false) {
37707
38064
  row.callNames.push(call.name);
37708
38065
  }
37709
38066
  if (part.functionResponse) {
37710
- const result = object10(part.functionResponse);
38067
+ const result = object11(part.functionResponse);
37711
38068
  if (row.role !== "user" || typeof result?.name !== "string" || result.id !== undefined && typeof result.id !== "string")
37712
38069
  return;
37713
38070
  results.push({
@@ -37741,11 +38098,11 @@ function matchesUserText(content, text, api, responses, googleOrBedrock) {
37741
38098
  if (responses || googleOrBedrock) {
37742
38099
  if (!Array.isArray(content) || content.length !== 1)
37743
38100
  return false;
37744
- const block = object10(content[0]);
38101
+ const block = object11(content[0]);
37745
38102
  return !!block && block.text === text && (responses ? block.type === "input_text" : Object.keys(block).length === 1);
37746
38103
  }
37747
38104
  if ((api === "anthropic-messages" || api === "factory-droid-agent") && Array.isArray(content)) {
37748
- const block = content.length === 1 ? object10(content[0]) : undefined;
38105
+ const block = content.length === 1 ? object11(content[0]) : undefined;
37749
38106
  return block?.type === "text" && block.text === text;
37750
38107
  }
37751
38108
  return content === text;
@@ -37798,7 +38155,7 @@ function trimPreparedImageRows(rows, budget, drops) {
37798
38155
  flush();
37799
38156
  return projected;
37800
38157
  }
37801
- function countAnthropicOptionalAlignments(plan, base, wire, compare) {
38158
+ function countAnthropicOptionalAlignments(plan, base, wire, compare, reminders, firstUser = -1) {
37802
38159
  const pad = {
37803
38160
  role: "user",
37804
38161
  calls: [],
@@ -37830,11 +38187,16 @@ function countAnthropicOptionalAlignments(plan, base, wire, compare) {
37830
38187
  const place = (next) => {
37831
38188
  if (current < 0)
37832
38189
  return at;
37833
- const nextRole = next === undefined ? undefined : role(next);
38190
+ let after = at + 1;
38191
+ while (after < wire.length && reminders?.has(wire[after]))
38192
+ after++;
38193
+ const controls = after > at + 1;
38194
+ if (controls && (firstUser < 0 || current < firstUser))
38195
+ return;
38196
+ const nextRole = controls ? wire[at + 1].role : next === undefined ? undefined : role(next);
37834
38197
  if (!matches(final(current, previous, nextRole), at))
37835
38198
  return;
37836
- let after = at + 1;
37837
- if (role(current) === "assistant" && nextRole === "assistant") {
38199
+ if (!controls && role(current) === "assistant" && nextRole === "assistant") {
37838
38200
  if (!matches(pad, after))
37839
38201
  return;
37840
38202
  after++;
@@ -37844,7 +38206,7 @@ function countAnthropicOptionalAlignments(plan, base, wire, compare) {
37844
38206
  for (let next = current + 1;next < base.length; next++) {
37845
38207
  const after = place(next);
37846
38208
  if (after !== undefined)
37847
- add(next, current < 0 ? undefined : role(current), after, count);
38209
+ add(next, current < 0 ? undefined : wire[after - 1]?.role, after, count);
37848
38210
  if (!base[next].optionalThinking)
37849
38211
  return;
37850
38212
  }
@@ -37854,7 +38216,7 @@ function countAnthropicOptionalAlignments(plan, base, wire, compare) {
37854
38216
  return;
37855
38217
  }
37856
38218
  const after = place(undefined);
37857
- if (after === wire.length || after === wire.length - 1 && role(current) === "assistant" && isAnthropicContinuePadRow(wire[after]))
38219
+ if (after === wire.length || after === wire.length - 1 && wire[after - 1]?.role === "assistant" && isAnthropicContinuePadRow(wire[after]))
37858
38220
  complete = Math.min(2, complete + count);
37859
38221
  };
37860
38222
  advance(-1, undefined, 0, 1);
@@ -37872,6 +38234,70 @@ function countAnthropicOptionalAlignments(plan, base, wire, compare) {
37872
38234
  return complete;
37873
38235
  }
37874
38236
  function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
38237
+ const plan = prepared && dateReminderPlans.get(prepared);
38238
+ try {
38239
+ const messages = plan ? object11(payload)?.messages : undefined;
38240
+ if (Array.isArray(messages)) {
38241
+ for (const value of messages) {
38242
+ const message = object11(value);
38243
+ if (message?.role !== "system" && message?.role !== "developer")
38244
+ break;
38245
+ if (piDateReminderWireText(message.content, plan?.cwd) !== undefined)
38246
+ return "comparison=role";
38247
+ }
38248
+ }
38249
+ } catch {}
38250
+ const mismatch = preparedStructureMismatch(payload, prepared, onImageTrim);
38251
+ if (!mismatch)
38252
+ return mismatch;
38253
+ try {
38254
+ if (!prepared || !plan)
38255
+ return mismatch;
38256
+ if (!plan.plan) {
38257
+ if (plan.firstUser < 0)
38258
+ return mismatch;
38259
+ const root = prepared.messages[plan.firstUser];
38260
+ const body = object11(payload);
38261
+ const routeRows = Array.isArray(body?.input) ? prepared.responsesMessages ?? prepared.messages : prepared.api === "openai-completions" ? prepared.chatMessages ?? prepared.messages : prepared.messages;
38262
+ const firstUser = routeRows.indexOf(root);
38263
+ if (firstUser < 0)
38264
+ return mismatch;
38265
+ const filtered = piWithoutDateReminders(payload, prepared.api ?? "", plan.cwd, plan.developerRole, (prefix) => {
38266
+ const rows = payloadStructure(prefix, prepared.api === "ollama-chat", !!prepared.responsesMessages);
38267
+ return !!rows && rows.length > firstUser;
38268
+ });
38269
+ return filtered === undefined ? mismatch : preparedStructureMismatch(filtered, prepared, onImageTrim);
38270
+ }
38271
+ const messages = object11(payload)?.messages;
38272
+ if (!Array.isArray(messages))
38273
+ return mismatch;
38274
+ for (const value of messages) {
38275
+ const message = object11(value);
38276
+ if (piDateReminderWireText(message?.content, plan.cwd) !== undefined && Object.keys(message ?? {}).some((key) => !["role", "content"].includes(key)))
38277
+ return mismatch;
38278
+ }
38279
+ const wire = payloadStructure(payload, false, false, !!prepared.imageBudget && piWireImageCount(payload) < prepared.imageBudget.count);
38280
+ if (!wire)
38281
+ return mismatch;
38282
+ const reminders = new Set(wire.filter((row) => piDateReminderWireText(row.wireContent, plan.cwd) !== undefined));
38283
+ if (!reminders.size)
38284
+ return mismatch;
38285
+ for (let index = 0;index < wire.length; index++) {
38286
+ const row = wire[index];
38287
+ if (!reminders.has(row))
38288
+ continue;
38289
+ const previous = wire[index - 1];
38290
+ const next = wire[index + 1];
38291
+ const promoted = plan.midConversationSystem && (previous?.role === "user" || previous?.role === "toolResult") && (!next || next.role === "assistant");
38292
+ if (row.wireRole !== (promoted ? "system" : "user") || row.calls.length || row.results.length)
38293
+ return mismatch;
38294
+ }
38295
+ return preparedStructureMismatch(payload, { ...prepared, anthropicOptional: plan.plan }, onImageTrim, reminders, wire, plan.firstUser);
38296
+ } catch {
38297
+ return mismatch;
38298
+ }
38299
+ }
38300
+ function preparedStructureMismatch(payload, prepared, onImageTrim, reminders, reminderWire, firstUser) {
37875
38301
  let stage = "image count";
37876
38302
  let row = 0;
37877
38303
  let expectedRows;
@@ -37886,10 +38312,10 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
37886
38312
  return "comparison=image count";
37887
38313
  const imageProjection = trimmed > 0;
37888
38314
  stage = "wire rows";
37889
- const body = object10(payload);
38315
+ const body = object11(payload);
37890
38316
  const ollama = prepared?.api === "ollama-chat" && !!body && Array.isArray(body.messages) && body.input === undefined && body.system === undefined && body.inferenceConfig === undefined;
37891
38317
  const responses = body?.messages === undefined && Array.isArray(body?.input);
37892
- rows = payloadStructure(payload, ollama, responses && !!prepared?.responsesMessages, imageProjection);
38318
+ rows = reminderWire ?? payloadStructure(payload, ollama, responses && !!prepared?.responsesMessages, imageProjection);
37893
38319
  const chat = !!body && Array.isArray(body.messages) && (prepared?.api === "openai-completions" || body.system === undefined) && body.input === undefined && body.inferenceConfig === undefined;
37894
38320
  stage = "prepared rows";
37895
38321
  expectedRows = responses && prepared?.responsesMessages ? prepared.responsesMessages : chat && prepared?.chatMessages ? prepared.chatMessages : prepared?.messages;
@@ -37913,7 +38339,7 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
37913
38339
  if (expected.systemText !== undefined) {
37914
38340
  const texts = expected.systemText;
37915
38341
  const content = actual.wireContent;
37916
- const actualTexts = typeof content === "string" ? [content] : Array.isArray(content) && content.every((part) => object10(part)?.type === "text" && typeof object10(part)?.text === "string") ? content.map((part) => part.text) : undefined;
38342
+ const actualTexts = typeof content === "string" ? [content] : Array.isArray(content) && content.every((part) => object11(part)?.type === "text" && typeof object11(part)?.text === "string") ? content.map((part) => part.text) : undefined;
37917
38343
  if (!actualTexts || (typeof content === "string" ? content !== texts.join(`
37918
38344
  `) : JSON.stringify(actualTexts) !== JSON.stringify(texts)))
37919
38345
  return "content";
@@ -37944,7 +38370,7 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
37944
38370
  };
37945
38371
  if (optionalPlan) {
37946
38372
  stage = "optional assistants";
37947
- const alignments = countAnthropicOptionalAlignments(optionalPlan, imageProjection && imageBudget ? trimPreparedImageRows(optionalPlan.rows, imageBudget, trimmed) : optionalPlan.rows, rows, compareRow);
38373
+ const alignments = countAnthropicOptionalAlignments(optionalPlan, imageProjection && imageBudget ? trimPreparedImageRows(optionalPlan.rows, imageBudget, trimmed) : optionalPlan.rows, rows, compareRow, reminders, firstUser);
37948
38374
  if (alignments > 1)
37949
38375
  return structureDetail(0, expectedRows, rows, "alignment");
37950
38376
  if (alignments === 1) {
@@ -39704,7 +40130,7 @@ function registerPiGuardedContext(pi, handler, options = {}) {
39704
40130
  }
39705
40131
  const result = await budget.waitMandatory(Promise.resolve(withSqliteTurnDeadline2(() => Math.max(0, budget.remainingOutcome() - PI_CONTEXT_BUDGET.completionReserveMs), () => withSqliteTransformPass2(() => handler(event, ctx, budget)))));
39706
40132
  if (result?.messages) {
39707
- const prepared = preparePiDispatch(result.messages, fenceEnabled ? ctx.model : undefined, fenceEnabled);
40133
+ const prepared = preparePiDispatch(result.messages, fenceEnabled ? ctx.model : undefined, fenceEnabled, ctx.cwd);
39708
40134
  if (prepared.messages !== result.messages)
39709
40135
  result.messages = prepared.messages;
39710
40136
  active.managedSignature = piManagedSignature(result.messages);
@@ -42883,7 +43309,7 @@ function createPiAssistantPart(working, messageIndex, partIndex, markDirty) {
42883
43309
  setToolOutput() {
42884
43310
  throw new Error("setToolOutput on assistant part");
42885
43311
  },
42886
- getToolMetadata() {
43312
+ getToolMetadata(options) {
42887
43313
  const current = working[messageIndex].content;
42888
43314
  const p = current[partIndex];
42889
43315
  if (p?.type !== "toolCall") {
@@ -42894,7 +43320,7 @@ function createPiAssistantPart(working, messageIndex, partIndex, markDirty) {
42894
43320
  try {
42895
43321
  const serialized = JSON.stringify(p.arguments);
42896
43322
  inputByteSize = serialized.length;
42897
- inputTokenCount = serialized ? estimateTokens(serialized) : 0;
43323
+ inputTokenCount = serialized && !options?.skipInputTokenCount ? estimateTokens(serialized) : 0;
42898
43324
  } catch {
42899
43325
  inputByteSize = 0;
42900
43326
  inputTokenCount = 0;
@@ -43255,6 +43681,7 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
43255
43681
  sourceCache.set(tagId, source);
43256
43682
  }
43257
43683
  const driftedMessageIds = new Set;
43684
+ const reusableTextMessageIds = new Set;
43258
43685
  const legacyReminderTagNumbers = new Set;
43259
43686
  for (const [messageId, currentSources] of currentSourcesByMessageId) {
43260
43687
  const legacyRows = legacyRowsByMessageId.get(messageId) ?? [];
@@ -43282,6 +43709,8 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
43282
43709
  });
43283
43710
  if (!vectorMatches)
43284
43711
  driftedMessageIds.add(messageId);
43712
+ else if (!messageId.startsWith("pi-msg-") && legacyRows.every((row) => sourceCache.has(row.tagId) && !legacyReminderTagNumbers.has(row.tagId)))
43713
+ reusableTextMessageIds.add(messageId);
43285
43714
  }
43286
43715
  const reusableMessageIds = new Set;
43287
43716
  for (const messageId of reuseCandidates) {
@@ -43292,7 +43721,8 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
43292
43721
  driftedMessageIds,
43293
43722
  legacyReminderTagNumbers,
43294
43723
  reusableMessageIds,
43295
- sourceCache
43724
+ sourceCache,
43725
+ reusableTextMessageIds
43296
43726
  };
43297
43727
  }
43298
43728
  var piBranchProjectionBySession = new Map;
@@ -44839,7 +45269,7 @@ function registerPiContextHandler(pi, baseOptions) {
44839
45269
  withoutSqliteTransformPass2(() => options.maybeAutoEmbedSession?.(sessionId, projectDirectory, projectIdentity));
44840
45270
  if (!options.compactionOff) {
44841
45271
  budget.stage = "tag snapshot hydration";
44842
- const hydration = ensurePiTagSnapshotReady(options.db, sessionId, budget);
45272
+ const hydration = ensurePiTagSnapshotReady(options.db, sessionId, budget, "pass");
44843
45273
  if (hydration)
44844
45274
  await guardAwait(hydration);
44845
45275
  }
@@ -46071,7 +46501,7 @@ function registerPiContextHandler(pi, baseOptions) {
46071
46501
  budget.failureReason = err.message;
46072
46502
  if (sessionIdForError) {
46073
46503
  try {
46074
- prewarmPiTagSnapshot(lkgOptions.db, sessionIdForError);
46504
+ prewarmPiTagSnapshot(lkgOptions.db, sessionIdForError, "pass");
46075
46505
  } catch {}
46076
46506
  }
46077
46507
  throw err;
@@ -46137,7 +46567,7 @@ function registerPiContextHandler(pi, baseOptions) {
46137
46567
  })
46138
46568
  });
46139
46569
  assertPiTagSnapshotReady(lkgOptions.db, sessionIdForError);
46140
- const drops = getPiTagSnapshotView(lkgOptions.db, sessionIdForError).filter((tag) => tag.status === "dropped");
46570
+ const drops = projectPiReplayDrops(recoveryTranscript, getPiPassTagSnapshotView(lkgOptions.db, sessionIdForError));
46141
46571
  const changed = applyFlushedStatuses(sessionIdForError, lkgOptions.db, buildPersistedDropTargets(recoveryTranscript, drops, {
46142
46572
  allowReasoningPrefixRewrite: true
46143
46573
  }), drops);
@@ -47136,6 +47566,21 @@ async function runPipeline(args) {
47136
47566
  try {
47137
47567
  nativeRemovalInputs = getNativeReplayState(args.db, args.sessionId).toolInputs;
47138
47568
  } catch {}
47569
+ const removalBatch = (edit) => withPiToolRemovalBatch({ db: args.db, sessionId: args.sessionId, saved: nativeRemovalInputs }, edit);
47570
+ const applyToolRemovalGroup = (edit) => {
47571
+ const savedRemovalInputs = nativeRemovalInputs;
47572
+ nativeRemovalInputs = savedRemovalInputs && new Map(savedRemovalInputs);
47573
+ try {
47574
+ return args.db.transaction(() => removalBatch((flush) => {
47575
+ const result = edit();
47576
+ flush();
47577
+ return result;
47578
+ })).immediate();
47579
+ } catch (cause) {
47580
+ nativeRemovalInputs = savedRemovalInputs;
47581
+ throw cause instanceof PiToolRemovalBatchError ? cause : new PiToolRemovalBatchError(cause);
47582
+ }
47583
+ };
47139
47584
  const tTranscriptBuild = performance.now();
47140
47585
  const transcript = createPiTranscript(args.messages, args.sessionId, args.messages.map(stableIdResolver), {
47141
47586
  preserveReasoningToolArcs: args.reasoningClearing?.preserveReasoningToolArcs,
@@ -47328,6 +47773,7 @@ async function runPipeline(args) {
47328
47773
  preserveTagOnlyAssistantText: true,
47329
47774
  entryFingerprintByMessageId,
47330
47775
  reuseMessageIds: textIdentityPlan.reusableMessageIds,
47776
+ reuseTextMessageIds: textIdentityPlan.reusableTextMessageIds,
47331
47777
  textIdentityDriftMessageIds: textIdentityPlan.driftedMessageIds,
47332
47778
  textIdentitySourceCache: textIdentityPlan.sourceCache,
47333
47779
  textTokenCache: tagTextTokenCache,
@@ -47408,21 +47854,40 @@ async function runPipeline(args) {
47408
47854
  message.content = content;
47409
47855
  });
47410
47856
  }
47857
+ const tLegacyToolConversion = performance.now();
47411
47858
  if (foldBustsServedPrefixThisPass) {
47859
+ const savedRemovalInputs = nativeRemovalInputs;
47412
47860
  try {
47861
+ nativeRemovalInputs = savedRemovalInputs && new Map(savedRemovalInputs);
47413
47862
  let converted = 0;
47414
- args.db.transaction(() => {
47863
+ args.db.transaction(() => removalBatch((flush) => {
47415
47864
  converted = convertLegacyToolSkeletons(args.db, args.sessionId, targets, {
47416
- keepFullDrop: (callId) => nativeRemovalInputs === undefined || callId !== null && nativeRemovalInputs.get(callId) === NATIVE_TOOL_REMOVAL_MARKER
47865
+ prepareRemovals: (rows) => preparePiToolRemovalChecks({
47866
+ db: args.db,
47867
+ rows,
47868
+ targets,
47869
+ messages: args.messages,
47870
+ prepare: transcript.prepareToolRemovalMeasurements
47871
+ }),
47872
+ keepFullDrop: (callId) => nativeRemovalInputs === undefined || callId !== null && authorizePiToolRemoval({
47873
+ db: args.db,
47874
+ sessionId: args.sessionId,
47875
+ callId,
47876
+ saved: nativeRemovalInputs,
47877
+ canApply: false
47878
+ }) === true
47417
47879
  }).size;
47418
- }).immediate();
47880
+ flush();
47881
+ })).immediate();
47419
47882
  if (converted > 0) {
47420
47883
  sessionLog2(args.sessionId, `pi HARD fold converted ${converted} legacy dropped-tool skeleton(s) to real-or-absent`);
47421
47884
  }
47422
47885
  } catch (error) {
47886
+ nativeRemovalInputs = savedRemovalInputs;
47423
47887
  sessionLog2(args.sessionId, `pi legacy dropped-tool skeleton conversion failed (kept legacy bytes): ${error instanceof Error ? error.message : String(error)}`);
47424
47888
  }
47425
47889
  }
47890
+ logTransformTiming(args.sessionId, "convertLegacyToolSkeletons", tLegacyToolConversion);
47426
47891
  try {
47427
47892
  if (!args.sessionMeta.isSubagent) {
47428
47893
  const hasRecentCommit = detectRecentCommit(args.messages);
@@ -47440,7 +47905,9 @@ async function runPipeline(args) {
47440
47905
  const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
47441
47906
  const shouldReadPendingOps = !args.compactionOff && (publishedWorkDrainAllowed || args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || foldExecutedThisPass || firstRenderBust);
47442
47907
  const pendingOps = shouldReadPendingOps ? getPendingOps(args.db, args.sessionId) : [];
47908
+ const tReclaimDistance = performance.now();
47443
47909
  const reclaimDistance = isCacheBustingPass ? toolReclaimDistanceEntries(mutationView, targets) : [];
47910
+ logTransformTiming(args.sessionId, "toolReclaimDistanceEntries", tReclaimDistance);
47444
47911
  const protectedToolTags = protectedToolTagNumbers(getActiveTagsBySession2(args.db, args.sessionId), args.protectedTools);
47445
47912
  for (const number of identityAdoption.protectedTagNumbers)
47446
47913
  protectedToolTags.add(number);
@@ -47477,13 +47944,14 @@ async function runPipeline(args) {
47477
47944
  try {
47478
47945
  nativeRemovalInputs = saved && new Map(saved);
47479
47946
  probingExecuteRemoval = true;
47480
- args.db.transaction(() => {
47947
+ args.db.transaction(() => removalBatch((flush) => {
47481
47948
  for (const [number, target] of targets) {
47482
47949
  if (target.prepareDrop?.() !== false)
47483
47950
  allowed.add(number);
47484
47951
  }
47952
+ flush();
47485
47953
  throw rollback;
47486
- }).immediate();
47954
+ })).immediate();
47487
47955
  } catch (error) {
47488
47956
  if (error !== rollback)
47489
47957
  allowed.clear();
@@ -47522,13 +47990,13 @@ async function runPipeline(args) {
47522
47990
  pendingDecisionLogObserverForTests?.(pendingDecisionLog);
47523
47991
  try {
47524
47992
  const tApplyPending = performance.now();
47525
- pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, newTargets, new Set([
47993
+ pendingOpsDidMutate = applyToolRemovalGroup(() => applyPendingOperations(args.sessionId, args.db, newTargets, new Set([
47526
47994
  ...args.contextUsage.percentage >= 95 ? [] : protectedTagNumbersForPass,
47527
47995
  ...protectedToolTags,
47528
47996
  ...identityAdoption.protectedTagNumbers
47529
47997
  ]), pendingOperationTags, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction), undefined, (eligible) => {
47530
47998
  eligiblePendingDropTagIds = eligible;
47531
- });
47999
+ }));
47532
48000
  if (pendingOpsDidMutate) {
47533
48001
  droppedCount += pendingOps.length;
47534
48002
  }
@@ -47558,7 +48026,26 @@ async function runPipeline(args) {
47558
48026
  const flushedDroppedTags = getDroppedTagsByNumbers2(args.db, args.sessionId, targetTagNumbers);
47559
48027
  logTransformTiming(args.sessionId, "getDroppedTagsByNumbers", tGetTags, `targets=${targetTagNumbers.length} fetched=${flushedDroppedTags.length}`);
47560
48028
  const tFlushed = performance.now();
47561
- runPersistedReplayStage("flushed-status-failure", undefined, () => applyFlushedStatuses(args.sessionId, args.db, targets, flushedDroppedTags));
48029
+ runPersistedReplayStage("flushed-status-failure", undefined, () => {
48030
+ const render = () => applyFlushedStatuses(args.sessionId, args.db, targets, flushedDroppedTags);
48031
+ const savedRemovalInputs = nativeRemovalInputs;
48032
+ const needsRemovalPreparation = savedRemovalInputs !== undefined && flushedDroppedTags.some((tag) => tag.type === "tool" && tag.dropMode === "full" && savedRemovalInputs.get(tag.messageId) !== NATIVE_TOOL_REMOVAL_MARKER);
48033
+ if (!isCacheBustingPass || !needsRemovalPreparation)
48034
+ return render();
48035
+ try {
48036
+ nativeRemovalInputs = savedRemovalInputs && new Map(savedRemovalInputs);
48037
+ return args.db.transaction(() => removalBatch((flush) => {
48038
+ prepareFlushedToolRemovals(targets, flushedDroppedTags);
48039
+ flush();
48040
+ return render();
48041
+ })).immediate();
48042
+ } catch (error) {
48043
+ nativeRemovalInputs = savedRemovalInputs;
48044
+ if (error instanceof PiToolRemovalBatchError)
48045
+ return render();
48046
+ throw error;
48047
+ }
48048
+ });
47562
48049
  logTransformTiming(args.sessionId, "applyFlushedStatuses", tFlushed);
47563
48050
  logTransformTiming(args.sessionId, "batchFinalize:flushed", tFlushed);
47564
48051
  const messageIdToMaxTag = buildMessageIdToMaxTag(targets);
@@ -47607,7 +48094,7 @@ async function runPipeline(args) {
47607
48094
  let routineCleanupApplied = false;
47608
48095
  let heuristicsResult = null;
47609
48096
  const tActiveTags = performance.now();
47610
- const allTagsForPass = getPiTagSnapshotView(args.db, args.sessionId);
48097
+ const allTagsForPass = getPiPassTagSnapshotView(args.db, args.sessionId);
47611
48098
  const activeTags = getPiActiveTagSnapshotView(args.db, args.sessionId, allTagsForPass);
47612
48099
  logTransformTiming(args.sessionId, "getTagsBySessionSnapshot", tActiveTags, `all=${allTagsForPass.length} active=${activeTags.length}`);
47613
48100
  if (shouldRunHeuristics) {
@@ -47629,7 +48116,7 @@ async function runPipeline(args) {
47629
48116
  clearEmergencyDropSample(args.db, args.sessionId);
47630
48117
  }
47631
48118
  routineCleanupApplied = (emergencyDropEligible ? args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0 : args.sessionMeta.isSubagent || !routinePressureAlreadyApplied) || hasPendingMaterializeSignal || rideSignals.explicitFlush || deferredMaterialize || independentMutationBeforeHeuristics;
47632
- heuristicsResult = applyPiHeuristicCleanup(args.sessionId, args.db, newTargets, args.messages, {
48119
+ heuristicsResult = applyToolRemovalGroup(() => applyPiHeuristicCleanup(args.sessionId, args.db, newTargets, args.messages, {
47633
48120
  protectedTags: args.protectedTags,
47634
48121
  prepareToolRemovalMeasurements: transcript.prepareToolRemovalMeasurements,
47635
48122
  protectedToolTags,
@@ -47643,18 +48130,18 @@ async function runPipeline(args) {
47643
48130
  usagePercentage: args.contextUsage.percentage,
47644
48131
  passAlreadyPriced: independentMutationBeforeHeuristics
47645
48132
  } : undefined,
47646
- caveman: args.isSubagent ? undefined : args.heuristics.caveman
47647
- }, activeTags, stableIdResolver);
48133
+ caveman: args.isSubagent ? undefined : args.heuristics?.caveman
48134
+ }, activeTags, stableIdResolver));
47648
48135
  if (!routineCleanupApplied && heuristicsResult.emergencyDroppedTools > 0) {
47649
- const ridingCleanup = applyPiHeuristicCleanup(args.sessionId, args.db, newTargets, args.messages, {
48136
+ const ridingCleanup = applyToolRemovalGroup(() => applyPiHeuristicCleanup(args.sessionId, args.db, newTargets, args.messages, {
47650
48137
  protectedTags: args.protectedTags,
47651
48138
  protectedToolTags,
47652
48139
  protectedCutoff: usesTokenProtection ? protectionWindowForPass.cutoff : undefined,
47653
48140
  routine: true,
47654
48141
  staleReduceStripEnabled: true,
47655
48142
  onStaleReduceEdit: recordStaleReduceEdit,
47656
- caveman: args.isSubagent ? undefined : args.heuristics.caveman
47657
- }, getActiveTagsBySession2(args.db, args.sessionId), stableIdResolver);
48143
+ caveman: args.isSubagent ? undefined : args.heuristics?.caveman
48144
+ }, getActiveTagsBySession2(args.db, args.sessionId), stableIdResolver));
47658
48145
  heuristicsResult = {
47659
48146
  droppedTools: heuristicsResult.droppedTools + ridingCleanup.droppedTools,
47660
48147
  deduplicatedTools: heuristicsResult.deduplicatedTools + ridingCleanup.deduplicatedTools,
@@ -47693,6 +48180,8 @@ async function runPipeline(args) {
47693
48180
  }
47694
48181
  logTransformTiming(args.sessionId, "applyHeuristicCleanup", tHeuristic, `droppedTools=${heuristicsResult.droppedTools} deduplicatedTools=${heuristicsResult.deduplicatedTools} droppedInjections=${heuristicsResult.droppedInjections} staleReduce=${heuristicsResult.droppedStaleReduceCalls} compressedTextTags=${heuristicsResult.compressedTextTags} mutatedTextTags=${heuristicsResult.mutatedTextTags}`);
47695
48182
  } catch (err) {
48183
+ if (err instanceof PiToolRemovalBatchError)
48184
+ throw err;
47696
48185
  sessionLog2(args.sessionId, `heuristic cleanup failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
47697
48186
  }
47698
48187
  }
@@ -47831,7 +48320,7 @@ async function runPipeline(args) {
47831
48320
  }
47832
48321
  autoReclaimTargetCount = syntheticPendingOps.length;
47833
48322
  if (syntheticPendingOps.length > 0) {
47834
- autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, newTargets, protectedTagNumbersForPass, undefined, [], syntheticPendingOps, editMarkerTagIds, (reduction) => droppedTokenReductions.push(reduction));
48323
+ autoReclaimDidMutate = applyToolRemovalGroup(() => applyPendingOperations(args.sessionId, args.db, newTargets, protectedTagNumbersForPass, undefined, [], syntheticPendingOps, editMarkerTagIds, (reduction) => droppedTokenReductions.push(reduction)));
47835
48324
  if (autoReclaimDidMutate) {
47836
48325
  droppedCount += syntheticPendingOps.length;
47837
48326
  autoReclaimDidMutateThisPass = true;
@@ -47852,10 +48341,7 @@ async function runPipeline(args) {
47852
48341
  noteImagePosition(message.info.id, tagNumber);
47853
48342
  }
47854
48343
  }
47855
- const imageToolTags = new Map(allTagsForPass.filter((tag) => tag.type === "tool").map((tag) => [
47856
- `${tag.toolOwnerMessageId ?? ""}\x00${tag.messageId}`,
47857
- tag.tagNumber
47858
- ]));
48344
+ const imageToolCoordinates = [];
47859
48345
  const imageToolOwners = new Map;
47860
48346
  for (let index = 0;index < workingMessages.length; index++) {
47861
48347
  const message = workingMessages[index];
@@ -47865,12 +48351,26 @@ async function runPipeline(args) {
47865
48351
  if (part.type !== "toolCall")
47866
48352
  continue;
47867
48353
  imageToolOwners.set(part.id, id ?? "");
47868
- noteImagePosition(id, imageToolTags.get(`${id ?? ""}\x00${part.id}`) ?? 0);
48354
+ imageToolCoordinates.push({ id, key: `${id ?? ""}\x00${part.id}` });
47869
48355
  }
47870
48356
  } else if (message.role === "toolResult") {
47871
- noteImagePosition(id, imageToolTags.get(`${imageToolOwners.get(message.toolCallId) ?? ""}\x00${message.toolCallId}`) ?? 0);
48357
+ imageToolCoordinates.push({
48358
+ id,
48359
+ key: `${imageToolOwners.get(message.toolCallId) ?? ""}\x00${message.toolCallId}`
48360
+ });
47872
48361
  }
47873
48362
  }
48363
+ const imageToolKeys = new Set(imageToolCoordinates.map(({ key }) => key));
48364
+ const imageToolTags = new Map;
48365
+ for (const tag of allTagsForPass) {
48366
+ if (tag.type !== "tool")
48367
+ continue;
48368
+ const key = `${tag.toolOwnerMessageId ?? ""}\x00${tag.messageId}`;
48369
+ if (imageToolKeys.has(key))
48370
+ imageToolTags.set(key, tag.tagNumber);
48371
+ }
48372
+ for (const { id, key } of imageToolCoordinates)
48373
+ noteImagePosition(id, imageToolTags.get(key) ?? 0);
47874
48374
  const protectedImageToolKeys = new Set(activeTags.filter((tag) => tag.type === "tool" && protectedToolTags.has(tag.tagNumber)).map((tag) => tag.toolOwnerMessageId ? `${tag.toolOwnerMessageId}\x00${tag.messageId}` : tag.messageId));
47875
48375
  const imageResult = stripPiProcessedImages({
47876
48376
  db: args.db,
@@ -48205,7 +48705,7 @@ async function runPipeline(args) {
48205
48705
  onAdopt: (message) => sessionLog2(args.sessionId, message)
48206
48706
  });
48207
48707
  protectionFloorResolution = resolveProtectionFloor();
48208
- const protectedTagNumbers = usesTokenProtection ? computeProtectionWindow(allTagsForPass, protectionFloorResolution.floor, activeCalibration.toolsRatio).protectedTagNumbers : newestActiveTagNumbersByCount(activeTags, args.protectedTags);
48708
+ const protectedTagNumbers = usesTokenProtection ? protectedPiPassTagNumbers(allTagsForPass, protectionFloorResolution.floor, activeCalibration.toolsRatio) : newestActiveTagNumbersByCount(activeTags, args.protectedTags);
48209
48709
  const channelPendingOps = shouldApplyPendingOps ? getPendingOps(args.db, args.sessionId) : shouldReadPendingOps ? pendingOps : getPendingOps(args.db, args.sessionId);
48210
48710
  const channelBaselineSnapshot = {
48211
48711
  tagCacheKey: fallbackCache.index,
@@ -52775,7 +53275,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
52775
53275
  return;
52776
53276
  }
52777
53277
  const emptyHistorian = empty.find((chain) => chain.owner === "historian");
52778
- const historianLine = historian ? `registered historian trigger (model=${historian.model}${historian.fallbackModels?.length ? `, fallbacks=${historian.fallbackModels.join(",")}` : ""}, executeThreshold=${formatExecuteThresholdForLog(historian.executeThresholdPercentage)})` : emptyHistorian ? `registered historian trigger: DISABLED (no configured model is registered in Pi: ${formatEmptyPiModelChain(emptyHistorian)})` : undefined;
53278
+ const historianLine = historian ? `registered historian trigger (model=${historian.model}${historian.fallbackModels?.length ? `, fallbacks=${historian.fallbackModels.map(formatPiModelForLog).join(",")}` : ""}, executeThreshold=${formatExecuteThresholdForLog(historian.executeThresholdPercentage)})` : emptyHistorian ? `registered historian trigger: DISABLED (no configured model is registered in Pi: ${formatEmptyPiModelChain(emptyHistorian)})` : undefined;
52779
53279
  if (historianLine && !loggedPiModelChainLines.has(historianLine)) {
52780
53280
  loggedPiModelChainLines.add(historianLine);
52781
53281
  info(historianLine);
@@ -52899,7 +53399,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
52899
53399
  registerPiCloneSessionTransitions(pi.on.bind(pi), {
52900
53400
  db,
52901
53401
  signalPendingMarker: signalPiDeferredCompactionMarkerDrain,
52902
- onInherited: (sessionId) => prewarmPiTagSnapshot(db, sessionId)
53402
+ onInherited: (sessionId) => prewarmPiTagSnapshot(db, sessionId, "pass")
52903
53403
  });
52904
53404
  pi.on("session_start", async (event, ctx) => {
52905
53405
  bindStaleBuildNotice(ctx, import.meta.url);
@@ -52921,7 +53421,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
52921
53421
  await handlePiCloneSessionStart(event, ctx, {
52922
53422
  db,
52923
53423
  signalPendingMarker: signalPiDeferredCompactionMarkerDrain,
52924
- onInherited: (sessionId) => prewarmPiTagSnapshot(db, sessionId)
53424
+ onInherited: (sessionId) => prewarmPiTagSnapshot(db, sessionId, "pass")
52925
53425
  });
52926
53426
  const sessionId = resolveSessionId(ctx);
52927
53427
  if (!piMarkerRehydrationLogged && pendingPiMarkerSessions.length > 0 && sessionId) {
@@ -52938,7 +53438,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
52938
53438
  });
52939
53439
  }
52940
53440
  if (sessionId)
52941
- prewarmPiTagSnapshot(db, sessionId);
53441
+ prewarmPiTagSnapshot(db, sessionId, "pass");
52942
53442
  });
52943
53443
  pi.on("agent_start", (_event, ctx) => {
52944
53444
  setEmbeddingSessionBusy2(ctx.sessionManager.getSessionId(), true);
@@ -53514,7 +54014,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
53514
54014
  try {
53515
54015
  const incomingSessionId = readSessionId(ctx);
53516
54016
  if (incomingSessionId && _event?.reason !== "fork")
53517
- prewarmPiTagSnapshot(db, incomingSessionId);
54017
+ prewarmPiTagSnapshot(db, incomingSessionId, "pass");
53518
54018
  if (!outgoingSessionId || outgoingSessionId === readSessionId(ctx))
53519
54019
  return;
53520
54020
  clearPiSystemPromptSession(outgoingSessionId);
@@ -53535,6 +54035,11 @@ function formatExecuteThresholdForLog(value) {
53535
54035
  const base = `${value.default}%`;
53536
54036
  return overrides.length > 0 ? `${base} (${overrides.join(", ")})` : base;
53537
54037
  }
54038
+ function formatPiModelForLog(entry) {
54039
+ if (typeof entry === "string")
54040
+ return entry;
54041
+ return `${entry.model}${entry.qualifier ? ` (thinking_level=${entry.qualifier})` : ""}`;
54042
+ }
53538
54043
  export {
53539
54044
  __test,
53540
54045
  canonicalPiModelKey,