@cortexkit/opencode-magic-context 0.44.3 → 0.44.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/{derive-budgets-vjmvh6pz.js → derive-budgets-ncwn1jk9.js} +2 -2
  2. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  3. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  4. package/dist/features/magic-context/memory/embedding-openai.d.ts +1 -0
  5. package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
  6. package/dist/features/magic-context/memory/project-identity.d.ts +5 -4
  7. package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
  8. package/dist/features/magic-context/storage-db.d.ts +6 -1
  9. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  10. package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
  11. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +12 -1
  12. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  13. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
  14. package/dist/hooks/magic-context/event-resolvers.d.ts +7 -0
  15. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  16. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  17. package/dist/hooks/magic-context/inject-compartments.d.ts +5 -0
  18. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  19. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/read-session-chunk.d.ts +4 -2
  21. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/read-session-raw.d.ts +2 -2
  23. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/tokenizer-calibration.d.ts +1 -1
  25. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  26. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
  27. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  28. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  29. package/dist/{index-q5p1aqvv.js → index-mrc0twf3.js} +10 -4
  30. package/dist/{index-9y5p0d50.js → index-msqr3x6m.js} +1 -1
  31. package/dist/{index-y5145x8k.js → index-n96ag4rk.js} +15 -1
  32. package/dist/{index-dgg5y7er.js → index-qm36k34q.js} +55 -12
  33. package/dist/{index-yhm60r53.js → index-sqp1hz9v.js} +180 -36
  34. package/dist/{index-rdsaxnf2.js → index-wprsye9w.js} +1 -1
  35. package/dist/{index-nf9sk8sh.js → index-zx7pmr39.js} +2 -2
  36. package/dist/index.js +88 -35
  37. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  38. package/dist/{read-session-chunk-n072mcq4.js → read-session-chunk-339hg90t.js} +2 -2
  39. package/dist/{recomp-orchestrator-19tr6zya.js → recomp-orchestrator-0ers6smx.js} +5 -5
  40. package/dist/shared/rpc-utils.d.ts +7 -0
  41. package/dist/shared/rpc-utils.d.ts.map +1 -1
  42. package/dist/shared/transcript.d.ts +2 -0
  43. package/dist/shared/transcript.d.ts.map +1 -1
  44. package/dist/shared/user-answer.d.ts +4 -0
  45. package/dist/shared/user-answer.d.ts.map +1 -0
  46. package/dist/{transform-postprocess-phase-z2mfc5w1.js → transform-postprocess-phase-ttdkrm6r.js} +5 -5
  47. package/dist/v2/hooks/payload.d.ts.map +1 -1
  48. package/dist/v2/hooks/store.d.ts +1 -1
  49. package/dist/v2/hooks/store.d.ts.map +1 -1
  50. package/dist/v2/server.js +334 -70
  51. package/dist/v2/store-reader.d.ts +2 -1
  52. package/dist/v2/store-reader.d.ts.map +1 -1
  53. package/dist/{wrapup-orchestrator-sy4m56a7.js → wrapup-orchestrator-x0jvvrqn.js} +6 -6
  54. package/package.json +1 -1
  55. package/src/shared/rpc-utils.test.ts +27 -2
  56. package/src/shared/rpc-utils.ts +44 -15
  57. package/src/shared/tag-transcript.ts +4 -1
  58. package/src/shared/transcript.ts +3 -0
  59. package/src/shared/user-answer.test.ts +40 -0
  60. package/src/shared/user-answer.ts +17 -0
package/dist/v2/server.js CHANGED
@@ -11755,6 +11755,27 @@ function isGitTimeoutError(error) {
11755
11755
  const signal = getErrorSignal(error);
11756
11756
  return code === "ETIMEDOUT" || signal === "SIGTERM" || signal === "SIGKILL" || getErrorKilled(error);
11757
11757
  }
11758
+ function hasUnbornHead(directory) {
11759
+ const options = {
11760
+ cwd: directory,
11761
+ encoding: "utf8",
11762
+ env: { ...process.env, LC_ALL: "C", LANG: "C" },
11763
+ stdio: ["ignore", "pipe", "pipe"],
11764
+ timeout: GIT_TIMEOUT_MS,
11765
+ windowsHide: true
11766
+ };
11767
+ try {
11768
+ execFileSyncForIdentity("git", ["rev-parse", "--git-dir"], options);
11769
+ try {
11770
+ execFileSyncForIdentity("git", ["rev-parse", "--verify", "--quiet", "HEAD"], options);
11771
+ return false;
11772
+ } catch (error) {
11773
+ return !isGitTimeoutError(error) && typeof error === "object" && error !== null && "status" in error && error.status === 1 && getErrorStderr(error) === "";
11774
+ }
11775
+ } catch {
11776
+ return false;
11777
+ }
11778
+ }
11758
11779
  function classifyGitError(error, rawDirectory) {
11759
11780
  if (isGitTimeoutError(error)) {
11760
11781
  return new ProjectIdentityError("git_timeout", rawDirectory, `git rev-list timed out after ${GIT_TIMEOUT_MS}ms`, asError(error));
@@ -11797,7 +11818,11 @@ function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectP
11797
11818
  windowsHide: true
11798
11819
  });
11799
11820
  } catch (error) {
11800
- throw classifyGitError(error, directory);
11821
+ const classified = classifyGitError(error, directory);
11822
+ if (classified.errorClass === "not_git_repo" && hasUnbornHead(canonical)) {
11823
+ throw new ProjectIdentityError("no_commits", directory, "Git repository has no commits yet");
11824
+ }
11825
+ throw classified;
11801
11826
  }
11802
11827
  const rootCommit = output.split(`
11803
11828
  `).map((line) => line.trim().slice(0, 64)).filter((line) => /^[0-9a-f]{7,64}$/.test(line)).sort()[0];
