@cortexkit/pi-magic-context 0.49.17 → 0.49.19

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
@@ -249,7 +249,7 @@ import {
249
249
  registerTodoStateLifecycle,
250
250
  syncCtxMemoryToolEnabled,
251
251
  registerMagicContextTools
252
- } from "./index-es03azap.js";
252
+ } from "./index-ek9zvs4f.js";
253
253
  import"./index-4knyh1kt.js";
254
254
  import {
255
255
  canonicalModelIdentity,
@@ -290,7 +290,7 @@ import {
290
290
  openCurrentDatabase,
291
291
  openDatabaseAsync,
292
292
  closeDatabase
293
- } from "./index-469ttgzv.js";
293
+ } from "./index-sqt2haap.js";
294
294
  import {
295
295
  pruneMissingProjectIdentities,
296
296
  setHomeProjectPermission,
@@ -415,6 +415,7 @@ import {
415
415
  computeRawRangeFingerprint,
416
416
  invalidateTrueRawTokenCache,
417
417
  stripSystemInjection,
418
+ isFilePart,
418
419
  hasUserAnswerMetadata,
419
420
  DreamTokenBudgetExceeded,
420
421
  TOKEN_BUDGET_FINALIZE_MESSAGE,
@@ -461,7 +462,7 @@ import {
461
462
  getRawSessionTagKeysThrough2,
462
463
  getLegacyProtectedTailStartOrdinal2,
463
464
  readSessionChunk2
464
- } from "./index-5k2mshvq.js";
465
+ } from "./index-wveb51es.js";
465
466
  import {
466
467
  UNKNOWN_FIT_RATIO,
467
468
  hasMeasuredDecisionCalibration,
@@ -548,7 +549,7 @@ import {
548
549
  getToolTagNumberByOwner2,
549
550
  getNullOwnerToolTag2,
550
551
  adoptNullOwnerToolTag2
551
- } from "./index-ej4eak9d.js";
552
+ } from "./index-rhprywn6.js";
552
553
  import {
553
554
  textMentionsRecentCommit,
554
555
  hasMeaningfulUserText2,
@@ -610,7 +611,7 @@ import {
610
611
  indexSingleMessage2,
611
612
  indexMessagesAfterOrdinal2,
612
613
  sweepOrphanedOpenCodeMessageIndexesCooperatively2
613
- } from "./index-8r2t8fv2.js";
614
+ } from "./index-ym6nh2gk.js";
614
615
  import {
615
616
  resolveOpenCodeDbPath,
616
617
  assertOpenCodeStoreGeneration,
@@ -687,7 +688,7 @@ import {
687
688
  expandWorkspaceIdentitySetWithAliases,
688
689
  sourceNameForMemory,
689
690
  computeWorkspaceEpochFingerprint
690
- } from "./index-gdjv1nnd.js";
691
+ } from "./index-msqrs4nf.js";
691
692
  import {
692
693
  configureContextDatabasePragmas2
693
694
  } from "./index-fapenpch.js";
@@ -737,7 +738,7 @@ import {
737
738
  normalizeVerificationFiles,
738
739
  indexCommitsForProject,
739
740
  embedUnembeddedCommits
740
- } from "./index-9j809q6f.js";
741
+ } from "./index-58mj0dzc.js";
741
742
  import {
742
743
  setEmbeddingSessionBusy2,
743
744
  isEmbeddingHostBusy2
@@ -794,10 +795,10 @@ import {
794
795
  drainPiTagSnapshotSession,
795
796
  assertPiTagSnapshotReady,
796
797
  ensurePiTagSnapshotReady
797
- } from "./index-dvbjsh98.js";
798
+ } from "./index-rc1dez8m.js";
798
799
  import"./index-f18ec69t.js";
799
800
  import"./index-1cvyaw9a.js";
800
- import"./index-z7kbck29.js";
801
+ import"./index-dtp1efvf.js";
801
802
  import {
802
803
  __toESM
803
804
  } from "./index-22jkk6wg.js";
