@retaw106/mmc-oc 2.4.0 → 2.5.0
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/{context-c72brxe5.js → context-xx09sh1g.js} +1279 -408
- package/dist/features/magic-context/message-index-async.d.ts +6 -2
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +5 -8
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +5 -1
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +2 -0
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-host-instruction-retention.d.ts +4 -0
- package/dist/features/magic-context/storage-host-instruction-retention.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +2 -2
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts +9 -1
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-hint.d.ts +3 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -2
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/diagnostic-log-state.d.ts +4 -0
- package/dist/hooks/magic-context/diagnostic-log-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/file-token-coverage.d.ts +11 -0
- package/dist/hooks/magic-context/file-token-coverage.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/host-served-rows.d.ts +10 -0
- package/dist/hooks/magic-context/host-served-rows.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/nudge-evaluation-log.d.ts +3 -0
- package/dist/hooks/magic-context/nudge-evaluation-log.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts +2 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
- package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +2 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +3 -3
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-date-refresh.d.ts +3 -2
- package/dist/hooks/magic-context/system-date-refresh.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts +4 -0
- package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +1 -1
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +15 -2
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/text-complete.d.ts +1 -1
- package/dist/hooks/magic-context/text-complete.d.ts.map +1 -1
- package/dist/hooks/magic-context/todo-view.d.ts +2 -2
- package/dist/hooks/magic-context/tool-drop-target.d.ts +3 -2
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +6 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-stage-logger.d.ts +3 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +4 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-kahkxcqw.js → index-0d40b4q8.js} +14740 -14292
- package/dist/{index-48e9znrc.js → index-1vxffj5j.js} +75 -22
- package/dist/{index-ykq24x1n.js → index-bpjjcdy9.js} +1 -1
- package/dist/{index-r7s7d350.js → index-k25thxq7.js} +1 -1
- package/dist/{index-27ddyx39.js → index-mjf0p7yq.js} +1 -1
- package/dist/{index-dwh99z66.js → index-pte3cfs9.js} +194 -5
- package/dist/index.js +2 -2
- package/dist/{message-time-backfill-j96x1sab.js → message-time-backfill-g9py24yt.js} +1 -1
- package/dist/plugin/subagent-tool-policy.d.ts +4 -0
- package/dist/plugin/subagent-tool-policy.d.ts.map +1 -1
- package/dist/{read-session-chunk-t8bg6wkz.js → read-session-chunk-eb3fy45y.js} +3 -3
- package/dist/{recomp-orchestrator-k760qy1n.js → recomp-orchestrator-mmpy5cb7.js} +6 -6
- package/dist/{send-session-notification-njjf3b4s.js → send-session-notification-zpqs213d.js} +3 -3
- package/dist/shared/model-suggestion-retry.d.ts +2 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/rpc-discovery-cleanup.d.ts +3 -0
- package/dist/shared/rpc-discovery-cleanup.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts +2 -0
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/search-text.d.ts +8 -0
- package/dist/shared/search-text.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +6 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/storage-file-mutex.d.ts.map +1 -1
- package/dist/shared/system-directive.d.ts +2 -0
- package/dist/shared/system-directive.d.ts.map +1 -1
- package/dist/v2/fold/native-replay.d.ts +11 -2
- package/dist/v2/fold/native-replay.d.ts.map +1 -1
- package/dist/v2/fold/policy.d.ts.map +1 -1
- package/dist/v2/fold/restore.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +1 -1
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/generate.d.ts +36 -1
- package/dist/v2/hooks/generate.d.ts.map +1 -1
- package/dist/v2/hooks/lkg-system.d.ts +35 -4
- package/dist/v2/hooks/lkg-system.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts +10 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts +2 -0
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +12 -0
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/server.js +9033 -7461
- package/dist/v2/store-reader.d.ts +11 -0
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/web/main.js +229 -8
- package/dist/{wrapup-orchestrator-b2gswatj.js → wrapup-orchestrator-jq589pgr.js} +6 -6
- package/package.json +1 -1
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/shared/model-suggestion-retry.test.ts +52 -0
- package/src/shared/model-suggestion-retry.ts +8 -3
- package/src/shared/rpc-discovery-cleanup.test.ts +125 -0
- package/src/shared/rpc-discovery-cleanup.ts +57 -0
- package/src/shared/rpc-server.ts +36 -13
- package/src/shared/search-text.test.ts +30 -0
- package/src/shared/search-text.ts +62 -0
- package/src/shared/sqlite-turn-deadline.test.ts +286 -0
- package/src/shared/sqlite.ts +237 -9
- package/src/shared/storage-file-mutex.test.ts +51 -2
- package/src/shared/storage-file-mutex.ts +11 -1
- package/src/shared/system-directive.test.ts +37 -0
- package/src/shared/system-directive.ts +19 -1
- package/src/shared/tag-transcript.ts +16 -4
|
@@ -71,7 +71,6 @@ import {
|
|
|
71
71
|
searchMemoriesFTSUnion,
|
|
72
72
|
clearMemoryVerifications,
|
|
73
73
|
queueMemoryMutation,
|
|
74
|
-
scheduleAfterBootQuiet,
|
|
75
74
|
BoundedSessionMap,
|
|
76
75
|
registerOwnRpcServerInstance,
|
|
77
76
|
rpcPortDir,
|
|
@@ -81,6 +80,12 @@ import {
|
|
|
81
80
|
dirtyLkgRecoveryRevision,
|
|
82
81
|
ownsLkgDirtyFence,
|
|
83
82
|
invalidateCleanLkgRecoveryFence,
|
|
83
|
+
cleanSearchText,
|
|
84
|
+
keywordRelevance,
|
|
85
|
+
matchedSearchSnippet,
|
|
86
|
+
gaDatabasePath,
|
|
87
|
+
RAW_MESSAGE_TYPES,
|
|
88
|
+
V2StoreReaderPool,
|
|
84
89
|
getLastIndexedOrdinal,
|
|
85
90
|
getIndexedMessageIdAtOrdinal,
|
|
86
91
|
getIndexedMessageCorpusSize,
|
|
@@ -88,6 +93,8 @@ import {
|
|
|
88
93
|
isMessageIndexReconciledThrough,
|
|
89
94
|
clearIndexedMessages,
|
|
90
95
|
indexMessagesAfterOrdinal,
|
|
96
|
+
sweepOrphanedOpenCodeMessageIndexesCooperatively,
|
|
97
|
+
scheduleAfterBootQuiet,
|
|
91
98
|
acquireCompartmentLease,
|
|
92
99
|
releaseCompartmentLeaseBestEffort,
|
|
93
100
|
isCompartmentLeaseHeld,
|
|
@@ -95,6 +102,7 @@ import {
|
|
|
95
102
|
getMaxM0MutationId,
|
|
96
103
|
ensureSessionMetaRow,
|
|
97
104
|
clearCachedM0M1,
|
|
105
|
+
clearCachedM0,
|
|
98
106
|
getCompartments,
|
|
99
107
|
getLastCompartmentEndMessage,
|
|
100
108
|
getLastCompartmentEndMessageId,
|
|
@@ -187,9 +195,6 @@ import {
|
|
|
187
195
|
getUnpublishedAutoSearchNoHint,
|
|
188
196
|
forgetUnpublishedAutoSearchNoHint,
|
|
189
197
|
registerAutoSearchWork,
|
|
190
|
-
gaDatabasePath,
|
|
191
|
-
RAW_MESSAGE_TYPES,
|
|
192
|
-
V2StoreReaderPool,
|
|
193
198
|
getOrCreateSessionMeta,
|
|
194
199
|
updateSessionMeta,
|
|
195
200
|
advanceToolReclaimWatermark,
|
|
@@ -292,6 +297,7 @@ import {
|
|
|
292
297
|
prepareCachedM0M1Replay,
|
|
293
298
|
hasCompleteCachedM0M1,
|
|
294
299
|
injectM0M1,
|
|
300
|
+
omitIncompleteFileTokenTotals,
|
|
295
301
|
RECOVERY_NO_HEAD_LIMIT,
|
|
296
302
|
deriveProtectedTailTokenTarget,
|
|
297
303
|
selectPerRunCap,
|
|
@@ -301,7 +307,7 @@ import {
|
|
|
301
307
|
recordHighPressureNoEligibleHead,
|
|
302
308
|
getActiveCompartmentRun,
|
|
303
309
|
startCompartmentAgent
|
|
304
|
-
} from "./index-
|
|
310
|
+
} from "./index-0d40b4q8.js";
|
|
305
311
|
import {
|
|
306
312
|
getHarness,
|
|
307
313
|
getDataDir,
|
|
@@ -429,12 +435,16 @@ import {
|
|
|
429
435
|
pickNearestPriorOwner,
|
|
430
436
|
expandToolPart,
|
|
431
437
|
markHostUnservedRow,
|
|
438
|
+
isHostRenderedSystemMessage,
|
|
439
|
+
markCoveredInstructionRow,
|
|
440
|
+
isCoveredInstructionRow,
|
|
441
|
+
takeCoveredInstructionRows,
|
|
442
|
+
cloneKeepingCoveredInstructionMarks,
|
|
432
443
|
estimateTrueRawMessageTokens,
|
|
433
444
|
stripSystemInjection,
|
|
434
445
|
isTextPart,
|
|
435
446
|
isToolPartWithOutput,
|
|
436
447
|
isFilePart,
|
|
437
|
-
buildFileSourceContent,
|
|
438
448
|
toolPartHasUserAnswer,
|
|
439
449
|
recordToolParameters,
|
|
440
450
|
createDroppedInputGuard,
|
|
@@ -477,12 +487,13 @@ import {
|
|
|
477
487
|
hasRawSessionMessageById2,
|
|
478
488
|
readRawSessionMessageById2,
|
|
479
489
|
readSessionChunk2
|
|
480
|
-
} from "./index-
|
|
490
|
+
} from "./index-1vxffj5j.js";
|
|
481
491
|
import {
|
|
482
492
|
normalizeModelEntry2,
|
|
483
493
|
resolveHistorianModel2
|
|
484
494
|
} from "./index-azbmnekv.js";
|
|
485
495
|
import {
|
|
496
|
+
Database,
|
|
486
497
|
getSqliteMemoryStats,
|
|
487
498
|
withSqliteBackgroundWriter,
|
|
488
499
|
withSqliteTransformPass,
|
|
@@ -492,7 +503,7 @@ import {
|
|
|
492
503
|
withAsyncPrivilegedWriter,
|
|
493
504
|
indexCoordinationInput,
|
|
494
505
|
withIndexChunk
|
|
495
|
-
} from "./index-
|
|
506
|
+
} from "./index-pte3cfs9.js";
|
|
496
507
|
import {
|
|
497
508
|
canonicalModelIdentity,
|
|
498
509
|
piModelRefToCanonical,
|
|
@@ -509,7 +520,7 @@ import {
|
|
|
509
520
|
latestRealUserTurnIdFromOpenCodeDb,
|
|
510
521
|
getMessageTimesFromOpenCodeDb,
|
|
511
522
|
findLastAssistantModelFromOpenCodeDb
|
|
512
|
-
} from "./index-
|
|
523
|
+
} from "./index-bpjjcdy9.js";
|
|
513
524
|
import {
|
|
514
525
|
registerNotificationSink2,
|
|
515
526
|
pushNotification2,
|
|
@@ -522,11 +533,14 @@ import {
|
|
|
522
533
|
getErrorMessage,
|
|
523
534
|
flushIgnoredMessages2,
|
|
524
535
|
sendStatusNotification2
|
|
525
|
-
} from "./index-
|
|
536
|
+
} from "./index-k25thxq7.js";
|
|
526
537
|
import {
|
|
527
538
|
logSlowWriteTransaction
|
|
528
539
|
} from "./index-yjv8dpht.js";
|
|
529
540
|
|
|
541
|
+
// src/v2/hooks/context.ts
|
|
542
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
543
|
+
|
|
530
544
|
// src/config/index.ts
|
|
531
545
|
import { existsSync as existsSync4 } from "node:fs";
|
|
532
546
|
|
|
@@ -5041,6 +5055,8 @@ var RECONCILIATION_BATCH_SIZE = 100;
|
|
|
5041
5055
|
|
|
5042
5056
|
class MagicContextMessageIndexHeapHolder {
|
|
5043
5057
|
reconciledSessions = new Set;
|
|
5058
|
+
reconciledSnapshots = new Map;
|
|
5059
|
+
stalledSessions = new Set;
|
|
5044
5060
|
reconciliationScheduledSessions = new Set;
|
|
5045
5061
|
clearAndReindexScheduledSessions = new Map;
|
|
5046
5062
|
sessionLocks = new Map;
|
|
@@ -5123,23 +5139,32 @@ function detectIndexMisalignment(db, sessionId, cursor, finalWatermark, readMess
|
|
|
5123
5139
|
return null;
|
|
5124
5140
|
return `indexed id '${indexedId}' at ordinal ${cursor} but projection has '${projectedId}'`;
|
|
5125
5141
|
}
|
|
5142
|
+
function logReconciliationStall(sessionId, reason) {
|
|
5143
|
+
if (heapHolder.stalledSessions.has(sessionId))
|
|
5144
|
+
return;
|
|
5145
|
+
heapHolder.stalledSessions.add(sessionId);
|
|
5146
|
+
sessionLog(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
|
|
5147
|
+
}
|
|
5126
5148
|
async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
5127
5149
|
if (!await sourceReady(readMessages, sessionId))
|
|
5128
5150
|
return false;
|
|
5129
5151
|
await runWithSessionLock(sessionId, async () => {
|
|
5130
|
-
if (heapHolder.reconciledSessions.has(sessionId))
|
|
5152
|
+
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
|
|
5131
5153
|
return;
|
|
5132
5154
|
let fallbackSnapshot = null;
|
|
5133
5155
|
try {
|
|
5134
5156
|
const fullReader = typeof readMessages === "function" ? readMessages : null;
|
|
5135
|
-
const
|
|
5157
|
+
const revision = readMessages.getRevision?.(sessionId);
|
|
5158
|
+
const previous = heapHolder.reconciledSnapshots.get(sessionId);
|
|
5159
|
+
const finalWatermark = previous && revision === previous.revision ? previous.count : revision !== undefined && readMessages.getCountAfterRevision ? previous && revision > previous.revision ? previous.count + readMessages.getCountAfterRevision(sessionId, previous.revision, revision) : readMessages.getCountAfterRevision(sessionId, -1, revision) : readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
|
|
5136
5160
|
let cursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
5137
|
-
let after;
|
|
5138
|
-
const misalignment = detectIndexMisalignment(db, sessionId, cursor, finalWatermark, readMessages, fallbackSnapshot);
|
|
5161
|
+
let after = cursor === previous?.count ? previous.after : undefined;
|
|
5162
|
+
const misalignment = revision !== undefined && previous && revision >= previous.revision ? null : detectIndexMisalignment(db, sessionId, cursor, finalWatermark, readMessages, fallbackSnapshot);
|
|
5139
5163
|
if (misalignment !== null) {
|
|
5140
5164
|
sessionLog(sessionId, `message FTS index misaligned (${misalignment}); clearing for full re-index`);
|
|
5141
5165
|
withSqliteBackgroundWriter(() => clearIndexedMessages(db, sessionId));
|
|
5142
5166
|
cursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
5167
|
+
after = undefined;
|
|
5143
5168
|
}
|
|
5144
5169
|
while (cursor < finalWatermark) {
|
|
5145
5170
|
const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
|
|
@@ -5159,6 +5184,22 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
|
5159
5184
|
}
|
|
5160
5185
|
if (isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
|
|
5161
5186
|
heapHolder.reconciledSessions.add(sessionId);
|
|
5187
|
+
heapHolder.stalledSessions.delete(sessionId);
|
|
5188
|
+
if (revision !== undefined) {
|
|
5189
|
+
if (!after && finalWatermark > 0 && readMessages.readPage) {
|
|
5190
|
+
const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
|
|
5191
|
+
if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
|
|
5192
|
+
after = { timeCreated: last.createdAt, id: last.id };
|
|
5193
|
+
}
|
|
5194
|
+
heapHolder.reconciledSnapshots.set(sessionId, {
|
|
5195
|
+
revision,
|
|
5196
|
+
count: finalWatermark,
|
|
5197
|
+
after
|
|
5198
|
+
});
|
|
5199
|
+
}
|
|
5200
|
+
} else {
|
|
5201
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
5202
|
+
logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
|
|
5162
5203
|
}
|
|
5163
5204
|
} finally {
|
|
5164
5205
|
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
@@ -5167,30 +5208,42 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
|
5167
5208
|
return true;
|
|
5168
5209
|
}
|
|
5169
5210
|
function scheduleReconciliation(db, sessionId, readMessages) {
|
|
5170
|
-
if (heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
|
|
5211
|
+
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
|
|
5171
5212
|
return;
|
|
5172
5213
|
}
|
|
5173
5214
|
heapHolder.reconciliationScheduledSessions.add(sessionId);
|
|
5174
5215
|
scheduleAfterBootQuiet(() => {
|
|
5175
5216
|
defer(() => {
|
|
5217
|
+
let appendedDuringReconciliation = false;
|
|
5218
|
+
const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
5176
5219
|
reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
|
|
5177
|
-
if (ran)
|
|
5220
|
+
if (ran) {
|
|
5221
|
+
const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
5222
|
+
appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
|
|
5178
5223
|
return;
|
|
5224
|
+
}
|
|
5179
5225
|
setTimeout(() => {
|
|
5180
5226
|
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
5181
5227
|
scheduleReconciliation(db, sessionId, readMessages);
|
|
5182
5228
|
}, PREPARE_RETRY_MS).unref?.();
|
|
5183
5229
|
}).catch((error) => {
|
|
5184
|
-
|
|
5230
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
5231
|
+
logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
|
|
5185
5232
|
if (isDatabaseLockedError(error))
|
|
5186
5233
|
setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000).unref();
|
|
5187
5234
|
}).finally(() => {
|
|
5188
5235
|
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
5236
|
+
if (appendedDuringReconciliation)
|
|
5237
|
+
scheduleReconciliation(db, sessionId, readMessages);
|
|
5189
5238
|
});
|
|
5190
5239
|
});
|
|
5191
5240
|
});
|
|
5192
5241
|
}
|
|
5193
5242
|
function scheduleReconciliationCatchup(db, sessionId, readMessages) {
|
|
5243
|
+
if (readMessages.getRevision) {
|
|
5244
|
+
scheduleReconciliation(db, sessionId, readMessages);
|
|
5245
|
+
return;
|
|
5246
|
+
}
|
|
5194
5247
|
if (typeof readMessages.getCount !== "function") {
|
|
5195
5248
|
scheduleReconciliation(db, sessionId, readMessages);
|
|
5196
5249
|
return;
|
|
@@ -5208,6 +5261,7 @@ function scheduleReconciliationCatchup(db, sessionId, readMessages) {
|
|
|
5208
5261
|
}
|
|
5209
5262
|
function scheduleClearAndReindex(db, sessionId, readMessages) {
|
|
5210
5263
|
heapHolder.reconciledSessions.delete(sessionId);
|
|
5264
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
5211
5265
|
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
5212
5266
|
clearCompletedIncrementalKeys(sessionId);
|
|
5213
5267
|
const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
|
|
@@ -5225,6 +5279,7 @@ function scheduleClearAndReindex(db, sessionId, readMessages) {
|
|
|
5225
5279
|
return;
|
|
5226
5280
|
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
5227
5281
|
heapHolder.reconciledSessions.delete(sessionId);
|
|
5282
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
5228
5283
|
clearCompletedIncrementalKeys(sessionId);
|
|
5229
5284
|
clearIndexedMessages(db, sessionId);
|
|
5230
5285
|
cleared = true;
|
|
@@ -7200,7 +7255,7 @@ function searchMessagesInSnapshot(args, sessionFirst) {
|
|
|
7200
7255
|
const filtered = rows.slice(0, limit);
|
|
7201
7256
|
return filtered.map((row, rank) => ({
|
|
7202
7257
|
source: "message",
|
|
7203
|
-
content: previewText(row.content),
|
|
7258
|
+
content: matchedSearchSnippet(row.content, args.query) || previewText(row.content),
|
|
7204
7259
|
score: linearDecayScore(rank, filtered.length),
|
|
7205
7260
|
messageOrdinal: row.messageOrdinal,
|
|
7206
7261
|
messageId: row.messageId,
|
|
@@ -7275,7 +7330,7 @@ function searchMessagesInSnapshot(args, sessionFirst) {
|
|
|
7275
7330
|
const ranked = [...fused.values()].sort((a, b) => b.score !== a.score ? b.score - a.score : a.row.messageOrdinal - b.row.messageOrdinal).slice(0, resultLimit);
|
|
7276
7331
|
return ranked.map((entry, rank) => ({
|
|
7277
7332
|
source: "message",
|
|
7278
|
-
content: previewText(entry.row.content),
|
|
7333
|
+
content: matchedSearchSnippet(entry.row.content, args.query) || previewText(entry.row.content),
|
|
7279
7334
|
score: linearDecayScore(rank, ranked.length),
|
|
7280
7335
|
messageOrdinal: entry.row.messageOrdinal,
|
|
7281
7336
|
messageId: entry.row.messageId,
|
|
@@ -7592,7 +7647,7 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
7592
7647
|
if (options.diagnostics) {
|
|
7593
7648
|
options.diagnostics.suppressedLiveMessageMatches = outcome.suppressedLiveMessageMatches;
|
|
7594
7649
|
}
|
|
7595
|
-
messageResults = outcome.results;
|
|
7650
|
+
messageResults = outcome.results.filter((result) => result.messageId !== options.excludeMessageId);
|
|
7596
7651
|
}
|
|
7597
7652
|
const workspace = resolveSearchWorkspaceContext(db, projectPath);
|
|
7598
7653
|
const [memoryOutcome, primerResults, noteResults] = await Promise.all([
|
|
@@ -7647,6 +7702,12 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
7647
7702
|
}).immediate();
|
|
7648
7703
|
}
|
|
7649
7704
|
}
|
|
7705
|
+
if (options.autoHint) {
|
|
7706
|
+
return results.map((result) => ({
|
|
7707
|
+
...result,
|
|
7708
|
+
relevanceScore: cleanSearchText(result.content).length === 0 ? 0 : keywordRelevance(trimmedQuery, result.content)
|
|
7709
|
+
}));
|
|
7710
|
+
}
|
|
7650
7711
|
return results;
|
|
7651
7712
|
}
|
|
7652
7713
|
var SEARCH_NOTE_EXPAND_HINT = "Use mmc_expand(start=N-10, end=N) around any note @msg anchor above to read the surrounding conversation context.";
|
|
@@ -8266,22 +8327,22 @@ function truncate(text, limit) {
|
|
|
8266
8327
|
return normalized;
|
|
8267
8328
|
return `${normalized.slice(0, Math.max(0, limit - 1)).trimEnd()}…`;
|
|
8268
8329
|
}
|
|
8269
|
-
function renderFragment(result, charCap, wordRules) {
|
|
8330
|
+
function renderFragment(result, charCap, wordRules, query) {
|
|
8270
8331
|
switch (result.source) {
|
|
8271
8332
|
case "memory": {
|
|
8272
|
-
const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8333
|
+
const compressed = cavemanCompress(cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8273
8334
|
return truncate(compressed, charCap);
|
|
8274
8335
|
}
|
|
8275
8336
|
case "message": {
|
|
8276
|
-
const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8337
|
+
const compressed = cavemanCompress(query ? matchedSearchSnippet(result.content, query, charCap) : cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8277
8338
|
return truncate(compressed, charCap);
|
|
8278
8339
|
}
|
|
8279
8340
|
case "primer": {
|
|
8280
|
-
const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8341
|
+
const compressed = cavemanCompress(cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8281
8342
|
return truncate(compressed, charCap);
|
|
8282
8343
|
}
|
|
8283
8344
|
case "note": {
|
|
8284
|
-
const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8345
|
+
const compressed = cavemanCompress(cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
|
|
8285
8346
|
return truncate(compressed, charCap);
|
|
8286
8347
|
}
|
|
8287
8348
|
}
|
|
@@ -8292,7 +8353,7 @@ function buildAutoSearchHint(results, options = {}) {
|
|
|
8292
8353
|
const picks = results.slice(0, maxFragments);
|
|
8293
8354
|
const lines = [];
|
|
8294
8355
|
for (const result of picks) {
|
|
8295
|
-
const fragment = renderFragment(result, fragmentCharCap, options.wordRules ?? "english");
|
|
8356
|
+
const fragment = renderFragment(result, fragmentCharCap, options.wordRules ?? "english", options.query ?? "");
|
|
8296
8357
|
if (fragment.length === 0)
|
|
8297
8358
|
continue;
|
|
8298
8359
|
lines.push(`- ${fragment}`);
|
|
@@ -8315,6 +8376,10 @@ ${trimmedBody}…
|
|
|
8315
8376
|
}
|
|
8316
8377
|
return wrapped;
|
|
8317
8378
|
}
|
|
8379
|
+
function selectAutoSearchResults(results, threshold) {
|
|
8380
|
+
const relevance = (result) => result.relevanceScore ?? result.score;
|
|
8381
|
+
return results.filter((result) => relevance(result) >= threshold).sort((left, right) => relevance(right) - relevance(left));
|
|
8382
|
+
}
|
|
8318
8383
|
|
|
8319
8384
|
// src/hooks/magic-context/transform-message-helpers.ts
|
|
8320
8385
|
function isMeaningfulUserMessage(msg) {
|
|
@@ -8591,6 +8656,9 @@ async function runAutoSearchHint(args) {
|
|
|
8591
8656
|
return null;
|
|
8592
8657
|
const searchOptions = {
|
|
8593
8658
|
limit: 10,
|
|
8659
|
+
autoHint: true,
|
|
8660
|
+
maxMessageOrdinal: Math.max(0, getLastCompartmentEndMessage(db, sessionId)),
|
|
8661
|
+
excludeMessageId: userMsgId,
|
|
8594
8662
|
memoryEnabled: options.memoryEnabled,
|
|
8595
8663
|
visibleMemoryIds: options.visibleMemoryIds ?? null,
|
|
8596
8664
|
sources: ["memory", "message"]
|
|
@@ -8615,11 +8683,15 @@ async function runAutoSearchHint(args) {
|
|
|
8615
8683
|
if (results.length === 0) {
|
|
8616
8684
|
return writeNoHintAndReconcile("empty");
|
|
8617
8685
|
}
|
|
8618
|
-
|
|
8619
|
-
|
|
8686
|
+
results = selectAutoSearchResults(results, options.scoreThreshold);
|
|
8687
|
+
if (results.length === 0) {
|
|
8688
|
+
sessionLog(sessionId, `auto-search: no fragment meets relevance threshold ${options.scoreThreshold}`);
|
|
8620
8689
|
return writeNoHintAndReconcile("below-threshold");
|
|
8621
8690
|
}
|
|
8622
|
-
const hintText = buildAutoSearchHint(results, {
|
|
8691
|
+
const hintText = buildAutoSearchHint(results, {
|
|
8692
|
+
wordRules: options.wordRules,
|
|
8693
|
+
query: rawPrompt
|
|
8694
|
+
});
|
|
8623
8695
|
if (!hintText) {
|
|
8624
8696
|
return writeNoHintAndReconcile("empty");
|
|
8625
8697
|
}
|
|
@@ -8683,6 +8755,30 @@ function getSessionErrorInfo(properties) {
|
|
|
8683
8755
|
};
|
|
8684
8756
|
}
|
|
8685
8757
|
|
|
8758
|
+
// src/hooks/magic-context/diagnostic-log-state.ts
|
|
8759
|
+
var states = new BoundedSessionMap(1000);
|
|
8760
|
+
var scope = (sessionId) => `${getMagicContextStorageDir()}\x00${getHarness()}\x00${sessionId}`;
|
|
8761
|
+
function diagnosticStateChanged(sessionId, category, state) {
|
|
8762
|
+
const key = scope(sessionId);
|
|
8763
|
+
const previous = states.get(key) ?? new Map;
|
|
8764
|
+
if (previous.get(category) === state)
|
|
8765
|
+
return false;
|
|
8766
|
+
previous.set(category, state);
|
|
8767
|
+
states.set(key, previous);
|
|
8768
|
+
return true;
|
|
8769
|
+
}
|
|
8770
|
+
function clearDiagnosticLogState(sessionId) {
|
|
8771
|
+
states.delete(scope(sessionId));
|
|
8772
|
+
}
|
|
8773
|
+
|
|
8774
|
+
// src/hooks/magic-context/nudge-evaluation-log.ts
|
|
8775
|
+
function logNudgeEvaluation(sessionId, phase, line) {
|
|
8776
|
+
const category = `${phase}:${line.split(":", 1)[0]}`;
|
|
8777
|
+
const state = line.split(" ").filter((field) => /^(ctx_reduce|band|dampening|verdict|reason|lease)=/.test(field)).join(" ");
|
|
8778
|
+
if (diagnosticStateChanged(sessionId, category, state))
|
|
8779
|
+
sessionLog(sessionId, line);
|
|
8780
|
+
}
|
|
8781
|
+
|
|
8686
8782
|
// src/hooks/magic-context/stripped-command.ts
|
|
8687
8783
|
function matchStrippedMagicContextCommand(parts) {
|
|
8688
8784
|
if (parts.length !== 1)
|
|
@@ -8871,7 +8967,7 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
|
|
|
8871
8967
|
evaluable: state.evaluable,
|
|
8872
8968
|
generationInvalidated: state.generationInvalidated
|
|
8873
8969
|
});
|
|
8874
|
-
|
|
8970
|
+
logNudgeEvaluation(sessionId, "tool-completion", formatChannel1Evaluation(decision));
|
|
8875
8971
|
setLastNudgeUndropped(args.db, sessionId, decision.nextLastNudge);
|
|
8876
8972
|
const nextNudgeState = {
|
|
8877
8973
|
...nudgeState,
|
|
@@ -10358,6 +10454,35 @@ function systemPromptDates(prompt, sticky) {
|
|
|
10358
10454
|
return { live: values.length ? JSON.stringify(values) : undefined, stable };
|
|
10359
10455
|
}
|
|
10360
10456
|
|
|
10457
|
+
// src/hooks/magic-context/system-prompt-sticky-date.ts
|
|
10458
|
+
var STICKY_DATE_KEY = "systemPromptStickyDate";
|
|
10459
|
+
function readPersistedSystemPromptStickyDate(db, sessionId) {
|
|
10460
|
+
try {
|
|
10461
|
+
const saved = readReplayEnvelope(db, sessionId, "read")[STICKY_DATE_KEY];
|
|
10462
|
+
return typeof saved === "string" && saved.length > 0 ? saved : undefined;
|
|
10463
|
+
} catch (error) {
|
|
10464
|
+
sessionLog(sessionId, "system prompt sticky date record unreadable:", error);
|
|
10465
|
+
return;
|
|
10466
|
+
}
|
|
10467
|
+
}
|
|
10468
|
+
function persistSystemPromptStickyDate(db, sessionId, stickyDate) {
|
|
10469
|
+
try {
|
|
10470
|
+
const written = updateReplayDocument(db, sessionId, (doc) => {
|
|
10471
|
+
if (doc[STICKY_DATE_KEY] === stickyDate)
|
|
10472
|
+
return false;
|
|
10473
|
+
doc.version = 2;
|
|
10474
|
+
doc[STICKY_DATE_KEY] = stickyDate;
|
|
10475
|
+
return true;
|
|
10476
|
+
});
|
|
10477
|
+
if (!written)
|
|
10478
|
+
sessionLog(sessionId, "system prompt sticky date record not written");
|
|
10479
|
+
return written;
|
|
10480
|
+
} catch (error) {
|
|
10481
|
+
sessionLog(sessionId, "system prompt sticky date record write failed:", error);
|
|
10482
|
+
return false;
|
|
10483
|
+
}
|
|
10484
|
+
}
|
|
10485
|
+
|
|
10361
10486
|
// src/hooks/magic-context/system-date-refresh.ts
|
|
10362
10487
|
var channels = new WeakMap;
|
|
10363
10488
|
var outputUpdates = new WeakMap;
|
|
@@ -10428,6 +10553,7 @@ function beginSystemDateRequest(history, sessionId, stage, turnId, identity) {
|
|
|
10428
10553
|
systemDone: false,
|
|
10429
10554
|
messagesSeen: false,
|
|
10430
10555
|
permitted: undefined,
|
|
10556
|
+
signedThinkingKept: undefined,
|
|
10431
10557
|
ambiguous: identity === undefined && (turnId === undefined || sameTurn)
|
|
10432
10558
|
};
|
|
10433
10559
|
const blocked = [...requests.values()].filter((candidate) => !candidate.explicit && candidate.ambiguous && !(candidate.systemSeen && candidate.messagesSeen) && candidate.turnId === turnId).length;
|
|
@@ -10450,6 +10576,10 @@ function systemDateRefreshPermission(history, request) {
|
|
|
10450
10576
|
const current = state(history, request);
|
|
10451
10577
|
return current?.ambiguous ? undefined : current?.permitted;
|
|
10452
10578
|
}
|
|
10579
|
+
function systemDateSignedThinkingKept(history, request) {
|
|
10580
|
+
const current = state(history, request);
|
|
10581
|
+
return current?.ambiguous ? undefined : current?.signedThinkingKept;
|
|
10582
|
+
}
|
|
10453
10583
|
function waitForSystemDateRefresh(history, request, apply) {
|
|
10454
10584
|
const current = state(history, request);
|
|
10455
10585
|
if (!current)
|
|
@@ -10464,7 +10594,7 @@ function retire(history, current) {
|
|
|
10464
10594
|
if (unpairable) {
|
|
10465
10595
|
const apply = current.waiting;
|
|
10466
10596
|
current.waiting = undefined;
|
|
10467
|
-
apply?.(false);
|
|
10597
|
+
apply?.(false, undefined);
|
|
10468
10598
|
}
|
|
10469
10599
|
const channel = channels.get(history);
|
|
10470
10600
|
const requests = channel?.get(current.sessionId);
|
|
@@ -10472,14 +10602,15 @@ function retire(history, current) {
|
|
|
10472
10602
|
if (requests?.size === 0)
|
|
10473
10603
|
channel?.delete(current.sessionId);
|
|
10474
10604
|
}
|
|
10475
|
-
function finishSystemDateRefresh(history, request, permitted) {
|
|
10605
|
+
function finishSystemDateRefresh(history, request, permitted, signedThinkingKept) {
|
|
10476
10606
|
const current = state(history, request);
|
|
10477
10607
|
if (!current)
|
|
10478
10608
|
return;
|
|
10479
10609
|
current.permitted = current.ambiguous ? false : permitted;
|
|
10610
|
+
current.signedThinkingKept = current.ambiguous ? undefined : signedThinkingKept;
|
|
10480
10611
|
const apply = current.waiting;
|
|
10481
10612
|
current.waiting = undefined;
|
|
10482
|
-
apply?.(current.permitted);
|
|
10613
|
+
apply?.(current.permitted, current.signedThinkingKept);
|
|
10483
10614
|
retire(history, current);
|
|
10484
10615
|
}
|
|
10485
10616
|
function finishSystemDateHook(history, request) {
|
|
@@ -10515,6 +10646,15 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10515
10646
|
});
|
|
10516
10647
|
const guidanceEpochs = createPromptSurfaceGuidanceEpochCache(promptSurfaceRuntime);
|
|
10517
10648
|
const stickyDateBySession = new Map;
|
|
10649
|
+
const recordedStickyDateBySession = new Map;
|
|
10650
|
+
const recordedStickyDate = (sessionId) => {
|
|
10651
|
+
let recorded = recordedStickyDateBySession.get(sessionId);
|
|
10652
|
+
if (recorded === undefined) {
|
|
10653
|
+
recorded = readPersistedSystemPromptStickyDate(deps.db, sessionId) ?? null;
|
|
10654
|
+
recordedStickyDateBySession.set(sessionId, recorded);
|
|
10655
|
+
}
|
|
10656
|
+
return recorded ?? undefined;
|
|
10657
|
+
};
|
|
10518
10658
|
const processSystemPrompt = async (input, output) => {
|
|
10519
10659
|
const sessionId = input.sessionID;
|
|
10520
10660
|
if (!sessionId)
|
|
@@ -10583,18 +10723,37 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10583
10723
|
const hasPersistedHash = previousHash !== "" && previousHash !== "0";
|
|
10584
10724
|
if (!hasPersistedHash)
|
|
10585
10725
|
stickyDateBySession.delete(sessionId);
|
|
10586
|
-
|
|
10726
|
+
let stickyDate = stickyDateBySession.get(sessionId);
|
|
10727
|
+
if (stickyDate === undefined && hasPersistedHash) {
|
|
10728
|
+
const recorded = recordedStickyDate(sessionId);
|
|
10729
|
+
const live = systemPromptDates(liveSystemContent).live;
|
|
10730
|
+
if (recorded !== undefined && live !== undefined && recorded !== live && systemPromptFingerprint(systemPromptDates(liveSystemContent, recorded).stable, promptSurface.preset) === previousHash) {
|
|
10731
|
+
stickyDate = recorded;
|
|
10732
|
+
stickyDateBySession.set(sessionId, recorded);
|
|
10733
|
+
}
|
|
10734
|
+
}
|
|
10735
|
+
const setStickyDate = (value) => {
|
|
10736
|
+
stickyDateBySession.set(sessionId, value);
|
|
10737
|
+
if (value !== recordedStickyDate(sessionId)) {
|
|
10738
|
+
if (persistSystemPromptStickyDate(deps.db, sessionId, value))
|
|
10739
|
+
recordedStickyDateBySession.set(sessionId, value);
|
|
10740
|
+
}
|
|
10741
|
+
};
|
|
10587
10742
|
const dates = systemPromptDates(liveSystemContent, stickyDate);
|
|
10588
10743
|
const currentDate = dates.live;
|
|
10589
10744
|
const stableCandidate = dates.stable;
|
|
10590
10745
|
const stableCandidateHash = systemPromptFingerprint(stableCandidate, promptSurface.preset);
|
|
10591
10746
|
const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
|
|
10592
10747
|
const rewritePermission = systemDateRefreshPermission(deps.historyRefreshSessions, dateRequest);
|
|
10748
|
+
const signedThinkingKept = systemDateSignedThinkingKept(deps.historyRefreshSessions, dateRequest);
|
|
10749
|
+
const prefixBoundModel = isPrefixBoundThinkingModel(liveModel?.providerID, liveModel?.modelID);
|
|
10750
|
+
const thinkingAllowsDate = (kept) => prefixBoundModel ? kept === false : kept !== true;
|
|
10751
|
+
const systemDateMayMove = (rewrite, kept) => (rewrite || idleCacheExpired) && thinkingAllowsDate(kept);
|
|
10593
10752
|
let deferredDateRefresh = false;
|
|
10594
|
-
if (currentDate && stickyDate && currentDate !== stickyDate && isCacheBusting
|
|
10753
|
+
if (currentDate && stickyDate && currentDate !== stickyDate && (isCacheBusting || idleCacheExpired && isPrefixBoundThinkingModel(liveModel?.providerID, liveModel?.modelID)) && rewritePermission === undefined && !contentOrPresetChanged && !requestMessagesFinal) {
|
|
10595
10754
|
const liveElements = [...output.system];
|
|
10596
|
-
deferredDateRefresh = waitForSystemDateRefresh(deps.historyRefreshSessions, dateRequest, (permitted) => {
|
|
10597
|
-
if (!permitted) {
|
|
10755
|
+
deferredDateRefresh = waitForSystemDateRefresh(deps.historyRefreshSessions, dateRequest, (permitted, keptSignedThinking) => {
|
|
10756
|
+
if (!systemDateMayMove(permitted, keptSignedThinking)) {
|
|
10598
10757
|
deps.systemPromptRefreshSessions.add(sessionId);
|
|
10599
10758
|
return;
|
|
10600
10759
|
}
|
|
@@ -10607,7 +10766,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10607
10766
|
cachedM0SystemHash: hash,
|
|
10608
10767
|
systemPromptTokens: estimateTokens(content)
|
|
10609
10768
|
});
|
|
10610
|
-
|
|
10769
|
+
setStickyDate(currentDate);
|
|
10611
10770
|
output.system.splice(0, output.system.length, ...liveElements);
|
|
10612
10771
|
publishSystemDateOutput(output.system);
|
|
10613
10772
|
deps.systemPromptRefreshSessions.delete(sessionId);
|
|
@@ -10618,12 +10777,12 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10618
10777
|
}
|
|
10619
10778
|
});
|
|
10620
10779
|
}
|
|
10621
|
-
const dateMayAdvance =
|
|
10780
|
+
const dateMayAdvance = thinkingAllowsDate(signedThinkingKept) && (contentOrPresetChanged || !deferredDateRefresh && systemDateMayMove(isCacheBusting && (dateRequest ? rewritePermission === true : rewritePermission !== false), signedThinkingKept));
|
|
10622
10781
|
if (currentDate && !stickyDate) {
|
|
10623
|
-
|
|
10782
|
+
setStickyDate(currentDate);
|
|
10624
10783
|
} else if (currentDate && stickyDate && currentDate !== stickyDate) {
|
|
10625
10784
|
if (dateMayAdvance) {
|
|
10626
|
-
|
|
10785
|
+
setStickyDate(currentDate);
|
|
10627
10786
|
sessionLog(sessionId, `system prompt date updated: ${stickyDate} → ${currentDate} (cache-busting pass)`);
|
|
10628
10787
|
} else {
|
|
10629
10788
|
let offset = 0;
|
|
@@ -10678,7 +10837,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10678
10837
|
sessionLog(sessionId, "system prompt meta persist failed (fail-open):", error);
|
|
10679
10838
|
}
|
|
10680
10839
|
}
|
|
10681
|
-
if (isCacheBusting && !deferredDateRefresh && (contentOrPresetChanged || !currentDate || currentDate === stickyDate || !dateRequest || rewritePermission === true)) {
|
|
10840
|
+
if (isCacheBusting && !deferredDateRefresh && (contentOrPresetChanged && thinkingAllowsDate(signedThinkingKept) || !currentDate || currentDate === stickyDate || !dateRequest && thinkingAllowsDate(signedThinkingKept) || rewritePermission === true && thinkingAllowsDate(signedThinkingKept))) {
|
|
10682
10841
|
deps.systemPromptRefreshSessions.delete(sessionId);
|
|
10683
10842
|
}
|
|
10684
10843
|
};
|
|
@@ -10692,6 +10851,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10692
10851
|
return {
|
|
10693
10852
|
handler,
|
|
10694
10853
|
clearSession: (sessionId) => {
|
|
10854
|
+
recordedStickyDateBySession.delete(sessionId);
|
|
10695
10855
|
clearSystemDateRefresh(deps.historyRefreshSessions, sessionId);
|
|
10696
10856
|
guidanceEpochs.clear(sessionId);
|
|
10697
10857
|
clearSystemPromptHashSession(sessionId, {
|
|
@@ -11867,6 +12027,8 @@ var PASS_DEGRADATION_EFFECTS = {
|
|
|
11867
12027
|
"stale-reduce-strip-exception": "changes-request",
|
|
11868
12028
|
"image-strip-exception": "changes-request",
|
|
11869
12029
|
"m0-m1-injection-degradation": "changes-request",
|
|
12030
|
+
"host-instruction-retention-read-failure": "changes-request",
|
|
12031
|
+
"host-instruction-retention-persistence-failure": "changes-request",
|
|
11870
12032
|
"m0-m1-fallback-failure": "changes-request",
|
|
11871
12033
|
"compaction-marker-drain-failure": "changes-request",
|
|
11872
12034
|
"auto-search-timeout": "served",
|
|
@@ -12165,7 +12327,7 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
12165
12327
|
justAwaitedPublication = activeRun.published;
|
|
12166
12328
|
published = published || activeRun.published;
|
|
12167
12329
|
const historyReprepareShouldBust = activeRun.published && args.deferredHistoryRefreshSessions.has(args.sessionId);
|
|
12168
|
-
pendingCompartmentInjection = prepareCompartmentInjection(args.db, args.resolvedSessionId, args.messages, historyReprepareShouldBust, args.projectPath, args.injectionBudgetTokens, args.experimentalTemporalAwareness);
|
|
12330
|
+
pendingCompartmentInjection = prepareCompartmentInjection(args.db, args.resolvedSessionId, args.messages, historyReprepareShouldBust, args.projectPath, args.injectionBudgetTokens, args.experimentalTemporalAwareness, args.coveredHostInstructions);
|
|
12169
12331
|
if (historyReprepareShouldBust) {
|
|
12170
12332
|
rebuiltHistoryThisPass = true;
|
|
12171
12333
|
}
|
|
@@ -12382,7 +12544,7 @@ function capturePendingDropEligibility(targets, protectedTagIds) {
|
|
|
12382
12544
|
eligible.add(number);
|
|
12383
12545
|
} else {
|
|
12384
12546
|
const content = target.getContent?.();
|
|
12385
|
-
if (typeof content === "string" && content.length > `[dropped §${number}§]`.length)
|
|
12547
|
+
if (typeof content === "string" && content.length > `[dropped §${number}§]`.length && target.canSetContent?.(`[dropped §${number}§]`) !== false)
|
|
12386
12548
|
eligible.add(number);
|
|
12387
12549
|
}
|
|
12388
12550
|
}
|
|
@@ -12440,27 +12602,43 @@ function buildReplacementContent(tagId) {
|
|
|
12440
12602
|
return `[dropped §${tagId}§]`;
|
|
12441
12603
|
}
|
|
12442
12604
|
function applyNewToolDrop(target, options) {
|
|
12443
|
-
|
|
12605
|
+
const plan = planNewToolDrop(target, options, !!options.persist);
|
|
12606
|
+
if (!plan)
|
|
12444
12607
|
return { result: "incomplete", mode: "full" };
|
|
12608
|
+
options.persist?.(plan.mode);
|
|
12609
|
+
return plan.apply();
|
|
12610
|
+
}
|
|
12611
|
+
function planNewToolDrop(target, options, prepare, plannedRemovals) {
|
|
12612
|
+
if (prepare && (target?.prepareDrop?.() ?? target?.canDrop?.()) === false) {
|
|
12613
|
+
return;
|
|
12445
12614
|
}
|
|
12446
12615
|
if (!target) {
|
|
12447
|
-
|
|
12448
|
-
return { result: "absent", mode: "full" };
|
|
12616
|
+
return { mode: "full", apply: () => ({ result: "absent", mode: "full" }) };
|
|
12449
12617
|
}
|
|
12450
|
-
if (options.inWindow && hasSmallToolInput(target) || options.keepSkeleton === true || target.cannotRemove?.() === true || target.wouldStrandConversationEnd?.() === true) {
|
|
12618
|
+
if (options.inWindow && hasSmallToolInput(target) || options.keepSkeleton === true || target.cannotRemove?.() === true || target.wouldStrandConversationEnd?.(plannedRemovals) === true) {
|
|
12451
12619
|
const strip = target.hasAttachments?.() === true;
|
|
12452
|
-
|
|
12620
|
+
const mode = strip ? "skeleton_stripped" : "skeleton_real";
|
|
12453
12621
|
return {
|
|
12454
|
-
|
|
12455
|
-
|
|
12622
|
+
mode,
|
|
12623
|
+
apply: () => ({
|
|
12624
|
+
result: (strip ? target.skeletonStripped?.() : target.skeletonReal?.()) ?? "absent",
|
|
12625
|
+
mode
|
|
12626
|
+
})
|
|
12456
12627
|
};
|
|
12457
12628
|
}
|
|
12458
|
-
|
|
12459
|
-
|
|
12460
|
-
|
|
12461
|
-
|
|
12462
|
-
|
|
12463
|
-
|
|
12629
|
+
return {
|
|
12630
|
+
mode: "full",
|
|
12631
|
+
apply: () => {
|
|
12632
|
+
const result = target.drop?.() ?? "absent";
|
|
12633
|
+
if (result === "truncated" && target.hasAttachments?.() === true) {
|
|
12634
|
+
return {
|
|
12635
|
+
result: target.skeletonStripped?.() ?? "absent",
|
|
12636
|
+
mode: "skeleton_stripped"
|
|
12637
|
+
};
|
|
12638
|
+
}
|
|
12639
|
+
return { result, mode: result === "truncated" ? "skeleton_real" : "full" };
|
|
12640
|
+
}
|
|
12641
|
+
};
|
|
12464
12642
|
}
|
|
12465
12643
|
function hasSmallToolInput(target) {
|
|
12466
12644
|
const bytes = target?.inputStringBytes?.() ?? null;
|
|
@@ -12542,6 +12720,7 @@ function renderConvertedToolSkeletons(targets, converted) {
|
|
|
12542
12720
|
}
|
|
12543
12721
|
return didMutate;
|
|
12544
12722
|
}
|
|
12723
|
+
var PENDING_OPERATION_CHUNK_SIZE = 64;
|
|
12545
12724
|
function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete, onEligibilitySnapshot) {
|
|
12546
12725
|
let didMutateMessage = false;
|
|
12547
12726
|
let diagnostics;
|
|
@@ -12551,159 +12730,188 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12551
12730
|
diagnostics.reasons[reason] = (diagnostics.reasons[reason] ?? 0) + 1;
|
|
12552
12731
|
};
|
|
12553
12732
|
let admitted = false;
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
if (!neededTagNumbers.has(tagNumber))
|
|
12569
|
-
numbers.push(tagNumber);
|
|
12570
|
-
}
|
|
12571
|
-
return numbers;
|
|
12572
|
-
})());
|
|
12573
|
-
const tagById = new Map(tags.map((tag) => [tag.tagNumber, tag]));
|
|
12574
|
-
const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
|
|
12575
|
-
const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
|
|
12576
|
-
const opsToApply = [
|
|
12577
|
-
...pendingOps.map((op) => ({ op, synthetic: false })),
|
|
12578
|
-
...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
|
|
12579
|
-
];
|
|
12580
|
-
diagnostics = {
|
|
12581
|
-
source: pendingOps.length > 0 && syntheticPendingOps.length > 0 ? "mixed" : syntheticPendingOps.length > 0 ? "synthetic" : "pending",
|
|
12582
|
-
total: opsToApply.length,
|
|
12583
|
-
mutated: 0,
|
|
12584
|
-
persistedWithoutMutation: 0,
|
|
12585
|
-
reasons: {}
|
|
12586
|
-
};
|
|
12587
|
-
const skeletonWindow = new Set(getNewestToolTagNumbers(db, sessionId, RECENT_TOOL_SKELETON_WINDOW));
|
|
12588
|
-
for (const { op: pendingOp, synthetic } of opsToApply) {
|
|
12589
|
-
let operationMutated = false;
|
|
12590
|
-
const tagStatus = tagStatusById.get(pendingOp.tagId);
|
|
12591
|
-
if (tagStatus === "compacted" || tagStatus === "dropped") {
|
|
12592
|
-
reject("already_reduced");
|
|
12593
|
-
if (!synthetic)
|
|
12594
|
-
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
12595
|
-
continue;
|
|
12596
|
-
}
|
|
12597
|
-
const target = targets.get(pendingOp.tagId);
|
|
12598
|
-
const veto = pendingDropVeto(pendingOp.tagId, target, protectedTagIds);
|
|
12599
|
-
if (veto) {
|
|
12600
|
-
reject(veto);
|
|
12601
|
-
continue;
|
|
12602
|
-
}
|
|
12603
|
-
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
12604
|
-
if (synthetic) {
|
|
12605
|
-
if (!isToolTag) {
|
|
12606
|
-
reject("synthetic_non_tool");
|
|
12607
|
-
continue;
|
|
12608
|
-
}
|
|
12609
|
-
if (target?.canDrop?.() !== true) {
|
|
12610
|
-
reject("synthetic_target_not_droppable");
|
|
12611
|
-
continue;
|
|
12612
|
-
}
|
|
12733
|
+
let startedAt = 0;
|
|
12734
|
+
const mutations = [];
|
|
12735
|
+
let drainChunk;
|
|
12736
|
+
let hasMore = false;
|
|
12737
|
+
do {
|
|
12738
|
+
admitted = false;
|
|
12739
|
+
startedAt = 0;
|
|
12740
|
+
try {
|
|
12741
|
+
db.transaction(() => {
|
|
12742
|
+
admitted = true;
|
|
12743
|
+
startedAt = performance.now();
|
|
12744
|
+
if (drainChunk) {
|
|
12745
|
+
drainChunk();
|
|
12746
|
+
return;
|
|
12613
12747
|
}
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12748
|
+
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
12749
|
+
onEligibilitySnapshot?.(capturePendingDropEligibility(targets, protectedTagIds));
|
|
12750
|
+
const tags = preloadedTags ?? getTagsByNumbers(db, sessionId, [
|
|
12751
|
+
...new Set([
|
|
12752
|
+
...pendingOps.map((op) => op.tagId),
|
|
12753
|
+
...syntheticPendingOps.map((op) => op.tagId)
|
|
12754
|
+
])
|
|
12755
|
+
]);
|
|
12756
|
+
const tagById = new Map(tags.map((tag) => [tag.tagNumber, tag]));
|
|
12757
|
+
const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
|
|
12758
|
+
const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
|
|
12759
|
+
const opsToApply = [
|
|
12760
|
+
...pendingOps.map((op) => ({ op, synthetic: false })),
|
|
12761
|
+
...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
|
|
12762
|
+
];
|
|
12763
|
+
diagnostics = {
|
|
12764
|
+
source: pendingOps.length > 0 && syntheticPendingOps.length > 0 ? "mixed" : syntheticPendingOps.length > 0 ? "synthetic" : "pending",
|
|
12765
|
+
total: opsToApply.length,
|
|
12766
|
+
mutated: 0,
|
|
12767
|
+
persistedWithoutMutation: 0,
|
|
12768
|
+
reasons: {}
|
|
12769
|
+
};
|
|
12770
|
+
const skeletonWindow = new Set(preloadedTags ? tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW) : getNewestToolTagNumbers(db, sessionId, RECENT_TOOL_SKELETON_WINDOW));
|
|
12771
|
+
const plannedRemovals = new Set;
|
|
12772
|
+
const removedTagIds = new Set;
|
|
12773
|
+
const record = (mutated) => {
|
|
12774
|
+
if (!diagnostics)
|
|
12775
|
+
return;
|
|
12776
|
+
if (mutated) {
|
|
12777
|
+
didMutateMessage = true;
|
|
12778
|
+
diagnostics.mutated += 1;
|
|
12779
|
+
} else
|
|
12780
|
+
diagnostics.persistedWithoutMutation += 1;
|
|
12781
|
+
};
|
|
12782
|
+
let cursor = 0;
|
|
12783
|
+
drainChunk = () => {
|
|
12784
|
+
const chunk = opsToApply.slice(cursor, cursor + PENDING_OPERATION_CHUNK_SIZE);
|
|
12785
|
+
cursor += chunk.length;
|
|
12786
|
+
hasMore = cursor < opsToApply.length;
|
|
12787
|
+
for (const { op: pendingOp, synthetic } of chunk) {
|
|
12788
|
+
const tagStatus = tagStatusById.get(pendingOp.tagId);
|
|
12789
|
+
if (tagStatus === "compacted" || tagStatus === "dropped") {
|
|
12790
|
+
reject("already_reduced");
|
|
12621
12791
|
if (!synthetic)
|
|
12622
12792
|
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
12623
|
-
}).immediate();
|
|
12624
|
-
} finally {
|
|
12625
|
-
if (startedAt)
|
|
12626
|
-
logSlowWriteTransaction("apply_pending_operation", startedAt);
|
|
12627
|
-
}
|
|
12628
|
-
};
|
|
12629
|
-
if (isToolTag) {
|
|
12630
|
-
if (editMarkerTagIds.has(pendingOp.tagId)) {
|
|
12631
|
-
const strip = target?.hasAttachments?.() === true;
|
|
12632
|
-
if (target?.canDrop?.() === false || target?.prepareDrop?.() === false || !target) {
|
|
12633
|
-
reject("edit_marker_incomplete");
|
|
12634
12793
|
continue;
|
|
12635
12794
|
}
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
if (markResult === "incomplete" || markResult === "absent") {
|
|
12639
|
-
reject(`edit_marker_${markResult}`);
|
|
12795
|
+
if (removedTagIds.has(pendingOp.tagId)) {
|
|
12796
|
+
reject("drop_incomplete");
|
|
12640
12797
|
continue;
|
|
12641
12798
|
}
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
} else {
|
|
12647
|
-
const { result: dropResult, mode: appliedMode } = applyNewToolDrop(target, {
|
|
12648
|
-
inWindow: skeletonWindow.has(pendingOp.tagId),
|
|
12649
|
-
persist: persistDrop
|
|
12650
|
-
});
|
|
12651
|
-
if (dropResult === "incomplete" || synthetic && dropResult !== "removed" && dropResult !== "truncated") {
|
|
12652
|
-
reject(`drop_${dropResult}`);
|
|
12799
|
+
const target = targets.get(pendingOp.tagId);
|
|
12800
|
+
const veto = pendingDropVeto(pendingOp.tagId, target, protectedTagIds);
|
|
12801
|
+
if (veto) {
|
|
12802
|
+
reject(veto);
|
|
12653
12803
|
continue;
|
|
12654
12804
|
}
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12805
|
+
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
12806
|
+
if (synthetic) {
|
|
12807
|
+
if (!isToolTag) {
|
|
12808
|
+
reject("synthetic_non_tool");
|
|
12809
|
+
continue;
|
|
12810
|
+
}
|
|
12811
|
+
if (target?.canDrop?.() !== true) {
|
|
12812
|
+
reject("synthetic_target_not_droppable");
|
|
12813
|
+
continue;
|
|
12814
|
+
}
|
|
12815
|
+
}
|
|
12816
|
+
const persistDrop = (mode) => {
|
|
12817
|
+
markTagDropped(db, sessionId, pendingOp.tagId, mode);
|
|
12818
|
+
if (!synthetic)
|
|
12819
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
12820
|
+
};
|
|
12821
|
+
if (isToolTag) {
|
|
12822
|
+
if (editMarkerTagIds.has(pendingOp.tagId)) {
|
|
12823
|
+
const strip = target?.hasAttachments?.() === true;
|
|
12824
|
+
if (target?.canDrop?.() === false || target?.prepareDrop?.() === false || !target) {
|
|
12825
|
+
reject("edit_marker_incomplete");
|
|
12826
|
+
continue;
|
|
12827
|
+
}
|
|
12828
|
+
persistDrop(strip ? "edit_marker_stripped" : "edit_marker");
|
|
12829
|
+
mutations.push(() => {
|
|
12830
|
+
const markResult = (strip ? target?.editMarkerStripped?.() : target?.editMarker?.()) ?? "absent";
|
|
12831
|
+
if (markResult === "incomplete" || markResult === "absent") {
|
|
12832
|
+
reject(`edit_marker_${markResult}`);
|
|
12833
|
+
return;
|
|
12834
|
+
}
|
|
12835
|
+
record(true);
|
|
12836
|
+
onTagReduced?.({
|
|
12837
|
+
tagNumber: pendingOp.tagId,
|
|
12838
|
+
mode: "edit_marker"
|
|
12839
|
+
});
|
|
12840
|
+
});
|
|
12841
|
+
} else {
|
|
12842
|
+
const plan = planNewToolDrop(target, { inWindow: skeletonWindow.has(pendingOp.tagId) }, true, plannedRemovals);
|
|
12843
|
+
if (!plan) {
|
|
12844
|
+
reject("drop_incomplete");
|
|
12845
|
+
continue;
|
|
12846
|
+
}
|
|
12847
|
+
persistDrop(plan.mode);
|
|
12848
|
+
if (plan.mode === "full" && target?.drop) {
|
|
12849
|
+
target.notePlannedRemoval?.(plannedRemovals);
|
|
12850
|
+
removedTagIds.add(pendingOp.tagId);
|
|
12851
|
+
}
|
|
12852
|
+
mutations.push(() => {
|
|
12853
|
+
const { result: dropResult, mode: appliedMode } = plan.apply();
|
|
12854
|
+
if (dropResult === "incomplete" || synthetic && dropResult !== "removed" && dropResult !== "truncated") {
|
|
12855
|
+
reject(`drop_${dropResult}`);
|
|
12856
|
+
return;
|
|
12857
|
+
}
|
|
12858
|
+
if (dropResult === "removed" || dropResult === "truncated") {
|
|
12859
|
+
record(true);
|
|
12860
|
+
onTagReduced?.({
|
|
12861
|
+
tagNumber: pendingOp.tagId,
|
|
12862
|
+
mode: appliedMode === "full" ? "full" : "truncated"
|
|
12863
|
+
});
|
|
12864
|
+
} else {
|
|
12865
|
+
reject(`drop_${dropResult}`);
|
|
12866
|
+
record(false);
|
|
12867
|
+
}
|
|
12868
|
+
});
|
|
12869
|
+
}
|
|
12870
|
+
} else if (target) {
|
|
12871
|
+
const replacement = buildReplacementContent(pendingOp.tagId);
|
|
12872
|
+
if (target.canSetContent?.(replacement) === false) {
|
|
12873
|
+
reject("content_unchanged");
|
|
12874
|
+
continue;
|
|
12875
|
+
}
|
|
12876
|
+
persistDrop();
|
|
12877
|
+
mutations.push(() => {
|
|
12878
|
+
const priorContent = target.getContent?.();
|
|
12879
|
+
const changed = target.setContent(replacement);
|
|
12880
|
+
record(changed);
|
|
12881
|
+
if (changed) {
|
|
12882
|
+
const originalCharacters = typeof priorContent === "string" ? priorContent.length : tagById.get(pendingOp.tagId)?.byteSize ?? replacement.length;
|
|
12883
|
+
onTagReduced?.({
|
|
12884
|
+
tagNumber: pendingOp.tagId,
|
|
12885
|
+
mode: "partial",
|
|
12886
|
+
removedCharacters: Math.max(0, originalCharacters - replacement.length)
|
|
12887
|
+
});
|
|
12888
|
+
} else {
|
|
12889
|
+
reject("content_unchanged");
|
|
12890
|
+
}
|
|
12661
12891
|
});
|
|
12662
|
-
} else {
|
|
12663
|
-
reject(
|
|
12892
|
+
} else if (!synthetic) {
|
|
12893
|
+
reject("target_absent");
|
|
12894
|
+
persistDrop();
|
|
12895
|
+
mutations.push(() => record(false));
|
|
12664
12896
|
}
|
|
12665
|
-
shouldPersistDrop = true;
|
|
12666
12897
|
}
|
|
12667
|
-
}
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
onTagReduced?.({
|
|
12677
|
-
tagNumber: pendingOp.tagId,
|
|
12678
|
-
mode: "partial",
|
|
12679
|
-
removedCharacters: Math.max(0, originalCharacters - replacement.length)
|
|
12680
|
-
});
|
|
12681
|
-
} else {
|
|
12682
|
-
reject("content_unchanged");
|
|
12683
|
-
}
|
|
12684
|
-
shouldPersistDrop = true;
|
|
12685
|
-
} else if (!synthetic) {
|
|
12686
|
-
reject("target_absent");
|
|
12687
|
-
persistDrop();
|
|
12688
|
-
shouldPersistDrop = true;
|
|
12689
|
-
}
|
|
12690
|
-
if (!shouldPersistDrop) {
|
|
12691
|
-
reject("not_persisted");
|
|
12692
|
-
continue;
|
|
12693
|
-
}
|
|
12694
|
-
if (operationMutated)
|
|
12695
|
-
diagnostics.mutated += 1;
|
|
12696
|
-
else
|
|
12697
|
-
diagnostics.persistedWithoutMutation += 1;
|
|
12898
|
+
};
|
|
12899
|
+
drainChunk();
|
|
12900
|
+
}).immediate();
|
|
12901
|
+
} catch (error) {
|
|
12902
|
+
if (!admitted && /database (?:table )?is locked|sqlite_(busy|locked)/i.test(String(error))) {
|
|
12903
|
+
sessionLog(sessionId, "pending operations write admission busy; retaining remaining operations for retry");
|
|
12904
|
+
hasMore = false;
|
|
12905
|
+
} else {
|
|
12906
|
+
throw error;
|
|
12698
12907
|
}
|
|
12908
|
+
} finally {
|
|
12909
|
+
if (startedAt)
|
|
12910
|
+
logSlowWriteTransaction("apply_pending_operations", startedAt);
|
|
12699
12911
|
}
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
return false;
|
|
12704
|
-
}
|
|
12705
|
-
throw error;
|
|
12706
|
-
}
|
|
12912
|
+
for (const mutate of mutations.splice(0))
|
|
12913
|
+
mutate();
|
|
12914
|
+
} while (hasMore);
|
|
12707
12915
|
if (diagnostics) {
|
|
12708
12916
|
onBatchComplete?.(diagnostics);
|
|
12709
12917
|
if (diagnostics.total > 0 && diagnostics.mutated === 0) {
|
|
@@ -12937,10 +13145,41 @@ function createExistingTagResolver(sessionId, tagger, db) {
|
|
|
12937
13145
|
}
|
|
12938
13146
|
|
|
12939
13147
|
// src/hooks/magic-context/transform-stage-logger.ts
|
|
12940
|
-
|
|
12941
|
-
|
|
13148
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
13149
|
+
var SLOW_STAGE_MS = 100;
|
|
13150
|
+
var passes = new AsyncLocalStorage;
|
|
13151
|
+
async function withTransformTimingSummary(run) {
|
|
13152
|
+
const pass = {
|
|
13153
|
+
stages: [],
|
|
13154
|
+
slow: [],
|
|
13155
|
+
closed: false,
|
|
13156
|
+
sessionId: undefined
|
|
13157
|
+
};
|
|
13158
|
+
return passes.run(pass, async () => {
|
|
13159
|
+
try {
|
|
13160
|
+
return await run();
|
|
13161
|
+
} finally {
|
|
13162
|
+
pass.closed = true;
|
|
13163
|
+
if (pass.sessionId)
|
|
13164
|
+
sessionLog(pass.sessionId, `transform stages: ${pass.stages.join(" ")} slow>=${SLOW_STAGE_MS}ms=[${pass.slow.join(",")}]`);
|
|
13165
|
+
}
|
|
13166
|
+
});
|
|
13167
|
+
}
|
|
13168
|
+
function logTransformElapsed(sessionId, stage, elapsedMs, extra) {
|
|
13169
|
+
const elapsed = elapsedMs.toFixed(1);
|
|
12942
13170
|
const suffix = extra ? ` ${extra}` : "";
|
|
12943
|
-
|
|
13171
|
+
const pass = passes.getStore();
|
|
13172
|
+
if (pass && !pass.closed) {
|
|
13173
|
+
pass.sessionId = sessionId;
|
|
13174
|
+
pass.stages.push(`${stage}=${elapsed}ms${extra ? `(${extra})` : ""}`);
|
|
13175
|
+
if (elapsedMs >= SLOW_STAGE_MS)
|
|
13176
|
+
pass.slow.push(stage);
|
|
13177
|
+
}
|
|
13178
|
+
if (elapsedMs >= SLOW_STAGE_MS)
|
|
13179
|
+
sessionLog(sessionId, `transform stage: stage=${stage} elapsed=${elapsed}ms${suffix}`);
|
|
13180
|
+
}
|
|
13181
|
+
function logTransformTiming(sessionId, stage, startMs, extra) {
|
|
13182
|
+
logTransformElapsed(sessionId, stage, performance.now() - startMs, extra);
|
|
12944
13183
|
}
|
|
12945
13184
|
|
|
12946
13185
|
// src/hooks/magic-context/tag-messages.ts
|
|
@@ -13318,13 +13557,19 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
13318
13557
|
}));
|
|
13319
13558
|
accAssignTag += performance.now() - _tAssignText;
|
|
13320
13559
|
const persistedSource = sourceContents.get(tagId);
|
|
13321
|
-
if (persistedSource !== undefined) {
|
|
13322
|
-
textPart.text = options.normalizeRestoredAssistantText && message.info.role === "assistant" ? options.normalizeRestoredAssistantText(persistedSource) : persistedSource;
|
|
13560
|
+
if (persistedSource !== undefined && !options.refreshSourceContents) {
|
|
13561
|
+
textPart.text = options.normalizeRestoredAssistantText && message.info.role === "assistant" ? options.normalizeRestoredAssistantText(persistedSource, message.info.providerID) : persistedSource;
|
|
13323
13562
|
} else {
|
|
13324
13563
|
const sourceContent = stripTagPrefix(textPart.text);
|
|
13325
|
-
if (sourceContent.trim().length > 0) {
|
|
13564
|
+
if (sourceContent.trim().length > 0 || options.refreshSourceContents) {
|
|
13326
13565
|
const _tSaveText = performance.now();
|
|
13327
|
-
|
|
13566
|
+
if (options.refreshSourceContents) {
|
|
13567
|
+
db.transaction(() => {
|
|
13568
|
+
replaceSourceContent(db, sessionId, tagId, sourceContent);
|
|
13569
|
+
db.prepare("UPDATE tags SET byte_size = ?, token_count = ? WHERE session_id = ? AND tag_number = ?").run(byteSize(sourceContent), estimateTextTagTokenCount(sourceContent), sessionId, tagId);
|
|
13570
|
+
}).immediate();
|
|
13571
|
+
} else
|
|
13572
|
+
saveSourceContent(db, sessionId, tagId, sourceContent);
|
|
13328
13573
|
accSaveSource += performance.now() - _tSaveText;
|
|
13329
13574
|
}
|
|
13330
13575
|
}
|
|
@@ -13343,6 +13588,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
13343
13588
|
dropReasoningParts: thinkingParts,
|
|
13344
13589
|
mutationParts: [{ message, part: textPart }],
|
|
13345
13590
|
textPrefix: skipPrefixInjection ? "" : prependTag(tagId, ""),
|
|
13591
|
+
canSetContent: (content) => textPart.text !== content,
|
|
13346
13592
|
setContent: (content, options) => {
|
|
13347
13593
|
if (textPart.text === content)
|
|
13348
13594
|
return false;
|
|
@@ -13400,26 +13646,20 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
13400
13646
|
const filePart = part;
|
|
13401
13647
|
const messageParts = message.parts;
|
|
13402
13648
|
const contentId = `${messageId}:file${partIndex}`;
|
|
13403
|
-
const existingTagId = resolver.resolve(messageId, "file", contentId, fileOrdinal);
|
|
13404
|
-
|
|
13405
|
-
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
|
|
13409
|
-
}));
|
|
13410
|
-
accAssignTag += performance.now() - _tAssignFile;
|
|
13411
|
-
if (existingTagId === undefined) {
|
|
13412
|
-
const sourceContent = buildFileSourceContent(message.parts);
|
|
13413
|
-
if (sourceContent) {
|
|
13414
|
-
const _tSaveFile = performance.now();
|
|
13415
|
-
saveSourceContent(db, sessionId, tagId, sourceContent);
|
|
13416
|
-
accSaveSource += performance.now() - _tSaveFile;
|
|
13417
|
-
}
|
|
13418
|
-
}
|
|
13649
|
+
const existingTagId = resolver.resolve(messageId, "file", contentId, fileOrdinal) ?? getTagNumberByMessageId(db, sessionId, contentId) ?? undefined;
|
|
13650
|
+
fileOrdinal += 1;
|
|
13651
|
+
if (existingTagId === undefined)
|
|
13652
|
+
continue;
|
|
13653
|
+
const tagId = existingTagId;
|
|
13654
|
+
tagger.bindTag(sessionId, contentId, tagId);
|
|
13419
13655
|
messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, tagId));
|
|
13420
13656
|
targets.set(tagId, {
|
|
13421
13657
|
message,
|
|
13422
13658
|
mutationParts: [{ message, part: filePart }],
|
|
13659
|
+
canSetContent: (content) => {
|
|
13660
|
+
const current = messageParts[partIndex];
|
|
13661
|
+
return !(typeof current === "object" && current !== null && ("text" in current) && current.text === content);
|
|
13662
|
+
},
|
|
13423
13663
|
setContent: (content) => {
|
|
13424
13664
|
const prev = messageParts[partIndex];
|
|
13425
13665
|
const prevText = typeof prev === "object" && prev !== null && "text" in prev ? prev.text : "";
|
|
@@ -13432,7 +13672,6 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
13432
13672
|
return true;
|
|
13433
13673
|
}
|
|
13434
13674
|
});
|
|
13435
|
-
fileOrdinal += 1;
|
|
13436
13675
|
}
|
|
13437
13676
|
}
|
|
13438
13677
|
if (message.info.role === "assistant" && !messageHasTextPart) {
|
|
@@ -13461,6 +13700,23 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
|
|
|
13461
13700
|
normalizationTargets
|
|
13462
13701
|
};
|
|
13463
13702
|
}
|
|
13703
|
+
// src/features/magic-context/storage-host-instruction-retention.ts
|
|
13704
|
+
var NAMESPACE3 = "hostInstructionRetention";
|
|
13705
|
+
function isHostInstructionRetentionOn(db, sessionId) {
|
|
13706
|
+
const lane = readReplayEnvelope(db, sessionId)[NAMESPACE3];
|
|
13707
|
+
return typeof lane === "object" && lane !== null && lane.on === true;
|
|
13708
|
+
}
|
|
13709
|
+
function markHostInstructionRetention(db, sessionId) {
|
|
13710
|
+
return updateReplayDocument(db, sessionId, (doc) => {
|
|
13711
|
+
const lane = doc[NAMESPACE3];
|
|
13712
|
+
if (typeof lane === "object" && lane !== null && lane.on === true)
|
|
13713
|
+
return false;
|
|
13714
|
+
doc.version = 2;
|
|
13715
|
+
doc[NAMESPACE3] = { on: true };
|
|
13716
|
+
return true;
|
|
13717
|
+
});
|
|
13718
|
+
}
|
|
13719
|
+
|
|
13464
13720
|
// src/hooks/magic-context/channel2-cycle.ts
|
|
13465
13721
|
function rearmChannel2AfterCoverageAdvancingHardFold(input) {
|
|
13466
13722
|
if (input.compactionOff || !input.foldExecuted || input.previousCoverage === null || input.currentCoverage === null || input.currentCoverage <= input.previousCoverage) {
|
|
@@ -14374,6 +14630,28 @@ function freezeReasoningOnBustingPass(args) {
|
|
|
14374
14630
|
sessionLog(args.sessionId, `proactive thinking strip: busting pass froze reasoning of ${messageIds.length} assistant(s) [${messageIds.join(",")}]`);
|
|
14375
14631
|
return { strip: { messageIds }, persistenceFailed: false };
|
|
14376
14632
|
}
|
|
14633
|
+
function servesThinkingBlock(messages) {
|
|
14634
|
+
for (const message of messages) {
|
|
14635
|
+
if (message.info.role !== "assistant")
|
|
14636
|
+
continue;
|
|
14637
|
+
for (const part of message.parts) {
|
|
14638
|
+
if (!isRecord(part) || part.ignored === true)
|
|
14639
|
+
continue;
|
|
14640
|
+
if (part.type === "redacted_thinking")
|
|
14641
|
+
return true;
|
|
14642
|
+
if (part.type !== "reasoning" && part.type !== "thinking")
|
|
14643
|
+
continue;
|
|
14644
|
+
const anthropic = isRecord(part.metadata) ? part.metadata.anthropic : undefined;
|
|
14645
|
+
if (!isRecord(anthropic))
|
|
14646
|
+
continue;
|
|
14647
|
+
if (anthropic.redactedData !== undefined)
|
|
14648
|
+
return true;
|
|
14649
|
+
if (typeof part.text === "string" && part.text !== "")
|
|
14650
|
+
return true;
|
|
14651
|
+
}
|
|
14652
|
+
}
|
|
14653
|
+
return false;
|
|
14654
|
+
}
|
|
14377
14655
|
function dropMarkerSummaryTag(db, sessionId, summaryMessageId) {
|
|
14378
14656
|
const tagNumber = getTagNumberByMessageId(db, sessionId, `${summaryMessageId}:p0`);
|
|
14379
14657
|
if (tagNumber !== null)
|
|
@@ -14537,7 +14815,7 @@ function finalizeMessageRepresentation(messages, resolvedProviderID, options) {
|
|
|
14537
14815
|
clearedParts = stripClearedReasoning(targetedMessages.filter((message) => !restoredMessages.has(message)));
|
|
14538
14816
|
}
|
|
14539
14817
|
}
|
|
14540
|
-
const bindingRecoveryParts =
|
|
14818
|
+
const bindingRecoveryParts = stripReasoningFromAssistantIds(messages, resolvedProviderID, options?.frozenThinkingBindingMessageIds ?? new Set, restoredMessages);
|
|
14541
14819
|
const mergedReasoningParts = bindingRecoveryParts + (options?.skipMergedReasoningStrip ? 0 : stripReasoningFromMergedAssistants(messages, resolvedProviderID, {
|
|
14542
14820
|
mutationExemptMessage: options?.reasoningMutationExemptMessage,
|
|
14543
14821
|
frozenMessageIds: options?.mergedReasoningStrippedIds,
|
|
@@ -14614,7 +14892,7 @@ async function runPostTransformPhase(args) {
|
|
|
14614
14892
|
let deferredMaterialize = args.canConsumeDeferredLate && deferredMaterializationWasPending;
|
|
14615
14893
|
let materializationRequested = isExplicitFlush || deferredMaterialize;
|
|
14616
14894
|
const m0M1EnabledForFold = args.m0M1 !== undefined && (!!args.m0M1.projectPath || !!args.m0M1.projectDirectory) && (args.fullFeatureMode || compactionOff);
|
|
14617
|
-
const frozenThinking = new Set(
|
|
14895
|
+
const frozenThinking = new Set(getMergedReasoningStrippedIds(args.db, args.sessionId));
|
|
14618
14896
|
const bindingThinking = new Set([...frozenThinking].filter((id) => id.startsWith(THINKING_BINDING_RECOVERY_FROZEN_PREFIX)).map((id) => id.slice(THINKING_BINDING_RECOVERY_FROZEN_PREFIX.length)));
|
|
14619
14897
|
const retainedThinking = args.activeThinkingTurn ? retainedActiveThinkingParts({
|
|
14620
14898
|
messages: args.messages,
|
|
@@ -14640,6 +14918,7 @@ async function runPostTransformPhase(args) {
|
|
|
14640
14918
|
let freezeM0M1 = args.freezeM0M1 === true || activeThinkingPrefixHold;
|
|
14641
14919
|
let rewritingSignedPrefix = false;
|
|
14642
14920
|
let thinkingReleasedForFit = false;
|
|
14921
|
+
let thinkingOmissionPersistenceFailed = false;
|
|
14643
14922
|
const releaseThinkingForRewrite = (forFit = false) => {
|
|
14644
14923
|
const stripped = freezeReasoningOnBustingPass({
|
|
14645
14924
|
db: args.db,
|
|
@@ -14647,8 +14926,12 @@ async function runPostTransformPhase(args) {
|
|
|
14647
14926
|
messages: args.messages,
|
|
14648
14927
|
alreadyFrozen: bindingThinking
|
|
14649
14928
|
});
|
|
14650
|
-
if (stripped.persistenceFailed)
|
|
14929
|
+
if (stripped.persistenceFailed) {
|
|
14930
|
+
thinkingOmissionPersistenceFailed = true;
|
|
14651
14931
|
throw new Error("Cannot persist signed thinking omission before prefix rewrite");
|
|
14932
|
+
}
|
|
14933
|
+
for (const id of stripped.strip?.messageIds ?? [])
|
|
14934
|
+
bindingThinking.add(id);
|
|
14652
14935
|
retainedThinking.clear();
|
|
14653
14936
|
protectedThinkingMessages.clear();
|
|
14654
14937
|
activeThinkingTurn = false;
|
|
@@ -14658,6 +14941,9 @@ async function runPostTransformPhase(args) {
|
|
|
14658
14941
|
rewritingSignedPrefix = true;
|
|
14659
14942
|
thinkingReleasedForFit ||= forFit;
|
|
14660
14943
|
};
|
|
14944
|
+
if (args.compactionModeTransition && args.thinkingBindingRecoveryEnabledForModel) {
|
|
14945
|
+
releaseThinkingForRewrite();
|
|
14946
|
+
}
|
|
14661
14947
|
const foldDueDecision = m0M1EnabledForFold && args.m0M1 && !freezeM0M1 ? mustMaterialize({
|
|
14662
14948
|
db: args.db,
|
|
14663
14949
|
sessionId: args.sessionId,
|
|
@@ -14693,6 +14979,8 @@ async function runPostTransformPhase(args) {
|
|
|
14693
14979
|
};
|
|
14694
14980
|
if ((foldDueDecision.value || softRefreshOpportunity || firstRenderBust && activeThinkingPrefixHold) && m0M1EnabledForFold && args.m0M1) {
|
|
14695
14981
|
let committedFoldBustsServedPrefix;
|
|
14982
|
+
let committedFoldChangesHead = false;
|
|
14983
|
+
let committedFoldThinkingIds = [];
|
|
14696
14984
|
try {
|
|
14697
14985
|
const previousM1 = args.sessionMeta.cachedM1Bytes?.toString("utf8");
|
|
14698
14986
|
const foldResult = injectM0M1({
|
|
@@ -14719,6 +15007,24 @@ async function runPostTransformPhase(args) {
|
|
|
14719
15007
|
m0Text: rendered.m0Bytes.toString(),
|
|
14720
15008
|
m1Text: rendered.m1Bytes.toString()
|
|
14721
15009
|
}) : foldBustsServedPrefix(foldDueDecision.reason, servedPrefixBeforeFold, rendered);
|
|
15010
|
+
committedFoldChangesHead = firstRenderBust ? !servedPrefixMatches({
|
|
15011
|
+
messages: servedBeforeFirstRender,
|
|
15012
|
+
m0Text: rendered.m0Bytes.toString(),
|
|
15013
|
+
m1Text: rendered.m1Bytes.toString()
|
|
15014
|
+
}) : foldChangesServedPrefix(servedPrefixBeforeFold, rendered);
|
|
15015
|
+
if (args.thinkingBindingRecoveryEnabledForModel && (compactionOff && !activeThinkingPrefixHold && committedFoldChangesHead || activeThinkingPrefixHold && firstRenderBust && bustsPrefix)) {
|
|
15016
|
+
const omission = freezeReasoningOnBustingPass({
|
|
15017
|
+
db,
|
|
15018
|
+
sessionId: args.sessionId,
|
|
15019
|
+
messages: args.messages,
|
|
15020
|
+
alreadyFrozen: bindingThinking
|
|
15021
|
+
});
|
|
15022
|
+
if (omission.persistenceFailed) {
|
|
15023
|
+
thinkingOmissionPersistenceFailed = true;
|
|
15024
|
+
throw new Error("Cannot persist signed thinking omission before prefix rewrite");
|
|
15025
|
+
}
|
|
15026
|
+
committedFoldThinkingIds = omission.strip?.messageIds ?? [];
|
|
15027
|
+
}
|
|
14722
15028
|
if (bustsPrefix) {
|
|
14723
15029
|
if (!conversions.isCurrent(db)) {
|
|
14724
15030
|
throw new MaterializeContentionError({
|
|
@@ -14735,7 +15041,13 @@ async function runPostTransformPhase(args) {
|
|
|
14735
15041
|
}
|
|
14736
15042
|
});
|
|
14737
15043
|
preparedPrefix = foldResult;
|
|
14738
|
-
if (
|
|
15044
|
+
if (foldResult.m0RematerializedThisPass) {
|
|
15045
|
+
for (const id of committedFoldThinkingIds)
|
|
15046
|
+
bindingThinking.add(id);
|
|
15047
|
+
}
|
|
15048
|
+
if (foldResult.m0RematerializedThisPass && activeThinkingPrefixHold && firstRenderBust && committedFoldBustsServedPrefix) {
|
|
15049
|
+
releaseThinkingForRewrite();
|
|
15050
|
+
} else if (compactionOff && foldResult.m0RematerializedThisPass && !activeThinkingPrefixHold && args.thinkingBindingRecoveryEnabledForModel && committedFoldChangesHead) {
|
|
14739
15051
|
releaseThinkingForRewrite();
|
|
14740
15052
|
}
|
|
14741
15053
|
prefixPreflightFailed = foldResult.materializationContentionRetryExhausted === true;
|
|
@@ -14764,6 +15076,8 @@ async function runPostTransformPhase(args) {
|
|
|
14764
15076
|
sessionLog(args.sessionId, "channel2 fold-cycle reset failed (ignored):", error);
|
|
14765
15077
|
}
|
|
14766
15078
|
} catch (error) {
|
|
15079
|
+
if (thinkingOmissionPersistenceFailed)
|
|
15080
|
+
throw error;
|
|
14767
15081
|
preparedPrefix = cachedPrefixBeforePreflight;
|
|
14768
15082
|
prefixPreflightFailed = true;
|
|
14769
15083
|
failPass("m0-m1-fold-preexecution-degradation", error);
|
|
@@ -14881,17 +15195,28 @@ async function runPostTransformPhase(args) {
|
|
|
14881
15195
|
throw new EmergencyFailClosedError("Magic Context could not read its saved reasoning-removal state for this session", { cause: error });
|
|
14882
15196
|
}
|
|
14883
15197
|
}
|
|
15198
|
+
const heuristicsLogChanged = diagnosticStateChanged(args.sessionId, "heuristics", JSON.stringify([
|
|
15199
|
+
args.currentTurnId,
|
|
15200
|
+
shouldRunHeuristics,
|
|
15201
|
+
shouldRunHeuristics ? null : args.schedulerDeferReason
|
|
15202
|
+
]));
|
|
15203
|
+
const pendingLogChanged = diagnosticStateChanged(args.sessionId, "pending-ops", JSON.stringify([
|
|
15204
|
+
args.currentTurnId,
|
|
15205
|
+
shouldApplyPendingOps,
|
|
15206
|
+
shouldApplyPendingOps ? null : args.schedulerDeferReason,
|
|
15207
|
+
shouldApplyPendingOps ? null : (getPendingOpsCount(args.db, args.sessionId) ?? 0) > 0
|
|
15208
|
+
]));
|
|
14884
15209
|
if (shouldRunHeuristics) {
|
|
14885
15210
|
const subagentRerun = !args.fullFeatureMode && alreadyRanThisTurn && args.schedulerDecision === "execute" && !isExplicitFlush && !forceMaterialization;
|
|
14886
15211
|
const reason = isExplicitFlush ? `pending_materialization origin=${pendingOrigin}` : deferredMaterialize ? "deferred_materialization" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : foldBustsServedPrefixThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : subagentRerun ? `${reclaimRideLabel(rideSignals)} subagent_rerun (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})` : `${reclaimRideLabel(rideSignals)} (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
|
|
14887
15212
|
sessionLog(args.sessionId, `heuristics WILL RUN — reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=${args.currentTurnId}`);
|
|
14888
|
-
} else if (args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
|
|
15213
|
+
} else if (heuristicsLogChanged && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
|
|
14889
15214
|
sessionLog(args.sessionId, `heuristics WILL NOT RUN — reason=${args.schedulerDeferReason}`);
|
|
14890
15215
|
}
|
|
14891
15216
|
if (alreadyRanThisTurn && args.schedulerDecision === "execute" && !materializationRequested && args.fullFeatureMode) {
|
|
14892
15217
|
sessionLog(args.sessionId, `transform: skipping heuristics (already ran for turn ${args.currentTurnId})`);
|
|
14893
15218
|
}
|
|
14894
|
-
if (!shouldApplyPendingOps && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
|
|
15219
|
+
if (!shouldApplyPendingOps && pendingLogChanged && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
|
|
14895
15220
|
sessionLog(args.sessionId, `pending ops WILL NOT APPLY — reason=${args.schedulerDeferReason} pendingOps=${formatPendingOpsDepth()} context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
14896
15221
|
}
|
|
14897
15222
|
if (hasPendingUserOps && !shouldApplyPendingOps) {
|
|
@@ -15278,6 +15603,30 @@ async function runPostTransformPhase(args) {
|
|
|
15278
15603
|
}
|
|
15279
15604
|
}
|
|
15280
15605
|
const m0M1Enabled = m0M1EnabledForFold;
|
|
15606
|
+
let retainCoveredInstructions = false;
|
|
15607
|
+
if (m0M1Enabled && args.m0M1 && !compactionOff && args.hostInstructionRows) {
|
|
15608
|
+
const covered = args.coveredHostInstructions ?? [];
|
|
15609
|
+
if (covered.length > 0 || canEditWholePrefix) {
|
|
15610
|
+
let retain = false;
|
|
15611
|
+
try {
|
|
15612
|
+
retain = isHostInstructionRetentionOn(args.db, args.sessionId);
|
|
15613
|
+
} catch (error) {
|
|
15614
|
+
failPass("host-instruction-retention-read-failure", error);
|
|
15615
|
+
}
|
|
15616
|
+
if (!retain && canEditWholePrefix) {
|
|
15617
|
+
let written = false;
|
|
15618
|
+
try {
|
|
15619
|
+
written = markHostInstructionRetention(args.db, args.sessionId);
|
|
15620
|
+
} catch (error) {
|
|
15621
|
+
failPass("host-instruction-retention-persistence-failure", error);
|
|
15622
|
+
}
|
|
15623
|
+
if (!written)
|
|
15624
|
+
failPass("host-instruction-retention-persistence-failure");
|
|
15625
|
+
retain = true;
|
|
15626
|
+
}
|
|
15627
|
+
retainCoveredInstructions = retain;
|
|
15628
|
+
}
|
|
15629
|
+
}
|
|
15281
15630
|
if (m0M1Enabled && args.m0M1) {
|
|
15282
15631
|
if (freezeM0M1 && !preparedPrefix) {
|
|
15283
15632
|
preparedPrefix = prepareCachedM0M1Replay(args.db, args.sessionId);
|
|
@@ -15305,6 +15654,17 @@ async function runPostTransformPhase(args) {
|
|
|
15305
15654
|
compactionOff
|
|
15306
15655
|
});
|
|
15307
15656
|
deliveredPrefix = result;
|
|
15657
|
+
if (retainCoveredInstructions) {
|
|
15658
|
+
const retained = new Set(args.messages);
|
|
15659
|
+
const covered = [...args.coveredHostInstructions ?? []];
|
|
15660
|
+
for (const message of messagesBeforeInjection) {
|
|
15661
|
+
if (!retained.has(message) && isHostRenderedSystemMessage(message)) {
|
|
15662
|
+
markCoveredInstructionRow(message.info);
|
|
15663
|
+
covered.push(message);
|
|
15664
|
+
}
|
|
15665
|
+
}
|
|
15666
|
+
args.messages.splice(result.prependedMessageCount, 0, ...covered);
|
|
15667
|
+
}
|
|
15308
15668
|
if (result.prefixTrimStatus === "applied") {
|
|
15309
15669
|
const retainedMessages = new Set(args.messages);
|
|
15310
15670
|
const trimmedMessageIds = messagesBeforeInjection.filter((message) => !retainedMessages.has(message)).map((message) => message.info.id).filter((id) => typeof id === "string");
|
|
@@ -15575,7 +15935,7 @@ async function runPostTransformPhase(args) {
|
|
|
15575
15935
|
}
|
|
15576
15936
|
}
|
|
15577
15937
|
const mergedReasoningStrippedIds = new Set(replaySnapshot?.mergedReasoningStrippedIds ?? []);
|
|
15578
|
-
const thinkingBindingRecoveryMessageIds = new Set;
|
|
15938
|
+
const thinkingBindingRecoveryMessageIds = new Set(bindingThinking);
|
|
15579
15939
|
let thinkingBindingRecovery = null;
|
|
15580
15940
|
let proactiveThinkingStrip = null;
|
|
15581
15941
|
if (!compactionOff) {
|
|
@@ -16080,7 +16440,9 @@ function createTransform(deps) {
|
|
|
16080
16440
|
const loadedSessions = new Set;
|
|
16081
16441
|
const prefixHoldLogTurnIds = new Map;
|
|
16082
16442
|
const thinkingFitRetries = new Set;
|
|
16443
|
+
const compactionModeTransitionPending = new Set;
|
|
16083
16444
|
const clearSessionLogState = (sessionId) => {
|
|
16445
|
+
clearDiagnosticLogState(sessionId);
|
|
16084
16446
|
prefixHoldLogTurnIds.delete(sessionId);
|
|
16085
16447
|
};
|
|
16086
16448
|
const unmanagedOverWindowSessions = new Set;
|
|
@@ -16101,7 +16463,8 @@ function createTransform(deps) {
|
|
|
16101
16463
|
const startTime = performance.now();
|
|
16102
16464
|
const historianRun = deps.resolveHistorianRun?.();
|
|
16103
16465
|
const messages = output.messages;
|
|
16104
|
-
const originalForThinkingFit = messages.some((message) => message.parts.some((part) => isRecord(part) && ["reasoning", "thinking", "redacted_thinking"].includes(String(part.type)))) ?
|
|
16466
|
+
const originalForThinkingFit = messages.some((message) => message.parts.some((part) => isRecord(part) && ["reasoning", "thinking", "redacted_thinking"].includes(String(part.type)))) ? cloneKeepingCoveredInstructionMarks(messages) : null;
|
|
16467
|
+
const coveredHostInstructions = takeCoveredInstructionRows(messages);
|
|
16105
16468
|
const passOutcome = createPassOutcome();
|
|
16106
16469
|
const tSessionId = performance.now();
|
|
16107
16470
|
const sessionId = findSessionId(messages);
|
|
@@ -16199,6 +16562,7 @@ function createTransform(deps) {
|
|
|
16199
16562
|
const hasTransitionEffects = transition.recordToWrite !== null || transition.notice !== null || transition.invalidatedM0Baseline || transition.clearedCompartmentInProgress || transition.historianCatchUpSignaled;
|
|
16200
16563
|
if (hasTransitionEffects) {
|
|
16201
16564
|
if (transition.invalidatedM0Baseline) {
|
|
16565
|
+
compactionModeTransitionPending.add(sessionId);
|
|
16202
16566
|
sessionMeta = {
|
|
16203
16567
|
...sessionMeta,
|
|
16204
16568
|
cachedM0Bytes: null,
|
|
@@ -16627,8 +16991,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16627
16991
|
recordedSessionProjectIdentity.set(sessionId, sessionIdentityForBinding);
|
|
16628
16992
|
}
|
|
16629
16993
|
const taggerFloor = compactionOff ? 0 : deriveTaggerLoadFloor(messages, sessionId, db);
|
|
16630
|
-
|
|
16631
|
-
|
|
16994
|
+
const tagFloorMode = compactionOff || messages.length === 0 ? "inactive" : taggerFloor === 0 ? "fallback" : "scoped";
|
|
16995
|
+
if (diagnosticStateChanged(sessionId, "tag-floor", tagFloorMode) && tagFloorMode !== "inactive") {
|
|
16996
|
+
sessionLog(sessionId, taggerFloor === 0 ? `tag floor: 0 (full-scan fallback) — no scoped floor above the safety margin across ${messages.length} msgs` : `tag floor: ${taggerFloor} (scoped load)`);
|
|
16632
16997
|
}
|
|
16633
16998
|
const ownerRatio = sessionDecisionCalibration(db, sessionId).proseRatio;
|
|
16634
16999
|
prewarmTagOwners(db, sessionId, ownerRatio);
|
|
@@ -16677,7 +17042,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16677
17042
|
const messagesBeforeInitialPrepare = isCacheBusting && deferredHistoryWasPendingAtPassStart ? [...messages] : null;
|
|
16678
17043
|
if (fullFeatureMode && !compactionOff) {
|
|
16679
17044
|
const tInj = performance.now();
|
|
16680
|
-
pendingCompartmentInjection = prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectIdentity, deps.memoryConfig?.injectionBudgetTokens, deps.experimentalTemporalAwareness);
|
|
17045
|
+
pendingCompartmentInjection = prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectIdentity, deps.memoryConfig?.injectionBudgetTokens, deps.experimentalTemporalAwareness, coveredHostInstructions);
|
|
16681
17046
|
if (messagesBeforeInitialPrepare) {
|
|
16682
17047
|
const skippedVisibleMessages = pendingCompartmentInjection?.skippedVisibleMessages ?? 0;
|
|
16683
17048
|
trimmedMessagesAtCompactionBoundary = messagesBeforeInitialPrepare.slice(0, skippedVisibleMessages);
|
|
@@ -16707,6 +17072,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16707
17072
|
logTransformTiming(sessionId, "injectTemporalMarkers", tTemporal);
|
|
16708
17073
|
}
|
|
16709
17074
|
let taggingSucceeded = false;
|
|
17075
|
+
const refreshSourceContents = deps.storeGeneration === "v2" && fullFeatureMode && !compactionOff && !!(projectIdentity || sessionDirectory) && !unresolvedDirectoryHold && !recovery.prefix && sessionMeta.cachedM0Bytes == null && sessionMeta.cachedM1Bytes == null && deps.refreshSourceContents?.(sessionId) === true;
|
|
16710
17076
|
let recoveryBatch = null;
|
|
16711
17077
|
let recoveryNormalized = false;
|
|
16712
17078
|
const normalizeRecoveryTail = recovery.prefix ? () => {
|
|
@@ -16742,7 +17108,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16742
17108
|
scopedToolSweep,
|
|
16743
17109
|
servedMessages: messages,
|
|
16744
17110
|
protectedThinkingMessages: protectedThinkingMessagesForPass,
|
|
16745
|
-
normalizeRestoredAssistantText: deps.normalizeRestoredAssistantText
|
|
17111
|
+
normalizeRestoredAssistantText: deps.normalizeRestoredAssistantText,
|
|
17112
|
+
refreshSourceContents
|
|
16746
17113
|
});
|
|
16747
17114
|
targets = result.targets;
|
|
16748
17115
|
if (thinkingRecovery.restore)
|
|
@@ -16823,6 +17190,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16823
17190
|
const rawGetNotifParams = runNotificationParams;
|
|
16824
17191
|
const tCompartmentPhase = performance.now();
|
|
16825
17192
|
const compartmentPhase = await runCompartmentPhase({
|
|
17193
|
+
coveredHostInstructions,
|
|
16826
17194
|
hiddenCompletionExecutor: deps.hiddenCompletionExecutor,
|
|
16827
17195
|
compactionMarkerStrategy: deps.compactionMarkerStrategy,
|
|
16828
17196
|
canRunCompartments,
|
|
@@ -16989,6 +17357,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16989
17357
|
fullFeatureMode,
|
|
16990
17358
|
compactionOff,
|
|
16991
17359
|
canRunCompartments,
|
|
17360
|
+
hostInstructionRows: deps.storeGeneration === "v2",
|
|
16992
17361
|
awaitedCompartmentRun,
|
|
16993
17362
|
phaseJustAwaitedPublication: compartmentPhase.justAwaitedPublication,
|
|
16994
17363
|
compartmentInProgress,
|
|
@@ -16997,6 +17366,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16997
17366
|
activeThinkingPrefixHold,
|
|
16998
17367
|
directoryPrefixHold: unresolvedDirectoryHold,
|
|
16999
17368
|
forceSignedRebuildForFit: thinkingFitRetries.has(sessionId) || !!recovery.rebuildReason,
|
|
17369
|
+
compactionModeTransition: compactionModeTransitionPending.has(sessionId),
|
|
17000
17370
|
readLastServedMessages: () => {
|
|
17001
17371
|
const slot = getInMemorySlot(sessionId) ?? loadPersistedLkgSlot(db, sessionId);
|
|
17002
17372
|
try {
|
|
@@ -17026,6 +17396,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17026
17396
|
emergencyCeilingTokens,
|
|
17027
17397
|
pendingCompartmentInjection,
|
|
17028
17398
|
prefixTrimSourceOrder,
|
|
17399
|
+
coveredHostInstructions,
|
|
17029
17400
|
hiddenMessagesAtCompactionSeam,
|
|
17030
17401
|
trimmedMessagesAtCompactionBoundary,
|
|
17031
17402
|
didMutateFromFlushedStatuses,
|
|
@@ -17220,7 +17591,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17220
17591
|
if (!finalWireEstimate) {
|
|
17221
17592
|
sessionLog(sessionId, `transform: final-wire telemetry estimate=unavailable trusted=false conversation=unknown tools=unknown system=unknown toolDefinitions=unknown tail=${finalWireTail}`);
|
|
17222
17593
|
}
|
|
17223
|
-
|
|
17594
|
+
const signedThinkingServed = isPrefixBoundThinkingModel(modelForBudget?.providerID, modelForBudget?.modelID) && servesThinkingBlock(messages);
|
|
17595
|
+
finishSystemDateRefresh(deps.historyRefreshSessions, dateRequest, postTransformResult.bustedThisPass && !activeThinkingPrefixHold && !signedThinkingServed || postTransformResult.thinkingReleasedForFit === true, signedThinkingServed);
|
|
17596
|
+
compactionModeTransitionPending.delete(sessionId);
|
|
17224
17597
|
if (activeThinkingPrefixHold && !postTransformResult.thinkingReleasedForFit && sessionMeta.cachedM0Bytes != null && sessionMeta.cachedM1Bytes != null) {
|
|
17225
17598
|
recordHeldHeadForRequest(sessionId, currentLkgRequestIdentity(sessionId), (ownsHistory) => deferDeliveredSystemRefresh(deps, sessionId, ownsHistory));
|
|
17226
17599
|
}
|
|
@@ -17322,6 +17695,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17322
17695
|
if (uncachedMessageIds.length > 0) {
|
|
17323
17696
|
try {
|
|
17324
17697
|
storedByMessage = getActiveTagTokenTotalsByMessage(db, sessionId, uncachedMessageIds);
|
|
17698
|
+
omitIncompleteFileTokenTotals(db, sessionId, messages.flatMap((message) => typeof message.info.id === "string" ? [{ id: message.info.id, parts: message.parts }] : []), storedByMessage);
|
|
17325
17699
|
} catch {
|
|
17326
17700
|
storedByMessage = new Map;
|
|
17327
17701
|
}
|
|
@@ -17378,7 +17752,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17378
17752
|
postReduceGraceBaselineU: channel1State.postReduceGraceBaselineU,
|
|
17379
17753
|
postReduceGracePreLevel: channel1State.postReduceGracePreLevel
|
|
17380
17754
|
});
|
|
17381
|
-
|
|
17755
|
+
logNudgeEvaluation(sessionId, "transform", formatChannel1Evaluation(channel1Decision));
|
|
17382
17756
|
const channel2Evaluation = evaluateChannel2(channelBaseline);
|
|
17383
17757
|
const leaseBefore = getChannel2NudgeState(db, sessionId);
|
|
17384
17758
|
if (channelBaseline.evaluable && !channelBaseline.generationInvalidated && !channelBaseline.reducedSinceRefresh) {
|
|
@@ -17389,7 +17763,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17389
17763
|
}
|
|
17390
17764
|
}
|
|
17391
17765
|
const leaseAfter = getChannel2NudgeState(db, sessionId);
|
|
17392
|
-
|
|
17766
|
+
logNudgeEvaluation(sessionId, "transform", formatChannel2Evaluation(channel2Evaluation, {
|
|
17393
17767
|
leaseBefore,
|
|
17394
17768
|
leaseAfter,
|
|
17395
17769
|
gateHoldReason: channelBaseline.reducedSinceRefresh ? "recent-reduce-refresh" : undefined
|
|
@@ -17428,7 +17802,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
17428
17802
|
sessionLog(sessionId, "memory maintenance launch probe failed (ignored):", error);
|
|
17429
17803
|
}
|
|
17430
17804
|
};
|
|
17431
|
-
|
|
17805
|
+
const timedTransform = (input, output) => withTransformTimingSummary(() => transform(input, output));
|
|
17806
|
+
return Object.assign(timedTransform, {
|
|
17432
17807
|
clearSessionLogState(sessionId) {
|
|
17433
17808
|
clearSessionLogState(sessionId);
|
|
17434
17809
|
}
|
|
@@ -18702,8 +19077,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
18702
19077
|
const db = readDatabase();
|
|
18703
19078
|
if (!db)
|
|
18704
19079
|
return { ok: false, error: "db unavailable" };
|
|
18705
|
-
const { runManagedRecomp } = await import("./recomp-orchestrator-
|
|
18706
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
19080
|
+
const { runManagedRecomp } = await import("./recomp-orchestrator-mmpy5cb7.js");
|
|
19081
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-zpqs213d.js");
|
|
18707
19082
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
18708
19083
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
18709
19084
|
return {
|
|
@@ -18752,7 +19127,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
18752
19127
|
const db = readDatabase();
|
|
18753
19128
|
if (!db)
|
|
18754
19129
|
return { ok: false, error: "db unavailable" };
|
|
18755
|
-
const { runManagedWrapup } = await import("./wrapup-orchestrator-
|
|
19130
|
+
const { runManagedWrapup } = await import("./wrapup-orchestrator-jq589pgr.js");
|
|
18756
19131
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
18757
19132
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
18758
19133
|
const ctx = {
|
|
@@ -18840,8 +19215,17 @@ function subagentToolRefusal(db, toolId, sessionId, isInternalChild = () => fals
|
|
|
18840
19215
|
function hideSubagentTools(draft, db) {
|
|
18841
19216
|
if (!getOrCreateSessionMeta(db, draft.sessionID).isSubagent)
|
|
18842
19217
|
return;
|
|
19218
|
+
removePrimaryOnlyTools(draft.tools);
|
|
19219
|
+
}
|
|
19220
|
+
function removePrimaryOnlyTools(tools) {
|
|
18843
19221
|
for (const id of PRIMARY_ONLY_TOOLS)
|
|
18844
|
-
delete
|
|
19222
|
+
delete tools[id];
|
|
19223
|
+
}
|
|
19224
|
+
function storedSubagentMode(db, sessionId) {
|
|
19225
|
+
const row = db.prepare("SELECT is_subagent FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
19226
|
+
if (!row || typeof row.is_subagent !== "number")
|
|
19227
|
+
return;
|
|
19228
|
+
return row.is_subagent === 1;
|
|
18845
19229
|
}
|
|
18846
19230
|
|
|
18847
19231
|
// src/shared/conflict-detector.ts
|
|
@@ -19099,7 +19483,58 @@ function readOmoDisabledHooks(directory) {
|
|
|
19099
19483
|
|
|
19100
19484
|
// src/shared/rpc-server.ts
|
|
19101
19485
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
19102
|
-
import { readdirSync, readFileSync as readFileSync6, unlinkSync } from "node:fs";
|
|
19486
|
+
import { readdirSync, readFileSync as readFileSync6, rmdirSync, unlinkSync } from "node:fs";
|
|
19487
|
+
|
|
19488
|
+
// src/shared/rpc-discovery-cleanup.ts
|
|
19489
|
+
import { promises as fs } from "node:fs";
|
|
19490
|
+
import { join as join4 } from "node:path";
|
|
19491
|
+
async function reapDeadRpcDiscovery(storageDir) {
|
|
19492
|
+
const root = join4(storageDir, "rpc");
|
|
19493
|
+
let directories;
|
|
19494
|
+
try {
|
|
19495
|
+
directories = await fs.readdir(root, { withFileTypes: true });
|
|
19496
|
+
} catch {
|
|
19497
|
+
return;
|
|
19498
|
+
}
|
|
19499
|
+
const records = [];
|
|
19500
|
+
const projectDirs = [];
|
|
19501
|
+
for (const entry of directories) {
|
|
19502
|
+
if (!entry.isDirectory() || !/^[0-9a-f]{16}$/.test(entry.name))
|
|
19503
|
+
continue;
|
|
19504
|
+
const directory = join4(root, entry.name);
|
|
19505
|
+
projectDirs.push(directory);
|
|
19506
|
+
try {
|
|
19507
|
+
for (const name of await fs.readdir(directory)) {
|
|
19508
|
+
const match = /^port-(\d+)(?:-[0-9a-f]+)?\.json$/.exec(name);
|
|
19509
|
+
if (!match)
|
|
19510
|
+
continue;
|
|
19511
|
+
const path = join4(directory, name);
|
|
19512
|
+
try {
|
|
19513
|
+
const content = await fs.readFile(path, "utf8");
|
|
19514
|
+
const record = parseRpcPortFile(content, Number(match[1]));
|
|
19515
|
+
if (record && record.pid === Number(match[1]))
|
|
19516
|
+
records.push({ path, content, pid: record.pid });
|
|
19517
|
+
} catch {}
|
|
19518
|
+
}
|
|
19519
|
+
} catch {}
|
|
19520
|
+
}
|
|
19521
|
+
const processes = records.length ? await inspectProcessesAsync(true) : undefined;
|
|
19522
|
+
for (const record of records) {
|
|
19523
|
+
if (processes?.liveness(record.pid) !== "dead")
|
|
19524
|
+
continue;
|
|
19525
|
+
try {
|
|
19526
|
+
if (await fs.readFile(record.path, "utf8") === record.content)
|
|
19527
|
+
await fs.unlink(record.path);
|
|
19528
|
+
} catch {}
|
|
19529
|
+
}
|
|
19530
|
+
for (const directory of projectDirs) {
|
|
19531
|
+
try {
|
|
19532
|
+
await fs.rmdir(directory);
|
|
19533
|
+
} catch {}
|
|
19534
|
+
}
|
|
19535
|
+
}
|
|
19536
|
+
|
|
19537
|
+
// src/shared/rpc-server.ts
|
|
19103
19538
|
var MAX_BODY_BYTES = 1048576;
|
|
19104
19539
|
var WS_AUTH_TIMEOUT_MS = 5000;
|
|
19105
19540
|
var WS_CLOSE_UNAUTHORIZED = 4401;
|
|
@@ -19122,17 +19557,20 @@ function websocketToken(req) {
|
|
|
19122
19557
|
}
|
|
19123
19558
|
|
|
19124
19559
|
class MagicContextRpcServer {
|
|
19560
|
+
storageDir;
|
|
19125
19561
|
server = null;
|
|
19126
19562
|
port = 0;
|
|
19127
19563
|
handlers = new Map;
|
|
19128
19564
|
portFilePath;
|
|
19129
19565
|
portDir;
|
|
19130
19566
|
startedAt = Date.now();
|
|
19567
|
+
stopped = false;
|
|
19131
19568
|
instanceId = randomBytes(8).toString("hex");
|
|
19132
19569
|
unregisterOwnInstance = null;
|
|
19133
19570
|
sockets = new Set;
|
|
19134
19571
|
token = randomBytes(32).toString("hex");
|
|
19135
19572
|
constructor(storageDir, directory) {
|
|
19573
|
+
this.storageDir = storageDir;
|
|
19136
19574
|
this.portFilePath = rpcPortFilePath(storageDir, directory, process.pid, this.instanceId);
|
|
19137
19575
|
this.portDir = rpcPortDir(storageDir, directory);
|
|
19138
19576
|
}
|
|
@@ -19150,6 +19588,10 @@ class MagicContextRpcServer {
|
|
|
19150
19588
|
log("rpc server skipped: Bun runtime not available (no TUI consumer)");
|
|
19151
19589
|
return 0;
|
|
19152
19590
|
}
|
|
19591
|
+
this.stopped = false;
|
|
19592
|
+
await reapDeadRpcDiscovery(this.storageDir);
|
|
19593
|
+
if (this.stopped)
|
|
19594
|
+
return 0;
|
|
19153
19595
|
this.startedAt = Date.now();
|
|
19154
19596
|
const self = this;
|
|
19155
19597
|
const server = Bun.serve({
|
|
@@ -19181,7 +19623,7 @@ class MagicContextRpcServer {
|
|
|
19181
19623
|
try {
|
|
19182
19624
|
this.warnIfOtherLiveInstance();
|
|
19183
19625
|
this.unregisterOwnInstance ??= registerOwnRpcServerInstance(this.instanceId);
|
|
19184
|
-
writeStorageFileAtomicSync(this.portFilePath, JSON.stringify({
|
|
19626
|
+
const publish = () => writeStorageFileAtomicSync(this.portFilePath, JSON.stringify({
|
|
19185
19627
|
port: this.port,
|
|
19186
19628
|
pid: process.pid,
|
|
19187
19629
|
started_at: this.startedAt,
|
|
@@ -19189,6 +19631,13 @@ class MagicContextRpcServer {
|
|
|
19189
19631
|
token: this.token,
|
|
19190
19632
|
instance_id: this.instanceId
|
|
19191
19633
|
}));
|
|
19634
|
+
try {
|
|
19635
|
+
publish();
|
|
19636
|
+
} catch (error) {
|
|
19637
|
+
if (error.code !== "ENOENT")
|
|
19638
|
+
throw error;
|
|
19639
|
+
publish();
|
|
19640
|
+
}
|
|
19192
19641
|
log(`[rpc] server listening on 127.0.0.1:${this.port}`);
|
|
19193
19642
|
} catch (err) {
|
|
19194
19643
|
log(`[rpc] failed to write port file: ${err}`);
|
|
@@ -19196,6 +19645,7 @@ class MagicContextRpcServer {
|
|
|
19196
19645
|
return this.port;
|
|
19197
19646
|
}
|
|
19198
19647
|
stop() {
|
|
19648
|
+
this.stopped = true;
|
|
19199
19649
|
for (const ws of this.sockets) {
|
|
19200
19650
|
try {
|
|
19201
19651
|
if (ws.data.authTimer)
|
|
@@ -19212,6 +19662,9 @@ class MagicContextRpcServer {
|
|
|
19212
19662
|
try {
|
|
19213
19663
|
unlinkSync(this.portFilePath);
|
|
19214
19664
|
} catch {}
|
|
19665
|
+
try {
|
|
19666
|
+
rmdirSync(this.portDir);
|
|
19667
|
+
} catch {}
|
|
19215
19668
|
this.unregisterOwnInstance?.();
|
|
19216
19669
|
this.unregisterOwnInstance = null;
|
|
19217
19670
|
}
|
|
@@ -19945,18 +20398,56 @@ function containsHostInstance(value) {
|
|
|
19945
20398
|
return false;
|
|
19946
20399
|
}
|
|
19947
20400
|
function clonePreservingInstances(value) {
|
|
19948
|
-
|
|
20401
|
+
return cloneCounting(value, undefined);
|
|
20402
|
+
}
|
|
20403
|
+
function clonePreservingInstancesMeasured(value) {
|
|
20404
|
+
const meter = { bytes: 0 };
|
|
20405
|
+
const copy = cloneCounting(value, meter);
|
|
20406
|
+
return { copy, bytes: meter.bytes };
|
|
20407
|
+
}
|
|
20408
|
+
function cloneCounting(value, meter) {
|
|
20409
|
+
if (isHostInstance(value)) {
|
|
20410
|
+
if (meter)
|
|
20411
|
+
meter.bytes += instanceBytes(value, new WeakSet);
|
|
19949
20412
|
return value;
|
|
19950
|
-
|
|
19951
|
-
|
|
20413
|
+
}
|
|
20414
|
+
if (Array.isArray(value)) {
|
|
20415
|
+
if (meter)
|
|
20416
|
+
meter.bytes += 16 + 8 * value.length;
|
|
20417
|
+
return value.map((entry) => cloneCounting(entry, meter));
|
|
20418
|
+
}
|
|
19952
20419
|
if (value && typeof value === "object") {
|
|
19953
20420
|
const copy = {};
|
|
19954
|
-
|
|
19955
|
-
|
|
20421
|
+
if (meter)
|
|
20422
|
+
meter.bytes += 32;
|
|
20423
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
20424
|
+
if (meter)
|
|
20425
|
+
meter.bytes += 16;
|
|
20426
|
+
copy[key] = cloneCounting(entry, meter);
|
|
20427
|
+
}
|
|
19956
20428
|
return copy;
|
|
19957
20429
|
}
|
|
20430
|
+
if (meter)
|
|
20431
|
+
meter.bytes += typeof value === "string" ? 2 * value.length : 8;
|
|
19958
20432
|
return value;
|
|
19959
20433
|
}
|
|
20434
|
+
function instanceBytes(value, seen) {
|
|
20435
|
+
if (typeof value === "string")
|
|
20436
|
+
return 2 * value.length;
|
|
20437
|
+
if (!value || typeof value !== "object")
|
|
20438
|
+
return 8;
|
|
20439
|
+
if (seen.has(value))
|
|
20440
|
+
return 0;
|
|
20441
|
+
seen.add(value);
|
|
20442
|
+
if (ArrayBuffer.isView(value))
|
|
20443
|
+
return value.byteLength;
|
|
20444
|
+
if (value instanceof ArrayBuffer)
|
|
20445
|
+
return value.byteLength;
|
|
20446
|
+
let bytes = 32;
|
|
20447
|
+
for (const entry of Object.values(value))
|
|
20448
|
+
bytes += 16 + instanceBytes(entry, seen);
|
|
20449
|
+
return bytes;
|
|
20450
|
+
}
|
|
19960
20451
|
function contentKey(value) {
|
|
19961
20452
|
const plain = (entry) => {
|
|
19962
20453
|
if (ArrayBuffer.isView(entry)) {
|
|
@@ -20012,7 +20503,7 @@ function rebuildFileContent(value, output, attachments) {
|
|
|
20012
20503
|
rebuilt.unshift({ type: "text", text: output });
|
|
20013
20504
|
return { type: "content", value: rebuilt };
|
|
20014
20505
|
}
|
|
20015
|
-
function adaptPayload(draft, admittedIDs = new Set) {
|
|
20506
|
+
function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map, hiddenTimes = false) {
|
|
20016
20507
|
const existingHeads = new Map(draft.messages.filter((m) => HEAD_IDS.some((id) => m.id === id)).map((m) => [m.id, m]));
|
|
20017
20508
|
const source = draft.messages.filter((m) => !existingHeads.has(m.id));
|
|
20018
20509
|
const results = new Map;
|
|
@@ -20122,6 +20613,7 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
20122
20613
|
id: message.id,
|
|
20123
20614
|
sessionID: draft.sessionID,
|
|
20124
20615
|
role: message.role,
|
|
20616
|
+
time: message.id ? messageTimes.get(message.id) : undefined,
|
|
20125
20617
|
...{
|
|
20126
20618
|
providerID: draft.model.providerID,
|
|
20127
20619
|
modelID: draft.model.id,
|
|
@@ -20130,7 +20622,19 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
20130
20622
|
},
|
|
20131
20623
|
parts
|
|
20132
20624
|
};
|
|
20625
|
+
if (hiddenTimes && mapped.info.time !== undefined) {
|
|
20626
|
+
const time = mapped.info.time;
|
|
20627
|
+
delete mapped.info.time;
|
|
20628
|
+
Object.defineProperty(mapped.info, "time", {
|
|
20629
|
+
value: time,
|
|
20630
|
+
enumerable: false,
|
|
20631
|
+
configurable: true,
|
|
20632
|
+
writable: true
|
|
20633
|
+
});
|
|
20634
|
+
}
|
|
20133
20635
|
originals.set(mapped, message);
|
|
20636
|
+
if (isCoveredInstructionRow(message))
|
|
20637
|
+
markCoveredInstructionRow(mapped.info);
|
|
20134
20638
|
if (typeof message.id !== "string")
|
|
20135
20639
|
bridgesByCarrier.set(mapped, byCallID);
|
|
20136
20640
|
messages.push(mapped);
|
|
@@ -20487,24 +20991,31 @@ ${data.output?.output ?? ""}`
|
|
|
20487
20991
|
const sameModel = sameProvider && previousModel?.id === model.id;
|
|
20488
20992
|
const reuse = sameModel && data.error === undefined;
|
|
20489
20993
|
const metadata = (state) => state === undefined ? undefined : { [model.providerID]: state };
|
|
20994
|
+
const reasoningInterrupted = data.content?.some((part) => part.type === "reasoning" && part.time !== undefined && part.time.completed === undefined);
|
|
20490
20995
|
const content = [];
|
|
20491
20996
|
const results = [];
|
|
20492
20997
|
for (const part of data.content ?? []) {
|
|
20998
|
+
let native = "native" in part ? part.native : part.type === "tool" ? part.providerState : part.state;
|
|
20999
|
+
if (part.type === "tool" && part.providerResultState !== null && typeof part.providerResultState === "object" && !Array.isArray(part.providerResultState))
|
|
21000
|
+
native = {
|
|
21001
|
+
...native !== null && typeof native === "object" && !Array.isArray(native) ? native : {},
|
|
21002
|
+
...part.providerResultState
|
|
21003
|
+
};
|
|
20493
21004
|
if (part.type === "text") {
|
|
20494
21005
|
if (part.text !== "")
|
|
20495
21006
|
content.push({
|
|
20496
21007
|
type: "text",
|
|
20497
21008
|
text: part.text,
|
|
20498
|
-
providerMetadata: reuse ? metadata(
|
|
21009
|
+
providerMetadata: reuse ? metadata(native) : undefined
|
|
20499
21010
|
});
|
|
20500
21011
|
continue;
|
|
20501
21012
|
}
|
|
20502
21013
|
if (part.type === "reasoning") {
|
|
20503
|
-
if (part.text !== "" || reuse &&
|
|
21014
|
+
if (part.text !== "" || reuse && !reasoningInterrupted && native !== undefined)
|
|
20504
21015
|
content.push({
|
|
20505
|
-
type:
|
|
21016
|
+
type: data.error === undefined && !reasoningInterrupted ? "reasoning" : "text",
|
|
20506
21017
|
text: part.text,
|
|
20507
|
-
providerMetadata: reuse ? metadata(
|
|
21018
|
+
providerMetadata: reuse && !reasoningInterrupted ? metadata(native) : undefined
|
|
20508
21019
|
});
|
|
20509
21020
|
continue;
|
|
20510
21021
|
}
|
|
@@ -20523,7 +21034,7 @@ ${data.output?.output ?? ""}`
|
|
|
20523
21034
|
name: part.name,
|
|
20524
21035
|
input,
|
|
20525
21036
|
providerExecuted: part.executed,
|
|
20526
|
-
providerMetadata: toolReuse ? metadata(
|
|
21037
|
+
providerMetadata: toolReuse ? metadata(native) : undefined
|
|
20527
21038
|
});
|
|
20528
21039
|
if (!completed)
|
|
20529
21040
|
continue;
|
|
@@ -20534,7 +21045,7 @@ ${data.output?.output ?? ""}`
|
|
|
20534
21045
|
id: part.id,
|
|
20535
21046
|
name: part.name,
|
|
20536
21047
|
providerExecuted: part.executed,
|
|
20537
|
-
providerMetadata:
|
|
21048
|
+
providerMetadata: (part.executed === true ? sameProvider : reuse) ? metadata(native) : undefined,
|
|
20538
21049
|
result: state.status === "error" ? { error: state.error, content: toolContent } : single?.type === "text" ? { type: "text", value: single.text } : { type: "content", value: toolContent },
|
|
20539
21050
|
...state.status === "error" ? { resultType: "error" } : {}
|
|
20540
21051
|
};
|
|
@@ -20562,13 +21073,50 @@ function copyNativeInput(messages) {
|
|
|
20562
21073
|
return copies;
|
|
20563
21074
|
}
|
|
20564
21075
|
function isLocalCheckpoint(row) {
|
|
20565
|
-
return row.type === "compaction" && row.data.status === "completed" && row.data.providerContext === undefined;
|
|
21076
|
+
return row.type === "compaction" && row.data.status === "completed" && row.data.providerContext === undefined && row.data.native?.messages === undefined;
|
|
21077
|
+
}
|
|
21078
|
+
function isAdmittedLocalCheckpoint(storage, sessionID, cut) {
|
|
21079
|
+
if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
|
|
21080
|
+
return false;
|
|
21081
|
+
const admission = storage.admission(sessionID, cut.id);
|
|
21082
|
+
if (!admission?.payload || admission.digest !== foldDigest(admission.payload))
|
|
21083
|
+
return false;
|
|
21084
|
+
try {
|
|
21085
|
+
const snapshot = JSON.parse(admission.payload);
|
|
21086
|
+
return snapshot.source === storage.sourceID && snapshot.sessionID === sessionID && snapshot.admissionID === cut.id && snapshot.summary === cut.data.summary;
|
|
21087
|
+
} catch {
|
|
21088
|
+
return false;
|
|
21089
|
+
}
|
|
20566
21090
|
}
|
|
20567
21091
|
var conversational = (row) => RAW_MESSAGE_TYPES.includes(row.type) || row.type === "location-switched";
|
|
21092
|
+
var historyDigest = (reader, sessionID, through) => foldDigest(JSON.stringify(reader.range(sessionID, -1, through).filter(conversational)));
|
|
21093
|
+
var admissionKey = (sessionID) => `native-fold/v2/${encodeURIComponent(sessionID)}`;
|
|
21094
|
+
async function forgetNativeFoldProvenance(storage, sessionID, legacyOnly = false) {
|
|
21095
|
+
const remove = async (key) => {
|
|
21096
|
+
if (storage.remove)
|
|
21097
|
+
await storage.remove(key);
|
|
21098
|
+
else
|
|
21099
|
+
await storage.set(key, null);
|
|
21100
|
+
};
|
|
21101
|
+
if (!legacyOnly)
|
|
21102
|
+
await remove(admissionKey(sessionID));
|
|
21103
|
+
if (!storage.scan)
|
|
21104
|
+
return;
|
|
21105
|
+
let after;
|
|
21106
|
+
do {
|
|
21107
|
+
const page = await storage.scan({ prefix: "native-fold/v1/", after, limit: 100 });
|
|
21108
|
+
for (const { key } of page.entries) {
|
|
21109
|
+
if (key.slice("native-fold/v1/".length).split("/").slice(1).join("/") === sessionID)
|
|
21110
|
+
await remove(key);
|
|
21111
|
+
}
|
|
21112
|
+
after = page.next;
|
|
21113
|
+
} while (after);
|
|
21114
|
+
}
|
|
20568
21115
|
|
|
20569
21116
|
class NativeFoldReplay {
|
|
20570
21117
|
storage;
|
|
20571
21118
|
openReader;
|
|
21119
|
+
admissions;
|
|
20572
21120
|
changed = new Set;
|
|
20573
21121
|
dirty = new Set;
|
|
20574
21122
|
unavailable = new Set;
|
|
@@ -20576,9 +21124,11 @@ class NativeFoldReplay {
|
|
|
20576
21124
|
metadataThrough = new Map;
|
|
20577
21125
|
loaded = new Map;
|
|
20578
21126
|
sources = new Map;
|
|
20579
|
-
|
|
21127
|
+
staleHeads = new Set;
|
|
21128
|
+
constructor(storage, openReader, admissions) {
|
|
20580
21129
|
this.storage = storage;
|
|
20581
21130
|
this.openReader = openReader;
|
|
21131
|
+
this.admissions = admissions;
|
|
20582
21132
|
storage.onEvict((sessionID) => this.clear(sessionID));
|
|
20583
21133
|
}
|
|
20584
21134
|
account(sessionID) {
|
|
@@ -20617,6 +21167,51 @@ class NativeFoldReplay {
|
|
|
20617
21167
|
async baseline(sessionID) {
|
|
20618
21168
|
return this.tail(sessionID)?.baseline;
|
|
20619
21169
|
}
|
|
21170
|
+
admissionKey(sessionID) {
|
|
21171
|
+
return admissionKey(sessionID);
|
|
21172
|
+
}
|
|
21173
|
+
async removeAdmission(key) {
|
|
21174
|
+
if (this.admissions?.remove)
|
|
21175
|
+
await this.admissions.remove(key);
|
|
21176
|
+
else
|
|
21177
|
+
await this.admissions?.set(key, null);
|
|
21178
|
+
}
|
|
21179
|
+
async removeLegacyAdmissions(sessionID) {
|
|
21180
|
+
if (this.admissions)
|
|
21181
|
+
await forgetNativeFoldProvenance(this.admissions, sessionID, true);
|
|
21182
|
+
}
|
|
21183
|
+
async admits(sessionID, cut, reader) {
|
|
21184
|
+
if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
|
|
21185
|
+
return false;
|
|
21186
|
+
if (isAdmittedLocalCheckpoint(this.storage, sessionID, cut))
|
|
21187
|
+
return true;
|
|
21188
|
+
if (!this.admissions)
|
|
21189
|
+
return false;
|
|
21190
|
+
try {
|
|
21191
|
+
const source = reader.hostIdentity();
|
|
21192
|
+
const saved = await this.admissions.get(this.admissionKey(sessionID));
|
|
21193
|
+
if (!saved?.payload || saved.digest !== foldDigest(saved.payload))
|
|
21194
|
+
return false;
|
|
21195
|
+
const snapshot = JSON.parse(saved.payload);
|
|
21196
|
+
if (snapshot.sourceDigest !== foldDigest(source) || snapshot.sessionID !== sessionID || snapshot.admissionID !== cut.id || snapshot.summaryDigest !== foldDigest(cut.data.summary ?? ""))
|
|
21197
|
+
return false;
|
|
21198
|
+
if (snapshot.historyDigest !== historyDigest(reader, sessionID, cut.seq - 1)) {
|
|
21199
|
+
this.staleHeads.add(sessionID);
|
|
21200
|
+
this.invalidate(sessionID);
|
|
21201
|
+
await this.removeAdmission(this.admissionKey(sessionID));
|
|
21202
|
+
return false;
|
|
21203
|
+
}
|
|
21204
|
+
await this.storage.supply(sessionID, cut.id, JSON.stringify({
|
|
21205
|
+
source: this.storage.sourceID,
|
|
21206
|
+
sessionID,
|
|
21207
|
+
admissionID: cut.id,
|
|
21208
|
+
summary: cut.data.summary
|
|
21209
|
+
}));
|
|
21210
|
+
return true;
|
|
21211
|
+
} catch {
|
|
21212
|
+
return false;
|
|
21213
|
+
}
|
|
21214
|
+
}
|
|
20620
21215
|
rendered(row, model) {
|
|
20621
21216
|
return restoreRow(row, model, hostUsesMediaAssets() ? {
|
|
20622
21217
|
asset: hostMediaAsset,
|
|
@@ -20694,6 +21289,7 @@ class NativeFoldReplay {
|
|
|
20694
21289
|
this.loaded.set(draft.sessionID, through);
|
|
20695
21290
|
this.unavailable.delete(draft.sessionID);
|
|
20696
21291
|
this.changed.delete(draft.sessionID);
|
|
21292
|
+
this.staleHeads.delete(draft.sessionID);
|
|
20697
21293
|
} finally {
|
|
20698
21294
|
reader.close();
|
|
20699
21295
|
}
|
|
@@ -20720,7 +21316,8 @@ class NativeFoldReplay {
|
|
|
20720
21316
|
async supplyHeld(args) {
|
|
20721
21317
|
const { draft, reader, summary } = args;
|
|
20722
21318
|
const tail = this.tail(draft.sessionID);
|
|
20723
|
-
const
|
|
21319
|
+
const running = reader.latestRunningCompaction(draft.sessionID);
|
|
21320
|
+
const id = running?.id;
|
|
20724
21321
|
if (!id || !tail || tail.model !== `${draft.model.providerID}/${draft.model.id}`)
|
|
20725
21322
|
return false;
|
|
20726
21323
|
const through = reader.latestSequence(draft.sessionID);
|
|
@@ -20744,6 +21341,21 @@ class NativeFoldReplay {
|
|
|
20744
21341
|
summary
|
|
20745
21342
|
};
|
|
20746
21343
|
await this.storage.supply(draft.sessionID, id, JSON.stringify(snapshot));
|
|
21344
|
+
if (this.admissions) {
|
|
21345
|
+
const provenance = {
|
|
21346
|
+
sourceDigest: foldDigest(reader.hostIdentity()),
|
|
21347
|
+
sessionID: draft.sessionID,
|
|
21348
|
+
admissionID: id,
|
|
21349
|
+
summaryDigest: foldDigest(summary),
|
|
21350
|
+
historyDigest: historyDigest(reader, draft.sessionID, (running?.seq ?? through) - 1)
|
|
21351
|
+
};
|
|
21352
|
+
const payload = JSON.stringify(provenance);
|
|
21353
|
+
await this.admissions.set(this.admissionKey(draft.sessionID), {
|
|
21354
|
+
payload,
|
|
21355
|
+
digest: foldDigest(payload)
|
|
21356
|
+
});
|
|
21357
|
+
await this.removeLegacyAdmissions(draft.sessionID);
|
|
21358
|
+
}
|
|
20747
21359
|
return true;
|
|
20748
21360
|
}
|
|
20749
21361
|
async restore(sessionID, cut, model, options = {}) {
|
|
@@ -20828,6 +21440,9 @@ class NativeFoldReplay {
|
|
|
20828
21440
|
sourceChanged(sessionID) {
|
|
20829
21441
|
return this.changed.has(sessionID);
|
|
20830
21442
|
}
|
|
21443
|
+
needsHeadRebuild(sessionID) {
|
|
21444
|
+
return this.staleHeads.has(sessionID);
|
|
21445
|
+
}
|
|
20831
21446
|
clear(sessionID) {
|
|
20832
21447
|
this.sources.delete(sessionID);
|
|
20833
21448
|
this.metadata.delete(sessionID);
|
|
@@ -20836,8 +21451,11 @@ class NativeFoldReplay {
|
|
|
20836
21451
|
this.unavailable.delete(sessionID);
|
|
20837
21452
|
this.dirty.delete(sessionID);
|
|
20838
21453
|
this.changed.delete(sessionID);
|
|
21454
|
+
this.staleHeads.delete(sessionID);
|
|
20839
21455
|
}
|
|
20840
21456
|
async forget(sessionID) {
|
|
21457
|
+
if (this.admissions)
|
|
21458
|
+
await forgetNativeFoldProvenance(this.admissions, sessionID);
|
|
20841
21459
|
await this.storage.forget(sessionID);
|
|
20842
21460
|
}
|
|
20843
21461
|
}
|
|
@@ -20852,11 +21470,7 @@ class HostFoldPolicy {
|
|
|
20852
21470
|
this.deps = deps;
|
|
20853
21471
|
}
|
|
20854
21472
|
owned(sessionID, cut, id) {
|
|
20855
|
-
|
|
20856
|
-
if (!isLocalCheckpoint(cut) || cut.id !== id || !row?.payload || row.digest !== foldDigest(row.payload))
|
|
20857
|
-
return false;
|
|
20858
|
-
const snapshot = JSON.parse(row.payload);
|
|
20859
|
-
return snapshot.summary === cut.data.summary && snapshot.source === this.deps.storage.sourceID && snapshot.sessionID === sessionID && snapshot.admissionID === id;
|
|
21473
|
+
return cut.id === id && isAdmittedLocalCheckpoint(this.deps.storage, sessionID, cut);
|
|
20860
21474
|
}
|
|
20861
21475
|
async idle(sessionID) {
|
|
20862
21476
|
const { storage, session, threshold } = this.deps;
|
|
@@ -22038,26 +22652,70 @@ function generateReplayAnchor(messages) {
|
|
|
22038
22652
|
return;
|
|
22039
22653
|
return { id, tail: clonePreservingInstances(messages.slice(index + 1)) };
|
|
22040
22654
|
}
|
|
22655
|
+
var DEFAULT_GENERATE_REPLAY_LIMITS = Object.freeze({
|
|
22656
|
+
maxSessions: 16,
|
|
22657
|
+
sessionMaxBytes: 128 * 1024 * 1024,
|
|
22658
|
+
totalMaxBytes: 256 * 1024 * 1024
|
|
22659
|
+
});
|
|
22041
22660
|
|
|
22042
22661
|
class V2GenerateReplay {
|
|
22043
22662
|
prefixes = new Map;
|
|
22663
|
+
totalBytes = 0;
|
|
22664
|
+
limits;
|
|
22665
|
+
constructor(limits = DEFAULT_GENERATE_REPLAY_LIMITS) {
|
|
22666
|
+
if (!Number.isSafeInteger(limits.maxSessions) || limits.maxSessions < 1 || !Number.isSafeInteger(limits.sessionMaxBytes) || limits.sessionMaxBytes < 1 || !Number.isSafeInteger(limits.totalMaxBytes) || limits.totalMaxBytes < 1)
|
|
22667
|
+
throw new Error("Generate replay limits must be positive integers");
|
|
22668
|
+
this.limits = { ...limits };
|
|
22669
|
+
}
|
|
22044
22670
|
capture(draft, anchor) {
|
|
22671
|
+
this.forget(draft.sessionID);
|
|
22045
22672
|
if (!anchor) {
|
|
22046
|
-
this.prefixes.delete(draft.sessionID);
|
|
22047
22673
|
sessionLog(draft.sessionID, "generate replay capture skipped: no-anchor");
|
|
22048
22674
|
return;
|
|
22049
22675
|
}
|
|
22676
|
+
const parts = {
|
|
22677
|
+
anchor: clonePreservingInstancesMeasured(anchor),
|
|
22678
|
+
system: clonePreservingInstancesMeasured(draft.system),
|
|
22679
|
+
messages: clonePreservingInstancesMeasured(draft.messages),
|
|
22680
|
+
tools: clonePreservingInstancesMeasured(draft.tools)
|
|
22681
|
+
};
|
|
22682
|
+
const bytes = 256 + parts.anchor.bytes + parts.system.bytes + parts.messages.bytes + parts.tools.bytes;
|
|
22683
|
+
if (bytes > this.limits.sessionMaxBytes || bytes > this.limits.totalMaxBytes) {
|
|
22684
|
+
sessionLog(draft.sessionID, `generate replay capture skipped: over-session-cap (${bytes} > ${Math.min(this.limits.sessionMaxBytes, this.limits.totalMaxBytes)} bytes)`);
|
|
22685
|
+
return;
|
|
22686
|
+
}
|
|
22687
|
+
while (this.prefixes.size > 0 && (this.prefixes.size >= this.limits.maxSessions || this.totalBytes + bytes > this.limits.totalMaxBytes)) {
|
|
22688
|
+
const oldest = this.prefixes.keys().next().value;
|
|
22689
|
+
if (oldest === undefined)
|
|
22690
|
+
break;
|
|
22691
|
+
this.forget(oldest);
|
|
22692
|
+
}
|
|
22050
22693
|
this.prefixes.set(draft.sessionID, {
|
|
22051
|
-
anchor:
|
|
22694
|
+
anchor: parts.anchor.copy,
|
|
22052
22695
|
model: `${draft.model.providerID}/${draft.model.id}`,
|
|
22053
22696
|
agent: draft.agent,
|
|
22054
|
-
system:
|
|
22055
|
-
messages:
|
|
22056
|
-
tools:
|
|
22697
|
+
system: parts.system.copy,
|
|
22698
|
+
messages: parts.messages.copy,
|
|
22699
|
+
tools: parts.tools.copy,
|
|
22700
|
+
bytes
|
|
22057
22701
|
});
|
|
22702
|
+
this.totalBytes += bytes;
|
|
22058
22703
|
}
|
|
22059
22704
|
forget(sessionID) {
|
|
22705
|
+
const prefix = this.prefixes.get(sessionID);
|
|
22706
|
+
if (!prefix)
|
|
22707
|
+
return;
|
|
22060
22708
|
this.prefixes.delete(sessionID);
|
|
22709
|
+
this.totalBytes -= prefix.bytes;
|
|
22710
|
+
}
|
|
22711
|
+
stats() {
|
|
22712
|
+
return {
|
|
22713
|
+
totalBytes: this.totalBytes,
|
|
22714
|
+
sessions: [...this.prefixes].map(([sessionId, prefix]) => ({
|
|
22715
|
+
sessionId,
|
|
22716
|
+
bytes: prefix.bytes
|
|
22717
|
+
}))
|
|
22718
|
+
};
|
|
22061
22719
|
}
|
|
22062
22720
|
apply(draft) {
|
|
22063
22721
|
const prefix = this.prefixes.get(draft.sessionID);
|
|
@@ -22067,6 +22725,8 @@ class V2GenerateReplay {
|
|
|
22067
22725
|
};
|
|
22068
22726
|
if (!prefix)
|
|
22069
22727
|
return skip("no-prefix");
|
|
22728
|
+
this.prefixes.delete(draft.sessionID);
|
|
22729
|
+
this.prefixes.set(draft.sessionID, prefix);
|
|
22070
22730
|
if (prefix.model !== `${draft.model.providerID}/${draft.model.id}`)
|
|
22071
22731
|
return skip("model-mismatch");
|
|
22072
22732
|
if (prefix.agent !== draft.agent)
|
|
@@ -22110,21 +22770,25 @@ function identity(slot) {
|
|
|
22110
22770
|
|
|
22111
22771
|
class V2LkgSystemReplay {
|
|
22112
22772
|
systems = new BoundedSessionMap(1000);
|
|
22113
|
-
capture(sessionId, slot, input, served) {
|
|
22773
|
+
capture(sessionId, slot, input, served, head) {
|
|
22114
22774
|
this.systems.set(sessionId, {
|
|
22115
22775
|
slot: identity(slot),
|
|
22116
|
-
input:
|
|
22117
|
-
served: structuredClone(served)
|
|
22776
|
+
input: hostInputKey(input),
|
|
22777
|
+
served: structuredClone(served),
|
|
22778
|
+
head: head ? structuredClone(head) : null
|
|
22118
22779
|
});
|
|
22119
22780
|
}
|
|
22120
22781
|
restore(sessionId, slot, input, target) {
|
|
22121
22782
|
const saved = this.systems.get(sessionId);
|
|
22122
|
-
if (!slot || !saved || saved.slot !== identity(slot) || saved.input !==
|
|
22123
|
-
return
|
|
22783
|
+
if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== hostInputKey(input))
|
|
22784
|
+
return;
|
|
22124
22785
|
target.splice(0, target.length, ...structuredClone(saved.served));
|
|
22125
|
-
return
|
|
22786
|
+
return { head: saved.head ? structuredClone(saved.head) : null };
|
|
22126
22787
|
}
|
|
22127
22788
|
}
|
|
22789
|
+
function hostInputKey(input) {
|
|
22790
|
+
return JSON.stringify({ system: input.system, checkpoint: input.checkpoint });
|
|
22791
|
+
}
|
|
22128
22792
|
|
|
22129
22793
|
// src/v2/hooks/model-limit-cache.ts
|
|
22130
22794
|
var warmStarted = false;
|
|
@@ -22785,6 +23449,22 @@ function* readV2RawMessagePagesForConversion(openReader, sessionID, pageRows = C
|
|
|
22785
23449
|
function createV2RawMessageReader(openReader) {
|
|
22786
23450
|
const servedBoundaryCache = new Map;
|
|
22787
23451
|
return {
|
|
23452
|
+
getRevision: (sessionID) => {
|
|
23453
|
+
const reader = openReader();
|
|
23454
|
+
try {
|
|
23455
|
+
return reader.latestSequence(sessionID);
|
|
23456
|
+
} finally {
|
|
23457
|
+
reader.close();
|
|
23458
|
+
}
|
|
23459
|
+
},
|
|
23460
|
+
getCountAfterRevision: (sessionID, after, through) => {
|
|
23461
|
+
const reader = openReader();
|
|
23462
|
+
try {
|
|
23463
|
+
return reader.messageCountAfterSequence(sessionID, after, through);
|
|
23464
|
+
} finally {
|
|
23465
|
+
reader.close();
|
|
23466
|
+
}
|
|
23467
|
+
},
|
|
22788
23468
|
readPage: (sessionID, afterOrdinal, limit, finalWatermark, after) => {
|
|
22789
23469
|
const reader = openReader();
|
|
22790
23470
|
try {
|
|
@@ -24252,7 +24932,7 @@ function createCtxReduceTool(deps) {
|
|
|
24252
24932
|
args = unwrapImitatedReducedArgs(args, ["drop"], { drop: "string" });
|
|
24253
24933
|
const sessionId = toolContext.sessionID;
|
|
24254
24934
|
if (!args.drop) {
|
|
24255
|
-
return
|
|
24935
|
+
return `Error: 'drop' must be provided as a string of tag numbers, for example {"drop": "3-5,8"}.`;
|
|
24256
24936
|
}
|
|
24257
24937
|
let dropIds = [];
|
|
24258
24938
|
try {
|
|
@@ -24634,6 +25314,26 @@ function persistV2UsageReading(args) {
|
|
|
24634
25314
|
}
|
|
24635
25315
|
|
|
24636
25316
|
// src/v2/hooks/context.ts
|
|
25317
|
+
function applyCheckpointHead(draft, head) {
|
|
25318
|
+
const { checkpoint, submitted } = head;
|
|
25319
|
+
const first = draft.messages.find((message) => message.id === HEAD_IDS[0]);
|
|
25320
|
+
const baseline = first?.content.find((part) => part.type === "text")?.text;
|
|
25321
|
+
if (typeof baseline !== "string")
|
|
25322
|
+
return false;
|
|
25323
|
+
for (const part of checkpoint.content)
|
|
25324
|
+
if (part.type === "text" && typeof part.text === "string") {
|
|
25325
|
+
part.text = part.text.replace(`<summary>
|
|
25326
|
+
${submitted}
|
|
25327
|
+
</summary>`, `<summary>
|
|
25328
|
+
${baseline}
|
|
25329
|
+
</summary>`);
|
|
25330
|
+
}
|
|
25331
|
+
const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
|
|
25332
|
+
if (volatile && first)
|
|
25333
|
+
volatile.content.push(...first.content.filter((part) => part.type !== "text"));
|
|
25334
|
+
draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== first));
|
|
25335
|
+
return true;
|
|
25336
|
+
}
|
|
24637
25337
|
var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
|
|
24638
25338
|
var STORE_POOL_DISPOSE_WAIT_MS = 1000;
|
|
24639
25339
|
|
|
@@ -24857,11 +25557,12 @@ async function registerContext(context) {
|
|
|
24857
25557
|
}
|
|
24858
25558
|
const folds = new FoldOwner(context.storage);
|
|
24859
25559
|
const nativeFoldMemory = !compactionOff && process.env.MMC_OC2_INVISIBLE_FOLD === "1" ? nativeFoldCache(() => storage.require()) : undefined;
|
|
24860
|
-
const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader()) : undefined;
|
|
25560
|
+
const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader(), context.storage) : undefined;
|
|
24861
25561
|
setOutputReserveConfig(config.output_reserve);
|
|
24862
25562
|
const queriedModels = new Set;
|
|
24863
25563
|
const rawLimits = new Map;
|
|
24864
25564
|
const hiddenSessionErrors = new Map;
|
|
25565
|
+
const committedSourceRefreshes = new Map;
|
|
24865
25566
|
const liveModels = new Map;
|
|
24866
25567
|
const promptSurfaceRuntime = createPromptSurfaceRuntime({
|
|
24867
25568
|
harness: "opencode2",
|
|
@@ -25061,11 +25762,17 @@ async function registerContext(context) {
|
|
|
25061
25762
|
}
|
|
25062
25763
|
});
|
|
25063
25764
|
const pagedRead = createV2RawMessageReader(openStoreReader);
|
|
25765
|
+
let orphanSweep;
|
|
25766
|
+
let orphanSweepTimer;
|
|
25064
25767
|
const prepareHistorySession = (sessionID) => {
|
|
25065
25768
|
if (!rawProviders.has(sessionID))
|
|
25066
25769
|
rawProviders.set(sessionID, setBoundedRawMessageProvider2(sessionID, createV2RawMessageProvider(pagedRead, sessionID)));
|
|
25067
25770
|
};
|
|
25068
25771
|
if (db && isDatabasePersisted(db)) {
|
|
25772
|
+
const sweepDb = db;
|
|
25773
|
+
orphanSweepTimer = scheduleAfterBootQuiet(() => {
|
|
25774
|
+
orphanSweep = sweepOrphanedOpenCodeMessageIndexesCooperatively(sweepDb, () => new Database(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), { readonly: true, fileMustExist: true })).catch((error) => log("[magic-context] v2 orphan sweep failed:", error));
|
|
25775
|
+
});
|
|
25069
25776
|
const backfillDb = db;
|
|
25070
25777
|
scheduleAfterBootQuiet(() => {
|
|
25071
25778
|
runV2SessionProjectBackfill(backfillDb, openStoreReader, config.allow_home_project).catch((error) => log("[session-project-backfill] OpenCode 2 backfill failed:", error));
|
|
@@ -25184,88 +25891,122 @@ async function registerContext(context) {
|
|
|
25184
25891
|
}) : undefined;
|
|
25185
25892
|
const usageController = new AbortController;
|
|
25186
25893
|
const usageDone = (async () => {
|
|
25187
|
-
|
|
25188
|
-
|
|
25189
|
-
|
|
25190
|
-
|
|
25191
|
-
const
|
|
25192
|
-
|
|
25193
|
-
|
|
25194
|
-
|
|
25195
|
-
|
|
25196
|
-
|
|
25197
|
-
|
|
25198
|
-
|
|
25199
|
-
|
|
25200
|
-
|
|
25201
|
-
|
|
25202
|
-
|
|
25203
|
-
|
|
25204
|
-
|
|
25205
|
-
|
|
25206
|
-
|
|
25207
|
-
|
|
25894
|
+
let retry = 0;
|
|
25895
|
+
while (!usageController.signal.aborted) {
|
|
25896
|
+
const subscribedAt = Date.now();
|
|
25897
|
+
try {
|
|
25898
|
+
for await (const value of context.event.subscribe({
|
|
25899
|
+
signal: usageController.signal
|
|
25900
|
+
})) {
|
|
25901
|
+
if (usageController.signal.aborted)
|
|
25902
|
+
break;
|
|
25903
|
+
const event = value;
|
|
25904
|
+
try {
|
|
25905
|
+
if (event.type === "provider.updated" || event.type === "model.updated") {
|
|
25906
|
+
queriedModels.clear();
|
|
25907
|
+
continue;
|
|
25908
|
+
}
|
|
25909
|
+
if (!event.data?.sessionID)
|
|
25910
|
+
continue;
|
|
25911
|
+
const sessionID = event.data.sessionID;
|
|
25912
|
+
if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
|
|
25913
|
+
nativeFoldReplay?.onEvent(event);
|
|
25914
|
+
restoredRows.forget(sessionID);
|
|
25915
|
+
}
|
|
25916
|
+
if (event.type === "session.revert.committed") {
|
|
25917
|
+
committedSourceRefreshes.set(sessionID, {});
|
|
25918
|
+
const database = db;
|
|
25919
|
+
if (database)
|
|
25920
|
+
withoutSqliteTransformPass(() => scheduleClearAndReindex(database, sessionID, pagedRead));
|
|
25921
|
+
}
|
|
25922
|
+
if (event.type === "session.error" || event.type === "session.execution.failed") {
|
|
25923
|
+
const error = hiddenTerminalError(event);
|
|
25924
|
+
if (error !== undefined)
|
|
25925
|
+
hiddenSessionErrors.set(sessionID, error);
|
|
25926
|
+
if (error !== undefined && db && !compactionOff) {
|
|
25927
|
+
const model = liveModels.get(sessionID);
|
|
25928
|
+
try {
|
|
25929
|
+
armLatestThinkingRecoveryFromError({
|
|
25930
|
+
db,
|
|
25931
|
+
sessionId: sessionID,
|
|
25932
|
+
error,
|
|
25933
|
+
providerID: model?.providerID,
|
|
25934
|
+
modelID: model?.modelID
|
|
25935
|
+
});
|
|
25936
|
+
} catch (armError) {
|
|
25937
|
+
log("[magic-context] v2 latest-thinking recovery arm failed", armError);
|
|
25938
|
+
}
|
|
25939
|
+
}
|
|
25940
|
+
continue;
|
|
25941
|
+
}
|
|
25942
|
+
if (event.type === "session.deleted") {
|
|
25943
|
+
committedSourceRefreshes.delete(sessionID);
|
|
25944
|
+
clearLkgMeasuredRequest(sessionID);
|
|
25945
|
+
deletedSessions.add(sessionID);
|
|
25946
|
+
transform?.clearSessionLogState(sessionID);
|
|
25947
|
+
if (db) {
|
|
25948
|
+
markSessionCleanupPending(db, sessionID);
|
|
25949
|
+
clearSession(db, sessionID, false, true);
|
|
25950
|
+
}
|
|
25951
|
+
rawProviders.get(sessionID)?.();
|
|
25952
|
+
rawProviders.delete(sessionID);
|
|
25953
|
+
usage.delete(sessionID);
|
|
25954
|
+
hiddenSessionErrors.delete(sessionID);
|
|
25955
|
+
storageNoticeBySession.delete(sessionID);
|
|
25956
|
+
liveModels.delete(sessionID);
|
|
25957
|
+
variants.delete(sessionID);
|
|
25958
|
+
agents.delete(sessionID);
|
|
25959
|
+
channel1.delete(sessionID);
|
|
25960
|
+
historyRefreshSessions.delete(sessionID);
|
|
25961
|
+
clearPendingMaterialization(pendingMaterializationSessions, sessionID);
|
|
25962
|
+
lastHeuristicsTurnId.delete(sessionID);
|
|
25963
|
+
restoredRows.forget(sessionID);
|
|
25964
|
+
if (nativeFoldReplay)
|
|
25965
|
+
await nativeFoldReplay.forget(sessionID);
|
|
25966
|
+
else
|
|
25967
|
+
await forgetNativeFoldProvenance(context.storage, sessionID);
|
|
25968
|
+
generateReplay.forget(sessionID);
|
|
25969
|
+
systemPromptRefreshSessions.delete(sessionID);
|
|
25970
|
+
systemPrompt?.clearSession(sessionID);
|
|
25971
|
+
clearMaintenanceSystemSnapshot(sessionID);
|
|
25972
|
+
tagger.cleanup(sessionID);
|
|
25973
|
+
sessionDirectories.delete(sessionID);
|
|
25974
|
+
forkSeedSettled.delete(sessionID);
|
|
25975
|
+
continue;
|
|
25976
|
+
}
|
|
25977
|
+
if (event.type !== "session.execution.succeeded")
|
|
25978
|
+
continue;
|
|
25208
25979
|
const model = liveModels.get(sessionID);
|
|
25209
|
-
|
|
25210
|
-
|
|
25211
|
-
|
|
25212
|
-
|
|
25213
|
-
error,
|
|
25214
|
-
providerID: model?.providerID,
|
|
25215
|
-
modelID: model?.modelID
|
|
25980
|
+
if (model) {
|
|
25981
|
+
await recordUsage({
|
|
25982
|
+
sessionID,
|
|
25983
|
+
model: { providerID: model.providerID, id: model.modelID }
|
|
25216
25984
|
});
|
|
25217
|
-
|
|
25218
|
-
|
|
25985
|
+
if (!compactionOff && typeof await nativeFoldReplay?.baseline(sessionID) === "string")
|
|
25986
|
+
hostFolds?.idle(sessionID);
|
|
25219
25987
|
}
|
|
25988
|
+
} catch (error) {
|
|
25989
|
+
log(`[magic-context] v2 event handler failed (type=${event.type ?? "unknown"}, session=${event.data?.sessionID ?? "none"})`, error);
|
|
25220
25990
|
}
|
|
25221
|
-
continue;
|
|
25222
|
-
}
|
|
25223
|
-
if (event.type === "session.deleted") {
|
|
25224
|
-
clearLkgMeasuredRequest(sessionID);
|
|
25225
|
-
deletedSessions.add(sessionID);
|
|
25226
|
-
transform?.clearSessionLogState(sessionID);
|
|
25227
|
-
if (db) {
|
|
25228
|
-
markSessionCleanupPending(db, sessionID);
|
|
25229
|
-
clearSession(db, sessionID);
|
|
25230
|
-
}
|
|
25231
|
-
rawProviders.get(sessionID)?.();
|
|
25232
|
-
rawProviders.delete(sessionID);
|
|
25233
|
-
usage.delete(sessionID);
|
|
25234
|
-
hiddenSessionErrors.delete(sessionID);
|
|
25235
|
-
storageNoticeBySession.delete(sessionID);
|
|
25236
|
-
liveModels.delete(sessionID);
|
|
25237
|
-
variants.delete(sessionID);
|
|
25238
|
-
agents.delete(sessionID);
|
|
25239
|
-
channel1.delete(sessionID);
|
|
25240
|
-
historyRefreshSessions.delete(sessionID);
|
|
25241
|
-
clearPendingMaterialization(pendingMaterializationSessions, sessionID);
|
|
25242
|
-
lastHeuristicsTurnId.delete(sessionID);
|
|
25243
|
-
restoredRows.forget(sessionID);
|
|
25244
|
-
await nativeFoldReplay?.forget(sessionID);
|
|
25245
|
-
generateReplay.forget(sessionID);
|
|
25246
|
-
systemPromptRefreshSessions.delete(sessionID);
|
|
25247
|
-
systemPrompt?.clearSession(sessionID);
|
|
25248
|
-
clearMaintenanceSystemSnapshot(sessionID);
|
|
25249
|
-
tagger.cleanup(sessionID);
|
|
25250
|
-
sessionDirectories.delete(sessionID);
|
|
25251
|
-
forkSeedSettled.delete(sessionID);
|
|
25252
|
-
continue;
|
|
25253
|
-
}
|
|
25254
|
-
if (event.type !== "session.execution.succeeded")
|
|
25255
|
-
continue;
|
|
25256
|
-
const model = liveModels.get(sessionID);
|
|
25257
|
-
if (model) {
|
|
25258
|
-
await recordUsage({
|
|
25259
|
-
sessionID,
|
|
25260
|
-
model: { providerID: model.providerID, id: model.modelID }
|
|
25261
|
-
});
|
|
25262
|
-
if (!compactionOff && typeof await nativeFoldReplay?.baseline(sessionID) === "string")
|
|
25263
|
-
hostFolds?.idle(sessionID);
|
|
25264
25991
|
}
|
|
25992
|
+
} catch (error) {
|
|
25993
|
+
if (!usageController.signal.aborted)
|
|
25994
|
+
log("[magic-context] v2 usage subscription failed", error);
|
|
25995
|
+
}
|
|
25996
|
+
if (usageController.signal.aborted)
|
|
25997
|
+
break;
|
|
25998
|
+
if (Date.now() - subscribedAt >= 30000)
|
|
25999
|
+
retry = 0;
|
|
26000
|
+
const ceiling = Math.min(30000, 250 * 2 ** retry);
|
|
26001
|
+
retry = Math.min(retry + 1, 7);
|
|
26002
|
+
try {
|
|
26003
|
+
await delay(ceiling * (0.5 + Math.random() * 0.5), undefined, {
|
|
26004
|
+
signal: usageController.signal
|
|
26005
|
+
});
|
|
26006
|
+
} catch (error) {
|
|
26007
|
+
if (!usageController.signal.aborted)
|
|
26008
|
+
throw error;
|
|
25265
26009
|
}
|
|
25266
|
-
} catch (error) {
|
|
25267
|
-
if (!usageController.signal.aborted)
|
|
25268
|
-
log("[magic-context] v2 usage subscription failed", error);
|
|
25269
26010
|
}
|
|
25270
26011
|
})();
|
|
25271
26012
|
const materialize = (draft) => {
|
|
@@ -25338,20 +26079,57 @@ async function registerContext(context) {
|
|
|
25338
26079
|
reader.close();
|
|
25339
26080
|
}
|
|
25340
26081
|
});
|
|
26082
|
+
const restoreAfterCheckpoint = (args) => {
|
|
26083
|
+
const { db, reader, draft, cut, boundaryRepair } = args;
|
|
26084
|
+
const boundaryID = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id = ?").get(draft.sessionID)?.id ?? (boundaryRepair?.kind === "repaired" || boundaryRepair?.kind === "baseline-reset" ? boundaryRepair.anchorEndMessageId : null);
|
|
26085
|
+
const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
|
|
26086
|
+
const boundary = servedBoundary?.seq ?? reader.sequenceForId(draft.sessionID, boundaryID) ?? (reader.earliestSequence(draft.sessionID) ?? 0) - 1;
|
|
26087
|
+
const present = new Set(args.messages.map((message) => message.id));
|
|
26088
|
+
const restored = restoredRows.rows(reader, draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
|
|
26089
|
+
asset: hostMediaAsset,
|
|
26090
|
+
unavailable: (detail) => sessionLog(draft.sessionID, `v2 restore: attachment replaced by a note row=${detail.rowID} name=${JSON.stringify(detail.name ?? null)} mediaType=${detail.mediaType} reason=${JSON.stringify(detail.reason)}`)
|
|
26091
|
+
} : undefined));
|
|
26092
|
+
const covered = reader.instructionRowsThrough(draft.sessionID, Math.min(boundary, cut.seq)).flatMap((row) => restoreRow(row, draft.model)).map((message) => markCoveredInstructionRow(message));
|
|
26093
|
+
return [
|
|
26094
|
+
...covered,
|
|
26095
|
+
...restored,
|
|
26096
|
+
...args.messages.filter((message) => message !== args.incoming)
|
|
26097
|
+
];
|
|
26098
|
+
};
|
|
26099
|
+
const temporalTimes = config.temporal_awareness === true;
|
|
26100
|
+
const anchorTimesOnly = !temporalTimes;
|
|
26101
|
+
const timeIds = (messages) => {
|
|
26102
|
+
if (temporalTimes)
|
|
26103
|
+
return messages.flatMap((message) => message.id ? [message.id] : []);
|
|
26104
|
+
const ids = [];
|
|
26105
|
+
for (const message of [...messages].reverse()) {
|
|
26106
|
+
if (message.id)
|
|
26107
|
+
ids.push(message.id);
|
|
26108
|
+
if (message.role === "assistant")
|
|
26109
|
+
break;
|
|
26110
|
+
}
|
|
26111
|
+
return ids;
|
|
26112
|
+
};
|
|
25341
26113
|
const runManagedContext = async (draft) => {
|
|
25342
26114
|
rememberHostMedia(draft.messages);
|
|
25343
26115
|
if (hiddenChildHook.apply(draft))
|
|
25344
26116
|
return;
|
|
25345
26117
|
if (deletedSessions.has(draft.sessionID))
|
|
25346
26118
|
return;
|
|
25347
|
-
|
|
26119
|
+
let systemAtEntry = structuredClone(draft.system);
|
|
25348
26120
|
const slotAtEntry = getSlot(draft.sessionID);
|
|
26121
|
+
let checkpointAtEntry;
|
|
26122
|
+
let replayHead;
|
|
26123
|
+
const hostInput = () => checkpointAtEntry === undefined ? undefined : { system: systemAtEntry, checkpoint: checkpointAtEntry };
|
|
25349
26124
|
const restoreLkgSystem = () => {
|
|
25350
26125
|
retirePendingSystemPromptDelivery(draft.sessionID);
|
|
25351
|
-
|
|
26126
|
+
const input = hostInput();
|
|
26127
|
+
const restored = input && lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, draft.system);
|
|
26128
|
+
if (!restored) {
|
|
25352
26129
|
sessionLog(draft.sessionID, "lkg_system_state_mismatch");
|
|
25353
26130
|
throw new Error("LKG system identity is unavailable or changed");
|
|
25354
26131
|
}
|
|
26132
|
+
replayHead = restored.head;
|
|
25355
26133
|
};
|
|
25356
26134
|
const isMagicContextSynthetic = (id) => isAdmittedSynthetic(context, draft.sessionID, id);
|
|
25357
26135
|
const newest = draft.messages.at(-1);
|
|
@@ -25360,6 +26138,24 @@ async function registerContext(context) {
|
|
|
25360
26138
|
return;
|
|
25361
26139
|
}
|
|
25362
26140
|
await dropStorageNotices(draft.messages, isMagicContextSynthetic);
|
|
26141
|
+
let hostMessagesAtEntry = [...draft.messages];
|
|
26142
|
+
const passTimes = new Map;
|
|
26143
|
+
const readTimes = (reader, messages) => {
|
|
26144
|
+
const ids = timeIds(messages);
|
|
26145
|
+
const missing = ids.filter((id) => !passTimes.has(id));
|
|
26146
|
+
if (missing.length) {
|
|
26147
|
+
const read = reader.messageTimes(draft.sessionID, missing);
|
|
26148
|
+
for (const id of missing)
|
|
26149
|
+
passTimes.set(id, read.get(id) ?? null);
|
|
26150
|
+
}
|
|
26151
|
+
const times = new Map;
|
|
26152
|
+
for (const id of ids) {
|
|
26153
|
+
const time = passTimes.get(id);
|
|
26154
|
+
if (time)
|
|
26155
|
+
times.set(id, time);
|
|
26156
|
+
}
|
|
26157
|
+
return times;
|
|
26158
|
+
};
|
|
25363
26159
|
liveModels.set(draft.sessionID, {
|
|
25364
26160
|
providerID: draft.model.providerID,
|
|
25365
26161
|
modelID: draft.model.id
|
|
@@ -25371,8 +26167,9 @@ async function registerContext(context) {
|
|
|
25371
26167
|
applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface);
|
|
25372
26168
|
const admissionDb = db ?? storage.current();
|
|
25373
26169
|
const replayFits = (messages) => {
|
|
25374
|
-
const system =
|
|
25375
|
-
|
|
26170
|
+
const system = [];
|
|
26171
|
+
const input = hostInput();
|
|
26172
|
+
if (!admissionDb || !draft.tools || !input || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, system))
|
|
25376
26173
|
return false;
|
|
25377
26174
|
const limit = lkgReplayLimit({
|
|
25378
26175
|
db: admissionDb,
|
|
@@ -25407,15 +26204,75 @@ async function registerContext(context) {
|
|
|
25407
26204
|
})
|
|
25408
26205
|
}).fit === "under";
|
|
25409
26206
|
};
|
|
26207
|
+
const buildReplayInput = async () => {
|
|
26208
|
+
let messages = [...hostMessagesAtEntry];
|
|
26209
|
+
const admitted = new Set;
|
|
26210
|
+
let times;
|
|
26211
|
+
try {
|
|
26212
|
+
const reader = openStoreReader();
|
|
26213
|
+
try {
|
|
26214
|
+
const cut = reader.latestCompaction(draft.sessionID);
|
|
26215
|
+
const localCut = cut && isLocalCheckpoint(cut) ? cut : undefined;
|
|
26216
|
+
const incoming = localCut && messages.find((message) => message.id === localCut.id);
|
|
26217
|
+
if (localCut && !incoming || cut && nativeFoldReplay)
|
|
26218
|
+
return;
|
|
26219
|
+
checkpointAtEntry = incoming || null;
|
|
26220
|
+
const modeDb = db ?? storage.current();
|
|
26221
|
+
const subagent = modeDb ? storedSubagentMode(modeDb, draft.sessionID) : undefined;
|
|
26222
|
+
if (subagent === undefined)
|
|
26223
|
+
return;
|
|
26224
|
+
if (subagent)
|
|
26225
|
+
removePrimaryOnlyTools(draft.tools);
|
|
26226
|
+
const candidates = syntheticCandidates(context, draft.sessionID, reader.syntheticMessageIDs(draft.sessionID));
|
|
26227
|
+
for (const message of messages)
|
|
26228
|
+
if (message.id && candidates.has(message.id) && await isAdmittedSynthetic(context, draft.sessionID, message.id))
|
|
26229
|
+
admitted.add(message.id);
|
|
26230
|
+
const replayDb = db ?? storage.current();
|
|
26231
|
+
if (localCut && incoming && replayDb)
|
|
26232
|
+
messages = restoreAfterCheckpoint({
|
|
26233
|
+
db: replayDb,
|
|
26234
|
+
reader,
|
|
26235
|
+
draft,
|
|
26236
|
+
messages,
|
|
26237
|
+
cut: localCut,
|
|
26238
|
+
incoming,
|
|
26239
|
+
boundaryRepair: undefined
|
|
26240
|
+
});
|
|
26241
|
+
else if (localCut)
|
|
26242
|
+
return;
|
|
26243
|
+
times = readTimes(reader, messages);
|
|
26244
|
+
} finally {
|
|
26245
|
+
reader.close();
|
|
26246
|
+
}
|
|
26247
|
+
} catch (error) {
|
|
26248
|
+
sessionLog(draft.sessionID, "lkg replay input unavailable", error);
|
|
26249
|
+
return;
|
|
26250
|
+
}
|
|
26251
|
+
const replayDraft = { ...draft, messages };
|
|
26252
|
+
return {
|
|
26253
|
+
draft: replayDraft,
|
|
26254
|
+
mapped: adaptPayload(replayDraft, admitted, times, anchorTimesOnly)
|
|
26255
|
+
};
|
|
26256
|
+
};
|
|
26257
|
+
const adoptReplay = (replayed) => {
|
|
26258
|
+
draft.messages.splice(0, draft.messages.length, ...replayed.messages);
|
|
26259
|
+
if (replayHead)
|
|
26260
|
+
applyCheckpointHead(draft, replayHead);
|
|
26261
|
+
};
|
|
25410
26262
|
let postFold = false;
|
|
25411
26263
|
try {
|
|
25412
26264
|
if (!compactionOff && admissionDb)
|
|
25413
26265
|
await withAsyncPrivilegedWriter(admissionDb, () => {
|
|
25414
26266
|
return;
|
|
25415
26267
|
}, {
|
|
25416
|
-
beforeRetry: (_error) => {
|
|
26268
|
+
beforeRetry: async (_error) => {
|
|
26269
|
+
hostMessagesAtEntry = [...draft.messages];
|
|
26270
|
+
systemAtEntry = structuredClone(draft.system);
|
|
25417
26271
|
let replayBlocked = false;
|
|
25418
|
-
const
|
|
26272
|
+
const input = await buildReplayInput();
|
|
26273
|
+
if (!input)
|
|
26274
|
+
return;
|
|
26275
|
+
const { mapped } = input;
|
|
25419
26276
|
try {
|
|
25420
26277
|
const overflowDb = db;
|
|
25421
26278
|
if (overflowDb !== undefined && overflowDb !== null && (isEmergencyRecoveryArmed(draft.sessionID) || getOverflowState(overflowDb, draft.sessionID).needsEmergencyRecovery)) {
|
|
@@ -25436,6 +26293,7 @@ async function registerContext(context) {
|
|
|
25436
26293
|
restoreLkgSystem();
|
|
25437
26294
|
mapped.messages.splice(0, mapped.messages.length, ...replay.messages);
|
|
25438
26295
|
mapped.commit();
|
|
26296
|
+
adoptReplay(input.draft);
|
|
25439
26297
|
sessionLog(draft.sessionID, "lkg_replay_served");
|
|
25440
26298
|
throw new V2LkgAdmissionReplay;
|
|
25441
26299
|
} else {
|
|
@@ -25452,6 +26310,8 @@ async function registerContext(context) {
|
|
|
25452
26310
|
sessionLog(draft.sessionID, "lkg_replay_declined");
|
|
25453
26311
|
}
|
|
25454
26312
|
});
|
|
26313
|
+
hostMessagesAtEntry = [...draft.messages];
|
|
26314
|
+
systemAtEntry = structuredClone(draft.system);
|
|
25455
26315
|
if (admissionDb)
|
|
25456
26316
|
hideSubagentTools(draft, admissionDb);
|
|
25457
26317
|
recordV2ToolDefinitions(draft);
|
|
@@ -25555,7 +26415,11 @@ async function registerContext(context) {
|
|
|
25555
26415
|
contextUsageMap: usage,
|
|
25556
26416
|
compactionOff,
|
|
25557
26417
|
storeGeneration: "v2",
|
|
25558
|
-
normalizeRestoredAssistantText:
|
|
26418
|
+
normalizeRestoredAssistantText: (text, providerID) => {
|
|
26419
|
+
const normalized = stripCopiedTagNotation(text);
|
|
26420
|
+
return normalized === "" && !modelAcceptsEmptyContent(providerID) ? text : normalized;
|
|
26421
|
+
},
|
|
26422
|
+
refreshSourceContents: (sessionID) => committedSourceRefreshes.has(sessionID),
|
|
25559
26423
|
hostCleanupCompactionMarkers: () => ({
|
|
25560
26424
|
verified: true,
|
|
25561
26425
|
removedLineages: 0,
|
|
@@ -25600,8 +26464,14 @@ async function registerContext(context) {
|
|
|
25600
26464
|
},
|
|
25601
26465
|
...createHostSeams(context, readAllForConversion, pagedRead, liveModels)
|
|
25602
26466
|
});
|
|
26467
|
+
const refreshToken = committedSourceRefreshes.get(draft.sessionID);
|
|
26468
|
+
if (refreshToken) {
|
|
26469
|
+
clearCachedM0(db, draft.sessionID);
|
|
26470
|
+
restoredRows.forget(draft.sessionID);
|
|
26471
|
+
}
|
|
25603
26472
|
const admitted = new Set;
|
|
25604
26473
|
const reader = openStoreReader();
|
|
26474
|
+
let messageTimes;
|
|
25605
26475
|
let checkpoint;
|
|
25606
26476
|
let submitted;
|
|
25607
26477
|
try {
|
|
@@ -25616,12 +26486,14 @@ async function registerContext(context) {
|
|
|
25616
26486
|
historyRefreshSessions.add(draft.sessionID);
|
|
25617
26487
|
requestPendingMaterialization(pendingMaterializationSessions, draft.sessionID, "boundary_repair");
|
|
25618
26488
|
}
|
|
25619
|
-
const
|
|
26489
|
+
const localCut = cut && isLocalCheckpoint(cut) ? cut : undefined;
|
|
26490
|
+
const incoming = localCut && draft.messages.find((message) => message.id === localCut.id);
|
|
25620
26491
|
postFold = cut !== undefined;
|
|
25621
|
-
|
|
26492
|
+
checkpointAtEntry = incoming || null;
|
|
26493
|
+
if (localCut && !incoming)
|
|
25622
26494
|
throw new Error("The host checkpoint disappeared from the context draft");
|
|
25623
26495
|
let nativeRestored;
|
|
25624
|
-
if (cut && nativeFoldReplay &&
|
|
26496
|
+
if (cut && nativeFoldReplay && await nativeFoldReplay.admits(draft.sessionID, cut, reader)) {
|
|
25625
26497
|
try {
|
|
25626
26498
|
nativeRestored = await nativeFoldReplay.restore(draft.sessionID, cut, `${draft.model.providerID}/${draft.model.id}`, { bounded: true });
|
|
25627
26499
|
} catch (error) {
|
|
@@ -25630,7 +26502,7 @@ async function registerContext(context) {
|
|
|
25630
26502
|
nativeRestored = await nativeFoldReplay.restoreRead(draft.sessionID, cut, draft.model);
|
|
25631
26503
|
}
|
|
25632
26504
|
}
|
|
25633
|
-
if (
|
|
26505
|
+
if (cut && nativeFoldReplay?.sourceChanged(draft.sessionID)) {
|
|
25634
26506
|
historyRefreshSessions.add(draft.sessionID);
|
|
25635
26507
|
requestPendingMaterialization(pendingMaterializationSessions, draft.sessionID, "host_history_change");
|
|
25636
26508
|
}
|
|
@@ -25641,30 +26513,33 @@ async function registerContext(context) {
|
|
|
25641
26513
|
return !id || !present.has(id);
|
|
25642
26514
|
});
|
|
25643
26515
|
draft.messages.splice(0, draft.messages.length, ...hidden, ...draft.messages.filter((message) => message !== incoming));
|
|
25644
|
-
} else if (cut && incoming) {
|
|
25645
|
-
|
|
25646
|
-
|
|
25647
|
-
|
|
25648
|
-
|
|
25649
|
-
|
|
25650
|
-
|
|
25651
|
-
|
|
25652
|
-
|
|
25653
|
-
|
|
25654
|
-
|
|
25655
|
-
|
|
25656
|
-
|
|
25657
|
-
|
|
25658
|
-
|
|
25659
|
-
|
|
25660
|
-
|
|
25661
|
-
|
|
25662
|
-
|
|
25663
|
-
|
|
25664
|
-
|
|
25665
|
-
|
|
25666
|
-
|
|
26516
|
+
} else if (localCut && cut && incoming) {
|
|
26517
|
+
if (!nativeFoldReplay) {
|
|
26518
|
+
const identity = await folds.observe({
|
|
26519
|
+
sessionID: draft.sessionID,
|
|
26520
|
+
cutSeq: cut.seq,
|
|
26521
|
+
summary: cut.data.summary ?? "",
|
|
26522
|
+
rendered: incoming,
|
|
26523
|
+
onHard: (reason) => {
|
|
26524
|
+
log(`[magic-context] HARD reason=${reason} session=${draft.sessionID}`);
|
|
26525
|
+
materialize(draft);
|
|
26526
|
+
requestPendingMaterialization(pendingMaterializationSessions, draft.sessionID, "host_compaction");
|
|
26527
|
+
}
|
|
26528
|
+
});
|
|
26529
|
+
checkpoint = structuredClone(identity.rendered ?? incoming);
|
|
26530
|
+
submitted = identity.rendered ? identity.renderedSummary ?? identity.submitted : cut.data.summary ?? "";
|
|
26531
|
+
}
|
|
26532
|
+
draft.messages.splice(0, draft.messages.length, ...restoreAfterCheckpoint({
|
|
26533
|
+
db,
|
|
26534
|
+
reader,
|
|
26535
|
+
draft,
|
|
26536
|
+
messages: draft.messages,
|
|
26537
|
+
cut: localCut,
|
|
26538
|
+
incoming,
|
|
26539
|
+
boundaryRepair
|
|
26540
|
+
}));
|
|
25667
26541
|
}
|
|
26542
|
+
messageTimes = readTimes(reader, draft.messages);
|
|
25668
26543
|
} finally {
|
|
25669
26544
|
reader.close();
|
|
25670
26545
|
}
|
|
@@ -25676,31 +26551,18 @@ async function registerContext(context) {
|
|
|
25676
26551
|
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
25677
26552
|
}
|
|
25678
26553
|
}
|
|
25679
|
-
const mapped = adaptPayload(draft, admitted);
|
|
26554
|
+
const mapped = adaptPayload(draft, admitted, messageTimes, anchorTimesOnly);
|
|
25680
26555
|
bindSystemDateRequestIdentity(mapped, draft);
|
|
25681
26556
|
await transform({}, mapped);
|
|
25682
26557
|
mapped.commit();
|
|
26558
|
+
if (refreshToken && committedSourceRefreshes.get(draft.sessionID) === refreshToken)
|
|
26559
|
+
committedSourceRefreshes.delete(draft.sessionID);
|
|
25683
26560
|
if (db) {
|
|
25684
26561
|
await deliverPendingChannel2(context, db, draft.sessionID, channel1.get(draft.sessionID));
|
|
25685
26562
|
}
|
|
25686
|
-
|
|
25687
|
-
|
|
25688
|
-
|
|
25689
|
-
if (typeof baseline === "string") {
|
|
25690
|
-
for (const part of checkpoint.content)
|
|
25691
|
-
if (part.type === "text" && typeof part.text === "string") {
|
|
25692
|
-
part.text = part.text.replace(`<summary>
|
|
25693
|
-
${submitted}
|
|
25694
|
-
</summary>`, `<summary>
|
|
25695
|
-
${baseline}
|
|
25696
|
-
</summary>`);
|
|
25697
|
-
}
|
|
25698
|
-
const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
|
|
25699
|
-
if (volatile && head)
|
|
25700
|
-
volatile.content.push(...head.content.filter((part) => part.type !== "text"));
|
|
25701
|
-
draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== head));
|
|
25702
|
-
}
|
|
25703
|
-
}
|
|
26563
|
+
const head = replayHead !== undefined ? replayHead : checkpoint && submitted !== undefined ? { checkpoint, submitted } : null;
|
|
26564
|
+
const servedHead = head && structuredClone(head);
|
|
26565
|
+
const headApplied = head ? applyCheckpointHead(draft, head) : false;
|
|
25704
26566
|
if (nativeMessages && !checkpoint) {
|
|
25705
26567
|
try {
|
|
25706
26568
|
await nativeFoldReplay?.capture(draft, nativeMessages);
|
|
@@ -25711,7 +26573,7 @@ ${baseline}
|
|
|
25711
26573
|
}
|
|
25712
26574
|
const capturedSlot = getSlot(draft.sessionID);
|
|
25713
26575
|
if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
|
|
25714
|
-
lkgSystems.capture(draft.sessionID, capturedSlot, systemAtEntry, draft.system);
|
|
26576
|
+
lkgSystems.capture(draft.sessionID, capturedSlot, { system: systemAtEntry, checkpoint: checkpointAtEntry ?? null }, draft.system, headApplied ? servedHead : null);
|
|
25715
26577
|
}
|
|
25716
26578
|
} catch (error) {
|
|
25717
26579
|
if (error instanceof V2ContextRefusal)
|
|
@@ -25737,7 +26599,10 @@ ${baseline}
|
|
|
25737
26599
|
replayBlocked = true;
|
|
25738
26600
|
sessionLog(draft.sessionID, "lkg_emergency_armed");
|
|
25739
26601
|
} else {
|
|
25740
|
-
const
|
|
26602
|
+
const input = await buildReplayInput();
|
|
26603
|
+
if (!input)
|
|
26604
|
+
throw new StorageBusyRefusalError(error, "v2-context");
|
|
26605
|
+
const replayMapped = input.mapped;
|
|
25741
26606
|
const keys = resolveLkgModelKeys(replayMapped.messages);
|
|
25742
26607
|
const replay = replayLkg({
|
|
25743
26608
|
sessionId: draft.sessionID,
|
|
@@ -25751,6 +26616,8 @@ ${baseline}
|
|
|
25751
26616
|
restoreLkgSystem();
|
|
25752
26617
|
replayMapped.messages.splice(0, replayMapped.messages.length, ...replay.messages);
|
|
25753
26618
|
replayMapped.commit();
|
|
26619
|
+
adoptReplay(input.draft);
|
|
26620
|
+
sessionLog(draft.sessionID, "lkg_replay_served");
|
|
25754
26621
|
return;
|
|
25755
26622
|
} else {
|
|
25756
26623
|
sessionLog(draft.sessionID, replay.reason);
|
|
@@ -25895,13 +26762,17 @@ ${baseline}
|
|
|
25895
26762
|
}, 0);
|
|
25896
26763
|
return {
|
|
25897
26764
|
async dispose() {
|
|
26765
|
+
usageController.abort();
|
|
26766
|
+
if (orphanSweepTimer)
|
|
26767
|
+
clearTimeout(orphanSweepTimer);
|
|
25898
26768
|
await hiddenCompletionExecutor?.dispose();
|
|
26769
|
+
await usageDone;
|
|
26770
|
+
await orphanSweep;
|
|
25899
26771
|
rpcStopped = true;
|
|
25900
26772
|
rpcServer.stop();
|
|
25901
26773
|
tools?.dispose();
|
|
25902
|
-
usageController.abort();
|
|
25903
|
-
await usageDone;
|
|
25904
26774
|
deletedSessions.clear();
|
|
26775
|
+
committedSourceRefreshes.clear();
|
|
25905
26776
|
for (const release of rawProviders.values())
|
|
25906
26777
|
release();
|
|
25907
26778
|
rawProviders.clear();
|