@@ -11937,6 +11962,8 @@ function resolveProjectIdentity(directory, allowHomeProject = homeProjectPermiss
11937
11962
  } catch (error) {
11938
11963
  if (error instanceof ProjectIdentityError && shouldUseDirectoryFallback(error)) {
11939
11964
  const fallback = directoryFallback(canonical);
11965
+ if (error.errorClass === "no_commits")
11966
+ return fallback;
11940
11967
  const hasGitMetadata = hasGitDir(canonical);
11941
11968
  if (!hasGitMetadata) {
11942
11969
  if (error.errorClass === "permission_denied")
@@ -12065,9 +12092,18 @@ function resolveProjectIdentityForSession(directory, allowHomeProject = homeProj
12065
12092
  } catch (error) {
12066
12093
  if (!(error instanceof ProjectIdentityError))
12067
12094
  throw error;
12095
+ const reason = error.errorClass === "git_identity_unavailable" ? pausedIdentityReasons.get(resolvedDirectory) ?? error.errorClass : error.errorClass;
12096
+ pausedIdentityReasons.set(resolvedDirectory, reason);
12097
+ const logKey = `${resolvedDirectory}\x00${reason}`;
12098
+ if (!pausedIdentityLogged.has(logKey)) {
12099
+ pausedIdentityLogged.add(logKey);
12100
+ log(`[magic-context] memory features paused for ${resolvedDirectory}: ${reason}`);
12101
+ }
12068
12102
  identity = undefined;
12069
12103
  }
12070
12104
  }
12105
+ if (identity !== undefined)
12106
+ pausedIdentityReasons.delete(resolvedDirectory);
12071
12107
  sessionIdentityCache.set(cacheKey, {
12072
12108
  identity,
12073
12109
  revalidateAt: identity?.startsWith("git:") === true ? null : nowMs() + TRANSIENT_FAILURE_COOLDOWN_MS
@@ -12108,7 +12144,7 @@ function isLinkedGitWorktree(directory) {
12108
12144
  linkedGitWorktreeCache.set(resolvedDirectory, linked);
12109
12145
  return linked;
12110
12146
  }
12111
- var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, homeProjectPermission = false, homeProjectSkipLogged = false, execFileSyncForIdentity, userHomeDirectoryForIdentity = () => homedir6(), nowMs = () => Date.now(), filesystemProbeObserverForTests, ProjectIdentityError;
12147
+ var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, homeProjectPermission = false, homeProjectSkipLogged = false, pausedIdentityReasons, pausedIdentityLogged, execFileSyncForIdentity, userHomeDirectoryForIdentity = () => homedir6(), nowMs = () => Date.now(), filesystemProbeObserverForTests, ProjectIdentityError;
12112
12148
  var init_project_identity = __esm(() => {
12113
12149
  init_logger();
12114
12150
  init_project_identity_cache();
@@ -12123,6 +12159,8 @@ var init_project_identity = __esm(() => {
12123
12159
  dubiousOwnershipWarnedDirectories = new Set;
12124
12160
  transientGitIdentityReuseLoggedDirectories = new Set;
12125
12161
  sessionIdentityCache = new Map;
12162
+ pausedIdentityReasons = new Map;
12163
+ pausedIdentityLogged = new Set;
12126
12164
  execFileSyncForIdentity = execFileSync;
12127
12165
  ProjectIdentityError = class ProjectIdentityError extends Error {
12128
12166
  errorClass;
@@ -16154,18 +16192,14 @@ function parseCsvLine(line) {
16154
16192
  }
16155
16193
  function parseTasklistOutput(output) {
16156
16194
  const entries = [];
16157
- let sawHeader = false;
16158
16195
  for (const rawLine of output.split(/\r?\n/)) {
16159
16196
  const line = rawLine.trim();
16160
16197
  if (!line)
16161
16198
  continue;
16162
- if (TASKLIST_NO_TASKS_PATTERN.test(line))
16163
- return [];
16164
16199
  const fields = parseCsvLine(line);
16165
16200
  if (!fields)
16166
16201
  continue;
16167
16202
  if (fields[1]?.trim().toLowerCase() === "pid") {
16168
- sawHeader = true;
16169
16203
  continue;
16170
16204
  }
16171
16205
  const pid = Number(fields[1]);
@@ -16173,11 +16207,11 @@ function parseTasklistOutput(output) {
16173
16207
  continue;
16174
16208
  entries.push({ pid, command: fields[0] });
16175
16209
  }
16176
- return entries.length > 0 || sawHeader ? entries : null;
16210
+ return entries;
16177
16211
  }
16178
16212
  function readWindowsProcess(pid) {
16179
16213
  try {
16180
- const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/FI", `PID eq ${pid}`], {
16214
+ const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/NH", "/FI", `PID eq ${pid}`], {
16181
16215
  encoding: "utf8",
16182
16216
  timeout: PS_PROBE_TIMEOUT_MS,
16183
16217
  stdio: ["ignore", "pipe", "pipe"],
@@ -16414,7 +16448,11 @@ function tryReadWindowsCimSnapshot(exec) {
16414
16448
  }
16415
16449
  function tryReadWindowsTasklistSnapshot() {
16416
16450
  try {
16417
- const output = execProcessList(rpcProcessListExecFileSync, "tasklist", ["/FO", "CSV"]);
16451
+ const output = execProcessList(rpcProcessListExecFileSync, "tasklist", [
16452
+ "/FO",
16453
+ "CSV",
16454
+ "/NH"
16455
+ ]);
16418
16456
  const entries = parseTasklistOutput(output);
16419
16457
  if (entries === null)
16420
16458
  return null;
@@ -16619,7 +16657,7 @@ function inspectProcessesAsync(forceFresh = false) {
16619
16657
  snapshot = snapshotFromFacts(facts, "cim");
16620
16658
  } catch {}
16621
16659
  if (!snapshot) {
16622
- const entries = parseTasklistOutput(await asyncProcessExec("tasklist", ["/FO", "CSV"], PS_PROBE_TIMEOUT_MS));
16660
+ const entries = parseTasklistOutput(await asyncProcessExec("tasklist", ["/FO", "CSV", "/NH"], PS_PROBE_TIMEOUT_MS));
16623
16661
  if (entries)
16624
16662
  snapshot = snapshotFromFacts(entries.map(({ pid, command }) => ({
16625
16663
  pid,
@@ -16668,13 +16706,25 @@ function inspectProcessesAsync(forceFresh = false) {
16668
16706
  });
16669
16707
  return asyncInspection;
16670
16708
  }
16671
- var ownRpcServerInstanceIds, RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000, LINUX_CLOCK_TICKS_PER_SECOND = 100, PS_PROBE_TIMEOUT_MS = 1000, WINDOWS_CIM_PROBE_TIMEOUT_MS = 5000, WINDOWS_PROCESS_SNAPSHOT_TTL_MS = 2000, MAX_ANCESTOR_WALK_DEPTH = 16, OPEN_CODE_COMMAND_MARKERS, TASKLIST_NO_TASKS_PATTERN, WINDOWS_CIM_COMMAND = "Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,Name,CommandLine,CreationDate | ConvertTo-Json -Compress", PI_HARNESS_ARC_MARKERS, rpcIdentityReadFileSync, rpcIdentityExecFileSync, rpcIdentityProcessKill, rpcProcessListExecFileSync, rpcIdentityPlatform, rpcIdentityNowMs = () => Date.now(), windowsProcessFactsCache = null, windowsProcessSnapshotCache = null, asyncProcessExec, asyncInspection, asyncInspectionExpires = 0, lastAsyncSnapshot = null;
16709
+ function inspectWindowsProcessesSync() {
16710
+ const snapshot = tryReadWindowsCimSnapshot(rpcProcessListExecFileSync) ?? tryReadWindowsTasklistSnapshot();
16711
+ const byPid = new Map(snapshot?.facts.map((fact) => [fact.pid, fact]));
16712
+ return {
16713
+ pi: snapshot ? classifyLivePiSnapshot(snapshot) : { state: "unreadable", processIds: [] },
16714
+ ...snapshot ? { processSnapshot: { source: snapshot.source, facts: snapshot.facts } } : {},
16715
+ evidence: (pid) => ({
16716
+ startTime: byPid.get(pid)?.startTime ?? null,
16717
+ commandLine: byPid.get(pid)?.commandLine ?? byPid.get(pid)?.imageName ?? null
16718
+ }),
16719
+ liveness: (pid) => byPid.has(pid) ? "alive" : snapshot ? "dead" : "inconclusive"
16720
+ };
16721
+ }
16722
+ var ownRpcServerInstanceIds, RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000, LINUX_CLOCK_TICKS_PER_SECOND = 100, PS_PROBE_TIMEOUT_MS = 1000, WINDOWS_CIM_PROBE_TIMEOUT_MS = 5000, WINDOWS_PROCESS_SNAPSHOT_TTL_MS = 2000, MAX_ANCESTOR_WALK_DEPTH = 16, OPEN_CODE_COMMAND_MARKERS, WINDOWS_CIM_COMMAND = "Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,Name,CommandLine,CreationDate | ConvertTo-Json -Compress", PI_HARNESS_ARC_MARKERS, rpcIdentityReadFileSync, rpcIdentityExecFileSync, rpcIdentityProcessKill, rpcProcessListExecFileSync, rpcIdentityPlatform, rpcIdentityNowMs = () => Date.now(), windowsProcessFactsCache = null, windowsProcessSnapshotCache = null, asyncProcessExec, asyncInspection, asyncInspectionExpires = 0, lastAsyncSnapshot = null;
16672
16723
  var init_rpc_utils = __esm(() => {
16673
16724
  init_logger();
16674
16725
  init_pi_executable();
16675
16726
  ownRpcServerInstanceIds = new Set;
16676
16727
  OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
16677
- TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
16678
16728
  PI_HARNESS_ARC_MARKERS = [
16679
16729
  "pi-coding-agent",
16680
16730
  "oh-my-pi",
@@ -22313,8 +22363,8 @@ function readRawSessionMessagesFromDb(db, sessionId) {
22313
22363
  };
22314
22364
  });
22315
22365
  }
22316
- function readRawSessionMessagePageFromDb(db, sessionId, afterOrdinal, limit, finalWatermark = Number.MAX_SAFE_INTEGER) {
22317
- const messageRows = readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark);
22366
+ function readRawSessionMessagePageFromDb(db, sessionId, afterOrdinal, limit, finalWatermark = Number.MAX_SAFE_INTEGER, after) {
22367
+ const messageRows = readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark, after);
22318
22368
  if (messageRows.length === 0)
22319
22369
  return [];
22320
22370
  const placeholders = messageRows.map(() => "?").join(", ");
@@ -22325,15 +22375,22 @@ function readRawSessionMessagePageFromDb(db, sessionId, afterOrdinal, limit, fin
22325
22375
  ORDER BY message_id ASC, time_created ASC, id ASC`).all(sessionId, ...messageRows.map((row) => row.id)).filter(isRawPartRow);
22326
22376
  return assembleRawMessagePage(messageRows, partRows);
22327
22377
  }
22328
- function readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark) {
22378
+ function readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark, after) {
22329
22379
  const remaining = Math.max(0, Math.floor(finalWatermark) - Math.floor(afterOrdinal));
22330
22380
  const pageSize = Math.min(Math.max(1, Math.floor(limit)), remaining);
22331
22381
  if (pageSize === 0)
22332
22382
  return [];
22383
+ const parameters = [sessionId];
22384
+ if (after)
22385
+ parameters.push(after.timeCreated, after.timeCreated, after.timeCreated, after.id);
22386
+ parameters.push(pageSize);
22387
+ if (!after)
22388
+ parameters.push(Math.max(0, Math.floor(afterOrdinal)));
22333
22389
  return db.prepare(`SELECT id, data, time_created, time_updated
22334
22390
  FROM message
22335
22391
  WHERE session_id = ?
22336
- AND NOT (
22392
+ ${after ? "AND time_created >= ? AND (time_created > ? OR (time_created = ? AND id > ?))" : ""}
22393
+ AND NOT (
22337
22394
  CASE WHEN json_valid(data) = 1
22338
22395
  THEN COALESCE(json_extract(data, '$.summary'), 0)
22339
22396
  ELSE 0 END = 1
@@ -22342,7 +22399,7 @@ function readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWaterma
22342
22399
  ELSE '' END = 'stop'
22343
22400
  )
22344
22401
  ORDER BY time_created ASC, id ASC
22345
- LIMIT ? OFFSET ?`).all(sessionId, pageSize, Math.max(0, Math.floor(afterOrdinal))).filter(isRawMessageRow).map((row, index) => ({
22402
+ LIMIT ? ${after ? "" : "OFFSET ?"}`).all(...parameters).filter(isRawMessageRow).map((row, index) => ({
22346
22403
  ...row,
22347
22404
  ordinal: Math.floor(afterOrdinal) + index + 1
22348
22405
  }));
@@ -22369,8 +22426,8 @@ function assembleRawMessagePage(messageRows, partRows) {
22369
22426
  function summaryStringField(jsonPath) {
22370
22427
  return `CASE WHEN json_type(data, '${jsonPath}') = 'text' THEN substr(json_extract(data, '${jsonPath}'), 1, ${RAW_SUMMARY_ARG_MAX_CHARS}) END`;
22371
22428
  }
22372
- function readRawSessionMessageSummaryPageFromDb(db, sessionId, afterOrdinal, limit, finalWatermark = Number.MAX_SAFE_INTEGER) {
22373
- const messageRows = readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark);
22429
+ function readRawSessionMessageSummaryPageFromDb(db, sessionId, afterOrdinal, limit, finalWatermark = Number.MAX_SAFE_INTEGER, after) {
22430
+ const messageRows = readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark, after);
22374
22431
  if (messageRows.length === 0)
22375
22432
  return [];
22376
22433
  const placeholders = messageRows.map(() => "?").join(", ");
@@ -23238,6 +23295,28 @@ var init_tag_part_guards = __esm(() => {
23238
23295
  init_tag_content_primitives();
23239
23296
  });
23240
23297
 
23298
+ // src/shared/user-answer.ts
23299
+ function hasUserAnswerMetadata(value) {
23300
+ if (!isRecord3(value))
23301
+ return false;
23302
+ if (value.userAnswer === true)
23303
+ return true;
23304
+ if (Array.isArray(value.answers))
23305
+ return true;
23306
+ if (typeof value.answer === "string")
23307
+ return true;
23308
+ if (Array.isArray(value.selectedOptions) || typeof value.customInput === "string")
23309
+ return true;
23310
+ return Array.isArray(value.results) && value.results.some(hasUserAnswerMetadata);
23311
+ }
23312
+ function toolPartHasUserAnswer(part) {
23313
+ if (!isRecord3(part))
23314
+ return false;
23315
+ const state = isRecord3(part.state) ? part.state : undefined;
23316
+ return hasUserAnswerMetadata(state?.metadata) || hasUserAnswerMetadata(part.details);
23317
+ }
23318
+ var init_user_answer = () => {};
23319
+
23241
23320
  // src/features/magic-context/dreamer/token-budget.ts
23242
23321
  function registerBudgetFinalizeChild(sessionId, guard) {
23243
23322
  finalizingChildren.set(sessionId, guard);
@@ -23827,6 +23906,20 @@ var init_tokenizer_calibration_seeds = __esm(() => {
23827
23906
  toolsRatio: 0.850953,
23828
23907
  proseRatio: 1.000017
23829
23908
  },
23909
+ {
23910
+ prefix: "openai/gpt-6-sol",
23911
+ systemRatio: 1.000278,
23912
+ toolsRatio: 0.850953,
23913
+ proseRatio: 1.000017,
23914
+ provenance: "Mirrored from openai/gpt-6-astra; prose inherited-unmeasured. Reported OAuth system/tools counts match GPT-5.5; no independent API-key measurement."
23915
+ },
23916
+ {
23917
+ prefix: "openai/gpt-6.1-sol",
23918
+ systemRatio: 1.000278,
23919
+ toolsRatio: 0.850953,
23920
+ proseRatio: 1.000017,
23921
+ provenance: "Mirrored from openai/gpt-6-astra; prose inherited-unmeasured. Reported OAuth system/tools counts match GPT-5.5; no independent API-key measurement."
23922
+ },
23830
23923
  {
23831
23924
  prefix: "openai/gpt-5",
23832
23925
  systemRatio: 1,
@@ -24180,7 +24273,7 @@ function calibrateBuckets(input) {
24180
24273
  toolCallTokens: toolCalls
24181
24274
  };
24182
24275
  }
24183
- var CALIBRATION_TABLE, NEUTRAL, CALIBRATION_TABLE_REVISION = "2026-09-23-model-id-generation-v2", UNKNOWN_FIT_RATIO;
24276
+ var CALIBRATION_TABLE, NEUTRAL, CALIBRATION_TABLE_REVISION = "2026-09-30-sol-tokenizer-seeds-v3", UNKNOWN_FIT_RATIO;
24184
24277
  var init_tokenizer_calibration = __esm(() => {
24185
24278
  init_tokenizer_calibration_seeds();
24186
24279
  CALIBRATION_TABLE = tokenizer_calibration_seeds_default;
@@ -24828,7 +24921,7 @@ function createToolDropTarget(compositeKey, thinkingParts, index, batch, tagId)
24828
24921
  },
24829
24922
  canDrop: () => {
24830
24923
  const entry = index.get(compositeKey);
24831
- return !!entry && entry.occurrences.length > 0 && entry.hasResult;
24924
+ return !!entry && entry.occurrences.length > 0 && entry.hasResult && !entry.occurrences.some((occurrence) => toolPartHasUserAnswer(occurrence.part));
24832
24925
  },
24833
24926
  requiresToolArcSkeleton: thinkingParts.length > 0 || (index.get(compositeKey)?.occurrences.some((occurrence) => messageHasNativeReasoning(occurrence.message)) ?? false),
24834
24927
  readInput: () => {
@@ -24853,6 +24946,7 @@ function createToolDropTarget(compositeKey, thinkingParts, index, batch, tagId)
24853
24946
  }
24854
24947
  var DROP_PREFIX = "[dropped", IGNORE_PART_TYPES;
24855
24948
  var init_tool_drop_target = __esm(() => {
24949
+ init_user_answer();
24856
24950
  init_dropped_input_guard();
24857
24951
  init_edit_marker();
24858
24952
  init_final_wire_token_estimate();
@@ -25003,6 +25097,8 @@ function getRawSessionMessageOrdinalCount(sessionId) {
25003
25097
  }
25004
25098
  function readRawSessionMessageRangeFromSource(sessionId, fromOrdinal, toOrdinal) {
25005
25099
  const provider = sessionProviders.get(sessionId);
25100
+ if (provider?.iterateMessageRange)
25101
+ return [...provider.iterateMessageRange(fromOrdinal, toOrdinal)];
25006
25102
  if (provider && !provider.readMessagePage) {
25007
25103
  return provider.readMessages().filter((message) => message.ordinal >= fromOrdinal && message.ordinal <= toOrdinal);
25008
25104
  }
@@ -25010,9 +25106,10 @@ function readRawSessionMessageRangeFromSource(sessionId, fromOrdinal, toOrdinal)
25010
25106
  return [];
25011
25107
  const messages = [];
25012
25108
  let afterOrdinal = fromOrdinal - 1;
25109
+ let after;
25013
25110
  while (afterOrdinal < toOrdinal) {
25014
25111
  const limit = Math.min(RAW_MESSAGE_RANGE_PAGE_SIZE, toOrdinal - afterOrdinal);
25015
- const page = provider?.readMessagePage ? provider.readMessagePage(afterOrdinal, limit, toOrdinal) : withReadOnlySessionDb((db) => readRawSessionMessagePageFromDb(db, sessionId, afterOrdinal, limit, toOrdinal));
25112
+ const page = provider?.readMessagePage ? provider.readMessagePage(afterOrdinal, limit, toOrdinal, after) : withReadOnlySessionDb((db) => readRawSessionMessagePageFromDb(db, sessionId, afterOrdinal, limit, toOrdinal, after));
25016
25113
  if (page.length === 0)
25017
25114
  break;
25018
25115
  let nextOrdinal = afterOrdinal;
@@ -25025,6 +25122,8 @@ function readRawSessionMessageRangeFromSource(sessionId, fromOrdinal, toOrdinal)
25025
25122
  if (nextOrdinal <= afterOrdinal)
25026
25123
  break;
25027
25124
  afterOrdinal = nextOrdinal;
25125
+ const last = page.at(-1);
25126
+ after = last ? { timeCreated: last.createdAt ?? 0, id: last.id } : undefined;
25028
25127
  }
25029
25128
  return messages;
25030
25129
  }
@@ -25034,6 +25133,13 @@ function visitRawSessionMessages(sessionId, fromOrdinal, toOrdinal, visit, optio
25034
25133
  if (to < from)
25035
25134
  return;
25036
25135
  const provider = sessionProviders.get(sessionId);
25136
+ if (provider?.iterateMessageRange) {
25137
+ for (const message of provider.iterateMessageRange(from, to)) {
25138
+ if (!visit(message))
25139
+ return;
25140
+ }
25141
+ return;
25142
+ }
25037
25143
  if (provider && !provider.readMessagePage) {
25038
25144
  for (const message of provider.readMessages()) {
25039
25145
  if (message.ordinal < from || message.ordinal > to)
@@ -25047,10 +25153,11 @@ function visitRawSessionMessages(sessionId, fromOrdinal, toOrdinal, visit, optio
25047
25153
  return;
25048
25154
  const pageSize = Math.max(1, Math.floor(options.pageSize ?? RAW_MESSAGE_VISIT_PAGE_SIZE));
25049
25155
  let afterOrdinal = from - 1;
25156
+ let after;
25050
25157
  while (afterOrdinal < to) {
25051
25158
  const limit = Math.min(pageSize, to - afterOrdinal);
25052
25159
  const cursor = afterOrdinal;
25053
- const page = provider?.readMessagePage ? provider.readMessagePage(cursor, limit, to) : withReadOnlySessionDb((db) => options.summary ? readRawSessionMessageSummaryPageFromDb(db, sessionId, cursor, limit, to) : readRawSessionMessagePageFromDb(db, sessionId, cursor, limit, to));
25160
+ const page = provider?.readMessagePage ? provider.readMessagePage(cursor, limit, to, after) : withReadOnlySessionDb((db) => options.summary ? readRawSessionMessageSummaryPageFromDb(db, sessionId, cursor, limit, to, after) : readRawSessionMessagePageFromDb(db, sessionId, cursor, limit, to, after));
25054
25161
  if (page.length === 0)
25055
25162
  return;
25056
25163
  let nextOrdinal = afterOrdinal;
@@ -25064,6 +25171,8 @@ function visitRawSessionMessages(sessionId, fromOrdinal, toOrdinal, visit, optio
25064
25171
  if (nextOrdinal <= afterOrdinal)
25065
25172
  return;
25066
25173
  afterOrdinal = nextOrdinal;
25174
+ const last = page.at(-1);
25175
+ after = last ? { timeCreated: last.createdAt ?? 0, id: last.id } : undefined;
25067
25176
  }
25068
25177
  }
25069
25178
  function readRawSessionMessageRange(sessionId, fromOrdinal, toOrdinal) {
@@ -32787,7 +32896,9 @@ function classifyJunkDiscovery(portFile, raw, staleFiles) {
32787
32896
  log(`[magic-context] removing stale RPC discovery file ${portFile}: ${reason} record older than 10 minutes`);
32788
32897
  return null;
32789
32898
  }
32790
- function inspectRpcServerDiscovery(storageDir, processes) {
32899
+ function inspectRpcServerDiscovery(storageDir, processes, options) {
32900
+ const deadline = options?.deadlineMs === undefined ? Number.POSITIVE_INFINITY : Date.now() + options.deadlineMs;
32901
+ let progressAt = Date.now() + 3000;
32791
32902
  const rpcRoot = join9(storageDir, "rpc");
32792
32903
  let projectEntries;
32793
32904
  try {
@@ -32820,11 +32931,19 @@ function inspectRpcServerDiscovery(storageDir, processes) {
32820
32931
  if (portFiles.length === 0) {
32821
32932
  return { state: "absent", serverPids: [], staleFiles: [] };
32822
32933
  }
32934
+ if (!processes && process.platform === "win32")
32935
+ processes = inspectWindowsProcessesSync();
32823
32936
  const pids = new Set;
32824
32937
  const processByPid = new Map;
32825
32938
  const staleFiles = [];
32826
32939
  const inconclusivePids = new Set;
32827
- for (const portFile of portFiles) {
32940
+ for (const [index, portFile] of portFiles.entries()) {
32941
+ if (Date.now() >= deadline)
32942
+ throw new Error(`RPC holder inspection timed out after ${Math.round((options?.deadlineMs ?? 0) / 1000)} seconds (${index}/${portFiles.length} records checked). Close OpenCode and Pi, then retry.`);
32943
+ if (options?.onProgress && Date.now() >= progressAt) {
32944
+ options.onProgress(index, portFiles.length);
32945
+ progressAt = Date.now() + 3000;
32946
+ }
32828
32947
  let raw;
32829
32948
  try {
32830
32949
  raw = rpcDiscoveryFs.readFileSync(portFile, "utf8");
@@ -32862,7 +32981,7 @@ function inspectRpcServerDiscovery(storageDir, processes) {
32862
32981
  if (!previous || previous.kind === "process" && detected.kind !== "process") {
32863
32982
  processByPid.set(record.pid, detected);
32864
32983
  }
32865
- } else if (identity === "implausible") {
32984
+ } else if (identity === "implausible" && !((processes?.processSnapshot?.source === "cim" || processes?.processSnapshot?.source === "tasklist") && liveness === "alive")) {
32866
32985
  staleFiles.push(portFile);
32867
32986
  } else {
32868
32987
  inconclusivePids.add(record.pid);
@@ -74329,6 +74448,28 @@ var init_embedding_ssrf = __esm(() => {
74329
74448
  });
74330
74449
 
74331
74450
  // src/features/magic-context/memory/embedding-openai.ts
74451
+ function capEmbeddingInput(input, maxInputTokens, purpose) {
74452
+ const ratio = purpose === "query" ? CHUNK_WINDOW_SAFETY_RATIO : 1;
74453
+ const budget = Math.max(1, Math.floor(maxInputTokens * ratio));
74454
+ if (estimateTokens(input) <= budget)
74455
+ return input;
74456
+ let low = 0;
74457
+ let high = input.length;
74458
+ while (low < high) {
74459
+ const mid = Math.ceil((low + high) / 2);
74460
+ if (estimateTokens(input.slice(0, mid)) <= budget)
74461
+ low = mid;
74462
+ else
74463
+ high = mid - 1;
74464
+ }
74465
+ if (low > 0 && low < input.length) {
74466
+ const last = input.charCodeAt(low - 1);
74467
+ const next = input.charCodeAt(low);
74468
+ if (last >= 55296 && last <= 56319 && next >= 56320 && next <= 57343)
74469
+ low -= 1;
74470
+ }
74471
+ return input.slice(0, low);
74472
+ }
74332
74473
  function normalizeEndpoint3(endpoint) {
74333
74474
  return endpoint?.trim().replace(/\/+$/, "") ?? "";
74334
74475
  }
@@ -74351,6 +74492,7 @@ class OpenAICompatibleEmbeddingProvider {
74351
74492
  modelMismatchLogged = false;
74352
74493
  lastFailureReason = null;
74353
74494
  halfOpenProbeInFlight = false;
74495
+ queryTruncationLogged = false;
74354
74496
  constructor(options) {
74355
74497
  this.endpoint = normalizeEndpoint3(options.endpoint);
74356
74498
  this.model = options.model?.trim() ?? "";
@@ -74404,7 +74546,15 @@ class OpenAICompatibleEmbeddingProvider {
74404
74546
  return [];
74405
74547
  }
74406
74548
  const textPrefix = purpose === "query" ? this.queryPrefix : this.documentPrefix;
74407
- const requestTexts = texts.map((text) => `${textPrefix}${text.trim().length === 0 ? " " : text}`);
74549
+ const requestTexts = texts.map((text) => {
74550
+ const input = `${textPrefix}${text.trim().length === 0 ? " " : text}`;
74551
+ const capped = capEmbeddingInput(input, this.maxInputTokens, purpose);
74552
+ if (purpose === "query" && capped.length < input.length && !this.queryTruncationLogged) {
74553
+ log(`[magic-context] embedding query truncated from ${input.length} to ${capped.length} characters to fit max_input_tokens`);
74554
+ this.queryTruncationLogged = true;
74555
+ }
74556
+ return capped;
74557
+ });
74408
74558
  if (!await this.initialize()) {
74409
74559
  return Array.from({ length: texts.length }, () => null);
74410
74560
  }
@@ -74613,8 +74763,10 @@ class OpenAICompatibleEmbeddingProvider {
74613
74763
  }
74614
74764
  var FAILURE_THRESHOLD = 3, FAILURE_WINDOW_MS = 60000, OPEN_DURATION_MS, FETCH_TIMEOUT_MS = 30000;
74615
74765
  var init_embedding_openai = __esm(() => {
74766
+ init_read_session_formatting();
74616
74767
  init_logger();
74617
74768
  init_redaction();
74769
+ init_compartment_chunk_embedding();
74618
74770
  init_embedding_identity();
74619
74771
  init_embedding_model_match();
74620
74772
  init_embedding_ssrf();
@@ -84124,7 +84276,7 @@ var init_render_trigger = __esm(async () => {
84124
84276
  });
84125
84277
 
84126
84278
  // src/hooks/magic-context/compartment-render-epoch.ts
84127
- function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH, muralEnabled = null, renderBudgetIdentity = null, memoryRenderEpoch = MEMORY_RENDER_FORMAT_EPOCH) {
84279
+ function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH, muralEnabled = null, renderBudgetIdentity = null, memoryRenderEpoch = MEMORY_RENDER_FORMAT_EPOCH, renderedBudgets = null) {
84128
84280
  let encoded = upgradeState ?? "";
84129
84281
  if (compartmentRenderEpoch !== null) {
84130
84282
  encoded += `${EPOCH_COMPONENT_PREFIX}${compartmentRenderEpoch}`;
@@ -84138,6 +84290,9 @@ function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = CO
84138
84290
  if (renderBudgetIdentity !== null) {
84139
84291
  encoded += `${BUDGET_COMPONENT_PREFIX}${renderBudgetIdentity}`;
84140
84292
  }
84293
+ if (renderedBudgets !== null) {
84294
+ encoded += `${RENDERED_BUDGETS_COMPONENT_PREFIX}${renderedBudgets}`;
84295
+ }
84141
84296
  return encoded.length > 0 ? encoded : null;
84142
84297
  }
84143
84298
  function component(value, prefix) {
@@ -84156,14 +84311,16 @@ function decodeCachedM0UpgradeIdentity(value) {
84156
84311
  compartmentRenderEpoch: null,
84157
84312
  memoryRenderEpoch: null,
84158
84313
  muralEnabled: null,
84159
- renderBudgetIdentity: null
84314
+ renderBudgetIdentity: null,
84315
+ renderedBudgets: null
84160
84316
  };
84161
84317
  }
84162
84318
  const componentIndexes = [
84163
84319
  value.indexOf(EPOCH_COMPONENT_PREFIX),
84164
84320
  value.indexOf(MEMORY_EPOCH_COMPONENT_PREFIX),
84165
84321
  value.indexOf(MURAL_COMPONENT_PREFIX),
84166
- value.indexOf(BUDGET_COMPONENT_PREFIX)
84322
+ value.indexOf(BUDGET_COMPONENT_PREFIX),
84323
+ value.indexOf(RENDERED_BUDGETS_COMPONENT_PREFIX)
84167
84324
  ].filter((index) => index >= 0);
84168
84325
  const identityEnd = componentIndexes.length > 0 ? Math.min(...componentIndexes) : value.length;
84169
84326
  const upgradeState = value.slice(0, identityEnd);
@@ -84173,10 +84330,37 @@ function decodeCachedM0UpgradeIdentity(value) {
84173
84330
  compartmentRenderEpoch: component(value, EPOCH_COMPONENT_PREFIX),
84174
84331
  memoryRenderEpoch: component(value, MEMORY_EPOCH_COMPONENT_PREFIX),
84175
84332
  muralEnabled: muralComponent === "1" ? true : muralComponent === "0" ? false : null,
84176
- renderBudgetIdentity: component(value, BUDGET_COMPONENT_PREFIX)
84333
+ renderBudgetIdentity: component(value, BUDGET_COMPONENT_PREFIX),
84334
+ renderedBudgets: component(value, RENDERED_BUDGETS_COMPONENT_PREFIX)
84177
84335
  };
84178
84336
  }
84179
- var COMPARTMENT_RENDER_EPOCH = "cre2", MEMORY_RENDER_FORMAT_EPOCH = "mre3", EPOCH_COMPONENT_PREFIX = "|compartment-render:", MEMORY_EPOCH_COMPONENT_PREFIX = "|memory-render:", MURAL_COMPONENT_PREFIX = "|mural-enabled:", BUDGET_COMPONENT_PREFIX = "|render-budgets:";
84337
+ function renderBudgetIdentityChanged(cached, current) {
84338
+ const legacy = /^(m[^-]+)-h\d+$/.exec(cached);
84339
+ if (legacy && current.startsWith("m") && current.includes("-hp")) {
84340
+ return legacy[1] !== current.slice(0, current.indexOf("-h"));
84341
+ }
84342
+ return cached !== current;
84343
+ }
84344
+ function renderedBudgetSnapshot(memoryTokens, historyTokens) {
84345
+ return `m${memoryTokens}-h${historyTokens}`;
84346
+ }
84347
+ function readRenderedBudgets(value) {
84348
+ const match = value?.match(/^m(\d+(?:\.\d+)?)-h(\d+(?:\.\d+)?)$/);
84349
+ if (!match)
84350
+ return null;
84351
+ const memory = Number(match[1]);
84352
+ const history = Number(match[2]);
84353
+ return Number.isFinite(memory) && Number.isFinite(history) ? { memory, history } : null;
84354
+ }
84355
+ function renderedBudgetShrinkReason(cached, current) {
84356
+ const before = readRenderedBudgets(cached);
84357
+ const after = readRenderedBudgets(current);
84358
+ if (!before || !after)
84359
+ return null;
84360
+ const shrunk = (oldTokens, newTokens) => oldTokens - newTokens > Math.max(64, oldTokens * 0.01);
84361
+ return shrunk(before.memory, after.memory) || shrunk(before.history, after.history) ? `render_config:budget_shrink(${cached}→${current})` : null;
84362
+ }
84363
+ var COMPARTMENT_RENDER_EPOCH = "cre2", MEMORY_RENDER_FORMAT_EPOCH = "mre3", EPOCH_COMPONENT_PREFIX = "|compartment-render:", MEMORY_EPOCH_COMPONENT_PREFIX = "|memory-render:", MURAL_COMPONENT_PREFIX = "|mural-enabled:", BUDGET_COMPONENT_PREFIX = "|render-budgets:", RENDERED_BUDGETS_COMPONENT_PREFIX = "|rendered-budgets:";
84180
84364
 
84181
84365
  // src/hooks/magic-context/decay-curve.ts
84182
84366
  function tier(compartmentIndex, importance, budgetPressure) {
@@ -84876,8 +85060,8 @@ function lastCompartmentBoundaryId(compartments) {
84876
85060
  const last = compartments.at(-1);
84877
85061
  return last?.endMessageId && last.endMessageId.length > 0 ? last.endMessageId : null;
84878
85062
  }
84879
- function renderBudgetIdentity(memoryBudget, historyBudget) {
84880
- return `m${memoryBudget ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${historyBudget ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
85063
+ function renderBudgetIdentity(memoryBudget, historyBudget, historyPolicy) {
85064
+ return `m${memoryBudget ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${historyPolicy ?? historyBudget ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
84881
85065
  }
84882
85066
  function readProjectDocsForM0(projectDirectory, injectDocs) {
84883
85067
  return projectDirectory && injectDocs !== false ? readProjectDocsCanonical(projectDirectory) : EMPTY_PROJECT_DOCS;
@@ -85057,7 +85241,8 @@ function readCurrentM0SnapshotMarkersUncached(args) {
85057
85241
  modelKey: piModelRefToCanonical(hard.modelKey),
85058
85242
  projectIdentity: args.projectPath ?? null,
85059
85243
  muralEnabled: args.memoryEnabled !== false && args.muralEnabled === true,
85060
- renderBudgetIdentity: renderBudgetIdentity(args.memoryInjectionBudgetTokens, args.historyBudgetTokens)
85244
+ renderBudgetIdentity: renderBudgetIdentity(args.memoryInjectionBudgetTokens, args.historyBudgetTokens, args.historyBudgetPolicyIdentity),
85245
+ renderedBudgets: renderedBudgetSnapshot(args.memoryInjectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS, args.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS)
85061
85246
  }
85062
85247
  };
85063
85248
  }
@@ -85071,7 +85256,8 @@ function refreshVolatileMarkerInputs(markers, args) {
85071
85256
  modelKey: hard.modelKey,
85072
85257
  projectIdentity: args.projectPath ?? null,
85073
85258
  muralEnabled: args.memoryEnabled !== false && args.muralEnabled === true,
85074
- renderBudgetIdentity: renderBudgetIdentity(args.memoryInjectionBudgetTokens, args.historyBudgetTokens)
85259
+ renderBudgetIdentity: renderBudgetIdentity(args.memoryInjectionBudgetTokens, args.historyBudgetTokens, args.historyBudgetPolicyIdentity),
85260
+ renderedBudgets: renderedBudgetSnapshot(args.memoryInjectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS, args.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS)
85075
85261
  };
85076
85262
  }
85077
85263
  function readCurrentM0SnapshotMarkers(args) {
@@ -85141,7 +85327,8 @@ function snapshotMarkersFromCachedM0(state) {
85141
85327
  projectIdentity: state.cachedM0ProjectIdentity ?? null,
85142
85328
  muralHash: state.cachedM0MuralHash ?? null,
85143
85329
  muralEnabled: cachedUpgradeIdentity.muralEnabled,
85144
- renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity
85330
+ renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity,
85331
+ renderedBudgets: cachedUpgradeIdentity.renderedBudgets
85145
85332
  };
85146
85333
  }
85147
85334
  function cachedMemoryDerivedSurfacePresent(state) {
@@ -85156,14 +85343,26 @@ function mustMaterialize(args) {
85156
85343
  const current = readCurrentM0SnapshotMarkers(args);
85157
85344
  const cachedUpgradeIdentity = decodeCachedM0UpgradeIdentity(args.state.cachedM0UpgradeState);
85158
85345
  if (args.memoryEnabled === false && cachedMemoryDerivedSurfacePresent(args.state)) {
85159
- return { value: true, reason: "render_config" };
85346
+ return { value: true, reason: "render_config:memory_disabled" };
85160
85347
  }
85161
85348
  if (cachedUpgradeIdentity.compartmentRenderEpoch !== current.compartmentRenderEpoch) {
85162
85349
  return { value: true, reason: "compartment_render_epoch" };
85163
85350
  }
85164
- if (cachedUpgradeIdentity.muralEnabled !== null && cachedUpgradeIdentity.muralEnabled !== current.muralEnabled || cachedUpgradeIdentity.renderBudgetIdentity !== null && cachedUpgradeIdentity.renderBudgetIdentity !== current.renderBudgetIdentity) {
85165
- return { value: true, reason: "render_config" };
85351
+ if (cachedUpgradeIdentity.muralEnabled !== null && cachedUpgradeIdentity.muralEnabled !== current.muralEnabled) {
85352
+ return {
85353
+ value: true,
85354
+ reason: `render_config:mural(${cachedUpgradeIdentity.muralEnabled}→${current.muralEnabled})`
85355
+ };
85356
+ }
85357
+ if (cachedUpgradeIdentity.renderBudgetIdentity !== null && current.renderBudgetIdentity != null && renderBudgetIdentityChanged(cachedUpgradeIdentity.renderBudgetIdentity, current.renderBudgetIdentity)) {
85358
+ return {
85359
+ value: true,
85360
+ reason: `render_config:budget(${cachedUpgradeIdentity.renderBudgetIdentity}→${current.renderBudgetIdentity})`
85361
+ };
85166
85362
  }
85363
+ const budgetShrinkReason = renderedBudgetShrinkReason(cachedUpgradeIdentity.renderedBudgets, current.renderedBudgets);
85364
+ if (budgetShrinkReason)
85365
+ return { value: true, reason: budgetShrinkReason };
85167
85366
  const canonicalHardModelKey = piModelRefToCanonical(hard.modelKey);
85168
85367
  const canonicalCachedModelKey = piModelRefToCanonical(args.state.cachedM0ModelKey ?? "");
85169
85368
  if (canonicalHardModelKey !== "" && canonicalHardModelKey !== canonicalCachedModelKey) {
@@ -85516,7 +85715,7 @@ function applyMarkersToState(state, m0Bytes, markers, m1Bytes) {
85516
85715
  state.cachedM0ProjectDocsHash = markers.projectDocsHash;
85517
85716
  state.cachedM0MaterializedAt = markers.materializedAt;
85518
85717
  state.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
85519
- state.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch);
85718
+ state.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null);
85520
85719
  state.cachedM0SystemHash = markers.systemHash;
85521
85720
  state.cachedM0ToolSetHash = markers.toolSetHash;
85522
85721
  state.cachedM0ModelKey = markers.modelKey;
@@ -85568,6 +85767,7 @@ function materializeM0(options) {
85568
85767
  muralEnabled: options.muralEnabled,
85569
85768
  memoryInjectionBudgetTokens: options.memoryInjectionBudgetTokens,
85570
85769
  historyBudgetTokens: options.historyBudgetTokens,
85770
+ historyBudgetPolicyIdentity: options.historyBudgetPolicyIdentity,
85571
85771
  hardSignals: options.hardSignals,
85572
85772
  workspaceIdentitySet: {
85573
85773
  identities: workspace.identities,
@@ -85668,7 +85868,8 @@ function materializeM0(options) {
85668
85868
  modelKey: snapshotMarkers.modelKey,
85669
85869
  projectIdentity: projectPath ?? null,
85670
85870
  muralEnabled: snapshotMarkers.muralEnabled,
85671
- renderBudgetIdentity: snapshotMarkers.renderBudgetIdentity
85871
+ renderBudgetIdentity: snapshotMarkers.renderBudgetIdentity,
85872
+ renderedBudgets: snapshotMarkers.renderedBudgets
85672
85873
  };
85673
85874
  const memoryEpochStale = current.workspaceFingerprint !== null || snapshotMarkers.workspaceFingerprint !== null ? current.workspaceFingerprint !== snapshotMarkers.workspaceFingerprint : current.projectMemoryEpoch !== snapshotMarkers.projectMemoryEpoch;
85674
85875
  const stale = memoryEpochStale || current.projectUserProfileVersion !== snapshotMarkers.projectUserProfileVersion || current.maxCompartmentSeq !== snapshotMarkers.maxCompartmentSeq || current.maxMutationId !== snapshotMarkers.maxMutationId || current.maxMemoryMutationId !== snapshotMarkers.maxMemoryMutationId || current.sessionFactsVersion !== snapshotMarkers.sessionFactsVersion || current.upgradeState !== snapshotMarkers.upgradeState || (current.projectIdentity ?? null) !== (snapshotMarkers.projectIdentity ?? null);
@@ -85703,7 +85904,7 @@ function materializeM0(options) {
85703
85904
  projectDocsHash: snapshotMarkers.projectDocsHash,
85704
85905
  materializedAt: snapshotMarkers.materializedAt,
85705
85906
  sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
85706
- upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch),
85907
+ upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity, snapshotMarkers.memoryRenderEpoch, snapshotMarkers.renderedBudgets ?? null),
85707
85908
  systemHash: snapshotMarkers.systemHash,
85708
85909
  toolSetHash: snapshotMarkers.toolSetHash,
85709
85910
  modelKey: snapshotMarkers.modelKey,
@@ -85966,7 +86167,8 @@ function markersFromCachedRow(row) {
85966
86167
  projectIdentity: row.cached_m0_project_identity ?? null,
85967
86168
  muralHash: row.cached_m0_mural_hash ?? null,
85968
86169
  muralEnabled: cachedUpgradeIdentity.muralEnabled,
85969
- renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity
86170
+ renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity,
86171
+ renderedBudgets: cachedUpgradeIdentity.renderedBudgets
85970
86172
  };
85971
86173
  }
85972
86174
  function cachedRowMatchesState(row, state) {
@@ -85991,7 +86193,7 @@ function applyCachedRowToState(state, row) {
85991
86193
  state.cachedM0ProjectDocsHash = markers.projectDocsHash;
85992
86194
  state.cachedM0MaterializedAt = markers.materializedAt;
85993
86195
  state.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
85994
- state.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch);
86196
+ state.cachedM0UpgradeState = encodeCachedM0UpgradeIdentity(markers.upgradeState, markers.compartmentRenderEpoch, markers.muralEnabled, markers.renderBudgetIdentity, markers.memoryRenderEpoch, markers.renderedBudgets ?? null);
85995
86197
  state.cachedM0SystemHash = markers.systemHash;
85996
86198
  state.cachedM0ToolSetHash = markers.toolSetHash;
85997
86199
  state.cachedM0ModelKey = markers.modelKey;
@@ -86084,6 +86286,7 @@ function renderFreshM0NonPersisted(options) {
86084
86286
  muralEnabled: options.muralEnabled,
86085
86287
  memoryInjectionBudgetTokens: options.memoryInjectionBudgetTokens,
86086
86288
  historyBudgetTokens: options.historyBudgetTokens,
86289
+ historyBudgetPolicyIdentity: options.historyBudgetPolicyIdentity,
86087
86290
  hardSignals: options.hardSignals,
86088
86291
  workspaceIdentitySet: {
86089
86292
  identities: workspace.identities,
@@ -86450,7 +86653,8 @@ function injectM0M1(options) {
86450
86653
  memoryEnabled: options.memoryEnabled,
86451
86654
  muralEnabled: options.muralEnabled,
86452
86655
  memoryInjectionBudgetTokens: options.memoryInjectionBudgetTokens,
86453
- historyBudgetTokens: options.historyBudgetTokens
86656
+ historyBudgetTokens: options.historyBudgetTokens,
86657
+ historyBudgetPolicyIdentity: options.historyBudgetPolicyIdentity
86454
86658
  });
86455
86659
  let rematerialized = false;
86456
86660
  let contentionExhausted = false;
@@ -106581,6 +106785,12 @@ function resolveModelKey(providerID, modelID) {
106581
106785
  }
106582
106786
  return piModelRefToCanonical(`${providerID}/${modelID}`);
106583
106787
  }
106788
+ function historyBudgetPolicyIdentity(historyBudgetPercentage, executeThresholdPercentage, modelKey, executeThresholdTokens) {
106789
+ if (!historyBudgetPercentage)
106790
+ return "pdefault";
106791
+ const threshold = resolveExecuteThresholdDetail(executeThresholdPercentage ?? 65, modelKey, 65, { tokensConfig: executeThresholdTokens, contextLimit: Number.MAX_SAFE_INTEGER });
106792
+ return `p${historyBudgetPercentage}:${threshold.mode}:${threshold.absoluteTokens ?? threshold.percentage}`;
106793
+ }
106584
106794
 
106585
106795
  // src/features/magic-context/scheduler.ts
106586
106796
  init_logger();
@@ -113332,7 +113542,9 @@ await __promiseAll([
113332
113542
  init_compaction_marker_manager(),
113333
113543
  init_compartment_runner()
113334
113544
  ]);
113545
+
113335
113546
  // src/hooks/magic-context/drop-stale-reduce-calls.ts
113547
+ init_user_answer();
113336
113548
  var STALE_TOOL_NAMES = new Set(["ctx_reduce"]);
113337
113549
  function isReduceToolPart(part) {
113338
113550
  if (!isRecord3(part))
@@ -113396,7 +113608,7 @@ function dropStaleReduceCalls(messages, frozenIds, options = {}) {
113396
113608
  const message = messages[i];
113397
113609
  const id = typeof message.info.id === "string" ? message.info.id : undefined;
113398
113610
  const inFrozen = id !== undefined && frozenIds.has(id);
113399
- const isNewDetection = !inFrozen && detect && i < protectedStart && id !== undefined && messageHasReducePart(message);
113611
+ const isNewDetection = !inFrozen && detect && i < protectedStart && id !== undefined && messageHasReducePart(message) && !message.parts.some(toolPartHasUserAnswer);
113400
113612
  if (!inFrozen && !isNewDetection)
113401
113613
  continue;
113402
113614
  const touched = sentinelizeReduceParts(message);
@@ -113814,6 +114026,8 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
113814
114026
  for (let i = 0;i < group.length - 1; i++) {
113815
114027
  const tag = group[i];
113816
114028
  const target = targets.get(tag.tagNumber);
114029
+ if (target?.canDrop?.() === false)
114030
+ continue;
113817
114031
  const { result, mode } = applyNewToolDrop(target, { inWindow: false });
113818
114032
  if (result === "incomplete")
113819
114033
  continue;
@@ -115985,6 +116199,7 @@ async function runPostTransformPhase(args) {
115985
116199
  muralEnabled: args.m0M1.muralEnabled,
115986
116200
  memoryInjectionBudgetTokens: args.m0M1.memoryInjectionBudgetTokens,
115987
116201
  historyBudgetTokens: args.m0M1.historyBudgetTokens,
116202
+ historyBudgetPolicyIdentity: args.m0M1.historyBudgetPolicyIdentity,
115988
116203
  hardSignals: args.m0M1.hardSignals
115989
116204
  }) : { value: false, reason: null };
115990
116205
  let preparedPrefix;
@@ -116023,6 +116238,7 @@ async function runPostTransformPhase(args) {
116023
116238
  memoryEnabled: args.m0M1.memoryEnabled,
116024
116239
  memoryInjectionBudgetTokens: args.m0M1.memoryInjectionBudgetTokens,
116025
116240
  historyBudgetTokens: args.m0M1.historyBudgetTokens,
116241
+ historyBudgetPolicyIdentity: args.m0M1.historyBudgetPolicyIdentity,
116026
116242
  temporalAwareness: args.m0M1.temporalAwareness,
116027
116243
  isCacheBustingPass: true,
116028
116244
  contentionFallbackPrefix: cachedPrefixBeforePreflight,
@@ -116403,6 +116619,7 @@ async function runPostTransformPhase(args) {
116403
116619
  memoryEnabled: args.m0M1.memoryEnabled,
116404
116620
  memoryInjectionBudgetTokens: args.m0M1.memoryInjectionBudgetTokens,
116405
116621
  historyBudgetTokens: args.m0M1.historyBudgetTokens,
116622
+ historyBudgetPolicyIdentity: args.m0M1.historyBudgetPolicyIdentity,
116406
116623
  temporalAwareness: args.m0M1.temporalAwareness,
116407
116624
  isCacheBustingPass,
116408
116625
  preparedPrefix,
@@ -118726,6 +118943,7 @@ function timedStateSyncDatabase(db, timing) {
118726
118943
  }
118727
118944
 
118728
118945
  // src/hooks/magic-context/module-wire.ts
118946
+ init_user_answer();
118729
118947
  init_read_session_raw();
118730
118948
  await init_read_session_chunk();
118731
118949
  import * as crypto2 from "node:crypto";
@@ -119307,6 +119525,7 @@ function encodeOpenCodeMessagesToCk(messages) {
119307
119525
  const synthetic = syntheticParts.length > 0 && syntheticParts.every((part) => part !== null && typeof part === "object" && (part.synthetic === true || part.syntheticTodoMarker === true));
119308
119526
  const content = [];
119309
119527
  const recoveryToolTitles = {};
119528
+ const userAnswerBlocks = [];
119310
119529
  for (const partValue of parts) {
119311
119530
  if (partValue === null || typeof partValue !== "object")
119312
119531
  continue;
@@ -119354,6 +119573,8 @@ function encodeOpenCodeMessagesToCk(messages) {
119354
119573
  if (title)
119355
119574
  recoveryToolTitles[callId] = title;
119356
119575
  const output = typeof state.output === "string" ? state.output : typeof state.error === "string" ? state.error : "";
119576
+ if (toolPartHasUserAnswer(part))
119577
+ userAnswerBlocks.push(content.length);
119357
119578
  content.push({
119358
119579
  kind: {
119359
119580
  type: "tool_result",
@@ -119385,9 +119606,12 @@ function encodeOpenCodeMessagesToCk(messages) {
119385
119606
  ck: {
119386
119607
  role,
119387
119608
  content,
119388
- ...Object.keys(recoveryToolTitles).length > 0 ? {
119609
+ ...Object.keys(recoveryToolTitles).length > 0 || userAnswerBlocks.length > 0 ? {
119389
119610
  provider_extras: {
119390
- opencode: { ctx_expand_tool_titles: recoveryToolTitles }
119611
+ opencode: {
119612
+ ...Object.keys(recoveryToolTitles).length > 0 ? { ctx_expand_tool_titles: recoveryToolTitles } : {},
119613
+ ...userAnswerBlocks.length > 0 ? { user_answer_block_indices: userAnswerBlocks } : {}
119614
+ }
119391
119615
  }
119392
119616
  } : {},
119393
119617
  meta: {
@@ -124190,7 +124414,9 @@ function createTransform(deps) {
124190
124414
  const persistedUsageFreshForBoundary = persistedUsageBeforeResets && Date.now() - persistedUsageBeforeResets.updatedAt <= 10 * 60 * 1000 && (persistedUsageBeforeResets.lastObservedModelKey === null || currentModelKeyForBoundary === undefined || piModelRefToCanonical(persistedUsageBeforeResets.lastObservedModelKey) === piModelRefToCanonical(currentModelKeyForBoundary)) && (resolvedContextLimit === undefined || persistedUsageBeforeResets.lastUsageContextLimit === 0 || persistedUsageBeforeResets.lastUsageContextLimit === resolvedContextLimit) ? persistedUsageBeforeResets.usage : null;
124191
124415
  const boundaryUsageForProtectedTail = persistedUsageFreshForBoundary ?? contextUsageEarly;
124192
124416
  const boundaryUsageSource = persistedUsageFreshForBoundary ? "persisted" : "live";
124193
- const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens, resolvedContextLimit);
124417
+ const historyPolicyIdentity = historyBudgetPolicyIdentity(deps.historyBudgetPercentage, deps.executeThresholdPercentage, currentModelKeyForBoundary, deps.executeThresholdTokens);
124418
+ const historyContextLimit = resolvedContextLimit ?? (currentModelKeyForBoundary && persistedUsageBeforeResets?.lastObservedModelKey && piModelRefToCanonical(currentModelKeyForBoundary) === piModelRefToCanonical(persistedUsageBeforeResets.lastObservedModelKey) && persistedUsageBeforeResets.lastUsageContextLimit > 0 ? persistedUsageBeforeResets.lastUsageContextLimit : undefined);
124419
+ const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens, historyContextLimit);
124194
124420
  const emergencyCeilingLimit = thresholdContextLimit ?? 0;
124195
124421
  const emergencyCeilingTokens = Number.isFinite(emergencyCeilingLimit) && emergencyCeilingLimit > 0 ? Math.floor(emergencyCeilingLimit * (effectiveExecuteThresholdPercentage / 100)) : undefined;
124196
124422
  const schedulerDecision = compactionOff ? "defer" : resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId), resolvedContextLimit);
@@ -124564,6 +124790,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
124564
124790
  muralEnabled: deps.muralEnabled,
124565
124791
  memoryInjectionBudgetTokens: deps.memoryConfig?.injectionBudgetTokens,
124566
124792
  historyBudgetTokens,
124793
+ historyBudgetPolicyIdentity: historyPolicyIdentity,
124567
124794
  hardSignals: m0HardSignals
124568
124795
  }).value;
124569
124796
  const protectionCacheBustingPass = !compactionOff && (schedulerDecision === "execute" || isCacheBusting || contextUsage.percentage >= forceMaterializationPercentage || deps.pendingMaterializationSessions.has(sessionId) || canConsumeDeferredLate && deferredMaterializationSessions.has(sessionId) || protectionFoldWillBust);
@@ -124687,6 +124914,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
124687
124914
  memoryEnabled: deps.memoryConfig?.enabled,
124688
124915
  memoryInjectionBudgetTokens: deps.memoryConfig?.injectionBudgetTokens,
124689
124916
  historyBudgetTokens,
124917
+ historyBudgetPolicyIdentity: historyPolicyIdentity,
124690
124918
  temporalAwareness: deps.experimentalTemporalAwareness,
124691
124919
  hardSignals: m0HardSignals,
124692
124920
  muralEnabled: deps.muralEnabled
@@ -126158,7 +126386,9 @@ function resolveConfigValue(cfg, key, modelKey, defaultValue) {
126158
126386
  }
126159
126387
  function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled = true) {
126160
126388
  try {
126161
- const projectIdentity = resolveProjectIdentity(directory);
126389
+ const projectIdentity = resolveProjectIdentityForSession(directory);
126390
+ if (projectIdentity === undefined)
126391
+ throw new ProjectIdentityError("git_identity_unavailable", directory, "Memory features paused while project identity is unavailable");
126162
126392
  const meta = db.prepare("SELECT * FROM session_meta WHERE session_id = ?").get(sessionId);
126163
126393
  const usagePercentage = meta ? Number(meta.last_context_percentage ?? meta.last_usage_percentage ?? 0) : 0;
126164
126394
  const inputTokens = meta ? Number(meta.last_input_tokens ?? 0) : 0;
@@ -126362,7 +126592,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
126362
126592
  };
126363
126593
  return applyStickySnapshotCache(sessionId, fresh);
126364
126594
  } catch (err) {
126365
- if (!(err instanceof ProjectIdentityError && err.errorClass === "home_project_disabled"))
126595
+ if (!(err instanceof ProjectIdentityError))
126366
126596
  log("[rpc] sidebar-snapshot error:", err);
126367
126597
  throw err;
126368
126598
  }
@@ -126370,6 +126600,8 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
126370
126600
  function buildSidebarSnapshotRpcResponse(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled = true) {
126371
126601
  if (shouldSkipHomeProjectMemory(directory))
126372
126602
  return { sessionId, disabled: true };
126603
+ if (resolveProjectIdentityForSession(directory) === undefined)
126604
+ return { sessionId, disabled: true, paused: true };
126373
126605
  try {
126374
126606
  return buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled);
126375
126607
  } catch {
@@ -126831,6 +127063,8 @@ function registerRpcHandlers(rpcServer, args) {
126831
127063
  const dir = String(params.directory ?? directory);
126832
127064
  if (shouldSkipHomeProjectMemory(dir))
126833
127065
  return { sessionId, disabled: true };
127066
+ if (resolveProjectIdentityForSession(dir) === undefined)
127067
+ return { sessionId, disabled: true, paused: true };
126834
127068
  const modelKey = params.modelKey ? String(params.modelKey) : undefined;
126835
127069
  const db = readDatabase();
126836
127070
  if (!db || !sessionId)
@@ -126853,6 +127087,8 @@ function registerRpcHandlers(rpcServer, args) {
126853
127087
  const dir = String(params.directory ?? directory);
126854
127088
  if (shouldSkipHomeProjectMemory(dir))
126855
127089
  return { sessionId, disabled: true };
127090
+ if (resolveProjectIdentityForSession(dir) === undefined)
127091
+ return { sessionId, disabled: true, paused: true };
126856
127092
  const db = readDatabase();
126857
127093
  if (!db || !sessionId)
126858
127094
  return { error: "unavailable" };
@@ -128427,7 +128663,7 @@ class V2StoreReader {
128427
128663
  return { rows, cursor: rows.at(-1)?.seq };
128428
128664
  });
128429
128665
  }
128430
- messagePage(sessionID, afterOrdinal, limit, finalWatermark) {
128666
+ messagePage(sessionID, afterOrdinal, limit, finalWatermark, after) {
128431
128667
  return trackDecodeOperation("messagePage", () => {
128432
128668
  if (!Number.isSafeInteger(afterOrdinal) || afterOrdinal < 0)
128433
128669
  throw new Error("Invalid raw-message ordinal cursor");
@@ -128438,6 +128674,14 @@ class V2StoreReader {
128438
128674
  const pageSize = Math.min(limit, finalWatermark - afterOrdinal);
128439
128675
  if (pageSize <= 0)
128440
128676
  return [];
128677
+ if (after) {
128678
+ const anchor = this.db.prepare("SELECT seq FROM session_message WHERE session_id = ? AND id = ?").get(sessionID, after.id);
128679
+ if (anchor) {
128680
+ return this.db.prepare(`SELECT id, session_id, type, seq, time_created, data
128681
+ FROM session_message WHERE session_id = ? AND seq > ?
128682
+ AND type IN (${RAW_MESSAGE_TYPE_PARAMETERS}) ORDER BY seq ASC LIMIT ?`).all(sessionID, anchor.seq, ...RAW_MESSAGE_TYPES, pageSize).map(decode2);
128683
+ }
128684
+ }
128441
128685
  const maximumSeq = Number.MAX_SAFE_INTEGER;
128442
128686
  const rows = this.db.prepare(V2_MESSAGE_PAGE_SQL).all(afterOrdinal, sessionID, ...RAW_MESSAGE_TYPES, Math.max(0, afterOrdinal - 1), sessionID, ...RAW_MESSAGE_TYPES, finalWatermark - 1, maximumSeq, sessionID, ...RAW_MESSAGE_TYPES, pageSize);
128443
128687
  return rows.map(decode2);
@@ -134270,6 +134514,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
134270
134514
  let agentSessionId = null;
134271
134515
  let promptSettled = false;
134272
134516
  const startedAt = Date.now();
134517
+ let budgetFinalized = false;
134518
+ const onBudgetUpdate = (state) => {
134519
+ budgetFinalized ||= state.finalizeFired;
134520
+ args.onBudgetUpdate?.(state);
134521
+ };
134273
134522
  try {
134274
134523
  const prompt = buildMapMemoriesPrompt(args.projectIdentity, batch);
134275
134524
  if (args.hiddenCompletionExecutor) {
@@ -134282,7 +134531,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
134282
134531
  prompt,
134283
134532
  title: "magic-context-dream-map-memories",
134284
134533
  callContext: "dreamer:map-memories",
134285
- metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate: args.onBudgetUpdate },
134534
+ metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
134286
134535
  model: args.model,
134287
134536
  fallbackModels: args.fallbackModels,
134288
134537
  timeoutMs: sliceMs,
@@ -134293,9 +134542,12 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
134293
134542
  status: "completed",
134294
134543
  messages: run.completion.messages ?? []
134295
134544
  });
134296
- const outcome = await applyParsedBatchMappings(args, batch, run.validated);
134545
+ const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
134297
134546
  const returnedIds = new Set(run.validated.map((entry) => entry.id));
134298
- return { ...outcome, requeue: batch.filter((memory) => !returnedIds.has(memory.id)) };
134547
+ return {
134548
+ ...outcome,
134549
+ requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
134550
+ };
134299
134551
  }
134300
134552
  const client = args.client;
134301
134553
  if (!client)
@@ -134325,7 +134577,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
134325
134577
  }, {
134326
134578
  transport: createPromptAsyncTransport(client, agentSessionId, {
134327
134579
  tokenBudget: args.tokenBudget,
134328
- onBudgetUpdate: args.onBudgetUpdate
134580
+ onBudgetUpdate
134329
134581
  }),
134330
134582
  timeoutMs: sliceMs,
134331
134583
  signal,
@@ -134352,11 +134604,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
134352
134604
  });
134353
134605
  promptSettled = true;
134354
134606
  recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
134355
- const outcome = await applyParsedBatchMappings(args, batch, run.validated);
134607
+ const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
134356
134608
  const returnedIds = new Set(run.validated.filter((entry) => batch.some((memory) => memory.id === entry.id)).map((entry) => entry.id));
134357
134609
  return {
134358
134610
  ...outcome,
134359
- requeue: batch.filter((memory) => !returnedIds.has(memory.id))
134611
+ requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
134360
134612
  };
134361
134613
  } catch (error) {
134362
134614
  const desc = describeError(error);
@@ -134391,7 +134643,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
134391
134643
  });
134392
134644
  }
134393
134645
  }
134394
- async function applyParsedBatchMappings(args, batch, parsed) {
134646
+ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = false) {
134395
134647
  const batchIds = new Set(batch.map((memory) => memory.id));
134396
134648
  const valid = parsed.filter((entry) => batchIds.has(entry.id));
134397
134649
  const unknown = parsed.filter((entry) => !batchIds.has(entry.id));
@@ -134399,9 +134651,12 @@ async function applyParsedBatchMappings(args, batch, parsed) {
134399
134651
  log(`[dreamer] map-memories warning: dropping ${unknown.length} unknown mapping entr${unknown.length === 1 ? "y" : "ies"} outside the current batch (${unknown.map((entry) => entry.id).join(", ")})`);
134400
134652
  }
134401
134653
  assertNoDuplicateManifestIds(valid.map((entry) => entry.id), "mappings");
134402
- if (valid.length * 2 < batch.length) {
134654
+ if (!budgetFinalized && valid.length * 2 < batch.length) {
134403
134655
  throw new Error(`mappings manifest covers ${valid.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
134404
134656
  }
134657
+ if (budgetFinalized && valid.length < batch.length) {
134658
+ log(`[dreamer] map-memories: accepted partial manifest after token budget: ${valid.length}/${batch.length}`);
134659
+ }
134405
134660
  if (valid.length === 0)
134406
134661
  return { mapped: 0, independent: 0 };
134407
134662
  const planned = [];
@@ -135958,6 +136213,11 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
135958
136213
  let agentSessionId = null;
135959
136214
  let promptSettled = false;
135960
136215
  const startedAt = Date.now();
136216
+ let budgetFinalized = false;
136217
+ const onBudgetUpdate = (state) => {
136218
+ budgetFinalized ||= state.finalizeFired;
136219
+ args.onBudgetUpdate?.(state);
136220
+ };
135961
136221
  try {
135962
136222
  const headAtPrompt = await readGitHead(args.sessionDirectory);
135963
136223
  const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await buildVerifyDiffEvidence(args.sessionDirectory, batch) : null;
@@ -135972,7 +136232,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
135972
136232
  prompt,
135973
136233
  title: "magic-context-dream-verify",
135974
136234
  callContext: "dreamer:verify",
135975
- metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate: args.onBudgetUpdate },
136235
+ metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
135976
136236
  model: args.model,
135977
136237
  fallbackModels: args.fallbackModels,
135978
136238
  language: args.language,
@@ -135989,7 +136249,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
135989
136249
  status: "completed",
135990
136250
  messages: run.completion.messages ?? []
135991
136251
  });
135992
- return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt);
136252
+ return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
135993
136253
  }
135994
136254
  const client = args.client;
135995
136255
  if (!client)
@@ -136019,7 +136279,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
136019
136279
  }, {
136020
136280
  transport: createPromptAsyncTransport(client, agentSessionId, {
136021
136281
  tokenBudget: args.tokenBudget,
136022
- onBudgetUpdate: args.onBudgetUpdate
136282
+ onBudgetUpdate
136023
136283
  }),
136024
136284
  timeoutMs: sliceMs,
136025
136285
  signal,
@@ -136049,7 +136309,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
136049
136309
  });
136050
136310
  promptSettled = true;
136051
136311
  recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
136052
- return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt);
136312
+ return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
136053
136313
  } catch (error) {
136054
136314
  const desc = describeError(error);
136055
136315
  const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
@@ -136095,7 +136355,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
136095
136355
  });
136096
136356
  }
136097
136357
  }
136098
- async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt) {
136358
+ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budgetFinalized = false) {
136099
136359
  const batchIds = new Set(batch.map((m) => m.id));
136100
136360
  const batchById = new Map(batch.map((memory) => [memory.id, memory]));
136101
136361
  const valid = {
@@ -136115,9 +136375,12 @@ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt) {
136115
136375
  }
136116
136376
  const validIds = [...valid.verified, ...valid.updated, ...valid.archived, ...valid.skipped].map((entry) => entry.id);
136117
136377
  assertNoDuplicateManifestIds(validIds, "verify");
136118
- if (validIds.length * 2 < batch.length) {
136378
+ if (!budgetFinalized && validIds.length * 2 < batch.length) {
136119
136379
  throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
136120
136380
  }
136381
+ if (budgetFinalized && validIds.length < batch.length) {
136382
+ log(`[dreamer] verify: accepted partial manifest after token budget: ${validIds.length}/${batch.length}`);
136383
+ }
136121
136384
  if (validIds.length === 0) {
136122
136385
  return { verified: 0, updated: 0, archived: 0, skipped: 0, refused: 0 };
136123
136386
  }
@@ -138333,6 +138596,7 @@ function adaptPayload(draft, admittedIDs = new Set) {
138333
138596
  input: structuredClone(call?.input ?? {}),
138334
138597
  status: result ? "completed" : "running",
138335
138598
  ...result ? { output } : {},
138599
+ ...result && (call?.name ?? result.part.name) === "question" ? { metadata: { userAnswer: true } } : {},
138336
138600
  ...files ? { attachments: contentValueAttachments(files) } : {}
138337
138601
  }
138338
138602
  };
@@ -139421,10 +139685,10 @@ function* readV2RawMessagePagesForConversion(openReader, sessionID, pageRows = C
139421
139685
  function createV2RawMessageReader(openReader) {
139422
139686
  const servedBoundaryCache = new Map;
139423
139687
  return {
139424
- readPage: (sessionID, afterOrdinal, limit, finalWatermark) => {
139688
+ readPage: (sessionID, afterOrdinal, limit, finalWatermark, after) => {
139425
139689
  const reader = openReader();
139426
139690
  try {
139427
- return rawMessagePage(reader.messagePage(sessionID, afterOrdinal, limit, finalWatermark), afterOrdinal);
139691
+ return rawMessagePage(reader.messagePage(sessionID, afterOrdinal, limit, finalWatermark, after), afterOrdinal);
139428
139692
  } finally {
139429
139693
  reader.close();
139430
139694
  }
@@ -139518,7 +139782,7 @@ function createV2RawMessageReader(openReader) {
139518
139782
  }
139519
139783
  function createV2RawMessageProvider(reader, sessionID) {
139520
139784
  return {
139521
- readMessagePage: (afterOrdinal, limit, finalWatermark) => reader.readPage(sessionID, afterOrdinal, limit, finalWatermark),
139785
+ readMessagePage: (afterOrdinal, limit, finalWatermark, after) => reader.readPage(sessionID, afterOrdinal, limit, finalWatermark, after),
139522
139786
  readMessageById: (messageID) => reader.findById(sessionID, messageID),
139523
139787
  readMessagePartsById: (messageID) => reader.findPartsById(sessionID, messageID),
139524
139788
  hasMessageById: (messageID) => reader.hasById(sessionID, messageID),