@@ -3519,7 +3520,7 @@ function startHostStallProfilerSwitch() {
3519
3520
  // package.json
3520
3521
  var package_default = {
3521
3522
  name: "@cortexkit/pi-magic-context",
3522
- version: "0.49.17",
3523
+ version: "0.49.19",
3523
3524
  type: "module",
3524
3525
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3525
3526
  main: "dist/index.js",
@@ -3584,8 +3585,13 @@ var package_default = {
3584
3585
  "@types/bun": "^1.3.10",
3585
3586
  "@types/node": "^22.20.0",
3586
3587
  "omp-coding-agent-1812": "npm:@oh-my-pi/pi-coding-agent@18.12.3",
3588
+ "omp-pi-ai-1889": "npm:@oh-my-pi/pi-ai@18.8.9",
3589
+ "omp-pi-ai-1811": "npm:@oh-my-pi/pi-ai@18.11.3",
3590
+ "omp-pi-ai-1812": "npm:@oh-my-pi/pi-ai@18.12.3",
3587
3591
  "pi-agent-core-087": "npm:@earendil-works/pi-agent-core@0.87.1",
3588
3592
  "pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
3593
+ "pi-ai-087": "npm:@earendil-works/pi-ai@0.87.1",
3594
+ "pi-ai-130": "npm:@earendil-works/pi-ai@1.3.0",
3589
3595
  "pi-coding-agent-086": "npm:@earendil-works/pi-coding-agent@0.86.0",
3590
3596
  "pi-coding-agent-087": "npm:@earendil-works/pi-coding-agent@0.87.1",
3591
3597
  "pi-coding-agent-130": "npm:@earendil-works/pi-coding-agent@1.3.0",
@@ -4838,9 +4844,33 @@ var promptFailureDetails = new WeakMap;
4838
4844
  function isHostTimeoutError(error) {
4839
4845
  return error !== null && typeof error === "object" && error.name === "TimeoutError";
4840
4846
  }
4847
+
4848
+ class ModelProducedNoOutputError extends Error {
4849
+ waitedMs;
4850
+ constructor(waitedMs) {
4851
+ super(`prompt timed out after ${waitedMs}ms with no model output`);
4852
+ this.waitedMs = waitedMs;
4853
+ this.name = "ModelProducedNoOutputError";
4854
+ }
4855
+ }
4856
+ var modelActivityBySignal = new WeakMap;
4857
+ function noteModelActivityMonitored(signal) {
4858
+ const activity = signal ? modelActivityBySignal.get(signal) : undefined;
4859
+ if (activity)
4860
+ activity.monitored = true;
4861
+ }
4862
+ function noteModelOutputReceived(signal) {
4863
+ const activity = signal ? modelActivityBySignal.get(signal) : undefined;
4864
+ if (activity) {
4865
+ activity.monitored = true;
4866
+ activity.received = true;
4867
+ }
4868
+ }
4841
4869
  function isPromptTimeoutError(error) {
4842
4870
  if (isHostTimeoutError(error))
4843
4871
  return true;
4872
+ if (error instanceof ModelProducedNoOutputError)
4873
+ return true;
4844
4874
  return error instanceof Error && /^prompt timed out after \d+ms$/.test(error.message);
4845
4875
  }
4846
4876
  function getPromptFailureDetail(error) {
@@ -4918,12 +4948,22 @@ function raceWithSignal(work, signal) {
4918
4948
  work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
4919
4949
  });
4920
4950
  }
4921
- async function promptWithTimeout(client, args, timeoutMs, signal, transport) {
4951
+ async function promptWithTimeout(client, args, timeoutMs, signal, transport, firstOutputTimeoutMs) {
4922
4952
  if (signal?.aborted) {
4923
4953
  throw new Error(externalAbortMessage(signal));
4924
4954
  }
4925
4955
  const controller = new AbortController;
4926
4956
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
4957
+ const activity = { monitored: false, received: false };
4958
+ modelActivityBySignal.set(controller.signal, activity);
4959
+ let silent = false;
4960
+ const firstOutputTimer = firstOutputTimeoutMs !== undefined && firstOutputTimeoutMs < timeoutMs ? setTimeout(() => {
4961
+ if (!activity.monitored || activity.received)
4962
+ return;
4963
+ silent = true;
4964
+ controller.abort();
4965
+ }, firstOutputTimeoutMs) : undefined;
4966
+ const timeoutError = () => silent && firstOutputTimeoutMs !== undefined ? new ModelProducedNoOutputError(firstOutputTimeoutMs) : new Error(`prompt timed out after ${timeoutMs}ms`);
4927
4967
  const onExternalAbort = () => controller.abort();
4928
4968
  signal?.addEventListener("abort", onExternalAbort);
4929
4969
  try {
@@ -4946,7 +4986,7 @@ async function promptWithTimeout(client, args, timeoutMs, signal, transport) {
4946
4986
  if (!transport || transport.childSessionId) {
4947
4987
  await abortChildRun(client, transport?.childSessionId ?? args.path.id);
4948
4988
  }
4949
- throw new Error(`prompt timed out after ${timeoutMs}ms`);
4989
+ throw timeoutError();
4950
4990
  }
4951
4991
  if (isHostTimeoutError(error)) {
4952
4992
  if (!transport || transport.childSessionId) {
@@ -4956,13 +4996,15 @@ async function promptWithTimeout(client, args, timeoutMs, signal, transport) {
4956
4996
  throw error;
4957
4997
  } finally {
4958
4998
  clearTimeout(timeout);
4999
+ if (firstOutputTimer)
5000
+ clearTimeout(firstOutputTimer);
4959
5001
  signal?.removeEventListener("abort", onExternalAbort);
4960
5002
  }
4961
5003
  if (signal?.aborted || controller.signal.aborted) {
4962
5004
  if (!transport || transport.childSessionId) {
4963
5005
  await abortChildRun(client, transport?.childSessionId ?? args.path.id);
4964
5006
  }
4965
- throw new Error(signal?.aborted ? externalAbortMessage(signal) : `prompt timed out after ${timeoutMs}ms`);
5007
+ throw signal?.aborted ? new Error(externalAbortMessage(signal)) : timeoutError();
4966
5008
  }
4967
5009
  }
4968
5010
  async function abortChildRun(client, sessionId) {
@@ -4980,6 +5022,8 @@ async function abortChildRun(client, sessionId) {
4980
5022
  function isNonRetryable(error, externalSignal) {
4981
5023
  if (externalSignal?.aborted || error instanceof HiddenCompletionRefusal && error.terminal || error instanceof HiddenAgentStepLimit || error instanceof DreamTokenBudgetExceeded)
4982
5024
  return true;
5025
+ if (error instanceof ModelProducedNoOutputError)
5026
+ return false;
4983
5027
  if (error instanceof Error) {
4984
5028
  if (error.name === "AbortError")
4985
5029
  return true;
@@ -5011,7 +5055,7 @@ function classifyPromptFailure(error, phase, externalSignal) {
5011
5055
  if (externalSignal?.aborted || message === "prompt aborted by external signal") {
5012
5056
  return "child_aborted";
5013
5057
  }
5014
- if (/^prompt timed out after \d+ms$/.test(message) || isHostTimeoutError(error)) {
5058
+ if (error instanceof ModelProducedNoOutputError || /^prompt timed out after \d+ms$/.test(message) || isHostTimeoutError(error)) {
5015
5059
  return "provider_timeout";
5016
5060
  }
5017
5061
  if (phase === "validation") {
@@ -5046,11 +5090,11 @@ function throwWithPromptFailure(legacyError, failedAttempts, args, timeoutMs, tr
5046
5090
  });
5047
5091
  throw error;
5048
5092
  }
5049
- async function attemptOnce(client, args, timeoutMs, signal, callContext, label, transport, allowModelSuggestions = true) {
5093
+ async function attemptOnce(client, args, timeoutMs, signal, callContext, label, transport, allowModelSuggestions = true, firstOutputTimeoutMs) {
5050
5094
  const originalBody = { ...args.body };
5051
5095
  const attemptArgs = copyPromptArgs(args, originalBody);
5052
5096
  try {
5053
- await promptWithTimeout(client, attemptArgs, timeoutMs, signal, transport);
5097
+ await promptWithTimeout(client, attemptArgs, timeoutMs, signal, transport, firstOutputTimeoutMs);
5054
5098
  return;
5055
5099
  } catch (error) {
5056
5100
  if (isNonRetryable(error, signal) || !allowModelSuggestions)
@@ -5069,9 +5113,30 @@ async function attemptOnce(client, args, timeoutMs, signal, callContext, label,
5069
5113
  providerID: suggestion.providerID,
5070
5114
  modelID: suggestion.suggestion
5071
5115
  }
5072
- }), timeoutMs, signal, transport);
5116
+ }), timeoutMs, signal, transport, firstOutputTimeoutMs);
5073
5117
  }
5074
5118
  }
5119
+ function createChainClock(options, timeoutMs) {
5120
+ const fallbacks = options.fallbackModels ?? [];
5121
+ const hasValidFallbackFrom = (index) => fallbacks.slice(index).some((fallback) => {
5122
+ const entry = toModelEntry(fallback);
5123
+ return entry ? parseProviderModel(entry.model) !== null : false;
5124
+ });
5125
+ let silentSpentMs = 0;
5126
+ return {
5127
+ budget(nextFallbackIndex) {
5128
+ const attemptTimeoutMs = Math.max(1, timeoutMs - silentSpentMs);
5129
+ if (options.firstOutputTimeoutMs === undefined || !hasValidFallbackFrom(nextFallbackIndex))
5130
+ return { timeoutMs: attemptTimeoutMs };
5131
+ const bound = Math.min(options.firstOutputTimeoutMs, Math.floor(attemptTimeoutMs / 2));
5132
+ return bound > 0 ? { timeoutMs: attemptTimeoutMs, firstOutputTimeoutMs: bound } : { timeoutMs: attemptTimeoutMs };
5133
+ },
5134
+ settle(error, startedAt) {
5135
+ if (error instanceof ModelProducedNoOutputError)
5136
+ silentSpentMs += Date.now() - startedAt;
5137
+ }
5138
+ };
5139
+ }
5075
5140
  async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
5076
5141
  const timeoutMs = options.timeoutMs ?? 300000;
5077
5142
  const callContext = options.callContext ?? "subagent";
@@ -5080,11 +5145,15 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
5080
5145
  const baseArgs = copyPromptArgs(args, baseBody);
5081
5146
  const explicitPrimaryLabel = baseBody.model?.providerID && baseBody.model.modelID ? `${baseBody.model.providerID}/${baseBody.model.modelID}` : "primary";
5082
5147
  let lastError = null;
5148
+ const clock = createChainClock(options, timeoutMs);
5149
+ const primaryStartedAt = Date.now();
5083
5150
  try {
5084
- await attemptOnce(client, baseArgs, timeoutMs, options.signal, callContext, explicitPrimaryLabel, options.transport, options.allowModelSuggestions);
5151
+ const budget = clock.budget(0);
5152
+ await attemptOnce(client, baseArgs, budget.timeoutMs, options.signal, callContext, explicitPrimaryLabel, options.transport, options.allowModelSuggestions, budget.firstOutputTimeoutMs);
5085
5153
  return;
5086
5154
  } catch (error) {
5087
5155
  lastError = error;
5156
+ clock.settle(error, primaryStartedAt);
5088
5157
  if (isNonRetryable(error, options.signal))
5089
5158
  throw error;
5090
5159
  if (fallbacks.length === 0) {
@@ -5106,12 +5175,15 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
5106
5175
  model: parsed,
5107
5176
  ...fallback?.qualifier ? { variant: fallback.qualifier } : {}
5108
5177
  });
5178
+ const attemptStartedAt = Date.now();
5109
5179
  try {
5110
- await attemptOnce(client, attemptArgs, timeoutMs, options.signal, callContext, label, options.transport, options.allowModelSuggestions);
5180
+ const budget = clock.budget(i + 1);
5181
+ await attemptOnce(client, attemptArgs, budget.timeoutMs, options.signal, callContext, label, options.transport, options.allowModelSuggestions, budget.firstOutputTimeoutMs);
5111
5182
  log2(`[${callContext}] fallback succeeded with ${label} (attempt ${i + 2}/${fallbacks.length + 1})`);
5112
5183
  return;
5113
5184
  } catch (error) {
5114
5185
  lastError = error;
5186
+ clock.settle(error, attemptStartedAt);
5115
5187
  if (isNonRetryable(error, options.signal))
5116
5188
  throw error;
5117
5189
  const remaining = fallbacks.length - i - 1;
@@ -5123,9 +5195,9 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
5123
5195
  log2(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks.map((fallback) => toModelEntry(fallback)?.model ?? String(fallback))].join(", ")}; last error: ${shortErr(lastError)}`);
5124
5196
  throw lastError ?? new Error("All fallback models failed");
5125
5197
  }
5126
- async function attemptAndValidate(client, args, timeoutMs, signal, callContext, attempt, options) {
5198
+ async function attemptAndValidate(client, args, timeoutMs, signal, callContext, attempt, options, firstOutputTimeoutMs) {
5127
5199
  try {
5128
- await attemptOnce(client, args, timeoutMs, signal, callContext, attempt.label, options.transport, options.allowModelSuggestions);
5200
+ await attemptOnce(client, args, timeoutMs, signal, callContext, attempt.label, options.transport, options.allowModelSuggestions, firstOutputTimeoutMs);
5129
5201
  } catch (error) {
5130
5202
  throw {
5131
5203
  error,
@@ -5187,6 +5259,8 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
5187
5259
  let firstError = null;
5188
5260
  let lastError = null;
5189
5261
  const cooledPrimary = primaryQuotaFailure(explicitPrimaryLabel);
5262
+ const clock = createChainClock(options, timeoutMs);
5263
+ const primaryStartedAt = Date.now();
5190
5264
  try {
5191
5265
  if (cooledPrimary)
5192
5266
  throw {
@@ -5201,16 +5275,18 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
5201
5275
  skipped: true
5202
5276
  }
5203
5277
  };
5204
- return await attemptAndValidate(client, baseArgs, timeoutMs, options.signal, callContext, {
5278
+ const budget = clock.budget(0);
5279
+ return await attemptAndValidate(client, baseArgs, budget.timeoutMs, options.signal, callContext, {
5205
5280
  label: explicitPrimaryLabel,
5206
5281
  attemptIndex: 0,
5207
5282
  isFallback: false,
5208
5283
  totalAttempts,
5209
5284
  model: baseBody.model
5210
- }, options);
5285
+ }, options, budget.firstOutputTimeoutMs);
5211
5286
  } catch (caught) {
5212
5287
  const failure = caught;
5213
5288
  failedAttempts.push(failure);
5289
+ clock.settle(failure.error, primaryStartedAt);
5214
5290
  firstError = failure.error;
5215
5291
  lastError = failure.error;
5216
5292
  if (failure.error instanceof DreamerProviderOutputFailureError && failure.error.quotaResetAt !== undefined)
@@ -5248,13 +5324,16 @@ async function promptSyncWithValidatedOutputRetry(client, args, options) {
5248
5324
  totalAttempts,
5249
5325
  model: parsed
5250
5326
  };
5327
+ const attemptStartedAt = Date.now();
5251
5328
  try {
5252
- const result = await attemptAndValidate(client, attemptArgs, timeoutMs, options.signal, callContext, attempt, options);
5329
+ const budget = clock.budget(i + 1);
5330
+ const result = await attemptAndValidate(client, attemptArgs, budget.timeoutMs, options.signal, callContext, attempt, options, budget.firstOutputTimeoutMs);
5253
5331
  log2(`[${callContext}] fallback succeeded with ${label} (attempt ${i + 2}/${fallbacks.length + 1})`);
5254
5332
  return result;
5255
5333
  } catch (caught) {
5256
5334
  const failure = caught;
5257
5335
  failedAttempts.push(failure);
5336
+ clock.settle(failure.error, attemptStartedAt);
5258
5337
  lastError = failure.error;
5259
5338
  if (isNonRetryable(failure.error, options.signal)) {
5260
5339
  throwWithPromptFailure(failure.error, failedAttempts, args, timeoutMs, options.transport);
@@ -5470,6 +5549,24 @@ function isTerminalAssistant(message) {
5470
5549
  const info = infoOf(message);
5471
5550
  return isSettledAssistant(message) && info.finish !== "tool-calls" && info.finish !== "tool_use" && !(message && typeof message === "object" && Array.isArray(message.parts) && message.parts.some((part) => part.type === "tool"));
5472
5551
  }
5552
+ function showsModelOutput(message) {
5553
+ if (infoOf(message).role !== "assistant")
5554
+ return false;
5555
+ const tokens = sumTokensFromChildMessages([message]);
5556
+ if (tokens.input + tokens.output + tokens.cacheRead + tokens.cacheWrite > 0)
5557
+ return true;
5558
+ const parts = message?.parts;
5559
+ if (!Array.isArray(parts))
5560
+ return false;
5561
+ return parts.some((part) => {
5562
+ if (!part || typeof part !== "object")
5563
+ return false;
5564
+ const { type, text } = part;
5565
+ if (type === "tool")
5566
+ return true;
5567
+ return (type === "text" || type === "reasoning") && typeof text === "string" && text.trim().length > 0;
5568
+ });
5569
+ }
5473
5570
  function unwrapData(response) {
5474
5571
  if (response && typeof response === "object" && "data" in response) {
5475
5572
  return response.data;
@@ -5567,6 +5664,8 @@ async function promptAsyncAndWaitForIdle(client, request, options = {}) {
5567
5664
  }
5568
5665
  let sentAt = Date.now();
5569
5666
  let sawBusy = false;
5667
+ noteModelActivityMonitored(signal);
5668
+ let sawOutput = false;
5570
5669
  for (;; ) {
5571
5670
  await sleep(pollIntervalMs, signal);
5572
5671
  const hostError = activeSessionErrors.get(sessionId);
@@ -5581,6 +5680,13 @@ async function promptAsyncAndWaitForIdle(client, request, options = {}) {
5581
5680
  }
5582
5681
  const status = await readStatus(session, sessionId, dir, signal);
5583
5682
  const messages = await readMessages(session, sessionId, dir, signal);
5683
+ if (!sawOutput && messages.some((message) => {
5684
+ const id = messageId(message);
5685
+ return id !== null && !initialBaseline.has(id) && showsModelOutput(message);
5686
+ })) {
5687
+ sawOutput = true;
5688
+ noteModelOutputReceived(signal);
5689
+ }
5584
5690
  if (budget) {
5585
5691
  const latest = messages.at(-1);
5586
5692
  const latestId = messageId(latest);
@@ -10475,6 +10581,7 @@ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
10475
10581
  }
10476
10582
 
10477
10583
  // ../plugin/src/features/magic-context/dreamer/hidden-single-shot.ts
10584
+ var DREAMER_FIRST_OUTPUT_TIMEOUT_MS = 90000;
10478
10585
  async function runHiddenSingleShotPrompt(args) {
10479
10586
  const system = withContentLanguageDirective(args.system, args.language);
10480
10587
  const opening = args.executor.open({
@@ -10516,6 +10623,7 @@ async function runHiddenSingleShotPrompt(args) {
10516
10623
  }, {
10517
10624
  transport: Object.assign((request) => args.executor.attempt(handle, request), { childSessionId: handle.childSessionId }),
10518
10625
  timeoutMs: args.timeoutMs,
10626
+ ...args.firstOutputTimeoutMs !== undefined ? { firstOutputTimeoutMs: args.firstOutputTimeoutMs } : {},
10519
10627
  ...args.signal ? { signal: args.signal } : {},
10520
10628
  fallbackModels: args.fallbackModels,
10521
10629
  callContext: args.callContext,
@@ -11369,6 +11477,7 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
11369
11477
  }, {
11370
11478
  transport: Object.assign((request) => executor.attempt(opened, request), { childSessionId: opened.childSessionId }),
11371
11479
  timeoutMs: sliceMs,
11480
+ firstOutputTimeoutMs: args.firstOutputTimeoutMs ?? DREAMER_FIRST_OUTPUT_TIMEOUT_MS,
11372
11481
  signal,
11373
11482
  fallbackModels: args.fallbackModels,
11374
11483
  callContext: "dreamer:classify-memories",
@@ -14596,6 +14705,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
14596
14705
  model: args.model,
14597
14706
  fallbackModels: args.fallbackModels,
14598
14707
  timeoutMs: sliceMs,
14708
+ firstOutputTimeoutMs: args.firstOutputTimeoutMs ?? DREAMER_FIRST_OUTPUT_TIMEOUT_MS,
14599
14709
  signal,
14600
14710
  onOpened: () => {
14601
14711
  stage = "prompt";
@@ -14650,6 +14760,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
14650
14760
  onBudgetUpdate
14651
14761
  }),
14652
14762
  timeoutMs: sliceMs,
14763
+ firstOutputTimeoutMs: args.firstOutputTimeoutMs ?? DREAMER_FIRST_OUTPUT_TIMEOUT_MS,
14653
14764
  signal,
14654
14765
  fallbackModels: args.fallbackModels,
14655
14766
  callContext: "dreamer:map-memories",
@@ -16700,6 +16811,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
16700
16811
  fallbackModels: args.fallbackModels,
16701
16812
  language: args.language,
16702
16813
  timeoutMs: sliceMs,
16814
+ firstOutputTimeoutMs: args.firstOutputTimeoutMs ?? DREAMER_FIRST_OUTPUT_TIMEOUT_MS,
16703
16815
  signal: batchSignal,
16704
16816
  onFailureOutput: (completion) => {
16705
16817
  failedCompletion = completion;
@@ -16757,6 +16869,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
16757
16869
  onBudgetUpdate
16758
16870
  }),
16759
16871
  timeoutMs: sliceMs,
16872
+ firstOutputTimeoutMs: args.firstOutputTimeoutMs ?? DREAMER_FIRST_OUTPUT_TIMEOUT_MS,
16760
16873
  signal: batchSignal,
16761
16874
  fallbackModels: args.fallbackModels,
16762
16875
  callContext: "dreamer:verify",
@@ -24620,6 +24733,12 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
24620
24733
  function hasReclaimRide(signals) {
24621
24734
  return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true;
24622
24735
  }
24736
+ function prefixMutationPermitted(gate) {
24737
+ return !gate.signedThinkingHold || gate.firstRender || gate.idleExpiry || gate.emergency;
24738
+ }
24739
+ function reclaimRidePermitted(signals, gate) {
24740
+ return prefixMutationPermitted(gate) && hasReclaimRide(signals);
24741
+ }
24623
24742
  var RECLAIM_RIDE_NAMES = [
24624
24743
  "hardFold",
24625
24744
  "force",
@@ -24858,6 +24977,31 @@ function rearmChannel2AfterMeasuredCollapse(input) {
24858
24977
  return casChannel2NudgeState(input.db, input.sessionId, "delivered", "");
24859
24978
  }
24860
24979
 
24980
+ // ../plugin/src/hooks/magic-context/file-token-coverage.ts
24981
+ function omitIncompleteFileTokenTotals(db, sessionId, messages, totals) {
24982
+ const filesByMessage = new Map;
24983
+ for (const message of messages) {
24984
+ const count = message.parts.filter(isFilePart).length;
24985
+ if (count > 0 && totals.has(message.id))
24986
+ filesByMessage.set(message.id, count);
24987
+ }
24988
+ if (filesByMessage.size === 0)
24989
+ return totals;
24990
+ const rows = db.prepare(`
24991
+ SELECT o.value AS owner, COUNT(t.id) AS count
24992
+ FROM json_each(?) o LEFT JOIN tags t
24993
+ ON t.session_id = ? AND t.type = 'file'
24994
+ AND t.message_id >= o.value || ':file'
24995
+ AND t.message_id < o.value || ':file;'
24996
+ GROUP BY o.value
24997
+ `).all(JSON.stringify([...filesByMessage.keys()]), sessionId);
24998
+ for (const row of rows) {
24999
+ if (row.count < (filesByMessage.get(row.owner) ?? 0))
25000
+ totals.delete(row.owner);
25001
+ }
25002
+ return totals;
25003
+ }
25004
+
24861
25005
  // ../plugin/src/hooks/magic-context/protected-tail-boundary.ts
24862
25006
  function describeBoundaryDiagnostics(snapshot) {
24863
25007
  return `boundaryDiagnostics=${JSON.stringify(snapshot.diagnostics ?? { unavailable: true, boundaryReason: snapshot.boundaryReason })}`;
@@ -25082,7 +25226,7 @@ function resolveProtectedTailBoundary(ctx) {
25082
25226
  const offset = Math.max(1, ctx.lastCompartmentEndOrdinal + 1);
25083
25227
  const absoluteMessageCount = getCachedAbsoluteMessageCount2(ctx.sessionId) ?? getRawSessionMessageOrdinalCount2(ctx.sessionId);
25084
25228
  const messages = readRawSessionMessageRange2(ctx.sessionId, Math.max(1, offset - 1), absoluteMessageCount);
25085
- const storedTotals = ctx.storedTokenTotalsForMessages?.(messages.map((m) => m.id)) ?? ctx.storedTokenTotals;
25229
+ const storedTotals = ctx.storedTokenTotalsForMessages?.(messages.map((m) => m.id), messages) ?? ctx.storedTokenTotals;
25086
25230
  const index = buildTrueRawTokenIndex(ctx.sessionId, messages, {
25087
25231
  providerShapeVersion: ctx.providerShapeVersion,
25088
25232
  cacheNamespace: ctx.cacheNamespace,
@@ -25325,9 +25469,10 @@ function resolveBoundaryContext(args) {
25325
25469
  migrationFloorActive = seedResult.seeded;
25326
25470
  }
25327
25471
  const calibration = sessionDecisionCalibration(args.db, args.sessionId);
25328
- const storedTokenTotalsForMessages = (messageIds) => {
25472
+ const storedTokenTotalsForMessages = (messageIds, messages = []) => {
25329
25473
  try {
25330
- return getAllStatusTagTokenTotalsFlat2(args.db, args.sessionId, args.taggerFloor ?? 0, calibration, messageIds).totals;
25474
+ const totals = getAllStatusTagTokenTotalsFlat2(args.db, args.sessionId, args.taggerFloor ?? 0, calibration, messageIds).totals;
25475
+ return omitIncompleteFileTokenTotals(args.db, args.sessionId, messages, totals);
25331
25476
  } catch (error) {
25332
25477
  sessionLog2(args.sessionId, "protected-tail stored-token map unavailable (live fallback):", error);
25333
25478
  return;
@@ -25362,7 +25507,7 @@ function resolveWrapupProtectedTailBoundary(args) {
25362
25507
  const offset = Math.max(1, ctx.lastCompartmentEndOrdinal + 1);
25363
25508
  const absoluteMessageCount = getCachedAbsoluteMessageCount2(ctx.sessionId) ?? getRawSessionMessageOrdinalCount2(ctx.sessionId);
25364
25509
  const messages = readRawSessionMessageRange2(ctx.sessionId, Math.max(1, offset - 1), absoluteMessageCount);
25365
- const storedTotals = ctx.storedTokenTotalsForMessages?.(messages.map((m) => m.id)) ?? ctx.storedTokenTotals;
25510
+ const storedTotals = ctx.storedTokenTotalsForMessages?.(messages.map((m) => m.id), messages) ?? ctx.storedTokenTotals;
25366
25511
  const index = buildTrueRawTokenIndex(ctx.sessionId, messages, {
25367
25512
  providerShapeVersion: ctx.providerShapeVersion,
25368
25513
  cacheNamespace: ctx.cacheNamespace,
@@ -25860,8 +26005,9 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
25860
26005
  const canClearReasoning = reasoningProjection?.canClearReasoning ?? modelAcceptsEmptyContent(reasoningProjection?.providerID);
25861
26006
  const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession2(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff, eligiblePendingDropTagIds);
25862
26007
  const relativePostDropTarget = executeThresholdPercentage * POST_DROP_TARGET_RATIO;
26008
+ const ridePermitted = reclaimRide !== undefined && (reclaimRide.permission ? reclaimRidePermitted(reclaimRide, reclaimRide.permission) : hasReclaimRide(reclaimRide));
25863
26009
  const rideLabel = reclaimRide ? reclaimRideLabel(reclaimRide) : "ride=none";
25864
- const dropsCanLand = reclaimRide !== undefined && hasReclaimRide(reclaimRide);
26010
+ const dropsCanLand = ridePermitted;
25865
26011
  const forceMaterializationPercentage = escalationBands(executeThresholdPercentage).forceMaterializationPercentage;
25866
26012
  if (usage.percentage >= forceMaterializationPercentage) {
25867
26013
  if (dropsCanLand && projectedPostDropPercentage !== null && projectedPostDropPercentage <= relativePostDropTarget) {
@@ -26355,6 +26501,101 @@ function opencodeReasoningBudgetStatus(messages, budget, prefixBound, proseRatio
26355
26501
  };
26356
26502
  }
26357
26503
 
26504
+ // ../plugin/src/hooks/magic-context/signed-thinking-hold.ts
26505
+ var HEAVY_REASONING_TOKENS = 1500;
26506
+ var HEAVY_REASONING_WINDOW_STEPS = 15;
26507
+ var HOLD_CAP_POINTS = 10;
26508
+ var REASONING_TYPES = new Set(["reasoning", "thinking"]);
26509
+ function role2(message) {
26510
+ if (!isRecord(message))
26511
+ return;
26512
+ return isRecord(message.info) ? message.info.role : message.role;
26513
+ }
26514
+ function parts(message) {
26515
+ if (!isRecord(message))
26516
+ return [];
26517
+ if (Array.isArray(message.parts))
26518
+ return message.parts;
26519
+ return Array.isArray(message.content) ? message.content : [];
26520
+ }
26521
+ function recordedReasoningTokens(message) {
26522
+ if (!isRecord(message))
26523
+ return;
26524
+ const info = isRecord(message.info) ? message.info : undefined;
26525
+ const candidates = [];
26526
+ if (info && isRecord(info.tokens))
26527
+ candidates.push(info.tokens.reasoning);
26528
+ if (isRecord(message.usage)) {
26529
+ candidates.push(message.usage.reasoning, message.usage.reasoningTokens);
26530
+ }
26531
+ for (const value of candidates) {
26532
+ if (typeof value === "number" && Number.isFinite(value) && value > 0)
26533
+ return value;
26534
+ }
26535
+ return;
26536
+ }
26537
+ function stepReasoningTokens(message, estimateTextTokens) {
26538
+ let text = "";
26539
+ let opaque = false;
26540
+ for (const part of parts(message)) {
26541
+ if (!isRecord(part))
26542
+ continue;
26543
+ const type = String(part.type ?? part.kind);
26544
+ if (type === "redacted_thinking" || part.redacted === true) {
26545
+ opaque = true;
26546
+ continue;
26547
+ }
26548
+ if (!REASONING_TYPES.has(type))
26549
+ continue;
26550
+ const body = typeof part.thinking === "string" ? part.thinking : typeof part.text === "string" ? part.text : "";
26551
+ if (body.length > 0)
26552
+ text += body;
26553
+ else
26554
+ opaque = true;
26555
+ }
26556
+ if (!text && !opaque)
26557
+ return 0;
26558
+ return reasoningStepCost(recordedReasoningTokens(message), text ? estimateTextTokens(text) : 0, opaque);
26559
+ }
26560
+ function decideSignedThinkingHold(args) {
26561
+ const capPercentage = args.executeThresholdPercentage + HOLD_CAP_POINTS;
26562
+ let heavyStepsBack = null;
26563
+ let heavyStepTokens = 0;
26564
+ const start = latestAssistantTurnStart(args.messages);
26565
+ let stepsBack = 0;
26566
+ for (let index = args.messages.length - 1;index >= start; index--) {
26567
+ const message = args.messages[index];
26568
+ if (role2(message) !== "assistant" || parts(message).length === 0)
26569
+ continue;
26570
+ stepsBack++;
26571
+ if (stepsBack > HEAVY_REASONING_WINDOW_STEPS)
26572
+ break;
26573
+ const tokens = stepReasoningTokens(message, args.estimateTextTokens);
26574
+ if (tokens > HEAVY_REASONING_TOKENS) {
26575
+ heavyStepsBack = stepsBack;
26576
+ heavyStepTokens = tokens;
26577
+ break;
26578
+ }
26579
+ }
26580
+ if (heavyStepsBack === null)
26581
+ return {
26582
+ held: false,
26583
+ reason: "no_recent_heavy_reasoning",
26584
+ heavyStepsBack,
26585
+ heavyStepTokens,
26586
+ capPercentage
26587
+ };
26588
+ if (!(args.usagePercentage < capPercentage))
26589
+ return { held: false, reason: "above_cap", heavyStepsBack, heavyStepTokens, capPercentage };
26590
+ return {
26591
+ held: true,
26592
+ reason: "heavy_reasoning",
26593
+ heavyStepsBack,
26594
+ heavyStepTokens,
26595
+ capPercentage
26596
+ };
26597
+ }
26598
+
26358
26599
  // ../plugin/src/hooks/magic-context/strict-thinking-prefix.ts
26359
26600
  function servedPrefixMatches(args) {
26360
26601
  const heads = args.messages?.slice(0, 2);
@@ -35135,10 +35376,50 @@ function piHasManagedSignature(payload, signature) {
35135
35376
  return false;
35136
35377
  }
35137
35378
 
35379
+ // src/pi-dispatch-tool-pairing.ts
35380
+ var RESPONSES_APIS = new Set([
35381
+ "openai-responses",
35382
+ "openai-codex-responses",
35383
+ "azure-openai-responses"
35384
+ ]);
35385
+ function object4(value) {
35386
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
35387
+ }
35388
+ function piResponsesCallComponent(id) {
35389
+ const pipe = id.indexOf("|");
35390
+ return pipe <= 0 ? id : id.slice(0, pipe);
35391
+ }
35392
+ function piToolCallPairing(messages) {
35393
+ const responsesComponents = new Set;
35394
+ const opaqueCompositeIds = new Set;
35395
+ for (const value of messages) {
35396
+ const message = object4(value);
35397
+ if (message?.role !== "assistant" || !Array.isArray(message.content))
35398
+ continue;
35399
+ const responses = RESPONSES_APIS.has(String(message.api));
35400
+ for (const part of message.content) {
35401
+ const block = object4(part);
35402
+ if (block?.type !== "toolCall" || typeof block.id !== "string")
35403
+ continue;
35404
+ if (responses)
35405
+ responsesComponents.add(piResponsesCallComponent(block.id));
35406
+ else if (block.id.includes("|"))
35407
+ opaqueCompositeIds.add(block.id);
35408
+ }
35409
+ }
35410
+ return (id) => {
35411
+ const pipe = id.indexOf("|");
35412
+ if (pipe <= 0 || opaqueCompositeIds.has(id))
35413
+ return id;
35414
+ const prefix = id.slice(0, pipe);
35415
+ return responsesComponents.has(prefix) ? prefix : id;
35416
+ };
35417
+ }
35418
+
35138
35419
  // src/pi-dispatch-chat-history.ts
35139
35420
  var MAX_EXACT_UNITS = 32 * 1024 * 1024;
35140
35421
  var IMAGE_CAPTION = "Attached image(s) from tool result:";
35141
- function object4(value) {
35422
+ function object5(value) {
35142
35423
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
35143
35424
  }
35144
35425
  function omitsAssistant(message, model, compat) {
@@ -35147,7 +35428,7 @@ function omitsAssistant(message, model, compat) {
35147
35428
  let thinking = false;
35148
35429
  let hasTextBlock = false;
35149
35430
  for (const value of message.content) {
35150
- const block = object4(value);
35431
+ const block = object5(value);
35151
35432
  if (!block)
35152
35433
  return false;
35153
35434
  if (block.type === "text") {
@@ -35172,23 +35453,24 @@ function omitsAssistant(message, model, compat) {
35172
35453
  function piChatHistoryPlan(messages, model) {
35173
35454
  if (model?.api !== "openai-completions")
35174
35455
  return;
35175
- const compat = object4(model.compat) ?? {};
35456
+ const compat = object5(model.compat) ?? {};
35457
+ const pairingId = piToolCallPairing(messages);
35176
35458
  const calls = new Set;
35177
35459
  for (const value of messages) {
35178
- const message = object4(value);
35460
+ const message = object5(value);
35179
35461
  if (message?.role !== "assistant" || !Array.isArray(message.content))
35180
35462
  continue;
35181
35463
  for (const value of message.content) {
35182
- const block = object4(value);
35464
+ const block = object5(value);
35183
35465
  if (block?.type === "toolCall" && typeof block.id === "string")
35184
- calls.add(block.id);
35466
+ calls.add(pairingId(block.id));
35185
35467
  }
35186
35468
  }
35187
35469
  const transformed = [];
35188
35470
  let pending = new Set;
35189
35471
  let exactUnits = 0;
35190
35472
  for (let index = 0;index < messages.length; index++) {
35191
- const message = object4(messages[index]);
35473
+ const message = object5(messages[index]);
35192
35474
  if (!message)
35193
35475
  return;
35194
35476
  if ((message.role === "bashExecution" || message.role === "pythonExecution") && message.excludeFromContext === true)
@@ -35200,19 +35482,19 @@ function piChatHistoryPlan(messages, model) {
35200
35482
  continue;
35201
35483
  if (Array.isArray(message.content))
35202
35484
  for (const value of message.content) {
35203
- const block = object4(value);
35485
+ const block = object5(value);
35204
35486
  if (block?.type === "toolCall" && typeof block.id === "string")
35205
- pending.add(block.id);
35487
+ pending.add(pairingId(block.id));
35206
35488
  }
35207
35489
  }
35208
35490
  if (message.role === "toolResult" && typeof message.toolCallId === "string") {
35209
- pending.delete(message.toolCallId);
35210
- if (!calls.has(message.toolCallId)) {
35491
+ pending.delete(pairingId(message.toolCallId));
35492
+ if (!calls.has(pairingId(message.toolCallId))) {
35211
35493
  if (pending.size || typeof message.toolName !== "string" || !Array.isArray(message.content))
35212
35494
  return;
35213
35495
  const parts = [];
35214
35496
  for (const value of message.content) {
35215
- const part = object4(value);
35497
+ const part = object5(value);
35216
35498
  if (part?.type === "text" && typeof part.text === "string" && part.text.trim())
35217
35499
  parts.push(part.text);
35218
35500
  }
@@ -35245,14 +35527,14 @@ ${parts.join(`
35245
35527
  };
35246
35528
  const vision = model.input?.includes("image") === true && compat.stripImageInput !== true;
35247
35529
  for (const step of transformed) {
35248
- const message = step.kind === "source" ? object4(messages[step.index]) : undefined;
35530
+ const message = step.kind === "source" ? object5(messages[step.index]) : undefined;
35249
35531
  if (message?.role !== "toolResult")
35250
35532
  flushImages();
35251
35533
  steps.push(step);
35252
35534
  if (message?.role !== "toolResult" || !vision || !Array.isArray(message.content))
35253
35535
  continue;
35254
35536
  for (const value of message.content) {
35255
- const block = object4(value);
35537
+ const block = object5(value);
35256
35538
  if (block?.type !== "image")
35257
35539
  continue;
35258
35540
  if (compat.requiresAssistantAfterToolResult === true)
@@ -35276,12 +35558,12 @@ ${parts.join(`
35276
35558
  function piMatchesChatImages(content, urls) {
35277
35559
  if (!Array.isArray(content) || content.length !== urls.length + 1)
35278
35560
  return false;
35279
- const caption = object4(content[0]);
35561
+ const caption = object5(content[0]);
35280
35562
  if (caption?.type !== "text" || caption.text !== IMAGE_CAPTION || Object.keys(caption).length !== 2)
35281
35563
  return false;
35282
35564
  for (let i = 0;i < urls.length; i++) {
35283
- const block = object4(content[i + 1]);
35284
- const image = object4(block?.image_url);
35565
+ const block = object5(content[i + 1]);
35566
+ const image = object5(block?.image_url);
35285
35567
  if (block?.type !== "image_url" || Object.keys(block).length !== 2 || !image || Object.keys(image).length !== 1 || image.url !== urls[i])
35286
35568
  return false;
35287
35569
  }
@@ -35289,22 +35571,22 @@ function piMatchesChatImages(content, urls) {
35289
35571
  }
35290
35572
 
35291
35573
  // src/pi-dispatch-image-budget.ts
35292
- function object5(value) {
35574
+ function object6(value) {
35293
35575
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
35294
35576
  }
35295
35577
  function piImageBudgetPlan(model) {
35296
- if (!model?.input?.includes("image") || object5(model.compat)?.stripImageInput === true)
35578
+ if (!model?.input?.includes("image") || object6(model.compat)?.stripImageInput === true)
35297
35579
  return;
35298
35580
  return {
35299
35581
  count: 0,
35300
35582
  api: model.api,
35301
35583
  rows: new Map,
35302
- hoistToolImages: model.api?.startsWith("google-") === true && object5(model.compat)?.multimodalFunctionResponse !== true || model.api === "bedrock-converse-stream" && model.requiresToolResultImageHoisting === true,
35584
+ hoistToolImages: model.api?.startsWith("google-") === true && object6(model.compat)?.multimodalFunctionResponse !== true || model.api === "bedrock-converse-stream" && model.requiresToolResultImageHoisting === true,
35303
35585
  hoistErrorImages: model.api === "anthropic-messages" || model.api === "bedrock-converse-stream"
35304
35586
  };
35305
35587
  }
35306
35588
  function inputImage(block, api) {
35307
- const file = object5(block.providerFile);
35589
+ const file = object6(block.providerFile);
35308
35590
  if (api === "ollama-chat")
35309
35591
  return { kind: "bytes", value: String(block.data ?? "") };
35310
35592
  if ((api?.endsWith("responses") && file?.provider === "openai" || api === "anthropic-messages" && file?.provider === "anthropic") && typeof file?.id === "string")
@@ -35324,7 +35606,7 @@ function piRecordImages(plan, row, source) {
35324
35606
  return;
35325
35607
  const images = [];
35326
35608
  for (const value of source.content) {
35327
- const block = object5(value);
35609
+ const block = object6(value);
35328
35610
  if (block?.type === "image")
35329
35611
  images.push(inputImage(block, plan.api));
35330
35612
  }
@@ -35350,20 +35632,20 @@ function piWireImages(content, ollamaImages) {
35350
35632
  return [];
35351
35633
  const images = [];
35352
35634
  for (const value of content) {
35353
- const block = object5(value);
35635
+ const block = object6(value);
35354
35636
  if (!block)
35355
35637
  continue;
35356
- const source = object5(block.source);
35357
- const inline = object5(block.inlineData);
35358
- const file = object5(block.fileData);
35359
- const bedrock = object5(block.image);
35638
+ const source = object6(block.source);
35639
+ const inline = object6(block.inlineData);
35640
+ const file = object6(block.fileData);
35641
+ const bedrock = object6(block.image);
35360
35642
  if (block.type === "image_url" || block.type === "input_image") {
35361
35643
  if (typeof block.file_id === "string")
35362
35644
  images.push({ kind: "file", value: block.file_id });
35363
35645
  else
35364
35646
  images.push({
35365
35647
  kind: "url",
35366
- value: String(typeof block.image_url === "string" ? block.image_url : object5(block.image_url)?.url)
35648
+ value: String(typeof block.image_url === "string" ? block.image_url : object6(block.image_url)?.url)
35367
35649
  });
35368
35650
  } else if (block.type === "image") {
35369
35651
  if (source?.type === "file")
@@ -35387,7 +35669,7 @@ function piWireImages(content, ollamaImages) {
35387
35669
  else if (bedrock)
35388
35670
  images.push({
35389
35671
  kind: "data",
35390
- value: String(object5(bedrock.source)?.bytes),
35672
+ value: String(object6(bedrock.source)?.bytes),
35391
35673
  mime: `image/${bedrock.format}`
35392
35674
  });
35393
35675
  }
@@ -35409,11 +35691,11 @@ function piMatchesImages(actual, expected) {
35409
35691
  return true;
35410
35692
  }
35411
35693
  function piWireImageCount(payload) {
35412
- const body = object5(payload);
35694
+ const body = object6(payload);
35413
35695
  const visit = (value) => {
35414
35696
  if (Array.isArray(value))
35415
35697
  return value.reduce((n, item) => n + visit(item), 0);
35416
- const block = object5(value);
35698
+ const block = object6(value);
35417
35699
  if (!block)
35418
35700
  return 0;
35419
35701
  if (["image", "image_url", "input_image"].includes(String(block.type)) || block.inlineData || block.fileData || block.image)
@@ -35427,12 +35709,12 @@ function piWireImageCount(payload) {
35427
35709
  block.response
35428
35710
  ].reduce((n, item) => n + visit(item), Array.isArray(block.images) ? block.images.length : 0);
35429
35711
  };
35430
- return visit(body?.messages ?? body?.input ?? body?.contents ?? object5(body?.request)?.contents);
35712
+ return visit(body?.messages ?? body?.input ?? body?.contents ?? object6(body?.request)?.contents);
35431
35713
  }
35432
35714
 
35433
35715
  // src/pi-dispatch-responses-history.ts
35434
35716
  var MAX_TEXT_UNITS = 32 * 1024 * 1024;
35435
- function object6(value) {
35717
+ function object7(value) {
35436
35718
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
35437
35719
  }
35438
35720
  function wellFormed(text) {
@@ -35447,7 +35729,7 @@ function textIdentity2(text, phase) {
35447
35729
  function signaturePhase(block) {
35448
35730
  try {
35449
35731
  if (typeof block.textSignature === "string") {
35450
- const signature = object6(JSON.parse(block.textSignature));
35732
+ const signature = object7(JSON.parse(block.textSignature));
35451
35733
  if (signature?.v === 1 && typeof signature.id === "string")
35452
35734
  return signature.phase;
35453
35735
  }
@@ -35467,17 +35749,17 @@ ${wellFormed(text)}
35467
35749
  return;
35468
35750
  }
35469
35751
  function piResponsesAssistantTexts(value, model) {
35470
- const message = object6(value);
35752
+ const message = object7(value);
35471
35753
  if (!message || !Array.isArray(message.content))
35472
35754
  return;
35473
- if (["length", "error", "aborted"].includes(String(message.stopReason)) && !message.content.some((value) => ["text", "toolCall"].includes(String(object6(value)?.type))))
35755
+ if (["length", "error", "aborted"].includes(String(message.stopReason)) && !message.content.some((value) => ["text", "toolCall"].includes(String(object7(value)?.type))))
35474
35756
  return [];
35475
35757
  const texts = [];
35476
35758
  const blocks = [];
35477
35759
  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;
35478
35760
  let units = 0;
35479
35761
  for (const value of message.content) {
35480
- const block = object6(value);
35762
+ const block = object7(value);
35481
35763
  if (block?.type === "toolCall")
35482
35764
  continue;
35483
35765
  if (block?.type === "thinking") {
@@ -35487,7 +35769,7 @@ function piResponsesAssistantTexts(value, model) {
35487
35769
  return;
35488
35770
  if (!block.thinking.trim())
35489
35771
  continue;
35490
- const compat = object6(model.compat);
35772
+ const compat = object7(model.compat);
35491
35773
  if (block.summary === false && (compat?.requiresReasoningContentForToolCalls === true || compat?.requiresReasoningContentForAllAssistantTurns === true))
35492
35774
  return;
35493
35775
  const text = demotedThinking(block.thinking, model);
@@ -35507,14 +35789,14 @@ function piResponsesAssistantTexts(value, model) {
35507
35789
  texts.push(textIdentity2(wellFormed(block.text), sameModel ? signaturePhase(block) : undefined));
35508
35790
  blocks.push(block);
35509
35791
  }
35510
- const payload = object6(message.providerPayload);
35792
+ const payload = object7(message.providerPayload);
35511
35793
  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))
35512
35794
  return texts;
35513
35795
  const replay = [];
35514
35796
  let bound = 0;
35515
35797
  let output = false;
35516
35798
  for (const value of payload.items) {
35517
- const item = object6(value);
35799
+ const item = object7(value);
35518
35800
  if (item?.type === "reasoning")
35519
35801
  continue;
35520
35802
  if (item?.type === "function_call" || item?.type === "custom_tool_call") {
@@ -35525,14 +35807,14 @@ function piResponsesAssistantTexts(value, model) {
35525
35807
  return texts;
35526
35808
  const itemTexts = [];
35527
35809
  for (const value of item.content) {
35528
- const part = object6(value);
35810
+ const part = object7(value);
35529
35811
  const block = blocks[bound];
35530
35812
  if (!block || part?.type !== "output_text" || typeof part.text !== "string")
35531
35813
  return texts;
35532
35814
  let signature;
35533
35815
  try {
35534
35816
  if (typeof block.textSignature === "string")
35535
- signature = object6(JSON.parse(block.textSignature));
35817
+ signature = object7(JSON.parse(block.textSignature));
35536
35818
  } catch {
35537
35819
  return texts;
35538
35820
  }
@@ -35559,7 +35841,7 @@ function piResponsesWireTexts(value, phase) {
35559
35841
  const texts = [];
35560
35842
  let units = 0;
35561
35843
  for (const partValue of value) {
35562
- const part = object6(partValue);
35844
+ const part = object7(partValue);
35563
35845
  if (part?.type !== "output_text" || typeof part.text !== "string")
35564
35846
  return;
35565
35847
  units += part.text.length;
@@ -35589,11 +35871,11 @@ var TRANSFORM_MESSAGES_APIS = new Set([
35589
35871
  "devin-agent",
35590
35872
  "apple-foundation-models"
35591
35873
  ]);
35592
- function object7(value) {
35874
+ function object8(value) {
35593
35875
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
35594
35876
  }
35595
35877
  function messageStructure(value) {
35596
- const message = object7(value);
35878
+ const message = object8(value);
35597
35879
  if (!message)
35598
35880
  return;
35599
35881
  const role = [
@@ -35622,7 +35904,7 @@ function messageStructure(value) {
35622
35904
  }
35623
35905
  if (role === "assistant" && Array.isArray(message.content)) {
35624
35906
  for (const value of message.content) {
35625
- const block = object7(value);
35907
+ const block = object8(value);
35626
35908
  if (block?.type !== "toolCall" && block?.type !== "tool_use")
35627
35909
  continue;
35628
35910
  if (typeof block.id !== "string")
@@ -35634,41 +35916,249 @@ function messageStructure(value) {
35634
35916
  }
35635
35917
  return row;
35636
35918
  }
35637
- function projectMissingToolResults(messages, api) {
35638
- const projectOrphans = TRANSFORM_MESSAGES_APIS.has(api ?? "");
35919
+ function windowCalls(message) {
35920
+ if (!Array.isArray(message.content))
35921
+ return [];
35922
+ return message.content.flatMap((value) => {
35923
+ const block = object8(value);
35924
+ return block?.type === "toolCall" && typeof block.id === "string" ? [
35925
+ {
35926
+ id: block.id,
35927
+ name: typeof block.name === "string" ? block.name : ""
35928
+ }
35929
+ ] : [];
35930
+ });
35931
+ }
35932
+ function duplicateSuffix(model) {
35933
+ const compat = object8(model?.compat);
35934
+ if (model?.api === "openai-completions") {
35935
+ if (compat?.requiresMistralToolIds === true)
35936
+ return { prefix: "dup", max: 9 };
35937
+ if (compat?.usesOpenAIToolCallIdLimit === true)
35938
+ return { prefix: "_dup", max: 40 };
35939
+ }
35940
+ if (model?.api === "devin-agent")
35941
+ return { prefix: "_dup", max: 40 };
35942
+ return { prefix: "_dup", max: 64 };
35943
+ }
35944
+ function appendDuplicateSuffix(id, suffix, max) {
35945
+ const segment = (part) => part.length + suffix.length <= max ? `${part}${suffix}` : `${part.slice(0, Math.max(0, max - suffix.length))}${suffix}`;
35946
+ return id.includes("|") ? id.split("|").map(segment).join("|") : segment(id);
35947
+ }
35948
+ function projectMissingToolResults(messages, model, host = "omp") {
35949
+ const input = messages.filter((value) => {
35950
+ const message = object8(value);
35951
+ return !((message?.role === "bashExecution" || message?.role === "pythonExecution") && message.excludeFromContext === true);
35952
+ });
35953
+ if (host === "pi")
35954
+ return projectPiToolResults(input);
35955
+ const api = model?.api;
35956
+ if (!TRANSFORM_MESSAGES_APIS.has(api ?? ""))
35957
+ return projectUnmodeledToolResults(messages);
35958
+ const pairingId = piToolCallPairing(input);
35959
+ const { prefix, max } = duplicateSuffix(model);
35960
+ const seen = new Map;
35961
+ const renames = new Map;
35962
+ const realResults = new Map;
35963
+ const validToolUseIds = new Set;
35964
+ const deduplicated = input.map((value, index) => {
35965
+ const message = object8(value);
35966
+ if (message?.role === "toolResult" && typeof message.toolCallId === "string") {
35967
+ let key = pairingId(message.toolCallId);
35968
+ let output = value;
35969
+ const queue = renames.get(key);
35970
+ if (queue?.length) {
35971
+ const replacement = queue.shift();
35972
+ if (!queue.length)
35973
+ renames.delete(key);
35974
+ if (replacement !== undefined) {
35975
+ output = { ...message, toolCallId: replacement };
35976
+ key = pairingId(replacement);
35977
+ }
35978
+ }
35979
+ const entry = { index, message: output, consumed: false };
35980
+ const entries = realResults.get(key);
35981
+ if (entries)
35982
+ entries.push(entry);
35983
+ else
35984
+ realResults.set(key, [entry]);
35985
+ return output;
35986
+ }
35987
+ if (message?.role !== "assistant" || !Array.isArray(message.content))
35988
+ return value;
35989
+ const touched = new Set;
35990
+ let changed = false;
35991
+ const content = message.content.map((part) => {
35992
+ const block = object8(part);
35993
+ if (block?.type !== "toolCall" || typeof block.id !== "string")
35994
+ return part;
35995
+ const key = pairingId(block.id);
35996
+ if (!touched.has(key)) {
35997
+ touched.add(key);
35998
+ renames.delete(key);
35999
+ }
36000
+ const count = seen.get(key) ?? 0;
36001
+ const queue = renames.get(key) ?? [];
36002
+ renames.set(key, queue);
36003
+ if (count === 0) {
36004
+ seen.set(key, 1);
36005
+ queue.push(undefined);
36006
+ return part;
36007
+ }
36008
+ let suffix = count;
36009
+ let replacement = appendDuplicateSuffix(block.id, `${prefix}${suffix}`, max);
36010
+ while (seen.has(pairingId(replacement))) {
36011
+ suffix++;
36012
+ replacement = appendDuplicateSuffix(block.id, `${prefix}${suffix}`, max);
36013
+ }
36014
+ seen.set(key, suffix + 1);
36015
+ seen.set(pairingId(replacement), 1);
36016
+ queue.push(replacement);
36017
+ changed = true;
36018
+ return { ...block, id: replacement };
36019
+ });
36020
+ for (const call of windowCalls({ content }))
36021
+ validToolUseIds.add(pairingId(call.id));
36022
+ return changed ? { ...message, content } : value;
36023
+ });
36024
+ const takeRealResult = (id, afterIndex) => {
36025
+ for (const entry of realResults.get(pairingId(id)) ?? []) {
36026
+ if (entry.consumed || entry.index <= afterIndex)
36027
+ continue;
36028
+ entry.consumed = true;
36029
+ return entry.message;
36030
+ }
36031
+ return;
36032
+ };
36033
+ const projected = [];
36034
+ const answered = new Set;
36035
+ let pending = [];
36036
+ let pendingStart = -1;
36037
+ let aborted = new Map;
36038
+ let abortedTimestamp;
36039
+ let abortedStart = -1;
36040
+ const stub = (call, text, timestamp) => ({
36041
+ role: "toolResult",
36042
+ toolCallId: call.id,
36043
+ toolName: call.name,
36044
+ content: [{ type: "text", text }],
36045
+ isError: true,
36046
+ timestamp
36047
+ });
36048
+ const flush = (boundaryTimestamp) => {
36049
+ for (const call of pending) {
36050
+ const key = pairingId(call.id);
36051
+ if (answered.has(key))
36052
+ continue;
36053
+ projected.push(takeRealResult(call.id, pendingStart) ?? stub(call, "No result provided", boundaryTimestamp));
36054
+ answered.add(key);
36055
+ }
36056
+ pending = [];
36057
+ if (abortedTimestamp === undefined)
36058
+ return;
36059
+ for (const call of aborted.values()) {
36060
+ const key = pairingId(call.id);
36061
+ if (answered.has(key))
36062
+ continue;
36063
+ projected.push(takeRealResult(call.id, abortedStart) ?? stub(call, "aborted", abortedTimestamp));
36064
+ answered.add(key);
36065
+ }
36066
+ aborted = new Map;
36067
+ abortedTimestamp = undefined;
36068
+ };
36069
+ for (let index = 0;index < deduplicated.length; index++) {
36070
+ const value = deduplicated[index];
36071
+ const message = object8(value);
36072
+ if (message?.role === "assistant") {
36073
+ flush(message.timestamp);
36074
+ projected.push(value);
36075
+ const calls = windowCalls(message);
36076
+ const truncated = ["length", "error", "aborted"].includes(String(message.stopReason));
36077
+ if (truncated && Array.isArray(message.content) && !message.content.some((part) => ["toolCall", "text"].includes(String(object8(part)?.type))))
36078
+ continue;
36079
+ if (message.stopReason === "aborted" || message.stopReason === "error") {
36080
+ aborted = new Map(calls.map((call) => [pairingId(call.id), call]));
36081
+ abortedTimestamp = message.timestamp;
36082
+ abortedStart = index;
36083
+ } else if (calls.length) {
36084
+ pending = calls;
36085
+ pendingStart = index;
36086
+ }
36087
+ continue;
36088
+ }
36089
+ if (message?.role !== "toolResult" || typeof message.toolCallId !== "string") {
36090
+ if (message?.role !== "toolResult")
36091
+ flush(message?.timestamp);
36092
+ projected.push(value);
36093
+ continue;
36094
+ }
36095
+ const key = pairingId(message.toolCallId);
36096
+ if (answered.has(key))
36097
+ continue;
36098
+ if (aborted.has(key) || pending.some((call) => pairingId(call.id) === key)) {
36099
+ aborted.delete(key);
36100
+ answered.add(key);
36101
+ projected.push(value);
36102
+ continue;
36103
+ }
36104
+ if (validToolUseIds.has(key))
36105
+ continue;
36106
+ if (typeof message.toolName !== "string" || !Array.isArray(message.content)) {
36107
+ projected.push(value);
36108
+ continue;
36109
+ }
36110
+ if (pending.some((call) => !answered.has(pairingId(call.id))) || aborted.size > 0)
36111
+ continue;
36112
+ const parts = message.content.flatMap((value) => {
36113
+ const part = object8(value);
36114
+ return part?.type === "text" && typeof part.text === "string" && part.text.trim() ? [part.text] : [];
36115
+ });
36116
+ if (!parts.length)
36117
+ continue;
36118
+ const error = message.isError ? ' is-error="true"' : "";
36119
+ const note = `<stale-tool-result tool="${message.toolName}" id="${message.toolCallId}"${error}>
36120
+ ${parts.join(`
36121
+ `)}
36122
+ </stale-tool-result>`;
36123
+ projected.push({
36124
+ role: "user",
36125
+ content: api === "ollama-chat" ? note : new TextDecoder().decode(new TextEncoder().encode(note)),
36126
+ timestamp: message.timestamp,
36127
+ [ORPHAN_NOTE]: true
36128
+ });
36129
+ }
36130
+ flush();
36131
+ return projected;
36132
+ }
36133
+ function projectUnmodeledToolResults(messages) {
35639
36134
  const responsesComponents = new Set;
35640
36135
  const opaqueIds = new Set;
35641
- const validToolUseIds = projectOrphans ? new Set : undefined;
35642
36136
  const component = (id) => {
35643
36137
  const pipe = id.indexOf("|");
35644
36138
  return pipe > 0 ? id.slice(0, pipe) : id;
35645
36139
  };
35646
36140
  for (const value of messages) {
35647
- const message = object7(value);
36141
+ const message = object8(value);
35648
36142
  if (message?.role !== "assistant" || !Array.isArray(message.content))
35649
36143
  continue;
35650
36144
  for (const value of message.content) {
35651
- const block = object7(value);
36145
+ const block = object8(value);
35652
36146
  if (block?.type !== "toolCall" || typeof block.id !== "string")
35653
36147
  continue;
35654
36148
  if ([
35655
36149
  "openai-responses",
35656
36150
  "azure-openai-responses",
35657
36151
  "openai-codex-responses"
35658
- ].includes(String(message.api))) {
36152
+ ].includes(String(message.api)))
35659
36153
  responsesComponents.add(component(block.id));
35660
- validToolUseIds?.add(component(block.id));
35661
- } else {
35662
- if (block.id.includes("|"))
35663
- opaqueIds.add(block.id);
35664
- validToolUseIds?.add(block.id);
35665
- }
36154
+ else if (block.id.includes("|"))
36155
+ opaqueIds.add(block.id);
35666
36156
  }
35667
36157
  }
35668
36158
  const pairingId = (id) => !opaqueIds.has(id) && responsesComponents.has(component(id)) ? component(id) : id;
35669
36159
  const lastResult = new Map;
35670
36160
  messages.forEach((value, index) => {
35671
- const message = object7(value);
36161
+ const message = object8(value);
35672
36162
  if (message?.role === "toolResult" && typeof message.toolCallId === "string")
35673
36163
  lastResult.set(pairingId(message.toolCallId), index);
35674
36164
  });
@@ -35699,35 +36189,13 @@ function projectMissingToolResults(messages, api) {
35699
36189
  };
35700
36190
  for (let index = 0;index < messages.length; index++) {
35701
36191
  const value = messages[index];
35702
- const message = object7(value);
36192
+ const message = object8(value);
35703
36193
  if ((message?.role === "bashExecution" || message?.role === "pythonExecution") && message.excludeFromContext === true)
35704
36194
  continue;
35705
36195
  if (message?.role !== "toolResult")
35706
36196
  flush(message?.timestamp);
35707
36197
  else if (typeof message.toolCallId === "string" && pending.some((call) => pairingId(call.id) === pairingId(String(message.toolCallId))))
35708
36198
  resolved.add(pairingId(message.toolCallId));
35709
- else if (validToolUseIds && message?.role === "toolResult" && typeof message.toolCallId === "string" && typeof message.toolName === "string" && !validToolUseIds.has(pairingId(message.toolCallId)) && Array.isArray(message.content)) {
35710
- if (pending.some((call) => !resolved.has(pairingId(call.id))))
35711
- continue;
35712
- const parts = message.content.flatMap((value) => {
35713
- const part = object7(value);
35714
- return part?.type === "text" && typeof part.text === "string" && part.text.trim() ? [part.text] : [];
35715
- });
35716
- if (parts.length) {
35717
- const error = message.isError ? ' is-error="true"' : "";
35718
- const note = `<stale-tool-result tool="${message.toolName}" id="${message.toolCallId}"${error}>
35719
- ${parts.join(`
35720
- `)}
35721
- </stale-tool-result>`;
35722
- projected.push({
35723
- role: "user",
35724
- content: api === "ollama-chat" ? note : new TextDecoder().decode(new TextEncoder().encode(note)),
35725
- timestamp: message.timestamp,
35726
- [ORPHAN_NOTE]: true
35727
- });
35728
- }
35729
- continue;
35730
- }
35731
36199
  projected.push(value);
35732
36200
  if (message?.role !== "assistant" || !Array.isArray(message.content))
35733
36201
  continue;
@@ -35736,39 +36204,82 @@ ${parts.join(`
35736
36204
  timestamp = message.timestamp;
35737
36205
  if (aborted && typeof timestamp !== "number")
35738
36206
  continue;
35739
- for (const value of message.content) {
35740
- const block = object7(value);
35741
- if (block?.type === "toolCall" && typeof block.id === "string")
35742
- pending.push({
35743
- id: block.id,
35744
- name: typeof block.name === "string" ? block.name : ""
35745
- });
35746
- }
36207
+ pending.push(...windowCalls(message));
35747
36208
  }
35748
36209
  flush();
35749
36210
  return projected;
35750
36211
  }
36212
+ function projectPiToolResults(messages) {
36213
+ const projected = [];
36214
+ let pending = [];
36215
+ let answered = new Set;
36216
+ const held = [];
36217
+ const close = (timestamp) => {
36218
+ for (const call of pending)
36219
+ if (!answered.has(call.id))
36220
+ projected.push({
36221
+ role: "toolResult",
36222
+ toolCallId: call.id,
36223
+ toolName: call.name,
36224
+ content: [{ type: "text", text: "No result provided" }],
36225
+ isError: true,
36226
+ timestamp
36227
+ });
36228
+ pending = [];
36229
+ answered = new Set;
36230
+ projected.push(...held);
36231
+ held.length = 0;
36232
+ };
36233
+ for (const value of messages) {
36234
+ const message = object8(value);
36235
+ const role = message?.role;
36236
+ if (role === "assistant") {
36237
+ close(message?.timestamp);
36238
+ if (message?.stopReason === "error" || message?.stopReason === "aborted")
36239
+ continue;
36240
+ const calls = message ? windowCalls(message) : [];
36241
+ if (calls.length)
36242
+ pending = calls;
36243
+ } else if (role === "toolResult") {
36244
+ if (typeof message?.toolCallId === "string")
36245
+ answered.add(message.toolCallId);
36246
+ } else if (role === "system" && pending.length) {
36247
+ held.push(value);
36248
+ continue;
36249
+ } else if ([
36250
+ "user",
36251
+ "custom",
36252
+ "bashExecution",
36253
+ "branchSummary",
36254
+ "compactionSummary"
36255
+ ].includes(String(role)))
36256
+ close(message?.timestamp);
36257
+ projected.push(value);
36258
+ }
36259
+ close();
36260
+ return projected;
36261
+ }
35751
36262
  function preparePiDispatch(messages, model, omp) {
35752
36263
  let output = messages;
35753
36264
  const structure = buildPiPreparedStructure(messages, model, omp ? (index, source) => {
35754
- if (object7(source.providerPayload)?.type !== "openaiResponsesHistory")
36265
+ if (object8(source.providerPayload)?.type !== "openaiResponsesHistory")
35755
36266
  return;
35756
36267
  if (output === messages)
35757
36268
  output = messages.slice();
35758
36269
  const { providerPayload: _payload, ...copy } = source;
35759
36270
  output[index] = copy;
35760
- } : undefined);
36271
+ } : undefined, omp ? "omp" : "pi");
35761
36272
  return { messages: output, structure };
35762
36273
  }
35763
- function buildPiPreparedStructure(messages, model, prepareUser) {
36274
+ function buildPiPreparedStructure(messages, model, prepareUser, host = "omp") {
35764
36275
  if (!messages.length || messages.length > MAX_MESSAGES)
35765
36276
  return;
35766
36277
  for (let index = 0;index < messages.length; index++) {
35767
- const source = object7(messages[index]);
36278
+ const source = object8(messages[index]);
35768
36279
  if (source?.role === "user" || source?.role === "compactionSummary")
35769
36280
  prepareUser?.(index, source);
35770
36281
  }
35771
- const projectedMessages = projectMissingToolResults(model?.api ? piAgentHistory(messages, model.api) : messages, model?.api);
36282
+ const projectedMessages = projectMissingToolResults(model?.api && host === "omp" ? piAgentHistory(messages, model.api) : messages, model, host);
35772
36283
  if (projectedMessages.length > MAX_MESSAGES)
35773
36284
  return;
35774
36285
  const rows = [];
@@ -35780,7 +36291,7 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35780
36291
  let valid = true;
35781
36292
  for (let index = 0;index < projectedMessages.length; index++) {
35782
36293
  const message = projectedMessages[index];
35783
- const source = object7(message);
36294
+ const source = object8(message);
35784
36295
  if (rows.length === 0 && (source?.role === "system" || source?.role === "developer"))
35785
36296
  continue;
35786
36297
  if ((source?.role === "bashExecution" || source?.role === "pythonExecution") && source.excludeFromContext === true)
@@ -35804,7 +36315,7 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35804
36315
  "azure-openai-responses",
35805
36316
  "openai-codex-responses"
35806
36317
  ].includes(model?.api ?? "") && (source?.role === "user" || source?.role === "developer") && (typeof source.content === "string" ? !source.content.trim() : Array.isArray(source.content) && !source.content.some((value) => {
35807
- const block = object7(value);
36318
+ const block = object8(value);
35808
36319
  return block?.type === "image" || block?.type === "text" && typeof block.text === "string" && block.text.trim();
35809
36320
  })))
35810
36321
  continue;
@@ -35837,16 +36348,16 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35837
36348
  const positionedRows = [...byIndex];
35838
36349
  for (let position = positionedRows.length - 1;position >= 0; position--) {
35839
36350
  const [index, row] = positionedRows[position];
35840
- const source = object7(projectedMessages[index]);
36351
+ const source = object8(projectedMessages[index]);
35841
36352
  if (!source)
35842
36353
  return;
35843
36354
  const content = source.content;
35844
36355
  const parts = typeof content === "string" ? [{ type: "text", text: content }] : content;
35845
- const textOnly = Array.isArray(parts) && parts.every((part) => object7(part)?.type === "text" && typeof object7(part)?.text === "string");
36356
+ const textOnly = Array.isArray(parts) && parts.every((part) => object8(part)?.type === "text" && typeof object8(part)?.text === "string");
35846
36357
  if (piIsDeveloperHistory(source) && source.attribution !== "user") {
35847
36358
  const previous = rows[position - 1];
35848
36359
  const next = rows[position + 1];
35849
- if (model?.api === "ollama-chat" || model?.api === "anthropic-messages" && object7(model.compat)?.supportsMidConversationSystem === true && textOnly && (previous?.role === "user" || previous?.role === "toolResult") && (!next || next.role === "assistant"))
36360
+ if (model?.api === "ollama-chat" || model?.api === "anthropic-messages" && object8(model.compat)?.supportsMidConversationSystem === true && textOnly && (previous?.role === "user" || previous?.role === "toolResult") && (!next || next.role === "assistant"))
35850
36361
  row.role = "system";
35851
36362
  }
35852
36363
  if (row.role === "system") {
@@ -35919,7 +36430,7 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35919
36430
  ...responsesMessages ? { responsesMessages } : {},
35920
36431
  ...model?.api ? { api: model.api } : {},
35921
36432
  ...model?.api?.startsWith("google-") ? {
35922
- googleFunctionIds: object7(model.compat)?.supportsFunctionPartId === true
36433
+ googleFunctionIds: object8(model.compat)?.supportsFunctionPartId === true
35923
36434
  } : {}
35924
36435
  };
35925
36436
  }
@@ -35931,7 +36442,7 @@ function responsesLane(api) {
35931
36442
  ].includes(api ?? "");
35932
36443
  }
35933
36444
  function payloadStructure(payload, ollama = false, responsesItems = false, imageProjection = false) {
35934
- const body = object7(payload);
36445
+ const body = object8(payload);
35935
36446
  if (!body)
35936
36447
  return;
35937
36448
  const google = piGoogleConversation(payload);
@@ -35946,7 +36457,7 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
35946
36457
  return;
35947
36458
  const rows = [];
35948
36459
  for (const value of messages) {
35949
- const message = object7(value);
36460
+ const message = object8(value);
35950
36461
  if (!message)
35951
36462
  return;
35952
36463
  if (rows.length === 0 && (message.role === "system" || message.role === "developer"))
@@ -36006,7 +36517,7 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
36006
36517
  continue;
36007
36518
  }
36008
36519
  if (message.role === "user" && Array.isArray(message.content)) {
36009
- const results = message.content.filter((block) => object7(block)?.type === "tool_result" || bedrock && object7(block)?.toolResult);
36520
+ const results = message.content.filter((block) => object8(block)?.type === "tool_result" || bedrock && object8(block)?.toolResult);
36010
36521
  if (results.length) {
36011
36522
  for (const block of results) {
36012
36523
  const id = bedrock ? block.toolResult?.toolUseId : block.tool_use_id;
@@ -36053,11 +36564,11 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
36053
36564
  }
36054
36565
  if (Array.isArray(message.tool_calls)) {
36055
36566
  for (const call of message.tool_calls) {
36056
- const source = object7(call);
36567
+ const source = object8(call);
36057
36568
  if (!source)
36058
36569
  return;
36059
36570
  if (source.id === undefined && ollama) {
36060
- const fn = object7(source.function);
36571
+ const fn = object8(source.function);
36061
36572
  if (typeof fn?.name !== "string")
36062
36573
  return;
36063
36574
  row.calls.push("");
@@ -36093,7 +36604,7 @@ function googleStructure(contents, imageProjection = false) {
36093
36604
  return;
36094
36605
  const rows = [];
36095
36606
  for (const value of contents) {
36096
- const message = object7(value);
36607
+ const message = object8(value);
36097
36608
  if (!message || !Array.isArray(message.parts))
36098
36609
  return;
36099
36610
  if (message.role !== "user" && message.role !== "model")
@@ -36108,11 +36619,11 @@ function googleStructure(contents, imageProjection = false) {
36108
36619
  };
36109
36620
  const results = [];
36110
36621
  for (const value of message.parts) {
36111
- const part = object7(value);
36622
+ const part = object8(value);
36112
36623
  if (!part)
36113
36624
  return;
36114
36625
  if (part.functionCall) {
36115
- const call = object7(part.functionCall);
36626
+ const call = object8(part.functionCall);
36116
36627
  if (row.role !== "assistant" || typeof call?.name !== "string" || call.id !== undefined && typeof call.id !== "string")
36117
36628
  return;
36118
36629
  row.calls.push(call.id ?? "");
@@ -36120,7 +36631,7 @@ function googleStructure(contents, imageProjection = false) {
36120
36631
  row.callNames.push(call.name);
36121
36632
  }
36122
36633
  if (part.functionResponse) {
36123
- const result = object7(part.functionResponse);
36634
+ const result = object8(part.functionResponse);
36124
36635
  if (row.role !== "user" || typeof result?.name !== "string" || result.id !== undefined && typeof result.id !== "string")
36125
36636
  return;
36126
36637
  results.push({
@@ -36154,11 +36665,11 @@ function matchesUserText(content, text, api, responses, googleOrBedrock) {
36154
36665
  if (responses || googleOrBedrock) {
36155
36666
  if (!Array.isArray(content) || content.length !== 1)
36156
36667
  return false;
36157
- const block = object7(content[0]);
36668
+ const block = object8(content[0]);
36158
36669
  return !!block && block.text === text && (responses ? block.type === "input_text" : Object.keys(block).length === 1);
36159
36670
  }
36160
36671
  if ((api === "anthropic-messages" || api === "factory-droid-agent") && Array.isArray(content)) {
36161
- const block = content.length === 1 ? object7(content[0]) : undefined;
36672
+ const block = content.length === 1 ? object8(content[0]) : undefined;
36162
36673
  return block?.type === "text" && block.text === text;
36163
36674
  }
36164
36675
  return content === text;
@@ -36226,7 +36737,7 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
36226
36737
  return "comparison=image count";
36227
36738
  const imageProjection = trimmed > 0;
36228
36739
  stage = "wire rows";
36229
- const body = object7(payload);
36740
+ const body = object8(payload);
36230
36741
  const ollama = prepared?.api === "ollama-chat" && !!body && Array.isArray(body.messages) && body.input === undefined && body.system === undefined && body.inferenceConfig === undefined;
36231
36742
  const responses = body?.messages === undefined && Array.isArray(body?.input);
36232
36743
  rows = payloadStructure(payload, ollama, responses && !!prepared?.responsesMessages, imageProjection);
@@ -36251,7 +36762,7 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
36251
36762
  if (expected.systemText !== undefined) {
36252
36763
  const texts = expected.systemText;
36253
36764
  const content = actual.wireContent;
36254
- const actualTexts = typeof content === "string" ? [content] : Array.isArray(content) && content.every((part) => object7(part)?.type === "text" && typeof object7(part)?.text === "string") ? content.map((part) => part.text) : undefined;
36765
+ const actualTexts = typeof content === "string" ? [content] : Array.isArray(content) && content.every((part) => object8(part)?.type === "text" && typeof object8(part)?.text === "string") ? content.map((part) => part.text) : undefined;
36255
36766
  if (!actualTexts || (typeof content === "string" ? content !== texts.join(`
36256
36767
  `) : JSON.stringify(actualTexts) !== JSON.stringify(texts)))
36257
36768
  return structureDetail(i, expectedRows, rows, "content");
@@ -43658,6 +44169,14 @@ function registerPiContextHandler(pi, baseOptions) {
43658
44169
  schedulerDeferReason,
43659
44170
  forceMaterialization: forceMaterialization || isEmergency,
43660
44171
  forceMaterializationPercentage,
44172
+ signedThinkingHold: resolvePiSignedThinkingHold({
44173
+ sessionId,
44174
+ db: options.db,
44175
+ messages: event.messages,
44176
+ prefixBound: isPrefixBoundThinkingModel(ctx.model?.provider, ctx.model?.id),
44177
+ usagePercentage,
44178
+ executeThresholdPercentage: effectiveExecuteThresholdPercentage
44179
+ }),
43661
44180
  contextUsage: {
43662
44181
  percentage: usagePercentage,
43663
44182
  inputTokens: usageInputTokens
@@ -43774,7 +44293,8 @@ function registerPiContextHandler(pi, baseOptions) {
43774
44293
  minimumPercentage: usagePercentage,
43775
44294
  liveIsRawBranchEstimate: piLiveUsageIsRawBranchEstimate,
43776
44295
  historianStateSnapshot: historianStateForPass,
43777
- publishedHistoryRide: isCacheBusting
44296
+ publishedHistoryRide: isCacheBusting,
44297
+ signedThinkingHeld: result.strictThinkingKept
43778
44298
  });
43779
44299
  } catch (error) {
43780
44300
  budget.assertOutcome();
@@ -44167,6 +44687,7 @@ function registerPiContextHandler(pi, baseOptions) {
44167
44687
  },
44168
44688
  minimumPercentage: 95,
44169
44689
  publishedHistoryRide: false,
44690
+ signedThinkingHeld: result.strictThinkingKept,
44170
44691
  historianStateSnapshot: loadPiHistorianStateSnapshot(options.db, sessionId)
44171
44692
  });
44172
44693
  const pending = inFlightHistorian.get(sessionId);
@@ -44928,8 +45449,14 @@ Historian previously failed ${failureCount} time(s), so Magic Context is retryin
44928
45449
  const trigger = checkCompartmentTrigger(db, sessionId, sessionMeta, usage, 0, triggerInputs.executeThresholdPercentage, triggerInputs.triggerBudget, triggerInputs.keepReasoningTokens, triggerInputs.commitClusterTrigger, args.activeTags, boundaryContextLimit, () => readPiHistorianTail(db, sessionId, provider), args.taggerFloor, { canClearReasoning: true }, {
44929
45450
  hardFold: false,
44930
45451
  force: usage.percentage >= historianForceMaterializationPercentage && (usage.percentage >= 95 || getEmergencyInputSample(db, sessionId) === 0),
44931
- explicitFlush: hasPendingMaterialization(sessionId),
44932
- publishedHistory: args.publishedHistoryRide
45452
+ explicitFlush: hasPendingMaterializationOrigin(pendingMaterializationSessions, sessionId, "user_flush"),
45453
+ publishedHistory: args.publishedHistoryRide,
45454
+ permission: {
45455
+ signedThinkingHold: args.signedThinkingHeld === true,
45456
+ firstRender: false,
45457
+ idleExpiry: false,
45458
+ emergency: usage.percentage >= historianForceMaterializationPercentage
45459
+ }
44933
45460
  }, args.eligiblePendingDropTagIds);
44934
45461
  if (!trigger.shouldFire) {
44935
45462
  sessionLog2(sessionId, `historian trigger eval: shouldFire=false (no trigger condition met)`);
@@ -45029,8 +45556,10 @@ function captureReasoningMutationRollback(messages) {
45029
45556
  }
45030
45557
  async function runCompactionOffPipeline(args) {
45031
45558
  let injectionResult = null;
45559
+ const transcript = [...args.messages];
45560
+ let headChangedUnderSignedTurn = false;
45032
45561
  if (args.injection) {
45033
- injectionResult = injectM0M1Pi({
45562
+ const state = {
45034
45563
  sessionId: args.sessionId,
45035
45564
  projectIdentity: args.projectIdentity,
45036
45565
  projectDirectory: args.projectDirectory,
@@ -45041,8 +45570,31 @@ async function runCompactionOffPipeline(args) {
45041
45570
  historyBudgetPolicyIdentity: args.injection.historyBudgetPolicyIdentity,
45042
45571
  muralEnabled: args.injection.muralEnabled === true,
45043
45572
  compactionOff: true
45044
- }, args.db, args.messages, args.entryIds, false, args.injectionPassSnapshot);
45045
- }
45573
+ };
45574
+ const signedTurnHoldsHead = args.reasoningClearing?.prefixBound === true && hasActiveAnthropicThinkingTurn(args.messages, args.resolvedProviderID, args.resolvedModelID);
45575
+ if (signedTurnHoldsHead)
45576
+ state.preparedPrefix = prepareCachedM0M1PiReplay(state, args.db, args.injectionPassSnapshot?.cachedRow);
45577
+ const servedBeforeFirstRender = signedTurnHoldsHead && !state.preparedPrefix ? args.readLastServedMessages?.() ?? null : undefined;
45578
+ injectionResult = injectM0M1Pi(state, args.db, args.messages, args.entryIds, false, args.injectionPassSnapshot);
45579
+ if (servedBeforeFirstRender !== undefined) {
45580
+ const headCount = injectionResult?.syntheticLeadingCount ?? 0;
45581
+ const head = JSON.stringify(args.messages.slice(0, headCount));
45582
+ headChangedUnderSignedTurn = servedBeforeFirstRender === null || JSON.stringify(servedBeforeFirstRender.slice(0, headCount)) !== head;
45583
+ }
45584
+ }
45585
+ if (headChangedUnderSignedTurn)
45586
+ applyPiProactiveThinkingStrip({
45587
+ db: args.db,
45588
+ sessionId: args.sessionId,
45589
+ messages: transcript,
45590
+ entryIds: transcript.map((message, index) => resolvePiRealStableId(message, index, args.entryIds, args.entryIdByRef ?? undefined)),
45591
+ provider: args.resolvedProviderID,
45592
+ model: args.resolvedModelID,
45593
+ cacheBustingPass: true,
45594
+ stripActiveTurn: true,
45595
+ requirePersistence: true,
45596
+ report: (line) => sessionLog2(args.sessionId, line)
45597
+ });
45046
45598
  return {
45047
45599
  messages: args.messages,
45048
45600
  prefixBustPermitted: false,
@@ -45077,6 +45629,27 @@ async function runCompactionOffPipeline(args) {
45077
45629
  lkgEntryIdByRef: new Map
45078
45630
  };
45079
45631
  }
45632
+ var signedThinkingHoldLogKeys = new Map;
45633
+ function resolvePiSignedThinkingHold(args) {
45634
+ if (!args.prefixBound)
45635
+ return false;
45636
+ let proseRatio;
45637
+ const decision = decideSignedThinkingHold({
45638
+ messages: args.messages,
45639
+ usagePercentage: args.usagePercentage,
45640
+ executeThresholdPercentage: args.executeThresholdPercentage,
45641
+ estimateTextTokens: (text) => {
45642
+ proseRatio ??= sessionDecisionCalibration(args.db, args.sessionId).proseRatio;
45643
+ return estimateTokens(text) * proseRatio;
45644
+ }
45645
+ });
45646
+ const key = `${decision.reason}:${decision.heavyStepsBack ?? "none"}`;
45647
+ if (signedThinkingHoldLogKeys.get(args.sessionId) !== key) {
45648
+ signedThinkingHoldLogKeys.set(args.sessionId, key);
45649
+ sessionLog2(args.sessionId, `signed thinking hold: held=${decision.held} reason=${decision.reason} heavyStepsBack=${decision.heavyStepsBack ?? "none"} heavyStepTokens=${decision.heavyStepTokens} usage=${args.usagePercentage.toFixed(1)}% cap=${decision.capPercentage}%`);
45650
+ }
45651
+ return decision.held;
45652
+ }
45080
45653
  async function runPipeline(args) {
45081
45654
  args.assertCurrentPass?.();
45082
45655
  if (args.compactionOff)
@@ -45092,7 +45665,8 @@ async function runPipeline(args) {
45092
45665
  signalPiPendingMaterialization(args.sessionId, "thinking_hold");
45093
45666
  let restoreOriginals;
45094
45667
  let activeThinkingTurn = hasActiveAnthropicThinkingTurn(args.messages, args.resolvedProviderID, args.resolvedModelID);
45095
- let protectedSignedPrefix = activeThinkingTurn && args.reasoningClearing?.prefixBound === true;
45668
+ const signedTurnOnPrefixBoundModel = args.reasoningClearing?.prefixBound === true && (activeThinkingTurn || activeAnthropicTurnStart(args.messages, true) === undefined && args.messages.some((message) => message.role === "assistant" && Array.isArray(message.content) && message.content.some((part) => part?.type === "thinking" || part?.type === "redacted_thinking")));
45669
+ let protectedSignedPrefix = signedTurnOnPrefixBoundModel && args.signedThinkingHold === true;
45096
45670
  let rewritingSignedPrefix = false;
45097
45671
  let isCacheBustingPass = args.recoveryRebuildReason === "lkg_recovery_input_rebuild" || (!!args.recoveryRebuildReason || args.forceSignedRebuildForFit === true) && hasUnfrozenPiThinking({
45098
45672
  messages: args.messages,
@@ -45123,8 +45697,12 @@ async function runPipeline(args) {
45123
45697
  activeThinkingTurn = false;
45124
45698
  protectedSignedPrefix = false;
45125
45699
  };
45126
- if (args.recoveryRebuildReason || args.forceSignedRebuildForFit && protectedSignedPrefix)
45700
+ if (args.recoveryRebuildReason || args.forceSignedRebuildForFit && signedTurnOnPrefixBoundModel)
45127
45701
  stripForPrefixRewrite(isCacheBustingPass);
45702
+ const stripUnheldSignedTurnOnBust = () => {
45703
+ if (isCacheBustingPass && signedTurnOnPrefixBoundModel && !protectedSignedPrefix && !rewritingSignedPrefix)
45704
+ stripForPrefixRewrite();
45705
+ };
45128
45706
  const realStableId = (msg, index) => resolvePiRealStableId(msg, index, args.entryIds, args.entryIdByRef ?? undefined);
45129
45707
  const passFallbackIds = settlePiFallbackOccurrences(args.db, args.sessionId, piContentFallbackIds(args.messages, realStableId));
45130
45708
  const stableIdResolver = (msg, index) => realStableId(msg, index) ?? passFallbackIds[index] ?? resolvePiStableId(msg, index);
@@ -45367,9 +45945,16 @@ async function runPipeline(args) {
45367
45945
  explicitFlush: !protectedSignedPrefix && (args.userFlushOrigin === true || hasPendingMaterializationOrigin(pendingMaterializationSessions, args.sessionId, "user_flush")),
45368
45946
  publishedHistory: !prefixPreflightContended && publishedM1RefreshedThisPass
45369
45947
  };
45370
- let prefixMutationAllowed = !protectedSignedPrefix || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible;
45371
- isCacheBustingPass = prefixMutationAllowed && hasReclaimRide(rideSignals);
45948
+ const ridePermissionGate = {
45949
+ signedThinkingHold: protectedSignedPrefix,
45950
+ firstRender: firstRenderBust,
45951
+ idleExpiry: heldIdleExpiryRebuild,
45952
+ emergency: emergencyDropEligible
45953
+ };
45954
+ let prefixMutationAllowed = prefixMutationPermitted(ridePermissionGate);
45955
+ isCacheBustingPass = reclaimRidePermitted(rideSignals, ridePermissionGate);
45372
45956
  let publishedWorkDrainAllowed = isCacheBustingPass;
45957
+ stripUnheldSignedTurnOnBust();
45373
45958
  const usesTokenProtection = args.protectedTokenTierOverrides !== undefined || args.protectedTokens !== undefined;
45374
45959
  const resolveProtectionFloor = () => resolveEpochFloorForPass(args.db, args.sessionId, {
45375
45960
  configuredOverride: args.protectedTokens,
@@ -45444,6 +46029,7 @@ async function runPipeline(args) {
45444
46029
  deferredMaterializeEligible = canConsumeDeferredLate && deferredMaterializationSessions.has(args.sessionId);
45445
46030
  isCacheBustingPass = prefixMutationAllowed;
45446
46031
  publishedWorkDrainAllowed = isCacheBustingPass;
46032
+ stripUnheldSignedTurnOnBust();
45447
46033
  shouldRunHeuristics = args.heuristics !== undefined;
45448
46034
  if (piM0State && prefixMutationAllowed) {
45449
46035
  try {
@@ -46652,6 +47238,7 @@ function clearContextHandlerSession(sessionId) {
46652
47238
  clearPiChannel1State(sessionId);
46653
47239
  lastHeuristicsTurnIdBySession.delete(sessionId);
46654
47240
  routinePressureAppliedBySession.delete(sessionId);
47241
+ signedThinkingHoldLogKeys.delete(sessionId);
46655
47242
  lastSeenProjectIdentityBySession.delete(sessionId);
46656
47243
  persistedProjectIdentityBySession.delete(sessionId);
46657
47244
  sessionProjectBindingFailureLogAtBySession.delete(sessionId);