@retaw106/mmc-oc 2.0.0 → 2.1.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 +1 -1
- package/dist/config/live-run-config.d.ts.map +1 -1
- package/dist/config-init.js +1 -1
- package/dist/{context-95zkksn3.js → context-vhcstgs3.js} +1812 -814
- package/dist/features/magic-context/memory/types.d.ts +1 -0
- package/dist/features/magic-context/memory/types.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-storage.d.ts +8 -2
- package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +12 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +6 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +2 -2
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +3 -1
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +3 -5
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts +2 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.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/historian-drain-gate.d.ts +11 -0
- package/dist/hooks/magic-context/historian-drain-gate.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts +118 -0
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts +2 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -28
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-fg34g6a5.js → index-1j34a56j.js} +49 -8
- package/dist/{index-5pg0acf7.js → index-amycb7b1.js} +1 -1
- package/dist/{index-1mjhzqq7.js → index-dr0gepzw.js} +86 -23
- package/dist/{index-xt7y10x6.js → index-n0vnzz6h.js} +1 -1
- package/dist/{index-977gxfz0.js → index-ramz5kkm.js} +1 -1
- package/dist/{index-bdt9my9y.js → index-wtb9hzk6.js} +130 -50
- package/dist/index.js +1 -1
- package/dist/{message-time-backfill-zfernxbw.js → message-time-backfill-phrwp2fz.js} +1 -1
- package/dist/{read-session-chunk-hp464g13.js → read-session-chunk-82rkqa8j.js} +3 -3
- package/dist/{recomp-orchestrator-3qxeqwb9.js → recomp-orchestrator-vc5dkzy2.js} +6 -6
- package/dist/{send-session-notification-y29y9fsr.js → send-session-notification-rnc4nrsr.js} +3 -3
- package/dist/shared/harness.d.ts +1 -1
- package/dist/shared/harness.d.ts.map +1 -1
- package/dist/shared/historian-tool-expansions.d.ts +1 -1
- package/dist/shared/historian-tool-expansions.d.ts.map +1 -1
- package/dist/shared/historian-tool-template.d.ts +2 -2
- package/dist/shared/historian-tool-template.d.ts.map +1 -1
- package/dist/shared/model-resolution.d.ts +1 -1
- package/dist/shared/model-resolution.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +14 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/v2/fold/host-media.d.ts +4 -0
- package/dist/v2/fold/host-media.d.ts.map +1 -1
- package/dist/v2/fold/memory-cache.d.ts +70 -0
- package/dist/v2/fold/memory-cache.d.ts.map +1 -0
- package/dist/v2/fold/native-codec.d.ts +10 -0
- package/dist/v2/fold/native-codec.d.ts.map +1 -0
- package/dist/v2/fold/native-replay.d.ts +58 -0
- package/dist/v2/fold/native-replay.d.ts.map +1 -0
- package/dist/v2/fold/policy.d.ts +24 -0
- package/dist/v2/fold/policy.d.ts.map +1 -0
- package/dist/v2/hidden-child-record.d.ts +6 -0
- package/dist/v2/hidden-child-record.d.ts.map +1 -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/types.d.ts +6 -0
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/server.js +1763 -528
- package/dist/v2/store-reader.d.ts +16 -0
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/web/api.d.ts.map +1 -1
- package/dist/web/fixtures.d.ts +41 -0
- package/dist/web/fixtures.d.ts.map +1 -1
- package/dist/web/host-opencode.d.ts +9 -0
- package/dist/web/host-opencode.d.ts.map +1 -1
- package/dist/web/main.js +705 -53
- package/dist/web/memories.d.ts +18 -2
- package/dist/web/memories.d.ts.map +1 -1
- package/dist/web/ui/panel.css +2 -0
- package/dist/web/ui/panel.js +135 -77
- package/dist/web/views.d.ts +50 -9
- package/dist/web/views.d.ts.map +1 -1
- package/dist/{wrapup-orchestrator-wgb2nd19.js → wrapup-orchestrator-x9xamts2.js} +6 -6
- package/package.json +1 -1
- package/src/config/live-run-config.ts +28 -0
- package/src/shared/harness.ts +1 -1
- package/src/shared/historian-tool-defaults.json +6 -6
- package/src/shared/historian-tool-expansions.ts +65 -8
- package/src/shared/historian-tool-preview-defaults.json +13 -0
- package/src/shared/historian-tool-template.ts +48 -14
- package/src/shared/model-resolution.ts +1 -1
- package/src/shared/sqlite-acquisition-routing.test.ts +18 -0
- package/src/shared/sqlite.ts +100 -15
- package/src/shared/write-transaction-attribution.test.ts +2 -2
|
@@ -102,6 +102,7 @@ import {
|
|
|
102
102
|
resolveCompactionModeRecord,
|
|
103
103
|
getCompactionModeRecord,
|
|
104
104
|
setCompactionModeRecord,
|
|
105
|
+
getProtectedTailDrainBudgetSkip,
|
|
105
106
|
clearPersistedReasoningWatermark,
|
|
106
107
|
getEmergencyInputSample,
|
|
107
108
|
setEmergencyDropSample,
|
|
@@ -246,13 +247,15 @@ import {
|
|
|
246
247
|
hasCompleteCachedM0M1,
|
|
247
248
|
injectM0M1,
|
|
248
249
|
RECOVERY_NO_HEAD_LIMIT,
|
|
250
|
+
deriveProtectedTailTokenTarget,
|
|
251
|
+
selectPerRunCap,
|
|
249
252
|
resolveOpenCodeProtectedTailBoundary,
|
|
250
253
|
getRawHistoryEligibility,
|
|
251
254
|
hasRunnableCompartmentWindow,
|
|
252
255
|
recordHighPressureNoEligibleHead,
|
|
253
256
|
getActiveCompartmentRun,
|
|
254
257
|
startCompartmentAgent
|
|
255
|
-
} from "./index-
|
|
258
|
+
} from "./index-wtb9hzk6.js";
|
|
256
259
|
import {
|
|
257
260
|
getHarness,
|
|
258
261
|
getDataDir,
|
|
@@ -386,6 +389,7 @@ import {
|
|
|
386
389
|
getMeasuredToolDefinitionTokens,
|
|
387
390
|
describeFinalWireTail,
|
|
388
391
|
estimateMessageTokens,
|
|
392
|
+
wireContentBytes,
|
|
389
393
|
createFinalWireUsageTracker,
|
|
390
394
|
estimateFinalWireInputTokens,
|
|
391
395
|
modelAcceptsEmptyContent,
|
|
@@ -412,7 +416,7 @@ import {
|
|
|
412
416
|
primeInMemoryTailRawMessageCache2,
|
|
413
417
|
readRawSessionMessageById2,
|
|
414
418
|
readSessionChunk2
|
|
415
|
-
} from "./index-
|
|
419
|
+
} from "./index-dr0gepzw.js";
|
|
416
420
|
import {
|
|
417
421
|
getSqliteMemoryStats,
|
|
418
422
|
withSqliteBackgroundWriter,
|
|
@@ -421,7 +425,7 @@ import {
|
|
|
421
425
|
isTransientSqliteError,
|
|
422
426
|
SqliteAcquisitionBusyError,
|
|
423
427
|
withAsyncPrivilegedWriter
|
|
424
|
-
} from "./index-
|
|
428
|
+
} from "./index-1j34a56j.js";
|
|
425
429
|
import {
|
|
426
430
|
canonicalModelIdentity,
|
|
427
431
|
piModelRefToCanonical,
|
|
@@ -435,7 +439,7 @@ import {
|
|
|
435
439
|
withReadOnlySessionDb,
|
|
436
440
|
getMessageTimesFromOpenCodeDb,
|
|
437
441
|
findLastAssistantModelFromOpenCodeDb
|
|
438
|
-
} from "./index-
|
|
442
|
+
} from "./index-ramz5kkm.js";
|
|
439
443
|
import {
|
|
440
444
|
registerNotificationSink2,
|
|
441
445
|
pushNotification2,
|
|
@@ -448,7 +452,7 @@ import {
|
|
|
448
452
|
getErrorMessage,
|
|
449
453
|
flushIgnoredMessages2,
|
|
450
454
|
sendStatusNotification2
|
|
451
|
-
} from "./index-
|
|
455
|
+
} from "./index-amycb7b1.js";
|
|
452
456
|
import {
|
|
453
457
|
resolveHistorianModel2
|
|
454
458
|
} from "./index-z2g20msd.js";
|
|
@@ -3034,6 +3038,10 @@ function sampleLiveConfig(boot, fresh) {
|
|
|
3034
3038
|
let value = fresh;
|
|
3035
3039
|
for (const part of parts)
|
|
3036
3040
|
value = value?.[part];
|
|
3041
|
+
if (value === undefined) {
|
|
3042
|
+
removeLeaf(result, parts);
|
|
3043
|
+
continue;
|
|
3044
|
+
}
|
|
3037
3045
|
let target = result;
|
|
3038
3046
|
for (const part of parts.slice(0, -1)) {
|
|
3039
3047
|
const child = target[part];
|
|
@@ -3047,6 +3055,26 @@ function sampleLiveConfig(boot, fresh) {
|
|
|
3047
3055
|
}
|
|
3048
3056
|
return result;
|
|
3049
3057
|
}
|
|
3058
|
+
function removeLeaf(root, parts) {
|
|
3059
|
+
const parents = parts.slice(0, -1);
|
|
3060
|
+
let node = root;
|
|
3061
|
+
for (const part of parents) {
|
|
3062
|
+
const child = node[part];
|
|
3063
|
+
if (!child || typeof child !== "object" || Array.isArray(child))
|
|
3064
|
+
return;
|
|
3065
|
+
node = child;
|
|
3066
|
+
}
|
|
3067
|
+
const leaf = parts.at(-1);
|
|
3068
|
+
if (leaf === undefined || !Object.hasOwn(node, leaf))
|
|
3069
|
+
return;
|
|
3070
|
+
let target = root;
|
|
3071
|
+
for (const part of parents) {
|
|
3072
|
+
const copy = { ...target[part] };
|
|
3073
|
+
target[part] = copy;
|
|
3074
|
+
target = copy;
|
|
3075
|
+
}
|
|
3076
|
+
delete target[leaf];
|
|
3077
|
+
}
|
|
3050
3078
|
function changedLiveKeys(previous, next) {
|
|
3051
3079
|
const at = (config, path) => path.split(".").reduce((node, part) => node?.[part], config);
|
|
3052
3080
|
return LIVE_RELOAD_CONFIG_PATHS.filter((path) => JSON.stringify(at(previous, path)) !== JSON.stringify(at(next, path)));
|
|
@@ -8599,6 +8627,9 @@ function createToolExecuteAfterHook(args) {
|
|
|
8599
8627
|
};
|
|
8600
8628
|
}
|
|
8601
8629
|
|
|
8630
|
+
// src/hooks/magic-context/lkg-measured-request.ts
|
|
8631
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
8632
|
+
|
|
8602
8633
|
// src/shared/provider-response-completion.ts
|
|
8603
8634
|
function providerResponseFailed(input) {
|
|
8604
8635
|
if (input.error !== undefined && input.error !== null && input.error !== "")
|
|
@@ -8620,9 +8651,49 @@ function lkgProviderInputTotal(tokens) {
|
|
|
8620
8651
|
const counts = [tokens?.input ?? 0, tokens?.cache?.read ?? 0, tokens?.cache?.write ?? 0];
|
|
8621
8652
|
return counts.every((count) => Number.isSafeInteger(count) && count >= 0) ? counts.reduce((sum, count) => sum + count, 0) : Number.NaN;
|
|
8622
8653
|
}
|
|
8654
|
+
function identity(slot) {
|
|
8655
|
+
return createHash3("sha256").update(JSON.stringify([
|
|
8656
|
+
slot.capturedAt,
|
|
8657
|
+
slot.captureSequence,
|
|
8658
|
+
slot.rowVersion,
|
|
8659
|
+
slot.modelKey,
|
|
8660
|
+
slot.providerKey,
|
|
8661
|
+
slot.inputIdSeq,
|
|
8662
|
+
slot.inputContentDigests
|
|
8663
|
+
])).update(slot.jsonPrefix).digest("hex");
|
|
8664
|
+
}
|
|
8665
|
+
function envelope(modelKey, systemPromptTokens, agentName) {
|
|
8666
|
+
const slash = modelKey.indexOf("/");
|
|
8667
|
+
return JSON.stringify([
|
|
8668
|
+
modelKey,
|
|
8669
|
+
systemPromptTokens,
|
|
8670
|
+
agentName,
|
|
8671
|
+
getMeasuredToolDefinitionTokens(modelKey.slice(0, slash), modelKey.slice(slash + 1), agentName)
|
|
8672
|
+
]);
|
|
8673
|
+
}
|
|
8623
8674
|
function beginV2LkgRequest(sessionId, modelKey, previousResponseId) {
|
|
8624
8675
|
requests.set(sessionId, { kind: "v2", previousResponseId, startedAt: Date.now(), modelKey });
|
|
8625
8676
|
}
|
|
8677
|
+
function claimLkgRequestIdentity(sessionId) {
|
|
8678
|
+
const request = requests.get(sessionId);
|
|
8679
|
+
if (!request || claimedRequests.has(request))
|
|
8680
|
+
return;
|
|
8681
|
+
claimedRequests.add(request);
|
|
8682
|
+
return request;
|
|
8683
|
+
}
|
|
8684
|
+
function noteCapturedLkgRequest(args) {
|
|
8685
|
+
const request = args.request;
|
|
8686
|
+
if (!request || request.modelKey !== args.slot.modelKey) {
|
|
8687
|
+
captures.delete(args.sessionId);
|
|
8688
|
+
return;
|
|
8689
|
+
}
|
|
8690
|
+
captures.set(args.sessionId, {
|
|
8691
|
+
request,
|
|
8692
|
+
slot: identity(args.slot),
|
|
8693
|
+
prefixCount: JSON.parse(args.slot.jsonPrefix).length,
|
|
8694
|
+
envelope: envelope(request.modelKey, args.systemPromptTokens, args.agentName)
|
|
8695
|
+
});
|
|
8696
|
+
}
|
|
8626
8697
|
function noteLkgProviderResponse(args) {
|
|
8627
8698
|
if (!args.responseId || !args.modelKey)
|
|
8628
8699
|
return;
|
|
@@ -8650,7 +8721,7 @@ function noteLkgProviderResponse(args) {
|
|
|
8650
8721
|
}
|
|
8651
8722
|
|
|
8652
8723
|
// src/hooks/magic-context/lkg-persist.ts
|
|
8653
|
-
import { createHash as
|
|
8724
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
8654
8725
|
function parseStringArray(value) {
|
|
8655
8726
|
if (typeof value !== "string")
|
|
8656
8727
|
return null;
|
|
@@ -8764,7 +8835,7 @@ function rememberFingerprint(db, sessionId, fingerprint) {
|
|
|
8764
8835
|
saved.set(sessionId, fingerprint);
|
|
8765
8836
|
}
|
|
8766
8837
|
function slotFingerprint(slot) {
|
|
8767
|
-
return
|
|
8838
|
+
return createHash4("sha256").update(JSON.stringify([
|
|
8768
8839
|
slot.jsonPrefix,
|
|
8769
8840
|
slot.inputIdSeq,
|
|
8770
8841
|
slot.inputContentDigests,
|
|
@@ -9210,7 +9281,7 @@ function captureLkgSlot(args) {
|
|
|
9210
9281
|
if (!built)
|
|
9211
9282
|
return false;
|
|
9212
9283
|
const modelKeys = canonicalLkgModelKeys(args.modelKey, args.providerKey);
|
|
9213
|
-
|
|
9284
|
+
const slot = {
|
|
9214
9285
|
jsonPrefix: built.jsonPrefix,
|
|
9215
9286
|
inputIdSeq: built.inputIdSeq,
|
|
9216
9287
|
inputContentDigests: built.inputContentDigests,
|
|
@@ -9218,7 +9289,17 @@ function captureLkgSlot(args) {
|
|
|
9218
9289
|
modelKey: modelKeys.modelKey,
|
|
9219
9290
|
providerKey: modelKeys.providerKey,
|
|
9220
9291
|
capturedAt: args.capturedAt ?? Date.now()
|
|
9221
|
-
}
|
|
9292
|
+
};
|
|
9293
|
+
const captured = captureSlot(args.sessionId, slot);
|
|
9294
|
+
if (captured)
|
|
9295
|
+
noteCapturedLkgRequest({
|
|
9296
|
+
sessionId: args.sessionId,
|
|
9297
|
+
slot,
|
|
9298
|
+
request: built.anchorIndex === args.input.length - 1 ? claimLkgRequestIdentity(args.sessionId) : undefined,
|
|
9299
|
+
systemPromptTokens: args.systemPromptTokens ?? 0,
|
|
9300
|
+
agentName: args.agentName
|
|
9301
|
+
});
|
|
9302
|
+
return captured;
|
|
9222
9303
|
}
|
|
9223
9304
|
function entryIdsAreValid(slot, entryIds) {
|
|
9224
9305
|
if (slot.inputIdSeq.length === 0 || entryIds.length < slot.inputIdSeq.length)
|
|
@@ -9444,6 +9525,45 @@ function replayLkg(args) {
|
|
|
9444
9525
|
return { ok: true, messages: replayed };
|
|
9445
9526
|
}
|
|
9446
9527
|
|
|
9528
|
+
// src/hooks/magic-context/lkg-replay-fit.ts
|
|
9529
|
+
var RAW_FALLBACK_BYTES_PER_CONTEXT_TOKEN = 4;
|
|
9530
|
+
function lkgReplayLimit(args) {
|
|
9531
|
+
const { db, sessionId, model } = args;
|
|
9532
|
+
const trusted = model ? resolveTrustedContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : undefined;
|
|
9533
|
+
if (trusted !== undefined && trusted > 0)
|
|
9534
|
+
return trusted;
|
|
9535
|
+
const detected = getOverflowState(db, sessionId, args.modelKey).detectedContextLimit;
|
|
9536
|
+
return detected > 0 ? detected : undefined;
|
|
9537
|
+
}
|
|
9538
|
+
function measureLkgReplay(args) {
|
|
9539
|
+
const baseline = args.measuredInputTokens ?? 0;
|
|
9540
|
+
const tailLimit = Math.max(0, args.limit - baseline);
|
|
9541
|
+
const proxy = wireContentBytes(args.messages, tailLimit * RAW_FALLBACK_BYTES_PER_CONTEXT_TOKEN, RAW_FALLBACK_BYTES_PER_CONTEXT_TOKEN);
|
|
9542
|
+
const skipped = { proxy, estimatorRan: false, trusted: false };
|
|
9543
|
+
if (proxy === null)
|
|
9544
|
+
return { fit: "unproven", tokens: null, ...skipped };
|
|
9545
|
+
const proxyTokens = baseline + Math.ceil(proxy.bytes / RAW_FALLBACK_BYTES_PER_CONTEXT_TOKEN);
|
|
9546
|
+
if (proxy.aborted || proxyTokens > args.limit) {
|
|
9547
|
+
return { fit: "over", tokens: null, proxyTokens, ...skipped };
|
|
9548
|
+
}
|
|
9549
|
+
let estimate;
|
|
9550
|
+
try {
|
|
9551
|
+
estimate = args.estimate();
|
|
9552
|
+
} catch {
|
|
9553
|
+
return { fit: "unproven", tokens: null, ...skipped };
|
|
9554
|
+
}
|
|
9555
|
+
const seen = { proxy, estimatorRan: true, trusted: estimate.trusted };
|
|
9556
|
+
const tokens = baseline + estimate.tokens;
|
|
9557
|
+
if (!estimate.trusted || !Number.isFinite(tokens) || tokens <= 0 || estimate.tokens < 0) {
|
|
9558
|
+
return {
|
|
9559
|
+
fit: "unproven",
|
|
9560
|
+
tokens: Number.isFinite(estimate.tokens) ? estimate.tokens : null,
|
|
9561
|
+
...seen
|
|
9562
|
+
};
|
|
9563
|
+
}
|
|
9564
|
+
return tokens > args.limit ? { fit: "over", tokens, proxyTokens, ...seen } : { fit: "under", tokens, ...seen };
|
|
9565
|
+
}
|
|
9566
|
+
|
|
9447
9567
|
// src/hooks/magic-context/storage-busy-refusal.ts
|
|
9448
9568
|
var STORAGE_BUSY_MESSAGE = "Magic Context's database is busy (another process held it too long); send your message again.";
|
|
9449
9569
|
function describeStorageBusyCause(cause) {
|
|
@@ -9471,7 +9591,7 @@ class StorageBusyRefusalError extends Error {
|
|
|
9471
9591
|
}
|
|
9472
9592
|
|
|
9473
9593
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
9474
|
-
import { createHash as
|
|
9594
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
9475
9595
|
|
|
9476
9596
|
// src/agents/magic-context-prompt.ts
|
|
9477
9597
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
@@ -9712,7 +9832,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
9712
9832
|
}
|
|
9713
9833
|
const stickyDate = stickyDateBySession.get(sessionId);
|
|
9714
9834
|
const stableCandidate = currentDate && stickyDate && currentDate !== stickyDate ? liveSystemContent.replace(DATE_PATTERN_ALL, stickyDate) : liveSystemContent;
|
|
9715
|
-
const stableCandidateHash =
|
|
9835
|
+
const stableCandidateHash = createHash5("md5").update(promptSurfaceHashMaterial(stableCandidate, promptSurface.preset)).digest("hex");
|
|
9716
9836
|
const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
|
|
9717
9837
|
const dateMayAdvance = isCacheBusting || idleCacheExpired || contentOrPresetChanged;
|
|
9718
9838
|
if (currentDate && !stickyDate) {
|
|
@@ -9732,7 +9852,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
9732
9852
|
`);
|
|
9733
9853
|
if (!availability.frozen || !modelKey)
|
|
9734
9854
|
return;
|
|
9735
|
-
const currentHash =
|
|
9855
|
+
const currentHash = createHash5("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
|
|
9736
9856
|
if (!sessionMetaEarly) {
|
|
9737
9857
|
return;
|
|
9738
9858
|
}
|
|
@@ -9947,10 +10067,14 @@ function recordSessionProjectIdentity(db, sessionId, projectPath) {
|
|
|
9947
10067
|
return;
|
|
9948
10068
|
const harness = getHarness();
|
|
9949
10069
|
const now = Date.now();
|
|
10070
|
+
let previousProjectPath;
|
|
9950
10071
|
db.transaction(() => {
|
|
10072
|
+
const existing = db.prepare("SELECT project_path FROM session_projects WHERE session_id = ? AND harness = ?").get(sessionId, harness);
|
|
10073
|
+
previousProjectPath = existing?.project_path;
|
|
9951
10074
|
getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
|
|
9952
10075
|
getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath, SESSION_CHUNK_REPAIR_BATCH_SIZE);
|
|
9953
10076
|
}).immediate();
|
|
10077
|
+
return previousProjectPath === projectPath ? undefined : { previousProjectPath, projectPath };
|
|
9954
10078
|
}
|
|
9955
10079
|
function hasRecordedSessionProjectIdentity(db, sessionId) {
|
|
9956
10080
|
const row = db.prepare("SELECT 1 AS found FROM session_projects WHERE session_id = ? AND harness = ?").get(sessionId, getHarness());
|
|
@@ -10384,6 +10508,29 @@ function commitCompactionModeRecord(db, sessionId, record) {
|
|
|
10384
10508
|
setCompactionModeRecord(db, sessionId, record);
|
|
10385
10509
|
}
|
|
10386
10510
|
|
|
10511
|
+
// src/hooks/magic-context/historian-drain-gate.ts
|
|
10512
|
+
var loggedWindows = new WeakMap;
|
|
10513
|
+
function isHistorianDrainBudgetSpent(args) {
|
|
10514
|
+
const target = deriveProtectedTailTokenTarget(args);
|
|
10515
|
+
const state = getProtectedTailDrainBudgetSkip({
|
|
10516
|
+
...args,
|
|
10517
|
+
usable: target.usable,
|
|
10518
|
+
perRunCap: selectPerRunCap({ ...args, N: target.N })
|
|
10519
|
+
});
|
|
10520
|
+
if (!state)
|
|
10521
|
+
return false;
|
|
10522
|
+
let windows = loggedWindows.get(args.db);
|
|
10523
|
+
if (!windows) {
|
|
10524
|
+
windows = new Map;
|
|
10525
|
+
loggedWindows.set(args.db, windows);
|
|
10526
|
+
}
|
|
10527
|
+
if (windows.get(args.sessionId) !== state.resetsAt) {
|
|
10528
|
+
windows.set(args.sessionId, state.resetsAt);
|
|
10529
|
+
sessionLog(args.sessionId, `historian skip: internal drain budget spent (${state.spentTokens}/${state.limitTokens} tokens); next eligible at ${new Date(state.nextEligibleAt).toISOString()}`);
|
|
10530
|
+
}
|
|
10531
|
+
return true;
|
|
10532
|
+
}
|
|
10533
|
+
|
|
10387
10534
|
// src/features/magic-context/storage-reasoning-removal.ts
|
|
10388
10535
|
var NAMESPACE2 = "reasoningRemoval";
|
|
10389
10536
|
var BACKUP_NAMESPACE = "reasoningRemovalBackup";
|
|
@@ -11375,7 +11522,7 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
11375
11522
|
taggerFloor,
|
|
11376
11523
|
storedTotalsExcludeToolTags
|
|
11377
11524
|
});
|
|
11378
|
-
const hasProtectedEligibleHead = boundary.offset < boundary.protectedTailStart;
|
|
11525
|
+
const hasProtectedEligibleHead = boundary.offset < Math.min(boundary.protectedTailStart, boundary.eligibleEndOrdinal);
|
|
11379
11526
|
if (!hasProtectedEligibleHead) {
|
|
11380
11527
|
return {
|
|
11381
11528
|
...TAIL_INFO_DEFAULTS,
|
|
@@ -11387,7 +11534,7 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
11387
11534
|
const seed = sessionDecisionCalibration(db, sessionId);
|
|
11388
11535
|
const sourceRatio = Math.max(seed.proseRatio, seed.toolsRatio);
|
|
11389
11536
|
const scanBudget = Math.floor(Math.max(MIN_PROACTIVE_TAIL_TOKEN_ESTIMATE, triggerBudget * TAIL_SIZE_TRIGGER_MULTIPLIER) / sourceRatio);
|
|
11390
|
-
const chunk = readSessionChunk2(sessionId, scanBudget, rawEligibility.offset, boundary.
|
|
11537
|
+
const chunk = readSessionChunk2(sessionId, scanBudget, rawEligibility.offset, boundary.eligibleEndOrdinal);
|
|
11391
11538
|
const isMeaningful = chunk.hasMore || boundary.trueRawEligibleTokens >= MIN_PROACTIVE_TAIL_TOKEN_ESTIMATE || Math.ceil(chunk.tokenEstimate * sourceRatio) >= MIN_PROACTIVE_TAIL_TOKEN_ESTIMATE || chunk.messageCount >= MIN_PROACTIVE_TAIL_MESSAGE_COUNT;
|
|
11392
11539
|
return {
|
|
11393
11540
|
nextStartOrdinal: rawEligibility.offset,
|
|
@@ -11414,6 +11561,14 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
11414
11561
|
sessionLog(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
|
|
11415
11562
|
return { shouldFire: false };
|
|
11416
11563
|
}
|
|
11564
|
+
if (isHistorianDrainBudgetSpent({
|
|
11565
|
+
db,
|
|
11566
|
+
sessionId,
|
|
11567
|
+
usagePercentage: usage.percentage,
|
|
11568
|
+
contextLimit: resolveBoundaryContextLimit(usage, contextLimit),
|
|
11569
|
+
executeThresholdPercentage
|
|
11570
|
+
}))
|
|
11571
|
+
return { shouldFire: false };
|
|
11417
11572
|
const lazyInMemoryTail = typeof inMemoryTail === "function" ? inMemoryTail : undefined;
|
|
11418
11573
|
let resolvedInMemoryTail = typeof inMemoryTail === "function" ? undefined : inMemoryTail;
|
|
11419
11574
|
if (resolvedInMemoryTail) {
|
|
@@ -11927,8 +12082,24 @@ function historianJoinFailClosedMessage(input) {
|
|
|
11927
12082
|
return `historian did not complete within ${seconds} s: ${reason}`;
|
|
11928
12083
|
}
|
|
11929
12084
|
function runCompartmentPhase(args) {
|
|
12085
|
+
if (args.historianRunnable !== false && !args.compactionOff && args.canRunCompartments && !getActiveCompartmentRun(args.sessionId) && (args.sessionMeta.compartmentInProgress || args.contextUsage.percentage >= BLOCK_UNTIL_DONE_PERCENTAGE) && isHistorianDrainBudgetSpent({
|
|
12086
|
+
db: args.db,
|
|
12087
|
+
sessionId: args.sessionId,
|
|
12088
|
+
contextLimit: args.boundaryContextLimit,
|
|
12089
|
+
executeThresholdPercentage: args.boundaryExecuteThresholdPercentage,
|
|
12090
|
+
usagePercentage: args.boundaryUsage.percentage
|
|
12091
|
+
})) {
|
|
12092
|
+
if (args.sessionMeta.compartmentInProgress) {
|
|
12093
|
+
updateSessionMeta(args.db, args.sessionId, { compartmentInProgress: false });
|
|
12094
|
+
}
|
|
12095
|
+
return runCompartmentPhaseImpl({
|
|
12096
|
+
...args,
|
|
12097
|
+
canRunCompartments: false,
|
|
12098
|
+
sessionMeta: { compartmentInProgress: false }
|
|
12099
|
+
});
|
|
12100
|
+
}
|
|
11930
12101
|
const historianRunnable = args.historianRunnable !== false;
|
|
11931
|
-
const willReadRawHistory = historianRunnable && !args.compactionOff && args.canRunCompartments && getActiveCompartmentRun(args.sessionId) === undefined &&
|
|
12102
|
+
const willReadRawHistory = historianRunnable && !args.compactionOff && args.canRunCompartments && getActiveCompartmentRun(args.sessionId) === undefined && args.contextUsage.percentage >= BLOCK_UNTIL_DONE_PERCENTAGE;
|
|
11932
12103
|
if (!willReadRawHistory) {
|
|
11933
12104
|
return runCompartmentPhaseImpl(args);
|
|
11934
12105
|
}
|
|
@@ -12054,7 +12225,7 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
12054
12225
|
compartmentInProgress = false;
|
|
12055
12226
|
}
|
|
12056
12227
|
if (historianRunnable && args.canRunCompartments && args.sessionMeta.compartmentInProgress && !getActiveCompartmentRun(args.sessionId)) {
|
|
12057
|
-
if (!hasEligibleHistoryForCompartment()) {
|
|
12228
|
+
if (args.contextUsage.percentage >= BLOCK_UNTIL_DONE_PERCENTAGE && !hasEligibleHistoryForCompartment()) {
|
|
12058
12229
|
sessionLog(args.sessionId, `transform: skipping compartment start, no eligible history before protected tail (beyond ${lastObservedCompartmentEnd})`);
|
|
12059
12230
|
updateSessionMeta(args.db, args.sessionId, { compartmentInProgress: false });
|
|
12060
12231
|
compartmentInProgress = false;
|
|
@@ -12071,7 +12242,7 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
12071
12242
|
db: args.db,
|
|
12072
12243
|
sessionId: args.sessionId,
|
|
12073
12244
|
historianChunkTokens: args.historianChunkTokens,
|
|
12074
|
-
boundarySnapshot:
|
|
12245
|
+
boundarySnapshot: args.preResolvedBoundarySnapshot,
|
|
12075
12246
|
currentContextLimit: args.boundaryContextLimit,
|
|
12076
12247
|
historyBudgetTokens: args.historyBudgetTokens,
|
|
12077
12248
|
historianTimeoutMs: args.historianTimeoutMs,
|
|
@@ -12089,6 +12260,12 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
12089
12260
|
autoPromote: args.autoPromote,
|
|
12090
12261
|
onCompartmentStatePublished: args.onCompartmentStatePublished,
|
|
12091
12262
|
preserveInjectionCacheUntilConsumed: true
|
|
12263
|
+
}, undefined, () => {
|
|
12264
|
+
const snapshot = getBoundarySnapshotForCompartment();
|
|
12265
|
+
if (snapshot && hasRunnableCompartmentWindow(snapshot))
|
|
12266
|
+
return snapshot;
|
|
12267
|
+
sessionLog(args.sessionId, `transform: skipping compartment start, no eligible history before protected tail (beyond ${lastObservedCompartmentEnd})`);
|
|
12268
|
+
return null;
|
|
12092
12269
|
});
|
|
12093
12270
|
compartmentInProgress = true;
|
|
12094
12271
|
}
|
|
@@ -15833,19 +16010,33 @@ function createTransform(deps) {
|
|
|
15833
16010
|
if (false) {}
|
|
15834
16011
|
return false;
|
|
15835
16012
|
};
|
|
15836
|
-
const startRecoveryRun = () => {
|
|
15837
|
-
|
|
15838
|
-
|
|
15839
|
-
|
|
15840
|
-
|
|
15841
|
-
|
|
15842
|
-
|
|
15843
|
-
|
|
16013
|
+
const startRecoveryRun = (onReady) => {
|
|
16014
|
+
if (isHistorianDrainBudgetSpent({
|
|
16015
|
+
db,
|
|
16016
|
+
sessionId,
|
|
16017
|
+
contextLimit: boundaryContextLimit,
|
|
16018
|
+
executeThresholdPercentage: boundaryExecuteThreshold,
|
|
16019
|
+
usagePercentage: boundaryUsageForProtectedTail.percentage
|
|
16020
|
+
}))
|
|
15844
16021
|
return false;
|
|
15845
|
-
|
|
15846
|
-
|
|
16022
|
+
if (!canRunCompartments || !deps.client && !deps.hiddenCompletionExecutor || getActiveCompartmentRun(sessionId))
|
|
16023
|
+
return false;
|
|
16024
|
+
const prepareRecoveryBoundary = () => {
|
|
16025
|
+
const scale = emergencyUsagePercentageEarly >= 95 ? 0.25 : 0.5;
|
|
16026
|
+
let boundarySnapshot = getRunnableBoundaryForCompartment();
|
|
16027
|
+
if (!boundarySnapshot || !hasRunnableCompartmentWindow(boundarySnapshot)) {
|
|
16028
|
+
boundarySnapshot = getRunnableBoundaryForCompartment(scale);
|
|
16029
|
+
}
|
|
16030
|
+
if (false) {}
|
|
16031
|
+
if (!boundarySnapshot || !hasRunnableCompartmentWindow(boundarySnapshot))
|
|
16032
|
+
return null;
|
|
16033
|
+
onReady?.();
|
|
16034
|
+
return boundarySnapshot;
|
|
16035
|
+
};
|
|
16036
|
+
const urgent = emergencyUsagePercentageEarly >= 95;
|
|
16037
|
+
const boundarySnapshot = urgent ? prepareRecoveryBoundary() : undefined;
|
|
16038
|
+
if (urgent && !boundarySnapshot)
|
|
15847
16039
|
return false;
|
|
15848
|
-
}
|
|
15849
16040
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
15850
16041
|
startCompartmentAgent({
|
|
15851
16042
|
client: deps.client,
|
|
@@ -15854,7 +16045,7 @@ function createTransform(deps) {
|
|
|
15854
16045
|
db,
|
|
15855
16046
|
sessionId,
|
|
15856
16047
|
historianChunkTokens: historianRun?.chunkTokens ?? deps.getHistorianChunkTokens?.() ?? 20000,
|
|
15857
|
-
boundarySnapshot,
|
|
16048
|
+
boundarySnapshot: boundarySnapshot ?? undefined,
|
|
15858
16049
|
currentContextLimit: boundaryContextLimit,
|
|
15859
16050
|
historyBudgetTokens,
|
|
15860
16051
|
historianTimeoutMs: historianRun?.timeoutMs ?? deps.historianTimeoutMs,
|
|
@@ -15874,7 +16065,7 @@ function createTransform(deps) {
|
|
|
15874
16065
|
deferredHistoryRefreshSessions.add(sid);
|
|
15875
16066
|
deferredMaterializationSessions.add(sid);
|
|
15876
16067
|
}
|
|
15877
|
-
});
|
|
16068
|
+
}, undefined, urgent ? undefined : prepareRecoveryBoundary);
|
|
15878
16069
|
return true;
|
|
15879
16070
|
};
|
|
15880
16071
|
if (fullFeatureMode && !compactionOff && historianFailureState.failureCount > 0 && emergencyUsagePercentageEarly >= 95 && !recoveryNoHeadEscapeActive) {
|
|
@@ -15888,13 +16079,15 @@ function createTransform(deps) {
|
|
|
15888
16079
|
sessionLog(sessionId, "transform: emergency recovery remains armed — no complete eligible head before protected tail");
|
|
15889
16080
|
}
|
|
15890
16081
|
sessionLog(sessionId, `EMERGENCY: historian recovery requested at ${emergencyPercentage}%, failures: ${historianFailureState.failureCount}`);
|
|
15891
|
-
} else if (fullFeatureMode && !compactionOff && isFirstTransformPassForSession && historianFailureState.failureCount > 0
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
16082
|
+
} else if (fullFeatureMode && !compactionOff && isFirstTransformPassForSession && historianFailureState.failureCount > 0) {
|
|
16083
|
+
startRecoveryRun(() => {
|
|
16084
|
+
sessionLog(sessionId, `transform: historian recovery triggered on session load after ${historianFailureState.failureCount} failure(s)`);
|
|
16085
|
+
if (deps.client) {
|
|
16086
|
+
withoutSqliteTransformPass(() => sendStatusNotification2(deps.client, sessionId, `## Historian recovery
|
|
15895
16087
|
|
|
15896
16088
|
Historian previously failed ${historianFailureState.failureCount} time(s), so Magic Context is retrying history comparting immediately after restart.`, notificationParams));
|
|
15897
|
-
|
|
16089
|
+
}
|
|
16090
|
+
});
|
|
15898
16091
|
}
|
|
15899
16092
|
logTransformTiming(sessionId, "emergencyRecoveryBlock", tFirstPass);
|
|
15900
16093
|
const memoryProjectDirectory = compartmentDirectory || process.cwd();
|
|
@@ -16441,7 +16634,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16441
16634
|
input: lkgInput,
|
|
16442
16635
|
output: messages,
|
|
16443
16636
|
modelKey,
|
|
16444
|
-
providerKey
|
|
16637
|
+
providerKey,
|
|
16638
|
+
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
16639
|
+
agentName: notificationParams?.agent
|
|
16445
16640
|
});
|
|
16446
16641
|
if (captured) {
|
|
16447
16642
|
const capturedSlot = getInMemorySlot(sessionId);
|
|
@@ -17855,8 +18050,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
17855
18050
|
const db = readDatabase();
|
|
17856
18051
|
if (!db)
|
|
17857
18052
|
return { ok: false, error: "db unavailable" };
|
|
17858
|
-
const { runManagedRecomp } = await import("./recomp-orchestrator-
|
|
17859
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
18053
|
+
const { runManagedRecomp } = await import("./recomp-orchestrator-vc5dkzy2.js");
|
|
18054
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-rnc4nrsr.js");
|
|
17860
18055
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
17861
18056
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
17862
18057
|
return {
|
|
@@ -17905,7 +18100,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
17905
18100
|
const db = readDatabase();
|
|
17906
18101
|
if (!db)
|
|
17907
18102
|
return { ok: false, error: "db unavailable" };
|
|
17908
|
-
const { runManagedWrapup } = await import("./wrapup-orchestrator-
|
|
18103
|
+
const { runManagedWrapup } = await import("./wrapup-orchestrator-x9xamts2.js");
|
|
17909
18104
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
17910
18105
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
17911
18106
|
const ctx = {
|
|
@@ -18646,7 +18841,8 @@ function hostUsesMediaAssets() {
|
|
|
18646
18841
|
schemaUsesAssets.set(messageClass, uses);
|
|
18647
18842
|
return uses;
|
|
18648
18843
|
}
|
|
18649
|
-
function decodeThroughHostSchema(
|
|
18844
|
+
function decodeThroughHostSchema(encoded) {
|
|
18845
|
+
const source = encoded.source;
|
|
18650
18846
|
const messageClass = rememberedMessageClass;
|
|
18651
18847
|
if (!messageClass)
|
|
18652
18848
|
return "no host message class seen";
|
|
@@ -18666,7 +18862,7 @@ function decodeThroughHostSchema(source) {
|
|
|
18666
18862
|
const run = decode?.run;
|
|
18667
18863
|
if (typeof run !== "function")
|
|
18668
18864
|
return "host media schema has no decode transformation";
|
|
18669
|
-
const result = run.call(decode, { _tag: "Some", value:
|
|
18865
|
+
const result = run.call(decode, { _tag: "Some", value: encoded }, {});
|
|
18670
18866
|
const option = result?._tag === "Success" ? result.value : undefined;
|
|
18671
18867
|
const asset = option?._tag === "Some" ? option.value : undefined;
|
|
18672
18868
|
if (!isClassInstance(asset) || asset.source !== source)
|
|
@@ -18674,18 +18870,30 @@ function decodeThroughHostSchema(source) {
|
|
|
18674
18870
|
return asset;
|
|
18675
18871
|
}
|
|
18676
18872
|
function hostMediaAsset(data, mediaType) {
|
|
18677
|
-
|
|
18873
|
+
return hostMediaFromEncoded({ source: { type: "base64", data, mediaType } });
|
|
18874
|
+
}
|
|
18875
|
+
function hostMediaFromEncoded(value) {
|
|
18876
|
+
if (!isRecord3(value.source))
|
|
18877
|
+
return "missing Media.Asset source";
|
|
18878
|
+
const encoded = structuredClone(value);
|
|
18879
|
+
if (encoded.source.type === "bytes") {
|
|
18880
|
+
if (typeof encoded.source.data !== "string")
|
|
18881
|
+
return "bytes media has no JSON codec payload";
|
|
18882
|
+
encoded.source.data = new Uint8Array(Buffer.from(encoded.source.data, "base64"));
|
|
18883
|
+
}
|
|
18884
|
+
if (!["bytes", "base64", "url", "ref"].includes(String(encoded.source.type)))
|
|
18885
|
+
return "unknown Media.Asset source";
|
|
18678
18886
|
let first = "no Media.Asset seen in this process";
|
|
18679
18887
|
if (rememberedAssetClass) {
|
|
18680
18888
|
try {
|
|
18681
|
-
return new rememberedAssetClass(
|
|
18889
|
+
return new rememberedAssetClass(encoded);
|
|
18682
18890
|
} catch (error) {
|
|
18683
18891
|
first = `remembered asset class threw: ${String(error)}`;
|
|
18684
18892
|
}
|
|
18685
18893
|
}
|
|
18686
18894
|
let second;
|
|
18687
18895
|
try {
|
|
18688
|
-
const decoded = decodeThroughHostSchema(
|
|
18896
|
+
const decoded = decodeThroughHostSchema(encoded);
|
|
18689
18897
|
if (typeof decoded !== "string")
|
|
18690
18898
|
return decoded;
|
|
18691
18899
|
second = decoded;
|
|
@@ -18703,9 +18911,12 @@ var v2CompactionMarkerStrategy = {
|
|
|
18703
18911
|
reconcile: () => false
|
|
18704
18912
|
};
|
|
18705
18913
|
|
|
18914
|
+
// src/v2/fold/memory-cache.ts
|
|
18915
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
18916
|
+
|
|
18706
18917
|
// src/v2/fold/owner.ts
|
|
18707
|
-
import { createHash as
|
|
18708
|
-
var foldDigest = (value) =>
|
|
18918
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
18919
|
+
var foldDigest = (value) => createHash6("sha256").update(value).digest("hex");
|
|
18709
18920
|
|
|
18710
18921
|
class FoldOwner {
|
|
18711
18922
|
storage;
|
|
@@ -18785,78 +18996,693 @@ class FoldOwner {
|
|
|
18785
18996
|
}
|
|
18786
18997
|
}
|
|
18787
18998
|
|
|
18788
|
-
// src/v2/fold/
|
|
18789
|
-
|
|
18999
|
+
// src/v2/fold/memory-cache.ts
|
|
19000
|
+
var DEFAULT_NATIVE_FOLD_BUDGET = Object.freeze({
|
|
19001
|
+
maxSessionBytes: 16 * 1024 * 1024,
|
|
19002
|
+
maxSessions: 16
|
|
19003
|
+
});
|
|
19004
|
+
var stringBytes = (value) => (value?.length ?? 0) * 2;
|
|
19005
|
+
|
|
19006
|
+
class NativeFoldCache {
|
|
19007
|
+
resolveDB;
|
|
19008
|
+
sourceID = randomUUID2();
|
|
19009
|
+
tails = new Map;
|
|
19010
|
+
nativeRows = new Map;
|
|
19011
|
+
admissions = new Map;
|
|
19012
|
+
retention = new Map;
|
|
19013
|
+
evictionListeners = new Set;
|
|
19014
|
+
budget;
|
|
19015
|
+
constructor(resolveDB, budget = DEFAULT_NATIVE_FOLD_BUDGET) {
|
|
19016
|
+
this.resolveDB = resolveDB;
|
|
19017
|
+
if (!Number.isSafeInteger(budget.maxSessionBytes) || budget.maxSessionBytes < 1 || !Number.isSafeInteger(budget.maxSessions) || budget.maxSessions < 1)
|
|
19018
|
+
throw new Error("Native fold cache budgets must be positive integers");
|
|
19019
|
+
this.budget = { ...budget };
|
|
19020
|
+
}
|
|
19021
|
+
onEvict(listener) {
|
|
19022
|
+
this.evictionListeners.add(listener);
|
|
19023
|
+
}
|
|
19024
|
+
touch(sessionID) {
|
|
19025
|
+
const state = this.retention.get(sessionID) ?? { active: 0, bytes: 0, replayBytes: 0 };
|
|
19026
|
+
this.retention.delete(sessionID);
|
|
19027
|
+
this.retention.set(sessionID, state);
|
|
19028
|
+
return state;
|
|
19029
|
+
}
|
|
19030
|
+
hold(sessionID) {
|
|
19031
|
+
const state = this.touch(sessionID);
|
|
19032
|
+
state.active++;
|
|
19033
|
+
return () => {
|
|
19034
|
+
state.active--;
|
|
19035
|
+
this.enforceBudget();
|
|
19036
|
+
};
|
|
19037
|
+
}
|
|
19038
|
+
accountReplay(sessionID, bytes) {
|
|
19039
|
+
this.touch(sessionID).replayBytes = bytes;
|
|
19040
|
+
this.recount(sessionID);
|
|
19041
|
+
}
|
|
19042
|
+
usage() {
|
|
19043
|
+
return {
|
|
19044
|
+
sessions: this.retention.size,
|
|
19045
|
+
bytes: [...this.retention.values()].reduce((total, state) => total + state.bytes, 0)
|
|
19046
|
+
};
|
|
19047
|
+
}
|
|
19048
|
+
recount(sessionID) {
|
|
19049
|
+
const state = this.touch(sessionID);
|
|
19050
|
+
let bytes = 256 + stringBytes(sessionID) + state.replayBytes;
|
|
19051
|
+
const tail = this.tails.get(sessionID);
|
|
19052
|
+
if (tail)
|
|
19053
|
+
bytes += 128 + stringBytes(tail.data) + stringBytes(tail.digest);
|
|
19054
|
+
for (const row of this.nativeRows.get(sessionID)?.values() ?? [])
|
|
19055
|
+
bytes += 256 + stringBytes(row.id) + stringBytes(row.type) + stringBytes(row.data) + stringBytes(row.digest);
|
|
19056
|
+
for (const row of this.admissions.get(sessionID)?.values() ?? [])
|
|
19057
|
+
bytes += 256 + stringBytes(row.admission_id) + stringBytes(row.status) + stringBytes(row.owner_token) + stringBytes(row.data) + stringBytes(row.payload) + stringBytes(row.digest);
|
|
19058
|
+
state.bytes = bytes;
|
|
19059
|
+
this.enforceBudget();
|
|
19060
|
+
}
|
|
19061
|
+
enforceBudget() {
|
|
19062
|
+
for (const [id, state] of this.retention)
|
|
19063
|
+
if (!state.active && state.bytes > this.budget.maxSessionBytes)
|
|
19064
|
+
this.evict(id);
|
|
19065
|
+
for (const [id, state] of this.retention) {
|
|
19066
|
+
if (this.retention.size <= this.budget.maxSessions)
|
|
19067
|
+
break;
|
|
19068
|
+
if (!state.active)
|
|
19069
|
+
this.evict(id);
|
|
19070
|
+
}
|
|
19071
|
+
}
|
|
19072
|
+
evict(sessionID) {
|
|
19073
|
+
this.tails.delete(sessionID);
|
|
19074
|
+
this.nativeRows.delete(sessionID);
|
|
19075
|
+
this.admissions.delete(sessionID);
|
|
19076
|
+
this.retention.delete(sessionID);
|
|
19077
|
+
for (const listener of this.evictionListeners)
|
|
19078
|
+
listener(sessionID);
|
|
19079
|
+
}
|
|
19080
|
+
get db() {
|
|
19081
|
+
return this.resolveDB();
|
|
19082
|
+
}
|
|
19083
|
+
tail(sessionID) {
|
|
19084
|
+
const record = this.tails.get(sessionID);
|
|
19085
|
+
if (record)
|
|
19086
|
+
this.touch(sessionID);
|
|
19087
|
+
return record && { ...record };
|
|
19088
|
+
}
|
|
19089
|
+
async saveTail(sessionID, data, rows) {
|
|
19090
|
+
this.tails.set(sessionID, {
|
|
19091
|
+
revision: (this.tails.get(sessionID)?.revision ?? -1) + 1,
|
|
19092
|
+
data,
|
|
19093
|
+
digest: foldDigest(data)
|
|
19094
|
+
});
|
|
19095
|
+
const kept = this.nativeRows.get(sessionID) ?? new Map;
|
|
19096
|
+
for (const row of rows)
|
|
19097
|
+
kept.set(row.id, Object.freeze({ ...row, revision: (kept.get(row.id)?.revision ?? -1) + 1 }));
|
|
19098
|
+
this.nativeRows.set(sessionID, kept);
|
|
19099
|
+
this.recount(sessionID);
|
|
19100
|
+
}
|
|
19101
|
+
replaceRows(sessionID, through, rows, after = -1) {
|
|
19102
|
+
const kept = this.nativeRows.get(sessionID) ?? new Map;
|
|
19103
|
+
for (const [id, row] of kept)
|
|
19104
|
+
if (row.seq > after && row.seq <= through)
|
|
19105
|
+
kept.delete(id);
|
|
19106
|
+
for (const row of rows)
|
|
19107
|
+
kept.set(row.id, Object.freeze({ ...row, revision: 0 }));
|
|
19108
|
+
this.nativeRows.set(sessionID, kept);
|
|
19109
|
+
this.recount(sessionID);
|
|
19110
|
+
}
|
|
19111
|
+
truncate(sessionID, through) {
|
|
19112
|
+
const kept = this.nativeRows.get(sessionID);
|
|
19113
|
+
if (kept) {
|
|
19114
|
+
for (const [id, row] of kept)
|
|
19115
|
+
if (row.seq > through)
|
|
19116
|
+
kept.delete(id);
|
|
19117
|
+
}
|
|
19118
|
+
if (kept)
|
|
19119
|
+
this.recount(sessionID);
|
|
19120
|
+
}
|
|
19121
|
+
sequenceForID(sessionID, id) {
|
|
19122
|
+
return this.nativeRows.get(sessionID)?.get(id)?.seq;
|
|
19123
|
+
}
|
|
19124
|
+
containsRows(sessionID, ids) {
|
|
19125
|
+
const kept = this.nativeRows.get(sessionID);
|
|
19126
|
+
return ids.every((id) => kept?.has(id));
|
|
19127
|
+
}
|
|
19128
|
+
rows(sessionID, after, through) {
|
|
19129
|
+
if (this.retention.has(sessionID))
|
|
19130
|
+
this.touch(sessionID);
|
|
19131
|
+
return [...this.nativeRows.get(sessionID)?.values() ?? []].filter((row) => row.seq > after && row.seq <= through).sort((a, b) => a.seq - b.seq).map((row) => ({ ...row }));
|
|
19132
|
+
}
|
|
19133
|
+
admission(sessionID, id) {
|
|
19134
|
+
const record = this.admissions.get(sessionID)?.get(id);
|
|
19135
|
+
if (record)
|
|
19136
|
+
this.touch(sessionID);
|
|
19137
|
+
return record && { ...record };
|
|
19138
|
+
}
|
|
19139
|
+
put(sessionID, id, record) {
|
|
19140
|
+
const kept = this.admissions.get(sessionID) ?? new Map;
|
|
19141
|
+
kept.set(id, Object.freeze({ ...record }));
|
|
19142
|
+
this.admissions.set(sessionID, kept);
|
|
19143
|
+
this.recount(sessionID);
|
|
19144
|
+
}
|
|
19145
|
+
async supply(sessionID, id, payload) {
|
|
19146
|
+
const old = this.admission(sessionID, id);
|
|
19147
|
+
this.put(sessionID, id, {
|
|
19148
|
+
admission_id: id,
|
|
19149
|
+
revision: (old?.revision ?? -1) + 1,
|
|
19150
|
+
status: old?.status ?? "supplied",
|
|
19151
|
+
owner_token: old?.owner_token ?? null,
|
|
19152
|
+
data: old?.data ?? "{}",
|
|
19153
|
+
payload,
|
|
19154
|
+
digest: foldDigest(payload),
|
|
19155
|
+
logged_at: old?.logged_at ?? null
|
|
19156
|
+
});
|
|
19157
|
+
}
|
|
19158
|
+
latestAttempt(sessionID) {
|
|
19159
|
+
const record = [...this.admissions.get(sessionID)?.values() ?? []].reverse().find((row) => JSON.parse(row.data).after !== undefined);
|
|
19160
|
+
return record && { ...record };
|
|
19161
|
+
}
|
|
19162
|
+
async claim(sessionID, id, data, owner, _now) {
|
|
19163
|
+
const old = this.admission(sessionID, id);
|
|
19164
|
+
if (old?.owner_token || old?.logged_at !== null && old?.logged_at !== undefined)
|
|
19165
|
+
return false;
|
|
19166
|
+
this.put(sessionID, id, {
|
|
19167
|
+
admission_id: id,
|
|
19168
|
+
revision: 0,
|
|
19169
|
+
status: "pending",
|
|
19170
|
+
owner_token: owner,
|
|
19171
|
+
data,
|
|
19172
|
+
payload: old?.payload ?? null,
|
|
19173
|
+
digest: old?.digest ?? null,
|
|
19174
|
+
logged_at: null
|
|
19175
|
+
});
|
|
19176
|
+
return true;
|
|
19177
|
+
}
|
|
19178
|
+
async finish(sessionID, id, owner, status, now) {
|
|
19179
|
+
const old = this.admission(sessionID, id);
|
|
19180
|
+
if (!old || old.owner_token !== owner || old.status !== "pending")
|
|
19181
|
+
return false;
|
|
19182
|
+
this.put(sessionID, id, { ...old, status, owner_token: null, logged_at: now });
|
|
19183
|
+
return true;
|
|
19184
|
+
}
|
|
19185
|
+
async forget(sessionID) {
|
|
19186
|
+
this.evict(sessionID);
|
|
19187
|
+
}
|
|
19188
|
+
}
|
|
19189
|
+
function nativeFoldCache(db, budget) {
|
|
19190
|
+
return new NativeFoldCache(typeof db === "function" ? db : () => db, budget);
|
|
19191
|
+
}
|
|
18790
19192
|
|
|
18791
|
-
// src/v2/
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
return
|
|
19193
|
+
// src/v2/tool-result.ts
|
|
19194
|
+
function isToolError(part) {
|
|
19195
|
+
const result = part.result;
|
|
19196
|
+
return part.resultType === "error" || result?.type === "error" || result !== null && typeof result === "object" && "error" in result;
|
|
18795
19197
|
}
|
|
18796
|
-
function
|
|
18797
|
-
|
|
19198
|
+
function toolErrorText(result) {
|
|
19199
|
+
const value = result.value === undefined ? result : result.value;
|
|
19200
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
18798
19201
|
}
|
|
18799
|
-
function
|
|
18800
|
-
|
|
19202
|
+
function toolStateContent(state) {
|
|
19203
|
+
if (typeof state.output === "string")
|
|
19204
|
+
return state.output;
|
|
19205
|
+
if (state.status === "error")
|
|
19206
|
+
return toolErrorText({ error: state.error, content: state.content ?? [] });
|
|
19207
|
+
if (typeof state.content === "string")
|
|
19208
|
+
return state.content;
|
|
19209
|
+
if (!Array.isArray(state.content))
|
|
19210
|
+
return "";
|
|
19211
|
+
return state.content.map((part) => {
|
|
19212
|
+
if (typeof part === "string")
|
|
19213
|
+
return part;
|
|
19214
|
+
if (!part || typeof part !== "object")
|
|
19215
|
+
return "";
|
|
19216
|
+
const value = part;
|
|
19217
|
+
if (typeof value.text === "string")
|
|
19218
|
+
return value.text;
|
|
19219
|
+
if (typeof value.value === "string")
|
|
19220
|
+
return value.value;
|
|
19221
|
+
return "";
|
|
19222
|
+
}).filter(Boolean).join(`
|
|
19223
|
+
`);
|
|
18801
19224
|
}
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
19225
|
+
|
|
19226
|
+
// src/v2/hooks/payload.ts
|
|
19227
|
+
var HEAD_IDS = ["__magic_context_v2_m0__", "__magic_context_v2_m1__"];
|
|
19228
|
+
var HOST_CONTENT_TYPES = new Set([
|
|
19229
|
+
"text",
|
|
19230
|
+
"media",
|
|
19231
|
+
"tool-call",
|
|
19232
|
+
"tool-result",
|
|
19233
|
+
"reasoning",
|
|
19234
|
+
"compaction",
|
|
19235
|
+
"effort"
|
|
19236
|
+
]);
|
|
19237
|
+
function rejectContentPart(message, part, reason) {
|
|
19238
|
+
const type = typeof part.type === "string" ? part.type : "<missing>";
|
|
19239
|
+
const text = `v2 context omitted a content part the host would reject: type=${type} message=${String(message.info.id ?? "<head>")} reason=${reason}`;
|
|
19240
|
+
if (typeof message.info.sessionID === "string")
|
|
19241
|
+
sessionLog(message.info.sessionID, text);
|
|
19242
|
+
else
|
|
19243
|
+
log(text);
|
|
19244
|
+
}
|
|
19245
|
+
function isHostInstance(value) {
|
|
19246
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
18806
19247
|
return false;
|
|
18807
|
-
const
|
|
18808
|
-
return
|
|
19248
|
+
const prototype = Object.getPrototypeOf(value);
|
|
19249
|
+
return prototype !== Object.prototype && prototype !== null;
|
|
18809
19250
|
}
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
|
|
18813
|
-
|
|
18814
|
-
|
|
18815
|
-
|
|
18816
|
-
|
|
18817
|
-
|
|
18818
|
-
if (drop.size === 0)
|
|
18819
|
-
return 0;
|
|
18820
|
-
const kept = messages.filter((message) => !drop.has(message));
|
|
18821
|
-
messages.splice(0, messages.length, ...kept);
|
|
18822
|
-
return drop.size;
|
|
19251
|
+
function containsHostInstance(value) {
|
|
19252
|
+
if (isHostInstance(value))
|
|
19253
|
+
return true;
|
|
19254
|
+
if (Array.isArray(value))
|
|
19255
|
+
return value.some(containsHostInstance);
|
|
19256
|
+
if (value && typeof value === "object")
|
|
19257
|
+
return Object.values(value).some(containsHostInstance);
|
|
19258
|
+
return false;
|
|
18823
19259
|
}
|
|
18824
|
-
|
|
18825
|
-
|
|
18826
|
-
|
|
18827
|
-
|
|
19260
|
+
function clonePreservingInstances(value) {
|
|
19261
|
+
if (isHostInstance(value))
|
|
19262
|
+
return value;
|
|
19263
|
+
if (Array.isArray(value))
|
|
19264
|
+
return value.map(clonePreservingInstances);
|
|
19265
|
+
if (value && typeof value === "object") {
|
|
19266
|
+
const copy = {};
|
|
19267
|
+
for (const [key, entry] of Object.entries(value))
|
|
19268
|
+
copy[key] = clonePreservingInstances(entry);
|
|
19269
|
+
return copy;
|
|
19270
|
+
}
|
|
19271
|
+
return value;
|
|
18828
19272
|
}
|
|
18829
|
-
|
|
18830
|
-
|
|
18831
|
-
|
|
18832
|
-
|
|
18833
|
-
|
|
18834
|
-
|
|
18835
|
-
file.mime,
|
|
18836
|
-
file.name ?? null,
|
|
18837
|
-
file.description ?? null,
|
|
18838
|
-
file.mention.text
|
|
18839
|
-
]);
|
|
18840
|
-
const payloads = seen.get(key) ?? new Set;
|
|
18841
|
-
if (payloads.has(file.data))
|
|
18842
|
-
return [];
|
|
18843
|
-
payloads.add(file.data);
|
|
18844
|
-
seen.set(key, payloads);
|
|
19273
|
+
function contentKey(value) {
|
|
19274
|
+
const plain = (entry) => {
|
|
19275
|
+
if (ArrayBuffer.isView(entry)) {
|
|
19276
|
+
return {
|
|
19277
|
+
bytes: Buffer.from(entry.buffer, entry.byteOffset, entry.byteLength).toString("base64")
|
|
19278
|
+
};
|
|
18845
19279
|
}
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
if (
|
|
18849
|
-
|
|
18850
|
-
|
|
18851
|
-
|
|
18852
|
-
|
|
18853
|
-
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
|
|
18858
|
-
|
|
18859
|
-
|
|
19280
|
+
if (Array.isArray(entry))
|
|
19281
|
+
return entry.map(plain);
|
|
19282
|
+
if (entry && typeof entry === "object") {
|
|
19283
|
+
return Object.fromEntries(Object.entries(entry).map(([key, nested]) => [key, plain(nested)]));
|
|
19284
|
+
}
|
|
19285
|
+
return entry;
|
|
19286
|
+
};
|
|
19287
|
+
return JSON.stringify(plain(value));
|
|
19288
|
+
}
|
|
19289
|
+
function fileContentValue(result) {
|
|
19290
|
+
const value = result?.value;
|
|
19291
|
+
if (result?.type !== "content" || !Array.isArray(value))
|
|
19292
|
+
return;
|
|
19293
|
+
return value.some((item) => item?.type === "file") ? value : undefined;
|
|
19294
|
+
}
|
|
19295
|
+
function contentValueText(value) {
|
|
19296
|
+
return value.filter((item) => item?.type === "text" && typeof item.text === "string").map((item) => item.text).join(`
|
|
19297
|
+
`);
|
|
19298
|
+
}
|
|
19299
|
+
function contentValueAttachments(value) {
|
|
19300
|
+
return value.filter((item) => item?.type === "file").map((item) => ({
|
|
19301
|
+
type: "file",
|
|
19302
|
+
mime: item.mime,
|
|
19303
|
+
url: item.uri,
|
|
19304
|
+
...typeof item.name === "string" ? { filename: item.name } : {}
|
|
19305
|
+
}));
|
|
19306
|
+
}
|
|
19307
|
+
function rebuildFileContent(value, output) {
|
|
19308
|
+
if (isDroppedToolOutput(output))
|
|
19309
|
+
return { type: "text", value: output };
|
|
19310
|
+
const rebuilt = [];
|
|
19311
|
+
let placed = false;
|
|
19312
|
+
for (const item of value) {
|
|
19313
|
+
if (item?.type !== "text") {
|
|
19314
|
+
rebuilt.push(item);
|
|
19315
|
+
continue;
|
|
19316
|
+
}
|
|
19317
|
+
if (placed)
|
|
19318
|
+
continue;
|
|
19319
|
+
placed = true;
|
|
19320
|
+
rebuilt.push({ ...item, text: output });
|
|
19321
|
+
}
|
|
19322
|
+
if (!placed && output)
|
|
19323
|
+
rebuilt.unshift({ type: "text", text: output });
|
|
19324
|
+
return { type: "content", value: rebuilt };
|
|
19325
|
+
}
|
|
19326
|
+
function adaptPayload(draft, admittedIDs = new Set) {
|
|
19327
|
+
const existingHeads = new Map(draft.messages.filter((m) => HEAD_IDS.some((id) => m.id === id)).map((m) => [m.id, m]));
|
|
19328
|
+
const source = draft.messages.filter((m) => !existingHeads.has(m.id));
|
|
19329
|
+
const results = new Map;
|
|
19330
|
+
const hostParts = new Map;
|
|
19331
|
+
const hostPartTypes = new Set;
|
|
19332
|
+
for (const message of source) {
|
|
19333
|
+
for (const part of message.content) {
|
|
19334
|
+
if (part.type !== "tool-call" && part.type !== "tool-result" && part.type !== "tool" && containsHostInstance(part)) {
|
|
19335
|
+
const key = contentKey(part);
|
|
19336
|
+
if (!hostParts.has(key))
|
|
19337
|
+
hostParts.set(key, part);
|
|
19338
|
+
hostPartTypes.add(part.type);
|
|
19339
|
+
}
|
|
19340
|
+
if (part.type === "tool-result" && typeof part.id === "string") {
|
|
19341
|
+
const queue = results.get(part.id) ?? [];
|
|
19342
|
+
queue.push({ part, message });
|
|
19343
|
+
results.set(part.id, queue);
|
|
19344
|
+
}
|
|
19345
|
+
}
|
|
19346
|
+
}
|
|
19347
|
+
const paired = new Set;
|
|
19348
|
+
const bridges = new Map;
|
|
19349
|
+
const originals = new Map;
|
|
19350
|
+
const bridgesByMessageID = new Map;
|
|
19351
|
+
const bridgesByCarrier = new Map;
|
|
19352
|
+
const originalsByID = new Map;
|
|
19353
|
+
const bridgesFor = (message) => typeof message.info.id === "string" ? bridgesByMessageID.get(message.info.id) : bridgesByCarrier.get(message);
|
|
19354
|
+
const nativeTool = (call, result) => {
|
|
19355
|
+
const hostResult = result?.part.result;
|
|
19356
|
+
const failed = result !== undefined && isToolError(result.part);
|
|
19357
|
+
const value = hostResult?.value;
|
|
19358
|
+
const files = fileContentValue(hostResult);
|
|
19359
|
+
const output = failed && hostResult ? toolErrorText(hostResult) : files ? contentValueText(files) : typeof value === "string" ? value : value === undefined ? "" : JSON.stringify(value);
|
|
19360
|
+
const part = {
|
|
19361
|
+
type: "tool",
|
|
19362
|
+
callID: call?.id ?? result?.part.id,
|
|
19363
|
+
tool: call?.name ?? result?.part.name,
|
|
19364
|
+
state: {
|
|
19365
|
+
input: structuredClone(call?.input ?? {}),
|
|
19366
|
+
status: failed ? "error" : result ? "completed" : "running",
|
|
19367
|
+
...result ? { output } : {},
|
|
19368
|
+
...result && (call?.name ?? result.part.name) === "question" ? { metadata: { userAnswer: true } } : {},
|
|
19369
|
+
...files ? { attachments: contentValueAttachments(files) } : {}
|
|
19370
|
+
}
|
|
19371
|
+
};
|
|
19372
|
+
bridges.set(part, {
|
|
19373
|
+
call,
|
|
19374
|
+
result: result?.part,
|
|
19375
|
+
resultMessage: result?.message,
|
|
19376
|
+
output,
|
|
19377
|
+
files
|
|
19378
|
+
});
|
|
19379
|
+
if (result)
|
|
19380
|
+
paired.add(result.part);
|
|
19381
|
+
return part;
|
|
19382
|
+
};
|
|
19383
|
+
const convertedTool = (source) => {
|
|
19384
|
+
const sourceState = source.state && typeof source.state === "object" ? source.state : {};
|
|
19385
|
+
const output = toolStateContent(sourceState);
|
|
19386
|
+
const { content: _content, ...projectedState } = structuredClone(sourceState);
|
|
19387
|
+
const part = {
|
|
19388
|
+
type: "tool",
|
|
19389
|
+
callID: source.callID ?? source.id,
|
|
19390
|
+
tool: source.tool ?? source.name,
|
|
19391
|
+
state: { ...projectedState, output }
|
|
19392
|
+
};
|
|
19393
|
+
bridges.set(part, { native: source, output });
|
|
19394
|
+
return part;
|
|
19395
|
+
};
|
|
19396
|
+
const callParts = new Map;
|
|
19397
|
+
for (const message of source) {
|
|
19398
|
+
for (const part of message.content) {
|
|
19399
|
+
if (part.type === "tool-call") {
|
|
19400
|
+
callParts.set(part, nativeTool(part, results.get(String(part.id))?.shift()));
|
|
19401
|
+
} else if (part.type === "tool") {
|
|
19402
|
+
callParts.set(part, convertedTool(part));
|
|
19403
|
+
}
|
|
19404
|
+
}
|
|
19405
|
+
}
|
|
19406
|
+
const messages = [];
|
|
19407
|
+
for (const message of source) {
|
|
19408
|
+
const parts = [];
|
|
19409
|
+
for (const content of message.content) {
|
|
19410
|
+
if (paired.has(content))
|
|
19411
|
+
continue;
|
|
19412
|
+
const part = callParts.get(content) ?? (content.type === "tool-result" ? nativeTool(undefined, { part: content, message }) : clonePreservingInstances(content));
|
|
19413
|
+
if (message.id && admittedIDs.has(message.id))
|
|
19414
|
+
part.synthetic = true;
|
|
19415
|
+
parts.push(part);
|
|
19416
|
+
}
|
|
19417
|
+
if (!parts.length && message.content.length)
|
|
19418
|
+
continue;
|
|
19419
|
+
const byCallID = new Map;
|
|
19420
|
+
for (const part of parts) {
|
|
19421
|
+
const bridge = bridges.get(part);
|
|
19422
|
+
if (bridge && typeof part.callID === "string")
|
|
19423
|
+
byCallID.set(part.callID, bridge);
|
|
19424
|
+
}
|
|
19425
|
+
if (typeof message.id === "string") {
|
|
19426
|
+
bridgesByMessageID.set(message.id, byCallID);
|
|
19427
|
+
originalsByID.set(message.id, message);
|
|
19428
|
+
}
|
|
19429
|
+
const mapped = {
|
|
19430
|
+
info: {
|
|
19431
|
+
id: message.id,
|
|
19432
|
+
sessionID: draft.sessionID,
|
|
19433
|
+
role: message.role,
|
|
19434
|
+
...{
|
|
19435
|
+
providerID: draft.model.providerID,
|
|
19436
|
+
modelID: draft.model.id,
|
|
19437
|
+
agent: draft.agent
|
|
19438
|
+
}
|
|
19439
|
+
},
|
|
19440
|
+
parts
|
|
19441
|
+
};
|
|
19442
|
+
originals.set(mapped, message);
|
|
19443
|
+
if (typeof message.id !== "string")
|
|
19444
|
+
bridgesByCarrier.set(mapped, byCallID);
|
|
19445
|
+
messages.push(mapped);
|
|
19446
|
+
}
|
|
19447
|
+
return {
|
|
19448
|
+
messages,
|
|
19449
|
+
commit() {
|
|
19450
|
+
let head = 0;
|
|
19451
|
+
const rendered = [];
|
|
19452
|
+
for (const message of messages) {
|
|
19453
|
+
const original = originals.get(message) ?? (typeof message.info.id === "string" ? originalsByID.get(message.info.id) : undefined);
|
|
19454
|
+
const id = message.info.syntheticHead ? HEAD_IDS[head++] : original?.id;
|
|
19455
|
+
const content = [];
|
|
19456
|
+
const following = [];
|
|
19457
|
+
for (const candidate of message.parts) {
|
|
19458
|
+
const part = candidate;
|
|
19459
|
+
const bridge = bridges.get(part) ?? (part.type === "tool" && typeof part.callID === "string" ? bridgesFor(message)?.get(part.callID) : undefined);
|
|
19460
|
+
if (!bridge) {
|
|
19461
|
+
if (part.type === "tool") {
|
|
19462
|
+
const state = part.state;
|
|
19463
|
+
if (typeof part.callID !== "string" || typeof part.tool !== "string" || !state || typeof state !== "object") {
|
|
19464
|
+
rejectContentPart(message, part, "tool has no call ID, name, or state");
|
|
19465
|
+
continue;
|
|
19466
|
+
}
|
|
19467
|
+
content.push({
|
|
19468
|
+
type: "tool-call",
|
|
19469
|
+
id: part.callID,
|
|
19470
|
+
name: part.tool,
|
|
19471
|
+
input: state.input
|
|
19472
|
+
});
|
|
19473
|
+
if (state.status === "completed" || state.status === "error") {
|
|
19474
|
+
following.push({
|
|
19475
|
+
role: "tool",
|
|
19476
|
+
content: [
|
|
19477
|
+
{
|
|
19478
|
+
type: "tool-result",
|
|
19479
|
+
id: part.callID,
|
|
19480
|
+
name: part.tool,
|
|
19481
|
+
result: {
|
|
19482
|
+
type: state.status === "error" ? "error" : "text",
|
|
19483
|
+
value: toolStateContent(state)
|
|
19484
|
+
}
|
|
19485
|
+
}
|
|
19486
|
+
]
|
|
19487
|
+
});
|
|
19488
|
+
}
|
|
19489
|
+
continue;
|
|
19490
|
+
}
|
|
19491
|
+
if (part.type === "file") {
|
|
19492
|
+
const mime = part.mime;
|
|
19493
|
+
const url = part.url;
|
|
19494
|
+
const prefix = `data:${mime};base64,`;
|
|
19495
|
+
if (typeof mime !== "string" || !/^image\/(png|jpeg|gif|webp)$/.test(mime) || typeof url !== "string" || !url.startsWith(prefix)) {
|
|
19496
|
+
rejectContentPart(message, part, "file is not an inline supported image");
|
|
19497
|
+
continue;
|
|
19498
|
+
}
|
|
19499
|
+
const asset = hostMediaAsset(url.slice(prefix.length), mime);
|
|
19500
|
+
if (typeof asset === "string") {
|
|
19501
|
+
rejectContentPart(message, part, `host media unavailable: ${asset}`);
|
|
19502
|
+
continue;
|
|
19503
|
+
}
|
|
19504
|
+
content.push({ type: "media", media: asset });
|
|
19505
|
+
continue;
|
|
19506
|
+
}
|
|
19507
|
+
if (!HOST_CONTENT_TYPES.has(String(part.type))) {
|
|
19508
|
+
rejectContentPart(message, part, "unknown host content type");
|
|
19509
|
+
continue;
|
|
19510
|
+
}
|
|
19511
|
+
const { synthetic: _synthetic, ...clean } = part;
|
|
19512
|
+
const original = hostPartTypes.has(clean.type) && !containsHostInstance(clean) ? hostParts.get(contentKey(clean)) : undefined;
|
|
19513
|
+
content.push(original ?? clean);
|
|
19514
|
+
continue;
|
|
19515
|
+
}
|
|
19516
|
+
const state = part.state;
|
|
19517
|
+
if (bridge.native) {
|
|
19518
|
+
const native = bridge.native;
|
|
19519
|
+
const callID = String(native.id ?? native.callID ?? part.callID);
|
|
19520
|
+
const name = String(native.name ?? native.tool ?? part.tool);
|
|
19521
|
+
content.push({ type: "tool-call", id: callID, name, input: state.input });
|
|
19522
|
+
if (state.status === "completed" || state.status === "error") {
|
|
19523
|
+
following.push({
|
|
19524
|
+
role: "tool",
|
|
19525
|
+
content: [
|
|
19526
|
+
{
|
|
19527
|
+
type: "tool-result",
|
|
19528
|
+
id: callID,
|
|
19529
|
+
name,
|
|
19530
|
+
result: {
|
|
19531
|
+
type: state.status === "error" ? "error" : "text",
|
|
19532
|
+
value: state.output
|
|
19533
|
+
}
|
|
19534
|
+
}
|
|
19535
|
+
]
|
|
19536
|
+
});
|
|
19537
|
+
}
|
|
19538
|
+
continue;
|
|
19539
|
+
}
|
|
19540
|
+
if (bridge.call)
|
|
19541
|
+
content.push({ ...bridge.call, input: state.input });
|
|
19542
|
+
if (bridge.result && bridge.resultMessage) {
|
|
19543
|
+
const result = {
|
|
19544
|
+
...bridge.result,
|
|
19545
|
+
result: state.output === bridge.output ? bridge.result.result : bridge.files && typeof state.output === "string" ? rebuildFileContent(bridge.files, state.output) : {
|
|
19546
|
+
type: state.status === "error" ? "error" : "text",
|
|
19547
|
+
value: state.output
|
|
19548
|
+
}
|
|
19549
|
+
};
|
|
19550
|
+
if (bridge.resultMessage === original)
|
|
19551
|
+
content.push(result);
|
|
19552
|
+
else
|
|
19553
|
+
following.push({ ...bridge.resultMessage, content: [result] });
|
|
19554
|
+
}
|
|
19555
|
+
}
|
|
19556
|
+
if (content.length || !original?.content.length) {
|
|
19557
|
+
const value = {
|
|
19558
|
+
...original,
|
|
19559
|
+
id,
|
|
19560
|
+
role: message.info.role ?? "user",
|
|
19561
|
+
content
|
|
19562
|
+
};
|
|
19563
|
+
const existing = id ? existingHeads.get(id) : undefined;
|
|
19564
|
+
rendered.push(existing ? Object.assign(existing, { content }) : value);
|
|
19565
|
+
}
|
|
19566
|
+
rendered.push(...following);
|
|
19567
|
+
}
|
|
19568
|
+
draft.messages.splice(0, draft.messages.length, ...rendered);
|
|
19569
|
+
}
|
|
19570
|
+
};
|
|
19571
|
+
}
|
|
19572
|
+
|
|
19573
|
+
// src/v2/fold/native-codec.ts
|
|
19574
|
+
class NativeReplayUnavailable extends Error {
|
|
19575
|
+
}
|
|
19576
|
+
function encodeNative(messages) {
|
|
19577
|
+
for (const message of messages)
|
|
19578
|
+
for (const part of message.content) {
|
|
19579
|
+
if (part.type !== "media" || !part.media)
|
|
19580
|
+
continue;
|
|
19581
|
+
const asset = part.media;
|
|
19582
|
+
if (typeof asset.toJSON !== "function" || asset.headers !== undefined)
|
|
19583
|
+
throw new NativeReplayUnavailable("Native media has no lossless replay codec");
|
|
19584
|
+
const encoded = asset.toJSON();
|
|
19585
|
+
const revived = hostMediaFromEncoded(encoded);
|
|
19586
|
+
if (typeof revived === "string" || JSON.stringify(revived) !== JSON.stringify(asset))
|
|
19587
|
+
throw new NativeReplayUnavailable("Native media cannot be decoded losslessly before admission");
|
|
19588
|
+
}
|
|
19589
|
+
const encoded = JSON.parse(JSON.stringify(messages));
|
|
19590
|
+
const freeze = (value) => {
|
|
19591
|
+
if (!value || typeof value !== "object")
|
|
19592
|
+
return;
|
|
19593
|
+
for (const item of Object.values(value))
|
|
19594
|
+
freeze(item);
|
|
19595
|
+
Object.freeze(value);
|
|
19596
|
+
};
|
|
19597
|
+
freeze(encoded);
|
|
19598
|
+
return encoded;
|
|
19599
|
+
}
|
|
19600
|
+
function reviveNative(messages) {
|
|
19601
|
+
const result = structuredClone([...messages]);
|
|
19602
|
+
for (const message of result)
|
|
19603
|
+
for (const part of message.content) {
|
|
19604
|
+
if (part.type !== "media" || !part.media)
|
|
19605
|
+
continue;
|
|
19606
|
+
const asset = hostMediaFromEncoded(part.media);
|
|
19607
|
+
if (typeof asset === "string")
|
|
19608
|
+
throw new NativeReplayUnavailable(asset);
|
|
19609
|
+
part.media = asset;
|
|
19610
|
+
}
|
|
19611
|
+
return result;
|
|
19612
|
+
}
|
|
19613
|
+
|
|
19614
|
+
// src/v2/fold/restore.ts
|
|
19615
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19616
|
+
|
|
19617
|
+
// src/v2/hooks/storage-notice.ts
|
|
19618
|
+
var STORAGE_NOTICE_PREFIX = "[Magic Context storage notice] ";
|
|
19619
|
+
function formatStorageRefusalNotice(reason) {
|
|
19620
|
+
return `${STORAGE_NOTICE_PREFIX}This turn was not sent to the model. ${formatFailClosedBlockingSummary(reason)}`;
|
|
19621
|
+
}
|
|
19622
|
+
function formatStorageRecoveryNotice(hiddenWorkRecovered) {
|
|
19623
|
+
return hiddenWorkRecovered ? `${STORAGE_NOTICE_PREFIX}Magic Context storage is available again and turns are sent to the model. The historian and dreamer are running again. Restart OpenCode to enable Magic Context's tools.` : `${STORAGE_NOTICE_PREFIX}Magic Context storage is available again and turns are sent to the model. Restart OpenCode to enable Magic Context's tools, historian and dreamer.`;
|
|
19624
|
+
}
|
|
19625
|
+
function isStorageNoticeText(text) {
|
|
19626
|
+
return typeof text === "string" && text.startsWith(STORAGE_NOTICE_PREFIX);
|
|
19627
|
+
}
|
|
19628
|
+
function hasStorageNoticeShape(message) {
|
|
19629
|
+
if (message.role !== "user" || typeof message.id !== "string")
|
|
19630
|
+
return false;
|
|
19631
|
+
if (message.content.length !== 1)
|
|
19632
|
+
return false;
|
|
19633
|
+
const part = message.content[0];
|
|
19634
|
+
return part?.type === "text" && isStorageNoticeText(part.text);
|
|
19635
|
+
}
|
|
19636
|
+
async function dropStorageNotices(messages, isAdmittedSynthetic) {
|
|
19637
|
+
const drop = new Set;
|
|
19638
|
+
for (const message of messages) {
|
|
19639
|
+
if (!hasStorageNoticeShape(message))
|
|
19640
|
+
continue;
|
|
19641
|
+
if (await isAdmittedSynthetic(message.id))
|
|
19642
|
+
drop.add(message);
|
|
19643
|
+
}
|
|
19644
|
+
if (drop.size === 0)
|
|
19645
|
+
return 0;
|
|
19646
|
+
const kept = messages.filter((message) => !drop.has(message));
|
|
19647
|
+
messages.splice(0, messages.length, ...kept);
|
|
19648
|
+
return drop.size;
|
|
19649
|
+
}
|
|
19650
|
+
|
|
19651
|
+
// src/v2/fold/restore.ts
|
|
19652
|
+
function unavailableAttachmentNote(name, mediaType) {
|
|
19653
|
+
return `[Attachment ${name ? `"${name}" ` : ""}(${mediaType}) is not available in this restored history]`;
|
|
19654
|
+
}
|
|
19655
|
+
var imageMimes = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
|
|
19656
|
+
function attachmentParts(files, rowID, media) {
|
|
19657
|
+
const seen = new Map;
|
|
19658
|
+
return files.flatMap((file) => {
|
|
19659
|
+
if (imageMimes.has(file.mime) && file.source.type === "inline" && file.mention?.text) {
|
|
19660
|
+
const key = JSON.stringify([
|
|
19661
|
+
file.mime,
|
|
19662
|
+
file.name ?? null,
|
|
19663
|
+
file.description ?? null,
|
|
19664
|
+
file.mention.text
|
|
19665
|
+
]);
|
|
19666
|
+
const payloads = seen.get(key) ?? new Set;
|
|
19667
|
+
if (payloads.has(file.data))
|
|
19668
|
+
return [];
|
|
19669
|
+
payloads.add(file.data);
|
|
19670
|
+
seen.set(key, payloads);
|
|
19671
|
+
}
|
|
19672
|
+
const uri = file.source.type === "uri" ? file.source.uri : undefined;
|
|
19673
|
+
const location = uri?.startsWith("file:") ? fileURLToPath2(uri) : undefined;
|
|
19674
|
+
if (file.mime === "text/plain" || file.mime === "application/x-directory") {
|
|
19675
|
+
const directory = file.mime === "application/x-directory";
|
|
19676
|
+
return [
|
|
19677
|
+
{
|
|
19678
|
+
type: "text",
|
|
19679
|
+
text: `
|
|
19680
|
+
|
|
19681
|
+
${[
|
|
19682
|
+
directory ? `Attached directory: ${location ?? file.name ?? uri ?? "directory"}` : `Attached file: ${file.name ?? uri ?? "inline attachment"}`,
|
|
19683
|
+
file.description === undefined ? undefined : `Description: ${file.description}`,
|
|
19684
|
+
directory && !file.data.length ? undefined : "",
|
|
19685
|
+
directory && !file.data.length ? undefined : Buffer.from(file.data, "base64").toString("utf8")
|
|
18860
19686
|
].filter((line) => line !== undefined).join(`
|
|
18861
19687
|
`)}`,
|
|
18862
19688
|
metadata: {
|
|
@@ -18984,33 +19810,422 @@ ${data.output?.output ?? ""}`
|
|
|
18984
19810
|
input = JSON.parse(input);
|
|
18985
19811
|
} catch {}
|
|
18986
19812
|
}
|
|
18987
|
-
content.push({
|
|
18988
|
-
type: "tool-call",
|
|
18989
|
-
id: part.id,
|
|
18990
|
-
name: part.name,
|
|
18991
|
-
input,
|
|
18992
|
-
providerExecuted: part.executed,
|
|
18993
|
-
providerMetadata: toolReuse ? metadata(part.providerState) : undefined
|
|
18994
|
-
});
|
|
18995
|
-
if (!completed)
|
|
18996
|
-
continue;
|
|
18997
|
-
const toolContent = state.content ?? [];
|
|
18998
|
-
const single = toolContent.length === 1 ? toolContent[0] : undefined;
|
|
18999
|
-
const result = {
|
|
19000
|
-
type: "tool-result",
|
|
19001
|
-
id: part.id,
|
|
19002
|
-
name: part.name,
|
|
19003
|
-
providerExecuted: part.executed,
|
|
19004
|
-
providerMetadata: toolReuse ? metadata(part.providerResultState ?? part.providerState) : sameProvider ? metadata(part.providerResultState) : undefined,
|
|
19005
|
-
result: state.status === "error" ? { error: state.error, content: toolContent } : single?.type === "text" ? { type: "text", value: single.text } : { type: "content", value: toolContent },
|
|
19006
|
-
...state.status === "error" ? { resultType: "error" } : {}
|
|
19007
|
-
};
|
|
19008
|
-
if (part.executed === true)
|
|
19009
|
-
content.push(result);
|
|
19010
|
-
else
|
|
19011
|
-
results.push({ role: "tool", content: [result] });
|
|
19813
|
+
content.push({
|
|
19814
|
+
type: "tool-call",
|
|
19815
|
+
id: part.id,
|
|
19816
|
+
name: part.name,
|
|
19817
|
+
input,
|
|
19818
|
+
providerExecuted: part.executed,
|
|
19819
|
+
providerMetadata: toolReuse ? metadata(part.providerState) : undefined
|
|
19820
|
+
});
|
|
19821
|
+
if (!completed)
|
|
19822
|
+
continue;
|
|
19823
|
+
const toolContent = state.content ?? [];
|
|
19824
|
+
const single = toolContent.length === 1 ? toolContent[0] : undefined;
|
|
19825
|
+
const result = {
|
|
19826
|
+
type: "tool-result",
|
|
19827
|
+
id: part.id,
|
|
19828
|
+
name: part.name,
|
|
19829
|
+
providerExecuted: part.executed,
|
|
19830
|
+
providerMetadata: toolReuse ? metadata(part.providerResultState ?? part.providerState) : sameProvider ? metadata(part.providerResultState) : undefined,
|
|
19831
|
+
result: state.status === "error" ? { error: state.error, content: toolContent } : single?.type === "text" ? { type: "text", value: single.text } : { type: "content", value: toolContent },
|
|
19832
|
+
...state.status === "error" ? { resultType: "error" } : {}
|
|
19833
|
+
};
|
|
19834
|
+
if (part.executed === true)
|
|
19835
|
+
content.push(result);
|
|
19836
|
+
else
|
|
19837
|
+
results.push({ role: "tool", content: [result] });
|
|
19838
|
+
}
|
|
19839
|
+
return [...content.length ? [make("assistant", content)] : [], ...results];
|
|
19840
|
+
}
|
|
19841
|
+
|
|
19842
|
+
// src/v2/fold/native-replay.ts
|
|
19843
|
+
var coordinates = new WeakMap;
|
|
19844
|
+
function nativeRowID(message) {
|
|
19845
|
+
return coordinates.get(message) ?? message.id;
|
|
19846
|
+
}
|
|
19847
|
+
function copyNativeInput(messages) {
|
|
19848
|
+
const copies = reviveNative(encodeNative(messages));
|
|
19849
|
+
copies.forEach((copy, i) => {
|
|
19850
|
+
const original = messages[i];
|
|
19851
|
+
const id = original && nativeRowID(original);
|
|
19852
|
+
if (id !== undefined)
|
|
19853
|
+
coordinates.set(copy, id);
|
|
19854
|
+
});
|
|
19855
|
+
return copies;
|
|
19856
|
+
}
|
|
19857
|
+
function isLocalCheckpoint(row) {
|
|
19858
|
+
return row.type === "compaction" && row.data.status === "completed" && row.data.providerContext === undefined;
|
|
19859
|
+
}
|
|
19860
|
+
var conversational = (row) => RAW_MESSAGE_TYPES.includes(row.type) || row.type === "location-switched";
|
|
19861
|
+
|
|
19862
|
+
class NativeFoldReplay {
|
|
19863
|
+
storage;
|
|
19864
|
+
openReader;
|
|
19865
|
+
changed = new Set;
|
|
19866
|
+
dirty = new Set;
|
|
19867
|
+
unavailable = new Set;
|
|
19868
|
+
metadata = new Map;
|
|
19869
|
+
metadataThrough = new Map;
|
|
19870
|
+
loaded = new Map;
|
|
19871
|
+
sources = new Map;
|
|
19872
|
+
constructor(storage, openReader) {
|
|
19873
|
+
this.storage = storage;
|
|
19874
|
+
this.openReader = openReader;
|
|
19875
|
+
storage.onEvict((sessionID) => this.clear(sessionID));
|
|
19876
|
+
}
|
|
19877
|
+
account(sessionID) {
|
|
19878
|
+
const source = this.sources.get(sessionID);
|
|
19879
|
+
let bytes = 256 + (source?.length ?? 0) * 2;
|
|
19880
|
+
for (const row of this.metadata.get(sessionID) ?? [])
|
|
19881
|
+
bytes += 128 + (row.id.length + row.type.length) * 2;
|
|
19882
|
+
this.storage.accountReplay(sessionID, bytes);
|
|
19883
|
+
}
|
|
19884
|
+
async observeSource(sessionID, reader) {
|
|
19885
|
+
const source = reader.hostIdentity();
|
|
19886
|
+
const prior = this.sources.get(sessionID);
|
|
19887
|
+
if (prior && prior !== source)
|
|
19888
|
+
await this.forget(sessionID);
|
|
19889
|
+
this.sources.set(sessionID, source);
|
|
19890
|
+
this.account(sessionID);
|
|
19891
|
+
}
|
|
19892
|
+
onEvent(event) {
|
|
19893
|
+
const sessionID = event.data?.sessionID;
|
|
19894
|
+
if (sessionID && (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated"))
|
|
19895
|
+
this.invalidate(sessionID);
|
|
19896
|
+
}
|
|
19897
|
+
invalidate(sessionID, suppressNomination = false) {
|
|
19898
|
+
if (suppressNomination)
|
|
19899
|
+
this.unavailable.add(sessionID);
|
|
19900
|
+
this.dirty.add(sessionID);
|
|
19901
|
+
this.changed.add(sessionID);
|
|
19902
|
+
this.metadata.delete(sessionID);
|
|
19903
|
+
this.metadataThrough.delete(sessionID);
|
|
19904
|
+
this.account(sessionID);
|
|
19905
|
+
}
|
|
19906
|
+
tail(sessionID) {
|
|
19907
|
+
const record = this.storage.tail(sessionID);
|
|
19908
|
+
return record ? JSON.parse(record.data) : undefined;
|
|
19909
|
+
}
|
|
19910
|
+
async baseline(sessionID) {
|
|
19911
|
+
return this.tail(sessionID)?.baseline;
|
|
19912
|
+
}
|
|
19913
|
+
rendered(row, model) {
|
|
19914
|
+
return restoreRow(row, model, hostUsesMediaAssets() ? {
|
|
19915
|
+
asset: hostMediaAsset,
|
|
19916
|
+
unavailable: () => {}
|
|
19917
|
+
} : undefined);
|
|
19918
|
+
}
|
|
19919
|
+
record(row, messages) {
|
|
19920
|
+
const data = JSON.stringify(encodeNative(messages));
|
|
19921
|
+
return { id: row.id, type: row.type, seq: row.seq, data, digest: foldDigest(data) };
|
|
19922
|
+
}
|
|
19923
|
+
records(sessionID, native, reader) {
|
|
19924
|
+
let metadata = this.metadata.get(sessionID);
|
|
19925
|
+
const through = reader.latestSequence(sessionID);
|
|
19926
|
+
const known = new Set(metadata?.map((row) => row.id));
|
|
19927
|
+
if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through || native.some((message) => message.id && !known.has(message.id))) {
|
|
19928
|
+
metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
|
|
19929
|
+
this.metadata.set(sessionID, metadata);
|
|
19930
|
+
this.metadataThrough.set(sessionID, through);
|
|
19931
|
+
}
|
|
19932
|
+
const byID = new Map(metadata.map((row) => [row.id, row]));
|
|
19933
|
+
const grouped = new Map;
|
|
19934
|
+
const anchorIndex = native.findIndex((message) => {
|
|
19935
|
+
const id = nativeRowID(message);
|
|
19936
|
+
return id !== undefined && byID.has(id);
|
|
19937
|
+
});
|
|
19938
|
+
const leading = native.slice(0, anchorIndex < 0 ? native.length : anchorIndex).filter((message) => !nativeRowID(message) && message.role === "system");
|
|
19939
|
+
const anchorMessage = native[anchorIndex];
|
|
19940
|
+
const anchorID = anchorMessage && nativeRowID(anchorMessage);
|
|
19941
|
+
const anchor = anchorID ? byID.get(anchorID) : undefined;
|
|
19942
|
+
const leadingRows = anchor ? metadata.filter((row) => row.type === "system" && row.seq < anchor.seq).slice(-leading.length) : [];
|
|
19943
|
+
const leadingIDs = new Map(leading.map((message, i) => [message, leadingRows[i]?.id]));
|
|
19944
|
+
let cursor = -1;
|
|
19945
|
+
let owner;
|
|
19946
|
+
for (const message of native) {
|
|
19947
|
+
let id = nativeRowID(message);
|
|
19948
|
+
if (!id && message.role === "system") {
|
|
19949
|
+
if (leadingIDs.has(message)) {
|
|
19950
|
+
id = leadingIDs.get(message);
|
|
19951
|
+
if (!id)
|
|
19952
|
+
continue;
|
|
19953
|
+
} else
|
|
19954
|
+
id = metadata.find((row) => row.type === "system" && row.seq > cursor)?.id;
|
|
19955
|
+
}
|
|
19956
|
+
if (!id && message.role === "tool")
|
|
19957
|
+
id = owner;
|
|
19958
|
+
const row = id ? byID.get(id) : undefined;
|
|
19959
|
+
if (!row)
|
|
19960
|
+
throw new NativeReplayUnavailable("Native carrier has no source row coordinate");
|
|
19961
|
+
cursor = row.seq;
|
|
19962
|
+
coordinates.set(message, row.id);
|
|
19963
|
+
if (message.role !== "tool")
|
|
19964
|
+
owner = row.id;
|
|
19965
|
+
const messages = grouped.get(row) ?? [];
|
|
19966
|
+
messages.push(message);
|
|
19967
|
+
grouped.set(row, messages);
|
|
19968
|
+
}
|
|
19969
|
+
return [...grouped].map(([row, messages]) => this.record(row, messages));
|
|
19970
|
+
}
|
|
19971
|
+
async capture(draft, native) {
|
|
19972
|
+
const release = this.storage.hold(draft.sessionID);
|
|
19973
|
+
try {
|
|
19974
|
+
rememberHostMedia(native);
|
|
19975
|
+
const reader = this.openReader(draft.sessionID);
|
|
19976
|
+
try {
|
|
19977
|
+
const rows = this.records(draft.sessionID, native, reader);
|
|
19978
|
+
const baseline = draft.messages.find((message) => message.id === HEAD_IDS[0])?.content.find((part) => part.type === "text")?.text;
|
|
19979
|
+
const through = Math.max(-1, ...rows.map((row) => row.seq));
|
|
19980
|
+
const tail = {
|
|
19981
|
+
model: `${draft.model.providerID}/${draft.model.id}`,
|
|
19982
|
+
sourceSeq: through,
|
|
19983
|
+
baseline: typeof baseline === "string" ? baseline : this.tail(draft.sessionID)?.baseline
|
|
19984
|
+
};
|
|
19985
|
+
await this.storage.saveTail(draft.sessionID, JSON.stringify(tail), rows);
|
|
19986
|
+
this.storage.truncate(draft.sessionID, through);
|
|
19987
|
+
this.loaded.set(draft.sessionID, through);
|
|
19988
|
+
this.unavailable.delete(draft.sessionID);
|
|
19989
|
+
this.changed.delete(draft.sessionID);
|
|
19990
|
+
} finally {
|
|
19991
|
+
reader.close();
|
|
19992
|
+
}
|
|
19993
|
+
} catch {
|
|
19994
|
+
this.unavailable.add(draft.sessionID);
|
|
19995
|
+
this.invalidate(draft.sessionID);
|
|
19996
|
+
} finally {
|
|
19997
|
+
this.account(draft.sessionID);
|
|
19998
|
+
release();
|
|
19999
|
+
}
|
|
20000
|
+
}
|
|
20001
|
+
async canReplay(sessionID, _reader) {
|
|
20002
|
+
return !this.unavailable.has(sessionID) && typeof await this.baseline(sessionID) === "string";
|
|
20003
|
+
}
|
|
20004
|
+
async supply(args) {
|
|
20005
|
+
const release = this.storage.hold(args.draft.sessionID);
|
|
20006
|
+
try {
|
|
20007
|
+
return await this.supplyHeld(args);
|
|
20008
|
+
} finally {
|
|
20009
|
+
this.account(args.draft.sessionID);
|
|
20010
|
+
release();
|
|
20011
|
+
}
|
|
20012
|
+
}
|
|
20013
|
+
async supplyHeld(args) {
|
|
20014
|
+
const { draft, reader, summary } = args;
|
|
20015
|
+
const tail = this.tail(draft.sessionID);
|
|
20016
|
+
const id = reader.latestRunningCompaction(draft.sessionID)?.id;
|
|
20017
|
+
if (!id || !tail || tail.model !== `${draft.model.providerID}/${draft.model.id}`)
|
|
20018
|
+
return false;
|
|
20019
|
+
const through = reader.latestSequence(draft.sessionID);
|
|
20020
|
+
const after = this.dirty.has(draft.sessionID) ? -1 : tail.sourceSeq;
|
|
20021
|
+
const fresh = reader.range(draft.sessionID, after, through).filter(conversational);
|
|
20022
|
+
const records = fresh.map((row) => this.record(row, this.rendered(row, draft.model)));
|
|
20023
|
+
if (this.dirty.has(draft.sessionID))
|
|
20024
|
+
this.storage.replaceRows(draft.sessionID, through, records);
|
|
20025
|
+
await this.storage.saveTail(draft.sessionID, JSON.stringify({
|
|
20026
|
+
...tail,
|
|
20027
|
+
sourceSeq: Math.max(tail.sourceSeq, ...fresh.map((row) => row.seq))
|
|
20028
|
+
}), records);
|
|
20029
|
+
this.dirty.delete(draft.sessionID);
|
|
20030
|
+
this.metadata.delete(draft.sessionID);
|
|
20031
|
+
this.metadataThrough.delete(draft.sessionID);
|
|
20032
|
+
this.loaded.set(draft.sessionID, through);
|
|
20033
|
+
const snapshot = {
|
|
20034
|
+
source: this.storage.sourceID,
|
|
20035
|
+
sessionID: draft.sessionID,
|
|
20036
|
+
admissionID: id,
|
|
20037
|
+
summary
|
|
20038
|
+
};
|
|
20039
|
+
await this.storage.supply(draft.sessionID, id, JSON.stringify(snapshot));
|
|
20040
|
+
return true;
|
|
20041
|
+
}
|
|
20042
|
+
async restore(sessionID, cut, model, options = {}) {
|
|
20043
|
+
const release = this.storage.hold(sessionID);
|
|
20044
|
+
try {
|
|
20045
|
+
return await this.restoreHeld(sessionID, cut, model, options);
|
|
20046
|
+
} finally {
|
|
20047
|
+
this.account(sessionID);
|
|
20048
|
+
release();
|
|
20049
|
+
}
|
|
20050
|
+
}
|
|
20051
|
+
async restoreHeld(sessionID, cut, model, options) {
|
|
20052
|
+
if (!isLocalCheckpoint(cut))
|
|
20053
|
+
return;
|
|
20054
|
+
const resolvedModel = {
|
|
20055
|
+
providerID: model.slice(0, model.indexOf("/")),
|
|
20056
|
+
id: model.slice(model.indexOf("/") + 1)
|
|
20057
|
+
};
|
|
20058
|
+
const tail = this.tail(sessionID);
|
|
20059
|
+
if (tail && tail.model !== model)
|
|
20060
|
+
this.invalidate(sessionID);
|
|
20061
|
+
let after = options.after ?? -1;
|
|
20062
|
+
if (options.bounded && options.after === undefined && !this.changed.has(sessionID)) {
|
|
20063
|
+
const state = getOrCreateSessionMeta(this.storage.db, sessionID);
|
|
20064
|
+
const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
|
|
20065
|
+
const boundary = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID)?.id;
|
|
20066
|
+
if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary)
|
|
20067
|
+
after = this.storage.sequenceForID(sessionID, boundary) ?? -1;
|
|
20068
|
+
}
|
|
20069
|
+
const through = cut.seq - 1;
|
|
20070
|
+
let reader;
|
|
20071
|
+
try {
|
|
20072
|
+
let metadata = this.metadata.get(sessionID);
|
|
20073
|
+
if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through) {
|
|
20074
|
+
reader = this.openReader(sessionID);
|
|
20075
|
+
metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
|
|
20076
|
+
this.metadata.set(sessionID, metadata);
|
|
20077
|
+
this.metadataThrough.set(sessionID, through);
|
|
20078
|
+
}
|
|
20079
|
+
const required = metadata.filter((row) => row.seq > after && row.seq <= through);
|
|
20080
|
+
if (this.dirty.has(sessionID) || !tail || (this.loaded.get(sessionID) ?? -1) < through && !this.storage.admission(sessionID, cut.id) || !this.storage.containsRows(sessionID, required.map((row) => row.id))) {
|
|
20081
|
+
reader ??= this.openReader(sessionID);
|
|
20082
|
+
const fresh = reader.range(sessionID, after, through).filter(conversational);
|
|
20083
|
+
const records = fresh.map((row) => this.record(row, this.rendered(row, resolvedModel)));
|
|
20084
|
+
const restored = new Set(records.map((row) => row.id));
|
|
20085
|
+
if (required.some((row) => !restored.has(row.id)))
|
|
20086
|
+
throw new NativeReplayUnavailable("Host restore omitted a required source row");
|
|
20087
|
+
this.storage.replaceRows(sessionID, through, records, after);
|
|
20088
|
+
await this.storage.saveTail(sessionID, JSON.stringify({
|
|
20089
|
+
model,
|
|
20090
|
+
sourceSeq: through,
|
|
20091
|
+
baseline: tail?.baseline ?? cut.data.summary
|
|
20092
|
+
}), []);
|
|
20093
|
+
this.loaded.set(sessionID, through);
|
|
20094
|
+
this.dirty.delete(sessionID);
|
|
20095
|
+
}
|
|
20096
|
+
} finally {
|
|
20097
|
+
reader?.close();
|
|
20098
|
+
}
|
|
20099
|
+
const messages = [];
|
|
20100
|
+
for (const row of this.storage.rows(sessionID, after, cut.seq - 1)) {
|
|
20101
|
+
const revived = reviveNative(JSON.parse(row.data));
|
|
20102
|
+
for (const message of revived)
|
|
20103
|
+
coordinates.set(message, row.id);
|
|
20104
|
+
messages.push(...revived);
|
|
20105
|
+
}
|
|
20106
|
+
return messages;
|
|
20107
|
+
}
|
|
20108
|
+
async restoreRead(sessionID, cut, model) {
|
|
20109
|
+
const reader = this.openReader(sessionID);
|
|
20110
|
+
try {
|
|
20111
|
+
return reader.range(sessionID, -1, cut.seq - 1).filter(conversational).flatMap((row) => {
|
|
20112
|
+
const messages = this.rendered(row, model);
|
|
20113
|
+
for (const message of messages)
|
|
20114
|
+
coordinates.set(message, row.id);
|
|
20115
|
+
return messages;
|
|
20116
|
+
});
|
|
20117
|
+
} finally {
|
|
20118
|
+
reader.close();
|
|
20119
|
+
}
|
|
20120
|
+
}
|
|
20121
|
+
sourceChanged(sessionID) {
|
|
20122
|
+
return this.changed.has(sessionID);
|
|
20123
|
+
}
|
|
20124
|
+
clear(sessionID) {
|
|
20125
|
+
this.sources.delete(sessionID);
|
|
20126
|
+
this.metadata.delete(sessionID);
|
|
20127
|
+
this.metadataThrough.delete(sessionID);
|
|
20128
|
+
this.loaded.delete(sessionID);
|
|
20129
|
+
this.unavailable.delete(sessionID);
|
|
20130
|
+
this.dirty.delete(sessionID);
|
|
20131
|
+
this.changed.delete(sessionID);
|
|
20132
|
+
}
|
|
20133
|
+
async forget(sessionID) {
|
|
20134
|
+
await this.storage.forget(sessionID);
|
|
20135
|
+
}
|
|
20136
|
+
}
|
|
20137
|
+
|
|
20138
|
+
// src/v2/fold/policy.ts
|
|
20139
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
20140
|
+
class HostFoldPolicy {
|
|
20141
|
+
deps;
|
|
20142
|
+
active = new Set;
|
|
20143
|
+
owner = randomUUID3();
|
|
20144
|
+
constructor(deps) {
|
|
20145
|
+
this.deps = deps;
|
|
20146
|
+
}
|
|
20147
|
+
owned(sessionID, cut, id) {
|
|
20148
|
+
const row = this.deps.storage.admission(sessionID, id);
|
|
20149
|
+
if (!isLocalCheckpoint(cut) || cut.id !== id || !row?.payload || row.digest !== foldDigest(row.payload))
|
|
20150
|
+
return false;
|
|
20151
|
+
const snapshot = JSON.parse(row.payload);
|
|
20152
|
+
return snapshot.summary === cut.data.summary && snapshot.source === this.deps.storage.sourceID && snapshot.sessionID === sessionID && snapshot.admissionID === id;
|
|
20153
|
+
}
|
|
20154
|
+
async idle(sessionID) {
|
|
20155
|
+
const { storage, session, threshold } = this.deps;
|
|
20156
|
+
if (!Number.isSafeInteger(threshold) || threshold <= 0 || typeof session.compact !== "function" || this.active.has(sessionID))
|
|
20157
|
+
return;
|
|
20158
|
+
this.active.add(sessionID);
|
|
20159
|
+
const now = this.deps.now ?? Date.now;
|
|
20160
|
+
let attempt;
|
|
20161
|
+
let claimed = false;
|
|
20162
|
+
try {
|
|
20163
|
+
const reader = this.deps.openReader();
|
|
20164
|
+
try {
|
|
20165
|
+
const cut = reader.latestCompaction(sessionID);
|
|
20166
|
+
const previous = storage.latestAttempt(sessionID);
|
|
20167
|
+
const old = previous ? JSON.parse(previous.data) : undefined;
|
|
20168
|
+
if (cut && previous?.status === "pending" && old && this.owned(sessionID, cut, old.id)) {
|
|
20169
|
+
if (await storage.claim(sessionID, old.id, previous.data, this.owner, now()) && await storage.finish(sessionID, old.id, this.owner, "completed", now()))
|
|
20170
|
+
this.deps.log(sessionID, `v2 host fold: rows_before=${old.before} rows_after=${reader.storedRowsAfter(sessionID, cut.seq)} duration_ms=${now() - old.started} reason=row_threshold id=${cut.id} status=completed`);
|
|
20171
|
+
return;
|
|
20172
|
+
}
|
|
20173
|
+
const after = cut?.seq ?? -1;
|
|
20174
|
+
const before = reader.storedRowsAfter(sessionID, after);
|
|
20175
|
+
if (before < threshold || !await this.deps.canReplay(sessionID, reader))
|
|
20176
|
+
return;
|
|
20177
|
+
const retry = old?.after === after ? old.attempt + (previous?.status === "failed" || previous?.status === "coalesced" ? 1 : 0) : 0;
|
|
20178
|
+
const id = old?.after === after && previous?.status === "pending" ? old.id : `msg_mc_fold_${foldDigest(`${storage.sourceID}/${sessionID}/${after}/${retry}`).slice(0, 24)}`;
|
|
20179
|
+
attempt = {
|
|
20180
|
+
after,
|
|
20181
|
+
before,
|
|
20182
|
+
watermark: reader.latestSequence(sessionID),
|
|
20183
|
+
attempt: retry,
|
|
20184
|
+
id,
|
|
20185
|
+
started: now()
|
|
20186
|
+
};
|
|
20187
|
+
claimed = await storage.claim(sessionID, id, JSON.stringify(attempt), this.owner, now());
|
|
20188
|
+
if (!claimed)
|
|
20189
|
+
return;
|
|
20190
|
+
} finally {
|
|
20191
|
+
reader.close();
|
|
20192
|
+
}
|
|
20193
|
+
const admitted = await session.compact({
|
|
20194
|
+
sessionID,
|
|
20195
|
+
id: attempt.id,
|
|
20196
|
+
delivery: "queue"
|
|
20197
|
+
});
|
|
20198
|
+
await session.wait({ sessionID });
|
|
20199
|
+
const settled = this.deps.openReader();
|
|
20200
|
+
try {
|
|
20201
|
+
const cut = settled.latestCompaction(sessionID);
|
|
20202
|
+
if (admitted?.id !== attempt.id || !cut || cut.seq <= attempt.after || !this.owned(sessionID, cut, attempt.id)) {
|
|
20203
|
+
if (await storage.finish(sessionID, attempt.id, this.owner, "coalesced", now()))
|
|
20204
|
+
this.deps.log(sessionID, `v2 host fold: rows_before=${attempt.before} rows_after=unknown duration_ms=${now() - attempt.started} reason=row_threshold id=${attempt.id} actual_id=${cut?.id ?? admitted?.id ?? "unknown"} status=coalesced`);
|
|
20205
|
+
return;
|
|
20206
|
+
}
|
|
20207
|
+
const after = settled.storedRowsAfter(sessionID, cut.seq);
|
|
20208
|
+
if (await storage.finish(sessionID, attempt.id, this.owner, "completed", now()))
|
|
20209
|
+
this.deps.log(sessionID, `v2 host fold: rows_before=${attempt.before} rows_after=${after} duration_ms=${now() - attempt.started} reason=row_threshold id=${cut.id} status=completed`);
|
|
20210
|
+
} finally {
|
|
20211
|
+
settled.close();
|
|
20212
|
+
}
|
|
20213
|
+
} catch (error) {
|
|
20214
|
+
if (claimed && attempt) {
|
|
20215
|
+
let finished = false;
|
|
20216
|
+
try {
|
|
20217
|
+
finished = await storage.finish(sessionID, attempt.id, this.owner, "failed", now());
|
|
20218
|
+
} catch {
|
|
20219
|
+
finished = true;
|
|
20220
|
+
}
|
|
20221
|
+
if (finished)
|
|
20222
|
+
this.deps.log(sessionID, `v2 host fold: rows_before=${attempt.before} rows_after=unknown duration_ms=${now() - attempt.started} reason=row_threshold id=${attempt.id} status=failed error=${JSON.stringify(String(error))}`);
|
|
20223
|
+
} else
|
|
20224
|
+
this.deps.log(sessionID, `v2 host fold: rows_before=unknown rows_after=unknown duration_ms=0 reason=row_threshold status=failed error=${JSON.stringify(String(error))} cache_error=${JSON.stringify(String(error))}`);
|
|
20225
|
+
} finally {
|
|
20226
|
+
this.active.delete(sessionID);
|
|
20227
|
+
}
|
|
19012
20228
|
}
|
|
19013
|
-
return [...content.length ? [make("assistant", content)] : [], ...results];
|
|
19014
20229
|
}
|
|
19015
20230
|
|
|
19016
20231
|
// src/v2/fork-inheritance.ts
|
|
@@ -19133,12 +20348,13 @@ function seedV2ForkFromParent(args) {
|
|
|
19133
20348
|
function keptUnderRetention(keepSubagents, child) {
|
|
19134
20349
|
return keepSubagents && (child.ever_settled === true || child.role === "historian");
|
|
19135
20350
|
}
|
|
20351
|
+
var HIDDEN_CHILD_ROLE_TITLES = {
|
|
20352
|
+
"maintainer-a": "Magic Context maintainer A",
|
|
20353
|
+
"maintainer-b": "Magic Context maintainer B",
|
|
20354
|
+
historian: "Magic Context historian"
|
|
20355
|
+
};
|
|
19136
20356
|
function roleTitle(role) {
|
|
19137
|
-
|
|
19138
|
-
return "Magic Context maintainer A";
|
|
19139
|
-
if (role === "maintainer-b")
|
|
19140
|
-
return "Magic Context maintainer B";
|
|
19141
|
-
return "Magic Context historian";
|
|
20357
|
+
return HIDDEN_CHILD_ROLE_TITLES[role];
|
|
19142
20358
|
}
|
|
19143
20359
|
function roleAgent(role) {
|
|
19144
20360
|
if (role === "maintainer-a")
|
|
@@ -19700,694 +20916,315 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
19700
20916
|
interruptAndRetire(run, "prompt-timeout").finally(() => abortReject(new Error("Hidden completion prompt timed out")));
|
|
19701
20917
|
}, Math.max(0, deadline - Date.now()));
|
|
19702
20918
|
request.signal?.addEventListener("abort", onAbort, { once: true });
|
|
19703
|
-
try {
|
|
19704
|
-
await Promise.race([
|
|
19705
|
-
host.prompt({ sessionID: run.child.id, text: marker }),
|
|
19706
|
-
aborted
|
|
19707
|
-
]);
|
|
19708
|
-
await Promise.race([host.wait({ sessionID: run.child.id }), aborted]);
|
|
19709
|
-
const row = await Promise.race([
|
|
19710
|
-
awaitAssistantRow(options.openReader, async () => {
|
|
19711
|
-
try {
|
|
19712
|
-
const eventError = await host.terminalError?.({
|
|
19713
|
-
sessionID: run.child.id
|
|
19714
|
-
});
|
|
19715
|
-
if (eventError !== undefined)
|
|
19716
|
-
return eventError;
|
|
19717
|
-
return (await host.get({ sessionID: run.child.id })).error;
|
|
19718
|
-
} catch {
|
|
19719
|
-
return;
|
|
19720
|
-
}
|
|
19721
|
-
}, () => attempt.refusal ?? attempt.stepLimit, run.child.id, baseline, deadline, request.signal),
|
|
19722
|
-
aborted
|
|
19723
|
-
]);
|
|
19724
|
-
if (!attempt.shaped) {
|
|
19725
|
-
|
|
19726
|
-
|
|
19727
|
-
const text = assistantText(row);
|
|
19728
|
-
const system = typeof request.body.system === "string" ? request.body.system : run.identity.system;
|
|
19729
|
-
const tokens = row.data.tokens;
|
|
19730
|
-
const tokenNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
19731
|
-
const reportedInput = tokenNumber(tokens?.input);
|
|
19732
|
-
const reportedOutput = tokenNumber(tokens?.output);
|
|
19733
|
-
if (request.signal?.aborted || run.retired || Date.now() >= deadline) {
|
|
19734
|
-
await interruptAndRetire(run, "prompt-aborted-or-timeout");
|
|
19735
|
-
throw new Error(request.signal?.aborted ? "Hidden completion prompt aborted" : "Hidden completion prompt timed out");
|
|
19736
|
-
}
|
|
19737
|
-
run.completion = {
|
|
19738
|
-
text,
|
|
19739
|
-
tokenLog: runTokenLog(tokens, run.identity.maxOutputTokens, row.data.finish),
|
|
19740
|
-
reasoning: text ? null : assistantReasoning(row),
|
|
19741
|
-
usage: reportedInput !== undefined || reportedOutput !== undefined ? {
|
|
19742
|
-
input: reportedInput ?? 0,
|
|
19743
|
-
output: reportedOutput ?? 0,
|
|
19744
|
-
cacheRead: tokenNumber(tokens?.cache?.read) ?? 0,
|
|
19745
|
-
cacheWrite: tokenNumber(tokens?.cache?.write) ?? 0
|
|
19746
|
-
} : meter(system, promptText(request), text ?? ""),
|
|
19747
|
-
lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
|
|
19748
|
-
providerId: row.data.model?.providerID ?? requested.providerID,
|
|
19749
|
-
modelId: row.data.model?.id ?? requested.modelID,
|
|
19750
|
-
...attempt.steps === undefined ? {} : { steps: attempt.steps }
|
|
19751
|
-
};
|
|
19752
|
-
if (!run.child.ever_settled)
|
|
19753
|
-
run.child = lifecycle.markEverSettled(run.child);
|
|
19754
|
-
} catch (caught) {
|
|
19755
|
-
const error = attempt.stepLimit ?? attempt.refusal ?? caught;
|
|
19756
|
-
run.failed = true;
|
|
19757
|
-
if (!(error instanceof HiddenProviderError)) {
|
|
19758
|
-
run.unsettledFailure = true;
|
|
19759
|
-
}
|
|
19760
|
-
if (request.signal?.aborted && !run.retired) {
|
|
19761
|
-
await interruptAndRetire(run, "prompt-aborted");
|
|
19762
|
-
} else if (error instanceof Error && error.message.includes("timed out") && !run.retired) {
|
|
19763
|
-
await interruptAndRetire(run, "prompt-timeout");
|
|
19764
|
-
} else if ((error instanceof HiddenAgentStepLimit || error instanceof HiddenProviderError && error.settled) && !run.retired) {
|
|
19765
|
-
await interruptAndRetire(run, error instanceof HiddenAgentStepLimit ? "hidden-run-step-limit" : "hidden-run-provider-error");
|
|
19766
|
-
}
|
|
19767
|
-
throw error;
|
|
19768
|
-
} finally {
|
|
19769
|
-
clearTimeout(deadlineTimer);
|
|
19770
|
-
request.signal?.removeEventListener("abort", onAbort);
|
|
19771
|
-
options.hook.releaseAttempt(marker);
|
|
19772
|
-
}
|
|
19773
|
-
},
|
|
19774
|
-
async collect(handle) {
|
|
19775
|
-
const completion = runs.get(handle)?.completion;
|
|
19776
|
-
if (!completion)
|
|
19777
|
-
throw new Error("Hidden completion has no settled output");
|
|
19778
|
-
return completion;
|
|
19779
|
-
},
|
|
19780
|
-
async close(handle, settlement) {
|
|
19781
|
-
if (!handle)
|
|
19782
|
-
return;
|
|
19783
|
-
const run = runs.get(handle);
|
|
19784
|
-
if (!run)
|
|
19785
|
-
return;
|
|
19786
|
-
try {
|
|
19787
|
-
const reusable = !run.retired && run.failed && !run.unsettledFailure;
|
|
19788
|
-
if (!run.completion && (run.failed || !settlement.promptSettled) && !reusable) {
|
|
19789
|
-
retire(run, "hidden-run-failed");
|
|
19790
|
-
}
|
|
19791
|
-
} finally {
|
|
19792
|
-
runs.delete(handle);
|
|
19793
|
-
run.releaseRole();
|
|
19794
|
-
}
|
|
19795
|
-
await lifecycle.finish(run.child, run.retired);
|
|
19796
|
-
}
|
|
19797
|
-
};
|
|
19798
|
-
}
|
|
19799
|
-
|
|
19800
|
-
// src/v2/hooks/channel2.ts
|
|
19801
|
-
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
19802
|
-
var pendingCandidates = new WeakMap;
|
|
19803
|
-
function syntheticCandidates(context, sessionID, stored) {
|
|
19804
|
-
const pending = pendingCandidates.get(context.storage);
|
|
19805
|
-
for (const [key, id] of pending ?? []) {
|
|
19806
|
-
if (!key.startsWith(`${sessionID}/`))
|
|
19807
|
-
continue;
|
|
19808
|
-
if (stored.has(id))
|
|
19809
|
-
pending?.delete(key);
|
|
19810
|
-
else
|
|
19811
|
-
stored.add(id);
|
|
19812
|
-
}
|
|
19813
|
-
return stored;
|
|
19814
|
-
}
|
|
19815
|
-
function clearSyntheticCandidates(context) {
|
|
19816
|
-
pendingCandidates.delete(context.storage);
|
|
19817
|
-
}
|
|
19818
|
-
async function deliverSynthetic(context, sessionID, text) {
|
|
19819
|
-
const id = `msg_${randomBytes2(12).toString("hex")}`;
|
|
19820
|
-
await context.storage.set(`synthetic/${sessionID}/${id}`, { id });
|
|
19821
|
-
let candidates = pendingCandidates.get(context.storage);
|
|
19822
|
-
if (!candidates) {
|
|
19823
|
-
candidates = new Map;
|
|
19824
|
-
pendingCandidates.set(context.storage, candidates);
|
|
19825
|
-
}
|
|
19826
|
-
candidates.set(`${sessionID}/${id}`, id);
|
|
19827
|
-
await context.session.synthetic({ sessionID, id, text, delivery: "steer" });
|
|
19828
|
-
return id;
|
|
19829
|
-
}
|
|
19830
|
-
async function isAdmittedSynthetic(context, sessionID, id) {
|
|
19831
|
-
const record = await context.storage.get(`synthetic/${sessionID}/${id}`);
|
|
19832
|
-
return record !== null && typeof record === "object" && "id" in record && record.id === id;
|
|
19833
|
-
}
|
|
19834
|
-
async function deliverPendingChannel2(context, db, sessionID, baseline) {
|
|
19835
|
-
if (getChannel2NudgeState(db, sessionID) !== "pending")
|
|
19836
|
-
return;
|
|
19837
|
-
const evaluation = evaluateChannel2(baseline);
|
|
19838
|
-
if (!evaluation.evaluable || !evaluation.shouldTrigger)
|
|
19839
|
-
return;
|
|
19840
|
-
const token = randomBytes2(16).toString("hex");
|
|
19841
|
-
if (!claimChannel2NudgeState(db, sessionID, token))
|
|
19842
|
-
return;
|
|
19843
|
-
try {
|
|
19844
|
-
await deliverSynthetic(context, sessionID, buildChannel2Reminder(evaluation.reclaimableTokens, reclaimableToolOutputCount(baseline?.baselineParts ?? [])));
|
|
19845
|
-
} catch (error) {
|
|
19846
|
-
casChannel2NudgeClaim(db, sessionID, "pending", token);
|
|
19847
|
-
throw error;
|
|
19848
|
-
}
|
|
19849
|
-
casChannel2NudgeClaim(db, sessionID, "delivered", token);
|
|
19850
|
-
}
|
|
19851
|
-
|
|
19852
|
-
// src/v2/hooks/commands.ts
|
|
19853
|
-
async function registerV2Commands(args) {
|
|
19854
|
-
const domain = args.command;
|
|
19855
|
-
if (!domain || typeof domain.transform !== "function") {
|
|
19856
|
-
log("[magic-context] v2 host exposes no command domain; /mmc-* commands are TUI-only");
|
|
19857
|
-
return false;
|
|
19858
|
-
}
|
|
19859
|
-
const descriptions = getMagicContextBuiltinCommands(args.compactionEnabled);
|
|
19860
|
-
const commands = buildV2Commands(args.rpc, args.directory);
|
|
19861
|
-
try {
|
|
19862
|
-
await domain.transform((editor) => {
|
|
19863
|
-
for (const command of commands) {
|
|
19864
|
-
editor.add({
|
|
19865
|
-
name: command.name,
|
|
19866
|
-
description: descriptions[command.name].description,
|
|
19867
|
-
execute: command.execute
|
|
19868
|
-
});
|
|
19869
|
-
}
|
|
19870
|
-
});
|
|
19871
|
-
} catch (error) {
|
|
19872
|
-
log("[magic-context] v2 command registration failed", error);
|
|
19873
|
-
return false;
|
|
19874
|
-
}
|
|
19875
|
-
log(`[magic-context] registered server-side commands: ${commands.map((command) => command.name).join(" ")}`);
|
|
19876
|
-
return true;
|
|
19877
|
-
}
|
|
19878
|
-
function commandArgument(input, name) {
|
|
19879
|
-
const raw = typeof input.prompt?.text === "string" ? input.prompt.text.trim() : "";
|
|
19880
|
-
const prefix = `/${name}`;
|
|
19881
|
-
if (raw === prefix)
|
|
19882
|
-
return "";
|
|
19883
|
-
if (raw.startsWith(`${prefix} `))
|
|
19884
|
-
return raw.slice(prefix.length).trim();
|
|
19885
|
-
return raw;
|
|
19886
|
-
}
|
|
19887
|
-
function reportResult(sessionID, title, message) {
|
|
19888
|
-
pushNotification2("action", { action: "show-result-dialog", title, message }, sessionID);
|
|
19889
|
-
}
|
|
19890
|
-
function reportUsage(sessionID, message) {
|
|
19891
|
-
pushNotification2("toast", { message, variant: "warning" }, sessionID);
|
|
19892
|
-
}
|
|
19893
|
-
function reportRpcReply(sessionID, title, reply, pending) {
|
|
19894
|
-
if (reply.ok !== true) {
|
|
19895
|
-
const error = typeof reply.error === "string" ? reply.error : `${title} request failed`;
|
|
19896
|
-
pushNotification2("toast", { message: error, variant: "error" }, sessionID);
|
|
19897
|
-
return;
|
|
19898
|
-
}
|
|
19899
|
-
if (reply.started === true) {
|
|
19900
|
-
pushNotification2("toast", { message: pending, variant: "info" }, sessionID);
|
|
19901
|
-
return;
|
|
19902
|
-
}
|
|
19903
|
-
reportResult(sessionID, title, typeof reply.message === "string" ? reply.message : "");
|
|
19904
|
-
}
|
|
19905
|
-
function buildV2Commands(rpc, directory) {
|
|
19906
|
-
return [
|
|
19907
|
-
{
|
|
19908
|
-
name: "mmc-status",
|
|
19909
|
-
execute: async (input) => {
|
|
19910
|
-
const detail = await rpc.dispatch("status-detail", {
|
|
19911
|
-
sessionId: input.sessionID,
|
|
19912
|
-
directory
|
|
19913
|
-
});
|
|
19914
|
-
if (typeof detail.error === "string") {
|
|
19915
|
-
throw new Error(`Magic Context status is unavailable: ${detail.error}`);
|
|
19916
|
-
}
|
|
19917
|
-
pushNotification2("action", { action: "show-status-dialog" }, input.sessionID);
|
|
19918
|
-
}
|
|
19919
|
-
},
|
|
19920
|
-
{
|
|
19921
|
-
name: "mmc-recomp",
|
|
19922
|
-
execute: async (input) => {
|
|
19923
|
-
if (isTuiConnected2(input.sessionID)) {
|
|
19924
|
-
pushNotification2("action", { action: "show-recomp-dialog" }, input.sessionID);
|
|
19925
|
-
return;
|
|
20919
|
+
try {
|
|
20920
|
+
await Promise.race([
|
|
20921
|
+
host.prompt({ sessionID: run.child.id, text: marker }),
|
|
20922
|
+
aborted
|
|
20923
|
+
]);
|
|
20924
|
+
await Promise.race([host.wait({ sessionID: run.child.id }), aborted]);
|
|
20925
|
+
const row = await Promise.race([
|
|
20926
|
+
awaitAssistantRow(options.openReader, async () => {
|
|
20927
|
+
try {
|
|
20928
|
+
const eventError = await host.terminalError?.({
|
|
20929
|
+
sessionID: run.child.id
|
|
20930
|
+
});
|
|
20931
|
+
if (eventError !== undefined)
|
|
20932
|
+
return eventError;
|
|
20933
|
+
return (await host.get({ sessionID: run.child.id })).error;
|
|
20934
|
+
} catch {
|
|
20935
|
+
return;
|
|
20936
|
+
}
|
|
20937
|
+
}, () => attempt.refusal ?? attempt.stepLimit, run.child.id, baseline, deadline, request.signal),
|
|
20938
|
+
aborted
|
|
20939
|
+
]);
|
|
20940
|
+
if (!attempt.shaped) {
|
|
20941
|
+
const task = run.identity.title.replace(/^magic-context-dream-/, "");
|
|
20942
|
+
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", `Host did not dispatch the hidden child context hook (task=${task}, agent=${run.identity.agent}, child=${run.child.id}, directory=${run.identity.directory}, stage=context/HiddenChildHook.apply). Check that the child's location loads the owning Magic Context instance; changing models cannot repair missing context shaping.`, true);
|
|
19926
20943
|
}
|
|
19927
|
-
const
|
|
19928
|
-
|
|
19929
|
-
|
|
20944
|
+
const text = assistantText(row);
|
|
20945
|
+
const system = typeof request.body.system === "string" ? request.body.system : run.identity.system;
|
|
20946
|
+
const tokens = row.data.tokens;
|
|
20947
|
+
const tokenNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
20948
|
+
const reportedInput = tokenNumber(tokens?.input);
|
|
20949
|
+
const reportedOutput = tokenNumber(tokens?.output);
|
|
20950
|
+
if (request.signal?.aborted || run.retired || Date.now() >= deadline) {
|
|
20951
|
+
await interruptAndRetire(run, "prompt-aborted-or-timeout");
|
|
20952
|
+
throw new Error(request.signal?.aborted ? "Hidden completion prompt aborted" : "Hidden completion prompt timed out");
|
|
19930
20953
|
}
|
|
19931
|
-
|
|
19932
|
-
|
|
19933
|
-
|
|
19934
|
-
|
|
19935
|
-
|
|
19936
|
-
|
|
19937
|
-
|
|
19938
|
-
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
|
|
19947
|
-
|
|
20954
|
+
run.completion = {
|
|
20955
|
+
text,
|
|
20956
|
+
tokenLog: runTokenLog(tokens, run.identity.maxOutputTokens, row.data.finish),
|
|
20957
|
+
reasoning: text ? null : assistantReasoning(row),
|
|
20958
|
+
usage: reportedInput !== undefined || reportedOutput !== undefined ? {
|
|
20959
|
+
input: reportedInput ?? 0,
|
|
20960
|
+
output: reportedOutput ?? 0,
|
|
20961
|
+
cacheRead: tokenNumber(tokens?.cache?.read) ?? 0,
|
|
20962
|
+
cacheWrite: tokenNumber(tokens?.cache?.write) ?? 0
|
|
20963
|
+
} : meter(system, promptText(request), text ?? ""),
|
|
20964
|
+
lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
|
|
20965
|
+
providerId: row.data.model?.providerID ?? requested.providerID,
|
|
20966
|
+
modelId: row.data.model?.id ?? requested.modelID,
|
|
20967
|
+
...attempt.steps === undefined ? {} : { steps: attempt.steps }
|
|
20968
|
+
};
|
|
20969
|
+
if (!run.child.ever_settled)
|
|
20970
|
+
run.child = lifecycle.markEverSettled(run.child);
|
|
20971
|
+
} catch (caught) {
|
|
20972
|
+
const error = attempt.stepLimit ?? attempt.refusal ?? caught;
|
|
20973
|
+
run.failed = true;
|
|
20974
|
+
if (!(error instanceof HiddenProviderError)) {
|
|
20975
|
+
run.unsettledFailure = true;
|
|
19948
20976
|
}
|
|
19949
|
-
|
|
19950
|
-
|
|
19951
|
-
|
|
19952
|
-
|
|
19953
|
-
|
|
20977
|
+
if (request.signal?.aborted && !run.retired) {
|
|
20978
|
+
await interruptAndRetire(run, "prompt-aborted");
|
|
20979
|
+
} else if (error instanceof Error && error.message.includes("timed out") && !run.retired) {
|
|
20980
|
+
await interruptAndRetire(run, "prompt-timeout");
|
|
20981
|
+
} else if ((error instanceof HiddenAgentStepLimit || error instanceof HiddenProviderError && error.settled) && !run.retired) {
|
|
20982
|
+
await interruptAndRetire(run, error instanceof HiddenAgentStepLimit ? "hidden-run-step-limit" : "hidden-run-provider-error");
|
|
19954
20983
|
}
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
|
|
19959
|
-
|
|
20984
|
+
throw error;
|
|
20985
|
+
} finally {
|
|
20986
|
+
clearTimeout(deadlineTimer);
|
|
20987
|
+
request.signal?.removeEventListener("abort", onAbort);
|
|
20988
|
+
options.hook.releaseAttempt(marker);
|
|
19960
20989
|
}
|
|
19961
20990
|
},
|
|
19962
|
-
{
|
|
19963
|
-
|
|
19964
|
-
|
|
19965
|
-
|
|
19966
|
-
|
|
19967
|
-
|
|
19968
|
-
|
|
19969
|
-
|
|
19970
|
-
|
|
20991
|
+
async collect(handle) {
|
|
20992
|
+
const completion = runs.get(handle)?.completion;
|
|
20993
|
+
if (!completion)
|
|
20994
|
+
throw new Error("Hidden completion has no settled output");
|
|
20995
|
+
return completion;
|
|
20996
|
+
},
|
|
20997
|
+
async close(handle, settlement) {
|
|
20998
|
+
if (!handle)
|
|
20999
|
+
return;
|
|
21000
|
+
const run = runs.get(handle);
|
|
21001
|
+
if (!run)
|
|
21002
|
+
return;
|
|
21003
|
+
try {
|
|
21004
|
+
const reusable = !run.retired && run.failed && !run.unsettledFailure;
|
|
21005
|
+
if (!run.completion && (run.failed || !settlement.promptSettled) && !reusable) {
|
|
21006
|
+
retire(run, "hidden-run-failed");
|
|
19971
21007
|
}
|
|
19972
|
-
|
|
19973
|
-
|
|
19974
|
-
|
|
19975
|
-
});
|
|
19976
|
-
reportRpcReply(input.sessionID, "Memory maintenance", reply, "Maintenance run started; see /mmc-memory-maintain status for the outcome");
|
|
21008
|
+
} finally {
|
|
21009
|
+
runs.delete(handle);
|
|
21010
|
+
run.releaseRole();
|
|
19977
21011
|
}
|
|
21012
|
+
await lifecycle.finish(run.child, run.retired);
|
|
19978
21013
|
}
|
|
19979
|
-
|
|
21014
|
+
};
|
|
19980
21015
|
}
|
|
19981
21016
|
|
|
19982
|
-
// src/v2/hooks/
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
|
|
19986
|
-
|
|
19987
|
-
|
|
19988
|
-
if (!
|
|
19989
|
-
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
|
|
19993
|
-
|
|
19994
|
-
this.#ids.add(sessionID);
|
|
19995
|
-
while (this.#ids.size > this.limit) {
|
|
19996
|
-
const oldest = this.#ids.values().next().value;
|
|
19997
|
-
if (oldest === undefined)
|
|
19998
|
-
break;
|
|
19999
|
-
this.#ids.delete(oldest);
|
|
20000
|
-
}
|
|
20001
|
-
}
|
|
20002
|
-
has(sessionID) {
|
|
20003
|
-
return this.#ids.has(sessionID);
|
|
20004
|
-
}
|
|
20005
|
-
clear() {
|
|
20006
|
-
this.#ids.clear();
|
|
20007
|
-
}
|
|
20008
|
-
get size() {
|
|
20009
|
-
return this.#ids.size;
|
|
21017
|
+
// src/v2/hooks/channel2.ts
|
|
21018
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
21019
|
+
var pendingCandidates = new WeakMap;
|
|
21020
|
+
function syntheticCandidates(context, sessionID, stored) {
|
|
21021
|
+
const pending = pendingCandidates.get(context.storage);
|
|
21022
|
+
for (const [key, id] of pending ?? []) {
|
|
21023
|
+
if (!key.startsWith(`${sessionID}/`))
|
|
21024
|
+
continue;
|
|
21025
|
+
if (stored.has(id))
|
|
21026
|
+
pending?.delete(key);
|
|
21027
|
+
else
|
|
21028
|
+
stored.add(id);
|
|
20010
21029
|
}
|
|
21030
|
+
return stored;
|
|
20011
21031
|
}
|
|
20012
|
-
|
|
20013
|
-
|
|
20014
|
-
function isToolError(part) {
|
|
20015
|
-
const result = part.result;
|
|
20016
|
-
return part.resultType === "error" || result?.type === "error" || result !== null && typeof result === "object" && "error" in result;
|
|
20017
|
-
}
|
|
20018
|
-
function toolErrorText(result) {
|
|
20019
|
-
const value = result.value === undefined ? result : result.value;
|
|
20020
|
-
return typeof value === "string" ? value : JSON.stringify(value);
|
|
20021
|
-
}
|
|
20022
|
-
function toolStateContent(state) {
|
|
20023
|
-
if (typeof state.output === "string")
|
|
20024
|
-
return state.output;
|
|
20025
|
-
if (state.status === "error")
|
|
20026
|
-
return toolErrorText({ error: state.error, content: state.content ?? [] });
|
|
20027
|
-
if (typeof state.content === "string")
|
|
20028
|
-
return state.content;
|
|
20029
|
-
if (!Array.isArray(state.content))
|
|
20030
|
-
return "";
|
|
20031
|
-
return state.content.map((part) => {
|
|
20032
|
-
if (typeof part === "string")
|
|
20033
|
-
return part;
|
|
20034
|
-
if (!part || typeof part !== "object")
|
|
20035
|
-
return "";
|
|
20036
|
-
const value = part;
|
|
20037
|
-
if (typeof value.text === "string")
|
|
20038
|
-
return value.text;
|
|
20039
|
-
if (typeof value.value === "string")
|
|
20040
|
-
return value.value;
|
|
20041
|
-
return "";
|
|
20042
|
-
}).filter(Boolean).join(`
|
|
20043
|
-
`);
|
|
20044
|
-
}
|
|
20045
|
-
|
|
20046
|
-
// src/v2/hooks/payload.ts
|
|
20047
|
-
var HEAD_IDS = ["__magic_context_v2_m0__", "__magic_context_v2_m1__"];
|
|
20048
|
-
var HOST_CONTENT_TYPES = new Set([
|
|
20049
|
-
"text",
|
|
20050
|
-
"media",
|
|
20051
|
-
"tool-call",
|
|
20052
|
-
"tool-result",
|
|
20053
|
-
"reasoning",
|
|
20054
|
-
"compaction",
|
|
20055
|
-
"effort"
|
|
20056
|
-
]);
|
|
20057
|
-
function rejectContentPart(message, part, reason) {
|
|
20058
|
-
const type = typeof part.type === "string" ? part.type : "<missing>";
|
|
20059
|
-
const text = `v2 context omitted a content part the host would reject: type=${type} message=${String(message.info.id ?? "<head>")} reason=${reason}`;
|
|
20060
|
-
if (typeof message.info.sessionID === "string")
|
|
20061
|
-
sessionLog(message.info.sessionID, text);
|
|
20062
|
-
else
|
|
20063
|
-
log(text);
|
|
20064
|
-
}
|
|
20065
|
-
function isHostInstance(value) {
|
|
20066
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
20067
|
-
return false;
|
|
20068
|
-
const prototype = Object.getPrototypeOf(value);
|
|
20069
|
-
return prototype !== Object.prototype && prototype !== null;
|
|
20070
|
-
}
|
|
20071
|
-
function containsHostInstance(value) {
|
|
20072
|
-
if (isHostInstance(value))
|
|
20073
|
-
return true;
|
|
20074
|
-
if (Array.isArray(value))
|
|
20075
|
-
return value.some(containsHostInstance);
|
|
20076
|
-
if (value && typeof value === "object")
|
|
20077
|
-
return Object.values(value).some(containsHostInstance);
|
|
20078
|
-
return false;
|
|
21032
|
+
function clearSyntheticCandidates(context) {
|
|
21033
|
+
pendingCandidates.delete(context.storage);
|
|
20079
21034
|
}
|
|
20080
|
-
function
|
|
20081
|
-
|
|
20082
|
-
|
|
20083
|
-
|
|
20084
|
-
|
|
20085
|
-
|
|
20086
|
-
|
|
20087
|
-
for (const [key, entry] of Object.entries(value))
|
|
20088
|
-
copy[key] = clonePreservingInstances(entry);
|
|
20089
|
-
return copy;
|
|
21035
|
+
async function deliverSynthetic(context, sessionID, text) {
|
|
21036
|
+
const id = `msg_${randomBytes2(12).toString("hex")}`;
|
|
21037
|
+
await context.storage.set(`synthetic/${sessionID}/${id}`, { id });
|
|
21038
|
+
let candidates = pendingCandidates.get(context.storage);
|
|
21039
|
+
if (!candidates) {
|
|
21040
|
+
candidates = new Map;
|
|
21041
|
+
pendingCandidates.set(context.storage, candidates);
|
|
20090
21042
|
}
|
|
20091
|
-
|
|
21043
|
+
candidates.set(`${sessionID}/${id}`, id);
|
|
21044
|
+
await context.session.synthetic({ sessionID, id, text, delivery: "steer" });
|
|
21045
|
+
return id;
|
|
20092
21046
|
}
|
|
20093
|
-
function
|
|
20094
|
-
const
|
|
20095
|
-
|
|
20096
|
-
return {
|
|
20097
|
-
bytes: Buffer.from(entry.buffer, entry.byteOffset, entry.byteLength).toString("base64")
|
|
20098
|
-
};
|
|
20099
|
-
}
|
|
20100
|
-
if (Array.isArray(entry))
|
|
20101
|
-
return entry.map(plain);
|
|
20102
|
-
if (entry && typeof entry === "object") {
|
|
20103
|
-
return Object.fromEntries(Object.entries(entry).map(([key, nested]) => [key, plain(nested)]));
|
|
20104
|
-
}
|
|
20105
|
-
return entry;
|
|
20106
|
-
};
|
|
20107
|
-
return JSON.stringify(plain(value));
|
|
21047
|
+
async function isAdmittedSynthetic(context, sessionID, id) {
|
|
21048
|
+
const record = await context.storage.get(`synthetic/${sessionID}/${id}`);
|
|
21049
|
+
return record !== null && typeof record === "object" && "id" in record && record.id === id;
|
|
20108
21050
|
}
|
|
20109
|
-
function
|
|
20110
|
-
|
|
20111
|
-
if (result?.type !== "content" || !Array.isArray(value))
|
|
21051
|
+
async function deliverPendingChannel2(context, db, sessionID, baseline) {
|
|
21052
|
+
if (getChannel2NudgeState(db, sessionID) !== "pending")
|
|
20112
21053
|
return;
|
|
20113
|
-
|
|
21054
|
+
const evaluation = evaluateChannel2(baseline);
|
|
21055
|
+
if (!evaluation.evaluable || !evaluation.shouldTrigger)
|
|
21056
|
+
return;
|
|
21057
|
+
const token = randomBytes2(16).toString("hex");
|
|
21058
|
+
if (!claimChannel2NudgeState(db, sessionID, token))
|
|
21059
|
+
return;
|
|
21060
|
+
try {
|
|
21061
|
+
await deliverSynthetic(context, sessionID, buildChannel2Reminder(evaluation.reclaimableTokens, reclaimableToolOutputCount(baseline?.baselineParts ?? [])));
|
|
21062
|
+
} catch (error) {
|
|
21063
|
+
casChannel2NudgeClaim(db, sessionID, "pending", token);
|
|
21064
|
+
throw error;
|
|
21065
|
+
}
|
|
21066
|
+
casChannel2NudgeClaim(db, sessionID, "delivered", token);
|
|
20114
21067
|
}
|
|
20115
|
-
|
|
20116
|
-
|
|
20117
|
-
|
|
21068
|
+
|
|
21069
|
+
// src/v2/hooks/commands.ts
|
|
21070
|
+
async function registerV2Commands(args) {
|
|
21071
|
+
const domain = args.command;
|
|
21072
|
+
if (!domain || typeof domain.transform !== "function") {
|
|
21073
|
+
log("[magic-context] v2 host exposes no command domain; /mmc-* commands are TUI-only");
|
|
21074
|
+
return false;
|
|
21075
|
+
}
|
|
21076
|
+
const descriptions = getMagicContextBuiltinCommands(args.compactionEnabled);
|
|
21077
|
+
const commands = buildV2Commands(args.rpc, args.directory);
|
|
21078
|
+
try {
|
|
21079
|
+
await domain.transform((editor) => {
|
|
21080
|
+
for (const command of commands) {
|
|
21081
|
+
editor.add({
|
|
21082
|
+
name: command.name,
|
|
21083
|
+
description: descriptions[command.name].description,
|
|
21084
|
+
execute: command.execute
|
|
21085
|
+
});
|
|
21086
|
+
}
|
|
21087
|
+
});
|
|
21088
|
+
} catch (error) {
|
|
21089
|
+
log("[magic-context] v2 command registration failed", error);
|
|
21090
|
+
return false;
|
|
21091
|
+
}
|
|
21092
|
+
log(`[magic-context] registered server-side commands: ${commands.map((command) => command.name).join(" ")}`);
|
|
21093
|
+
return true;
|
|
20118
21094
|
}
|
|
20119
|
-
function
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
21095
|
+
function commandArgument(input, name) {
|
|
21096
|
+
const raw = typeof input.prompt?.text === "string" ? input.prompt.text.trim() : "";
|
|
21097
|
+
const prefix = `/${name}`;
|
|
21098
|
+
if (raw === prefix)
|
|
21099
|
+
return "";
|
|
21100
|
+
if (raw.startsWith(`${prefix} `))
|
|
21101
|
+
return raw.slice(prefix.length).trim();
|
|
21102
|
+
return raw;
|
|
20126
21103
|
}
|
|
20127
|
-
function
|
|
20128
|
-
|
|
20129
|
-
return { type: "text", value: output };
|
|
20130
|
-
const rebuilt = [];
|
|
20131
|
-
let placed = false;
|
|
20132
|
-
for (const item of value) {
|
|
20133
|
-
if (item?.type !== "text") {
|
|
20134
|
-
rebuilt.push(item);
|
|
20135
|
-
continue;
|
|
20136
|
-
}
|
|
20137
|
-
if (placed)
|
|
20138
|
-
continue;
|
|
20139
|
-
placed = true;
|
|
20140
|
-
rebuilt.push({ ...item, text: output });
|
|
20141
|
-
}
|
|
20142
|
-
if (!placed && output)
|
|
20143
|
-
rebuilt.unshift({ type: "text", text: output });
|
|
20144
|
-
return { type: "content", value: rebuilt };
|
|
21104
|
+
function reportResult(sessionID, title, message) {
|
|
21105
|
+
pushNotification2("action", { action: "show-result-dialog", title, message }, sessionID);
|
|
20145
21106
|
}
|
|
20146
|
-
function
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
if (part.type !== "tool-call" && part.type !== "tool-result" && part.type !== "tool" && containsHostInstance(part)) {
|
|
20155
|
-
const key = contentKey(part);
|
|
20156
|
-
if (!hostParts.has(key))
|
|
20157
|
-
hostParts.set(key, part);
|
|
20158
|
-
hostPartTypes.add(part.type);
|
|
20159
|
-
}
|
|
20160
|
-
if (part.type === "tool-result" && typeof part.id === "string") {
|
|
20161
|
-
const queue = results.get(part.id) ?? [];
|
|
20162
|
-
queue.push({ part, message });
|
|
20163
|
-
results.set(part.id, queue);
|
|
20164
|
-
}
|
|
20165
|
-
}
|
|
21107
|
+
function reportUsage(sessionID, message) {
|
|
21108
|
+
pushNotification2("toast", { message, variant: "warning" }, sessionID);
|
|
21109
|
+
}
|
|
21110
|
+
function reportRpcReply(sessionID, title, reply, pending) {
|
|
21111
|
+
if (reply.ok !== true) {
|
|
21112
|
+
const error = typeof reply.error === "string" ? reply.error : `${title} request failed`;
|
|
21113
|
+
pushNotification2("toast", { message: error, variant: "error" }, sessionID);
|
|
21114
|
+
return;
|
|
20166
21115
|
}
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20172
|
-
|
|
20173
|
-
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
status: failed ? "error" : result ? "completed" : "running",
|
|
20187
|
-
...result ? { output } : {},
|
|
20188
|
-
...result && (call?.name ?? result.part.name) === "question" ? { metadata: { userAnswer: true } } : {},
|
|
20189
|
-
...files ? { attachments: contentValueAttachments(files) } : {}
|
|
21116
|
+
if (reply.started === true) {
|
|
21117
|
+
pushNotification2("toast", { message: pending, variant: "info" }, sessionID);
|
|
21118
|
+
return;
|
|
21119
|
+
}
|
|
21120
|
+
reportResult(sessionID, title, typeof reply.message === "string" ? reply.message : "");
|
|
21121
|
+
}
|
|
21122
|
+
function buildV2Commands(rpc, directory) {
|
|
21123
|
+
return [
|
|
21124
|
+
{
|
|
21125
|
+
name: "mmc-status",
|
|
21126
|
+
execute: async (input) => {
|
|
21127
|
+
const detail = await rpc.dispatch("status-detail", {
|
|
21128
|
+
sessionId: input.sessionID,
|
|
21129
|
+
directory
|
|
21130
|
+
});
|
|
21131
|
+
if (typeof detail.error === "string") {
|
|
21132
|
+
throw new Error(`Magic Context status is unavailable: ${detail.error}`);
|
|
21133
|
+
}
|
|
21134
|
+
pushNotification2("action", { action: "show-status-dialog" }, input.sessionID);
|
|
20190
21135
|
}
|
|
20191
|
-
}
|
|
20192
|
-
|
|
20193
|
-
|
|
20194
|
-
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
|
|
20201
|
-
|
|
20202
|
-
|
|
20203
|
-
const convertedTool = (source) => {
|
|
20204
|
-
const sourceState = source.state && typeof source.state === "object" ? source.state : {};
|
|
20205
|
-
const output = toolStateContent(sourceState);
|
|
20206
|
-
const { content: _content, ...projectedState } = structuredClone(sourceState);
|
|
20207
|
-
const part = {
|
|
20208
|
-
type: "tool",
|
|
20209
|
-
callID: source.callID ?? source.id,
|
|
20210
|
-
tool: source.tool ?? source.name,
|
|
20211
|
-
state: { ...projectedState, output }
|
|
20212
|
-
};
|
|
20213
|
-
bridges.set(part, { native: source, output });
|
|
20214
|
-
return part;
|
|
20215
|
-
};
|
|
20216
|
-
const callParts = new Map;
|
|
20217
|
-
for (const message of source) {
|
|
20218
|
-
for (const part of message.content) {
|
|
20219
|
-
if (part.type === "tool-call") {
|
|
20220
|
-
callParts.set(part, nativeTool(part, results.get(String(part.id))?.shift()));
|
|
20221
|
-
} else if (part.type === "tool") {
|
|
20222
|
-
callParts.set(part, convertedTool(part));
|
|
21136
|
+
},
|
|
21137
|
+
{
|
|
21138
|
+
name: "mmc-recomp",
|
|
21139
|
+
execute: async (input) => {
|
|
21140
|
+
if (isTuiConnected2(input.sessionID)) {
|
|
21141
|
+
pushNotification2("action", { action: "show-recomp-dialog" }, input.sessionID);
|
|
21142
|
+
return;
|
|
21143
|
+
}
|
|
21144
|
+
const reply = await rpc.dispatch("recomp", { sessionId: input.sessionID });
|
|
21145
|
+
if (reply.ok !== true) {
|
|
21146
|
+
throw new Error("Magic Context could not start the history rebuild.");
|
|
21147
|
+
}
|
|
20223
21148
|
}
|
|
20224
|
-
}
|
|
20225
|
-
|
|
20226
|
-
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
|
|
20236
|
-
|
|
20237
|
-
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
for (const part of parts) {
|
|
20241
|
-
const bridge = bridges.get(part);
|
|
20242
|
-
if (bridge && typeof part.callID === "string")
|
|
20243
|
-
byCallID.set(part.callID, bridge);
|
|
20244
|
-
}
|
|
20245
|
-
if (typeof message.id === "string") {
|
|
20246
|
-
bridgesByMessageID.set(message.id, byCallID);
|
|
20247
|
-
originalsByID.set(message.id, message);
|
|
20248
|
-
}
|
|
20249
|
-
const mapped = {
|
|
20250
|
-
info: {
|
|
20251
|
-
id: message.id,
|
|
20252
|
-
sessionID: draft.sessionID,
|
|
20253
|
-
role: message.role,
|
|
20254
|
-
...{
|
|
20255
|
-
providerID: draft.model.providerID,
|
|
20256
|
-
modelID: draft.model.id,
|
|
20257
|
-
agent: draft.agent
|
|
21149
|
+
},
|
|
21150
|
+
{
|
|
21151
|
+
name: "mmc-flush",
|
|
21152
|
+
execute: async (input) => {
|
|
21153
|
+
const reply = await rpc.dispatch("flush", { sessionId: input.sessionID });
|
|
21154
|
+
reportRpcReply(input.sessionID, "Flush", reply, "Flush started");
|
|
21155
|
+
}
|
|
21156
|
+
},
|
|
21157
|
+
{
|
|
21158
|
+
name: "mmc-wrapup",
|
|
21159
|
+
execute: async (input) => {
|
|
21160
|
+
const argument = commandArgument(input, "mmc-wrapup");
|
|
21161
|
+
if (argument !== "" && !/^\d+$/.test(argument)) {
|
|
21162
|
+
const usage = "Usage: /mmc-wrapup [messages_to_keep] where messages_to_keep is a positive integer";
|
|
21163
|
+
reportUsage(input.sessionID, usage);
|
|
21164
|
+
throw new Error(usage);
|
|
20258
21165
|
}
|
|
20259
|
-
|
|
20260
|
-
|
|
20261
|
-
|
|
20262
|
-
|
|
20263
|
-
|
|
20264
|
-
bridgesByCarrier.set(mapped, byCallID);
|
|
20265
|
-
messages.push(mapped);
|
|
20266
|
-
}
|
|
20267
|
-
return {
|
|
20268
|
-
messages,
|
|
20269
|
-
commit() {
|
|
20270
|
-
let head = 0;
|
|
20271
|
-
const rendered = [];
|
|
20272
|
-
for (const message of messages) {
|
|
20273
|
-
const original = originals.get(message) ?? (typeof message.info.id === "string" ? originalsByID.get(message.info.id) : undefined);
|
|
20274
|
-
const id = message.info.syntheticHead ? HEAD_IDS[head++] : original?.id;
|
|
20275
|
-
const content = [];
|
|
20276
|
-
const following = [];
|
|
20277
|
-
for (const candidate of message.parts) {
|
|
20278
|
-
const part = candidate;
|
|
20279
|
-
const bridge = bridges.get(part) ?? (part.type === "tool" && typeof part.callID === "string" ? bridgesFor(message)?.get(part.callID) : undefined);
|
|
20280
|
-
if (!bridge) {
|
|
20281
|
-
if (part.type === "tool") {
|
|
20282
|
-
const state = part.state;
|
|
20283
|
-
if (typeof part.callID !== "string" || typeof part.tool !== "string" || !state || typeof state !== "object") {
|
|
20284
|
-
rejectContentPart(message, part, "tool has no call ID, name, or state");
|
|
20285
|
-
continue;
|
|
20286
|
-
}
|
|
20287
|
-
content.push({
|
|
20288
|
-
type: "tool-call",
|
|
20289
|
-
id: part.callID,
|
|
20290
|
-
name: part.tool,
|
|
20291
|
-
input: state.input
|
|
20292
|
-
});
|
|
20293
|
-
if (state.status === "completed" || state.status === "error") {
|
|
20294
|
-
following.push({
|
|
20295
|
-
role: "tool",
|
|
20296
|
-
content: [
|
|
20297
|
-
{
|
|
20298
|
-
type: "tool-result",
|
|
20299
|
-
id: part.callID,
|
|
20300
|
-
name: part.tool,
|
|
20301
|
-
result: {
|
|
20302
|
-
type: state.status === "error" ? "error" : "text",
|
|
20303
|
-
value: toolStateContent(state)
|
|
20304
|
-
}
|
|
20305
|
-
}
|
|
20306
|
-
]
|
|
20307
|
-
});
|
|
20308
|
-
}
|
|
20309
|
-
continue;
|
|
20310
|
-
}
|
|
20311
|
-
if (part.type === "file") {
|
|
20312
|
-
const mime = part.mime;
|
|
20313
|
-
const url = part.url;
|
|
20314
|
-
const prefix = `data:${mime};base64,`;
|
|
20315
|
-
if (typeof mime !== "string" || !/^image\/(png|jpeg|gif|webp)$/.test(mime) || typeof url !== "string" || !url.startsWith(prefix)) {
|
|
20316
|
-
rejectContentPart(message, part, "file is not an inline supported image");
|
|
20317
|
-
continue;
|
|
20318
|
-
}
|
|
20319
|
-
const asset = hostMediaAsset(url.slice(prefix.length), mime);
|
|
20320
|
-
if (typeof asset === "string") {
|
|
20321
|
-
rejectContentPart(message, part, `host media unavailable: ${asset}`);
|
|
20322
|
-
continue;
|
|
20323
|
-
}
|
|
20324
|
-
content.push({ type: "media", media: asset });
|
|
20325
|
-
continue;
|
|
20326
|
-
}
|
|
20327
|
-
if (!HOST_CONTENT_TYPES.has(String(part.type))) {
|
|
20328
|
-
rejectContentPart(message, part, "unknown host content type");
|
|
20329
|
-
continue;
|
|
20330
|
-
}
|
|
20331
|
-
const { synthetic: _synthetic, ...clean } = part;
|
|
20332
|
-
const original = hostPartTypes.has(clean.type) && !containsHostInstance(clean) ? hostParts.get(contentKey(clean)) : undefined;
|
|
20333
|
-
content.push(original ?? clean);
|
|
20334
|
-
continue;
|
|
20335
|
-
}
|
|
20336
|
-
const state = part.state;
|
|
20337
|
-
if (bridge.native) {
|
|
20338
|
-
const native = bridge.native;
|
|
20339
|
-
const callID = String(native.id ?? native.callID ?? part.callID);
|
|
20340
|
-
const name = String(native.name ?? native.tool ?? part.tool);
|
|
20341
|
-
content.push({ type: "tool-call", id: callID, name, input: state.input });
|
|
20342
|
-
if (state.status === "completed" || state.status === "error") {
|
|
20343
|
-
following.push({
|
|
20344
|
-
role: "tool",
|
|
20345
|
-
content: [
|
|
20346
|
-
{
|
|
20347
|
-
type: "tool-result",
|
|
20348
|
-
id: callID,
|
|
20349
|
-
name,
|
|
20350
|
-
result: {
|
|
20351
|
-
type: state.status === "error" ? "error" : "text",
|
|
20352
|
-
value: state.output
|
|
20353
|
-
}
|
|
20354
|
-
}
|
|
20355
|
-
]
|
|
20356
|
-
});
|
|
20357
|
-
}
|
|
20358
|
-
continue;
|
|
20359
|
-
}
|
|
20360
|
-
if (bridge.call)
|
|
20361
|
-
content.push({ ...bridge.call, input: state.input });
|
|
20362
|
-
if (bridge.result && bridge.resultMessage) {
|
|
20363
|
-
const result = {
|
|
20364
|
-
...bridge.result,
|
|
20365
|
-
result: state.output === bridge.output ? bridge.result.result : bridge.files && typeof state.output === "string" ? rebuildFileContent(bridge.files, state.output) : {
|
|
20366
|
-
type: state.status === "error" ? "error" : "text",
|
|
20367
|
-
value: state.output
|
|
20368
|
-
}
|
|
20369
|
-
};
|
|
20370
|
-
if (bridge.resultMessage === original)
|
|
20371
|
-
content.push(result);
|
|
20372
|
-
else
|
|
20373
|
-
following.push({ ...bridge.resultMessage, content: [result] });
|
|
20374
|
-
}
|
|
21166
|
+
const messagesToKeep = argument === "" ? 20 : Number.parseInt(argument, 10);
|
|
21167
|
+
if (messagesToKeep <= 0) {
|
|
21168
|
+
const usage = "messages_to_keep must be a positive integer";
|
|
21169
|
+
reportUsage(input.sessionID, usage);
|
|
21170
|
+
throw new Error(usage);
|
|
20375
21171
|
}
|
|
20376
|
-
|
|
20377
|
-
|
|
20378
|
-
|
|
20379
|
-
|
|
20380
|
-
|
|
20381
|
-
|
|
20382
|
-
|
|
20383
|
-
|
|
20384
|
-
|
|
21172
|
+
const reply = await rpc.dispatch("wrapup", {
|
|
21173
|
+
sessionId: input.sessionID,
|
|
21174
|
+
messagesToKeep
|
|
21175
|
+
});
|
|
21176
|
+
reportRpcReply(input.sessionID, "Wrapup", reply, "Wrapup started; the summary appears when it finishes");
|
|
21177
|
+
}
|
|
21178
|
+
},
|
|
21179
|
+
{
|
|
21180
|
+
name: "mmc-memory-maintain",
|
|
21181
|
+
execute: async (input) => {
|
|
21182
|
+
const argument = commandArgument(input, "mmc-memory-maintain");
|
|
21183
|
+
const subcommand = argument === "" ? "status" : argument.trim().toLowerCase();
|
|
21184
|
+
if (subcommand !== "run" && subcommand !== "status" && subcommand !== "resume") {
|
|
21185
|
+
const usage = "Usage: /mmc-memory-maintain [run|status|resume] — status is the default";
|
|
21186
|
+
reportUsage(input.sessionID, usage);
|
|
21187
|
+
throw new Error(usage);
|
|
20385
21188
|
}
|
|
20386
|
-
|
|
21189
|
+
const reply = await rpc.dispatch("maintenance", {
|
|
21190
|
+
sessionId: input.sessionID,
|
|
21191
|
+
subcommand
|
|
21192
|
+
});
|
|
21193
|
+
reportRpcReply(input.sessionID, "Memory maintenance", reply, "Maintenance run started; see /mmc-memory-maintain status for the outcome");
|
|
20387
21194
|
}
|
|
20388
|
-
draft.messages.splice(0, draft.messages.length, ...rendered);
|
|
20389
21195
|
}
|
|
20390
|
-
|
|
21196
|
+
];
|
|
21197
|
+
}
|
|
21198
|
+
|
|
21199
|
+
// src/v2/hooks/deleted-session-tombstones.ts
|
|
21200
|
+
class DeletedSessionTombstones {
|
|
21201
|
+
limit;
|
|
21202
|
+
#ids = new Set;
|
|
21203
|
+
constructor(limit = 1000) {
|
|
21204
|
+
this.limit = limit;
|
|
21205
|
+
if (!Number.isSafeInteger(limit) || limit < 1) {
|
|
21206
|
+
throw new Error("Deleted-session tombstone limit must be a positive integer");
|
|
21207
|
+
}
|
|
21208
|
+
}
|
|
21209
|
+
add(sessionID) {
|
|
21210
|
+
this.#ids.delete(sessionID);
|
|
21211
|
+
this.#ids.add(sessionID);
|
|
21212
|
+
while (this.#ids.size > this.limit) {
|
|
21213
|
+
const oldest = this.#ids.values().next().value;
|
|
21214
|
+
if (oldest === undefined)
|
|
21215
|
+
break;
|
|
21216
|
+
this.#ids.delete(oldest);
|
|
21217
|
+
}
|
|
21218
|
+
}
|
|
21219
|
+
has(sessionID) {
|
|
21220
|
+
return this.#ids.has(sessionID);
|
|
21221
|
+
}
|
|
21222
|
+
clear() {
|
|
21223
|
+
this.#ids.clear();
|
|
21224
|
+
}
|
|
21225
|
+
get size() {
|
|
21226
|
+
return this.#ids.size;
|
|
21227
|
+
}
|
|
20391
21228
|
}
|
|
20392
21229
|
|
|
20393
21230
|
// src/v2/hooks/generate.ts
|
|
@@ -20433,9 +21270,9 @@ function hiddenTerminalError(event) {
|
|
|
20433
21270
|
}
|
|
20434
21271
|
|
|
20435
21272
|
// src/v2/hooks/lkg-system.ts
|
|
20436
|
-
import { createHash as
|
|
20437
|
-
function
|
|
20438
|
-
return
|
|
21273
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
21274
|
+
function identity2(slot) {
|
|
21275
|
+
return createHash7("sha256").update(JSON.stringify({
|
|
20439
21276
|
capturedAt: slot.capturedAt,
|
|
20440
21277
|
captureSequence: slot.captureSequence,
|
|
20441
21278
|
rowVersion: slot.rowVersion,
|
|
@@ -20450,14 +21287,14 @@ class V2LkgSystemReplay {
|
|
|
20450
21287
|
systems = new BoundedSessionMap(1000);
|
|
20451
21288
|
capture(sessionId, slot, input, served) {
|
|
20452
21289
|
this.systems.set(sessionId, {
|
|
20453
|
-
slot:
|
|
21290
|
+
slot: identity2(slot),
|
|
20454
21291
|
input: JSON.stringify(input),
|
|
20455
21292
|
served: structuredClone(served)
|
|
20456
21293
|
});
|
|
20457
21294
|
}
|
|
20458
21295
|
restore(sessionId, slot, input, target) {
|
|
20459
21296
|
const saved = this.systems.get(sessionId);
|
|
20460
|
-
if (!slot || !saved || saved.slot !==
|
|
21297
|
+
if (!slot || !saved || saved.slot !== identity2(slot) || saved.input !== JSON.stringify(input))
|
|
20461
21298
|
return false;
|
|
20462
21299
|
target.splice(0, target.length, ...structuredClone(saved.served));
|
|
20463
21300
|
return true;
|
|
@@ -20642,7 +21479,7 @@ function hasRequiredSessionAPI(session) {
|
|
|
20642
21479
|
}
|
|
20643
21480
|
|
|
20644
21481
|
// src/features/magic-context/session-project-backfill.ts
|
|
20645
|
-
import { randomUUID as
|
|
21482
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
20646
21483
|
import { existsSync as existsSync7 } from "node:fs";
|
|
20647
21484
|
var LEASE_TTL_MS = 10 * 60 * 1000;
|
|
20648
21485
|
var SESSION_PAGE_SIZE = 100;
|
|
@@ -20784,7 +21621,7 @@ async function runSessionProjectBackfill(db, source, options = {}) {
|
|
|
20784
21621
|
const now = options.now ?? Date.now;
|
|
20785
21622
|
const resolveIdentity = options.resolveIdentity ?? ((directory) => resolveProjectIdentityForSession(directory, options.allowHomeProject));
|
|
20786
21623
|
const yieldFn = options.yieldFn ?? defaultYieldFn;
|
|
20787
|
-
const holderId = options.holderId ??
|
|
21624
|
+
const holderId = options.holderId ?? randomUUID4();
|
|
20788
21625
|
const readPage = createPageReader(source);
|
|
20789
21626
|
const result = {
|
|
20790
21627
|
status: "completed",
|
|
@@ -21377,7 +22214,7 @@ function resolveCtxExpandMode(args, domain) {
|
|
|
21377
22214
|
}
|
|
21378
22215
|
|
|
21379
22216
|
// src/tools/ctx-expand/render.ts
|
|
21380
|
-
import { createHash as
|
|
22217
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
21381
22218
|
function isRecord4(value) {
|
|
21382
22219
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21383
22220
|
}
|
|
@@ -21466,7 +22303,7 @@ function reasoningOf(part) {
|
|
|
21466
22303
|
function renderPartPreview(part, expandTools) {
|
|
21467
22304
|
if (!isRecord4(part))
|
|
21468
22305
|
return null;
|
|
21469
|
-
const expansion = expandToolPart(part, expandTools);
|
|
22306
|
+
const expansion = expandToolPart(part, expandTools, true);
|
|
21470
22307
|
if (expansion !== null)
|
|
21471
22308
|
return ` • tool ${part.tool}: ${expansion}`;
|
|
21472
22309
|
const text = textOf(part);
|
|
@@ -21601,7 +22438,7 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
|
|
|
21601
22438
|
const index = scoped ? Number(scoped[2]) : 0;
|
|
21602
22439
|
const piText = message.parts.filter((part) => isRecord4(part) && part.type === "text");
|
|
21603
22440
|
const part = message.parts[index];
|
|
21604
|
-
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" &&
|
|
22441
|
+
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" && createHash8("sha256").update(part.text).digest("hex") === derived[3]) : [];
|
|
21605
22442
|
const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
|
|
21606
22443
|
return selected ? renderPartFull(selected) ?? "" : `Tag ${number}'s original text part is no longer in stored history.`;
|
|
21607
22444
|
}
|
|
@@ -22912,6 +23749,9 @@ function persistV2UsageReading(args) {
|
|
|
22912
23749
|
|
|
22913
23750
|
// src/v2/hooks/context.ts
|
|
22914
23751
|
var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
|
|
23752
|
+
|
|
23753
|
+
class V2LkgAdmissionReplay extends Error {
|
|
23754
|
+
}
|
|
22915
23755
|
function isBlockingV2TransformError(error) {
|
|
22916
23756
|
return error instanceof EmergencyFailClosedError || error instanceof UnresolvedHistoryBoundaryError || error instanceof UnmanagedOverWindowError || error instanceof DegradedPassRefusalError || isFailClosedBlockingError(error);
|
|
22917
23757
|
}
|
|
@@ -23120,6 +23960,8 @@ async function registerContext(context) {
|
|
|
23120
23960
|
return;
|
|
23121
23961
|
}
|
|
23122
23962
|
const folds = new FoldOwner(context.storage);
|
|
23963
|
+
const nativeFoldMemory = !compactionOff && process.env.MMC_OC2_INVISIBLE_FOLD === "1" ? nativeFoldCache(() => storage.require()) : undefined;
|
|
23964
|
+
const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader()) : undefined;
|
|
23123
23965
|
setOutputReserveConfig(config.output_reserve);
|
|
23124
23966
|
const queriedModels = new Set;
|
|
23125
23967
|
const rawLimits = new Map;
|
|
@@ -23151,7 +23993,7 @@ async function registerContext(context) {
|
|
|
23151
23993
|
let storageRecoveryAnnounced = false;
|
|
23152
23994
|
const storageNoticeBySession = new Map;
|
|
23153
23995
|
const storeStorageNotice = (sessionID, text, what) => {
|
|
23154
|
-
withoutSqliteTransformPass(() => context.session.wait({ sessionID }).then(() => deliverSynthetic(context, sessionID, text)).catch((error) => sessionLog(sessionID, `v2 storage ${what} notice could not be delivered:`, error)));
|
|
23996
|
+
withoutSqliteTransformPass(() => Promise.resolve().then(() => context.session.wait({ sessionID })).then(() => deliverSynthetic(context, sessionID, text)).catch((error) => sessionLog(sessionID, `v2 storage ${what} notice could not be delivered:`, error)));
|
|
23155
23997
|
};
|
|
23156
23998
|
const noticeStorageRefusal = (sessionID, reason) => {
|
|
23157
23999
|
const message = formatStorageRefusalNotice(reason);
|
|
@@ -23418,6 +24260,14 @@ async function registerContext(context) {
|
|
|
23418
24260
|
}
|
|
23419
24261
|
return unsafe;
|
|
23420
24262
|
};
|
|
24263
|
+
const hostFolds = nativeFoldReplay && nativeFoldMemory ? new HostFoldPolicy({
|
|
24264
|
+
session: context.session,
|
|
24265
|
+
storage: nativeFoldMemory,
|
|
24266
|
+
openReader: openStoreReader,
|
|
24267
|
+
canReplay: (sessionID, reader) => nativeFoldReplay.canReplay(sessionID, reader),
|
|
24268
|
+
threshold: Number(process.env.MMC_OC2_HOST_FOLD_ROWS ?? 1000),
|
|
24269
|
+
log: sessionLog
|
|
24270
|
+
}) : undefined;
|
|
23421
24271
|
const usageController = new AbortController;
|
|
23422
24272
|
const usageDone = (async () => {
|
|
23423
24273
|
try {
|
|
@@ -23428,6 +24278,10 @@ async function registerContext(context) {
|
|
|
23428
24278
|
if (!event.data?.sessionID)
|
|
23429
24279
|
continue;
|
|
23430
24280
|
const sessionID = event.data.sessionID;
|
|
24281
|
+
if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
|
|
24282
|
+
nativeFoldReplay?.onEvent(event);
|
|
24283
|
+
restoredRows.forget(sessionID);
|
|
24284
|
+
}
|
|
23431
24285
|
if (event.type === "session.error" || event.type === "session.execution.failed") {
|
|
23432
24286
|
const error = hiddenTerminalError(event);
|
|
23433
24287
|
if (error !== undefined)
|
|
@@ -23453,6 +24307,7 @@ async function registerContext(context) {
|
|
|
23453
24307
|
pendingMaterializationSessions.delete(sessionID);
|
|
23454
24308
|
lastHeuristicsTurnId.delete(sessionID);
|
|
23455
24309
|
restoredRows.forget(sessionID);
|
|
24310
|
+
await nativeFoldReplay?.forget(sessionID);
|
|
23456
24311
|
generateReplay.forget(sessionID);
|
|
23457
24312
|
systemPromptRefreshSessions.delete(sessionID);
|
|
23458
24313
|
systemPrompt?.clearSession(sessionID);
|
|
@@ -23465,11 +24320,14 @@ async function registerContext(context) {
|
|
|
23465
24320
|
if (event.type !== "session.execution.succeeded")
|
|
23466
24321
|
continue;
|
|
23467
24322
|
const model = liveModels.get(sessionID);
|
|
23468
|
-
if (model)
|
|
24323
|
+
if (model) {
|
|
23469
24324
|
await recordUsage({
|
|
23470
24325
|
sessionID,
|
|
23471
24326
|
model: { providerID: model.providerID, id: model.modelID }
|
|
23472
24327
|
});
|
|
24328
|
+
if (!compactionOff && typeof await nativeFoldReplay?.baseline(sessionID) === "string")
|
|
24329
|
+
hostFolds?.idle(sessionID);
|
|
24330
|
+
}
|
|
23473
24331
|
}
|
|
23474
24332
|
} catch (error) {
|
|
23475
24333
|
if (!usageController.signal.aborted)
|
|
@@ -23504,10 +24362,32 @@ async function registerContext(context) {
|
|
|
23504
24362
|
}
|
|
23505
24363
|
if (compactionOff)
|
|
23506
24364
|
return;
|
|
24365
|
+
if (nativeFoldReplay)
|
|
24366
|
+
rememberHostMedia(draft.messages);
|
|
23507
24367
|
const reader = openStoreReader();
|
|
23508
24368
|
try {
|
|
23509
24369
|
const watermark = reader.latestSequenceForIds(draft.sessionID, draft.messages.flatMap((message) => message.id ? [message.id] : []));
|
|
23510
24370
|
const running = reader.latestRunningCompaction(draft.sessionID);
|
|
24371
|
+
if (nativeFoldReplay) {
|
|
24372
|
+
try {
|
|
24373
|
+
if (await nativeFoldReplay.canReplay(draft.sessionID, reader)) {
|
|
24374
|
+
const state = getOrCreateSessionMeta(storage.require(), draft.sessionID);
|
|
24375
|
+
const summary = await nativeFoldReplay.baseline(draft.sessionID) ?? state.cachedM0Bytes?.toString("utf8") ?? "<session-history></session-history>";
|
|
24376
|
+
if (await nativeFoldReplay.supply({
|
|
24377
|
+
draft,
|
|
24378
|
+
reader,
|
|
24379
|
+
previousCut: reader.latestCompaction(draft.sessionID),
|
|
24380
|
+
summary
|
|
24381
|
+
})) {
|
|
24382
|
+
draft.result = { summary };
|
|
24383
|
+
return;
|
|
24384
|
+
}
|
|
24385
|
+
}
|
|
24386
|
+
} catch (error) {
|
|
24387
|
+
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
24388
|
+
sessionLog(draft.sessionID, `v2 host fold: legacy compaction reason=${JSON.stringify(String(error))}`);
|
|
24389
|
+
}
|
|
24390
|
+
}
|
|
23511
24391
|
const fold = await folds.supply({
|
|
23512
24392
|
sessionID: draft.sessionID,
|
|
23513
24393
|
watermark,
|
|
@@ -23554,12 +24434,88 @@ async function registerContext(context) {
|
|
|
23554
24434
|
withoutSqliteTransformPass(() => warmModelLimitCacheFromCatalog(context));
|
|
23555
24435
|
agents.set(draft.sessionID, draft.agent);
|
|
23556
24436
|
applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface);
|
|
24437
|
+
const admissionDb = db ?? storage.current();
|
|
24438
|
+
const replayFits = (messages) => {
|
|
24439
|
+
const system = structuredClone(draft.system);
|
|
24440
|
+
if (!admissionDb || !draft.tools || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), draft.system, system))
|
|
24441
|
+
return false;
|
|
24442
|
+
const limit = lkgReplayLimit({
|
|
24443
|
+
db: admissionDb,
|
|
24444
|
+
sessionId: draft.sessionID,
|
|
24445
|
+
model: {
|
|
24446
|
+
providerID: draft.model.providerID,
|
|
24447
|
+
modelID: draft.model.id
|
|
24448
|
+
},
|
|
24449
|
+
modelKey: `${draft.model.providerID}/${draft.model.id}`
|
|
24450
|
+
});
|
|
24451
|
+
if (limit === undefined)
|
|
24452
|
+
return false;
|
|
24453
|
+
let toolDefinitionTokens = 0;
|
|
24454
|
+
for (const tool of Object.values(draft.tools)) {
|
|
24455
|
+
if (!tool || typeof tool.description !== "string" || !tool.input)
|
|
24456
|
+
return false;
|
|
24457
|
+
const schema = JSON.stringify(tool.input);
|
|
24458
|
+
if (!schema)
|
|
24459
|
+
return false;
|
|
24460
|
+
toolDefinitionTokens += estimateTokens(tool.description) + estimateTokens(schema);
|
|
24461
|
+
}
|
|
24462
|
+
return measureLkgReplay({
|
|
24463
|
+
messages,
|
|
24464
|
+
limit,
|
|
24465
|
+
estimate: () => estimateFinalWireInputTokens({
|
|
24466
|
+
messages,
|
|
24467
|
+
toolDefinitionTokens,
|
|
24468
|
+
systemPromptTokens: estimateTokens(JSON.stringify(system)),
|
|
24469
|
+
providerID: draft.model.providerID,
|
|
24470
|
+
modelID: draft.model.id,
|
|
24471
|
+
agentName: draft.agent
|
|
24472
|
+
})
|
|
24473
|
+
}).fit === "under";
|
|
24474
|
+
};
|
|
23557
24475
|
let postFold = false;
|
|
23558
24476
|
try {
|
|
23559
|
-
const admissionDb = db ?? storage.current();
|
|
23560
24477
|
if (!compactionOff && admissionDb)
|
|
23561
24478
|
await withAsyncPrivilegedWriter(admissionDb, () => {
|
|
23562
24479
|
return;
|
|
24480
|
+
}, {
|
|
24481
|
+
beforeRetry: (_error) => {
|
|
24482
|
+
let replayBlocked = false;
|
|
24483
|
+
const mapped = adaptPayload(draft);
|
|
24484
|
+
try {
|
|
24485
|
+
const overflowDb = db;
|
|
24486
|
+
if (overflowDb !== undefined && overflowDb !== null && (isEmergencyRecoveryArmed(draft.sessionID) || getOverflowState(overflowDb, draft.sessionID).needsEmergencyRecovery)) {
|
|
24487
|
+
replayBlocked = true;
|
|
24488
|
+
sessionLog(draft.sessionID, "lkg_emergency_armed");
|
|
24489
|
+
} else {
|
|
24490
|
+
const keys = resolveLkgModelKeys(mapped.messages);
|
|
24491
|
+
const replay = replayLkg({
|
|
24492
|
+
sessionId: draft.sessionID,
|
|
24493
|
+
messages: mapped.messages,
|
|
24494
|
+
modelKey: keys.modelKey,
|
|
24495
|
+
providerKey: keys.providerKey
|
|
24496
|
+
});
|
|
24497
|
+
if (replay.ok && !replayFits(replay.messages)) {
|
|
24498
|
+
replayBlocked = true;
|
|
24499
|
+
sessionLog(draft.sessionID, "lkg_replay_does_not_fit");
|
|
24500
|
+
} else if (replay.ok) {
|
|
24501
|
+
restoreLkgSystem();
|
|
24502
|
+
mapped.messages.splice(0, mapped.messages.length, ...replay.messages);
|
|
24503
|
+
mapped.commit();
|
|
24504
|
+
sessionLog(draft.sessionID, "lkg_replay_served");
|
|
24505
|
+
throw new V2LkgAdmissionReplay;
|
|
24506
|
+
} else {
|
|
24507
|
+
sessionLog(draft.sessionID, replay.reason);
|
|
24508
|
+
}
|
|
24509
|
+
}
|
|
24510
|
+
} catch (replayError) {
|
|
24511
|
+
if (replayError instanceof V2LkgAdmissionReplay)
|
|
24512
|
+
throw replayError;
|
|
24513
|
+
replayBlocked = true;
|
|
24514
|
+
sessionLog(draft.sessionID, "lkg_replay_unavailable", replayError);
|
|
24515
|
+
}
|
|
24516
|
+
if (replayBlocked)
|
|
24517
|
+
sessionLog(draft.sessionID, "lkg_replay_declined");
|
|
24518
|
+
}
|
|
23563
24519
|
});
|
|
23564
24520
|
if (admissionDb)
|
|
23565
24521
|
hideSubagentTools(draft, admissionDb);
|
|
@@ -23714,7 +24670,28 @@ async function registerContext(context) {
|
|
|
23714
24670
|
postFold = cut !== undefined;
|
|
23715
24671
|
if (cut && !incoming)
|
|
23716
24672
|
throw new Error("The host checkpoint disappeared from the context draft");
|
|
23717
|
-
|
|
24673
|
+
let nativeRestored;
|
|
24674
|
+
if (cut && nativeFoldReplay && isLocalCheckpoint(cut)) {
|
|
24675
|
+
try {
|
|
24676
|
+
nativeRestored = await nativeFoldReplay.restore(draft.sessionID, cut, `${draft.model.providerID}/${draft.model.id}`, { bounded: true });
|
|
24677
|
+
} catch (error) {
|
|
24678
|
+
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
24679
|
+
sessionLog(draft.sessionID, "v2 host fold: cache unavailable; restoring host rows", error);
|
|
24680
|
+
nativeRestored = await nativeFoldReplay.restoreRead(draft.sessionID, cut, draft.model);
|
|
24681
|
+
}
|
|
24682
|
+
}
|
|
24683
|
+
if (nativeRestored && nativeFoldReplay?.sourceChanged(draft.sessionID)) {
|
|
24684
|
+
historyRefreshSessions.add(draft.sessionID);
|
|
24685
|
+
pendingMaterializationSessions.add(draft.sessionID);
|
|
24686
|
+
}
|
|
24687
|
+
if (cut && incoming && nativeRestored) {
|
|
24688
|
+
const present = new Set(draft.messages.flatMap((message) => message.id ? [message.id] : []));
|
|
24689
|
+
const hidden = nativeRestored.filter((message) => {
|
|
24690
|
+
const id = nativeRowID(message);
|
|
24691
|
+
return !id || !present.has(id);
|
|
24692
|
+
});
|
|
24693
|
+
draft.messages.splice(0, draft.messages.length, ...hidden, ...draft.messages.filter((message) => message !== incoming));
|
|
24694
|
+
} else if (cut && incoming) {
|
|
23718
24695
|
const identity = await folds.observe({
|
|
23719
24696
|
sessionID: draft.sessionID,
|
|
23720
24697
|
cutSeq: cut.seq,
|
|
@@ -23741,6 +24718,14 @@ async function registerContext(context) {
|
|
|
23741
24718
|
} finally {
|
|
23742
24719
|
reader.close();
|
|
23743
24720
|
}
|
|
24721
|
+
let nativeMessages;
|
|
24722
|
+
if (nativeFoldReplay) {
|
|
24723
|
+
try {
|
|
24724
|
+
nativeMessages = copyNativeInput(draft.messages);
|
|
24725
|
+
} catch {
|
|
24726
|
+
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
24727
|
+
}
|
|
24728
|
+
}
|
|
23744
24729
|
const mapped = adaptPayload(draft, admitted);
|
|
23745
24730
|
beginV2LkgRequest(draft.sessionID, `${draft.model.providerID}/${draft.model.id}`, latestLkgResponseIds.get(draft.sessionID));
|
|
23746
24731
|
await transform({}, mapped);
|
|
@@ -23766,6 +24751,14 @@ ${baseline}
|
|
|
23766
24751
|
draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== head));
|
|
23767
24752
|
}
|
|
23768
24753
|
}
|
|
24754
|
+
if (nativeMessages && !checkpoint) {
|
|
24755
|
+
try {
|
|
24756
|
+
await nativeFoldReplay?.capture(draft, nativeMessages);
|
|
24757
|
+
} catch (error) {
|
|
24758
|
+
nativeFoldReplay?.invalidate(draft.sessionID, true);
|
|
24759
|
+
sessionLog(draft.sessionID, "v2 host fold: optional capture unavailable", error);
|
|
24760
|
+
}
|
|
24761
|
+
}
|
|
23769
24762
|
const capturedSlot = getSlot(draft.sessionID);
|
|
23770
24763
|
if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
|
|
23771
24764
|
lkgSystems.capture(draft.sessionID, capturedSlot, systemAtEntry, draft.system);
|
|
@@ -23773,6 +24766,8 @@ ${baseline}
|
|
|
23773
24766
|
} catch (error) {
|
|
23774
24767
|
if (error instanceof V2ContextRefusal)
|
|
23775
24768
|
throw error;
|
|
24769
|
+
if (error instanceof V2LkgAdmissionReplay)
|
|
24770
|
+
return;
|
|
23776
24771
|
if (!compactionOff && (isTransientSqliteError(error) || error instanceof StorageBusyRefusalError)) {
|
|
23777
24772
|
if (isTransientSqliteError(error)) {
|
|
23778
24773
|
try {
|
|
@@ -23800,13 +24795,16 @@ ${baseline}
|
|
|
23800
24795
|
modelKey: keys.modelKey,
|
|
23801
24796
|
providerKey: keys.providerKey
|
|
23802
24797
|
});
|
|
23803
|
-
if (replay.ok) {
|
|
24798
|
+
if (replay.ok && !replayFits(replay.messages)) {
|
|
24799
|
+
sessionLog(draft.sessionID, "lkg_replay_does_not_fit");
|
|
24800
|
+
} else if (replay.ok) {
|
|
23804
24801
|
restoreLkgSystem();
|
|
23805
24802
|
replayMapped.messages.splice(0, replayMapped.messages.length, ...replay.messages);
|
|
23806
24803
|
replayMapped.commit();
|
|
23807
24804
|
return;
|
|
24805
|
+
} else {
|
|
24806
|
+
sessionLog(draft.sessionID, replay.reason);
|
|
23808
24807
|
}
|
|
23809
|
-
sessionLog(draft.sessionID, replay.reason);
|
|
23810
24808
|
}
|
|
23811
24809
|
} catch (replayError) {
|
|
23812
24810
|
replayBlocked = true;
|