@retaw106/mmc-oc 2.3.0 → 2.4.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/cli.js +12 -1
- package/dist/config/schema/magic-context.d.ts +33 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/config-init.js +12 -1
- package/dist/{context-wt7g4f8k.js → context-c72brxe5.js} +717 -206
- package/dist/features/magic-context/memory-maintainer/launcher.d.ts +13 -4
- package/dist/features/magic-context/memory-maintainer/launcher.d.ts.map +1 -1
- package/dist/features/magic-context/memory-maintainer/manual-commands.d.ts.map +1 -1
- package/dist/features/magic-context/memory-maintainer/model-chain.d.ts +47 -0
- package/dist/features/magic-context/memory-maintainer/model-chain.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/oc2-adapter.d.ts +17 -4
- package/dist/features/magic-context/memory-maintainer/oc2-adapter.d.ts.map +1 -1
- package/dist/features/magic-context/memory-maintainer/pipeline.d.ts +6 -0
- package/dist/features/magic-context/memory-maintainer/pipeline.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +4 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +57 -2
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/hooks/magic-context/__fixtures__/tail-hygiene-refresh.d.ts +34 -0
- package/dist/hooks/magic-context/__fixtures__/tail-hygiene-refresh.d.ts.map +1 -0
- package/dist/hooks/magic-context/apply-operations.d.ts +3 -1
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +2 -2
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts +4 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger-error.d.ts +11 -0
- package/dist/hooks/magic-context/compartment-trigger-error.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +1 -0
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/degraded-pass-refusal.d.ts +2 -0
- package/dist/hooks/magic-context/degraded-pass-refusal.d.ts.map +1 -1
- package/dist/hooks/magic-context/edit-marker.d.ts +2 -0
- package/dist/hooks/magic-context/edit-marker.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +2 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/pending-drop-eligibility.d.ts +14 -0
- package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -0
- package/dist/hooks/magic-context/pending-materialization.d.ts +2 -0
- package/dist/hooks/magic-context/pending-materialization.d.ts.map +1 -1
- package/dist/hooks/magic-context/provider-visible-parts.d.ts +10 -4
- package/dist/hooks/magic-context/provider-visible-parts.d.ts.map +1 -1
- package/dist/hooks/magic-context/render-options.d.ts +19 -0
- package/dist/hooks/magic-context/render-options.d.ts.map +1 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts +5 -3
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-output-count.d.ts +18 -0
- package/dist/hooks/magic-context/tail-hygiene-output-count.d.ts.map +1 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +8 -4
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-reclaim.d.ts +5 -2
- package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +2 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +0 -7
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts +5 -1
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts.map +1 -1
- package/dist/{index-3gj1ak4c.js → index-27ddyx39.js} +1 -1
- package/dist/{index-z2w1eq3y.js → index-48e9znrc.js} +491 -197
- package/dist/{index-z2g20msd.js → index-azbmnekv.js} +4 -4
- package/dist/{index-czba8tw3.js → index-dwh99z66.js} +33 -10
- package/dist/{index-kw21z5pe.js → index-kahkxcqw.js} +7005 -6903
- package/dist/{index-a5mw0xp3.js → index-r7s7d350.js} +1 -1
- package/dist/{index-18yrysyj.js → index-ykq24x1n.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/{message-time-backfill-sykevdax.js → message-time-backfill-j96x1sab.js} +1 -1
- package/dist/model-resolution-cvyrrcjw.js +8 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{read-session-chunk-863d6c06.js → read-session-chunk-t8bg6wkz.js} +3 -3
- package/dist/{recomp-orchestrator-wrjy3qym.js → recomp-orchestrator-k760qy1n.js} +6 -6
- package/dist/{send-session-notification-cz6ev088.js → send-session-notification-njjf3b4s.js} +3 -3
- package/dist/shared/model-suggestion-retry.d.ts +21 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/prompt-surface-runtime.d.ts +5 -0
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/shared/reclaim-distance.d.ts +33 -0
- package/dist/shared/reclaim-distance.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +2 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/stable-json.d.ts +7 -0
- package/dist/shared/stable-json.d.ts.map +1 -1
- package/dist/shared/tail-hygiene-json.d.ts +22 -0
- package/dist/shared/tail-hygiene-json.d.ts.map +1 -0
- package/dist/shared/user-facing-codes.d.ts +2 -2
- package/dist/v2/hidden-completion.d.ts +20 -1
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/hidden-child.d.ts +22 -1
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
- package/dist/v2/server.js +8312 -7354
- package/dist/v2/store-reader.d.ts +27 -1
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/web/main.js +34 -10
- package/dist/{wrapup-orchestrator-bmybc5p5.js → wrapup-orchestrator-b2gswatj.js} +6 -6
- package/package.json +1 -1
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/config/project-security.test.ts +17 -0
- package/src/config/schema/magic-context.test.ts +50 -0
- package/src/config/schema/magic-context.ts +34 -1
- package/src/shared/model-suggestion-retry.ts +5 -1
- package/src/shared/prompt-surface-runtime.ts +12 -0
- package/src/shared/reclaim-distance.test.ts +111 -0
- package/src/shared/reclaim-distance.ts +91 -0
- package/src/shared/root-async-context.probe.mjs +36 -0
- package/src/shared/root-async-context.test.ts +49 -0
- package/src/shared/sqlite-busy-budget-review.test.ts +291 -0
- package/src/shared/sqlite-foreground-wait.test.ts +237 -1
- package/src/shared/sqlite.ts +55 -14
- package/src/shared/stable-json.ts +56 -14
- package/src/shared/tail-hygiene-json.test.ts +117 -0
- package/src/shared/tail-hygiene-json.ts +217 -0
- package/src/shared/user-facing-codes.ts +2 -2
- package/dist/model-resolution-wazv26n0.js +0 -6
|
@@ -34,6 +34,19 @@ import {
|
|
|
34
34
|
resolveProjectIdentityForSession,
|
|
35
35
|
normalizeStoredProjectPath,
|
|
36
36
|
storedPathBelongsToIdentity,
|
|
37
|
+
parseProviderModel,
|
|
38
|
+
modelBodyField,
|
|
39
|
+
toModelEntry,
|
|
40
|
+
HiddenCompletionRefusal,
|
|
41
|
+
HIDDEN_HISTORIAN_AGENT,
|
|
42
|
+
resolveHistorianStepCap,
|
|
43
|
+
HIDDEN_RUN_DISPOSED_REASON,
|
|
44
|
+
noteChildOfDisposedInstance,
|
|
45
|
+
hiddenChildPermissions,
|
|
46
|
+
registerHiddenChildAgents,
|
|
47
|
+
HiddenAgentStepLimit,
|
|
48
|
+
HiddenChildHook,
|
|
49
|
+
isNonRetryable,
|
|
37
50
|
V2_MEMORY_CATEGORIES,
|
|
38
51
|
CATEGORY_PRIORITY,
|
|
39
52
|
computeNormalizedHash,
|
|
@@ -97,6 +110,7 @@ import {
|
|
|
97
110
|
HYGIENE_PROVIDER_UNITS_VERSION,
|
|
98
111
|
sessionDecisionCalibration,
|
|
99
112
|
transitionSessionHygieneUnits,
|
|
113
|
+
readEpochFloorSnapshot,
|
|
100
114
|
getProtectionWindowForSession,
|
|
101
115
|
ReplayDocumentError,
|
|
102
116
|
readReplayEnvelope,
|
|
@@ -183,6 +197,7 @@ import {
|
|
|
183
197
|
clearSession,
|
|
184
198
|
requestPendingMaterialization,
|
|
185
199
|
pendingMaterializationOrigin,
|
|
200
|
+
hasPendingMaterializationOrigin,
|
|
186
201
|
clearPendingMaterialization,
|
|
187
202
|
recordSystemPromptForRequest,
|
|
188
203
|
recordHeldHeadForRequest,
|
|
@@ -242,18 +257,10 @@ import {
|
|
|
242
257
|
sourceNameForMemory,
|
|
243
258
|
rebaseSessionCoordinatesAsync,
|
|
244
259
|
renderUserFacingFailure,
|
|
260
|
+
userFacingFailureCode,
|
|
245
261
|
renderCapabilityRefusal,
|
|
246
|
-
HiddenCompletionRefusal,
|
|
247
|
-
HIDDEN_HISTORIAN_AGENT,
|
|
248
|
-
resolveHistorianStepCap,
|
|
249
|
-
hiddenChildPermissions,
|
|
250
|
-
registerHiddenChildAgents,
|
|
251
|
-
HiddenAgentStepLimit,
|
|
252
|
-
HiddenChildHook,
|
|
253
|
-
parseProviderModel,
|
|
254
|
-
toModelEntry,
|
|
255
262
|
ACTIVE_TOOL_IDS,
|
|
256
|
-
|
|
263
|
+
systemPromptFingerprint,
|
|
257
264
|
createPromptSurfaceRuntime,
|
|
258
265
|
createPromptSurfaceGuidanceEpochCache,
|
|
259
266
|
getOpenCodeDbPath,
|
|
@@ -294,7 +301,7 @@ import {
|
|
|
294
301
|
recordHighPressureNoEligibleHead,
|
|
295
302
|
getActiveCompartmentRun,
|
|
296
303
|
startCompartmentAgent
|
|
297
|
-
} from "./index-
|
|
304
|
+
} from "./index-kahkxcqw.js";
|
|
298
305
|
import {
|
|
299
306
|
getHarness,
|
|
300
307
|
getDataDir,
|
|
@@ -326,6 +333,16 @@ import {
|
|
|
326
333
|
import {
|
|
327
334
|
normalizeProtectedToolName,
|
|
328
335
|
mergeProtectedTools,
|
|
336
|
+
detectLatestTurnThinkingMismatch,
|
|
337
|
+
isPrefixBoundThinkingModel,
|
|
338
|
+
detectOverflow,
|
|
339
|
+
stripWellFormedLeadingTagPrefix,
|
|
340
|
+
stripPersistedAssistantText,
|
|
341
|
+
byteSize,
|
|
342
|
+
stripTagPrefix,
|
|
343
|
+
peelLeadingMcTagNotation,
|
|
344
|
+
prependTag,
|
|
345
|
+
isThinkingPart,
|
|
329
346
|
isRecord,
|
|
330
347
|
protectedToolTagNumbers,
|
|
331
348
|
protectedToolTokenCount,
|
|
@@ -335,13 +352,7 @@ import {
|
|
|
335
352
|
preloadTokenizer,
|
|
336
353
|
estimateTokens,
|
|
337
354
|
estimateFixedPromptTokens,
|
|
338
|
-
|
|
339
|
-
stripPersistedAssistantText,
|
|
340
|
-
byteSize,
|
|
341
|
-
stripTagPrefix,
|
|
342
|
-
peelLeadingMcTagNotation,
|
|
343
|
-
prependTag,
|
|
344
|
-
isThinkingPart,
|
|
355
|
+
currentReclaimableToolOutputCount,
|
|
345
356
|
contentTagOwnerMessageId,
|
|
346
357
|
estimateImageTokensFromDataUrl,
|
|
347
358
|
estimateToolAttachmentImageTokens,
|
|
@@ -374,6 +385,7 @@ import {
|
|
|
374
385
|
getPendingOpsCount,
|
|
375
386
|
clearPendingOps,
|
|
376
387
|
removePendingOp,
|
|
388
|
+
tagRevisionKey,
|
|
377
389
|
tagIdentityRevisionKey,
|
|
378
390
|
getRecentTagOwnerMessageIds,
|
|
379
391
|
AGE_RECLAIM_MIN_TOKENS,
|
|
@@ -390,6 +402,7 @@ import {
|
|
|
390
402
|
backfillTagTokenCounts,
|
|
391
403
|
insertTag,
|
|
392
404
|
updateTagStatus,
|
|
405
|
+
markTagDropped,
|
|
393
406
|
markWhitespaceAssistantTagInert,
|
|
394
407
|
getInertWhitespaceAssistantTags,
|
|
395
408
|
getInertWhitespaceAssistantTagsByNumbers,
|
|
@@ -431,13 +444,11 @@ import {
|
|
|
431
444
|
recordToolDefinition,
|
|
432
445
|
getMeasuredToolDefinitionTokens,
|
|
433
446
|
describeFinalWireTail,
|
|
447
|
+
estimatePartImageTokens,
|
|
434
448
|
estimateMessageTokens,
|
|
435
449
|
wireContentBytes,
|
|
436
450
|
createFinalWireUsageTracker,
|
|
437
451
|
estimateFinalWireInputTokens,
|
|
438
|
-
detectLatestTurnThinkingMismatch,
|
|
439
|
-
isPrefixBoundThinkingModel,
|
|
440
|
-
detectOverflow,
|
|
441
452
|
modelAcceptsEmptyContent,
|
|
442
453
|
isAnthropicFamilyRoute,
|
|
443
454
|
neutralizeDroppedReasoningPart,
|
|
@@ -463,9 +474,14 @@ import {
|
|
|
463
474
|
primeTailRawMessageCache2,
|
|
464
475
|
primeInMemoryTailRawMessageCache2,
|
|
465
476
|
readRawSessionMessageIdOrdinalsForRange2,
|
|
477
|
+
hasRawSessionMessageById2,
|
|
466
478
|
readRawSessionMessageById2,
|
|
467
479
|
readSessionChunk2
|
|
468
|
-
} from "./index-
|
|
480
|
+
} from "./index-48e9znrc.js";
|
|
481
|
+
import {
|
|
482
|
+
normalizeModelEntry2,
|
|
483
|
+
resolveHistorianModel2
|
|
484
|
+
} from "./index-azbmnekv.js";
|
|
469
485
|
import {
|
|
470
486
|
getSqliteMemoryStats,
|
|
471
487
|
withSqliteBackgroundWriter,
|
|
@@ -476,7 +492,7 @@ import {
|
|
|
476
492
|
withAsyncPrivilegedWriter,
|
|
477
493
|
indexCoordinationInput,
|
|
478
494
|
withIndexChunk
|
|
479
|
-
} from "./index-
|
|
495
|
+
} from "./index-dwh99z66.js";
|
|
480
496
|
import {
|
|
481
497
|
canonicalModelIdentity,
|
|
482
498
|
piModelRefToCanonical,
|
|
@@ -493,7 +509,7 @@ import {
|
|
|
493
509
|
latestRealUserTurnIdFromOpenCodeDb,
|
|
494
510
|
getMessageTimesFromOpenCodeDb,
|
|
495
511
|
findLastAssistantModelFromOpenCodeDb
|
|
496
|
-
} from "./index-
|
|
512
|
+
} from "./index-ykq24x1n.js";
|
|
497
513
|
import {
|
|
498
514
|
registerNotificationSink2,
|
|
499
515
|
pushNotification2,
|
|
@@ -506,10 +522,7 @@ import {
|
|
|
506
522
|
getErrorMessage,
|
|
507
523
|
flushIgnoredMessages2,
|
|
508
524
|
sendStatusNotification2
|
|
509
|
-
} from "./index-
|
|
510
|
-
import {
|
|
511
|
-
resolveHistorianModel2
|
|
512
|
-
} from "./index-z2g20msd.js";
|
|
525
|
+
} from "./index-r7s7d350.js";
|
|
513
526
|
import {
|
|
514
527
|
logSlowWriteTransaction
|
|
515
528
|
} from "./index-yjv8dpht.js";
|
|
@@ -3159,6 +3172,40 @@ function currentPluginConfigReader(directory) {
|
|
|
3159
3172
|
return pluginReaders.get(directory);
|
|
3160
3173
|
}
|
|
3161
3174
|
|
|
3175
|
+
// src/features/magic-context/memory-maintainer/model-chain.ts
|
|
3176
|
+
var MAINTENANCE_MODEL_UNCONFIGURED_MESSAGE = "memory maintenance has no primary model configured — set maintenance.model or historian.model in the user-level mmc config (fallback_models alone does not enable maintenance; the session model is never inherited)";
|
|
3177
|
+
function inheritMaintenanceModelConfig(config) {
|
|
3178
|
+
const { maintenance, historian } = config;
|
|
3179
|
+
if (maintenance.model !== undefined || historian?.model === undefined)
|
|
3180
|
+
return maintenance;
|
|
3181
|
+
const entry = typeof historian.model === "string" ? { model: historian.model } : historian.model;
|
|
3182
|
+
return {
|
|
3183
|
+
...maintenance,
|
|
3184
|
+
model: {
|
|
3185
|
+
...entry,
|
|
3186
|
+
variant: entry.variant ?? historian.variant,
|
|
3187
|
+
thinking_level: entry.thinking_level ?? historian.thinking_level
|
|
3188
|
+
},
|
|
3189
|
+
fallback_models: maintenance.fallback_models ?? historian.fallback_models
|
|
3190
|
+
};
|
|
3191
|
+
}
|
|
3192
|
+
function resolveMaintenanceModelChain(config, harness) {
|
|
3193
|
+
const primary = normalizeModelEntry2(config.model, harness);
|
|
3194
|
+
if (!primary)
|
|
3195
|
+
return;
|
|
3196
|
+
const fallbacks = [];
|
|
3197
|
+
for (const entry of config.fallback_models ?? []) {
|
|
3198
|
+
const resolved = normalizeModelEntry2(entry, harness);
|
|
3199
|
+
if (resolved)
|
|
3200
|
+
fallbacks.push(resolved);
|
|
3201
|
+
}
|
|
3202
|
+
return { primary, fallbacks };
|
|
3203
|
+
}
|
|
3204
|
+
function hasMaintenancePrimary(config) {
|
|
3205
|
+
const primary = toModelEntry(config.model);
|
|
3206
|
+
return primary !== undefined && primary.model.trim().length > 0;
|
|
3207
|
+
}
|
|
3208
|
+
|
|
3162
3209
|
// src/features/magic-context/memory-maintainer/dream-state.ts
|
|
3163
3210
|
var getDreamStateStatements = new WeakMap;
|
|
3164
3211
|
var setDreamStateStatements = new WeakMap;
|
|
@@ -4500,6 +4547,7 @@ async function executeGuardedRun(opts, holderId, leaseKey, acquisition) {
|
|
|
4500
4547
|
pending,
|
|
4501
4548
|
fullPool: roundState.snapshot,
|
|
4502
4549
|
shouldContinue: () => meter.shouldContinue(),
|
|
4550
|
+
remainingWallMs: () => Math.max(0, config.budgets.wallMs - meter.getState().spent.wallMs),
|
|
4503
4551
|
recordUsage: (delta) => meter.recordUsage(delta),
|
|
4504
4552
|
recordToolStep: () => meter.recordToolStep(),
|
|
4505
4553
|
refuseToolStep: () => meter.refuseToolStep()
|
|
@@ -4798,49 +4846,86 @@ function transcriptFromCompletion(completion, createdAt) {
|
|
|
4798
4846
|
}
|
|
4799
4847
|
];
|
|
4800
4848
|
}
|
|
4801
|
-
async function
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4849
|
+
async function attemptPhaseModelChain(ctx, phase, executor, deps, agentId, system, prompt) {
|
|
4850
|
+
const chain = [deps.modelChain.primary, ...deps.modelChain.fallbacks];
|
|
4851
|
+
let lastError;
|
|
4852
|
+
for (let index = 0;index < chain.length; index += 1) {
|
|
4853
|
+
const entry = toModelEntry(chain[index]);
|
|
4854
|
+
if (!entry || entry.model.trim().length === 0)
|
|
4855
|
+
continue;
|
|
4856
|
+
if (!parseProviderModel(entry.model)) {
|
|
4857
|
+
if (index === 0) {
|
|
4858
|
+
throw new Error(`memory maintenance: primary model "${entry.model}" is not in provider/model form — the hidden executor cannot use it and no model substitution is allowed`);
|
|
4859
|
+
}
|
|
4860
|
+
log(`[magic-context][maintenance] phase ${phase}: dropping invalid fallback spec: ${entry.model}`);
|
|
4861
|
+
continue;
|
|
4862
|
+
}
|
|
4863
|
+
if (index > 0) {
|
|
4864
|
+
if (ctx.shouldContinue() !== "continue")
|
|
4865
|
+
throw lastError;
|
|
4866
|
+
log(`[magic-context][maintenance] phase ${phase}: switching to fallback model ${entry.model} (attempt ${index + 1}/${chain.length})`);
|
|
4867
|
+
}
|
|
4816
4868
|
const identity = {
|
|
4817
4869
|
parentSessionId: deps.parentSessionId(),
|
|
4818
4870
|
kind: "memory-maintenance",
|
|
4819
4871
|
agent: agentId,
|
|
4820
4872
|
system,
|
|
4821
|
-
|
|
4873
|
+
model: entry,
|
|
4874
|
+
timeoutMs: Math.max(1000, Math.min(deps.budget.wallMs, ctx.remainingWallMs())),
|
|
4822
4875
|
title: `magic-context-maintainer-${phase.toLowerCase()}`,
|
|
4823
4876
|
directory: deps.directory() ?? ""
|
|
4824
4877
|
};
|
|
4825
|
-
const handle = await
|
|
4826
|
-
let completion;
|
|
4878
|
+
const handle = await executor.open(identity);
|
|
4827
4879
|
let promptSettled = false;
|
|
4828
4880
|
try {
|
|
4829
4881
|
const request = {
|
|
4830
4882
|
path: { id: handle.id },
|
|
4831
|
-
body: {
|
|
4883
|
+
body: {
|
|
4884
|
+
parts: [{ type: "text", text: prompt }],
|
|
4885
|
+
...modelBodyField(entry)
|
|
4886
|
+
}
|
|
4832
4887
|
};
|
|
4833
|
-
|
|
4834
|
-
|
|
4888
|
+
try {
|
|
4889
|
+
await executor.attempt(handle, request);
|
|
4890
|
+
} catch (error) {
|
|
4891
|
+
lastError = error;
|
|
4892
|
+
if (index >= chain.length - 1 || isNonRetryable(error))
|
|
4893
|
+
throw error;
|
|
4894
|
+
log(`[magic-context][maintenance] phase ${phase}: model ${entry.model} failed: ${error instanceof Error ? error.message : String(error)}; trying next fallback`);
|
|
4895
|
+
continue;
|
|
4896
|
+
}
|
|
4897
|
+
const completion = await executor.collect(handle, 50);
|
|
4835
4898
|
promptSettled = true;
|
|
4899
|
+
return completion;
|
|
4836
4900
|
} finally {
|
|
4837
|
-
await
|
|
4901
|
+
await executor.close(handle, {
|
|
4838
4902
|
promptSettled,
|
|
4839
4903
|
privacySensitive: false,
|
|
4840
4904
|
context: "memory-maintenance",
|
|
4841
4905
|
log: (message) => log(`[magic-context][maintenance] ${message}`)
|
|
4842
4906
|
});
|
|
4843
4907
|
}
|
|
4908
|
+
}
|
|
4909
|
+
if (lastError !== undefined)
|
|
4910
|
+
throw lastError;
|
|
4911
|
+
return;
|
|
4912
|
+
}
|
|
4913
|
+
async function runOc2MaintenancePhase(ctx, phase, deps, stageAManifest = "") {
|
|
4914
|
+
if (!deps.executor)
|
|
4915
|
+
return emptyPhaseResult();
|
|
4916
|
+
const agentId = phase === "A" ? MEMORY_MAINTAINER_A_AGENT : MEMORY_MAINTAINER_B_AGENT;
|
|
4917
|
+
const system = phase === "A" ? MEMORY_MAINTAINER_A_SYSTEM_PROMPT : MEMORY_MAINTAINER_B_SYSTEM_PROMPT;
|
|
4918
|
+
const basePrompt = buildPhasePrompt(ctx, phase, deps, stageAManifest);
|
|
4919
|
+
let manifestText = "";
|
|
4920
|
+
let messages;
|
|
4921
|
+
for (let round = 0;round < 2; round += 1) {
|
|
4922
|
+
const decision = ctx.shouldContinue();
|
|
4923
|
+
if (decision === "stop")
|
|
4924
|
+
break;
|
|
4925
|
+
const prompt = decision === "finalize" ? `${MEMORY_MAINTAINER_FINALIZE_INSTRUCTION}
|
|
4926
|
+
|
|
4927
|
+
${basePrompt}` : basePrompt;
|
|
4928
|
+
const completion = await attemptPhaseModelChain(ctx, phase, deps.executor, deps, agentId, system, prompt);
|
|
4844
4929
|
if (completion) {
|
|
4845
4930
|
const inputTotal = completion.usage.input + completion.usage.cacheRead + completion.usage.cacheWrite;
|
|
4846
4931
|
ctx.recordUsage({ inputTokens: inputTotal, outputTokens: completion.usage.output });
|
|
@@ -4898,9 +4983,18 @@ function createOc2MaintenanceRunFactory(options) {
|
|
|
4898
4983
|
if (!options.executor) {
|
|
4899
4984
|
throw new Error("memory maintenance: no hidden completion executor wired");
|
|
4900
4985
|
}
|
|
4986
|
+
const chain = resolveMaintenanceModelChain(options.config(), "opencode");
|
|
4987
|
+
if (!chain) {
|
|
4988
|
+
throw new Error(MAINTENANCE_MODEL_UNCONFIGURED_MESSAGE);
|
|
4989
|
+
}
|
|
4990
|
+
const primarySpec = toModelEntry(chain.primary)?.model ?? "";
|
|
4991
|
+
if (!parseProviderModel(primarySpec)) {
|
|
4992
|
+
throw new Error(`memory maintenance: primary model "${primarySpec}" is not in provider/model form — the hidden executor cannot use it and no model substitution is allowed`);
|
|
4993
|
+
}
|
|
4901
4994
|
const cfg = options.config();
|
|
4902
4995
|
const phaseDeps = {
|
|
4903
4996
|
executor: options.executor,
|
|
4997
|
+
modelChain: chain,
|
|
4904
4998
|
budget: cfg.budgets,
|
|
4905
4999
|
parentSessionId: () => signals.parentSessionId,
|
|
4906
5000
|
directory: () => signals.directory,
|
|
@@ -6160,6 +6254,20 @@ function resolveTodowriteAvailability(sessionId) {
|
|
|
6160
6254
|
}
|
|
6161
6255
|
|
|
6162
6256
|
// src/hooks/magic-context/degraded-pass-refusal.ts
|
|
6257
|
+
function describeDegradedPassFailure(site, cause) {
|
|
6258
|
+
const details = [site];
|
|
6259
|
+
const seen = new Set;
|
|
6260
|
+
while (cause !== undefined && cause !== null && !seen.has(cause)) {
|
|
6261
|
+
seen.add(cause);
|
|
6262
|
+
const current = cause;
|
|
6263
|
+
const detail = typeof current.site === "string" ? current.site : typeof current.message === "string" ? current.message : String(cause);
|
|
6264
|
+
if (!details.includes(detail))
|
|
6265
|
+
details.push(detail);
|
|
6266
|
+
cause = current.cause;
|
|
6267
|
+
}
|
|
6268
|
+
return `Magic Context could not safely prepare this turn [${userFacingFailureCode("transform_pass_degraded")}] (${details.join(": ")}). This request was not sent.`;
|
|
6269
|
+
}
|
|
6270
|
+
|
|
6163
6271
|
class DegradedPassRefusalError extends Error {
|
|
6164
6272
|
site;
|
|
6165
6273
|
code = "DEGRADED_PASS_REFUSAL";
|
|
@@ -6167,7 +6275,7 @@ class DegradedPassRefusalError extends Error {
|
|
|
6167
6275
|
estimatedTokens;
|
|
6168
6276
|
contextLimitTokens;
|
|
6169
6277
|
constructor(site, options) {
|
|
6170
|
-
super(
|
|
6278
|
+
super(describeDegradedPassFailure(site, options?.cause), {
|
|
6171
6279
|
cause: options?.cause
|
|
6172
6280
|
});
|
|
6173
6281
|
this.site = site;
|
|
@@ -8776,7 +8884,7 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
|
|
|
8776
8884
|
setChannel1NudgeState(args.db, sessionId, nextNudgeState);
|
|
8777
8885
|
return;
|
|
8778
8886
|
}
|
|
8779
|
-
out.output += buildChannel1Reminder(decision.level, decision.undroppedTokens,
|
|
8887
|
+
out.output += buildChannel1Reminder(decision.level, decision.undroppedTokens, currentReclaimableToolOutputCount(state), state.oldestReclaimableToolTags, decision.sticky);
|
|
8780
8888
|
setChannel1NudgeState(args.db, sessionId, {
|
|
8781
8889
|
...nextNudgeState,
|
|
8782
8890
|
ordinal: state.realUserTurnCount
|
|
@@ -10008,9 +10116,6 @@ class StorageBusyRefusalError extends Error {
|
|
|
10008
10116
|
}
|
|
10009
10117
|
}
|
|
10010
10118
|
|
|
10011
|
-
// src/hooks/magic-context/system-prompt-hash.ts
|
|
10012
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
10013
|
-
|
|
10014
10119
|
// src/agents/magic-context-prompt.ts
|
|
10015
10120
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
10016
10121
|
|
|
@@ -10152,6 +10257,90 @@ ${BASE_INTRO(memoryEnabled, temporalAwarenessEnabled)}${cavemanWarning}
|
|
|
10152
10257
|
${SELF_TAG_GUIDANCE}${languageGuidance}`;
|
|
10153
10258
|
}
|
|
10154
10259
|
|
|
10260
|
+
// src/features/magic-context/transform-decision-log.ts
|
|
10261
|
+
var canonicalReasons = new Set([
|
|
10262
|
+
"system_hash",
|
|
10263
|
+
"model_change",
|
|
10264
|
+
"ttl_idle",
|
|
10265
|
+
"explicit_flush",
|
|
10266
|
+
"max_mutation_id",
|
|
10267
|
+
"first_render",
|
|
10268
|
+
"pressure_refold",
|
|
10269
|
+
"upgrade_state",
|
|
10270
|
+
"cached_m1_missing",
|
|
10271
|
+
"project_change",
|
|
10272
|
+
"compartment_render_epoch",
|
|
10273
|
+
"m1_delta",
|
|
10274
|
+
"ttl_expiry",
|
|
10275
|
+
"epoch_change",
|
|
10276
|
+
"coverage_fold",
|
|
10277
|
+
"profile_transition",
|
|
10278
|
+
"host_compaction"
|
|
10279
|
+
]);
|
|
10280
|
+
var piReasonAliases = {
|
|
10281
|
+
pending_mutations: "max_mutation_id",
|
|
10282
|
+
renderer_upgrade: "upgrade_state",
|
|
10283
|
+
cache_invalid: "cached_m1_missing",
|
|
10284
|
+
drift: "pressure_refold"
|
|
10285
|
+
};
|
|
10286
|
+
var sharedReasonAliases = {
|
|
10287
|
+
model_key: "model_change",
|
|
10288
|
+
pressure: "pressure_refold"
|
|
10289
|
+
};
|
|
10290
|
+
var pendingDecisionBySession = new Map;
|
|
10291
|
+
var pendingPiDecisionBySession = new Map;
|
|
10292
|
+
var lastBoundMessageIdBySession = new Map;
|
|
10293
|
+
var scheduledWriteTokensBySession = new Map;
|
|
10294
|
+
var systemHashChangedSessions = new Set;
|
|
10295
|
+
var piSystemHashChangedSessions = new Set;
|
|
10296
|
+
var unbustedPassBySession = new Map;
|
|
10297
|
+
var newestInputAssistantBySession = new Map;
|
|
10298
|
+
var stagedV2DecisionBySession = new Map;
|
|
10299
|
+
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
10300
|
+
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
10301
|
+
if (raw.length > 0) {
|
|
10302
|
+
const alias = sharedReasonAliases[raw] ?? (harness === "pi" ? piReasonAliases[raw] : undefined) ?? undefined;
|
|
10303
|
+
if (alias)
|
|
10304
|
+
return alias;
|
|
10305
|
+
if (canonicalReasons.has(raw))
|
|
10306
|
+
return raw;
|
|
10307
|
+
return null;
|
|
10308
|
+
}
|
|
10309
|
+
return rematerialized ? "pressure_refold" : null;
|
|
10310
|
+
}
|
|
10311
|
+
function clearOpenCodePendingTransformDecision(sessionId, inputMessages) {
|
|
10312
|
+
pendingDecisionBySession.delete(sessionId);
|
|
10313
|
+
unbustedPassBySession.delete(sessionId);
|
|
10314
|
+
if (!inputMessages)
|
|
10315
|
+
return;
|
|
10316
|
+
let newestAssistant = "";
|
|
10317
|
+
for (const message of inputMessages) {
|
|
10318
|
+
const id = message.info?.id;
|
|
10319
|
+
if (message.info?.role !== "assistant" || typeof id !== "string")
|
|
10320
|
+
continue;
|
|
10321
|
+
if (id > newestAssistant)
|
|
10322
|
+
newestAssistant = id;
|
|
10323
|
+
}
|
|
10324
|
+
newestInputAssistantBySession.set(sessionId, newestAssistant);
|
|
10325
|
+
}
|
|
10326
|
+
function noteSystemPromptHashChange(sessionId) {
|
|
10327
|
+
systemHashChangedSessions.add(sessionId);
|
|
10328
|
+
}
|
|
10329
|
+
function noteOpenCodeUnbustedPass(sessionId, decision) {
|
|
10330
|
+
unbustedPassBySession.set(sessionId, decision);
|
|
10331
|
+
}
|
|
10332
|
+
var IDLE_EXPIRY_REASONS = new Set([
|
|
10333
|
+
"ttl_idle",
|
|
10334
|
+
"ttl_expiry"
|
|
10335
|
+
]);
|
|
10336
|
+
function recordPendingTransformDecision(sessionId, decision) {
|
|
10337
|
+
if (!decision.bustedThisPass) {
|
|
10338
|
+
pendingDecisionBySession.delete(sessionId);
|
|
10339
|
+
return;
|
|
10340
|
+
}
|
|
10341
|
+
pendingDecisionBySession.set(sessionId, decision);
|
|
10342
|
+
}
|
|
10343
|
+
|
|
10155
10344
|
// src/hooks/magic-context/system-prompt-dates.ts
|
|
10156
10345
|
function replaceHostDates(prompt, replace) {
|
|
10157
10346
|
const fields = /<(plugin-env|environment|env)>[\s\S]*?<\/\1>|Today's date: [^\r\n<]+/g;
|
|
@@ -10398,7 +10587,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10398
10587
|
const dates = systemPromptDates(liveSystemContent, stickyDate);
|
|
10399
10588
|
const currentDate = dates.live;
|
|
10400
10589
|
const stableCandidate = dates.stable;
|
|
10401
|
-
const stableCandidateHash =
|
|
10590
|
+
const stableCandidateHash = systemPromptFingerprint(stableCandidate, promptSurface.preset);
|
|
10402
10591
|
const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
|
|
10403
10592
|
const rewritePermission = systemDateRefreshPermission(deps.historyRefreshSessions, dateRequest);
|
|
10404
10593
|
let deferredDateRefresh = false;
|
|
@@ -10412,7 +10601,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10412
10601
|
try {
|
|
10413
10602
|
const content = liveElements.join(`
|
|
10414
10603
|
`);
|
|
10415
|
-
const hash =
|
|
10604
|
+
const hash = systemPromptFingerprint(content, promptSurface.preset);
|
|
10416
10605
|
updateSessionMeta(deps.db, sessionId, {
|
|
10417
10606
|
systemPromptHash: hash,
|
|
10418
10607
|
cachedM0SystemHash: hash,
|
|
@@ -10452,7 +10641,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10452
10641
|
`);
|
|
10453
10642
|
if (!availability.frozen || !modelKey)
|
|
10454
10643
|
return;
|
|
10455
|
-
const currentHash =
|
|
10644
|
+
const currentHash = systemPromptFingerprint(systemContent, promptSurface.preset);
|
|
10456
10645
|
recordSystemPromptForRequest(sessionId, currentLkgRequestIdentity(sessionId), currentHash, deps.db, previousHash !== currentHash ? !deps.historyRefreshSessions.has(sessionId) : undefined, deps.historyRefreshSessions, deps.pendingMaterializationSessions);
|
|
10457
10646
|
if (!sessionMetaEarly) {
|
|
10458
10647
|
return;
|
|
@@ -10460,6 +10649,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
10460
10649
|
const sessionMeta = sessionMetaEarly;
|
|
10461
10650
|
if (previousHash !== "" && previousHash !== "0" && previousHash !== currentHash) {
|
|
10462
10651
|
sessionLog(sessionId, `system prompt hash changed: ${previousHash} → ${currentHash} (len=${systemContent.length}), ${idleCacheExpired ? "adopting on idle-expired request" : requestMessagesFinal ? "adopting on the request whose messages are already final" : "triggering flush"}`);
|
|
10652
|
+
noteSystemPromptHashChange(sessionId);
|
|
10463
10653
|
if (!adoptSystemChange) {
|
|
10464
10654
|
deps.historyRefreshSessions.add(sessionId);
|
|
10465
10655
|
deps.systemPromptRefreshSessions.add(sessionId);
|
|
@@ -10520,10 +10710,16 @@ class MaintenanceLauncher {
|
|
|
10520
10710
|
constructor(deps) {
|
|
10521
10711
|
this.deps = deps;
|
|
10522
10712
|
}
|
|
10713
|
+
modelConfigured() {
|
|
10714
|
+
return hasMaintenancePrimary(this.deps.getConfig().maintenance);
|
|
10715
|
+
}
|
|
10523
10716
|
maybeLaunch(signals) {
|
|
10524
10717
|
if (!this.deps.getConfig().maintenance.enabled) {
|
|
10525
10718
|
return { launched: false, reason: "maintenance-disabled" };
|
|
10526
10719
|
}
|
|
10720
|
+
if (!this.modelConfigured()) {
|
|
10721
|
+
return { launched: false, reason: "maintenance-model-unconfigured" };
|
|
10722
|
+
}
|
|
10527
10723
|
if (this.runInFlight) {
|
|
10528
10724
|
return { launched: false, reason: "run-in-flight-local" };
|
|
10529
10725
|
}
|
|
@@ -10553,6 +10749,9 @@ class MaintenanceLauncher {
|
|
|
10553
10749
|
if (!this.deps.getConfig().maintenance.enabled) {
|
|
10554
10750
|
return { launched: false, reason: "maintenance-disabled" };
|
|
10555
10751
|
}
|
|
10752
|
+
if (!this.modelConfigured()) {
|
|
10753
|
+
return { launched: false, reason: "maintenance-model-unconfigured" };
|
|
10754
|
+
}
|
|
10556
10755
|
if (this.runInFlight) {
|
|
10557
10756
|
return { launched: false, reason: "run-in-flight-local" };
|
|
10558
10757
|
}
|
|
@@ -10692,63 +10891,6 @@ function hasRecordedSessionProjectIdentity(db, sessionId) {
|
|
|
10692
10891
|
return row?.found === 1;
|
|
10693
10892
|
}
|
|
10694
10893
|
|
|
10695
|
-
// src/features/magic-context/transform-decision-log.ts
|
|
10696
|
-
var canonicalReasons = new Set([
|
|
10697
|
-
"system_hash",
|
|
10698
|
-
"model_change",
|
|
10699
|
-
"ttl_idle",
|
|
10700
|
-
"explicit_flush",
|
|
10701
|
-
"max_mutation_id",
|
|
10702
|
-
"first_render",
|
|
10703
|
-
"pressure_refold",
|
|
10704
|
-
"upgrade_state",
|
|
10705
|
-
"cached_m1_missing",
|
|
10706
|
-
"project_change",
|
|
10707
|
-
"compartment_render_epoch",
|
|
10708
|
-
"m1_delta",
|
|
10709
|
-
"ttl_expiry",
|
|
10710
|
-
"epoch_change",
|
|
10711
|
-
"coverage_fold",
|
|
10712
|
-
"profile_transition",
|
|
10713
|
-
"host_compaction"
|
|
10714
|
-
]);
|
|
10715
|
-
var piReasonAliases = {
|
|
10716
|
-
pending_mutations: "max_mutation_id",
|
|
10717
|
-
renderer_upgrade: "upgrade_state",
|
|
10718
|
-
cache_invalid: "cached_m1_missing",
|
|
10719
|
-
drift: "pressure_refold"
|
|
10720
|
-
};
|
|
10721
|
-
var sharedReasonAliases = {
|
|
10722
|
-
model_key: "model_change",
|
|
10723
|
-
pressure: "pressure_refold"
|
|
10724
|
-
};
|
|
10725
|
-
var pendingDecisionBySession = new Map;
|
|
10726
|
-
var pendingPiDecisionBySession = new Map;
|
|
10727
|
-
var lastBoundMessageIdBySession = new Map;
|
|
10728
|
-
var scheduledWriteTokensBySession = new Map;
|
|
10729
|
-
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
10730
|
-
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
10731
|
-
if (raw.length > 0) {
|
|
10732
|
-
const alias = sharedReasonAliases[raw] ?? (harness === "pi" ? piReasonAliases[raw] : undefined) ?? undefined;
|
|
10733
|
-
if (alias)
|
|
10734
|
-
return alias;
|
|
10735
|
-
if (canonicalReasons.has(raw))
|
|
10736
|
-
return raw;
|
|
10737
|
-
return null;
|
|
10738
|
-
}
|
|
10739
|
-
return rematerialized ? "pressure_refold" : null;
|
|
10740
|
-
}
|
|
10741
|
-
function clearOpenCodePendingTransformDecision(sessionId) {
|
|
10742
|
-
pendingDecisionBySession.delete(sessionId);
|
|
10743
|
-
}
|
|
10744
|
-
function recordPendingTransformDecision(sessionId, decision) {
|
|
10745
|
-
if (!decision.bustedThisPass) {
|
|
10746
|
-
pendingDecisionBySession.delete(sessionId);
|
|
10747
|
-
return;
|
|
10748
|
-
}
|
|
10749
|
-
pendingDecisionBySession.set(sessionId, decision);
|
|
10750
|
-
}
|
|
10751
|
-
|
|
10752
10894
|
// src/hooks/magic-context/cache-busting-signals.ts
|
|
10753
10895
|
function canConsumeDeferredOnThisPass(args) {
|
|
10754
10896
|
if (args.justAwaitedPublication)
|
|
@@ -11422,12 +11564,12 @@ function buildTriggerInMemoryTail(db, sessionId, messages) {
|
|
|
11422
11564
|
function getProactiveCompartmentTriggerPercentage(executeThresholdPercentage) {
|
|
11423
11565
|
return Math.max(0, executeThresholdPercentage - PROACTIVE_TRIGGER_OFFSET_PERCENTAGE);
|
|
11424
11566
|
}
|
|
11425
|
-
function estimateProjectedPostDropPercentage(db, sessionId, usage, activeTags, keepReasoningTokens, clearedReasoningThroughTag, canClearReasoning, liveBudgetCutoff) {
|
|
11567
|
+
function estimateProjectedPostDropPercentage(db, sessionId, usage, activeTags, keepReasoningTokens, clearedReasoningThroughTag, canClearReasoning, liveBudgetCutoff, eligiblePendingDropTagIds) {
|
|
11426
11568
|
const totalActiveBytes = activeTags.reduce((sum, tag) => sum + tag.byteSize + tag.reasoningByteSize, 0);
|
|
11427
11569
|
if (totalActiveBytes === 0)
|
|
11428
11570
|
return null;
|
|
11429
11571
|
let droppableBytes = 0;
|
|
11430
|
-
const pendingDrops = getPendingOps(db, sessionId).filter((op) => op.operation === "drop");
|
|
11572
|
+
const pendingDrops = getPendingOps(db, sessionId).filter((op) => op.operation === "drop" && eligiblePendingDropTagIds?.has(op.tagId) === true);
|
|
11431
11573
|
const pendingDropTagIds = new Set(pendingDrops.map((op) => op.tagId));
|
|
11432
11574
|
if (pendingDrops.length > 0) {
|
|
11433
11575
|
droppableBytes += activeTags.filter((tag) => pendingDropTagIds.has(tag.tagNumber)).reduce((sum, tag) => sum + tag.byteSize + tag.reasoningByteSize, 0);
|
|
@@ -11555,7 +11697,7 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
11555
11697
|
function formatProjectedPostDropPercentage(value) {
|
|
11556
11698
|
return value === null ? "none" : `${value.toFixed(1)}%`;
|
|
11557
11699
|
}
|
|
11558
|
-
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, storedTotalsExcludeToolTags) {
|
|
11700
|
+
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds, storedTotalsExcludeToolTags) {
|
|
11559
11701
|
if (sessionMeta.compartmentInProgress) {
|
|
11560
11702
|
sessionLog(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
|
|
11561
11703
|
return { shouldFire: false };
|
|
@@ -11619,7 +11761,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
11619
11761
|
return { shouldFire: false };
|
|
11620
11762
|
}
|
|
11621
11763
|
const canClearReasoning = reasoningProjection?.canClearReasoning ?? modelAcceptsEmptyContent(reasoningProjection?.providerID);
|
|
11622
|
-
const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff);
|
|
11764
|
+
const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff, eligiblePendingDropTagIds);
|
|
11623
11765
|
const relativePostDropTarget = executeThresholdPercentage * POST_DROP_TARGET_RATIO;
|
|
11624
11766
|
const rideLabel = reclaimRide ? reclaimRideLabel(reclaimRide) : "ride=none";
|
|
11625
11767
|
const dropsCanLand = reclaimRide !== undefined && hasReclaimRide(reclaimRide);
|
|
@@ -11703,6 +11845,12 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
11703
11845
|
};
|
|
11704
11846
|
}
|
|
11705
11847
|
|
|
11848
|
+
// src/hooks/magic-context/compartment-trigger-error.ts
|
|
11849
|
+
function recordCompartmentTriggerError(passOutcome, sessionId, error, log = sessionLog) {
|
|
11850
|
+
passOutcome.record("compartment-trigger-failure");
|
|
11851
|
+
log(sessionId, "compartment trigger failed (non-fatal):", error);
|
|
11852
|
+
}
|
|
11853
|
+
|
|
11706
11854
|
// src/hooks/magic-context/pass-outcome.ts
|
|
11707
11855
|
var PASS_DEGRADATION_EFFECTS = {
|
|
11708
11856
|
"store-generation-rebase-failure": "changes-request",
|
|
@@ -11763,6 +11911,37 @@ function createPassOutcome() {
|
|
|
11763
11911
|
};
|
|
11764
11912
|
}
|
|
11765
11913
|
|
|
11914
|
+
// src/hooks/magic-context/render-options.ts
|
|
11915
|
+
function createM0RenderOptions(controls, contextUsage, modelKey, resolvedContextLimit, projectPath) {
|
|
11916
|
+
return {
|
|
11917
|
+
projectPath: controls.memoryConfig?.enabled ? projectPath : undefined,
|
|
11918
|
+
memoryEnabled: controls.memoryConfig?.enabled,
|
|
11919
|
+
memoryInjectionBudgetTokens: controls.memoryConfig?.injectionBudgetTokens,
|
|
11920
|
+
temporalAwareness: controls.experimentalTemporalAwareness,
|
|
11921
|
+
historyBudgetTokens: resolveHistoryBudgetTokens(controls.historyBudgetPercentage, contextUsage, controls.executeThresholdPercentage, modelKey, controls.executeThresholdTokens, resolvedContextLimit),
|
|
11922
|
+
historyBudgetPolicyIdentity: historyBudgetPolicyIdentity(controls.historyBudgetPercentage, controls.executeThresholdPercentage, modelKey, controls.executeThresholdTokens)
|
|
11923
|
+
};
|
|
11924
|
+
}
|
|
11925
|
+
function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, executeThresholdPercentage, modelKey, executeThresholdTokens, resolvedContextLimit) {
|
|
11926
|
+
if (!historyBudgetPercentage) {
|
|
11927
|
+
return;
|
|
11928
|
+
}
|
|
11929
|
+
let contextLimit = resolvedContextLimit && resolvedContextLimit > 0 ? resolvedContextLimit : 0;
|
|
11930
|
+
if (contextLimit <= 0) {
|
|
11931
|
+
if (contextUsage.percentage <= 0) {
|
|
11932
|
+
return;
|
|
11933
|
+
}
|
|
11934
|
+
contextLimit = contextUsage.inputTokens / (contextUsage.percentage / 100);
|
|
11935
|
+
}
|
|
11936
|
+
if (!Number.isFinite(contextLimit) || contextLimit <= 0) {
|
|
11937
|
+
return;
|
|
11938
|
+
}
|
|
11939
|
+
return Math.floor(contextLimit * (resolveExecuteThreshold(executeThresholdPercentage ?? 65, modelKey, 65, {
|
|
11940
|
+
tokensConfig: executeThresholdTokens,
|
|
11941
|
+
contextLimit
|
|
11942
|
+
}) / 100) * historyBudgetPercentage);
|
|
11943
|
+
}
|
|
11944
|
+
|
|
11766
11945
|
// src/hooks/magic-context/temporal-served-projection.ts
|
|
11767
11946
|
function readLkgTemporalDecisions(db, sessionId, runtime) {
|
|
11768
11947
|
const slot = getInMemorySlot(sessionId) ?? loadPersistedLkgSlot(db, sessionId);
|
|
@@ -11955,6 +12134,13 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
11955
12134
|
return snapshot !== null && hasRunnableCompartmentWindow(snapshot);
|
|
11956
12135
|
}
|
|
11957
12136
|
async function awaitCompartmentRun(activeRun, reason) {
|
|
12137
|
+
await Promise.resolve();
|
|
12138
|
+
if (activeRun.inlineJoinTimedOutBudgetMs !== undefined && !activeRun.settled) {
|
|
12139
|
+
historianJoinTimedOut = true;
|
|
12140
|
+
historianJoinBudgetMs = activeRun.inlineJoinTimedOutBudgetMs;
|
|
12141
|
+
sessionLog(args.sessionId, "transform: compartment inline join budget already exhausted for this run — not waiting again");
|
|
12142
|
+
return "timed_out";
|
|
12143
|
+
}
|
|
11958
12144
|
sessionLog(args.sessionId, reason);
|
|
11959
12145
|
const timeoutMs = resolveHistorianInlineJoinBudget(args.historianTimeoutMs);
|
|
11960
12146
|
historianJoinBudgetMs = timeoutMs;
|
|
@@ -11970,6 +12156,7 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
11970
12156
|
clearTimeout(timer);
|
|
11971
12157
|
}
|
|
11972
12158
|
if (result === "timeout") {
|
|
12159
|
+
activeRun.inlineJoinTimedOutBudgetMs = timeoutMs;
|
|
11973
12160
|
historianJoinTimedOut = true;
|
|
11974
12161
|
sessionLog(args.sessionId, `transform: compartment await timed out after ${timeoutMs}ms — proceeding without waiting`);
|
|
11975
12162
|
return "timed_out";
|
|
@@ -12177,6 +12364,76 @@ function resolveSchedulerDecision(scheduler, sessionMeta, contextUsage, sessionI
|
|
|
12177
12364
|
}
|
|
12178
12365
|
}
|
|
12179
12366
|
|
|
12367
|
+
// src/hooks/magic-context/pending-drop-eligibility.ts
|
|
12368
|
+
function pendingDropVeto(tagNumber, target, protectedTagIds) {
|
|
12369
|
+
if (protectedTagIds.has(tagNumber))
|
|
12370
|
+
return "protected";
|
|
12371
|
+
if (target?.thinkingDropProtected)
|
|
12372
|
+
return "active_thinking";
|
|
12373
|
+
return null;
|
|
12374
|
+
}
|
|
12375
|
+
function capturePendingDropEligibility(targets, protectedTagIds) {
|
|
12376
|
+
const eligible = new Set;
|
|
12377
|
+
for (const [number, target] of targets) {
|
|
12378
|
+
if (pendingDropVeto(number, target, protectedTagIds))
|
|
12379
|
+
continue;
|
|
12380
|
+
if (target.drop) {
|
|
12381
|
+
if (target.canDrop?.() === true)
|
|
12382
|
+
eligible.add(number);
|
|
12383
|
+
} else {
|
|
12384
|
+
const content = target.getContent?.();
|
|
12385
|
+
if (typeof content === "string" && content.length > `[dropped §${number}§]`.length)
|
|
12386
|
+
eligible.add(number);
|
|
12387
|
+
}
|
|
12388
|
+
}
|
|
12389
|
+
return eligible;
|
|
12390
|
+
}
|
|
12391
|
+
function pendingDropEligibilityKey(db, sessionId, input, protectionInputs) {
|
|
12392
|
+
const digests = input.map((message) => message.contentDigest?.() ?? null);
|
|
12393
|
+
if (digests.some((digest) => digest === null))
|
|
12394
|
+
return null;
|
|
12395
|
+
const revision = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(tagRevisionKey(sessionId));
|
|
12396
|
+
if (!revision?.value)
|
|
12397
|
+
return null;
|
|
12398
|
+
return JSON.stringify([
|
|
12399
|
+
input.map((message, index) => [
|
|
12400
|
+
message.id,
|
|
12401
|
+
message.role,
|
|
12402
|
+
message.synthetic,
|
|
12403
|
+
digests[index]
|
|
12404
|
+
]),
|
|
12405
|
+
revision.value,
|
|
12406
|
+
readEpochFloorSnapshot(db, sessionId),
|
|
12407
|
+
sessionDecisionCalibration(db, sessionId).toolsRatio,
|
|
12408
|
+
loadProtectedTailMeta(db, sessionId),
|
|
12409
|
+
[...getMergedReasoningStrippedIds(db, sessionId)].sort(),
|
|
12410
|
+
[...getReasoningRemovalState(db, sessionId).messageIds].sort(),
|
|
12411
|
+
protectionInputs
|
|
12412
|
+
]);
|
|
12413
|
+
}
|
|
12414
|
+
function createPendingDropEligibilityCache() {
|
|
12415
|
+
const sessions = new Map;
|
|
12416
|
+
return {
|
|
12417
|
+
read(sessionId, key) {
|
|
12418
|
+
const previous = sessions.get(sessionId);
|
|
12419
|
+
if (key === null || previous?.key !== key) {
|
|
12420
|
+
sessions.delete(sessionId);
|
|
12421
|
+
return;
|
|
12422
|
+
}
|
|
12423
|
+
return previous.eligible;
|
|
12424
|
+
},
|
|
12425
|
+
record(sessionId, key, eligible) {
|
|
12426
|
+
sessions.delete(sessionId);
|
|
12427
|
+
if (key === null)
|
|
12428
|
+
return;
|
|
12429
|
+
const oldest = sessions.keys().next().value;
|
|
12430
|
+
if (sessions.size >= 64 && oldest !== undefined)
|
|
12431
|
+
sessions.delete(oldest);
|
|
12432
|
+
sessions.set(sessionId, { key, eligible: new Set(eligible) });
|
|
12433
|
+
}
|
|
12434
|
+
};
|
|
12435
|
+
}
|
|
12436
|
+
|
|
12180
12437
|
// src/hooks/magic-context/apply-operations.ts
|
|
12181
12438
|
var RECENT_TOOL_SKELETON_WINDOW = 20;
|
|
12182
12439
|
function buildReplacementContent(tagId) {
|
|
@@ -12285,7 +12542,7 @@ function renderConvertedToolSkeletons(targets, converted) {
|
|
|
12285
12542
|
}
|
|
12286
12543
|
return didMutate;
|
|
12287
12544
|
}
|
|
12288
|
-
function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete) {
|
|
12545
|
+
function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete, onEligibilitySnapshot) {
|
|
12289
12546
|
let didMutateMessage = false;
|
|
12290
12547
|
let diagnostics;
|
|
12291
12548
|
const reject = (reason) => {
|
|
@@ -12300,6 +12557,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12300
12557
|
}).immediate();
|
|
12301
12558
|
{
|
|
12302
12559
|
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
12560
|
+
onEligibilitySnapshot?.(capturePendingDropEligibility(targets, protectedTagIds));
|
|
12303
12561
|
const neededTagNumbers = new Set(pendingOps.map((op) => op.tagId));
|
|
12304
12562
|
for (const op of syntheticPendingOps)
|
|
12305
12563
|
neededTagNumbers.add(op.tagId);
|
|
@@ -12336,13 +12594,10 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12336
12594
|
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
12337
12595
|
continue;
|
|
12338
12596
|
}
|
|
12339
|
-
if (protectedTagIds.has(pendingOp.tagId)) {
|
|
12340
|
-
reject("protected");
|
|
12341
|
-
continue;
|
|
12342
|
-
}
|
|
12343
12597
|
const target = targets.get(pendingOp.tagId);
|
|
12344
|
-
|
|
12345
|
-
|
|
12598
|
+
const veto = pendingDropVeto(pendingOp.tagId, target, protectedTagIds);
|
|
12599
|
+
if (veto) {
|
|
12600
|
+
reject(veto);
|
|
12346
12601
|
continue;
|
|
12347
12602
|
}
|
|
12348
12603
|
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
@@ -12362,9 +12617,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
12362
12617
|
try {
|
|
12363
12618
|
db.transaction(() => {
|
|
12364
12619
|
startedAt = performance.now();
|
|
12365
|
-
|
|
12366
|
-
updateTagDropMode(db, sessionId, pendingOp.tagId, mode);
|
|
12367
|
-
updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
|
|
12620
|
+
markTagDropped(db, sessionId, pendingOp.tagId, mode);
|
|
12368
12621
|
if (!synthetic)
|
|
12369
12622
|
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
12370
12623
|
}).immediate();
|
|
@@ -13774,7 +14027,7 @@ function buildEditSupersessionReclaim(input) {
|
|
|
13774
14027
|
seenFile.add(filePath);
|
|
13775
14028
|
continue;
|
|
13776
14029
|
}
|
|
13777
|
-
if (input.recentMessageIds && (tag.toolOwnerMessageId === null || input.recentMessageIds.has(tag.toolOwnerMessageId))) {
|
|
14030
|
+
if (tag.tagNumber > input.watermark || input.recentMessageIds && (tag.toolOwnerMessageId === null || input.recentMessageIds.has(tag.toolOwnerMessageId))) {
|
|
13778
14031
|
continue;
|
|
13779
14032
|
}
|
|
13780
14033
|
if (realPendingTagIds.has(tag.tagNumber))
|
|
@@ -13822,6 +14075,51 @@ async function waitForTagOwners(db, sessionId, ratio, _waitMs = 250) {
|
|
|
13822
14075
|
return prewarmTagOwners(db, sessionId, ratio);
|
|
13823
14076
|
}
|
|
13824
14077
|
|
|
14078
|
+
// src/shared/reclaim-distance.ts
|
|
14079
|
+
var RECLAIM_DISTANCE_USER_TURNS = 3;
|
|
14080
|
+
var RECLAIM_DISTANCE_WINDOW_FRACTION = 0.25;
|
|
14081
|
+
function isReclaimUserTurn(args) {
|
|
14082
|
+
return args.role === "user" && !args.syntheticHead && !args.synthetic && !args.ignored && args.parts.some((part) => {
|
|
14083
|
+
if (part.synthetic || part.ignored)
|
|
14084
|
+
return false;
|
|
14085
|
+
if (part.kind !== "text" && part.kind !== "image" && part.kind !== "file")
|
|
14086
|
+
return false;
|
|
14087
|
+
if (part.kind !== "text")
|
|
14088
|
+
return true;
|
|
14089
|
+
return stripReclaimMcText(part.text ?? "").trim().length > 0;
|
|
14090
|
+
});
|
|
14091
|
+
}
|
|
14092
|
+
function stripReclaimMcText(text) {
|
|
14093
|
+
return text.replace(/^§\d+§\s*/, "").replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, (reminder) => /^(?:Your next step: call ctx_reduce on the outputs you've already used|Still unstamped:|Housekeeping: .* are reclaimable\. Stamp each output with ctx_reduce|.* are reclaimable\. Make a ctx_reduce pass now|.* are still unstamped\. Call ctx_reduce now)/.test(reminder.slice("<system-reminder>".length).trimStart()) ? "" : reminder).replace(/<instruction name="deferred_notes">[\s\S]*?<\/instruction>/g, "");
|
|
14094
|
+
}
|
|
14095
|
+
function farBehindToolBookmark(entries, usableWindow) {
|
|
14096
|
+
let newerTurns = 0;
|
|
14097
|
+
let newerTokens = 0;
|
|
14098
|
+
const farTags = [];
|
|
14099
|
+
let firstYoungTag = Infinity;
|
|
14100
|
+
const seenOutputs = new Set;
|
|
14101
|
+
const tokenDistance = usableWindow > 0 && Number.isFinite(usableWindow) ? usableWindow * RECLAIM_DISTANCE_WINDOW_FRACTION : Infinity;
|
|
14102
|
+
for (let index = entries.length - 1;index >= 0; index--) {
|
|
14103
|
+
const entry = entries[index];
|
|
14104
|
+
if (!entry)
|
|
14105
|
+
continue;
|
|
14106
|
+
const tag = entry.toolOutputTag;
|
|
14107
|
+
if (tag !== undefined && !seenOutputs.has(tag)) {
|
|
14108
|
+
seenOutputs.add(tag);
|
|
14109
|
+
if (newerTurns >= RECLAIM_DISTANCE_USER_TURNS || newerTokens >= tokenDistance) {
|
|
14110
|
+
farTags.push(tag);
|
|
14111
|
+
} else {
|
|
14112
|
+
firstYoungTag = Math.min(firstYoungTag, tag);
|
|
14113
|
+
}
|
|
14114
|
+
}
|
|
14115
|
+
if (entry.userTurn)
|
|
14116
|
+
newerTurns++;
|
|
14117
|
+
if (Number.isFinite(entry.tokens) && entry.tokens > 0)
|
|
14118
|
+
newerTokens += entry.tokens;
|
|
14119
|
+
}
|
|
14120
|
+
return farTags.reduce((bookmark, tag) => tag < firstYoungTag ? Math.max(bookmark, tag) : bookmark, 0);
|
|
14121
|
+
}
|
|
14122
|
+
|
|
13825
14123
|
// src/hooks/magic-context/tool-reclaim.ts
|
|
13826
14124
|
function buildSyntheticToolReclaimOps(input) {
|
|
13827
14125
|
const watermark = Math.max(0, input.watermark);
|
|
@@ -13853,10 +14151,74 @@ function buildSyntheticToolReclaimOps(input) {
|
|
|
13853
14151
|
}
|
|
13854
14152
|
return synthetic;
|
|
13855
14153
|
}
|
|
13856
|
-
function
|
|
13857
|
-
const
|
|
13858
|
-
advanceToolReclaimWatermark(db, sessionId,
|
|
13859
|
-
return
|
|
14154
|
+
function advanceToolReclaimWatermarkByDistance(db, sessionId, entries, usableWindow) {
|
|
14155
|
+
const bookmark = farBehindToolBookmark(entries, usableWindow);
|
|
14156
|
+
advanceToolReclaimWatermark(db, sessionId, bookmark);
|
|
14157
|
+
return bookmark;
|
|
14158
|
+
}
|
|
14159
|
+
function toolReclaimDistanceEntries(messages, targets) {
|
|
14160
|
+
const outputTags = new Map;
|
|
14161
|
+
for (const [tag, target] of targets) {
|
|
14162
|
+
for (const location of target.mutationParts ?? []) {
|
|
14163
|
+
const part = distancePart(location.part);
|
|
14164
|
+
if (part.kind === "tool_result" || part.kind === "tool")
|
|
14165
|
+
outputTags.set(location.part, tag);
|
|
14166
|
+
}
|
|
14167
|
+
}
|
|
14168
|
+
const entries = [];
|
|
14169
|
+
for (const message of messages) {
|
|
14170
|
+
const parts = message.parts.map(distancePart);
|
|
14171
|
+
let userTurn = isReclaimUserTurn({ ...message.info, parts });
|
|
14172
|
+
for (const [index, part] of parts.entries()) {
|
|
14173
|
+
const authored = isReclaimUserTurn({ role: "user", parts: [part] });
|
|
14174
|
+
entries.push({
|
|
14175
|
+
tokens: message.info.syntheticHead ? 0 : estimateTokens(stripReclaimMcText(part.text ?? "")) + part.imageTokens,
|
|
14176
|
+
userTurn: userTurn && authored,
|
|
14177
|
+
toolOutputTag: outputTags.get(message.parts[index])
|
|
14178
|
+
});
|
|
14179
|
+
if (authored)
|
|
14180
|
+
userTurn = false;
|
|
14181
|
+
}
|
|
14182
|
+
}
|
|
14183
|
+
return entries;
|
|
14184
|
+
}
|
|
14185
|
+
function distancePart(raw) {
|
|
14186
|
+
if (!raw || typeof raw !== "object")
|
|
14187
|
+
return { kind: "structural", imageTokens: 0 };
|
|
14188
|
+
const part = raw;
|
|
14189
|
+
const provenance = { synthetic: part.synthetic === true, ignored: part.ignored === true };
|
|
14190
|
+
if (typeof part.getText === "function") {
|
|
14191
|
+
const text = part.getText();
|
|
14192
|
+
return {
|
|
14193
|
+
...provenance,
|
|
14194
|
+
kind: String(part.kind),
|
|
14195
|
+
text: typeof text === "string" ? text : undefined,
|
|
14196
|
+
imageTokens: typeof part.imageTokens === "function" ? Number(part.imageTokens()) : 0
|
|
14197
|
+
};
|
|
14198
|
+
}
|
|
14199
|
+
const metadata = { ...provenance, imageTokens: estimatePartImageTokens(raw) };
|
|
14200
|
+
if (part.type === "tool") {
|
|
14201
|
+
const state = part.state;
|
|
14202
|
+
return {
|
|
14203
|
+
...metadata,
|
|
14204
|
+
kind: "tool",
|
|
14205
|
+
text: `${JSON.stringify(state?.input ?? {})}
|
|
14206
|
+
${typeof state?.output === "string" ? state.output : JSON.stringify(state?.output ?? "")}`
|
|
14207
|
+
};
|
|
14208
|
+
}
|
|
14209
|
+
if (part.type === "tool_use")
|
|
14210
|
+
return { ...metadata, kind: "tool_use", text: JSON.stringify(part.input ?? {}) };
|
|
14211
|
+
if (part.type === "tool_result")
|
|
14212
|
+
return {
|
|
14213
|
+
...metadata,
|
|
14214
|
+
kind: "tool_result",
|
|
14215
|
+
text: typeof part.content === "string" ? part.content : JSON.stringify(part.content ?? "")
|
|
14216
|
+
};
|
|
14217
|
+
return {
|
|
14218
|
+
...metadata,
|
|
14219
|
+
kind: String(part.type),
|
|
14220
|
+
text: typeof part.text === "string" ? part.text : typeof part.thinking === "string" ? part.thinking : undefined
|
|
14221
|
+
};
|
|
13860
14222
|
}
|
|
13861
14223
|
|
|
13862
14224
|
// src/hooks/magic-context/transform-postprocess-phase.ts
|
|
@@ -14187,6 +14549,25 @@ function finalizeMessageRepresentation(messages, resolvedProviderID, options) {
|
|
|
14187
14549
|
}
|
|
14188
14550
|
return { clearedParts, mergedReasoningParts };
|
|
14189
14551
|
}
|
|
14552
|
+
function legacyPublishedHeadChanged(args) {
|
|
14553
|
+
if (!args.pendingCompartmentInjection || !args.readLastServedMessages)
|
|
14554
|
+
return false;
|
|
14555
|
+
const served = args.readLastServedMessages();
|
|
14556
|
+
if (served === null)
|
|
14557
|
+
return true;
|
|
14558
|
+
const previous = served[0];
|
|
14559
|
+
if (!Array.isArray(previous?.parts) || !args.pendingCompartmentInjection)
|
|
14560
|
+
return false;
|
|
14561
|
+
const text = previous.parts.find((part) => typeof part === "object" && part !== null && ("type" in part) && part.type === "text" && ("text" in part))?.text;
|
|
14562
|
+
if (typeof text !== "string")
|
|
14563
|
+
return false;
|
|
14564
|
+
const block = `<session-history>
|
|
14565
|
+
${args.pendingCompartmentInjection.block}
|
|
14566
|
+
</session-history>`;
|
|
14567
|
+
return text !== block && !text.startsWith(`${block}
|
|
14568
|
+
|
|
14569
|
+
`);
|
|
14570
|
+
}
|
|
14190
14571
|
async function runPostTransformPhase(args) {
|
|
14191
14572
|
const tPostprocessSetup = performance.now();
|
|
14192
14573
|
const compactionOff = args.compactionOff === true;
|
|
@@ -14390,11 +14771,6 @@ async function runPostTransformPhase(args) {
|
|
|
14390
14771
|
}
|
|
14391
14772
|
sessionLog(args.sessionId, `m[0] HARD fold decision: reason=${m0MaterializeReason ?? foldDueDecision.reason ?? (foldExecutedThisPass ? "drift" : "soft_refresh")} executed=${foldExecutedThisPass} bustsServedPrefix=${foldBustsServedPrefixThisPass}`);
|
|
14392
14773
|
}
|
|
14393
|
-
if (args.normalizeRecoveryTail && (foldBustsServedPrefixThisPass || firstRenderBust)) {
|
|
14394
|
-
args.normalizeRecoveryTail();
|
|
14395
|
-
args.tags = getTagsBySession(args.db, args.sessionId);
|
|
14396
|
-
newTargets = protectNewTagMutations(args.messages, args.targets, retainedThinking, args.thinkingBindingRecoveryEnabledForModel === true);
|
|
14397
|
-
}
|
|
14398
14774
|
logTransformTiming(args.sessionId, "pp.prefixPreflight", tPostprocessSetup, `foldExecuted=${foldExecutedThisPass} m1Refreshed=${publishedM1RefreshedThisPass}`);
|
|
14399
14775
|
const tPassDecisions = performance.now();
|
|
14400
14776
|
const frontToolCandidates = args.tags.filter((tag) => tag.type === "tool" && tag.status === "active" && args.targets.get(tag.tagNumber)?.canDrop?.());
|
|
@@ -14421,13 +14797,19 @@ async function runPostTransformPhase(args) {
|
|
|
14421
14797
|
subagentExecute: !args.fullFeatureMode && args.schedulerDecision === "execute",
|
|
14422
14798
|
hardFold: foldBustsServedPrefixThisPass || firstRenderBust || idleExpiryRebuild,
|
|
14423
14799
|
force: emergencyDropEligible && (args.contextUsage.percentage >= 95 || getEmergencyInputSample(args.db, args.sessionId) === 0),
|
|
14424
|
-
explicitFlush: isExplicitFlush
|
|
14425
|
-
publishedHistory: publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && (args
|
|
14800
|
+
explicitFlush: isExplicitFlush && hasPendingMaterializationOrigin(args.pendingMaterializationSessions, args.sessionId, "user_flush"),
|
|
14801
|
+
publishedHistory: !prefixPreflightFailed && (publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && legacyPublishedHeadChanged(args))
|
|
14426
14802
|
};
|
|
14427
14803
|
const publishedWorkDrainAllowed = !compactionOff && (!activeThinkingPrefixHold || firstRenderBust || idleExpiryRebuild || emergencyDropEligible) && hasReclaimRide(rideSignals);
|
|
14428
14804
|
const shouldApplyPendingOps = publishedWorkDrainAllowed;
|
|
14429
14805
|
const shouldRunHeuristics = !compactionOff && publishedWorkDrainAllowed && (rideSignals.publishedHistory || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
|
|
14430
14806
|
const isCacheBustingPass = publishedWorkDrainAllowed;
|
|
14807
|
+
if (args.normalizeRecoveryTail && isCacheBustingPass) {
|
|
14808
|
+
args.normalizeRecoveryTail();
|
|
14809
|
+
args.tags = getTagsBySession(args.db, args.sessionId);
|
|
14810
|
+
newTargets = protectNewTagMutations(args.messages, args.targets, retainedThinking, args.thinkingBindingRecoveryEnabledForModel === true);
|
|
14811
|
+
}
|
|
14812
|
+
const reclaimDistance = isCacheBustingPass ? toolReclaimDistanceEntries(args.messages, args.targets) : [];
|
|
14431
14813
|
const canEditWholePrefix = isCacheBustingPass && !activeThinkingPrefixHold;
|
|
14432
14814
|
const previousTemporalDecisions = args.temporalCandidates && !compactionOff ? new Map([
|
|
14433
14815
|
...args.temporalObservedDecisions ?? [],
|
|
@@ -14570,7 +14952,7 @@ async function runPostTransformPhase(args) {
|
|
|
14570
14952
|
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, newTargets, new Set([
|
|
14571
14953
|
...args.contextUsage.percentage >= 95 ? [] : args.protectedTagIds,
|
|
14572
14954
|
...protectedToolTags
|
|
14573
|
-
]), undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
|
|
14955
|
+
]), undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction), undefined, args.onPendingDropEligibility);
|
|
14574
14956
|
if (pendingOpsDidMutate) {
|
|
14575
14957
|
droppedCount += pendingOps.length;
|
|
14576
14958
|
for (const pendingOp of pendingOps) {
|
|
@@ -14773,6 +15155,7 @@ async function runPostTransformPhase(args) {
|
|
|
14773
15155
|
}
|
|
14774
15156
|
}
|
|
14775
15157
|
const editReclaim = buildEditSupersessionReclaim({
|
|
15158
|
+
watermark: args.sessionMeta.toolReclaimWatermark ?? 0,
|
|
14776
15159
|
db: args.db,
|
|
14777
15160
|
sessionId: args.sessionId,
|
|
14778
15161
|
targets: newTargets,
|
|
@@ -14811,7 +15194,7 @@ async function runPostTransformPhase(args) {
|
|
|
14811
15194
|
const tBatchFinalize = performance.now();
|
|
14812
15195
|
args.batch?.finalize();
|
|
14813
15196
|
if (toolReclaimApplicationOpportunity) {
|
|
14814
|
-
const maxTagNumber =
|
|
15197
|
+
const maxTagNumber = advanceToolReclaimWatermarkByDistance(args.db, args.sessionId, reclaimDistance, args.usableWindow);
|
|
14815
15198
|
args.sessionMeta.toolReclaimWatermark = Math.max(args.sessionMeta.toolReclaimWatermark ?? 0, maxTagNumber);
|
|
14816
15199
|
}
|
|
14817
15200
|
if (autoReclaimTargetCount > 0) {
|
|
@@ -15444,6 +15827,7 @@ async function runPostTransformPhase(args) {
|
|
|
15444
15827
|
const hygieneCalibration = sessionDecisionCalibration(args.db, args.sessionId);
|
|
15445
15828
|
const hygieneUnitsVersion = transitionSessionHygieneUnits(args.db, args.sessionId, bustedThisPass, hygieneCalibration);
|
|
15446
15829
|
const baseline = refreshTailHygieneBaseline({
|
|
15830
|
+
opencode2: args.opencode2,
|
|
15447
15831
|
messages: args.messages,
|
|
15448
15832
|
tags,
|
|
15449
15833
|
protectedTagNumbers: args.protectedTagNumbers,
|
|
@@ -15459,7 +15843,7 @@ async function runPostTransformPhase(args) {
|
|
|
15459
15843
|
sessionLog(args.sessionId, formatTailHygienePrefixMismatch(baseline.lastPrefixMismatch, baseline.baselineGeneration));
|
|
15460
15844
|
}
|
|
15461
15845
|
const tTailState = performance.now();
|
|
15462
|
-
const structuralSignature = tailHygieneStructuralSignature(args.messages);
|
|
15846
|
+
const structuralSignature = tailHygieneStructuralSignature(args.messages, args.opencode2);
|
|
15463
15847
|
const effective = effectiveTailHygiene(baseline);
|
|
15464
15848
|
const durableGrace = baseline.evaluable && !baseline.generationInvalidated ? captureChannel1PostReduceGraceBaseline(args.db, args.sessionId, effective.u) : getChannel1NudgeState(args.db, args.sessionId);
|
|
15465
15849
|
baseline.channel1PostReduceGrace = durableGrace.postReduceGracePending || durableGrace.postReduceGraceBaselineU !== undefined ? {
|
|
@@ -15471,7 +15855,7 @@ async function runPostTransformPhase(args) {
|
|
|
15471
15855
|
...baseline,
|
|
15472
15856
|
usableWindow: args.usableWindow,
|
|
15473
15857
|
realUserTurnCount: countRealUserMessages(args.messages),
|
|
15474
|
-
reducedSinceRefresh: baseline.baselineGeneration !== previous?.baselineGeneration ? false : previous?.reducedSinceRefresh ?? false,
|
|
15858
|
+
reducedSinceRefresh: baseline.baselineGeneration !== previous?.baselineGeneration || (previous?.generationInvalidated === true || previous?.evaluable === false) && baseline.evaluable && !baseline.generationInvalidated ? false : previous?.reducedSinceRefresh ?? false,
|
|
15475
15859
|
agentDropsAppliedThisPass: pendingOpsDidMutate,
|
|
15476
15860
|
oldestReclaimableToolTags: postprocessOldestTags(args.db, args.sessionId, args.protectedTagNumbers)
|
|
15477
15861
|
});
|
|
@@ -15509,7 +15893,7 @@ async function runPostTransformPhase(args) {
|
|
|
15509
15893
|
const tTailGuard = performance.now();
|
|
15510
15894
|
if (assertedBaseline) {
|
|
15511
15895
|
try {
|
|
15512
|
-
const servedSignature = tailHygieneStructuralSignature(args.messages);
|
|
15896
|
+
const servedSignature = tailHygieneStructuralSignature(args.messages, args.opencode2);
|
|
15513
15897
|
if (!sameTailHygieneStructuralSignature(assertedBaseline.structuralSignature, servedSignature)) {
|
|
15514
15898
|
sessionLog(args.sessionId, `ERROR [tail-hygiene-last-writer-mismatch]: served messages changed after tail-hygiene baseline refresh (expected messages=${assertedBaseline.structuralSignature.messageCount}, parts=[${assertedBaseline.structuralSignature.partCounts.join(",")}], bytes=${assertedBaseline.structuralSignature.totalBytes}; actual messages=${servedSignature.messageCount}, parts=[${servedSignature.partCounts.join(",")}], bytes=${servedSignature.totalBytes})`);
|
|
15515
15899
|
}
|
|
@@ -15517,6 +15901,7 @@ async function runPostTransformPhase(args) {
|
|
|
15517
15901
|
sessionLog(args.sessionId, "ERROR [tail-hygiene-last-writer-check-failed]: structural production guard failed open:", error);
|
|
15518
15902
|
}
|
|
15519
15903
|
assertTailHygieneContentUnchangedIfEnabled({
|
|
15904
|
+
opencode2: args.opencode2,
|
|
15520
15905
|
messages: args.messages,
|
|
15521
15906
|
tags: assertedBaseline.tags,
|
|
15522
15907
|
protectedTagNumbers: assertedBaseline.protectedTagNumbers,
|
|
@@ -15584,15 +15969,27 @@ class UnmanagedOverWindowError extends Error {
|
|
|
15584
15969
|
}
|
|
15585
15970
|
|
|
15586
15971
|
// src/hooks/magic-context/unresolved-history-boundary.ts
|
|
15972
|
+
function storedHistoryBoundaryPresence(db, sessionId) {
|
|
15973
|
+
try {
|
|
15974
|
+
const row = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
15975
|
+
return row?.id ? hasRawSessionMessageById2(sessionId, row.id) : undefined;
|
|
15976
|
+
} catch {
|
|
15977
|
+
return;
|
|
15978
|
+
}
|
|
15979
|
+
}
|
|
15980
|
+
|
|
15587
15981
|
class UnresolvedHistoryBoundaryError extends Error {
|
|
15588
15982
|
estimatedTokens;
|
|
15589
15983
|
contextLimitTokens;
|
|
15984
|
+
boundaryPresent;
|
|
15590
15985
|
code = "UNRESOLVED_HISTORY_BOUNDARY";
|
|
15591
15986
|
recoverable = true;
|
|
15592
|
-
constructor(estimatedTokens, contextLimitTokens) {
|
|
15593
|
-
|
|
15987
|
+
constructor(estimatedTokens, contextLimitTokens, boundaryPresent) {
|
|
15988
|
+
const reason = boundaryPresent === true ? "The boundary row is present in the host store but out of order relative to the loaded history. " : boundaryPresent === false ? "The boundary row is missing from the host store. " : "";
|
|
15989
|
+
super(reason + renderUserFacingFailure("history_boundary_unresolved", "plain"));
|
|
15594
15990
|
this.estimatedTokens = estimatedTokens;
|
|
15595
15991
|
this.contextLimitTokens = contextLimitTokens;
|
|
15992
|
+
this.boundaryPresent = boundaryPresent;
|
|
15596
15993
|
this.name = "UnresolvedHistoryBoundaryError";
|
|
15597
15994
|
}
|
|
15598
15995
|
}
|
|
@@ -15676,6 +16073,7 @@ function resolveTransformHostSeams(deps) {
|
|
|
15676
16073
|
};
|
|
15677
16074
|
}
|
|
15678
16075
|
function createTransform(deps) {
|
|
16076
|
+
const pendingDropEligibility = createPendingDropEligibilityCache();
|
|
15679
16077
|
registerSystemDateRefresh(deps.historyRefreshSessions);
|
|
15680
16078
|
const finalWireUsage = createFinalWireUsageTracker();
|
|
15681
16079
|
const host = resolveTransformHostSeams(deps);
|
|
@@ -15726,7 +16124,7 @@ function createTransform(deps) {
|
|
|
15726
16124
|
return historianRun?.toastDurationMs === undefined ? params : { ...params, toastDurationMs: historianRun.toastDurationMs };
|
|
15727
16125
|
};
|
|
15728
16126
|
beginLkgPass(sessionId);
|
|
15729
|
-
clearOpenCodePendingTransformDecision(sessionId);
|
|
16127
|
+
clearOpenCodePendingTransformDecision(sessionId, messages);
|
|
15730
16128
|
const db = deps.db;
|
|
15731
16129
|
try {
|
|
15732
16130
|
const tPrepare = performance.now();
|
|
@@ -16080,9 +16478,10 @@ function createTransform(deps) {
|
|
|
16080
16478
|
const persistedUsageFreshForBoundary = persistedUsageBeforeResets && Date.now() - persistedUsageBeforeResets.updatedAt <= 10 * 60 * 1000 && (persistedUsageBeforeResets.lastObservedModelKey === null || currentModelKeyForBoundary === undefined || piModelRefToCanonical(persistedUsageBeforeResets.lastObservedModelKey) === piModelRefToCanonical(currentModelKeyForBoundary)) && (resolvedContextLimit === undefined || persistedUsageBeforeResets.lastUsageContextLimit === 0 || persistedUsageBeforeResets.lastUsageContextLimit === resolvedContextLimit) ? persistedUsageBeforeResets.usage : null;
|
|
16081
16479
|
const boundaryUsageForProtectedTail = persistedUsageFreshForBoundary ?? contextUsageEarly;
|
|
16082
16480
|
const boundaryUsageSource = persistedUsageFreshForBoundary ? "persisted" : "live";
|
|
16083
|
-
const historyPolicyIdentity = historyBudgetPolicyIdentity(deps.historyBudgetPercentage, deps.executeThresholdPercentage, currentModelKeyForBoundary, deps.executeThresholdTokens);
|
|
16084
16481
|
const historyContextLimit = resolvedContextLimit ?? (currentModelKeyForBoundary && persistedUsageBeforeResets?.lastObservedModelKey && piModelRefToCanonical(currentModelKeyForBoundary) === piModelRefToCanonical(persistedUsageBeforeResets.lastObservedModelKey) && persistedUsageBeforeResets.lastUsageContextLimit > 0 ? persistedUsageBeforeResets.lastUsageContextLimit : undefined);
|
|
16085
|
-
const
|
|
16482
|
+
const memoryProjectDirectory = compartmentDirectory || process.cwd();
|
|
16483
|
+
const renderOptions = createM0RenderOptions(deps, contextUsageEarly, currentModelKeyForBoundary, historyContextLimit, deps.memoryConfig?.enabled ? resolveProjectIdentityForSession(memoryProjectDirectory, deps.allowHomeProject) : undefined);
|
|
16484
|
+
const { historyBudgetTokens, projectPath: projectIdentity } = renderOptions;
|
|
16086
16485
|
const emergencyCeilingLimit = thresholdContextLimit ?? 0;
|
|
16087
16486
|
const emergencyCeilingTokens = Number.isFinite(emergencyCeilingLimit) && emergencyCeilingLimit > 0 ? Math.floor(emergencyCeilingLimit * (effectiveExecuteThresholdPercentage / 100)) : undefined;
|
|
16088
16487
|
const schedulerDecision = compactionOff ? "defer" : resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId), resolvedContextLimit);
|
|
@@ -16215,8 +16614,6 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16215
16614
|
});
|
|
16216
16615
|
}
|
|
16217
16616
|
logTransformTiming(sessionId, "emergencyRecoveryBlock", tFirstPass);
|
|
16218
|
-
const memoryProjectDirectory = compartmentDirectory || process.cwd();
|
|
16219
|
-
const projectIdentity = deps.memoryConfig?.enabled ? resolveProjectIdentityForSession(memoryProjectDirectory, deps.allowHomeProject) : undefined;
|
|
16220
16617
|
if (deps.memoryConfig?.enabled) {
|
|
16221
16618
|
maybeSendProjectIdentityWarning(deps, sessionId, memoryProjectDirectory, notificationParams);
|
|
16222
16619
|
}
|
|
@@ -16237,6 +16634,18 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16237
16634
|
prewarmTagOwners(db, sessionId, ownerRatio);
|
|
16238
16635
|
const tagOwnersReady = isTagOwnerSummaryReady(db, sessionId, ownerRatio);
|
|
16239
16636
|
let triggerBoundarySnapshot;
|
|
16637
|
+
const dropProjectionEmergency = contextUsageEarly.percentage >= 95;
|
|
16638
|
+
const dropProjectionKey = () => pendingDropEligibilityKey(db, sessionId, lkgInput, {
|
|
16639
|
+
currentTurnId,
|
|
16640
|
+
model: modelForBudget,
|
|
16641
|
+
protectedTokens: deps.protectedTokens,
|
|
16642
|
+
protectedTokenTierOverrides: deps.protectedTokenTierOverrides,
|
|
16643
|
+
protectedTools: deps.protectedTools,
|
|
16644
|
+
keepReasoningTokens: deps.keepReasoningTokens,
|
|
16645
|
+
usableSoft: windowGeometry?.usableSoft ?? boundaryContextLimit,
|
|
16646
|
+
emergency: dropProjectionEmergency,
|
|
16647
|
+
clearedReasoningThroughTag: sessionMeta?.clearedReasoningThroughTag
|
|
16648
|
+
});
|
|
16240
16649
|
if (fullFeatureMode && !compactionOff && historianRunnable && tagOwnersReady && !sessionMeta.compartmentInProgress) {
|
|
16241
16650
|
const tTrigger = performance.now();
|
|
16242
16651
|
try {
|
|
@@ -16249,7 +16658,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16249
16658
|
force: contextUsageEarly.percentage >= forceMaterializationPercentage && (contextUsageEarly.percentage >= 95 || getEmergencyInputSample(db, sessionId) === 0),
|
|
16250
16659
|
explicitFlush: deps.pendingMaterializationSessions.has(sessionId),
|
|
16251
16660
|
publishedHistory: isCacheBusting
|
|
16252
|
-
});
|
|
16661
|
+
}, pendingDropEligibility.read(sessionId, dropProjectionKey()));
|
|
16253
16662
|
if (triggerResult.shouldFire) {
|
|
16254
16663
|
sessionLog(sessionId, `compartment trigger: firing (reason=${triggerResult.reason})`);
|
|
16255
16664
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
@@ -16257,8 +16666,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16257
16666
|
triggerBoundarySnapshot = triggerResult.boundarySnapshot;
|
|
16258
16667
|
}
|
|
16259
16668
|
} catch (error) {
|
|
16260
|
-
passOutcome
|
|
16261
|
-
sessionLog(sessionId, "compartment trigger failed (non-fatal):", error);
|
|
16669
|
+
recordCompartmentTriggerError(passOutcome, sessionId, error);
|
|
16262
16670
|
}
|
|
16263
16671
|
logTransformTiming(sessionId, "compartmentTrigger", tTrigger);
|
|
16264
16672
|
}
|
|
@@ -16498,12 +16906,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16498
16906
|
db,
|
|
16499
16907
|
sessionId,
|
|
16500
16908
|
state: sessionMeta,
|
|
16501
|
-
projectPath: projectIdentity,
|
|
16502
16909
|
projectDirectory: sessionDirectory,
|
|
16503
|
-
|
|
16504
|
-
memoryInjectionBudgetTokens: deps.memoryConfig?.injectionBudgetTokens,
|
|
16505
|
-
historyBudgetTokens,
|
|
16506
|
-
historyBudgetPolicyIdentity: historyPolicyIdentity,
|
|
16910
|
+
...renderOptions,
|
|
16507
16911
|
hardSignals: m0HardSignals
|
|
16508
16912
|
}).value;
|
|
16509
16913
|
const protectionCacheBustingPass = !compactionOff && (schedulerDecision === "execute" || isCacheBusting || contextUsage.percentage >= forceMaterializationPercentage || deps.pendingMaterializationSessions.has(sessionId) || canConsumeDeferredLate && deferredMaterializationSessions.has(sessionId) || protectionFoldWillBust);
|
|
@@ -16615,6 +17019,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16615
17019
|
keepReasoningTokens: resolveKeepReasoningTokens(deps.keepReasoningTokens, currentModelKeyForBoundary),
|
|
16616
17020
|
resolvedModelID: modelForBudget?.modelID,
|
|
16617
17021
|
protectedTagIds,
|
|
17022
|
+
onPendingDropEligibility: (eligible) => pendingDropEligibility.record(sessionId, dropProjectionKey(), eligible),
|
|
16618
17023
|
protectedTagNumbers,
|
|
16619
17024
|
protectedCutoff,
|
|
16620
17025
|
protectedCount: protectionWindow.status.protectedCount,
|
|
@@ -16642,13 +17047,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16642
17047
|
passOutcome,
|
|
16643
17048
|
historyRefreshSessions: deps.historyRefreshSessions,
|
|
16644
17049
|
m0M1: {
|
|
16645
|
-
projectPath: projectIdentity,
|
|
16646
17050
|
projectDirectory: sessionDirectory,
|
|
16647
|
-
|
|
16648
|
-
memoryInjectionBudgetTokens: deps.memoryConfig?.injectionBudgetTokens,
|
|
16649
|
-
historyBudgetTokens,
|
|
16650
|
-
historyBudgetPolicyIdentity: historyPolicyIdentity,
|
|
16651
|
-
temporalAwareness: deps.experimentalTemporalAwareness,
|
|
17051
|
+
...renderOptions,
|
|
16652
17052
|
hardSignals: m0HardSignals
|
|
16653
17053
|
}
|
|
16654
17054
|
});
|
|
@@ -16716,7 +17116,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16716
17116
|
});
|
|
16717
17117
|
if (untrimmed.tokens > boundaryContextLimit) {
|
|
16718
17118
|
sessionLog(sessionId, `history boundary unresolved: prefix trim refused and the untrimmed request estimate ${untrimmed.tokens} (trusted=${untrimmed.trusted}) exceeds the context limit ${boundaryContextLimit}; not sending it`);
|
|
16719
|
-
throw new UnresolvedHistoryBoundaryError(untrimmed.tokens, boundaryContextLimit);
|
|
17119
|
+
throw new UnresolvedHistoryBoundaryError(untrimmed.tokens, boundaryContextLimit, storedHistoryBoundaryPresence(db, sessionId));
|
|
16720
17120
|
}
|
|
16721
17121
|
}
|
|
16722
17122
|
if (unmanagedOverWindowPass) {
|
|
@@ -16893,6 +17293,24 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16893
17293
|
bustedThisPass: true,
|
|
16894
17294
|
lkgFrozenReleaseReason: recoveryReleaseReason
|
|
16895
17295
|
});
|
|
17296
|
+
} else {
|
|
17297
|
+
noteOpenCodeUnbustedPass(sessionId, {
|
|
17298
|
+
tsMs: Date.now(),
|
|
17299
|
+
decision: schedulerDecision,
|
|
17300
|
+
materialized: postTransformResult.materialized,
|
|
17301
|
+
materializeReason: normalizeMaterializeReason("opencode", postTransformResult.materializeReason, postTransformResult.materialized),
|
|
17302
|
+
systemHashPrev: postTransformResult.systemHashPrev,
|
|
17303
|
+
systemHashNew: postTransformResult.systemHashNew,
|
|
17304
|
+
m0ToolSetHashPrev: postTransformResult.m0ToolSetHashPrev,
|
|
17305
|
+
m0ToolSetHashNew: postTransformResult.m0ToolSetHashNew,
|
|
17306
|
+
m0ModelKeyPrev: postTransformResult.m0ModelKeyPrev,
|
|
17307
|
+
m0ModelKeyNew: postTransformResult.m0ModelKeyNew,
|
|
17308
|
+
emergency: postTransformResult.emergency,
|
|
17309
|
+
droppedTokens: postTransformResult.droppedTokens,
|
|
17310
|
+
droppedCount: postTransformResult.droppedCount,
|
|
17311
|
+
inputTokens: contextUsage.inputTokens,
|
|
17312
|
+
bustedThisPass: false
|
|
17313
|
+
});
|
|
16896
17314
|
}
|
|
16897
17315
|
logTransformTiming(sessionId, "postTransformPhase", tPostProcess);
|
|
16898
17316
|
const msgTokens = getMessageTokensCache(sessionId);
|
|
@@ -17047,11 +17465,19 @@ function clearMaintenanceSystemSnapshot(sessionId) {
|
|
|
17047
17465
|
function readMaintenanceSystemSnapshot(sessionId) {
|
|
17048
17466
|
return maintenanceSystemSnapshotBySession.get(sessionId);
|
|
17049
17467
|
}
|
|
17468
|
+
var maintenanceModelUnconfiguredNoted = new Set;
|
|
17469
|
+
function noteMaintenanceModelUnconfigured(projectPath, sessionId) {
|
|
17470
|
+
if (maintenanceModelUnconfiguredNoted.has(projectPath))
|
|
17471
|
+
return;
|
|
17472
|
+
maintenanceModelUnconfiguredNoted.add(projectPath);
|
|
17473
|
+
sessionLog(sessionId, "memory maintenance skipped: neither maintenance.model nor historian.model is configured (set either in the user-level mmc config; the session model is never inherited)");
|
|
17474
|
+
}
|
|
17050
17475
|
function createMaintenanceTailLauncher(deps) {
|
|
17051
17476
|
const buildLauncher = (projectPath) => (deps.launcherFactory ?? ((db, path) => getMaintenanceLauncher(db, path, {
|
|
17052
17477
|
getConfig: () => ({
|
|
17053
17478
|
maintenance: {
|
|
17054
|
-
enabled: deps.getMaintenanceConfig?.()?.enabled ?? false
|
|
17479
|
+
enabled: deps.getMaintenanceConfig?.()?.enabled ?? false,
|
|
17480
|
+
model: deps.getMaintenanceConfig?.()?.model
|
|
17055
17481
|
}
|
|
17056
17482
|
}),
|
|
17057
17483
|
runFactory: (signals) => {
|
|
@@ -17089,6 +17515,10 @@ function createMaintenanceTailLauncher(deps) {
|
|
|
17089
17515
|
return;
|
|
17090
17516
|
if (!deps.hiddenCompletionExecutor)
|
|
17091
17517
|
return;
|
|
17518
|
+
if (!hasMaintenancePrimary(maintenance)) {
|
|
17519
|
+
noteMaintenanceModelUnconfigured(projectPath, input.sessionId);
|
|
17520
|
+
return;
|
|
17521
|
+
}
|
|
17092
17522
|
const poolCount = countMaintenancePool(deps.db, projectPath);
|
|
17093
17523
|
const hostSystemText = readMaintenanceSystemSnapshot(input.sessionId);
|
|
17094
17524
|
buildLauncher(projectPath).maybeLaunch({
|
|
@@ -17107,25 +17537,6 @@ function createMaintenanceTailLauncher(deps) {
|
|
|
17107
17537
|
}
|
|
17108
17538
|
};
|
|
17109
17539
|
}
|
|
17110
|
-
function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, executeThresholdPercentage, modelKey, executeThresholdTokens, resolvedContextLimit) {
|
|
17111
|
-
if (!historyBudgetPercentage) {
|
|
17112
|
-
return;
|
|
17113
|
-
}
|
|
17114
|
-
let contextLimit = resolvedContextLimit && resolvedContextLimit > 0 ? resolvedContextLimit : 0;
|
|
17115
|
-
if (contextLimit <= 0) {
|
|
17116
|
-
if (contextUsage.percentage <= 0) {
|
|
17117
|
-
return;
|
|
17118
|
-
}
|
|
17119
|
-
contextLimit = contextUsage.inputTokens / (contextUsage.percentage / 100);
|
|
17120
|
-
}
|
|
17121
|
-
if (!Number.isFinite(contextLimit) || contextLimit <= 0) {
|
|
17122
|
-
return;
|
|
17123
|
-
}
|
|
17124
|
-
return Math.floor(contextLimit * (resolveExecuteThreshold(executeThresholdPercentage ?? 65, modelKey, 65, {
|
|
17125
|
-
tokensConfig: executeThresholdTokens,
|
|
17126
|
-
contextLimit
|
|
17127
|
-
}) / 100) * historyBudgetPercentage);
|
|
17128
|
-
}
|
|
17129
17540
|
|
|
17130
17541
|
// src/plugin/rpc-handlers.ts
|
|
17131
17542
|
import { once } from "node:events";
|
|
@@ -17376,6 +17787,7 @@ function runManualMaintenanceCommand(args) {
|
|
|
17376
17787
|
}
|
|
17377
17788
|
const explanations = {
|
|
17378
17789
|
"maintenance-disabled": "memory maintenance is disabled (maintenance.enabled: false)",
|
|
17790
|
+
"maintenance-model-unconfigured": "memory maintenance has no primary model configured — set maintenance.model in the user-level mmc config (fallback_models alone does not enable maintenance; the chain never inherits the historian or session model)",
|
|
17379
17791
|
"run-in-flight-local": "a maintenance run is already in flight; next_due_at is due now, so the launcher retries on the next pass",
|
|
17380
17792
|
"empty-pool": "memory pool is empty (no active/permanent rows) — nothing to maintain"
|
|
17381
17793
|
};
|
|
@@ -18261,7 +18673,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
18261
18673
|
});
|
|
18262
18674
|
const buildManagedCtx = async (db) => {
|
|
18263
18675
|
const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await import("./derive-budgets-s1p37t2g.js");
|
|
18264
|
-
const { resolveHistorianModel } = await import("./model-resolution-
|
|
18676
|
+
const { resolveHistorianModel } = await import("./model-resolution-cvyrrcjw.js");
|
|
18265
18677
|
const DEFAULT_HISTORIAN_TIMEOUT_MS = 600000;
|
|
18266
18678
|
const runConfig = historianRunConfig(config, currentPluginConfigReader(directory)?.poll().effective ?? config);
|
|
18267
18679
|
const historianModel = resolveHistorianModel(runConfig, "opencode");
|
|
@@ -18290,8 +18702,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
18290
18702
|
const db = readDatabase();
|
|
18291
18703
|
if (!db)
|
|
18292
18704
|
return { ok: false, error: "db unavailable" };
|
|
18293
|
-
const { runManagedRecomp } = await import("./recomp-orchestrator-
|
|
18294
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
18705
|
+
const { runManagedRecomp } = await import("./recomp-orchestrator-k760qy1n.js");
|
|
18706
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-njjf3b4s.js");
|
|
18295
18707
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
18296
18708
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
18297
18709
|
return {
|
|
@@ -18340,7 +18752,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
18340
18752
|
const db = readDatabase();
|
|
18341
18753
|
if (!db)
|
|
18342
18754
|
return { ok: false, error: "db unavailable" };
|
|
18343
|
-
const { runManagedWrapup } = await import("./wrapup-orchestrator-
|
|
18755
|
+
const { runManagedWrapup } = await import("./wrapup-orchestrator-b2gswatj.js");
|
|
18344
18756
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
18345
18757
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
18346
18758
|
const ctx = {
|
|
@@ -18372,11 +18784,14 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
18372
18784
|
const raw = String(params.subcommand ?? "status").toLowerCase();
|
|
18373
18785
|
const action = raw === "run" || raw === "resume" ? raw : "status";
|
|
18374
18786
|
if (action === "run") {
|
|
18375
|
-
const maintenance = config
|
|
18787
|
+
const maintenance = inheritMaintenanceModelConfig(config);
|
|
18376
18788
|
const hostSystemText = readMaintenanceSystemSnapshot(sessionId);
|
|
18377
18789
|
const launcher = getMaintenanceLauncher(db, projectPath, {
|
|
18378
18790
|
getConfig: () => ({
|
|
18379
|
-
maintenance: {
|
|
18791
|
+
maintenance: {
|
|
18792
|
+
enabled: maintenance?.enabled ?? false,
|
|
18793
|
+
model: maintenance?.model
|
|
18794
|
+
}
|
|
18380
18795
|
}),
|
|
18381
18796
|
nowMs: Date.now,
|
|
18382
18797
|
runFactory: createOc2MaintenanceRunFactory({
|
|
@@ -18384,7 +18799,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
18384
18799
|
projectPath,
|
|
18385
18800
|
executor: args.hiddenCompletionExecutor,
|
|
18386
18801
|
config: () => {
|
|
18387
|
-
const slice = config
|
|
18802
|
+
const slice = inheritMaintenanceModelConfig(config);
|
|
18388
18803
|
if (!slice) {
|
|
18389
18804
|
throw new Error("memory maintenance config unavailable");
|
|
18390
18805
|
}
|
|
@@ -19153,8 +19568,8 @@ var v2CompactionMarkerStrategy = {
|
|
|
19153
19568
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
19154
19569
|
|
|
19155
19570
|
// src/v2/fold/owner.ts
|
|
19156
|
-
import { createHash as
|
|
19157
|
-
var foldDigest = (value) =>
|
|
19571
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
19572
|
+
var foldDigest = (value) => createHash3("sha256").update(value).digest("hex");
|
|
19158
19573
|
|
|
19159
19574
|
class FoldOwner {
|
|
19160
19575
|
storage;
|
|
@@ -20869,6 +21284,25 @@ async function cleanupLegacyHiddenChildren(db, remove, note, options = {}) {
|
|
|
20869
21284
|
}
|
|
20870
21285
|
|
|
20871
21286
|
// src/v2/hidden-completion.ts
|
|
21287
|
+
var DEFAULT_DISPOSE_DRAIN_MS = 2000;
|
|
21288
|
+
async function settleWithin(work, ms) {
|
|
21289
|
+
let timer;
|
|
21290
|
+
try {
|
|
21291
|
+
await Promise.race([
|
|
21292
|
+
work.then(() => {
|
|
21293
|
+
return;
|
|
21294
|
+
}, () => {
|
|
21295
|
+
return;
|
|
21296
|
+
}),
|
|
21297
|
+
new Promise((resolve) => {
|
|
21298
|
+
timer = setTimeout(resolve, Math.max(0, ms));
|
|
21299
|
+
})
|
|
21300
|
+
]);
|
|
21301
|
+
} finally {
|
|
21302
|
+
if (timer)
|
|
21303
|
+
clearTimeout(timer);
|
|
21304
|
+
}
|
|
21305
|
+
}
|
|
20872
21306
|
var POLL_INTERVAL_MS = 200;
|
|
20873
21307
|
function modelKey(model) {
|
|
20874
21308
|
return `${model.providerID}/${model.modelID}`;
|
|
@@ -20968,6 +21402,9 @@ function isProviderFailure(error) {
|
|
|
20968
21402
|
}
|
|
20969
21403
|
async function awaitAssistantRow(openReader, readSessionError, localFailure, childID, afterSeq, deadline, signal) {
|
|
20970
21404
|
for (;; ) {
|
|
21405
|
+
const refusedBefore = localFailure();
|
|
21406
|
+
if (refusedBefore)
|
|
21407
|
+
throw refusedBefore;
|
|
20971
21408
|
const { assistant, idle } = withReader(openReader, (reader) => ({
|
|
20972
21409
|
assistant: reader.latestAssistant(childID),
|
|
20973
21410
|
idle: reader.latestIdle(childID)
|
|
@@ -21043,6 +21480,9 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21043
21480
|
const generation = options.generation ?? "opencode2";
|
|
21044
21481
|
const roleTails = new Map;
|
|
21045
21482
|
const note = options.log ?? log;
|
|
21483
|
+
let disposed;
|
|
21484
|
+
const openRuns = new Set;
|
|
21485
|
+
const inFlight = new Set;
|
|
21046
21486
|
const removeSession = host.removeSession;
|
|
21047
21487
|
if (!removeSession)
|
|
21048
21488
|
throw new Error("Magic Context requires OpenCode 2.0.22 session.remove");
|
|
@@ -21079,7 +21519,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21079
21519
|
const entry = rows.find((row) => row && typeof row === "object" && row.providerID === model.providerID && row.id === model.modelID);
|
|
21080
21520
|
if (!entry)
|
|
21081
21521
|
return model;
|
|
21082
|
-
if (entry.variants && typeof entry.variants === "object" && Object.hasOwn(entry.variants, model.variant))
|
|
21522
|
+
if (Array.isArray(entry.variants) ? entry.variants.some((variant) => variant?.id === model.variant) : entry.variants && typeof entry.variants === "object" && Object.hasOwn(entry.variants, model.variant))
|
|
21083
21523
|
return model;
|
|
21084
21524
|
const key = `${model.providerID}/${model.modelID}:${model.variant}`;
|
|
21085
21525
|
if (!warnedVariants.has(key)) {
|
|
@@ -21137,10 +21577,17 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21137
21577
|
return {
|
|
21138
21578
|
capabilities: V2_HIDDEN_EXECUTOR_CAPABILITIES,
|
|
21139
21579
|
async open(identity) {
|
|
21580
|
+
if (disposed)
|
|
21581
|
+
throw disposed;
|
|
21140
21582
|
const role = roleFor(identity);
|
|
21141
|
-
const
|
|
21583
|
+
const releaseStore = options.holdStore?.() ?? (() => {});
|
|
21584
|
+
let releaseRole;
|
|
21142
21585
|
let openedChild;
|
|
21586
|
+
let opened;
|
|
21143
21587
|
try {
|
|
21588
|
+
releaseRole = await acquireRole(role);
|
|
21589
|
+
if (disposed)
|
|
21590
|
+
throw disposed;
|
|
21144
21591
|
await options.ensureAgent?.();
|
|
21145
21592
|
const head = await resolveHead(identity);
|
|
21146
21593
|
const active = await lifecycle.open(identity, role, head);
|
|
@@ -21151,17 +21598,25 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21151
21598
|
role,
|
|
21152
21599
|
child: active,
|
|
21153
21600
|
releaseRole,
|
|
21601
|
+
releaseStore,
|
|
21154
21602
|
failed: false,
|
|
21155
21603
|
unsettledFailure: false,
|
|
21156
21604
|
retired: false
|
|
21157
21605
|
};
|
|
21158
21606
|
runs.set(handle, run);
|
|
21607
|
+
opened = run;
|
|
21608
|
+
openRuns.add(run);
|
|
21609
|
+
if (disposed)
|
|
21610
|
+
noteChildOfDisposedInstance(active.id);
|
|
21159
21611
|
await switchChildModel(run, head);
|
|
21160
21612
|
return handle;
|
|
21161
21613
|
} catch (error) {
|
|
21162
21614
|
if (openedChild)
|
|
21163
21615
|
lifecycle.retire(openedChild, "hidden-run-open-failed");
|
|
21164
|
-
|
|
21616
|
+
if (opened)
|
|
21617
|
+
openRuns.delete(opened);
|
|
21618
|
+
releaseRole?.();
|
|
21619
|
+
releaseStore();
|
|
21165
21620
|
throw error;
|
|
21166
21621
|
}
|
|
21167
21622
|
},
|
|
@@ -21169,6 +21624,15 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21169
21624
|
const run = runs.get(handle);
|
|
21170
21625
|
if (!run)
|
|
21171
21626
|
throw new Error("Unknown hidden completion run");
|
|
21627
|
+
const refuseDisposed = () => {
|
|
21628
|
+
if (!disposed)
|
|
21629
|
+
return;
|
|
21630
|
+
run.failed = true;
|
|
21631
|
+
run.unsettledFailure = true;
|
|
21632
|
+
retire(run, "plugin-instance-disposed");
|
|
21633
|
+
throw disposed;
|
|
21634
|
+
};
|
|
21635
|
+
refuseDisposed();
|
|
21172
21636
|
if (request.signal?.aborted) {
|
|
21173
21637
|
await interruptAndRetire(run, "aborted-before-prompt");
|
|
21174
21638
|
throw new Error("Hidden completion prompt aborted");
|
|
@@ -21183,6 +21647,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21183
21647
|
handle.childSessionId = run.child.id;
|
|
21184
21648
|
}
|
|
21185
21649
|
await switchChildModel(run, requested);
|
|
21650
|
+
refuseDisposed();
|
|
21186
21651
|
const baseline = withReader(options.openReader, (reader) => reader.latestSequence(run.child.id));
|
|
21187
21652
|
const marker = `mc:hidden:${crypto.randomUUID()}:${crypto.randomUUID()}`;
|
|
21188
21653
|
run.completion = undefined;
|
|
@@ -21208,6 +21673,28 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21208
21673
|
interruptAndRetire(run, "prompt-timeout").finally(() => abortReject(new Error("Hidden completion prompt timed out")));
|
|
21209
21674
|
}, Math.max(0, deadline - Date.now()));
|
|
21210
21675
|
request.signal?.addEventListener("abort", onAbort, { once: true });
|
|
21676
|
+
let settle;
|
|
21677
|
+
const entry = {
|
|
21678
|
+
cancel: async (refusal) => {
|
|
21679
|
+
attempt.refusal ??= refusal;
|
|
21680
|
+
noteChildOfDisposedInstance(run.child.id);
|
|
21681
|
+
try {
|
|
21682
|
+
await interruptAndRetire(run, "plugin-instance-disposed");
|
|
21683
|
+
} catch (error) {
|
|
21684
|
+
note(`[magic-context] hidden child ${run.child.id} could not be interrupted on dispose: ${errorText(error)}`);
|
|
21685
|
+
} finally {
|
|
21686
|
+
abortReject(refusal);
|
|
21687
|
+
}
|
|
21688
|
+
},
|
|
21689
|
+
reject: (refusal) => {
|
|
21690
|
+
attempt.refusal ??= refusal;
|
|
21691
|
+
abortReject(refusal);
|
|
21692
|
+
},
|
|
21693
|
+
settled: new Promise((resolve) => {
|
|
21694
|
+
settle = resolve;
|
|
21695
|
+
})
|
|
21696
|
+
};
|
|
21697
|
+
inFlight.add(entry);
|
|
21211
21698
|
try {
|
|
21212
21699
|
await Promise.race([
|
|
21213
21700
|
host.prompt({ sessionID: run.child.id, text: marker }),
|
|
@@ -21278,6 +21765,8 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21278
21765
|
clearTimeout(deadlineTimer);
|
|
21279
21766
|
request.signal?.removeEventListener("abort", onAbort);
|
|
21280
21767
|
options.hook.releaseAttempt(marker);
|
|
21768
|
+
inFlight.delete(entry);
|
|
21769
|
+
settle();
|
|
21281
21770
|
}
|
|
21282
21771
|
},
|
|
21283
21772
|
async collect(handle) {
|
|
@@ -21299,9 +21788,27 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
21299
21788
|
}
|
|
21300
21789
|
} finally {
|
|
21301
21790
|
runs.delete(handle);
|
|
21791
|
+
openRuns.delete(run);
|
|
21302
21792
|
run.releaseRole();
|
|
21793
|
+
run.releaseStore();
|
|
21303
21794
|
}
|
|
21304
21795
|
await lifecycle.finish(run.child, run.retired);
|
|
21796
|
+
},
|
|
21797
|
+
async dispose() {
|
|
21798
|
+
disposed ??= new HiddenCompletionRefusal("hidden_instance_disposed", HIDDEN_RUN_DISPOSED_REASON, true);
|
|
21799
|
+
const refusal = disposed;
|
|
21800
|
+
for (const run of openRuns)
|
|
21801
|
+
noteChildOfDisposedInstance(run.child.id);
|
|
21802
|
+
const entries = [...inFlight];
|
|
21803
|
+
if (entries.length === 0)
|
|
21804
|
+
return;
|
|
21805
|
+
note(`[magic-context] plugin instance disposed with ${entries.length} hidden run(s) in flight; cancelling them`);
|
|
21806
|
+
const bound = options.disposeDrainMs ?? DEFAULT_DISPOSE_DRAIN_MS;
|
|
21807
|
+
const deadline = Date.now() + bound;
|
|
21808
|
+
await settleWithin(Promise.allSettled(entries.map((entry) => entry.cancel(refusal))), bound);
|
|
21809
|
+
for (const entry of entries)
|
|
21810
|
+
entry.reject(refusal);
|
|
21811
|
+
await settleWithin(Promise.allSettled(entries.map((entry) => entry.settled)), deadline - Date.now());
|
|
21305
21812
|
}
|
|
21306
21813
|
};
|
|
21307
21814
|
}
|
|
@@ -21588,9 +22095,9 @@ function hiddenTerminalError(event) {
|
|
|
21588
22095
|
}
|
|
21589
22096
|
|
|
21590
22097
|
// src/v2/hooks/lkg-system.ts
|
|
21591
|
-
import { createHash as
|
|
22098
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
21592
22099
|
function identity(slot) {
|
|
21593
|
-
return
|
|
22100
|
+
return createHash4("sha256").update(JSON.stringify({
|
|
21594
22101
|
capturedAt: slot.capturedAt,
|
|
21595
22102
|
captureSequence: slot.captureSequence,
|
|
21596
22103
|
rowVersion: slot.rowVersion,
|
|
@@ -22553,7 +23060,7 @@ function resolveCtxExpandMode(args, domain) {
|
|
|
22553
23060
|
}
|
|
22554
23061
|
|
|
22555
23062
|
// src/tools/ctx-expand/render.ts
|
|
22556
|
-
import { createHash as
|
|
23063
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
22557
23064
|
function isRecord4(value) {
|
|
22558
23065
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
22559
23066
|
}
|
|
@@ -22777,7 +23284,7 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
|
|
|
22777
23284
|
const index = scoped ? Number(scoped[2]) : 0;
|
|
22778
23285
|
const piText = message.parts.filter((part) => isRecord4(part) && part.type === "text");
|
|
22779
23286
|
const part = message.parts[index];
|
|
22780
|
-
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" &&
|
|
23287
|
+
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" && createHash5("sha256").update(part.text).digest("hex") === derived[3]) : [];
|
|
22781
23288
|
const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
|
|
22782
23289
|
if (!selected)
|
|
22783
23290
|
return `Tag ${number}'s original text part is no longer in stored history.`;
|
|
@@ -24128,6 +24635,7 @@ function persistV2UsageReading(args) {
|
|
|
24128
24635
|
|
|
24129
24636
|
// src/v2/hooks/context.ts
|
|
24130
24637
|
var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
|
|
24638
|
+
var STORE_POOL_DISPOSE_WAIT_MS = 1000;
|
|
24131
24639
|
|
|
24132
24640
|
class V2LkgAdmissionReplay extends Error {
|
|
24133
24641
|
}
|
|
@@ -24467,6 +24975,7 @@ async function registerContext(context) {
|
|
|
24467
24975
|
ensureAgent: () => hiddenAgentsReady ??= context.agent.reload(),
|
|
24468
24976
|
modelCatalog: () => Promise.resolve(context.model.list()),
|
|
24469
24977
|
openReader: openStoreReader,
|
|
24978
|
+
holdStore: () => readerPool.hold(),
|
|
24470
24979
|
resolveStepCap: resolveHiddenStepCap
|
|
24471
24980
|
});
|
|
24472
24981
|
};
|
|
@@ -25073,7 +25582,7 @@ async function registerContext(context) {
|
|
|
25073
25582
|
sessionDirectoryBySession: sessionDirectories,
|
|
25074
25583
|
projectPath: directory,
|
|
25075
25584
|
agentBySession: agents,
|
|
25076
|
-
maintenanceConfig: config.maintenance ? () => config
|
|
25585
|
+
maintenanceConfig: config.maintenance ? () => inheritMaintenanceModelConfig(config) : undefined,
|
|
25077
25586
|
hiddenCompletionExecutor,
|
|
25078
25587
|
historianRunnable: !compactionOff && hiddenCompletionExecutor !== undefined && config.historian?.disable !== true,
|
|
25079
25588
|
historianModel: historianModels.primary,
|
|
@@ -25386,6 +25895,7 @@ ${baseline}
|
|
|
25386
25895
|
}, 0);
|
|
25387
25896
|
return {
|
|
25388
25897
|
async dispose() {
|
|
25898
|
+
await hiddenCompletionExecutor?.dispose();
|
|
25389
25899
|
rpcStopped = true;
|
|
25390
25900
|
rpcServer.stop();
|
|
25391
25901
|
tools?.dispose();
|
|
@@ -25396,7 +25906,8 @@ ${baseline}
|
|
|
25396
25906
|
release();
|
|
25397
25907
|
rawProviders.clear();
|
|
25398
25908
|
restoredRows.clear();
|
|
25399
|
-
readerPool.
|
|
25909
|
+
if (!await readerPool.closeWhenIdle(STORE_POOL_DISPOSE_WAIT_MS))
|
|
25910
|
+
log(`[magic-context] v2 store reader pool still held by ${readerPool.holdCount()} hidden run(s) at dispose; it closes when they finish`);
|
|
25400
25911
|
clearSyntheticCandidates(context);
|
|
25401
25912
|
}
|
|
25402
25913
|
};
|