@retaw106/mmc-oc 2.0.0 → 2.1.1
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-cx3y8abt.js} +2602 -1594
- 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/heuristic-cleanup.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/constants.d.ts +1 -1
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
- package/dist/tools/ctx-expand/render.d.ts +3 -2
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/tools/ctx-expand/tools.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 +1819 -574
- 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/context-store.d.ts +2 -0
- package/dist/web/context-store.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 +873 -64
- package/dist/web/memories.d.ts +18 -2
- package/dist/web/memories.d.ts.map +1 -1
- package/dist/web/ui/panel.css +3 -0
- package/dist/web/ui/panel.js +151 -80
- package/dist/web/views.d.ts +71 -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/prompt-surface-a1-golden.md +2 -2
- 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
|
}
|
|
@@ -13442,6 +13619,8 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
13442
13619
|
continue;
|
|
13443
13620
|
const strippedSource = stripTagPrefix(stripped);
|
|
13444
13621
|
if (strippedSource.trim().length === 0) {
|
|
13622
|
+
if (target.thinkingDropProtected)
|
|
13623
|
+
continue;
|
|
13445
13624
|
const dropResult = target.drop?.() ?? "absent";
|
|
13446
13625
|
const replacement = `[dropped §${tag.tagNumber}§]`;
|
|
13447
13626
|
const didReplace = dropResult === "absent" ? target.setContent(replacement) : false;
|
|
@@ -15833,19 +16012,33 @@ function createTransform(deps) {
|
|
|
15833
16012
|
if (false) {}
|
|
15834
16013
|
return false;
|
|
15835
16014
|
};
|
|
15836
|
-
const startRecoveryRun = () => {
|
|
15837
|
-
|
|
15838
|
-
|
|
15839
|
-
|
|
15840
|
-
|
|
15841
|
-
|
|
15842
|
-
|
|
15843
|
-
|
|
16015
|
+
const startRecoveryRun = (onReady) => {
|
|
16016
|
+
if (isHistorianDrainBudgetSpent({
|
|
16017
|
+
db,
|
|
16018
|
+
sessionId,
|
|
16019
|
+
contextLimit: boundaryContextLimit,
|
|
16020
|
+
executeThresholdPercentage: boundaryExecuteThreshold,
|
|
16021
|
+
usagePercentage: boundaryUsageForProtectedTail.percentage
|
|
16022
|
+
}))
|
|
15844
16023
|
return false;
|
|
15845
|
-
|
|
15846
|
-
|
|
16024
|
+
if (!canRunCompartments || !deps.client && !deps.hiddenCompletionExecutor || getActiveCompartmentRun(sessionId))
|
|
16025
|
+
return false;
|
|
16026
|
+
const prepareRecoveryBoundary = () => {
|
|
16027
|
+
const scale = emergencyUsagePercentageEarly >= 95 ? 0.25 : 0.5;
|
|
16028
|
+
let boundarySnapshot = getRunnableBoundaryForCompartment();
|
|
16029
|
+
if (!boundarySnapshot || !hasRunnableCompartmentWindow(boundarySnapshot)) {
|
|
16030
|
+
boundarySnapshot = getRunnableBoundaryForCompartment(scale);
|
|
16031
|
+
}
|
|
16032
|
+
if (false) {}
|
|
16033
|
+
if (!boundarySnapshot || !hasRunnableCompartmentWindow(boundarySnapshot))
|
|
16034
|
+
return null;
|
|
16035
|
+
onReady?.();
|
|
16036
|
+
return boundarySnapshot;
|
|
16037
|
+
};
|
|
16038
|
+
const urgent = emergencyUsagePercentageEarly >= 95;
|
|
16039
|
+
const boundarySnapshot = urgent ? prepareRecoveryBoundary() : undefined;
|
|
16040
|
+
if (urgent && !boundarySnapshot)
|
|
15847
16041
|
return false;
|
|
15848
|
-
}
|
|
15849
16042
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
15850
16043
|
startCompartmentAgent({
|
|
15851
16044
|
client: deps.client,
|
|
@@ -15854,7 +16047,7 @@ function createTransform(deps) {
|
|
|
15854
16047
|
db,
|
|
15855
16048
|
sessionId,
|
|
15856
16049
|
historianChunkTokens: historianRun?.chunkTokens ?? deps.getHistorianChunkTokens?.() ?? 20000,
|
|
15857
|
-
boundarySnapshot,
|
|
16050
|
+
boundarySnapshot: boundarySnapshot ?? undefined,
|
|
15858
16051
|
currentContextLimit: boundaryContextLimit,
|
|
15859
16052
|
historyBudgetTokens,
|
|
15860
16053
|
historianTimeoutMs: historianRun?.timeoutMs ?? deps.historianTimeoutMs,
|
|
@@ -15874,7 +16067,7 @@ function createTransform(deps) {
|
|
|
15874
16067
|
deferredHistoryRefreshSessions.add(sid);
|
|
15875
16068
|
deferredMaterializationSessions.add(sid);
|
|
15876
16069
|
}
|
|
15877
|
-
});
|
|
16070
|
+
}, undefined, urgent ? undefined : prepareRecoveryBoundary);
|
|
15878
16071
|
return true;
|
|
15879
16072
|
};
|
|
15880
16073
|
if (fullFeatureMode && !compactionOff && historianFailureState.failureCount > 0 && emergencyUsagePercentageEarly >= 95 && !recoveryNoHeadEscapeActive) {
|
|
@@ -15888,13 +16081,15 @@ function createTransform(deps) {
|
|
|
15888
16081
|
sessionLog(sessionId, "transform: emergency recovery remains armed — no complete eligible head before protected tail");
|
|
15889
16082
|
}
|
|
15890
16083
|
sessionLog(sessionId, `EMERGENCY: historian recovery requested at ${emergencyPercentage}%, failures: ${historianFailureState.failureCount}`);
|
|
15891
|
-
} else if (fullFeatureMode && !compactionOff && isFirstTransformPassForSession && historianFailureState.failureCount > 0
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
16084
|
+
} else if (fullFeatureMode && !compactionOff && isFirstTransformPassForSession && historianFailureState.failureCount > 0) {
|
|
16085
|
+
startRecoveryRun(() => {
|
|
16086
|
+
sessionLog(sessionId, `transform: historian recovery triggered on session load after ${historianFailureState.failureCount} failure(s)`);
|
|
16087
|
+
if (deps.client) {
|
|
16088
|
+
withoutSqliteTransformPass(() => sendStatusNotification2(deps.client, sessionId, `## Historian recovery
|
|
15895
16089
|
|
|
15896
16090
|
Historian previously failed ${historianFailureState.failureCount} time(s), so Magic Context is retrying history comparting immediately after restart.`, notificationParams));
|
|
15897
|
-
|
|
16091
|
+
}
|
|
16092
|
+
});
|
|
15898
16093
|
}
|
|
15899
16094
|
logTransformTiming(sessionId, "emergencyRecoveryBlock", tFirstPass);
|
|
15900
16095
|
const memoryProjectDirectory = compartmentDirectory || process.cwd();
|
|
@@ -16441,7 +16636,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
16441
16636
|
input: lkgInput,
|
|
16442
16637
|
output: messages,
|
|
16443
16638
|
modelKey,
|
|
16444
|
-
providerKey
|
|
16639
|
+
providerKey,
|
|
16640
|
+
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
16641
|
+
agentName: notificationParams?.agent
|
|
16445
16642
|
});
|
|
16446
16643
|
if (captured) {
|
|
16447
16644
|
const capturedSlot = getInMemorySlot(sessionId);
|
|
@@ -17855,8 +18052,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
17855
18052
|
const db = readDatabase();
|
|
17856
18053
|
if (!db)
|
|
17857
18054
|
return { ok: false, error: "db unavailable" };
|
|
17858
|
-
const { runManagedRecomp } = await import("./recomp-orchestrator-
|
|
17859
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
18055
|
+
const { runManagedRecomp } = await import("./recomp-orchestrator-vc5dkzy2.js");
|
|
18056
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-rnc4nrsr.js");
|
|
17860
18057
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
17861
18058
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
17862
18059
|
return {
|
|
@@ -17905,7 +18102,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
17905
18102
|
const db = readDatabase();
|
|
17906
18103
|
if (!db)
|
|
17907
18104
|
return { ok: false, error: "db unavailable" };
|
|
17908
|
-
const { runManagedWrapup } = await import("./wrapup-orchestrator-
|
|
18105
|
+
const { runManagedWrapup } = await import("./wrapup-orchestrator-x9xamts2.js");
|
|
17909
18106
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
17910
18107
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
17911
18108
|
const ctx = {
|
|
@@ -18646,7 +18843,8 @@ function hostUsesMediaAssets() {
|
|
|
18646
18843
|
schemaUsesAssets.set(messageClass, uses);
|
|
18647
18844
|
return uses;
|
|
18648
18845
|
}
|
|
18649
|
-
function decodeThroughHostSchema(
|
|
18846
|
+
function decodeThroughHostSchema(encoded) {
|
|
18847
|
+
const source = encoded.source;
|
|
18650
18848
|
const messageClass = rememberedMessageClass;
|
|
18651
18849
|
if (!messageClass)
|
|
18652
18850
|
return "no host message class seen";
|
|
@@ -18666,7 +18864,7 @@ function decodeThroughHostSchema(source) {
|
|
|
18666
18864
|
const run = decode?.run;
|
|
18667
18865
|
if (typeof run !== "function")
|
|
18668
18866
|
return "host media schema has no decode transformation";
|
|
18669
|
-
const result = run.call(decode, { _tag: "Some", value:
|
|
18867
|
+
const result = run.call(decode, { _tag: "Some", value: encoded }, {});
|
|
18670
18868
|
const option = result?._tag === "Success" ? result.value : undefined;
|
|
18671
18869
|
const asset = option?._tag === "Some" ? option.value : undefined;
|
|
18672
18870
|
if (!isClassInstance(asset) || asset.source !== source)
|
|
@@ -18674,18 +18872,30 @@ function decodeThroughHostSchema(source) {
|
|
|
18674
18872
|
return asset;
|
|
18675
18873
|
}
|
|
18676
18874
|
function hostMediaAsset(data, mediaType) {
|
|
18677
|
-
|
|
18875
|
+
return hostMediaFromEncoded({ source: { type: "base64", data, mediaType } });
|
|
18876
|
+
}
|
|
18877
|
+
function hostMediaFromEncoded(value) {
|
|
18878
|
+
if (!isRecord3(value.source))
|
|
18879
|
+
return "missing Media.Asset source";
|
|
18880
|
+
const encoded = structuredClone(value);
|
|
18881
|
+
if (encoded.source.type === "bytes") {
|
|
18882
|
+
if (typeof encoded.source.data !== "string")
|
|
18883
|
+
return "bytes media has no JSON codec payload";
|
|
18884
|
+
encoded.source.data = new Uint8Array(Buffer.from(encoded.source.data, "base64"));
|
|
18885
|
+
}
|
|
18886
|
+
if (!["bytes", "base64", "url", "ref"].includes(String(encoded.source.type)))
|
|
18887
|
+
return "unknown Media.Asset source";
|
|
18678
18888
|
let first = "no Media.Asset seen in this process";
|
|
18679
18889
|
if (rememberedAssetClass) {
|
|
18680
18890
|
try {
|
|
18681
|
-
return new rememberedAssetClass(
|
|
18891
|
+
return new rememberedAssetClass(encoded);
|
|
18682
18892
|
} catch (error) {
|
|
18683
18893
|
first = `remembered asset class threw: ${String(error)}`;
|
|
18684
18894
|
}
|
|
18685
18895
|
}
|
|
18686
18896
|
let second;
|
|
18687
18897
|
try {
|
|
18688
|
-
const decoded = decodeThroughHostSchema(
|
|
18898
|
+
const decoded = decodeThroughHostSchema(encoded);
|
|
18689
18899
|
if (typeof decoded !== "string")
|
|
18690
18900
|
return decoded;
|
|
18691
18901
|
second = decoded;
|
|
@@ -18703,9 +18913,12 @@ var v2CompactionMarkerStrategy = {
|
|
|
18703
18913
|
reconcile: () => false
|
|
18704
18914
|
};
|
|
18705
18915
|
|
|
18916
|
+
// src/v2/fold/memory-cache.ts
|
|
18917
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
18918
|
+
|
|
18706
18919
|
// src/v2/fold/owner.ts
|
|
18707
|
-
import { createHash as
|
|
18708
|
-
var foldDigest = (value) =>
|
|
18920
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
18921
|
+
var foldDigest = (value) => createHash6("sha256").update(value).digest("hex");
|
|
18709
18922
|
|
|
18710
18923
|
class FoldOwner {
|
|
18711
18924
|
storage;
|
|
@@ -18785,1609 +18998,2235 @@ class FoldOwner {
|
|
|
18785
18998
|
}
|
|
18786
18999
|
}
|
|
18787
19000
|
|
|
18788
|
-
// src/v2/fold/
|
|
18789
|
-
|
|
19001
|
+
// src/v2/fold/memory-cache.ts
|
|
19002
|
+
var DEFAULT_NATIVE_FOLD_BUDGET = Object.freeze({
|
|
19003
|
+
maxSessionBytes: 16 * 1024 * 1024,
|
|
19004
|
+
maxSessions: 16
|
|
19005
|
+
});
|
|
19006
|
+
var stringBytes = (value) => (value?.length ?? 0) * 2;
|
|
19007
|
+
|
|
19008
|
+
class NativeFoldCache {
|
|
19009
|
+
resolveDB;
|
|
19010
|
+
sourceID = randomUUID2();
|
|
19011
|
+
tails = new Map;
|
|
19012
|
+
nativeRows = new Map;
|
|
19013
|
+
admissions = new Map;
|
|
19014
|
+
retention = new Map;
|
|
19015
|
+
evictionListeners = new Set;
|
|
19016
|
+
budget;
|
|
19017
|
+
constructor(resolveDB, budget = DEFAULT_NATIVE_FOLD_BUDGET) {
|
|
19018
|
+
this.resolveDB = resolveDB;
|
|
19019
|
+
if (!Number.isSafeInteger(budget.maxSessionBytes) || budget.maxSessionBytes < 1 || !Number.isSafeInteger(budget.maxSessions) || budget.maxSessions < 1)
|
|
19020
|
+
throw new Error("Native fold cache budgets must be positive integers");
|
|
19021
|
+
this.budget = { ...budget };
|
|
19022
|
+
}
|
|
19023
|
+
onEvict(listener) {
|
|
19024
|
+
this.evictionListeners.add(listener);
|
|
19025
|
+
}
|
|
19026
|
+
touch(sessionID) {
|
|
19027
|
+
const state = this.retention.get(sessionID) ?? { active: 0, bytes: 0, replayBytes: 0 };
|
|
19028
|
+
this.retention.delete(sessionID);
|
|
19029
|
+
this.retention.set(sessionID, state);
|
|
19030
|
+
return state;
|
|
19031
|
+
}
|
|
19032
|
+
hold(sessionID) {
|
|
19033
|
+
const state = this.touch(sessionID);
|
|
19034
|
+
state.active++;
|
|
19035
|
+
return () => {
|
|
19036
|
+
state.active--;
|
|
19037
|
+
this.enforceBudget();
|
|
19038
|
+
};
|
|
19039
|
+
}
|
|
19040
|
+
accountReplay(sessionID, bytes) {
|
|
19041
|
+
this.touch(sessionID).replayBytes = bytes;
|
|
19042
|
+
this.recount(sessionID);
|
|
19043
|
+
}
|
|
19044
|
+
usage() {
|
|
19045
|
+
return {
|
|
19046
|
+
sessions: this.retention.size,
|
|
19047
|
+
bytes: [...this.retention.values()].reduce((total, state) => total + state.bytes, 0)
|
|
19048
|
+
};
|
|
19049
|
+
}
|
|
19050
|
+
recount(sessionID) {
|
|
19051
|
+
const state = this.touch(sessionID);
|
|
19052
|
+
let bytes = 256 + stringBytes(sessionID) + state.replayBytes;
|
|
19053
|
+
const tail = this.tails.get(sessionID);
|
|
19054
|
+
if (tail)
|
|
19055
|
+
bytes += 128 + stringBytes(tail.data) + stringBytes(tail.digest);
|
|
19056
|
+
for (const row of this.nativeRows.get(sessionID)?.values() ?? [])
|
|
19057
|
+
bytes += 256 + stringBytes(row.id) + stringBytes(row.type) + stringBytes(row.data) + stringBytes(row.digest);
|
|
19058
|
+
for (const row of this.admissions.get(sessionID)?.values() ?? [])
|
|
19059
|
+
bytes += 256 + stringBytes(row.admission_id) + stringBytes(row.status) + stringBytes(row.owner_token) + stringBytes(row.data) + stringBytes(row.payload) + stringBytes(row.digest);
|
|
19060
|
+
state.bytes = bytes;
|
|
19061
|
+
this.enforceBudget();
|
|
19062
|
+
}
|
|
19063
|
+
enforceBudget() {
|
|
19064
|
+
for (const [id, state] of this.retention)
|
|
19065
|
+
if (!state.active && state.bytes > this.budget.maxSessionBytes)
|
|
19066
|
+
this.evict(id);
|
|
19067
|
+
for (const [id, state] of this.retention) {
|
|
19068
|
+
if (this.retention.size <= this.budget.maxSessions)
|
|
19069
|
+
break;
|
|
19070
|
+
if (!state.active)
|
|
19071
|
+
this.evict(id);
|
|
19072
|
+
}
|
|
19073
|
+
}
|
|
19074
|
+
evict(sessionID) {
|
|
19075
|
+
this.tails.delete(sessionID);
|
|
19076
|
+
this.nativeRows.delete(sessionID);
|
|
19077
|
+
this.admissions.delete(sessionID);
|
|
19078
|
+
this.retention.delete(sessionID);
|
|
19079
|
+
for (const listener of this.evictionListeners)
|
|
19080
|
+
listener(sessionID);
|
|
19081
|
+
}
|
|
19082
|
+
get db() {
|
|
19083
|
+
return this.resolveDB();
|
|
19084
|
+
}
|
|
19085
|
+
tail(sessionID) {
|
|
19086
|
+
const record = this.tails.get(sessionID);
|
|
19087
|
+
if (record)
|
|
19088
|
+
this.touch(sessionID);
|
|
19089
|
+
return record && { ...record };
|
|
19090
|
+
}
|
|
19091
|
+
async saveTail(sessionID, data, rows) {
|
|
19092
|
+
this.tails.set(sessionID, {
|
|
19093
|
+
revision: (this.tails.get(sessionID)?.revision ?? -1) + 1,
|
|
19094
|
+
data,
|
|
19095
|
+
digest: foldDigest(data)
|
|
19096
|
+
});
|
|
19097
|
+
const kept = this.nativeRows.get(sessionID) ?? new Map;
|
|
19098
|
+
for (const row of rows)
|
|
19099
|
+
kept.set(row.id, Object.freeze({ ...row, revision: (kept.get(row.id)?.revision ?? -1) + 1 }));
|
|
19100
|
+
this.nativeRows.set(sessionID, kept);
|
|
19101
|
+
this.recount(sessionID);
|
|
19102
|
+
}
|
|
19103
|
+
replaceRows(sessionID, through, rows, after = -1) {
|
|
19104
|
+
const kept = this.nativeRows.get(sessionID) ?? new Map;
|
|
19105
|
+
for (const [id, row] of kept)
|
|
19106
|
+
if (row.seq > after && row.seq <= through)
|
|
19107
|
+
kept.delete(id);
|
|
19108
|
+
for (const row of rows)
|
|
19109
|
+
kept.set(row.id, Object.freeze({ ...row, revision: 0 }));
|
|
19110
|
+
this.nativeRows.set(sessionID, kept);
|
|
19111
|
+
this.recount(sessionID);
|
|
19112
|
+
}
|
|
19113
|
+
truncate(sessionID, through) {
|
|
19114
|
+
const kept = this.nativeRows.get(sessionID);
|
|
19115
|
+
if (kept) {
|
|
19116
|
+
for (const [id, row] of kept)
|
|
19117
|
+
if (row.seq > through)
|
|
19118
|
+
kept.delete(id);
|
|
19119
|
+
}
|
|
19120
|
+
if (kept)
|
|
19121
|
+
this.recount(sessionID);
|
|
19122
|
+
}
|
|
19123
|
+
sequenceForID(sessionID, id) {
|
|
19124
|
+
return this.nativeRows.get(sessionID)?.get(id)?.seq;
|
|
19125
|
+
}
|
|
19126
|
+
containsRows(sessionID, ids) {
|
|
19127
|
+
const kept = this.nativeRows.get(sessionID);
|
|
19128
|
+
return ids.every((id) => kept?.has(id));
|
|
19129
|
+
}
|
|
19130
|
+
rows(sessionID, after, through) {
|
|
19131
|
+
if (this.retention.has(sessionID))
|
|
19132
|
+
this.touch(sessionID);
|
|
19133
|
+
return [...this.nativeRows.get(sessionID)?.values() ?? []].filter((row) => row.seq > after && row.seq <= through).sort((a, b) => a.seq - b.seq).map((row) => ({ ...row }));
|
|
19134
|
+
}
|
|
19135
|
+
admission(sessionID, id) {
|
|
19136
|
+
const record = this.admissions.get(sessionID)?.get(id);
|
|
19137
|
+
if (record)
|
|
19138
|
+
this.touch(sessionID);
|
|
19139
|
+
return record && { ...record };
|
|
19140
|
+
}
|
|
19141
|
+
put(sessionID, id, record) {
|
|
19142
|
+
const kept = this.admissions.get(sessionID) ?? new Map;
|
|
19143
|
+
kept.set(id, Object.freeze({ ...record }));
|
|
19144
|
+
this.admissions.set(sessionID, kept);
|
|
19145
|
+
this.recount(sessionID);
|
|
19146
|
+
}
|
|
19147
|
+
async supply(sessionID, id, payload) {
|
|
19148
|
+
const old = this.admission(sessionID, id);
|
|
19149
|
+
this.put(sessionID, id, {
|
|
19150
|
+
admission_id: id,
|
|
19151
|
+
revision: (old?.revision ?? -1) + 1,
|
|
19152
|
+
status: old?.status ?? "supplied",
|
|
19153
|
+
owner_token: old?.owner_token ?? null,
|
|
19154
|
+
data: old?.data ?? "{}",
|
|
19155
|
+
payload,
|
|
19156
|
+
digest: foldDigest(payload),
|
|
19157
|
+
logged_at: old?.logged_at ?? null
|
|
19158
|
+
});
|
|
19159
|
+
}
|
|
19160
|
+
latestAttempt(sessionID) {
|
|
19161
|
+
const record = [...this.admissions.get(sessionID)?.values() ?? []].reverse().find((row) => JSON.parse(row.data).after !== undefined);
|
|
19162
|
+
return record && { ...record };
|
|
19163
|
+
}
|
|
19164
|
+
async claim(sessionID, id, data, owner, _now) {
|
|
19165
|
+
const old = this.admission(sessionID, id);
|
|
19166
|
+
if (old?.owner_token || old?.logged_at !== null && old?.logged_at !== undefined)
|
|
19167
|
+
return false;
|
|
19168
|
+
this.put(sessionID, id, {
|
|
19169
|
+
admission_id: id,
|
|
19170
|
+
revision: 0,
|
|
19171
|
+
status: "pending",
|
|
19172
|
+
owner_token: owner,
|
|
19173
|
+
data,
|
|
19174
|
+
payload: old?.payload ?? null,
|
|
19175
|
+
digest: old?.digest ?? null,
|
|
19176
|
+
logged_at: null
|
|
19177
|
+
});
|
|
19178
|
+
return true;
|
|
19179
|
+
}
|
|
19180
|
+
async finish(sessionID, id, owner, status, now) {
|
|
19181
|
+
const old = this.admission(sessionID, id);
|
|
19182
|
+
if (!old || old.owner_token !== owner || old.status !== "pending")
|
|
19183
|
+
return false;
|
|
19184
|
+
this.put(sessionID, id, { ...old, status, owner_token: null, logged_at: now });
|
|
19185
|
+
return true;
|
|
19186
|
+
}
|
|
19187
|
+
async forget(sessionID) {
|
|
19188
|
+
this.evict(sessionID);
|
|
19189
|
+
}
|
|
19190
|
+
}
|
|
19191
|
+
function nativeFoldCache(db, budget) {
|
|
19192
|
+
return new NativeFoldCache(typeof db === "function" ? db : () => db, budget);
|
|
19193
|
+
}
|
|
18790
19194
|
|
|
18791
|
-
// src/v2/
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
return
|
|
19195
|
+
// src/v2/tool-result.ts
|
|
19196
|
+
function isToolError(part) {
|
|
19197
|
+
const result = part.result;
|
|
19198
|
+
return part.resultType === "error" || result?.type === "error" || result !== null && typeof result === "object" && "error" in result;
|
|
18795
19199
|
}
|
|
18796
|
-
function
|
|
18797
|
-
|
|
19200
|
+
function toolErrorText(result) {
|
|
19201
|
+
const value = result.value === undefined ? result : result.value;
|
|
19202
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
18798
19203
|
}
|
|
18799
|
-
function
|
|
18800
|
-
|
|
19204
|
+
function toolStateContent(state) {
|
|
19205
|
+
if (typeof state.output === "string")
|
|
19206
|
+
return state.output;
|
|
19207
|
+
if (state.status === "error")
|
|
19208
|
+
return toolErrorText({ error: state.error, content: state.content ?? [] });
|
|
19209
|
+
if (typeof state.content === "string")
|
|
19210
|
+
return state.content;
|
|
19211
|
+
if (!Array.isArray(state.content))
|
|
19212
|
+
return "";
|
|
19213
|
+
return state.content.map((part) => {
|
|
19214
|
+
if (typeof part === "string")
|
|
19215
|
+
return part;
|
|
19216
|
+
if (!part || typeof part !== "object")
|
|
19217
|
+
return "";
|
|
19218
|
+
const value = part;
|
|
19219
|
+
if (typeof value.text === "string")
|
|
19220
|
+
return value.text;
|
|
19221
|
+
if (typeof value.value === "string")
|
|
19222
|
+
return value.value;
|
|
19223
|
+
return "";
|
|
19224
|
+
}).filter(Boolean).join(`
|
|
19225
|
+
`);
|
|
18801
19226
|
}
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
19227
|
+
|
|
19228
|
+
// src/v2/hooks/payload.ts
|
|
19229
|
+
var HEAD_IDS = ["__magic_context_v2_m0__", "__magic_context_v2_m1__"];
|
|
19230
|
+
var HOST_CONTENT_TYPES = new Set([
|
|
19231
|
+
"text",
|
|
19232
|
+
"media",
|
|
19233
|
+
"tool-call",
|
|
19234
|
+
"tool-result",
|
|
19235
|
+
"reasoning",
|
|
19236
|
+
"compaction",
|
|
19237
|
+
"effort"
|
|
19238
|
+
]);
|
|
19239
|
+
function rejectContentPart(message, part, reason) {
|
|
19240
|
+
const type = typeof part.type === "string" ? part.type : "<missing>";
|
|
19241
|
+
const text = `v2 context omitted a content part the host would reject: type=${type} message=${String(message.info.id ?? "<head>")} reason=${reason}`;
|
|
19242
|
+
if (typeof message.info.sessionID === "string")
|
|
19243
|
+
sessionLog(message.info.sessionID, text);
|
|
19244
|
+
else
|
|
19245
|
+
log(text);
|
|
19246
|
+
}
|
|
19247
|
+
function isHostInstance(value) {
|
|
19248
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
18806
19249
|
return false;
|
|
18807
|
-
const
|
|
18808
|
-
return
|
|
19250
|
+
const prototype = Object.getPrototypeOf(value);
|
|
19251
|
+
return prototype !== Object.prototype && prototype !== null;
|
|
18809
19252
|
}
|
|
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;
|
|
19253
|
+
function containsHostInstance(value) {
|
|
19254
|
+
if (isHostInstance(value))
|
|
19255
|
+
return true;
|
|
19256
|
+
if (Array.isArray(value))
|
|
19257
|
+
return value.some(containsHostInstance);
|
|
19258
|
+
if (value && typeof value === "object")
|
|
19259
|
+
return Object.values(value).some(containsHostInstance);
|
|
19260
|
+
return false;
|
|
18823
19261
|
}
|
|
18824
|
-
|
|
18825
|
-
|
|
18826
|
-
|
|
18827
|
-
|
|
19262
|
+
function clonePreservingInstances(value) {
|
|
19263
|
+
if (isHostInstance(value))
|
|
19264
|
+
return value;
|
|
19265
|
+
if (Array.isArray(value))
|
|
19266
|
+
return value.map(clonePreservingInstances);
|
|
19267
|
+
if (value && typeof value === "object") {
|
|
19268
|
+
const copy = {};
|
|
19269
|
+
for (const [key, entry] of Object.entries(value))
|
|
19270
|
+
copy[key] = clonePreservingInstances(entry);
|
|
19271
|
+
return copy;
|
|
19272
|
+
}
|
|
19273
|
+
return value;
|
|
18828
19274
|
}
|
|
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);
|
|
19275
|
+
function contentKey(value) {
|
|
19276
|
+
const plain = (entry) => {
|
|
19277
|
+
if (ArrayBuffer.isView(entry)) {
|
|
19278
|
+
return {
|
|
19279
|
+
bytes: Buffer.from(entry.buffer, entry.byteOffset, entry.byteLength).toString("base64")
|
|
19280
|
+
};
|
|
18845
19281
|
}
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
if (
|
|
18849
|
-
|
|
18850
|
-
return [
|
|
18851
|
-
{
|
|
18852
|
-
type: "text",
|
|
18853
|
-
text: `
|
|
18854
|
-
|
|
18855
|
-
${[
|
|
18856
|
-
directory ? `Attached directory: ${location ?? file.name ?? uri ?? "directory"}` : `Attached file: ${file.name ?? uri ?? "inline attachment"}`,
|
|
18857
|
-
file.description === undefined ? undefined : `Description: ${file.description}`,
|
|
18858
|
-
directory && !file.data.length ? undefined : "",
|
|
18859
|
-
directory && !file.data.length ? undefined : Buffer.from(file.data, "base64").toString("utf8")
|
|
18860
|
-
].filter((line) => line !== undefined).join(`
|
|
18861
|
-
`)}`,
|
|
18862
|
-
metadata: {
|
|
18863
|
-
attachment: {
|
|
18864
|
-
source: file.source,
|
|
18865
|
-
name: file.name,
|
|
18866
|
-
description: file.description
|
|
18867
|
-
}
|
|
18868
|
-
}
|
|
18869
|
-
}
|
|
18870
|
-
];
|
|
18871
|
-
}
|
|
18872
|
-
if (!imageMimes.has(file.mime) && file.mime !== "application/pdf")
|
|
18873
|
-
return [];
|
|
18874
|
-
const metadata = file.description === undefined ? undefined : { description: file.description };
|
|
18875
|
-
const located = location ? [{ type: "text", text: `Attached file: ${location}` }] : [];
|
|
18876
|
-
if (!media)
|
|
18877
|
-
return [
|
|
18878
|
-
...located,
|
|
18879
|
-
{
|
|
18880
|
-
type: "media",
|
|
18881
|
-
mediaType: file.mime,
|
|
18882
|
-
data: file.data,
|
|
18883
|
-
filename: file.name,
|
|
18884
|
-
metadata
|
|
18885
|
-
}
|
|
18886
|
-
];
|
|
18887
|
-
const asset = media.asset(file.data, file.mime);
|
|
18888
|
-
if (typeof asset === "string") {
|
|
18889
|
-
media.unavailable({ rowID, name: file.name, mediaType: file.mime, reason: asset });
|
|
18890
|
-
return [
|
|
18891
|
-
...located,
|
|
18892
|
-
{ type: "text", text: unavailableAttachmentNote(file.name, file.mime) }
|
|
18893
|
-
];
|
|
19282
|
+
if (Array.isArray(entry))
|
|
19283
|
+
return entry.map(plain);
|
|
19284
|
+
if (entry && typeof entry === "object") {
|
|
19285
|
+
return Object.fromEntries(Object.entries(entry).map(([key, nested]) => [key, plain(nested)]));
|
|
18894
19286
|
}
|
|
18895
|
-
return
|
|
18896
|
-
}
|
|
19287
|
+
return entry;
|
|
19288
|
+
};
|
|
19289
|
+
return JSON.stringify(plain(value));
|
|
18897
19290
|
}
|
|
18898
|
-
function
|
|
18899
|
-
const
|
|
18900
|
-
|
|
18901
|
-
|
|
18902
|
-
|
|
18903
|
-
|
|
18904
|
-
|
|
18905
|
-
|
|
18906
|
-
|
|
18907
|
-
|
|
18908
|
-
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
18922
|
-
|
|
18923
|
-
|
|
18924
|
-
if (["synthetic", "skill"].includes(row.type))
|
|
18925
|
-
return [make("user", [{ type: "text", text: data.text ?? "" }])];
|
|
18926
|
-
if (row.type === "location-switched")
|
|
18927
|
-
return [
|
|
18928
|
-
make("user", [
|
|
18929
|
-
{
|
|
18930
|
-
type: "text",
|
|
18931
|
-
text: `The working directory has been changed to ${data.location.directory}.`
|
|
18932
|
-
}
|
|
18933
|
-
])
|
|
18934
|
-
];
|
|
18935
|
-
if (row.type === "shell")
|
|
18936
|
-
return data.metadata?.background === true ? [] : [
|
|
18937
|
-
make("user", [
|
|
18938
|
-
{
|
|
18939
|
-
type: "text",
|
|
18940
|
-
text: `The following shell command was executed by the user:
|
|
18941
|
-
|
|
18942
|
-
Command:
|
|
18943
|
-
${data.command}
|
|
18944
|
-
|
|
18945
|
-
Output:
|
|
18946
|
-
${data.output?.output ?? ""}`
|
|
18947
|
-
}
|
|
18948
|
-
])
|
|
18949
|
-
];
|
|
18950
|
-
if (row.type !== "assistant")
|
|
18951
|
-
return [];
|
|
18952
|
-
const previousModel = data.model;
|
|
18953
|
-
const sameProvider = previousModel?.providerID === model.providerID;
|
|
18954
|
-
const sameModel = sameProvider && previousModel?.id === model.id;
|
|
18955
|
-
const reuse = sameModel && data.error === undefined;
|
|
18956
|
-
const metadata = (state) => state === undefined ? undefined : { [model.providerID]: state };
|
|
18957
|
-
const content = [];
|
|
18958
|
-
const results = [];
|
|
18959
|
-
for (const part of data.content ?? []) {
|
|
18960
|
-
if (part.type === "text") {
|
|
18961
|
-
if (part.text !== "")
|
|
18962
|
-
content.push({
|
|
18963
|
-
type: "text",
|
|
18964
|
-
text: part.text,
|
|
18965
|
-
providerMetadata: reuse ? metadata(part.state) : undefined
|
|
18966
|
-
});
|
|
18967
|
-
continue;
|
|
18968
|
-
}
|
|
18969
|
-
if (part.type === "reasoning") {
|
|
18970
|
-
if (part.text !== "" || reuse && part.state !== undefined)
|
|
18971
|
-
content.push({
|
|
18972
|
-
type: reuse || data.error === undefined ? "reasoning" : "text",
|
|
18973
|
-
text: part.text,
|
|
18974
|
-
providerMetadata: reuse ? metadata(part.state) : undefined
|
|
18975
|
-
});
|
|
19291
|
+
function fileContentValue(result) {
|
|
19292
|
+
const value = result?.value;
|
|
19293
|
+
if (result?.type !== "content" || !Array.isArray(value))
|
|
19294
|
+
return;
|
|
19295
|
+
return value.some((item) => item?.type === "file") ? value : undefined;
|
|
19296
|
+
}
|
|
19297
|
+
function contentValueText(value) {
|
|
19298
|
+
return value.filter((item) => item?.type === "text" && typeof item.text === "string").map((item) => item.text).join(`
|
|
19299
|
+
`);
|
|
19300
|
+
}
|
|
19301
|
+
function contentValueAttachments(value) {
|
|
19302
|
+
return value.filter((item) => item?.type === "file").map((item) => ({
|
|
19303
|
+
type: "file",
|
|
19304
|
+
mime: item.mime,
|
|
19305
|
+
url: item.uri,
|
|
19306
|
+
...typeof item.name === "string" ? { filename: item.name } : {}
|
|
19307
|
+
}));
|
|
19308
|
+
}
|
|
19309
|
+
function rebuildFileContent(value, output) {
|
|
19310
|
+
if (isDroppedToolOutput(output))
|
|
19311
|
+
return { type: "text", value: output };
|
|
19312
|
+
const rebuilt = [];
|
|
19313
|
+
let placed = false;
|
|
19314
|
+
for (const item of value) {
|
|
19315
|
+
if (item?.type !== "text") {
|
|
19316
|
+
rebuilt.push(item);
|
|
18976
19317
|
continue;
|
|
18977
19318
|
}
|
|
18978
|
-
|
|
18979
|
-
const completed = state.status === "completed" || state.status === "error";
|
|
18980
|
-
const toolReuse = reuse || sameModel && part.executed === true && completed;
|
|
18981
|
-
let input = state.input;
|
|
18982
|
-
if (state.status === "streaming" && typeof input === "string") {
|
|
18983
|
-
try {
|
|
18984
|
-
input = JSON.parse(input);
|
|
18985
|
-
} catch {}
|
|
18986
|
-
}
|
|
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)
|
|
19319
|
+
if (placed)
|
|
18996
19320
|
continue;
|
|
18997
|
-
|
|
18998
|
-
|
|
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] });
|
|
19321
|
+
placed = true;
|
|
19322
|
+
rebuilt.push({ ...item, text: output });
|
|
19012
19323
|
}
|
|
19013
|
-
|
|
19014
|
-
}
|
|
19015
|
-
|
|
19016
|
-
// src/v2/fork-inheritance.ts
|
|
19017
|
-
var RAW_TYPES = new Set(RAW_MESSAGE_TYPES);
|
|
19018
|
-
function forkBoundarySeq(origin, sequenceForId) {
|
|
19019
|
-
const seq = sequenceForId(origin.parentSessionID, origin.boundary.messageID);
|
|
19020
|
-
if (seq === undefined)
|
|
19021
|
-
return;
|
|
19022
|
-
return origin.boundary.type === "before" ? seq - 1 : seq;
|
|
19324
|
+
if (!placed && output)
|
|
19325
|
+
rebuilt.unshift({ type: "text", text: output });
|
|
19326
|
+
return { type: "content", value: rebuilt };
|
|
19023
19327
|
}
|
|
19024
|
-
function
|
|
19025
|
-
const
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
const
|
|
19030
|
-
const
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
|
|
19034
|
-
|
|
19035
|
-
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19328
|
+
function adaptPayload(draft, admittedIDs = new Set) {
|
|
19329
|
+
const existingHeads = new Map(draft.messages.filter((m) => HEAD_IDS.some((id) => m.id === id)).map((m) => [m.id, m]));
|
|
19330
|
+
const source = draft.messages.filter((m) => !existingHeads.has(m.id));
|
|
19331
|
+
const results = new Map;
|
|
19332
|
+
const hostParts = new Map;
|
|
19333
|
+
const hostPartTypes = new Set;
|
|
19334
|
+
for (const message of source) {
|
|
19335
|
+
for (const part of message.content) {
|
|
19336
|
+
if (part.type !== "tool-call" && part.type !== "tool-result" && part.type !== "tool" && containsHostInstance(part)) {
|
|
19337
|
+
const key = contentKey(part);
|
|
19338
|
+
if (!hostParts.has(key))
|
|
19339
|
+
hostParts.set(key, part);
|
|
19340
|
+
hostPartTypes.add(part.type);
|
|
19341
|
+
}
|
|
19342
|
+
if (part.type === "tool-result" && typeof part.id === "string") {
|
|
19343
|
+
const queue = results.get(part.id) ?? [];
|
|
19344
|
+
queue.push({ part, message });
|
|
19345
|
+
results.set(part.id, queue);
|
|
19346
|
+
}
|
|
19042
19347
|
}
|
|
19043
19348
|
}
|
|
19044
|
-
const
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
|
|
19063
|
-
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
if (direct)
|
|
19068
|
-
return direct;
|
|
19069
|
-
const { messageId, suffix } = splitMessageScopedId(id);
|
|
19070
|
-
if (!suffix)
|
|
19071
|
-
return;
|
|
19072
|
-
const mapped = idMap.parentToFork.get(messageId);
|
|
19073
|
-
return mapped ? `${mapped}${suffix}` : undefined;
|
|
19074
|
-
};
|
|
19075
|
-
return {
|
|
19076
|
-
resolveBoundaryOrdinal: (messageId) => {
|
|
19077
|
-
const forkId = idMap.parentToFork.get(messageId);
|
|
19078
|
-
return forkId ? idMap.forkOrdinals.get(forkId) : undefined;
|
|
19079
|
-
},
|
|
19080
|
-
includeMessageId: (messageId) => mapMessageScoped(messageId) !== undefined || copiedToolCallIds.has(messageId),
|
|
19081
|
-
mapMessageId: (messageId) => mapMessageScoped(messageId) ?? messageId,
|
|
19082
|
-
includeTag: (tag) => {
|
|
19083
|
-
if (tag.type === "tool") {
|
|
19084
|
-
return tag.toolOwnerMessageId !== null && idMap.parentToFork.has(tag.toolOwnerMessageId);
|
|
19085
|
-
}
|
|
19086
|
-
return mapMessageScoped(tag.messageId) !== undefined;
|
|
19087
|
-
},
|
|
19088
|
-
mapOrdinal: (sourceOrdinal) => {
|
|
19089
|
-
const parentId = idMap.parentOrdinals.get(sourceOrdinal);
|
|
19090
|
-
const forkId = parentId ? idMap.parentToFork.get(parentId) : undefined;
|
|
19091
|
-
return forkId ? idMap.forkOrdinals.get(forkId) : undefined;
|
|
19092
|
-
},
|
|
19093
|
-
copySessionNotesAndFacts: true,
|
|
19094
|
-
selectPendingPiMarker: () => null
|
|
19095
|
-
};
|
|
19096
|
-
}
|
|
19097
|
-
function countSessionRows(db, table, sessionId) {
|
|
19098
|
-
const row = db.prepare(`SELECT COUNT(*) AS count FROM ${table} WHERE session_id = ?`).get(sessionId);
|
|
19099
|
-
return typeof row?.count === "number" ? row.count : 0;
|
|
19100
|
-
}
|
|
19101
|
-
function sessionHasMagicContextState(db, sessionId) {
|
|
19102
|
-
return countSessionRows(db, "compartments", sessionId) > 0 || countSessionRows(db, "tags", sessionId) > 0;
|
|
19103
|
-
}
|
|
19104
|
-
function seedV2ForkFromParent(args) {
|
|
19105
|
-
const { db, store, sessionId } = args;
|
|
19106
|
-
if (sessionHasMagicContextState(db, sessionId))
|
|
19107
|
-
return { kind: "has-state" };
|
|
19108
|
-
const origin = store.forkOrigin(sessionId);
|
|
19109
|
-
if (!origin)
|
|
19110
|
-
return { kind: "not-a-fork" };
|
|
19111
|
-
const parentSessionID = origin.parentSessionID;
|
|
19112
|
-
if (parentSessionID === sessionId)
|
|
19113
|
-
return { kind: "not-a-fork" };
|
|
19114
|
-
if (!sessionHasMagicContextState(db, parentSessionID))
|
|
19115
|
-
return { kind: "parent-missing", parentSessionID, reason: "no Magic Context state" };
|
|
19116
|
-
if (!store.sessionExists(parentSessionID))
|
|
19117
|
-
return { kind: "parent-missing", parentSessionID, reason: "no host session row" };
|
|
19118
|
-
const throughSeq = forkBoundarySeq(origin, (session, id) => store.sequenceForId(session, id));
|
|
19119
|
-
if (throughSeq === undefined)
|
|
19120
|
-
return { kind: "parent-missing", parentSessionID, reason: "boundary row not in the store" };
|
|
19121
|
-
const idMap = buildForkIdMap(store.rowStampsThrough(parentSessionID, throughSeq), store.rowStampsThrough(sessionId, throughSeq), throughSeq);
|
|
19122
|
-
if (idMap.parentToFork.size === 0)
|
|
19123
|
-
return { kind: "parent-missing", parentSessionID, reason: "no copied rows pair up" };
|
|
19124
|
-
const toolTags = db.prepare("SELECT message_id, tool_owner_message_id FROM tags WHERE session_id = ? AND type = 'tool'").all(parentSessionID);
|
|
19125
|
-
const copiedToolCallIds = new Set(toolTags.filter((row) => row.tool_owner_message_id !== null && idMap.parentToFork.has(row.tool_owner_message_id)).map((row) => row.message_id));
|
|
19126
|
-
const result = copySessionStateForClone(db, parentSessionID, sessionId, forkCloneFilter(idMap, copiedToolCallIds));
|
|
19127
|
-
if (result.kind === "destination-not-empty")
|
|
19128
|
-
return { kind: "destination-not-empty", parentSessionID };
|
|
19129
|
-
return { kind: "seeded", parentSessionID, pairedRows: idMap.parentToFork.size, result };
|
|
19130
|
-
}
|
|
19131
|
-
|
|
19132
|
-
// src/v2/hidden-child-record.ts
|
|
19133
|
-
function keptUnderRetention(keepSubagents, child) {
|
|
19134
|
-
return keepSubagents && (child.ever_settled === true || child.role === "historian");
|
|
19135
|
-
}
|
|
19136
|
-
function roleTitle(role) {
|
|
19137
|
-
if (role === "maintainer-a")
|
|
19138
|
-
return "Magic Context maintainer A";
|
|
19139
|
-
if (role === "maintainer-b")
|
|
19140
|
-
return "Magic Context maintainer B";
|
|
19141
|
-
return "Magic Context historian";
|
|
19142
|
-
}
|
|
19143
|
-
function roleAgent(role) {
|
|
19144
|
-
if (role === "maintainer-a")
|
|
19145
|
-
return MEMORY_MAINTAINER_A_AGENT;
|
|
19146
|
-
if (role === "maintainer-b")
|
|
19147
|
-
return MEMORY_MAINTAINER_B_AGENT;
|
|
19148
|
-
return HIDDEN_HISTORIAN_AGENT;
|
|
19149
|
-
}
|
|
19150
|
-
function childCreateInput(identity, role, model) {
|
|
19151
|
-
const agent = roleAgent(role);
|
|
19152
|
-
return {
|
|
19153
|
-
title: roleTitle(role),
|
|
19154
|
-
agent,
|
|
19155
|
-
model: {
|
|
19156
|
-
providerID: model.providerID,
|
|
19157
|
-
id: model.modelID,
|
|
19158
|
-
...model.variant ? { variant: model.variant } : {}
|
|
19159
|
-
},
|
|
19160
|
-
location: { directory: identity.directory },
|
|
19161
|
-
metadata: { magic_context: "hidden-run", role },
|
|
19162
|
-
permissions: hiddenChildPermissions(agent)
|
|
19163
|
-
};
|
|
19164
|
-
}
|
|
19165
|
-
function assistantOutcome(row) {
|
|
19166
|
-
const outcome = row?.data.outcome;
|
|
19167
|
-
return outcome === "succeeded" || outcome === "failed" || outcome === "interrupted" ? outcome : undefined;
|
|
19168
|
-
}
|
|
19169
|
-
function withReader(openReader, read) {
|
|
19170
|
-
const reader = openReader();
|
|
19171
|
-
try {
|
|
19172
|
-
return read(reader);
|
|
19173
|
-
} finally {
|
|
19174
|
-
reader.close?.();
|
|
19175
|
-
}
|
|
19176
|
-
}
|
|
19177
|
-
function errorText(value) {
|
|
19178
|
-
if (value instanceof Error)
|
|
19179
|
-
return value.message;
|
|
19180
|
-
if (typeof value === "string")
|
|
19181
|
-
return value;
|
|
19182
|
-
try {
|
|
19183
|
-
return JSON.stringify(value);
|
|
19184
|
-
} catch {
|
|
19185
|
-
return String(value);
|
|
19186
|
-
}
|
|
19187
|
-
}
|
|
19188
|
-
|
|
19189
|
-
// src/v2/hidden-child-native.ts
|
|
19190
|
-
function nativeSessionRemove(session) {
|
|
19191
|
-
const remove = session.remove;
|
|
19192
|
-
if (typeof remove !== "function")
|
|
19193
|
-
return;
|
|
19194
|
-
return (input) => Promise.resolve(remove.call(session, { sessionID: input.sessionID }));
|
|
19195
|
-
}
|
|
19196
|
-
function isSessionNotFound(error) {
|
|
19197
|
-
if (!error || typeof error !== "object")
|
|
19198
|
-
return false;
|
|
19199
|
-
const fields = error;
|
|
19200
|
-
if (fields.status === 404)
|
|
19201
|
-
return true;
|
|
19202
|
-
const label = [fields.name, fields._tag, fields.message].filter((value) => typeof value === "string").join(" ");
|
|
19203
|
-
return /not\s*found/i.test(label);
|
|
19204
|
-
}
|
|
19205
|
-
var parentDroppedNoted = false;
|
|
19206
|
-
function createNativeHiddenChildren(host, removeSession, options) {
|
|
19207
|
-
const removing = new Map;
|
|
19208
|
-
const remove = (child) => {
|
|
19209
|
-
const inFlight = removing.get(child.id);
|
|
19210
|
-
if (inFlight)
|
|
19211
|
-
return inFlight;
|
|
19212
|
-
const done = (async () => {
|
|
19213
|
-
try {
|
|
19214
|
-
let timer;
|
|
19215
|
-
try {
|
|
19216
|
-
await Promise.race([
|
|
19217
|
-
removeSession({ sessionID: child.id }),
|
|
19218
|
-
new Promise((_, reject) => {
|
|
19219
|
-
timer = setTimeout(() => reject(new Error("session.remove timed out")), options.removalTimeoutMs ?? 5000);
|
|
19220
|
-
})
|
|
19221
|
-
]);
|
|
19222
|
-
} finally {
|
|
19223
|
-
if (timer)
|
|
19224
|
-
clearTimeout(timer);
|
|
19225
|
-
}
|
|
19226
|
-
} catch (error) {
|
|
19227
|
-
if (isSessionNotFound(error))
|
|
19228
|
-
return;
|
|
19229
|
-
options.log(`[magic-context] hidden child ${child.id} could not be removed; it goes when its parent session is deleted: ${errorText(error)}`);
|
|
19349
|
+
const paired = new Set;
|
|
19350
|
+
const bridges = new Map;
|
|
19351
|
+
const originals = new Map;
|
|
19352
|
+
const bridgesByMessageID = new Map;
|
|
19353
|
+
const bridgesByCarrier = new Map;
|
|
19354
|
+
const originalsByID = new Map;
|
|
19355
|
+
const bridgesFor = (message) => typeof message.info.id === "string" ? bridgesByMessageID.get(message.info.id) : bridgesByCarrier.get(message);
|
|
19356
|
+
const nativeTool = (call, result) => {
|
|
19357
|
+
const hostResult = result?.part.result;
|
|
19358
|
+
const failed = result !== undefined && isToolError(result.part);
|
|
19359
|
+
const value = hostResult?.value;
|
|
19360
|
+
const files = fileContentValue(hostResult);
|
|
19361
|
+
const output = failed && hostResult ? toolErrorText(hostResult) : files ? contentValueText(files) : typeof value === "string" ? value : value === undefined ? "" : JSON.stringify(value);
|
|
19362
|
+
const part = {
|
|
19363
|
+
type: "tool",
|
|
19364
|
+
callID: call?.id ?? result?.part.id,
|
|
19365
|
+
tool: call?.name ?? result?.part.name,
|
|
19366
|
+
state: {
|
|
19367
|
+
input: structuredClone(call?.input ?? {}),
|
|
19368
|
+
status: failed ? "error" : result ? "completed" : "running",
|
|
19369
|
+
...result ? { output } : {},
|
|
19370
|
+
...result && (call?.name ?? result.part.name) === "question" ? { metadata: { userAnswer: true } } : {},
|
|
19371
|
+
...files ? { attachments: contentValueAttachments(files) } : {}
|
|
19230
19372
|
}
|
|
19231
|
-
}
|
|
19232
|
-
|
|
19373
|
+
};
|
|
19374
|
+
bridges.set(part, {
|
|
19375
|
+
call,
|
|
19376
|
+
result: result?.part,
|
|
19377
|
+
resultMessage: result?.message,
|
|
19378
|
+
output,
|
|
19379
|
+
files
|
|
19233
19380
|
});
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
|
|
19237
|
-
const confirmPlacement = async (sessionID, parentID) => {
|
|
19238
|
-
let stored;
|
|
19239
|
-
try {
|
|
19240
|
-
stored = await host.get({ sessionID });
|
|
19241
|
-
} catch (error) {
|
|
19242
|
-
options.log(`[magic-context] could not read back hidden child ${sessionID} to confirm its parent: ${errorText(error)}`);
|
|
19243
|
-
return;
|
|
19244
|
-
}
|
|
19245
|
-
const directory = stored.location?.directory;
|
|
19246
|
-
if (options.directory !== undefined && directory !== undefined && directory !== options.directory) {
|
|
19247
|
-
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", `hidden child ${sessionID} is bound to ${directory}, not to this instance's ${options.directory}`, true);
|
|
19248
|
-
}
|
|
19249
|
-
if (stored.parentID === parentID || parentDroppedNoted)
|
|
19250
|
-
return;
|
|
19251
|
-
parentDroppedNoted = true;
|
|
19252
|
-
options.log(`[magic-context] this OpenCode 2 host does not keep the parent of hidden-run sessions (asked for ${parentID}, read back ${stored.parentID ?? "none"}); they are created as separate sessions and still removed when each run ends`);
|
|
19381
|
+
if (result)
|
|
19382
|
+
paired.add(result.part);
|
|
19383
|
+
return part;
|
|
19253
19384
|
};
|
|
19254
|
-
const
|
|
19255
|
-
const
|
|
19256
|
-
const
|
|
19257
|
-
const {
|
|
19258
|
-
const
|
|
19259
|
-
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
id: created.id,
|
|
19264
|
-
role,
|
|
19265
|
-
generation: options.generation,
|
|
19266
|
-
title: roleTitle(role),
|
|
19267
|
-
model,
|
|
19268
|
-
created_at: Date.now(),
|
|
19269
|
-
directory: identity.directory
|
|
19385
|
+
const convertedTool = (source) => {
|
|
19386
|
+
const sourceState = source.state && typeof source.state === "object" ? source.state : {};
|
|
19387
|
+
const output = toolStateContent(sourceState);
|
|
19388
|
+
const { content: _content, ...projectedState } = structuredClone(sourceState);
|
|
19389
|
+
const part = {
|
|
19390
|
+
type: "tool",
|
|
19391
|
+
callID: source.callID ?? source.id,
|
|
19392
|
+
tool: source.tool ?? source.name,
|
|
19393
|
+
state: { ...projectedState, output }
|
|
19270
19394
|
};
|
|
19271
|
-
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19395
|
+
bridges.set(part, { native: source, output });
|
|
19396
|
+
return part;
|
|
19397
|
+
};
|
|
19398
|
+
const callParts = new Map;
|
|
19399
|
+
for (const message of source) {
|
|
19400
|
+
for (const part of message.content) {
|
|
19401
|
+
if (part.type === "tool-call") {
|
|
19402
|
+
callParts.set(part, nativeTool(part, results.get(String(part.id))?.shift()));
|
|
19403
|
+
} else if (part.type === "tool") {
|
|
19404
|
+
callParts.set(part, convertedTool(part));
|
|
19277
19405
|
}
|
|
19278
19406
|
}
|
|
19279
|
-
|
|
19280
|
-
|
|
19281
|
-
const
|
|
19282
|
-
|
|
19283
|
-
|
|
19284
|
-
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19290
|
-
|
|
19291
|
-
|
|
19292
|
-
return;
|
|
19293
|
-
}
|
|
19294
|
-
if (!kept(child))
|
|
19295
|
-
await remove(child);
|
|
19296
|
-
},
|
|
19297
|
-
updateModel: (child, model) => ({ ...child, model }),
|
|
19298
|
-
markEverSettled: (child) => ({ ...child, ever_settled: true })
|
|
19299
|
-
};
|
|
19300
|
-
}
|
|
19301
|
-
|
|
19302
|
-
// src/v2/hidden-child-cleanup.ts
|
|
19303
|
-
var PREFIX = "opencode2_hidden_children:";
|
|
19304
|
-
var COMPLETE = "opencode2_hidden_children_cleanup_complete";
|
|
19305
|
-
async function cleanupLegacyHiddenChildren(db, remove, note, options = {}) {
|
|
19306
|
-
if (db.prepare("SELECT 1 FROM schema_migrations_meta WHERE key = ?").get(COMPLETE))
|
|
19307
|
-
return;
|
|
19308
|
-
const rows = db.prepare("SELECT key, value FROM schema_migrations_meta WHERE key GLOB ? ORDER BY key LIMIT 25").all(`${PREFIX}*`);
|
|
19309
|
-
let remaining = options.limit ?? 25;
|
|
19310
|
-
const now = options.now ?? (() => performance.now());
|
|
19311
|
-
const deadline = now() + (options.budgetMs ?? 2000);
|
|
19312
|
-
for (const row of rows) {
|
|
19313
|
-
let record;
|
|
19314
|
-
try {
|
|
19315
|
-
record = JSON.parse(row.value);
|
|
19316
|
-
if (!record || typeof record !== "object" || record.active !== undefined && (!record.active || typeof record.active !== "object" || Array.isArray(record.active)) || record.retired_children !== undefined && !Array.isArray(record.retired_children))
|
|
19317
|
-
throw new Error("invalid record");
|
|
19318
|
-
} catch {
|
|
19319
|
-
note(`[magic-context] legacy hidden-child cleanup cannot read ${row.key}`);
|
|
19407
|
+
}
|
|
19408
|
+
const messages = [];
|
|
19409
|
+
for (const message of source) {
|
|
19410
|
+
const parts = [];
|
|
19411
|
+
for (const content of message.content) {
|
|
19412
|
+
if (paired.has(content))
|
|
19413
|
+
continue;
|
|
19414
|
+
const part = callParts.get(content) ?? (content.type === "tool-result" ? nativeTool(undefined, { part: content, message }) : clonePreservingInstances(content));
|
|
19415
|
+
if (message.id && admittedIDs.has(message.id))
|
|
19416
|
+
part.synthetic = true;
|
|
19417
|
+
parts.push(part);
|
|
19418
|
+
}
|
|
19419
|
+
if (!parts.length && message.content.length)
|
|
19320
19420
|
continue;
|
|
19421
|
+
const byCallID = new Map;
|
|
19422
|
+
for (const part of parts) {
|
|
19423
|
+
const bridge = bridges.get(part);
|
|
19424
|
+
if (bridge && typeof part.callID === "string")
|
|
19425
|
+
byCallID.set(part.callID, bridge);
|
|
19321
19426
|
}
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
try {
|
|
19336
|
-
await Promise.race([
|
|
19337
|
-
remove({ sessionID: child.id }),
|
|
19338
|
-
new Promise((_, reject) => {
|
|
19339
|
-
timer = setTimeout(() => reject(new Error("session.remove timed out")), Math.min(options.timeoutMs ?? 1000, Math.max(1, deadline - now())));
|
|
19340
|
-
})
|
|
19341
|
-
]);
|
|
19342
|
-
} catch (error) {
|
|
19343
|
-
if (!isSessionNotFound(error))
|
|
19344
|
-
throw error;
|
|
19427
|
+
if (typeof message.id === "string") {
|
|
19428
|
+
bridgesByMessageID.set(message.id, byCallID);
|
|
19429
|
+
originalsByID.set(message.id, message);
|
|
19430
|
+
}
|
|
19431
|
+
const mapped = {
|
|
19432
|
+
info: {
|
|
19433
|
+
id: message.id,
|
|
19434
|
+
sessionID: draft.sessionID,
|
|
19435
|
+
role: message.role,
|
|
19436
|
+
...{
|
|
19437
|
+
providerID: draft.model.providerID,
|
|
19438
|
+
modelID: draft.model.id,
|
|
19439
|
+
agent: draft.agent
|
|
19345
19440
|
}
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19350
|
-
|
|
19351
|
-
|
|
19352
|
-
|
|
19353
|
-
|
|
19441
|
+
},
|
|
19442
|
+
parts
|
|
19443
|
+
};
|
|
19444
|
+
originals.set(mapped, message);
|
|
19445
|
+
if (typeof message.id !== "string")
|
|
19446
|
+
bridgesByCarrier.set(mapped, byCallID);
|
|
19447
|
+
messages.push(mapped);
|
|
19448
|
+
}
|
|
19449
|
+
return {
|
|
19450
|
+
messages,
|
|
19451
|
+
commit() {
|
|
19452
|
+
let head = 0;
|
|
19453
|
+
const rendered = [];
|
|
19454
|
+
for (const message of messages) {
|
|
19455
|
+
const original = originals.get(message) ?? (typeof message.info.id === "string" ? originalsByID.get(message.info.id) : undefined);
|
|
19456
|
+
const id = message.info.syntheticHead ? HEAD_IDS[head++] : original?.id;
|
|
19457
|
+
const content = [];
|
|
19458
|
+
const following = [];
|
|
19459
|
+
for (const candidate of message.parts) {
|
|
19460
|
+
const part = candidate;
|
|
19461
|
+
const bridge = bridges.get(part) ?? (part.type === "tool" && typeof part.callID === "string" ? bridgesFor(message)?.get(part.callID) : undefined);
|
|
19462
|
+
if (!bridge) {
|
|
19463
|
+
if (part.type === "tool") {
|
|
19464
|
+
const state = part.state;
|
|
19465
|
+
if (typeof part.callID !== "string" || typeof part.tool !== "string" || !state || typeof state !== "object") {
|
|
19466
|
+
rejectContentPart(message, part, "tool has no call ID, name, or state");
|
|
19467
|
+
continue;
|
|
19468
|
+
}
|
|
19469
|
+
content.push({
|
|
19470
|
+
type: "tool-call",
|
|
19471
|
+
id: part.callID,
|
|
19472
|
+
name: part.tool,
|
|
19473
|
+
input: state.input
|
|
19474
|
+
});
|
|
19475
|
+
if (state.status === "completed" || state.status === "error") {
|
|
19476
|
+
following.push({
|
|
19477
|
+
role: "tool",
|
|
19478
|
+
content: [
|
|
19479
|
+
{
|
|
19480
|
+
type: "tool-result",
|
|
19481
|
+
id: part.callID,
|
|
19482
|
+
name: part.tool,
|
|
19483
|
+
result: {
|
|
19484
|
+
type: state.status === "error" ? "error" : "text",
|
|
19485
|
+
value: toolStateContent(state)
|
|
19486
|
+
}
|
|
19487
|
+
}
|
|
19488
|
+
]
|
|
19489
|
+
});
|
|
19490
|
+
}
|
|
19491
|
+
continue;
|
|
19492
|
+
}
|
|
19493
|
+
if (part.type === "file") {
|
|
19494
|
+
const mime = part.mime;
|
|
19495
|
+
const url = part.url;
|
|
19496
|
+
const prefix = `data:${mime};base64,`;
|
|
19497
|
+
if (typeof mime !== "string" || !/^image\/(png|jpeg|gif|webp)$/.test(mime) || typeof url !== "string" || !url.startsWith(prefix)) {
|
|
19498
|
+
rejectContentPart(message, part, "file is not an inline supported image");
|
|
19499
|
+
continue;
|
|
19500
|
+
}
|
|
19501
|
+
const asset = hostMediaAsset(url.slice(prefix.length), mime);
|
|
19502
|
+
if (typeof asset === "string") {
|
|
19503
|
+
rejectContentPart(message, part, `host media unavailable: ${asset}`);
|
|
19504
|
+
continue;
|
|
19505
|
+
}
|
|
19506
|
+
content.push({ type: "media", media: asset });
|
|
19507
|
+
continue;
|
|
19508
|
+
}
|
|
19509
|
+
if (!HOST_CONTENT_TYPES.has(String(part.type))) {
|
|
19510
|
+
rejectContentPart(message, part, "unknown host content type");
|
|
19511
|
+
continue;
|
|
19512
|
+
}
|
|
19513
|
+
const { synthetic: _synthetic, ...clean } = part;
|
|
19514
|
+
const original = hostPartTypes.has(clean.type) && !containsHostInstance(clean) ? hostParts.get(contentKey(clean)) : undefined;
|
|
19515
|
+
content.push(original ?? clean);
|
|
19516
|
+
continue;
|
|
19517
|
+
}
|
|
19518
|
+
const state = part.state;
|
|
19519
|
+
if (bridge.native) {
|
|
19520
|
+
const native = bridge.native;
|
|
19521
|
+
const callID = String(native.id ?? native.callID ?? part.callID);
|
|
19522
|
+
const name = String(native.name ?? native.tool ?? part.tool);
|
|
19523
|
+
content.push({ type: "tool-call", id: callID, name, input: state.input });
|
|
19524
|
+
if (state.status === "completed" || state.status === "error") {
|
|
19525
|
+
following.push({
|
|
19526
|
+
role: "tool",
|
|
19527
|
+
content: [
|
|
19528
|
+
{
|
|
19529
|
+
type: "tool-result",
|
|
19530
|
+
id: callID,
|
|
19531
|
+
name,
|
|
19532
|
+
result: {
|
|
19533
|
+
type: state.status === "error" ? "error" : "text",
|
|
19534
|
+
value: state.output
|
|
19535
|
+
}
|
|
19536
|
+
}
|
|
19537
|
+
]
|
|
19538
|
+
});
|
|
19539
|
+
}
|
|
19540
|
+
continue;
|
|
19541
|
+
}
|
|
19542
|
+
if (bridge.call)
|
|
19543
|
+
content.push({ ...bridge.call, input: state.input });
|
|
19544
|
+
if (bridge.result && bridge.resultMessage) {
|
|
19545
|
+
const result = {
|
|
19546
|
+
...bridge.result,
|
|
19547
|
+
result: state.output === bridge.output ? bridge.result.result : bridge.files && typeof state.output === "string" ? rebuildFileContent(bridge.files, state.output) : {
|
|
19548
|
+
type: state.status === "error" ? "error" : "text",
|
|
19549
|
+
value: state.output
|
|
19550
|
+
}
|
|
19551
|
+
};
|
|
19552
|
+
if (bridge.resultMessage === original)
|
|
19553
|
+
content.push(result);
|
|
19554
|
+
else
|
|
19555
|
+
following.push({ ...bridge.resultMessage, content: [result] });
|
|
19556
|
+
}
|
|
19557
|
+
}
|
|
19558
|
+
if (content.length || !original?.content.length) {
|
|
19559
|
+
const value = {
|
|
19560
|
+
...original,
|
|
19561
|
+
id,
|
|
19562
|
+
role: message.info.role ?? "user",
|
|
19563
|
+
content
|
|
19564
|
+
};
|
|
19565
|
+
const existing = id ? existingHeads.get(id) : undefined;
|
|
19566
|
+
rendered.push(existing ? Object.assign(existing, { content }) : value);
|
|
19567
|
+
}
|
|
19568
|
+
rendered.push(...following);
|
|
19354
19569
|
}
|
|
19570
|
+
draft.messages.splice(0, draft.messages.length, ...rendered);
|
|
19355
19571
|
}
|
|
19356
|
-
|
|
19357
|
-
db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(row.key);
|
|
19358
|
-
}
|
|
19359
|
-
if (!db.prepare("SELECT 1 FROM schema_migrations_meta WHERE key GLOB ? LIMIT 1").get(`${PREFIX}*`))
|
|
19360
|
-
db.prepare("INSERT OR IGNORE INTO schema_migrations_meta (key, value) VALUES (?, 'true')").run(COMPLETE);
|
|
19572
|
+
};
|
|
19361
19573
|
}
|
|
19362
19574
|
|
|
19363
|
-
// src/v2/
|
|
19364
|
-
|
|
19365
|
-
function modelKey(model) {
|
|
19366
|
-
return `${model.providerID}/${model.modelID}`;
|
|
19575
|
+
// src/v2/fold/native-codec.ts
|
|
19576
|
+
class NativeReplayUnavailable extends Error {
|
|
19367
19577
|
}
|
|
19368
|
-
function
|
|
19369
|
-
|
|
19578
|
+
function encodeNative(messages) {
|
|
19579
|
+
for (const message of messages)
|
|
19580
|
+
for (const part of message.content) {
|
|
19581
|
+
if (part.type !== "media" || !part.media)
|
|
19582
|
+
continue;
|
|
19583
|
+
const asset = part.media;
|
|
19584
|
+
if (typeof asset.toJSON !== "function" || asset.headers !== undefined)
|
|
19585
|
+
throw new NativeReplayUnavailable("Native media has no lossless replay codec");
|
|
19586
|
+
const encoded = asset.toJSON();
|
|
19587
|
+
const revived = hostMediaFromEncoded(encoded);
|
|
19588
|
+
if (typeof revived === "string" || JSON.stringify(revived) !== JSON.stringify(asset))
|
|
19589
|
+
throw new NativeReplayUnavailable("Native media cannot be decoded losslessly before admission");
|
|
19590
|
+
}
|
|
19591
|
+
const encoded = JSON.parse(JSON.stringify(messages));
|
|
19592
|
+
const freeze = (value) => {
|
|
19593
|
+
if (!value || typeof value !== "object")
|
|
19594
|
+
return;
|
|
19595
|
+
for (const item of Object.values(value))
|
|
19596
|
+
freeze(item);
|
|
19597
|
+
Object.freeze(value);
|
|
19598
|
+
};
|
|
19599
|
+
freeze(encoded);
|
|
19600
|
+
return encoded;
|
|
19370
19601
|
}
|
|
19371
|
-
function
|
|
19372
|
-
const
|
|
19373
|
-
for (const
|
|
19374
|
-
const
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
"maintainer-b": "magic-context-maintainer-b"
|
|
19384
|
-
};
|
|
19385
|
-
function roleFor(identity) {
|
|
19386
|
-
for (const [role, agent] of Object.entries(HIDDEN_MAINTAINER_ROLES)) {
|
|
19387
|
-
if (identity.agent === agent)
|
|
19388
|
-
return role;
|
|
19389
|
-
}
|
|
19390
|
-
return "historian";
|
|
19391
|
-
}
|
|
19392
|
-
function promptText(request) {
|
|
19393
|
-
const parts = request.body.parts;
|
|
19394
|
-
return Array.isArray(parts) ? parts.flatMap((part) => part && typeof part === "object" && typeof part.text === "string" ? [part.text] : []).join(`
|
|
19395
|
-
`) : "";
|
|
19602
|
+
function reviveNative(messages) {
|
|
19603
|
+
const result = structuredClone([...messages]);
|
|
19604
|
+
for (const message of result)
|
|
19605
|
+
for (const part of message.content) {
|
|
19606
|
+
if (part.type !== "media" || !part.media)
|
|
19607
|
+
continue;
|
|
19608
|
+
const asset = hostMediaFromEncoded(part.media);
|
|
19609
|
+
if (typeof asset === "string")
|
|
19610
|
+
throw new NativeReplayUnavailable(asset);
|
|
19611
|
+
part.media = asset;
|
|
19612
|
+
}
|
|
19613
|
+
return result;
|
|
19396
19614
|
}
|
|
19397
|
-
|
|
19398
|
-
|
|
19399
|
-
|
|
19400
|
-
|
|
19401
|
-
|
|
19402
|
-
|
|
19403
|
-
|
|
19615
|
+
|
|
19616
|
+
// src/v2/fold/restore.ts
|
|
19617
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19618
|
+
|
|
19619
|
+
// src/v2/hooks/storage-notice.ts
|
|
19620
|
+
var STORAGE_NOTICE_PREFIX = "[Magic Context storage notice] ";
|
|
19621
|
+
function formatStorageRefusalNotice(reason) {
|
|
19622
|
+
return `${STORAGE_NOTICE_PREFIX}This turn was not sent to the model. ${formatFailClosedBlockingSummary(reason)}`;
|
|
19404
19623
|
}
|
|
19405
|
-
function
|
|
19406
|
-
|
|
19407
|
-
`);
|
|
19408
|
-
return reasoning.length > 0 ? reasoning : null;
|
|
19624
|
+
function formatStorageRecoveryNotice(hiddenWorkRecovered) {
|
|
19625
|
+
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.`;
|
|
19409
19626
|
}
|
|
19410
|
-
function
|
|
19411
|
-
|
|
19412
|
-
return text.length > 0 ? text : null;
|
|
19627
|
+
function isStorageNoticeText(text) {
|
|
19628
|
+
return typeof text === "string" && text.startsWith(STORAGE_NOTICE_PREFIX);
|
|
19413
19629
|
}
|
|
19414
|
-
|
|
19415
|
-
|
|
19416
|
-
|
|
19417
|
-
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
|
|
19421
|
-
}
|
|
19630
|
+
function hasStorageNoticeShape(message) {
|
|
19631
|
+
if (message.role !== "user" || typeof message.id !== "string")
|
|
19632
|
+
return false;
|
|
19633
|
+
if (message.content.length !== 1)
|
|
19634
|
+
return false;
|
|
19635
|
+
const part = message.content[0];
|
|
19636
|
+
return part?.type === "text" && isStorageNoticeText(part.text);
|
|
19422
19637
|
}
|
|
19423
|
-
function
|
|
19424
|
-
const
|
|
19425
|
-
|
|
19426
|
-
|
|
19427
|
-
|
|
19428
|
-
|
|
19429
|
-
|
|
19430
|
-
};
|
|
19638
|
+
async function dropStorageNotices(messages, isAdmittedSynthetic) {
|
|
19639
|
+
const drop = new Set;
|
|
19640
|
+
for (const message of messages) {
|
|
19641
|
+
if (!hasStorageNoticeShape(message))
|
|
19642
|
+
continue;
|
|
19643
|
+
if (await isAdmittedSynthetic(message.id))
|
|
19644
|
+
drop.add(message);
|
|
19431
19645
|
}
|
|
19432
|
-
|
|
19433
|
-
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
const delay = Math.min(POLL_INTERVAL_MS, Math.max(0, deadline - Date.now()));
|
|
19438
|
-
if (delay <= 0)
|
|
19439
|
-
return;
|
|
19440
|
-
await new Promise((resolve, reject) => {
|
|
19441
|
-
const timer = setTimeout(resolve, delay);
|
|
19442
|
-
const abort = () => {
|
|
19443
|
-
clearTimeout(timer);
|
|
19444
|
-
reject(new Error("Hidden completion prompt aborted"));
|
|
19445
|
-
};
|
|
19446
|
-
signal?.addEventListener("abort", abort, { once: true });
|
|
19447
|
-
if (signal?.aborted)
|
|
19448
|
-
abort();
|
|
19449
|
-
else
|
|
19450
|
-
setTimeout(() => {
|
|
19451
|
-
signal?.removeEventListener("abort", abort);
|
|
19452
|
-
}, delay);
|
|
19453
|
-
});
|
|
19646
|
+
if (drop.size === 0)
|
|
19647
|
+
return 0;
|
|
19648
|
+
const kept = messages.filter((message) => !drop.has(message));
|
|
19649
|
+
messages.splice(0, messages.length, ...kept);
|
|
19650
|
+
return drop.size;
|
|
19454
19651
|
}
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
return typeof type === "string" && (type.startsWith("provider.") || type.toLowerCase().includes("provider"));
|
|
19652
|
+
|
|
19653
|
+
// src/v2/fold/restore.ts
|
|
19654
|
+
function unavailableAttachmentNote(name, mediaType) {
|
|
19655
|
+
return `[Attachment ${name ? `"${name}" ` : ""}(${mediaType}) is not available in this restored history]`;
|
|
19460
19656
|
}
|
|
19461
|
-
|
|
19462
|
-
|
|
19463
|
-
|
|
19464
|
-
|
|
19465
|
-
|
|
19466
|
-
|
|
19467
|
-
|
|
19468
|
-
|
|
19469
|
-
|
|
19470
|
-
|
|
19471
|
-
|
|
19472
|
-
|
|
19473
|
-
|
|
19474
|
-
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
`outcome=${outcome}`,
|
|
19478
|
-
`terminal_row=${errorText(newIdle)}`,
|
|
19479
|
-
`session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
|
|
19480
|
-
];
|
|
19481
|
-
throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
|
|
19482
|
-
}
|
|
19483
|
-
if (outcome === "succeeded" && newAssistant)
|
|
19484
|
-
return newAssistant;
|
|
19657
|
+
var imageMimes = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
|
|
19658
|
+
function attachmentParts(files, rowID, media) {
|
|
19659
|
+
const seen = new Map;
|
|
19660
|
+
return files.flatMap((file) => {
|
|
19661
|
+
if (imageMimes.has(file.mime) && file.source.type === "inline" && file.mention?.text) {
|
|
19662
|
+
const key = JSON.stringify([
|
|
19663
|
+
file.mime,
|
|
19664
|
+
file.name ?? null,
|
|
19665
|
+
file.description ?? null,
|
|
19666
|
+
file.mention.text
|
|
19667
|
+
]);
|
|
19668
|
+
const payloads = seen.get(key) ?? new Set;
|
|
19669
|
+
if (payloads.has(file.data))
|
|
19670
|
+
return [];
|
|
19671
|
+
payloads.add(file.data);
|
|
19672
|
+
seen.set(key, payloads);
|
|
19485
19673
|
}
|
|
19486
|
-
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19490
|
-
|
|
19491
|
-
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
|
|
19497
|
-
|
|
19498
|
-
|
|
19499
|
-
|
|
19500
|
-
|
|
19501
|
-
|
|
19502
|
-
|
|
19503
|
-
|
|
19504
|
-
|
|
19674
|
+
const uri = file.source.type === "uri" ? file.source.uri : undefined;
|
|
19675
|
+
const location = uri?.startsWith("file:") ? fileURLToPath2(uri) : undefined;
|
|
19676
|
+
if (file.mime === "text/plain" || file.mime === "application/x-directory") {
|
|
19677
|
+
const directory = file.mime === "application/x-directory";
|
|
19678
|
+
return [
|
|
19679
|
+
{
|
|
19680
|
+
type: "text",
|
|
19681
|
+
text: `
|
|
19682
|
+
|
|
19683
|
+
${[
|
|
19684
|
+
directory ? `Attached directory: ${location ?? file.name ?? uri ?? "directory"}` : `Attached file: ${file.name ?? uri ?? "inline attachment"}`,
|
|
19685
|
+
file.description === undefined ? undefined : `Description: ${file.description}`,
|
|
19686
|
+
directory && !file.data.length ? undefined : "",
|
|
19687
|
+
directory && !file.data.length ? undefined : Buffer.from(file.data, "base64").toString("utf8")
|
|
19688
|
+
].filter((line) => line !== undefined).join(`
|
|
19689
|
+
`)}`,
|
|
19690
|
+
metadata: {
|
|
19691
|
+
attachment: {
|
|
19692
|
+
source: file.source,
|
|
19693
|
+
name: file.name,
|
|
19694
|
+
description: file.description
|
|
19695
|
+
}
|
|
19696
|
+
}
|
|
19697
|
+
}
|
|
19698
|
+
];
|
|
19505
19699
|
}
|
|
19506
|
-
if (
|
|
19507
|
-
|
|
19700
|
+
if (!imageMimes.has(file.mime) && file.mime !== "application/pdf")
|
|
19701
|
+
return [];
|
|
19702
|
+
const metadata = file.description === undefined ? undefined : { description: file.description };
|
|
19703
|
+
const located = location ? [{ type: "text", text: `Attached file: ${location}` }] : [];
|
|
19704
|
+
if (!media)
|
|
19705
|
+
return [
|
|
19706
|
+
...located,
|
|
19707
|
+
{
|
|
19708
|
+
type: "media",
|
|
19709
|
+
mediaType: file.mime,
|
|
19710
|
+
data: file.data,
|
|
19711
|
+
filename: file.name,
|
|
19712
|
+
metadata
|
|
19713
|
+
}
|
|
19714
|
+
];
|
|
19715
|
+
const asset = media.asset(file.data, file.mime);
|
|
19716
|
+
if (typeof asset === "string") {
|
|
19717
|
+
media.unavailable({ rowID, name: file.name, mediaType: file.mime, reason: asset });
|
|
19718
|
+
return [
|
|
19719
|
+
...located,
|
|
19720
|
+
{ type: "text", text: unavailableAttachmentNote(file.name, file.mime) }
|
|
19721
|
+
];
|
|
19508
19722
|
}
|
|
19509
|
-
|
|
19510
|
-
}
|
|
19511
|
-
}
|
|
19512
|
-
var V2_HIDDEN_EXECUTOR_CAPABILITIES = {
|
|
19513
|
-
tools: true,
|
|
19514
|
-
harness: "opencode2"
|
|
19515
|
-
};
|
|
19516
|
-
function createLateHiddenExecutor(current) {
|
|
19517
|
-
const wired = () => {
|
|
19518
|
-
const executor = current();
|
|
19519
|
-
if (executor)
|
|
19520
|
-
return executor;
|
|
19521
|
-
throw new Error("Magic Context hidden work is unavailable until the context database opens.");
|
|
19522
|
-
};
|
|
19523
|
-
return {
|
|
19524
|
-
get capabilities() {
|
|
19525
|
-
return current()?.capabilities ?? V2_HIDDEN_EXECUTOR_CAPABILITIES;
|
|
19526
|
-
},
|
|
19527
|
-
open: (run) => wired().open(run),
|
|
19528
|
-
attempt: (handle, request) => wired().attempt(handle, request),
|
|
19529
|
-
collect: (handle, limit) => wired().collect(handle, limit),
|
|
19530
|
-
close: (handle, settlement) => wired().close(handle, settlement)
|
|
19531
|
-
};
|
|
19723
|
+
return [...located, { type: "media", media: asset, filename: file.name, metadata }];
|
|
19724
|
+
});
|
|
19532
19725
|
}
|
|
19533
|
-
|
|
19534
|
-
const
|
|
19535
|
-
const
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
throw new Error("Magic Context requires OpenCode 2.0.22 session.remove");
|
|
19541
|
-
const lifecycle = createNativeHiddenChildren(host, (input) => removeSession.call(host, input), {
|
|
19542
|
-
hook: options.hook,
|
|
19543
|
-
generation,
|
|
19544
|
-
keepSubagents: options.keepSubagents === true,
|
|
19545
|
-
log: note,
|
|
19546
|
-
removalTimeoutMs: options.removalTimeoutMs,
|
|
19547
|
-
directory: options.directory
|
|
19726
|
+
function restoreRow(row, model, media) {
|
|
19727
|
+
const data = row.data;
|
|
19728
|
+
const make = (role, content, metadata = data.metadata) => ({
|
|
19729
|
+
id: row.id,
|
|
19730
|
+
role,
|
|
19731
|
+
content,
|
|
19732
|
+
...metadata === undefined ? {} : { metadata }
|
|
19548
19733
|
});
|
|
19549
|
-
|
|
19550
|
-
const
|
|
19551
|
-
|
|
19552
|
-
|
|
19553
|
-
|
|
19734
|
+
if (row.type === "user") {
|
|
19735
|
+
const skills = data.skills ?? [];
|
|
19736
|
+
const content = [
|
|
19737
|
+
...skills.flatMap((skill) => skill.text === undefined ? [] : [{ type: "text", text: skill.text }]),
|
|
19738
|
+
...data.text ? [{ type: "text", text: data.text }] : [],
|
|
19739
|
+
...attachmentParts(data.files ?? [], row.id, media)
|
|
19740
|
+
];
|
|
19741
|
+
return content.length ? [
|
|
19742
|
+
make("user", content, {
|
|
19743
|
+
...data.metadata ?? {},
|
|
19744
|
+
...data.agents?.length ? { agents: data.agents } : {}
|
|
19745
|
+
})
|
|
19746
|
+
] : [];
|
|
19747
|
+
}
|
|
19748
|
+
if (row.type === "system")
|
|
19749
|
+
return [{ role: "system", content: [{ type: "text", text: data.text ?? "" }] }];
|
|
19750
|
+
if (row.type === "synthetic" && isStorageNoticeText(data.text))
|
|
19751
|
+
return [];
|
|
19752
|
+
if (["synthetic", "skill"].includes(row.type))
|
|
19753
|
+
return [make("user", [{ type: "text", text: data.text ?? "" }])];
|
|
19754
|
+
if (row.type === "location-switched")
|
|
19755
|
+
return [
|
|
19756
|
+
make("user", [
|
|
19757
|
+
{
|
|
19758
|
+
type: "text",
|
|
19759
|
+
text: `The working directory has been changed to ${data.location.directory}.`
|
|
19760
|
+
}
|
|
19761
|
+
])
|
|
19762
|
+
];
|
|
19763
|
+
if (row.type === "shell")
|
|
19764
|
+
return data.metadata?.background === true ? [] : [
|
|
19765
|
+
make("user", [
|
|
19766
|
+
{
|
|
19767
|
+
type: "text",
|
|
19768
|
+
text: `The following shell command was executed by the user:
|
|
19769
|
+
|
|
19770
|
+
Command:
|
|
19771
|
+
${data.command}
|
|
19772
|
+
|
|
19773
|
+
Output:
|
|
19774
|
+
${data.output?.output ?? ""}`
|
|
19775
|
+
}
|
|
19776
|
+
])
|
|
19777
|
+
];
|
|
19778
|
+
if (row.type !== "assistant")
|
|
19779
|
+
return [];
|
|
19780
|
+
const previousModel = data.model;
|
|
19781
|
+
const sameProvider = previousModel?.providerID === model.providerID;
|
|
19782
|
+
const sameModel = sameProvider && previousModel?.id === model.id;
|
|
19783
|
+
const reuse = sameModel && data.error === undefined;
|
|
19784
|
+
const metadata = (state) => state === undefined ? undefined : { [model.providerID]: state };
|
|
19785
|
+
const content = [];
|
|
19786
|
+
const results = [];
|
|
19787
|
+
for (const part of data.content ?? []) {
|
|
19788
|
+
if (part.type === "text") {
|
|
19789
|
+
if (part.text !== "")
|
|
19790
|
+
content.push({
|
|
19791
|
+
type: "text",
|
|
19792
|
+
text: part.text,
|
|
19793
|
+
providerMetadata: reuse ? metadata(part.state) : undefined
|
|
19794
|
+
});
|
|
19795
|
+
continue;
|
|
19796
|
+
}
|
|
19797
|
+
if (part.type === "reasoning") {
|
|
19798
|
+
if (part.text !== "" || reuse && part.state !== undefined)
|
|
19799
|
+
content.push({
|
|
19800
|
+
type: reuse || data.error === undefined ? "reasoning" : "text",
|
|
19801
|
+
text: part.text,
|
|
19802
|
+
providerMetadata: reuse ? metadata(part.state) : undefined
|
|
19803
|
+
});
|
|
19804
|
+
continue;
|
|
19805
|
+
}
|
|
19806
|
+
const state = part.state;
|
|
19807
|
+
const completed = state.status === "completed" || state.status === "error";
|
|
19808
|
+
const toolReuse = reuse || sameModel && part.executed === true && completed;
|
|
19809
|
+
let input = state.input;
|
|
19810
|
+
if (state.status === "streaming" && typeof input === "string") {
|
|
19811
|
+
try {
|
|
19812
|
+
input = JSON.parse(input);
|
|
19813
|
+
} catch {}
|
|
19814
|
+
}
|
|
19815
|
+
content.push({
|
|
19816
|
+
type: "tool-call",
|
|
19817
|
+
id: part.id,
|
|
19818
|
+
name: part.name,
|
|
19819
|
+
input,
|
|
19820
|
+
providerExecuted: part.executed,
|
|
19821
|
+
providerMetadata: toolReuse ? metadata(part.providerState) : undefined
|
|
19554
19822
|
});
|
|
19555
|
-
|
|
19556
|
-
|
|
19557
|
-
|
|
19558
|
-
|
|
19559
|
-
|
|
19560
|
-
|
|
19561
|
-
|
|
19823
|
+
if (!completed)
|
|
19824
|
+
continue;
|
|
19825
|
+
const toolContent = state.content ?? [];
|
|
19826
|
+
const single = toolContent.length === 1 ? toolContent[0] : undefined;
|
|
19827
|
+
const result = {
|
|
19828
|
+
type: "tool-result",
|
|
19829
|
+
id: part.id,
|
|
19830
|
+
name: part.name,
|
|
19831
|
+
providerExecuted: part.executed,
|
|
19832
|
+
providerMetadata: toolReuse ? metadata(part.providerResultState ?? part.providerState) : sameProvider ? metadata(part.providerResultState) : undefined,
|
|
19833
|
+
result: state.status === "error" ? { error: state.error, content: toolContent } : single?.type === "text" ? { type: "text", value: single.text } : { type: "content", value: toolContent },
|
|
19834
|
+
...state.status === "error" ? { resultType: "error" } : {}
|
|
19562
19835
|
};
|
|
19563
|
-
|
|
19564
|
-
|
|
19565
|
-
|
|
19566
|
-
|
|
19567
|
-
|
|
19836
|
+
if (part.executed === true)
|
|
19837
|
+
content.push(result);
|
|
19838
|
+
else
|
|
19839
|
+
results.push({ role: "tool", content: [result] });
|
|
19840
|
+
}
|
|
19841
|
+
return [...content.length ? [make("assistant", content)] : [], ...results];
|
|
19842
|
+
}
|
|
19843
|
+
|
|
19844
|
+
// src/v2/fold/native-replay.ts
|
|
19845
|
+
var coordinates = new WeakMap;
|
|
19846
|
+
function nativeRowID(message) {
|
|
19847
|
+
return coordinates.get(message) ?? message.id;
|
|
19848
|
+
}
|
|
19849
|
+
function copyNativeInput(messages) {
|
|
19850
|
+
const copies = reviveNative(encodeNative(messages));
|
|
19851
|
+
copies.forEach((copy, i) => {
|
|
19852
|
+
const original = messages[i];
|
|
19853
|
+
const id = original && nativeRowID(original);
|
|
19854
|
+
if (id !== undefined)
|
|
19855
|
+
coordinates.set(copy, id);
|
|
19856
|
+
});
|
|
19857
|
+
return copies;
|
|
19858
|
+
}
|
|
19859
|
+
function isLocalCheckpoint(row) {
|
|
19860
|
+
return row.type === "compaction" && row.data.status === "completed" && row.data.providerContext === undefined;
|
|
19861
|
+
}
|
|
19862
|
+
var conversational = (row) => RAW_MESSAGE_TYPES.includes(row.type) || row.type === "location-switched";
|
|
19863
|
+
|
|
19864
|
+
class NativeFoldReplay {
|
|
19865
|
+
storage;
|
|
19866
|
+
openReader;
|
|
19867
|
+
changed = new Set;
|
|
19868
|
+
dirty = new Set;
|
|
19869
|
+
unavailable = new Set;
|
|
19870
|
+
metadata = new Map;
|
|
19871
|
+
metadataThrough = new Map;
|
|
19872
|
+
loaded = new Map;
|
|
19873
|
+
sources = new Map;
|
|
19874
|
+
constructor(storage, openReader) {
|
|
19875
|
+
this.storage = storage;
|
|
19876
|
+
this.openReader = openReader;
|
|
19877
|
+
storage.onEvict((sessionID) => this.clear(sessionID));
|
|
19878
|
+
}
|
|
19879
|
+
account(sessionID) {
|
|
19880
|
+
const source = this.sources.get(sessionID);
|
|
19881
|
+
let bytes = 256 + (source?.length ?? 0) * 2;
|
|
19882
|
+
for (const row of this.metadata.get(sessionID) ?? [])
|
|
19883
|
+
bytes += 128 + (row.id.length + row.type.length) * 2;
|
|
19884
|
+
this.storage.accountReplay(sessionID, bytes);
|
|
19885
|
+
}
|
|
19886
|
+
async observeSource(sessionID, reader) {
|
|
19887
|
+
const source = reader.hostIdentity();
|
|
19888
|
+
const prior = this.sources.get(sessionID);
|
|
19889
|
+
if (prior && prior !== source)
|
|
19890
|
+
await this.forget(sessionID);
|
|
19891
|
+
this.sources.set(sessionID, source);
|
|
19892
|
+
this.account(sessionID);
|
|
19893
|
+
}
|
|
19894
|
+
onEvent(event) {
|
|
19895
|
+
const sessionID = event.data?.sessionID;
|
|
19896
|
+
if (sessionID && (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated"))
|
|
19897
|
+
this.invalidate(sessionID);
|
|
19898
|
+
}
|
|
19899
|
+
invalidate(sessionID, suppressNomination = false) {
|
|
19900
|
+
if (suppressNomination)
|
|
19901
|
+
this.unavailable.add(sessionID);
|
|
19902
|
+
this.dirty.add(sessionID);
|
|
19903
|
+
this.changed.add(sessionID);
|
|
19904
|
+
this.metadata.delete(sessionID);
|
|
19905
|
+
this.metadataThrough.delete(sessionID);
|
|
19906
|
+
this.account(sessionID);
|
|
19907
|
+
}
|
|
19908
|
+
tail(sessionID) {
|
|
19909
|
+
const record = this.storage.tail(sessionID);
|
|
19910
|
+
return record ? JSON.parse(record.data) : undefined;
|
|
19911
|
+
}
|
|
19912
|
+
async baseline(sessionID) {
|
|
19913
|
+
return this.tail(sessionID)?.baseline;
|
|
19914
|
+
}
|
|
19915
|
+
rendered(row, model) {
|
|
19916
|
+
return restoreRow(row, model, hostUsesMediaAssets() ? {
|
|
19917
|
+
asset: hostMediaAsset,
|
|
19918
|
+
unavailable: () => {}
|
|
19919
|
+
} : undefined);
|
|
19920
|
+
}
|
|
19921
|
+
record(row, messages) {
|
|
19922
|
+
const data = JSON.stringify(encodeNative(messages));
|
|
19923
|
+
return { id: row.id, type: row.type, seq: row.seq, data, digest: foldDigest(data) };
|
|
19924
|
+
}
|
|
19925
|
+
records(sessionID, native, reader) {
|
|
19926
|
+
let metadata = this.metadata.get(sessionID);
|
|
19927
|
+
const through = reader.latestSequence(sessionID);
|
|
19928
|
+
const known = new Set(metadata?.map((row) => row.id));
|
|
19929
|
+
if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through || native.some((message) => message.id && !known.has(message.id))) {
|
|
19930
|
+
metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
|
|
19931
|
+
this.metadata.set(sessionID, metadata);
|
|
19932
|
+
this.metadataThrough.set(sessionID, through);
|
|
19933
|
+
}
|
|
19934
|
+
const byID = new Map(metadata.map((row) => [row.id, row]));
|
|
19935
|
+
const grouped = new Map;
|
|
19936
|
+
const anchorIndex = native.findIndex((message) => {
|
|
19937
|
+
const id = nativeRowID(message);
|
|
19938
|
+
return id !== undefined && byID.has(id);
|
|
19939
|
+
});
|
|
19940
|
+
const leading = native.slice(0, anchorIndex < 0 ? native.length : anchorIndex).filter((message) => !nativeRowID(message) && message.role === "system");
|
|
19941
|
+
const anchorMessage = native[anchorIndex];
|
|
19942
|
+
const anchorID = anchorMessage && nativeRowID(anchorMessage);
|
|
19943
|
+
const anchor = anchorID ? byID.get(anchorID) : undefined;
|
|
19944
|
+
const leadingRows = anchor ? metadata.filter((row) => row.type === "system" && row.seq < anchor.seq).slice(-leading.length) : [];
|
|
19945
|
+
const leadingIDs = new Map(leading.map((message, i) => [message, leadingRows[i]?.id]));
|
|
19946
|
+
let cursor = -1;
|
|
19947
|
+
let owner;
|
|
19948
|
+
for (const message of native) {
|
|
19949
|
+
let id = nativeRowID(message);
|
|
19950
|
+
if (!id && message.role === "system") {
|
|
19951
|
+
if (leadingIDs.has(message)) {
|
|
19952
|
+
id = leadingIDs.get(message);
|
|
19953
|
+
if (!id)
|
|
19954
|
+
continue;
|
|
19955
|
+
} else
|
|
19956
|
+
id = metadata.find((row) => row.type === "system" && row.seq > cursor)?.id;
|
|
19957
|
+
}
|
|
19958
|
+
if (!id && message.role === "tool")
|
|
19959
|
+
id = owner;
|
|
19960
|
+
const row = id ? byID.get(id) : undefined;
|
|
19961
|
+
if (!row)
|
|
19962
|
+
throw new NativeReplayUnavailable("Native carrier has no source row coordinate");
|
|
19963
|
+
cursor = row.seq;
|
|
19964
|
+
coordinates.set(message, row.id);
|
|
19965
|
+
if (message.role !== "tool")
|
|
19966
|
+
owner = row.id;
|
|
19967
|
+
const messages = grouped.get(row) ?? [];
|
|
19968
|
+
messages.push(message);
|
|
19969
|
+
grouped.set(row, messages);
|
|
19970
|
+
}
|
|
19971
|
+
return [...grouped].map(([row, messages]) => this.record(row, messages));
|
|
19972
|
+
}
|
|
19973
|
+
async capture(draft, native) {
|
|
19974
|
+
const release = this.storage.hold(draft.sessionID);
|
|
19568
19975
|
try {
|
|
19569
|
-
|
|
19570
|
-
const
|
|
19571
|
-
|
|
19572
|
-
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
|
|
19577
|
-
|
|
19578
|
-
|
|
19579
|
-
|
|
19976
|
+
rememberHostMedia(native);
|
|
19977
|
+
const reader = this.openReader(draft.sessionID);
|
|
19978
|
+
try {
|
|
19979
|
+
const rows = this.records(draft.sessionID, native, reader);
|
|
19980
|
+
const baseline = draft.messages.find((message) => message.id === HEAD_IDS[0])?.content.find((part) => part.type === "text")?.text;
|
|
19981
|
+
const through = Math.max(-1, ...rows.map((row) => row.seq));
|
|
19982
|
+
const tail = {
|
|
19983
|
+
model: `${draft.model.providerID}/${draft.model.id}`,
|
|
19984
|
+
sourceSeq: through,
|
|
19985
|
+
baseline: typeof baseline === "string" ? baseline : this.tail(draft.sessionID)?.baseline
|
|
19986
|
+
};
|
|
19987
|
+
await this.storage.saveTail(draft.sessionID, JSON.stringify(tail), rows);
|
|
19988
|
+
this.storage.truncate(draft.sessionID, through);
|
|
19989
|
+
this.loaded.set(draft.sessionID, through);
|
|
19990
|
+
this.unavailable.delete(draft.sessionID);
|
|
19991
|
+
this.changed.delete(draft.sessionID);
|
|
19992
|
+
} finally {
|
|
19993
|
+
reader.close();
|
|
19580
19994
|
}
|
|
19581
|
-
return { providerID: model.providerID, modelID: model.modelID };
|
|
19582
19995
|
} catch {
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19587
|
-
|
|
19588
|
-
if (configured)
|
|
19589
|
-
return validateVariant(configured);
|
|
19590
|
-
if (!identity.parentSessionId) {
|
|
19591
|
-
throw new HiddenCompletionRefusal("hidden_model_unsupported", "Hidden completion requires a configured model or an existing parent session model", true);
|
|
19996
|
+
this.unavailable.add(draft.sessionID);
|
|
19997
|
+
this.invalidate(draft.sessionID);
|
|
19998
|
+
} finally {
|
|
19999
|
+
this.account(draft.sessionID);
|
|
20000
|
+
release();
|
|
19592
20001
|
}
|
|
19593
|
-
|
|
19594
|
-
|
|
19595
|
-
|
|
20002
|
+
}
|
|
20003
|
+
async canReplay(sessionID, _reader) {
|
|
20004
|
+
return !this.unavailable.has(sessionID) && typeof await this.baseline(sessionID) === "string";
|
|
20005
|
+
}
|
|
20006
|
+
async supply(args) {
|
|
20007
|
+
const release = this.storage.hold(args.draft.sessionID);
|
|
20008
|
+
try {
|
|
20009
|
+
return await this.supplyHeld(args);
|
|
20010
|
+
} finally {
|
|
20011
|
+
this.account(args.draft.sessionID);
|
|
20012
|
+
release();
|
|
19596
20013
|
}
|
|
19597
|
-
|
|
19598
|
-
|
|
19599
|
-
|
|
19600
|
-
|
|
20014
|
+
}
|
|
20015
|
+
async supplyHeld(args) {
|
|
20016
|
+
const { draft, reader, summary } = args;
|
|
20017
|
+
const tail = this.tail(draft.sessionID);
|
|
20018
|
+
const id = reader.latestRunningCompaction(draft.sessionID)?.id;
|
|
20019
|
+
if (!id || !tail || tail.model !== `${draft.model.providerID}/${draft.model.id}`)
|
|
20020
|
+
return false;
|
|
20021
|
+
const through = reader.latestSequence(draft.sessionID);
|
|
20022
|
+
const after = this.dirty.has(draft.sessionID) ? -1 : tail.sourceSeq;
|
|
20023
|
+
const fresh = reader.range(draft.sessionID, after, through).filter(conversational);
|
|
20024
|
+
const records = fresh.map((row) => this.record(row, this.rendered(row, draft.model)));
|
|
20025
|
+
if (this.dirty.has(draft.sessionID))
|
|
20026
|
+
this.storage.replaceRows(draft.sessionID, through, records);
|
|
20027
|
+
await this.storage.saveTail(draft.sessionID, JSON.stringify({
|
|
20028
|
+
...tail,
|
|
20029
|
+
sourceSeq: Math.max(tail.sourceSeq, ...fresh.map((row) => row.seq))
|
|
20030
|
+
}), records);
|
|
20031
|
+
this.dirty.delete(draft.sessionID);
|
|
20032
|
+
this.metadata.delete(draft.sessionID);
|
|
20033
|
+
this.metadataThrough.delete(draft.sessionID);
|
|
20034
|
+
this.loaded.set(draft.sessionID, through);
|
|
20035
|
+
const snapshot = {
|
|
20036
|
+
source: this.storage.sourceID,
|
|
20037
|
+
sessionID: draft.sessionID,
|
|
20038
|
+
admissionID: id,
|
|
20039
|
+
summary
|
|
19601
20040
|
};
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
|
|
20041
|
+
await this.storage.supply(draft.sessionID, id, JSON.stringify(snapshot));
|
|
20042
|
+
return true;
|
|
20043
|
+
}
|
|
20044
|
+
async restore(sessionID, cut, model, options = {}) {
|
|
20045
|
+
const release = this.storage.hold(sessionID);
|
|
20046
|
+
try {
|
|
20047
|
+
return await this.restoreHeld(sessionID, cut, model, options);
|
|
20048
|
+
} finally {
|
|
20049
|
+
this.account(sessionID);
|
|
20050
|
+
release();
|
|
20051
|
+
}
|
|
20052
|
+
}
|
|
20053
|
+
async restoreHeld(sessionID, cut, model, options) {
|
|
20054
|
+
if (!isLocalCheckpoint(cut))
|
|
19605
20055
|
return;
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
20056
|
+
const resolvedModel = {
|
|
20057
|
+
providerID: model.slice(0, model.indexOf("/")),
|
|
20058
|
+
id: model.slice(model.indexOf("/") + 1)
|
|
20059
|
+
};
|
|
20060
|
+
const tail = this.tail(sessionID);
|
|
20061
|
+
if (tail && tail.model !== model)
|
|
20062
|
+
this.invalidate(sessionID);
|
|
20063
|
+
let after = options.after ?? -1;
|
|
20064
|
+
if (options.bounded && options.after === undefined && !this.changed.has(sessionID)) {
|
|
20065
|
+
const state = getOrCreateSessionMeta(this.storage.db, sessionID);
|
|
20066
|
+
const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
|
|
20067
|
+
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;
|
|
20068
|
+
if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary)
|
|
20069
|
+
after = this.storage.sequenceForID(sessionID, boundary) ?? -1;
|
|
20070
|
+
}
|
|
20071
|
+
const through = cut.seq - 1;
|
|
20072
|
+
let reader;
|
|
20073
|
+
try {
|
|
20074
|
+
let metadata = this.metadata.get(sessionID);
|
|
20075
|
+
if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through) {
|
|
20076
|
+
reader = this.openReader(sessionID);
|
|
20077
|
+
metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
|
|
20078
|
+
this.metadata.set(sessionID, metadata);
|
|
20079
|
+
this.metadataThrough.set(sessionID, through);
|
|
20080
|
+
}
|
|
20081
|
+
const required = metadata.filter((row) => row.seq > after && row.seq <= through);
|
|
20082
|
+
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))) {
|
|
20083
|
+
reader ??= this.openReader(sessionID);
|
|
20084
|
+
const fresh = reader.range(sessionID, after, through).filter(conversational);
|
|
20085
|
+
const records = fresh.map((row) => this.record(row, this.rendered(row, resolvedModel)));
|
|
20086
|
+
const restored = new Set(records.map((row) => row.id));
|
|
20087
|
+
if (required.some((row) => !restored.has(row.id)))
|
|
20088
|
+
throw new NativeReplayUnavailable("Host restore omitted a required source row");
|
|
20089
|
+
this.storage.replaceRows(sessionID, through, records, after);
|
|
20090
|
+
await this.storage.saveTail(sessionID, JSON.stringify({
|
|
20091
|
+
model,
|
|
20092
|
+
sourceSeq: through,
|
|
20093
|
+
baseline: tail?.baseline ?? cut.data.summary
|
|
20094
|
+
}), []);
|
|
20095
|
+
this.loaded.set(sessionID, through);
|
|
20096
|
+
this.dirty.delete(sessionID);
|
|
19612
20097
|
}
|
|
19613
|
-
}
|
|
19614
|
-
|
|
19615
|
-
|
|
19616
|
-
|
|
19617
|
-
|
|
19618
|
-
|
|
19619
|
-
|
|
19620
|
-
|
|
19621
|
-
|
|
19622
|
-
|
|
20098
|
+
} finally {
|
|
20099
|
+
reader?.close();
|
|
20100
|
+
}
|
|
20101
|
+
const messages = [];
|
|
20102
|
+
for (const row of this.storage.rows(sessionID, after, cut.seq - 1)) {
|
|
20103
|
+
const revived = reviveNative(JSON.parse(row.data));
|
|
20104
|
+
for (const message of revived)
|
|
20105
|
+
coordinates.set(message, row.id);
|
|
20106
|
+
messages.push(...revived);
|
|
20107
|
+
}
|
|
20108
|
+
return messages;
|
|
20109
|
+
}
|
|
20110
|
+
async restoreRead(sessionID, cut, model) {
|
|
20111
|
+
const reader = this.openReader(sessionID);
|
|
19623
20112
|
try {
|
|
19624
|
-
|
|
20113
|
+
return reader.range(sessionID, -1, cut.seq - 1).filter(conversational).flatMap((row) => {
|
|
20114
|
+
const messages = this.rendered(row, model);
|
|
20115
|
+
for (const message of messages)
|
|
20116
|
+
coordinates.set(message, row.id);
|
|
20117
|
+
return messages;
|
|
20118
|
+
});
|
|
19625
20119
|
} finally {
|
|
19626
|
-
|
|
20120
|
+
reader.close();
|
|
19627
20121
|
}
|
|
19628
|
-
}
|
|
19629
|
-
|
|
19630
|
-
|
|
19631
|
-
|
|
19632
|
-
|
|
19633
|
-
|
|
19634
|
-
|
|
20122
|
+
}
|
|
20123
|
+
sourceChanged(sessionID) {
|
|
20124
|
+
return this.changed.has(sessionID);
|
|
20125
|
+
}
|
|
20126
|
+
clear(sessionID) {
|
|
20127
|
+
this.sources.delete(sessionID);
|
|
20128
|
+
this.metadata.delete(sessionID);
|
|
20129
|
+
this.metadataThrough.delete(sessionID);
|
|
20130
|
+
this.loaded.delete(sessionID);
|
|
20131
|
+
this.unavailable.delete(sessionID);
|
|
20132
|
+
this.dirty.delete(sessionID);
|
|
20133
|
+
this.changed.delete(sessionID);
|
|
20134
|
+
}
|
|
20135
|
+
async forget(sessionID) {
|
|
20136
|
+
await this.storage.forget(sessionID);
|
|
20137
|
+
}
|
|
20138
|
+
}
|
|
20139
|
+
|
|
20140
|
+
// src/v2/fold/policy.ts
|
|
20141
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
20142
|
+
class HostFoldPolicy {
|
|
20143
|
+
deps;
|
|
20144
|
+
active = new Set;
|
|
20145
|
+
owner = randomUUID3();
|
|
20146
|
+
constructor(deps) {
|
|
20147
|
+
this.deps = deps;
|
|
20148
|
+
}
|
|
20149
|
+
owned(sessionID, cut, id) {
|
|
20150
|
+
const row = this.deps.storage.admission(sessionID, id);
|
|
20151
|
+
if (!isLocalCheckpoint(cut) || cut.id !== id || !row?.payload || row.digest !== foldDigest(row.payload))
|
|
20152
|
+
return false;
|
|
20153
|
+
const snapshot = JSON.parse(row.payload);
|
|
20154
|
+
return snapshot.summary === cut.data.summary && snapshot.source === this.deps.storage.sourceID && snapshot.sessionID === sessionID && snapshot.admissionID === id;
|
|
20155
|
+
}
|
|
20156
|
+
async idle(sessionID) {
|
|
20157
|
+
const { storage, session, threshold } = this.deps;
|
|
20158
|
+
if (!Number.isSafeInteger(threshold) || threshold <= 0 || typeof session.compact !== "function" || this.active.has(sessionID))
|
|
20159
|
+
return;
|
|
20160
|
+
this.active.add(sessionID);
|
|
20161
|
+
const now = this.deps.now ?? Date.now;
|
|
20162
|
+
let attempt;
|
|
20163
|
+
let claimed = false;
|
|
20164
|
+
try {
|
|
20165
|
+
const reader = this.deps.openReader();
|
|
19635
20166
|
try {
|
|
19636
|
-
|
|
19637
|
-
const
|
|
19638
|
-
const
|
|
19639
|
-
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
|
|
19643
|
-
role,
|
|
19644
|
-
child: active,
|
|
19645
|
-
releaseRole,
|
|
19646
|
-
failed: false,
|
|
19647
|
-
unsettledFailure: false,
|
|
19648
|
-
retired: false
|
|
19649
|
-
};
|
|
19650
|
-
runs.set(handle, run);
|
|
19651
|
-
await switchChildModel(run, head);
|
|
19652
|
-
return handle;
|
|
19653
|
-
} catch (error) {
|
|
19654
|
-
if (openedChild)
|
|
19655
|
-
lifecycle.retire(openedChild, "hidden-run-open-failed");
|
|
19656
|
-
releaseRole();
|
|
19657
|
-
throw error;
|
|
19658
|
-
}
|
|
19659
|
-
},
|
|
19660
|
-
async attempt(handle, request) {
|
|
19661
|
-
const run = runs.get(handle);
|
|
19662
|
-
if (!run)
|
|
19663
|
-
throw new Error("Unknown hidden completion run");
|
|
19664
|
-
if (request.signal?.aborted) {
|
|
19665
|
-
await interruptAndRetire(run, "aborted-before-prompt");
|
|
19666
|
-
throw new Error("Hidden completion prompt aborted");
|
|
19667
|
-
}
|
|
19668
|
-
const requested = await validateVariant(requestModel(request, run.child.model));
|
|
19669
|
-
if (run.retired) {
|
|
19670
|
-
run.child = await lifecycle.create(run.identity, run.role, requested);
|
|
19671
|
-
run.failed = false;
|
|
19672
|
-
run.unsettledFailure = false;
|
|
19673
|
-
run.retired = false;
|
|
19674
|
-
handle.id = run.child.id;
|
|
19675
|
-
handle.childSessionId = run.child.id;
|
|
19676
|
-
}
|
|
19677
|
-
await switchChildModel(run, requested);
|
|
19678
|
-
const baseline = withReader(options.openReader, (reader) => reader.latestSequence(run.child.id));
|
|
19679
|
-
const marker = `mc:hidden:${crypto.randomUUID()}:${crypto.randomUUID()}`;
|
|
19680
|
-
run.completion = undefined;
|
|
19681
|
-
const stepCap = options.resolveStepCap?.(run.identity);
|
|
19682
|
-
const attempt = {
|
|
19683
|
-
childSessionId: run.child.id,
|
|
19684
|
-
identity: run.identity,
|
|
19685
|
-
agent: run.identity.agent,
|
|
19686
|
-
request,
|
|
19687
|
-
shaped: false,
|
|
19688
|
-
...stepCap === undefined ? {} : { stepCap }
|
|
19689
|
-
};
|
|
19690
|
-
options.hook.registerAttempt(marker, attempt);
|
|
19691
|
-
const deadline = Date.now() + run.identity.timeoutMs;
|
|
19692
|
-
let abortReject;
|
|
19693
|
-
const aborted = new Promise((_resolve, reject) => {
|
|
19694
|
-
abortReject = reject;
|
|
19695
|
-
});
|
|
19696
|
-
const onAbort = () => {
|
|
19697
|
-
interruptAndRetire(run, "prompt-aborted").finally(() => abortReject(new Error("Hidden completion prompt aborted")));
|
|
19698
|
-
};
|
|
19699
|
-
const deadlineTimer = setTimeout(() => {
|
|
19700
|
-
interruptAndRetire(run, "prompt-timeout").finally(() => abortReject(new Error("Hidden completion prompt timed out")));
|
|
19701
|
-
}, Math.max(0, deadline - Date.now()));
|
|
19702
|
-
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
|
-
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", "Host did not dispatch the hidden child context hook", true);
|
|
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");
|
|
20167
|
+
const cut = reader.latestCompaction(sessionID);
|
|
20168
|
+
const previous = storage.latestAttempt(sessionID);
|
|
20169
|
+
const old = previous ? JSON.parse(previous.data) : undefined;
|
|
20170
|
+
if (cut && previous?.status === "pending" && old && this.owned(sessionID, cut, old.id)) {
|
|
20171
|
+
if (await storage.claim(sessionID, old.id, previous.data, this.owner, now()) && await storage.finish(sessionID, old.id, this.owner, "completed", now()))
|
|
20172
|
+
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`);
|
|
20173
|
+
return;
|
|
19736
20174
|
}
|
|
19737
|
-
|
|
19738
|
-
|
|
19739
|
-
|
|
19740
|
-
|
|
19741
|
-
|
|
19742
|
-
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
|
|
19746
|
-
|
|
19747
|
-
|
|
19748
|
-
|
|
19749
|
-
|
|
19750
|
-
...attempt.steps === undefined ? {} : { steps: attempt.steps }
|
|
20175
|
+
const after = cut?.seq ?? -1;
|
|
20176
|
+
const before = reader.storedRowsAfter(sessionID, after);
|
|
20177
|
+
if (before < threshold || !await this.deps.canReplay(sessionID, reader))
|
|
20178
|
+
return;
|
|
20179
|
+
const retry = old?.after === after ? old.attempt + (previous?.status === "failed" || previous?.status === "coalesced" ? 1 : 0) : 0;
|
|
20180
|
+
const id = old?.after === after && previous?.status === "pending" ? old.id : `msg_mc_fold_${foldDigest(`${storage.sourceID}/${sessionID}/${after}/${retry}`).slice(0, 24)}`;
|
|
20181
|
+
attempt = {
|
|
20182
|
+
after,
|
|
20183
|
+
before,
|
|
20184
|
+
watermark: reader.latestSequence(sessionID),
|
|
20185
|
+
attempt: retry,
|
|
20186
|
+
id,
|
|
20187
|
+
started: now()
|
|
19751
20188
|
};
|
|
19752
|
-
|
|
19753
|
-
|
|
19754
|
-
|
|
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;
|
|
20189
|
+
claimed = await storage.claim(sessionID, id, JSON.stringify(attempt), this.owner, now());
|
|
20190
|
+
if (!claimed)
|
|
20191
|
+
return;
|
|
19768
20192
|
} finally {
|
|
19769
|
-
|
|
19770
|
-
request.signal?.removeEventListener("abort", onAbort);
|
|
19771
|
-
options.hook.releaseAttempt(marker);
|
|
20193
|
+
reader.close();
|
|
19772
20194
|
}
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
|
|
19777
|
-
|
|
19778
|
-
|
|
19779
|
-
|
|
19780
|
-
async close(handle, settlement) {
|
|
19781
|
-
if (!handle)
|
|
19782
|
-
return;
|
|
19783
|
-
const run = runs.get(handle);
|
|
19784
|
-
if (!run)
|
|
19785
|
-
return;
|
|
20195
|
+
const admitted = await session.compact({
|
|
20196
|
+
sessionID,
|
|
20197
|
+
id: attempt.id,
|
|
20198
|
+
delivery: "queue"
|
|
20199
|
+
});
|
|
20200
|
+
await session.wait({ sessionID });
|
|
20201
|
+
const settled = this.deps.openReader();
|
|
19786
20202
|
try {
|
|
19787
|
-
const
|
|
19788
|
-
if (!
|
|
19789
|
-
|
|
20203
|
+
const cut = settled.latestCompaction(sessionID);
|
|
20204
|
+
if (admitted?.id !== attempt.id || !cut || cut.seq <= attempt.after || !this.owned(sessionID, cut, attempt.id)) {
|
|
20205
|
+
if (await storage.finish(sessionID, attempt.id, this.owner, "coalesced", now()))
|
|
20206
|
+
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`);
|
|
20207
|
+
return;
|
|
19790
20208
|
}
|
|
20209
|
+
const after = settled.storedRowsAfter(sessionID, cut.seq);
|
|
20210
|
+
if (await storage.finish(sessionID, attempt.id, this.owner, "completed", now()))
|
|
20211
|
+
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`);
|
|
19791
20212
|
} finally {
|
|
19792
|
-
|
|
19793
|
-
run.releaseRole();
|
|
20213
|
+
settled.close();
|
|
19794
20214
|
}
|
|
19795
|
-
|
|
20215
|
+
} catch (error) {
|
|
20216
|
+
if (claimed && attempt) {
|
|
20217
|
+
let finished = false;
|
|
20218
|
+
try {
|
|
20219
|
+
finished = await storage.finish(sessionID, attempt.id, this.owner, "failed", now());
|
|
20220
|
+
} catch {
|
|
20221
|
+
finished = true;
|
|
20222
|
+
}
|
|
20223
|
+
if (finished)
|
|
20224
|
+
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))}`);
|
|
20225
|
+
} else
|
|
20226
|
+
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))}`);
|
|
20227
|
+
} finally {
|
|
20228
|
+
this.active.delete(sessionID);
|
|
19796
20229
|
}
|
|
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
20230
|
}
|
|
19813
|
-
return stored;
|
|
19814
20231
|
}
|
|
19815
|
-
|
|
19816
|
-
|
|
20232
|
+
|
|
20233
|
+
// src/v2/fork-inheritance.ts
|
|
20234
|
+
var RAW_TYPES = new Set(RAW_MESSAGE_TYPES);
|
|
20235
|
+
function forkBoundarySeq(origin, sequenceForId) {
|
|
20236
|
+
const seq = sequenceForId(origin.parentSessionID, origin.boundary.messageID);
|
|
20237
|
+
if (seq === undefined)
|
|
20238
|
+
return;
|
|
20239
|
+
return origin.boundary.type === "before" ? seq - 1 : seq;
|
|
19817
20240
|
}
|
|
19818
|
-
|
|
19819
|
-
const
|
|
19820
|
-
|
|
19821
|
-
|
|
19822
|
-
|
|
19823
|
-
|
|
19824
|
-
|
|
20241
|
+
function buildForkIdMap(parentRows, forkRows, throughSeq) {
|
|
20242
|
+
const parentBySeq = new Map;
|
|
20243
|
+
for (const row of parentRows)
|
|
20244
|
+
if (row.seq <= throughSeq)
|
|
20245
|
+
parentBySeq.set(row.seq, row);
|
|
20246
|
+
const parentToFork = new Map;
|
|
20247
|
+
const forkOrdinals = new Map;
|
|
20248
|
+
let ordinal = 0;
|
|
20249
|
+
for (const row of forkRows) {
|
|
20250
|
+
if (row.seq > throughSeq)
|
|
20251
|
+
break;
|
|
20252
|
+
if (RAW_TYPES.has(row.type)) {
|
|
20253
|
+
ordinal += 1;
|
|
20254
|
+
forkOrdinals.set(row.id, ordinal);
|
|
20255
|
+
}
|
|
20256
|
+
const parent = parentBySeq.get(row.seq);
|
|
20257
|
+
if (parent && parent.type === row.type && parent.time_created === row.time_created && row.id !== parent.id && row.id.endsWith(`_${row.seq}`)) {
|
|
20258
|
+
parentToFork.set(parent.id, row.id);
|
|
20259
|
+
}
|
|
19825
20260
|
}
|
|
19826
|
-
|
|
19827
|
-
|
|
19828
|
-
|
|
19829
|
-
|
|
19830
|
-
|
|
19831
|
-
|
|
19832
|
-
|
|
19833
|
-
|
|
19834
|
-
|
|
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;
|
|
20261
|
+
const parentOrdinals = new Map;
|
|
20262
|
+
let parentOrdinal = 0;
|
|
20263
|
+
for (const row of parentRows) {
|
|
20264
|
+
if (row.seq > throughSeq)
|
|
20265
|
+
break;
|
|
20266
|
+
if (!RAW_TYPES.has(row.type))
|
|
20267
|
+
continue;
|
|
20268
|
+
parentOrdinal += 1;
|
|
20269
|
+
parentOrdinals.set(parentOrdinal, row.id);
|
|
19848
20270
|
}
|
|
19849
|
-
|
|
20271
|
+
return { parentToFork, forkOrdinals, parentOrdinals, throughSeq };
|
|
19850
20272
|
}
|
|
19851
|
-
|
|
19852
|
-
|
|
19853
|
-
|
|
19854
|
-
const
|
|
19855
|
-
if (!
|
|
19856
|
-
|
|
19857
|
-
|
|
19858
|
-
|
|
19859
|
-
|
|
19860
|
-
const
|
|
19861
|
-
|
|
19862
|
-
|
|
19863
|
-
|
|
19864
|
-
|
|
19865
|
-
|
|
19866
|
-
|
|
19867
|
-
|
|
19868
|
-
|
|
20273
|
+
var CONTENT_ID_SUFFIX = /(:(?:p|file)\d+)$/;
|
|
20274
|
+
var BLOCK_ID_SUFFIX = /(#\d+)$/;
|
|
20275
|
+
function splitMessageScopedId(id) {
|
|
20276
|
+
const match = id.match(CONTENT_ID_SUFFIX) ?? id.match(BLOCK_ID_SUFFIX);
|
|
20277
|
+
if (!match?.[1])
|
|
20278
|
+
return { messageId: id, suffix: "" };
|
|
20279
|
+
return { messageId: id.slice(0, -match[1].length), suffix: match[1] };
|
|
20280
|
+
}
|
|
20281
|
+
function forkCloneFilter(idMap, copiedToolCallIds) {
|
|
20282
|
+
const mapMessageScoped = (id) => {
|
|
20283
|
+
const direct = idMap.parentToFork.get(id);
|
|
20284
|
+
if (direct)
|
|
20285
|
+
return direct;
|
|
20286
|
+
const { messageId, suffix } = splitMessageScopedId(id);
|
|
20287
|
+
if (!suffix)
|
|
20288
|
+
return;
|
|
20289
|
+
const mapped = idMap.parentToFork.get(messageId);
|
|
20290
|
+
return mapped ? `${mapped}${suffix}` : undefined;
|
|
20291
|
+
};
|
|
20292
|
+
return {
|
|
20293
|
+
resolveBoundaryOrdinal: (messageId) => {
|
|
20294
|
+
const forkId = idMap.parentToFork.get(messageId);
|
|
20295
|
+
return forkId ? idMap.forkOrdinals.get(forkId) : undefined;
|
|
20296
|
+
},
|
|
20297
|
+
includeMessageId: (messageId) => mapMessageScoped(messageId) !== undefined || copiedToolCallIds.has(messageId),
|
|
20298
|
+
mapMessageId: (messageId) => mapMessageScoped(messageId) ?? messageId,
|
|
20299
|
+
includeTag: (tag) => {
|
|
20300
|
+
if (tag.type === "tool") {
|
|
20301
|
+
return tag.toolOwnerMessageId !== null && idMap.parentToFork.has(tag.toolOwnerMessageId);
|
|
19869
20302
|
}
|
|
19870
|
-
|
|
19871
|
-
|
|
19872
|
-
|
|
19873
|
-
|
|
19874
|
-
|
|
19875
|
-
|
|
19876
|
-
|
|
20303
|
+
return mapMessageScoped(tag.messageId) !== undefined;
|
|
20304
|
+
},
|
|
20305
|
+
mapOrdinal: (sourceOrdinal) => {
|
|
20306
|
+
const parentId = idMap.parentOrdinals.get(sourceOrdinal);
|
|
20307
|
+
const forkId = parentId ? idMap.parentToFork.get(parentId) : undefined;
|
|
20308
|
+
return forkId ? idMap.forkOrdinals.get(forkId) : undefined;
|
|
20309
|
+
},
|
|
20310
|
+
copySessionNotesAndFacts: true,
|
|
20311
|
+
selectPendingPiMarker: () => null
|
|
20312
|
+
};
|
|
19877
20313
|
}
|
|
19878
|
-
function
|
|
19879
|
-
const
|
|
19880
|
-
|
|
19881
|
-
if (raw === prefix)
|
|
19882
|
-
return "";
|
|
19883
|
-
if (raw.startsWith(`${prefix} `))
|
|
19884
|
-
return raw.slice(prefix.length).trim();
|
|
19885
|
-
return raw;
|
|
20314
|
+
function countSessionRows(db, table, sessionId) {
|
|
20315
|
+
const row = db.prepare(`SELECT COUNT(*) AS count FROM ${table} WHERE session_id = ?`).get(sessionId);
|
|
20316
|
+
return typeof row?.count === "number" ? row.count : 0;
|
|
19886
20317
|
}
|
|
19887
|
-
function
|
|
19888
|
-
|
|
20318
|
+
function sessionHasMagicContextState(db, sessionId) {
|
|
20319
|
+
return countSessionRows(db, "compartments", sessionId) > 0 || countSessionRows(db, "tags", sessionId) > 0;
|
|
19889
20320
|
}
|
|
19890
|
-
function
|
|
19891
|
-
|
|
20321
|
+
function seedV2ForkFromParent(args) {
|
|
20322
|
+
const { db, store, sessionId } = args;
|
|
20323
|
+
if (sessionHasMagicContextState(db, sessionId))
|
|
20324
|
+
return { kind: "has-state" };
|
|
20325
|
+
const origin = store.forkOrigin(sessionId);
|
|
20326
|
+
if (!origin)
|
|
20327
|
+
return { kind: "not-a-fork" };
|
|
20328
|
+
const parentSessionID = origin.parentSessionID;
|
|
20329
|
+
if (parentSessionID === sessionId)
|
|
20330
|
+
return { kind: "not-a-fork" };
|
|
20331
|
+
if (!sessionHasMagicContextState(db, parentSessionID))
|
|
20332
|
+
return { kind: "parent-missing", parentSessionID, reason: "no Magic Context state" };
|
|
20333
|
+
if (!store.sessionExists(parentSessionID))
|
|
20334
|
+
return { kind: "parent-missing", parentSessionID, reason: "no host session row" };
|
|
20335
|
+
const throughSeq = forkBoundarySeq(origin, (session, id) => store.sequenceForId(session, id));
|
|
20336
|
+
if (throughSeq === undefined)
|
|
20337
|
+
return { kind: "parent-missing", parentSessionID, reason: "boundary row not in the store" };
|
|
20338
|
+
const idMap = buildForkIdMap(store.rowStampsThrough(parentSessionID, throughSeq), store.rowStampsThrough(sessionId, throughSeq), throughSeq);
|
|
20339
|
+
if (idMap.parentToFork.size === 0)
|
|
20340
|
+
return { kind: "parent-missing", parentSessionID, reason: "no copied rows pair up" };
|
|
20341
|
+
const toolTags = db.prepare("SELECT message_id, tool_owner_message_id FROM tags WHERE session_id = ? AND type = 'tool'").all(parentSessionID);
|
|
20342
|
+
const copiedToolCallIds = new Set(toolTags.filter((row) => row.tool_owner_message_id !== null && idMap.parentToFork.has(row.tool_owner_message_id)).map((row) => row.message_id));
|
|
20343
|
+
const result = copySessionStateForClone(db, parentSessionID, sessionId, forkCloneFilter(idMap, copiedToolCallIds));
|
|
20344
|
+
if (result.kind === "destination-not-empty")
|
|
20345
|
+
return { kind: "destination-not-empty", parentSessionID };
|
|
20346
|
+
return { kind: "seeded", parentSessionID, pairedRows: idMap.parentToFork.size, result };
|
|
19892
20347
|
}
|
|
19893
|
-
|
|
19894
|
-
|
|
19895
|
-
|
|
19896
|
-
|
|
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 : "");
|
|
20348
|
+
|
|
20349
|
+
// src/v2/hidden-child-record.ts
|
|
20350
|
+
function keptUnderRetention(keepSubagents, child) {
|
|
20351
|
+
return keepSubagents && (child.ever_settled === true || child.role === "historian");
|
|
19904
20352
|
}
|
|
19905
|
-
|
|
19906
|
-
|
|
19907
|
-
|
|
19908
|
-
|
|
19909
|
-
|
|
19910
|
-
|
|
19911
|
-
|
|
19912
|
-
|
|
19913
|
-
|
|
19914
|
-
|
|
19915
|
-
|
|
19916
|
-
|
|
19917
|
-
|
|
19918
|
-
|
|
19919
|
-
|
|
19920
|
-
|
|
19921
|
-
|
|
19922
|
-
|
|
19923
|
-
|
|
19924
|
-
|
|
19925
|
-
|
|
19926
|
-
|
|
19927
|
-
|
|
19928
|
-
|
|
19929
|
-
throw new Error("Magic Context could not start the history rebuild.");
|
|
19930
|
-
}
|
|
19931
|
-
}
|
|
19932
|
-
},
|
|
19933
|
-
{
|
|
19934
|
-
name: "mmc-flush",
|
|
19935
|
-
execute: async (input) => {
|
|
19936
|
-
const reply = await rpc.dispatch("flush", { sessionId: input.sessionID });
|
|
19937
|
-
reportRpcReply(input.sessionID, "Flush", reply, "Flush started");
|
|
19938
|
-
}
|
|
19939
|
-
},
|
|
19940
|
-
{
|
|
19941
|
-
name: "mmc-wrapup",
|
|
19942
|
-
execute: async (input) => {
|
|
19943
|
-
const argument = commandArgument(input, "mmc-wrapup");
|
|
19944
|
-
if (argument !== "" && !/^\d+$/.test(argument)) {
|
|
19945
|
-
const usage = "Usage: /mmc-wrapup [messages_to_keep] where messages_to_keep is a positive integer";
|
|
19946
|
-
reportUsage(input.sessionID, usage);
|
|
19947
|
-
throw new Error(usage);
|
|
19948
|
-
}
|
|
19949
|
-
const messagesToKeep = argument === "" ? 20 : Number.parseInt(argument, 10);
|
|
19950
|
-
if (messagesToKeep <= 0) {
|
|
19951
|
-
const usage = "messages_to_keep must be a positive integer";
|
|
19952
|
-
reportUsage(input.sessionID, usage);
|
|
19953
|
-
throw new Error(usage);
|
|
19954
|
-
}
|
|
19955
|
-
const reply = await rpc.dispatch("wrapup", {
|
|
19956
|
-
sessionId: input.sessionID,
|
|
19957
|
-
messagesToKeep
|
|
19958
|
-
});
|
|
19959
|
-
reportRpcReply(input.sessionID, "Wrapup", reply, "Wrapup started; the summary appears when it finishes");
|
|
19960
|
-
}
|
|
20353
|
+
var HIDDEN_CHILD_ROLE_TITLES = {
|
|
20354
|
+
"maintainer-a": "Magic Context maintainer A",
|
|
20355
|
+
"maintainer-b": "Magic Context maintainer B",
|
|
20356
|
+
historian: "Magic Context historian"
|
|
20357
|
+
};
|
|
20358
|
+
function roleTitle(role) {
|
|
20359
|
+
return HIDDEN_CHILD_ROLE_TITLES[role];
|
|
20360
|
+
}
|
|
20361
|
+
function roleAgent(role) {
|
|
20362
|
+
if (role === "maintainer-a")
|
|
20363
|
+
return MEMORY_MAINTAINER_A_AGENT;
|
|
20364
|
+
if (role === "maintainer-b")
|
|
20365
|
+
return MEMORY_MAINTAINER_B_AGENT;
|
|
20366
|
+
return HIDDEN_HISTORIAN_AGENT;
|
|
20367
|
+
}
|
|
20368
|
+
function childCreateInput(identity, role, model) {
|
|
20369
|
+
const agent = roleAgent(role);
|
|
20370
|
+
return {
|
|
20371
|
+
title: roleTitle(role),
|
|
20372
|
+
agent,
|
|
20373
|
+
model: {
|
|
20374
|
+
providerID: model.providerID,
|
|
20375
|
+
id: model.modelID,
|
|
20376
|
+
...model.variant ? { variant: model.variant } : {}
|
|
19961
20377
|
},
|
|
19962
|
-
{
|
|
19963
|
-
|
|
19964
|
-
|
|
19965
|
-
|
|
19966
|
-
const subcommand = argument === "" ? "status" : argument.trim().toLowerCase();
|
|
19967
|
-
if (subcommand !== "run" && subcommand !== "status" && subcommand !== "resume") {
|
|
19968
|
-
const usage = "Usage: /mmc-memory-maintain [run|status|resume] — status is the default";
|
|
19969
|
-
reportUsage(input.sessionID, usage);
|
|
19970
|
-
throw new Error(usage);
|
|
19971
|
-
}
|
|
19972
|
-
const reply = await rpc.dispatch("maintenance", {
|
|
19973
|
-
sessionId: input.sessionID,
|
|
19974
|
-
subcommand
|
|
19975
|
-
});
|
|
19976
|
-
reportRpcReply(input.sessionID, "Memory maintenance", reply, "Maintenance run started; see /mmc-memory-maintain status for the outcome");
|
|
19977
|
-
}
|
|
19978
|
-
}
|
|
19979
|
-
];
|
|
20378
|
+
location: { directory: identity.directory },
|
|
20379
|
+
metadata: { magic_context: "hidden-run", role },
|
|
20380
|
+
permissions: hiddenChildPermissions(agent)
|
|
20381
|
+
};
|
|
19980
20382
|
}
|
|
19981
|
-
|
|
19982
|
-
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
|
|
19986
|
-
|
|
19987
|
-
|
|
19988
|
-
|
|
19989
|
-
|
|
19990
|
-
|
|
19991
|
-
}
|
|
19992
|
-
add(sessionID) {
|
|
19993
|
-
this.#ids.delete(sessionID);
|
|
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();
|
|
20383
|
+
function assistantOutcome(row) {
|
|
20384
|
+
const outcome = row?.data.outcome;
|
|
20385
|
+
return outcome === "succeeded" || outcome === "failed" || outcome === "interrupted" ? outcome : undefined;
|
|
20386
|
+
}
|
|
20387
|
+
function withReader(openReader, read) {
|
|
20388
|
+
const reader = openReader();
|
|
20389
|
+
try {
|
|
20390
|
+
return read(reader);
|
|
20391
|
+
} finally {
|
|
20392
|
+
reader.close?.();
|
|
20007
20393
|
}
|
|
20008
|
-
|
|
20009
|
-
|
|
20394
|
+
}
|
|
20395
|
+
function errorText(value) {
|
|
20396
|
+
if (value instanceof Error)
|
|
20397
|
+
return value.message;
|
|
20398
|
+
if (typeof value === "string")
|
|
20399
|
+
return value;
|
|
20400
|
+
try {
|
|
20401
|
+
return JSON.stringify(value);
|
|
20402
|
+
} catch {
|
|
20403
|
+
return String(value);
|
|
20010
20404
|
}
|
|
20011
20405
|
}
|
|
20012
20406
|
|
|
20013
|
-
// src/v2/
|
|
20014
|
-
function
|
|
20015
|
-
const
|
|
20016
|
-
|
|
20017
|
-
|
|
20018
|
-
|
|
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);
|
|
20407
|
+
// src/v2/hidden-child-native.ts
|
|
20408
|
+
function nativeSessionRemove(session) {
|
|
20409
|
+
const remove = session.remove;
|
|
20410
|
+
if (typeof remove !== "function")
|
|
20411
|
+
return;
|
|
20412
|
+
return (input) => Promise.resolve(remove.call(session, { sessionID: input.sessionID }));
|
|
20064
20413
|
}
|
|
20065
|
-
function
|
|
20066
|
-
if (!
|
|
20414
|
+
function isSessionNotFound(error) {
|
|
20415
|
+
if (!error || typeof error !== "object")
|
|
20067
20416
|
return false;
|
|
20068
|
-
const
|
|
20069
|
-
|
|
20070
|
-
}
|
|
20071
|
-
function containsHostInstance(value) {
|
|
20072
|
-
if (isHostInstance(value))
|
|
20417
|
+
const fields = error;
|
|
20418
|
+
if (fields.status === 404)
|
|
20073
20419
|
return true;
|
|
20074
|
-
|
|
20075
|
-
|
|
20076
|
-
if (value && typeof value === "object")
|
|
20077
|
-
return Object.values(value).some(containsHostInstance);
|
|
20078
|
-
return false;
|
|
20079
|
-
}
|
|
20080
|
-
function clonePreservingInstances(value) {
|
|
20081
|
-
if (isHostInstance(value))
|
|
20082
|
-
return value;
|
|
20083
|
-
if (Array.isArray(value))
|
|
20084
|
-
return value.map(clonePreservingInstances);
|
|
20085
|
-
if (value && typeof value === "object") {
|
|
20086
|
-
const copy = {};
|
|
20087
|
-
for (const [key, entry] of Object.entries(value))
|
|
20088
|
-
copy[key] = clonePreservingInstances(entry);
|
|
20089
|
-
return copy;
|
|
20090
|
-
}
|
|
20091
|
-
return value;
|
|
20420
|
+
const label = [fields.name, fields._tag, fields.message].filter((value) => typeof value === "string").join(" ");
|
|
20421
|
+
return /not\s*found/i.test(label);
|
|
20092
20422
|
}
|
|
20093
|
-
|
|
20094
|
-
|
|
20095
|
-
|
|
20096
|
-
|
|
20097
|
-
|
|
20098
|
-
|
|
20423
|
+
var parentDroppedNoted = false;
|
|
20424
|
+
function createNativeHiddenChildren(host, removeSession, options) {
|
|
20425
|
+
const removing = new Map;
|
|
20426
|
+
const remove = (child) => {
|
|
20427
|
+
const inFlight = removing.get(child.id);
|
|
20428
|
+
if (inFlight)
|
|
20429
|
+
return inFlight;
|
|
20430
|
+
const done = (async () => {
|
|
20431
|
+
try {
|
|
20432
|
+
let timer;
|
|
20433
|
+
try {
|
|
20434
|
+
await Promise.race([
|
|
20435
|
+
removeSession({ sessionID: child.id }),
|
|
20436
|
+
new Promise((_, reject) => {
|
|
20437
|
+
timer = setTimeout(() => reject(new Error("session.remove timed out")), options.removalTimeoutMs ?? 5000);
|
|
20438
|
+
})
|
|
20439
|
+
]);
|
|
20440
|
+
} finally {
|
|
20441
|
+
if (timer)
|
|
20442
|
+
clearTimeout(timer);
|
|
20443
|
+
}
|
|
20444
|
+
} catch (error) {
|
|
20445
|
+
if (isSessionNotFound(error))
|
|
20446
|
+
return;
|
|
20447
|
+
options.log(`[magic-context] hidden child ${child.id} could not be removed; it goes when its parent session is deleted: ${errorText(error)}`);
|
|
20448
|
+
}
|
|
20449
|
+
})().finally(() => {
|
|
20450
|
+
removing.delete(child.id);
|
|
20451
|
+
});
|
|
20452
|
+
removing.set(child.id, done);
|
|
20453
|
+
return done;
|
|
20454
|
+
};
|
|
20455
|
+
const confirmPlacement = async (sessionID, parentID) => {
|
|
20456
|
+
let stored;
|
|
20457
|
+
try {
|
|
20458
|
+
stored = await host.get({ sessionID });
|
|
20459
|
+
} catch (error) {
|
|
20460
|
+
options.log(`[magic-context] could not read back hidden child ${sessionID} to confirm its parent: ${errorText(error)}`);
|
|
20461
|
+
return;
|
|
20099
20462
|
}
|
|
20100
|
-
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
return Object.fromEntries(Object.entries(entry).map(([key, nested]) => [key, plain(nested)]));
|
|
20463
|
+
const directory = stored.location?.directory;
|
|
20464
|
+
if (options.directory !== undefined && directory !== undefined && directory !== options.directory) {
|
|
20465
|
+
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", `hidden child ${sessionID} is bound to ${directory}, not to this instance's ${options.directory}`, true);
|
|
20104
20466
|
}
|
|
20105
|
-
|
|
20467
|
+
if (stored.parentID === parentID || parentDroppedNoted)
|
|
20468
|
+
return;
|
|
20469
|
+
parentDroppedNoted = true;
|
|
20470
|
+
options.log(`[magic-context] this OpenCode 2 host does not keep the parent of hidden-run sessions (asked for ${parentID}, read back ${stored.parentID ?? "none"}); they are created as separate sessions and still removed when each run ends`);
|
|
20471
|
+
};
|
|
20472
|
+
const create = async (identity, role, model) => {
|
|
20473
|
+
const parentID = identity.parentSessionId;
|
|
20474
|
+
const input = childCreateInput(identity, role, model);
|
|
20475
|
+
const { location, ...parented } = input;
|
|
20476
|
+
const created = await host.create(parentID ? { ...parented, parentID } : { ...parented, location });
|
|
20477
|
+
if (!created.id)
|
|
20478
|
+
throw new Error("OpenCode 2 did not return a child session id");
|
|
20479
|
+
options.hook.registerChild(created.id, input.agent);
|
|
20480
|
+
const child = {
|
|
20481
|
+
id: created.id,
|
|
20482
|
+
role,
|
|
20483
|
+
generation: options.generation,
|
|
20484
|
+
title: roleTitle(role),
|
|
20485
|
+
model,
|
|
20486
|
+
created_at: Date.now(),
|
|
20487
|
+
directory: identity.directory
|
|
20488
|
+
};
|
|
20489
|
+
if (parentID) {
|
|
20490
|
+
try {
|
|
20491
|
+
await confirmPlacement(created.id, parentID);
|
|
20492
|
+
} catch (error) {
|
|
20493
|
+
await remove(child);
|
|
20494
|
+
throw error;
|
|
20495
|
+
}
|
|
20496
|
+
}
|
|
20497
|
+
return child;
|
|
20498
|
+
};
|
|
20499
|
+
const kept = (child) => keptUnderRetention(options.keepSubagents, child);
|
|
20500
|
+
return {
|
|
20501
|
+
open: create,
|
|
20502
|
+
create,
|
|
20503
|
+
retire(child) {
|
|
20504
|
+
if (!kept(child))
|
|
20505
|
+
remove(child);
|
|
20506
|
+
},
|
|
20507
|
+
async finish(child, retired) {
|
|
20508
|
+
if (retired) {
|
|
20509
|
+
await removing.get(child.id);
|
|
20510
|
+
return;
|
|
20511
|
+
}
|
|
20512
|
+
if (!kept(child))
|
|
20513
|
+
await remove(child);
|
|
20514
|
+
},
|
|
20515
|
+
updateModel: (child, model) => ({ ...child, model }),
|
|
20516
|
+
markEverSettled: (child) => ({ ...child, ever_settled: true })
|
|
20106
20517
|
};
|
|
20107
|
-
return JSON.stringify(plain(value));
|
|
20108
20518
|
}
|
|
20109
|
-
|
|
20110
|
-
|
|
20111
|
-
|
|
20519
|
+
|
|
20520
|
+
// src/v2/hidden-child-cleanup.ts
|
|
20521
|
+
var PREFIX = "opencode2_hidden_children:";
|
|
20522
|
+
var COMPLETE = "opencode2_hidden_children_cleanup_complete";
|
|
20523
|
+
async function cleanupLegacyHiddenChildren(db, remove, note, options = {}) {
|
|
20524
|
+
if (db.prepare("SELECT 1 FROM schema_migrations_meta WHERE key = ?").get(COMPLETE))
|
|
20112
20525
|
return;
|
|
20113
|
-
|
|
20114
|
-
|
|
20115
|
-
|
|
20116
|
-
|
|
20117
|
-
|
|
20118
|
-
|
|
20119
|
-
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
}));
|
|
20126
|
-
}
|
|
20127
|
-
function rebuildFileContent(value, output) {
|
|
20128
|
-
if (isDroppedToolOutput(output))
|
|
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);
|
|
20526
|
+
const rows = db.prepare("SELECT key, value FROM schema_migrations_meta WHERE key GLOB ? ORDER BY key LIMIT 25").all(`${PREFIX}*`);
|
|
20527
|
+
let remaining = options.limit ?? 25;
|
|
20528
|
+
const now = options.now ?? (() => performance.now());
|
|
20529
|
+
const deadline = now() + (options.budgetMs ?? 2000);
|
|
20530
|
+
for (const row of rows) {
|
|
20531
|
+
let record;
|
|
20532
|
+
try {
|
|
20533
|
+
record = JSON.parse(row.value);
|
|
20534
|
+
if (!record || typeof record !== "object" || record.active !== undefined && (!record.active || typeof record.active !== "object" || Array.isArray(record.active)) || record.retired_children !== undefined && !Array.isArray(record.retired_children))
|
|
20535
|
+
throw new Error("invalid record");
|
|
20536
|
+
} catch {
|
|
20537
|
+
note(`[magic-context] legacy hidden-child cleanup cannot read ${row.key}`);
|
|
20135
20538
|
continue;
|
|
20136
20539
|
}
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
|
|
20141
|
-
|
|
20142
|
-
|
|
20143
|
-
|
|
20144
|
-
|
|
20145
|
-
}
|
|
20146
|
-
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
|
|
20155
|
-
|
|
20156
|
-
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20161
|
-
|
|
20162
|
-
|
|
20163
|
-
|
|
20540
|
+
const children = [
|
|
20541
|
+
...Object.values(record.active ?? {}),
|
|
20542
|
+
...record.retired_children ?? []
|
|
20543
|
+
];
|
|
20544
|
+
for (const child of children) {
|
|
20545
|
+
if (remaining-- <= 0 || now() >= deadline)
|
|
20546
|
+
return;
|
|
20547
|
+
if (typeof child?.id !== "string") {
|
|
20548
|
+
note(`[magic-context] legacy hidden-child cleanup has an invalid child in ${row.key}`);
|
|
20549
|
+
continue;
|
|
20550
|
+
}
|
|
20551
|
+
let timer;
|
|
20552
|
+
try {
|
|
20553
|
+
try {
|
|
20554
|
+
await Promise.race([
|
|
20555
|
+
remove({ sessionID: child.id }),
|
|
20556
|
+
new Promise((_, reject) => {
|
|
20557
|
+
timer = setTimeout(() => reject(new Error("session.remove timed out")), Math.min(options.timeoutMs ?? 1000, Math.max(1, deadline - now())));
|
|
20558
|
+
})
|
|
20559
|
+
]);
|
|
20560
|
+
} catch (error) {
|
|
20561
|
+
if (!isSessionNotFound(error))
|
|
20562
|
+
throw error;
|
|
20563
|
+
}
|
|
20564
|
+
record.active = Object.fromEntries(Object.entries(record.active ?? {}).filter(([, entry]) => entry.id !== child.id));
|
|
20565
|
+
record.retired_children = (record.retired_children ?? []).filter((entry) => entry.id !== child.id);
|
|
20566
|
+
db.prepare("UPDATE schema_migrations_meta SET value = ? WHERE key = ?").run(JSON.stringify(record), row.key);
|
|
20567
|
+
} catch (error) {
|
|
20568
|
+
note(`[magic-context] legacy hidden child ${child.id} cleanup deferred: ${String(error)}`);
|
|
20569
|
+
} finally {
|
|
20570
|
+
if (timer)
|
|
20571
|
+
clearTimeout(timer);
|
|
20164
20572
|
}
|
|
20165
20573
|
}
|
|
20574
|
+
if (Object.keys(record.active ?? {}).length === 0 && (record.retired_children ?? []).length === 0)
|
|
20575
|
+
db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(row.key);
|
|
20166
20576
|
}
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20172
|
-
|
|
20173
|
-
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
|
|
20187
|
-
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
|
|
20191
|
-
|
|
20192
|
-
|
|
20193
|
-
|
|
20194
|
-
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
|
|
20201
|
-
|
|
20577
|
+
if (!db.prepare("SELECT 1 FROM schema_migrations_meta WHERE key GLOB ? LIMIT 1").get(`${PREFIX}*`))
|
|
20578
|
+
db.prepare("INSERT OR IGNORE INTO schema_migrations_meta (key, value) VALUES (?, 'true')").run(COMPLETE);
|
|
20579
|
+
}
|
|
20580
|
+
|
|
20581
|
+
// src/v2/hidden-completion.ts
|
|
20582
|
+
var POLL_INTERVAL_MS = 200;
|
|
20583
|
+
function modelKey(model) {
|
|
20584
|
+
return `${model.providerID}/${model.modelID}`;
|
|
20585
|
+
}
|
|
20586
|
+
function sameModel(left, right) {
|
|
20587
|
+
return modelKey(left) === modelKey(right) && left.variant === right.variant;
|
|
20588
|
+
}
|
|
20589
|
+
function configuredHead(identity) {
|
|
20590
|
+
const candidates = [identity.model, ...identity.configuredModels ?? []];
|
|
20591
|
+
for (const candidate of candidates) {
|
|
20592
|
+
const entry = toModelEntry(candidate);
|
|
20593
|
+
const parsed = entry ? parseProviderModel(entry.model) : null;
|
|
20594
|
+
if (parsed)
|
|
20595
|
+
return { ...parsed, ...entry?.qualifier ? { variant: entry.qualifier } : {} };
|
|
20596
|
+
}
|
|
20597
|
+
return;
|
|
20598
|
+
}
|
|
20599
|
+
var HIDDEN_MAINTAINER_ROLES = {
|
|
20600
|
+
"maintainer-a": "magic-context-maintainer-a",
|
|
20601
|
+
"maintainer-b": "magic-context-maintainer-b"
|
|
20602
|
+
};
|
|
20603
|
+
function roleFor(identity) {
|
|
20604
|
+
for (const [role, agent] of Object.entries(HIDDEN_MAINTAINER_ROLES)) {
|
|
20605
|
+
if (identity.agent === agent)
|
|
20606
|
+
return role;
|
|
20607
|
+
}
|
|
20608
|
+
return "historian";
|
|
20609
|
+
}
|
|
20610
|
+
function promptText(request) {
|
|
20611
|
+
const parts = request.body.parts;
|
|
20612
|
+
return Array.isArray(parts) ? parts.flatMap((part) => part && typeof part === "object" && typeof part.text === "string" ? [part.text] : []).join(`
|
|
20613
|
+
`) : "";
|
|
20614
|
+
}
|
|
20615
|
+
function meter(system, prompt, text) {
|
|
20616
|
+
return {
|
|
20617
|
+
input: estimateTokens(system) + estimateTokens(prompt),
|
|
20618
|
+
output: estimateTokens(text),
|
|
20619
|
+
cacheRead: 0,
|
|
20620
|
+
cacheWrite: 0
|
|
20202
20621
|
};
|
|
20203
|
-
|
|
20204
|
-
|
|
20205
|
-
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20622
|
+
}
|
|
20623
|
+
function assistantReasoning(row) {
|
|
20624
|
+
const reasoning = (row.data.content ?? []).flatMap((part) => part.type === "reasoning" && typeof part.text === "string" ? [part.text] : []).join(`
|
|
20625
|
+
`);
|
|
20626
|
+
return reasoning.length > 0 ? reasoning : null;
|
|
20627
|
+
}
|
|
20628
|
+
function assistantText(row) {
|
|
20629
|
+
const text = (row.data.content ?? []).flatMap((part) => part.type === "text" && typeof part.text === "string" ? [part.text] : []).join("");
|
|
20630
|
+
return text.length > 0 ? text : null;
|
|
20631
|
+
}
|
|
20632
|
+
|
|
20633
|
+
class HiddenProviderError extends Error {
|
|
20634
|
+
settled;
|
|
20635
|
+
constructor(detail, options = {}) {
|
|
20636
|
+
super(`Hidden completion provider error: ${detail}`);
|
|
20637
|
+
this.name = "HiddenProviderError";
|
|
20638
|
+
this.settled = options.settled ?? true;
|
|
20639
|
+
}
|
|
20640
|
+
}
|
|
20641
|
+
function requestModel(request, current) {
|
|
20642
|
+
const requested = request.body.model;
|
|
20643
|
+
if (requested && typeof requested.providerID === "string" && typeof requested.modelID === "string") {
|
|
20644
|
+
return {
|
|
20645
|
+
providerID: requested.providerID,
|
|
20646
|
+
modelID: requested.modelID,
|
|
20647
|
+
...typeof request.body.variant === "string" ? { variant: request.body.variant } : {}
|
|
20212
20648
|
};
|
|
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));
|
|
20223
|
-
}
|
|
20224
|
-
}
|
|
20225
20649
|
}
|
|
20226
|
-
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
|
|
20650
|
+
return current;
|
|
20651
|
+
}
|
|
20652
|
+
async function sleepUntilPoll(signal, deadline) {
|
|
20653
|
+
if (signal?.aborted)
|
|
20654
|
+
throw new Error("Hidden completion prompt aborted");
|
|
20655
|
+
const delay = Math.min(POLL_INTERVAL_MS, Math.max(0, deadline - Date.now()));
|
|
20656
|
+
if (delay <= 0)
|
|
20657
|
+
return;
|
|
20658
|
+
await new Promise((resolve, reject) => {
|
|
20659
|
+
const timer = setTimeout(resolve, delay);
|
|
20660
|
+
const abort = () => {
|
|
20661
|
+
clearTimeout(timer);
|
|
20662
|
+
reject(new Error("Hidden completion prompt aborted"));
|
|
20663
|
+
};
|
|
20664
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
20665
|
+
if (signal?.aborted)
|
|
20666
|
+
abort();
|
|
20667
|
+
else
|
|
20668
|
+
setTimeout(() => {
|
|
20669
|
+
signal?.removeEventListener("abort", abort);
|
|
20670
|
+
}, delay);
|
|
20671
|
+
});
|
|
20672
|
+
}
|
|
20673
|
+
function isProviderFailure(error) {
|
|
20674
|
+
if (!error || typeof error !== "object")
|
|
20675
|
+
return false;
|
|
20676
|
+
const type = error.type;
|
|
20677
|
+
return typeof type === "string" && (type.startsWith("provider.") || type.toLowerCase().includes("provider"));
|
|
20678
|
+
}
|
|
20679
|
+
async function awaitAssistantRow(openReader, readSessionError, localFailure, childID, afterSeq, deadline, signal) {
|
|
20680
|
+
for (;; ) {
|
|
20681
|
+
const { assistant, idle } = withReader(openReader, (reader) => ({
|
|
20682
|
+
assistant: reader.latestAssistant(childID),
|
|
20683
|
+
idle: reader.latestIdle(childID)
|
|
20684
|
+
}));
|
|
20685
|
+
const newAssistant = assistant && assistant.seq > afterSeq ? assistant : undefined;
|
|
20686
|
+
const newIdle = idle && idle.seq > afterSeq ? idle : undefined;
|
|
20687
|
+
const refused = localFailure();
|
|
20688
|
+
if (refused)
|
|
20689
|
+
throw refused;
|
|
20690
|
+
if (newIdle && (!newAssistant || newIdle.seq > newAssistant.seq)) {
|
|
20691
|
+
const outcome = newIdle.data.outcome;
|
|
20692
|
+
if (outcome === "failed" || outcome === "interrupted") {
|
|
20693
|
+
const sessionError = await readSessionError();
|
|
20694
|
+
const details = [
|
|
20695
|
+
`outcome=${outcome}`,
|
|
20696
|
+
`terminal_row=${errorText(newIdle)}`,
|
|
20697
|
+
`session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
|
|
20698
|
+
];
|
|
20699
|
+
throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
|
|
20700
|
+
}
|
|
20701
|
+
if (outcome === "succeeded" && newAssistant)
|
|
20702
|
+
return newAssistant;
|
|
20236
20703
|
}
|
|
20237
|
-
if (
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
|
|
20241
|
-
|
|
20242
|
-
|
|
20243
|
-
|
|
20704
|
+
if (newAssistant) {
|
|
20705
|
+
const outcome = assistantOutcome(newAssistant);
|
|
20706
|
+
if (outcome === "failed" || outcome === "interrupted") {
|
|
20707
|
+
const sessionError = await readSessionError();
|
|
20708
|
+
const details = [
|
|
20709
|
+
`outcome=${outcome}`,
|
|
20710
|
+
`terminal_row=${errorText(newAssistant)}`,
|
|
20711
|
+
`session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
|
|
20712
|
+
];
|
|
20713
|
+
throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
|
|
20714
|
+
}
|
|
20715
|
+
if (newAssistant.data.error !== undefined) {
|
|
20716
|
+
throw new HiddenProviderError(errorText(newAssistant.data.error), {
|
|
20717
|
+
settled: typeof newAssistant.data.finish === "string"
|
|
20718
|
+
});
|
|
20719
|
+
}
|
|
20720
|
+
if (typeof newAssistant.data.finish === "string" || outcome === "succeeded") {
|
|
20721
|
+
return newAssistant;
|
|
20722
|
+
}
|
|
20244
20723
|
}
|
|
20245
|
-
if (
|
|
20246
|
-
|
|
20247
|
-
originalsByID.set(message.id, message);
|
|
20724
|
+
if (Date.now() >= deadline) {
|
|
20725
|
+
throw new Error("Hidden completion timed out waiting for a persisted assistant row");
|
|
20248
20726
|
}
|
|
20249
|
-
|
|
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
|
|
20258
|
-
}
|
|
20259
|
-
},
|
|
20260
|
-
parts
|
|
20261
|
-
};
|
|
20262
|
-
originals.set(mapped, message);
|
|
20263
|
-
if (typeof message.id !== "string")
|
|
20264
|
-
bridgesByCarrier.set(mapped, byCallID);
|
|
20265
|
-
messages.push(mapped);
|
|
20727
|
+
await sleepUntilPoll(signal, deadline);
|
|
20266
20728
|
}
|
|
20729
|
+
}
|
|
20730
|
+
var V2_HIDDEN_EXECUTOR_CAPABILITIES = {
|
|
20731
|
+
tools: true,
|
|
20732
|
+
harness: "opencode2"
|
|
20733
|
+
};
|
|
20734
|
+
function createLateHiddenExecutor(current) {
|
|
20735
|
+
const wired = () => {
|
|
20736
|
+
const executor = current();
|
|
20737
|
+
if (executor)
|
|
20738
|
+
return executor;
|
|
20739
|
+
throw new Error("Magic Context hidden work is unavailable until the context database opens.");
|
|
20740
|
+
};
|
|
20267
20741
|
return {
|
|
20268
|
-
|
|
20269
|
-
|
|
20270
|
-
|
|
20271
|
-
|
|
20272
|
-
|
|
20273
|
-
|
|
20274
|
-
|
|
20275
|
-
|
|
20276
|
-
|
|
20277
|
-
|
|
20278
|
-
|
|
20279
|
-
|
|
20280
|
-
|
|
20281
|
-
|
|
20282
|
-
|
|
20283
|
-
|
|
20284
|
-
|
|
20285
|
-
|
|
20286
|
-
|
|
20287
|
-
|
|
20288
|
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
|
|
20292
|
-
|
|
20293
|
-
|
|
20294
|
-
|
|
20295
|
-
|
|
20296
|
-
|
|
20297
|
-
|
|
20298
|
-
|
|
20299
|
-
|
|
20300
|
-
|
|
20301
|
-
|
|
20302
|
-
|
|
20303
|
-
|
|
20304
|
-
|
|
20305
|
-
|
|
20306
|
-
|
|
20307
|
-
|
|
20308
|
-
|
|
20309
|
-
|
|
20310
|
-
|
|
20311
|
-
|
|
20312
|
-
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20319
|
-
|
|
20320
|
-
|
|
20321
|
-
|
|
20322
|
-
|
|
20323
|
-
|
|
20324
|
-
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
|
|
20337
|
-
|
|
20338
|
-
|
|
20339
|
-
|
|
20340
|
-
|
|
20341
|
-
|
|
20342
|
-
|
|
20343
|
-
|
|
20344
|
-
|
|
20345
|
-
|
|
20346
|
-
|
|
20347
|
-
|
|
20348
|
-
|
|
20349
|
-
|
|
20350
|
-
|
|
20351
|
-
|
|
20352
|
-
|
|
20353
|
-
|
|
20354
|
-
|
|
20355
|
-
|
|
20742
|
+
get capabilities() {
|
|
20743
|
+
return current()?.capabilities ?? V2_HIDDEN_EXECUTOR_CAPABILITIES;
|
|
20744
|
+
},
|
|
20745
|
+
open: (run) => wired().open(run),
|
|
20746
|
+
attempt: (handle, request) => wired().attempt(handle, request),
|
|
20747
|
+
collect: (handle, limit) => wired().collect(handle, limit),
|
|
20748
|
+
close: (handle, settlement) => wired().close(handle, settlement)
|
|
20749
|
+
};
|
|
20750
|
+
}
|
|
20751
|
+
async function createV2HiddenCompletionExecutor(host, options) {
|
|
20752
|
+
const runs = new WeakMap;
|
|
20753
|
+
const generation = options.generation ?? "opencode2";
|
|
20754
|
+
const roleTails = new Map;
|
|
20755
|
+
const note = options.log ?? log;
|
|
20756
|
+
const removeSession = host.removeSession;
|
|
20757
|
+
if (!removeSession)
|
|
20758
|
+
throw new Error("Magic Context requires OpenCode 2.0.22 session.remove");
|
|
20759
|
+
const lifecycle = createNativeHiddenChildren(host, (input) => removeSession.call(host, input), {
|
|
20760
|
+
hook: options.hook,
|
|
20761
|
+
generation,
|
|
20762
|
+
keepSubagents: options.keepSubagents === true,
|
|
20763
|
+
log: note,
|
|
20764
|
+
removalTimeoutMs: options.removalTimeoutMs,
|
|
20765
|
+
directory: options.directory
|
|
20766
|
+
});
|
|
20767
|
+
const acquireRole = async (role) => {
|
|
20768
|
+
const previous = roleTails.get(role) ?? Promise.resolve();
|
|
20769
|
+
let release;
|
|
20770
|
+
const gate = new Promise((resolve) => {
|
|
20771
|
+
release = resolve;
|
|
20772
|
+
});
|
|
20773
|
+
const tail = previous.then(() => gate);
|
|
20774
|
+
roleTails.set(role, tail);
|
|
20775
|
+
await previous;
|
|
20776
|
+
return () => {
|
|
20777
|
+
release();
|
|
20778
|
+
if (roleTails.get(role) === tail)
|
|
20779
|
+
roleTails.delete(role);
|
|
20780
|
+
};
|
|
20781
|
+
};
|
|
20782
|
+
const warnedVariants = new Set;
|
|
20783
|
+
const validateVariant = async (model) => {
|
|
20784
|
+
if (!model.variant || !options.modelCatalog)
|
|
20785
|
+
return model;
|
|
20786
|
+
try {
|
|
20787
|
+
const listed = await options.modelCatalog();
|
|
20788
|
+
const rows = Array.isArray(listed) ? listed : listed && typeof listed === "object" && Array.isArray(listed.data) ? listed.data : [];
|
|
20789
|
+
const entry = rows.find((row) => row && typeof row === "object" && row.providerID === model.providerID && row.id === model.modelID);
|
|
20790
|
+
if (!entry)
|
|
20791
|
+
return model;
|
|
20792
|
+
if (entry.variants && typeof entry.variants === "object" && Object.hasOwn(entry.variants, model.variant))
|
|
20793
|
+
return model;
|
|
20794
|
+
const key = `${model.providerID}/${model.modelID}:${model.variant}`;
|
|
20795
|
+
if (!warnedVariants.has(key)) {
|
|
20796
|
+
warnedVariants.add(key);
|
|
20797
|
+
note(`[magic-context] ${recordHiddenVariantWarning(model.providerID, model.modelID, model.variant)}`);
|
|
20798
|
+
}
|
|
20799
|
+
return { providerID: model.providerID, modelID: model.modelID };
|
|
20800
|
+
} catch {
|
|
20801
|
+
return model;
|
|
20802
|
+
}
|
|
20803
|
+
};
|
|
20804
|
+
const resolveHead = async (identity) => {
|
|
20805
|
+
const configured = configuredHead(identity);
|
|
20806
|
+
if (configured)
|
|
20807
|
+
return validateVariant(configured);
|
|
20808
|
+
if (!identity.parentSessionId) {
|
|
20809
|
+
throw new HiddenCompletionRefusal("hidden_model_unsupported", "Hidden completion requires a configured model or an existing parent session model", true);
|
|
20810
|
+
}
|
|
20811
|
+
const parent = await host.get({ sessionID: identity.parentSessionId });
|
|
20812
|
+
if (!parent.model) {
|
|
20813
|
+
throw new HiddenCompletionRefusal("hidden_model_unsupported", "Hidden completion could not resolve the parent session model", true);
|
|
20814
|
+
}
|
|
20815
|
+
return {
|
|
20816
|
+
providerID: parent.model.providerID,
|
|
20817
|
+
modelID: parent.model.id,
|
|
20818
|
+
...parent.model.variant ? { variant: parent.model.variant } : {}
|
|
20819
|
+
};
|
|
20820
|
+
};
|
|
20821
|
+
const switchChildModel = async (run, requested) => {
|
|
20822
|
+
if (sameModel(run.child.model, requested))
|
|
20823
|
+
return;
|
|
20824
|
+
await host.switchModel({
|
|
20825
|
+
sessionID: run.child.id,
|
|
20826
|
+
model: {
|
|
20827
|
+
providerID: requested.providerID,
|
|
20828
|
+
id: requested.modelID,
|
|
20829
|
+
...requested.variant ? { variant: requested.variant } : {}
|
|
20830
|
+
}
|
|
20831
|
+
});
|
|
20832
|
+
run.child = lifecycle.updateModel(run.child, requested);
|
|
20833
|
+
};
|
|
20834
|
+
const retire = (run, reason) => {
|
|
20835
|
+
if (run.retired)
|
|
20836
|
+
return;
|
|
20837
|
+
lifecycle.retire(run.child, reason);
|
|
20838
|
+
run.retired = true;
|
|
20839
|
+
};
|
|
20840
|
+
const interruptAndRetire = async (run, reason) => {
|
|
20841
|
+
try {
|
|
20842
|
+
await host.interrupt({ sessionID: run.child.id });
|
|
20843
|
+
} finally {
|
|
20844
|
+
retire(run, reason);
|
|
20845
|
+
}
|
|
20846
|
+
};
|
|
20847
|
+
return {
|
|
20848
|
+
capabilities: V2_HIDDEN_EXECUTOR_CAPABILITIES,
|
|
20849
|
+
async open(identity) {
|
|
20850
|
+
const role = roleFor(identity);
|
|
20851
|
+
const releaseRole = await acquireRole(role);
|
|
20852
|
+
let openedChild;
|
|
20853
|
+
try {
|
|
20854
|
+
await options.ensureAgent?.();
|
|
20855
|
+
const head = await resolveHead(identity);
|
|
20856
|
+
const active = await lifecycle.open(identity, role, head);
|
|
20857
|
+
openedChild = active;
|
|
20858
|
+
const handle = { id: active.id, childSessionId: active.id };
|
|
20859
|
+
const run = {
|
|
20860
|
+
identity,
|
|
20861
|
+
role,
|
|
20862
|
+
child: active,
|
|
20863
|
+
releaseRole,
|
|
20864
|
+
failed: false,
|
|
20865
|
+
unsettledFailure: false,
|
|
20866
|
+
retired: false
|
|
20867
|
+
};
|
|
20868
|
+
runs.set(handle, run);
|
|
20869
|
+
await switchChildModel(run, head);
|
|
20870
|
+
return handle;
|
|
20871
|
+
} catch (error) {
|
|
20872
|
+
if (openedChild)
|
|
20873
|
+
lifecycle.retire(openedChild, "hidden-run-open-failed");
|
|
20874
|
+
releaseRole();
|
|
20875
|
+
throw error;
|
|
20876
|
+
}
|
|
20877
|
+
},
|
|
20878
|
+
async attempt(handle, request) {
|
|
20879
|
+
const run = runs.get(handle);
|
|
20880
|
+
if (!run)
|
|
20881
|
+
throw new Error("Unknown hidden completion run");
|
|
20882
|
+
if (request.signal?.aborted) {
|
|
20883
|
+
await interruptAndRetire(run, "aborted-before-prompt");
|
|
20884
|
+
throw new Error("Hidden completion prompt aborted");
|
|
20885
|
+
}
|
|
20886
|
+
const requested = await validateVariant(requestModel(request, run.child.model));
|
|
20887
|
+
if (run.retired) {
|
|
20888
|
+
run.child = await lifecycle.create(run.identity, run.role, requested);
|
|
20889
|
+
run.failed = false;
|
|
20890
|
+
run.unsettledFailure = false;
|
|
20891
|
+
run.retired = false;
|
|
20892
|
+
handle.id = run.child.id;
|
|
20893
|
+
handle.childSessionId = run.child.id;
|
|
20894
|
+
}
|
|
20895
|
+
await switchChildModel(run, requested);
|
|
20896
|
+
const baseline = withReader(options.openReader, (reader) => reader.latestSequence(run.child.id));
|
|
20897
|
+
const marker = `mc:hidden:${crypto.randomUUID()}:${crypto.randomUUID()}`;
|
|
20898
|
+
run.completion = undefined;
|
|
20899
|
+
const stepCap = options.resolveStepCap?.(run.identity);
|
|
20900
|
+
const attempt = {
|
|
20901
|
+
childSessionId: run.child.id,
|
|
20902
|
+
identity: run.identity,
|
|
20903
|
+
agent: run.identity.agent,
|
|
20904
|
+
request,
|
|
20905
|
+
shaped: false,
|
|
20906
|
+
...stepCap === undefined ? {} : { stepCap }
|
|
20907
|
+
};
|
|
20908
|
+
options.hook.registerAttempt(marker, attempt);
|
|
20909
|
+
const deadline = Date.now() + run.identity.timeoutMs;
|
|
20910
|
+
let abortReject;
|
|
20911
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
20912
|
+
abortReject = reject;
|
|
20913
|
+
});
|
|
20914
|
+
const onAbort = () => {
|
|
20915
|
+
interruptAndRetire(run, "prompt-aborted").finally(() => abortReject(new Error("Hidden completion prompt aborted")));
|
|
20916
|
+
};
|
|
20917
|
+
const deadlineTimer = setTimeout(() => {
|
|
20918
|
+
interruptAndRetire(run, "prompt-timeout").finally(() => abortReject(new Error("Hidden completion prompt timed out")));
|
|
20919
|
+
}, Math.max(0, deadline - Date.now()));
|
|
20920
|
+
request.signal?.addEventListener("abort", onAbort, { once: true });
|
|
20921
|
+
try {
|
|
20922
|
+
await Promise.race([
|
|
20923
|
+
host.prompt({ sessionID: run.child.id, text: marker }),
|
|
20924
|
+
aborted
|
|
20925
|
+
]);
|
|
20926
|
+
await Promise.race([host.wait({ sessionID: run.child.id }), aborted]);
|
|
20927
|
+
const row = await Promise.race([
|
|
20928
|
+
awaitAssistantRow(options.openReader, async () => {
|
|
20929
|
+
try {
|
|
20930
|
+
const eventError = await host.terminalError?.({
|
|
20931
|
+
sessionID: run.child.id
|
|
20356
20932
|
});
|
|
20933
|
+
if (eventError !== undefined)
|
|
20934
|
+
return eventError;
|
|
20935
|
+
return (await host.get({ sessionID: run.child.id })).error;
|
|
20936
|
+
} catch {
|
|
20937
|
+
return;
|
|
20357
20938
|
}
|
|
20358
|
-
|
|
20359
|
-
|
|
20360
|
-
|
|
20361
|
-
|
|
20362
|
-
|
|
20363
|
-
|
|
20364
|
-
|
|
20365
|
-
|
|
20366
|
-
|
|
20367
|
-
|
|
20368
|
-
|
|
20369
|
-
|
|
20370
|
-
|
|
20371
|
-
|
|
20372
|
-
|
|
20373
|
-
|
|
20374
|
-
|
|
20939
|
+
}, () => attempt.refusal ?? attempt.stepLimit, run.child.id, baseline, deadline, request.signal),
|
|
20940
|
+
aborted
|
|
20941
|
+
]);
|
|
20942
|
+
if (!attempt.shaped) {
|
|
20943
|
+
const task = run.identity.title.replace(/^magic-context-dream-/, "");
|
|
20944
|
+
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);
|
|
20945
|
+
}
|
|
20946
|
+
const text = assistantText(row);
|
|
20947
|
+
const system = typeof request.body.system === "string" ? request.body.system : run.identity.system;
|
|
20948
|
+
const tokens = row.data.tokens;
|
|
20949
|
+
const tokenNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
20950
|
+
const reportedInput = tokenNumber(tokens?.input);
|
|
20951
|
+
const reportedOutput = tokenNumber(tokens?.output);
|
|
20952
|
+
if (request.signal?.aborted || run.retired || Date.now() >= deadline) {
|
|
20953
|
+
await interruptAndRetire(run, "prompt-aborted-or-timeout");
|
|
20954
|
+
throw new Error(request.signal?.aborted ? "Hidden completion prompt aborted" : "Hidden completion prompt timed out");
|
|
20955
|
+
}
|
|
20956
|
+
run.completion = {
|
|
20957
|
+
text,
|
|
20958
|
+
tokenLog: runTokenLog(tokens, run.identity.maxOutputTokens, row.data.finish),
|
|
20959
|
+
reasoning: text ? null : assistantReasoning(row),
|
|
20960
|
+
usage: reportedInput !== undefined || reportedOutput !== undefined ? {
|
|
20961
|
+
input: reportedInput ?? 0,
|
|
20962
|
+
output: reportedOutput ?? 0,
|
|
20963
|
+
cacheRead: tokenNumber(tokens?.cache?.read) ?? 0,
|
|
20964
|
+
cacheWrite: tokenNumber(tokens?.cache?.write) ?? 0
|
|
20965
|
+
} : meter(system, promptText(request), text ?? ""),
|
|
20966
|
+
lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
|
|
20967
|
+
providerId: row.data.model?.providerID ?? requested.providerID,
|
|
20968
|
+
modelId: row.data.model?.id ?? requested.modelID,
|
|
20969
|
+
...attempt.steps === undefined ? {} : { steps: attempt.steps }
|
|
20970
|
+
};
|
|
20971
|
+
if (!run.child.ever_settled)
|
|
20972
|
+
run.child = lifecycle.markEverSettled(run.child);
|
|
20973
|
+
} catch (caught) {
|
|
20974
|
+
const error = attempt.stepLimit ?? attempt.refusal ?? caught;
|
|
20975
|
+
run.failed = true;
|
|
20976
|
+
if (!(error instanceof HiddenProviderError)) {
|
|
20977
|
+
run.unsettledFailure = true;
|
|
20978
|
+
}
|
|
20979
|
+
if (request.signal?.aborted && !run.retired) {
|
|
20980
|
+
await interruptAndRetire(run, "prompt-aborted");
|
|
20981
|
+
} else if (error instanceof Error && error.message.includes("timed out") && !run.retired) {
|
|
20982
|
+
await interruptAndRetire(run, "prompt-timeout");
|
|
20983
|
+
} else if ((error instanceof HiddenAgentStepLimit || error instanceof HiddenProviderError && error.settled) && !run.retired) {
|
|
20984
|
+
await interruptAndRetire(run, error instanceof HiddenAgentStepLimit ? "hidden-run-step-limit" : "hidden-run-provider-error");
|
|
20985
|
+
}
|
|
20986
|
+
throw error;
|
|
20987
|
+
} finally {
|
|
20988
|
+
clearTimeout(deadlineTimer);
|
|
20989
|
+
request.signal?.removeEventListener("abort", onAbort);
|
|
20990
|
+
options.hook.releaseAttempt(marker);
|
|
20991
|
+
}
|
|
20992
|
+
},
|
|
20993
|
+
async collect(handle) {
|
|
20994
|
+
const completion = runs.get(handle)?.completion;
|
|
20995
|
+
if (!completion)
|
|
20996
|
+
throw new Error("Hidden completion has no settled output");
|
|
20997
|
+
return completion;
|
|
20998
|
+
},
|
|
20999
|
+
async close(handle, settlement) {
|
|
21000
|
+
if (!handle)
|
|
21001
|
+
return;
|
|
21002
|
+
const run = runs.get(handle);
|
|
21003
|
+
if (!run)
|
|
21004
|
+
return;
|
|
21005
|
+
try {
|
|
21006
|
+
const reusable = !run.retired && run.failed && !run.unsettledFailure;
|
|
21007
|
+
if (!run.completion && (run.failed || !settlement.promptSettled) && !reusable) {
|
|
21008
|
+
retire(run, "hidden-run-failed");
|
|
21009
|
+
}
|
|
21010
|
+
} finally {
|
|
21011
|
+
runs.delete(handle);
|
|
21012
|
+
run.releaseRole();
|
|
21013
|
+
}
|
|
21014
|
+
await lifecycle.finish(run.child, run.retired);
|
|
21015
|
+
}
|
|
21016
|
+
};
|
|
21017
|
+
}
|
|
21018
|
+
|
|
21019
|
+
// src/v2/hooks/channel2.ts
|
|
21020
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
21021
|
+
var pendingCandidates = new WeakMap;
|
|
21022
|
+
function syntheticCandidates(context, sessionID, stored) {
|
|
21023
|
+
const pending = pendingCandidates.get(context.storage);
|
|
21024
|
+
for (const [key, id] of pending ?? []) {
|
|
21025
|
+
if (!key.startsWith(`${sessionID}/`))
|
|
21026
|
+
continue;
|
|
21027
|
+
if (stored.has(id))
|
|
21028
|
+
pending?.delete(key);
|
|
21029
|
+
else
|
|
21030
|
+
stored.add(id);
|
|
21031
|
+
}
|
|
21032
|
+
return stored;
|
|
21033
|
+
}
|
|
21034
|
+
function clearSyntheticCandidates(context) {
|
|
21035
|
+
pendingCandidates.delete(context.storage);
|
|
21036
|
+
}
|
|
21037
|
+
async function deliverSynthetic(context, sessionID, text) {
|
|
21038
|
+
const id = `msg_${randomBytes2(12).toString("hex")}`;
|
|
21039
|
+
await context.storage.set(`synthetic/${sessionID}/${id}`, { id });
|
|
21040
|
+
let candidates = pendingCandidates.get(context.storage);
|
|
21041
|
+
if (!candidates) {
|
|
21042
|
+
candidates = new Map;
|
|
21043
|
+
pendingCandidates.set(context.storage, candidates);
|
|
21044
|
+
}
|
|
21045
|
+
candidates.set(`${sessionID}/${id}`, id);
|
|
21046
|
+
await context.session.synthetic({ sessionID, id, text, delivery: "steer" });
|
|
21047
|
+
return id;
|
|
21048
|
+
}
|
|
21049
|
+
async function isAdmittedSynthetic(context, sessionID, id) {
|
|
21050
|
+
const record = await context.storage.get(`synthetic/${sessionID}/${id}`);
|
|
21051
|
+
return record !== null && typeof record === "object" && "id" in record && record.id === id;
|
|
21052
|
+
}
|
|
21053
|
+
async function deliverPendingChannel2(context, db, sessionID, baseline) {
|
|
21054
|
+
if (getChannel2NudgeState(db, sessionID) !== "pending")
|
|
21055
|
+
return;
|
|
21056
|
+
const evaluation = evaluateChannel2(baseline);
|
|
21057
|
+
if (!evaluation.evaluable || !evaluation.shouldTrigger)
|
|
21058
|
+
return;
|
|
21059
|
+
const token = randomBytes2(16).toString("hex");
|
|
21060
|
+
if (!claimChannel2NudgeState(db, sessionID, token))
|
|
21061
|
+
return;
|
|
21062
|
+
try {
|
|
21063
|
+
await deliverSynthetic(context, sessionID, buildChannel2Reminder(evaluation.reclaimableTokens, reclaimableToolOutputCount(baseline?.baselineParts ?? [])));
|
|
21064
|
+
} catch (error) {
|
|
21065
|
+
casChannel2NudgeClaim(db, sessionID, "pending", token);
|
|
21066
|
+
throw error;
|
|
21067
|
+
}
|
|
21068
|
+
casChannel2NudgeClaim(db, sessionID, "delivered", token);
|
|
21069
|
+
}
|
|
21070
|
+
|
|
21071
|
+
// src/v2/hooks/commands.ts
|
|
21072
|
+
async function registerV2Commands(args) {
|
|
21073
|
+
const domain = args.command;
|
|
21074
|
+
if (!domain || typeof domain.transform !== "function") {
|
|
21075
|
+
log("[magic-context] v2 host exposes no command domain; /mmc-* commands are TUI-only");
|
|
21076
|
+
return false;
|
|
21077
|
+
}
|
|
21078
|
+
const descriptions = getMagicContextBuiltinCommands(args.compactionEnabled);
|
|
21079
|
+
const commands = buildV2Commands(args.rpc, args.directory);
|
|
21080
|
+
try {
|
|
21081
|
+
await domain.transform((editor) => {
|
|
21082
|
+
for (const command of commands) {
|
|
21083
|
+
editor.add({
|
|
21084
|
+
name: command.name,
|
|
21085
|
+
description: descriptions[command.name].description,
|
|
21086
|
+
execute: command.execute
|
|
21087
|
+
});
|
|
21088
|
+
}
|
|
21089
|
+
});
|
|
21090
|
+
} catch (error) {
|
|
21091
|
+
log("[magic-context] v2 command registration failed", error);
|
|
21092
|
+
return false;
|
|
21093
|
+
}
|
|
21094
|
+
log(`[magic-context] registered server-side commands: ${commands.map((command) => command.name).join(" ")}`);
|
|
21095
|
+
return true;
|
|
21096
|
+
}
|
|
21097
|
+
function commandArgument(input, name) {
|
|
21098
|
+
const raw = typeof input.prompt?.text === "string" ? input.prompt.text.trim() : "";
|
|
21099
|
+
const prefix = `/${name}`;
|
|
21100
|
+
if (raw === prefix)
|
|
21101
|
+
return "";
|
|
21102
|
+
if (raw.startsWith(`${prefix} `))
|
|
21103
|
+
return raw.slice(prefix.length).trim();
|
|
21104
|
+
return raw;
|
|
21105
|
+
}
|
|
21106
|
+
function reportResult(sessionID, title, message) {
|
|
21107
|
+
pushNotification2("action", { action: "show-result-dialog", title, message }, sessionID);
|
|
21108
|
+
}
|
|
21109
|
+
function reportUsage(sessionID, message) {
|
|
21110
|
+
pushNotification2("toast", { message, variant: "warning" }, sessionID);
|
|
21111
|
+
}
|
|
21112
|
+
function reportRpcReply(sessionID, title, reply, pending) {
|
|
21113
|
+
if (reply.ok !== true) {
|
|
21114
|
+
const error = typeof reply.error === "string" ? reply.error : `${title} request failed`;
|
|
21115
|
+
pushNotification2("toast", { message: error, variant: "error" }, sessionID);
|
|
21116
|
+
return;
|
|
21117
|
+
}
|
|
21118
|
+
if (reply.started === true) {
|
|
21119
|
+
pushNotification2("toast", { message: pending, variant: "info" }, sessionID);
|
|
21120
|
+
return;
|
|
21121
|
+
}
|
|
21122
|
+
reportResult(sessionID, title, typeof reply.message === "string" ? reply.message : "");
|
|
21123
|
+
}
|
|
21124
|
+
function buildV2Commands(rpc, directory) {
|
|
21125
|
+
return [
|
|
21126
|
+
{
|
|
21127
|
+
name: "mmc-status",
|
|
21128
|
+
execute: async (input) => {
|
|
21129
|
+
const detail = await rpc.dispatch("status-detail", {
|
|
21130
|
+
sessionId: input.sessionID,
|
|
21131
|
+
directory
|
|
21132
|
+
});
|
|
21133
|
+
if (typeof detail.error === "string") {
|
|
21134
|
+
throw new Error(`Magic Context status is unavailable: ${detail.error}`);
|
|
20375
21135
|
}
|
|
20376
|
-
|
|
20377
|
-
|
|
20378
|
-
|
|
20379
|
-
|
|
20380
|
-
|
|
20381
|
-
|
|
20382
|
-
|
|
20383
|
-
|
|
20384
|
-
|
|
21136
|
+
pushNotification2("action", { action: "show-status-dialog" }, input.sessionID);
|
|
21137
|
+
}
|
|
21138
|
+
},
|
|
21139
|
+
{
|
|
21140
|
+
name: "mmc-recomp",
|
|
21141
|
+
execute: async (input) => {
|
|
21142
|
+
if (isTuiConnected2(input.sessionID)) {
|
|
21143
|
+
pushNotification2("action", { action: "show-recomp-dialog" }, input.sessionID);
|
|
21144
|
+
return;
|
|
21145
|
+
}
|
|
21146
|
+
const reply = await rpc.dispatch("recomp", { sessionId: input.sessionID });
|
|
21147
|
+
if (reply.ok !== true) {
|
|
21148
|
+
throw new Error("Magic Context could not start the history rebuild.");
|
|
20385
21149
|
}
|
|
20386
|
-
rendered.push(...following);
|
|
20387
21150
|
}
|
|
20388
|
-
|
|
21151
|
+
},
|
|
21152
|
+
{
|
|
21153
|
+
name: "mmc-flush",
|
|
21154
|
+
execute: async (input) => {
|
|
21155
|
+
const reply = await rpc.dispatch("flush", { sessionId: input.sessionID });
|
|
21156
|
+
reportRpcReply(input.sessionID, "Flush", reply, "Flush started");
|
|
21157
|
+
}
|
|
21158
|
+
},
|
|
21159
|
+
{
|
|
21160
|
+
name: "mmc-wrapup",
|
|
21161
|
+
execute: async (input) => {
|
|
21162
|
+
const argument = commandArgument(input, "mmc-wrapup");
|
|
21163
|
+
if (argument !== "" && !/^\d+$/.test(argument)) {
|
|
21164
|
+
const usage = "Usage: /mmc-wrapup [messages_to_keep] where messages_to_keep is a positive integer";
|
|
21165
|
+
reportUsage(input.sessionID, usage);
|
|
21166
|
+
throw new Error(usage);
|
|
21167
|
+
}
|
|
21168
|
+
const messagesToKeep = argument === "" ? 20 : Number.parseInt(argument, 10);
|
|
21169
|
+
if (messagesToKeep <= 0) {
|
|
21170
|
+
const usage = "messages_to_keep must be a positive integer";
|
|
21171
|
+
reportUsage(input.sessionID, usage);
|
|
21172
|
+
throw new Error(usage);
|
|
21173
|
+
}
|
|
21174
|
+
const reply = await rpc.dispatch("wrapup", {
|
|
21175
|
+
sessionId: input.sessionID,
|
|
21176
|
+
messagesToKeep
|
|
21177
|
+
});
|
|
21178
|
+
reportRpcReply(input.sessionID, "Wrapup", reply, "Wrapup started; the summary appears when it finishes");
|
|
21179
|
+
}
|
|
21180
|
+
},
|
|
21181
|
+
{
|
|
21182
|
+
name: "mmc-memory-maintain",
|
|
21183
|
+
execute: async (input) => {
|
|
21184
|
+
const argument = commandArgument(input, "mmc-memory-maintain");
|
|
21185
|
+
const subcommand = argument === "" ? "status" : argument.trim().toLowerCase();
|
|
21186
|
+
if (subcommand !== "run" && subcommand !== "status" && subcommand !== "resume") {
|
|
21187
|
+
const usage = "Usage: /mmc-memory-maintain [run|status|resume] — status is the default";
|
|
21188
|
+
reportUsage(input.sessionID, usage);
|
|
21189
|
+
throw new Error(usage);
|
|
21190
|
+
}
|
|
21191
|
+
const reply = await rpc.dispatch("maintenance", {
|
|
21192
|
+
sessionId: input.sessionID,
|
|
21193
|
+
subcommand
|
|
21194
|
+
});
|
|
21195
|
+
reportRpcReply(input.sessionID, "Memory maintenance", reply, "Maintenance run started; see /mmc-memory-maintain status for the outcome");
|
|
21196
|
+
}
|
|
20389
21197
|
}
|
|
20390
|
-
|
|
21198
|
+
];
|
|
21199
|
+
}
|
|
21200
|
+
|
|
21201
|
+
// src/v2/hooks/deleted-session-tombstones.ts
|
|
21202
|
+
class DeletedSessionTombstones {
|
|
21203
|
+
limit;
|
|
21204
|
+
#ids = new Set;
|
|
21205
|
+
constructor(limit = 1000) {
|
|
21206
|
+
this.limit = limit;
|
|
21207
|
+
if (!Number.isSafeInteger(limit) || limit < 1) {
|
|
21208
|
+
throw new Error("Deleted-session tombstone limit must be a positive integer");
|
|
21209
|
+
}
|
|
21210
|
+
}
|
|
21211
|
+
add(sessionID) {
|
|
21212
|
+
this.#ids.delete(sessionID);
|
|
21213
|
+
this.#ids.add(sessionID);
|
|
21214
|
+
while (this.#ids.size > this.limit) {
|
|
21215
|
+
const oldest = this.#ids.values().next().value;
|
|
21216
|
+
if (oldest === undefined)
|
|
21217
|
+
break;
|
|
21218
|
+
this.#ids.delete(oldest);
|
|
21219
|
+
}
|
|
21220
|
+
}
|
|
21221
|
+
has(sessionID) {
|
|
21222
|
+
return this.#ids.has(sessionID);
|
|
21223
|
+
}
|
|
21224
|
+
clear() {
|
|
21225
|
+
this.#ids.clear();
|
|
21226
|
+
}
|
|
21227
|
+
get size() {
|
|
21228
|
+
return this.#ids.size;
|
|
21229
|
+
}
|
|
20391
21230
|
}
|
|
20392
21231
|
|
|
20393
21232
|
// src/v2/hooks/generate.ts
|
|
@@ -20433,9 +21272,9 @@ function hiddenTerminalError(event) {
|
|
|
20433
21272
|
}
|
|
20434
21273
|
|
|
20435
21274
|
// src/v2/hooks/lkg-system.ts
|
|
20436
|
-
import { createHash as
|
|
20437
|
-
function
|
|
20438
|
-
return
|
|
21275
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
21276
|
+
function identity2(slot) {
|
|
21277
|
+
return createHash7("sha256").update(JSON.stringify({
|
|
20439
21278
|
capturedAt: slot.capturedAt,
|
|
20440
21279
|
captureSequence: slot.captureSequence,
|
|
20441
21280
|
rowVersion: slot.rowVersion,
|
|
@@ -20450,14 +21289,14 @@ class V2LkgSystemReplay {
|
|
|
20450
21289
|
systems = new BoundedSessionMap(1000);
|
|
20451
21290
|
capture(sessionId, slot, input, served) {
|
|
20452
21291
|
this.systems.set(sessionId, {
|
|
20453
|
-
slot:
|
|
21292
|
+
slot: identity2(slot),
|
|
20454
21293
|
input: JSON.stringify(input),
|
|
20455
21294
|
served: structuredClone(served)
|
|
20456
21295
|
});
|
|
20457
21296
|
}
|
|
20458
21297
|
restore(sessionId, slot, input, target) {
|
|
20459
21298
|
const saved = this.systems.get(sessionId);
|
|
20460
|
-
if (!slot || !saved || saved.slot !==
|
|
21299
|
+
if (!slot || !saved || saved.slot !== identity2(slot) || saved.input !== JSON.stringify(input))
|
|
20461
21300
|
return false;
|
|
20462
21301
|
target.splice(0, target.length, ...structuredClone(saved.served));
|
|
20463
21302
|
return true;
|
|
@@ -20642,7 +21481,7 @@ function hasRequiredSessionAPI(session) {
|
|
|
20642
21481
|
}
|
|
20643
21482
|
|
|
20644
21483
|
// src/features/magic-context/session-project-backfill.ts
|
|
20645
|
-
import { randomUUID as
|
|
21484
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
20646
21485
|
import { existsSync as existsSync7 } from "node:fs";
|
|
20647
21486
|
var LEASE_TTL_MS = 10 * 60 * 1000;
|
|
20648
21487
|
var SESSION_PAGE_SIZE = 100;
|
|
@@ -20784,7 +21623,7 @@ async function runSessionProjectBackfill(db, source, options = {}) {
|
|
|
20784
21623
|
const now = options.now ?? Date.now;
|
|
20785
21624
|
const resolveIdentity = options.resolveIdentity ?? ((directory) => resolveProjectIdentityForSession(directory, options.allowHomeProject));
|
|
20786
21625
|
const yieldFn = options.yieldFn ?? defaultYieldFn;
|
|
20787
|
-
const holderId = options.holderId ??
|
|
21626
|
+
const holderId = options.holderId ?? randomUUID4();
|
|
20788
21627
|
const readPage = createPageReader(source);
|
|
20789
21628
|
const result = {
|
|
20790
21629
|
status: "completed",
|
|
@@ -21304,7 +22143,7 @@ Returns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversiz
|
|
|
21304
22143
|
|
|
21305
22144
|
Finer recovery:
|
|
21306
22145
|
- verbose=true lists each message separately with its ordinal and a per-part preview (tool calls with output sizes) so you can pick one.
|
|
21307
|
-
- message=N returns that one message in full — every text part and every tool call's complete input and output — from stored history. This is the way back to a tool output you released with mmc_reduce; if the message
|
|
22146
|
+
- message=N returns that one message in full — every text part and every tool call's complete input and output — from stored history. This is the way back to a tool output you released with mmc_reduce; if the message is no longer in stored history it says so.`;
|
|
21308
22147
|
var CTX_EXPAND_TOKEN_BUDGET = 15000;
|
|
21309
22148
|
|
|
21310
22149
|
// src/features/magic-context/tag-input.ts
|
|
@@ -21377,7 +22216,7 @@ function resolveCtxExpandMode(args, domain) {
|
|
|
21377
22216
|
}
|
|
21378
22217
|
|
|
21379
22218
|
// src/tools/ctx-expand/render.ts
|
|
21380
|
-
import { createHash as
|
|
22219
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
21381
22220
|
function isRecord4(value) {
|
|
21382
22221
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21383
22222
|
}
|
|
@@ -21466,7 +22305,7 @@ function reasoningOf(part) {
|
|
|
21466
22305
|
function renderPartPreview(part, expandTools) {
|
|
21467
22306
|
if (!isRecord4(part))
|
|
21468
22307
|
return null;
|
|
21469
|
-
const expansion = expandToolPart(part, expandTools);
|
|
22308
|
+
const expansion = expandToolPart(part, expandTools, true);
|
|
21470
22309
|
if (expansion !== null)
|
|
21471
22310
|
return ` • tool ${part.tool}: ${expansion}`;
|
|
21472
22311
|
const text = textOf(part);
|
|
@@ -21530,7 +22369,7 @@ function renderMessageByOrdinal(sessionId, ordinal) {
|
|
|
21530
22369
|
});
|
|
21531
22370
|
const msg = found[0];
|
|
21532
22371
|
if (!msg) {
|
|
21533
|
-
return `No message at ordinal ${ordinal} in this session's stored history — it
|
|
22372
|
+
return `No message at ordinal ${ordinal} is currently in this session's stored history — ` + `it may have been removed by a session prune/revert, or the ordinal may be wrong. ` + `Re-run the tool if you still need the data.`;
|
|
21534
22373
|
}
|
|
21535
22374
|
const rendered = msg.parts.map(renderPartFull).filter((l) => l !== null);
|
|
21536
22375
|
const lines = [`[${msg.ordinal}] ${roleLabel(msg.role)} — full recovery:`, ""];
|
|
@@ -21601,9 +22440,12 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
|
|
|
21601
22440
|
const index = scoped ? Number(scoped[2]) : 0;
|
|
21602
22441
|
const piText = message.parts.filter((part) => isRecord4(part) && part.type === "text");
|
|
21603
22442
|
const part = message.parts[index];
|
|
21604
|
-
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" &&
|
|
22443
|
+
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" && createHash8("sha256").update(part.text).digest("hex") === derived[3]) : [];
|
|
21605
22444
|
const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
|
|
21606
|
-
|
|
22445
|
+
if (!selected)
|
|
22446
|
+
return `Tag ${number}'s original text part is no longer in stored history.`;
|
|
22447
|
+
const renderedPart = renderPartFull(selected);
|
|
22448
|
+
return renderedPart !== null ? renderedPart : `Tag ${number}'s stored text part has no renderable content (empty or structural-only); the requested content was not recovered.`;
|
|
21607
22449
|
}
|
|
21608
22450
|
|
|
21609
22451
|
// src/tools/ctx-expand/tools.ts
|
|
@@ -21629,52 +22471,57 @@ function createCtxExpandTool(deps) {
|
|
|
21629
22471
|
message: "number"
|
|
21630
22472
|
});
|
|
21631
22473
|
const sessionId = toolContext.sessionID;
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
if (mode.kind === "tag") {
|
|
21637
|
-
return renderItemByTag(deps.db, sessionId, mode.tag);
|
|
21638
|
-
}
|
|
21639
|
-
if (mode.kind === "message") {
|
|
21640
|
-
return renderMessageByOrdinal(sessionId, mode.message);
|
|
21641
|
-
}
|
|
21642
|
-
const { start, end, verbose } = mode;
|
|
21643
|
-
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
21644
|
-
if (lastCompartmentEnd >= 0 && start > lastCompartmentEnd) {
|
|
21645
|
-
return `Range ${start}-${end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`;
|
|
21646
|
-
}
|
|
21647
|
-
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(end, lastCompartmentEnd) : end;
|
|
21648
|
-
if (verbose) {
|
|
21649
|
-
const v = renderVerboseRange(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET, deps.expandTools);
|
|
21650
|
-
if (!v.text) {
|
|
21651
|
-
return `No messages found in range ${start}-${effectiveEnd}. The range may be outside this session's history.`;
|
|
22474
|
+
try {
|
|
22475
|
+
const mode = resolveCtxExpandMode(args, "positive");
|
|
22476
|
+
if (mode.kind === "error") {
|
|
22477
|
+
return mode.message;
|
|
21652
22478
|
}
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
"",
|
|
21656
|
-
v.text
|
|
21657
|
-
];
|
|
21658
|
-
if (v.truncated) {
|
|
21659
|
-
out.push("", `Truncated at message ${v.lastOrdinal} (budget: ~${CTX_EXPAND_TOKEN_BUDGET} tokens). Call again with start=${v.lastOrdinal + 1} end=${effectiveEnd} verbose=true for more.`);
|
|
22479
|
+
if (mode.kind === "tag") {
|
|
22480
|
+
return renderItemByTag(deps.db, sessionId, mode.tag);
|
|
21660
22481
|
}
|
|
21661
|
-
|
|
22482
|
+
if (mode.kind === "message") {
|
|
22483
|
+
return renderMessageByOrdinal(sessionId, mode.message);
|
|
22484
|
+
}
|
|
22485
|
+
const { start, end, verbose } = mode;
|
|
22486
|
+
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
22487
|
+
if (lastCompartmentEnd >= 0 && start > lastCompartmentEnd) {
|
|
22488
|
+
return `Range ${start}-${end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`;
|
|
22489
|
+
}
|
|
22490
|
+
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(end, lastCompartmentEnd) : end;
|
|
22491
|
+
if (verbose) {
|
|
22492
|
+
const v = renderVerboseRange(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET, deps.expandTools);
|
|
22493
|
+
if (!v.text) {
|
|
22494
|
+
return `No messages found in range ${start}-${effectiveEnd}. The range may be outside this session's history.`;
|
|
22495
|
+
}
|
|
22496
|
+
const out = [
|
|
22497
|
+
`Messages ${start}-${v.lastOrdinal} (verbose). Recover any one in full with mmc_expand(message=<ordinal>):`,
|
|
22498
|
+
"",
|
|
22499
|
+
v.text
|
|
22500
|
+
];
|
|
22501
|
+
if (v.truncated) {
|
|
22502
|
+
out.push("", `Truncated at message ${v.lastOrdinal} (budget: ~${CTX_EXPAND_TOKEN_BUDGET} tokens). Call again with start=${v.lastOrdinal + 1} end=${effectiveEnd} verbose=true for more.`);
|
|
22503
|
+
}
|
|
22504
|
+
return out.join(`
|
|
21662
22505
|
`);
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
lines.push("");
|
|
21671
|
-
lines.push(chunk.text);
|
|
21672
|
-
if (chunk.endIndex < effectiveEnd) {
|
|
22506
|
+
}
|
|
22507
|
+
const chunk = readSessionChunk2(sessionId, CTX_EXPAND_TOKEN_BUDGET, start, effectiveEnd + 1, { expand: false });
|
|
22508
|
+
if (!chunk.text || chunk.messageCount === 0) {
|
|
22509
|
+
return `No messages found in range ${start}-${end}. The range may be outside this session's history.`;
|
|
22510
|
+
}
|
|
22511
|
+
const lines = [];
|
|
22512
|
+
lines.push(`Messages ${chunk.startIndex}-${chunk.endIndex} (${chunk.messageCount} messages, ~${chunk.tokenEstimate} tokens):`);
|
|
21673
22513
|
lines.push("");
|
|
21674
|
-
lines.push(
|
|
21675
|
-
|
|
21676
|
-
|
|
22514
|
+
lines.push(chunk.text);
|
|
22515
|
+
if (chunk.endIndex < effectiveEnd) {
|
|
22516
|
+
lines.push("");
|
|
22517
|
+
lines.push(`Truncated at message ${chunk.endIndex} (budget: ~${CTX_EXPAND_TOKEN_BUDGET} tokens). Call again with start=${chunk.endIndex + 1} end=${effectiveEnd} for more.`);
|
|
22518
|
+
}
|
|
22519
|
+
return lines.join(`
|
|
21677
22520
|
`);
|
|
22521
|
+
} catch (error) {
|
|
22522
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
22523
|
+
return `Error: mmc_expand failed to read this session's stored history: ${message}`;
|
|
22524
|
+
}
|
|
21678
22525
|
}
|
|
21679
22526
|
});
|
|
21680
22527
|
}
|
|
@@ -22912,6 +23759,9 @@ function persistV2UsageReading(args) {
|
|
|
22912
23759
|
|
|
22913
23760
|
// src/v2/hooks/context.ts
|
|
22914
23761
|
var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
|
|
23762
|
+
|
|
23763
|
+
class V2LkgAdmissionReplay extends Error {
|
|
23764
|
+
}
|
|
22915
23765
|
function isBlockingV2TransformError(error) {
|
|
22916
23766
|
return error instanceof EmergencyFailClosedError || error instanceof UnresolvedHistoryBoundaryError || error instanceof UnmanagedOverWindowError || error instanceof DegradedPassRefusalError || isFailClosedBlockingError(error);
|
|
22917
23767
|
}
|
|
@@ -23120,6 +23970,8 @@ async function registerContext(context) {
|
|
|
23120
23970
|
return;
|
|
23121
23971
|
}
|
|
23122
23972
|
const folds = new FoldOwner(context.storage);
|
|
23973
|
+
const nativeFoldMemory = !compactionOff && process.env.MMC_OC2_INVISIBLE_FOLD === "1" ? nativeFoldCache(() => storage.require()) : undefined;
|
|
23974
|
+
const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader()) : undefined;
|
|
23123
23975
|
setOutputReserveConfig(config.output_reserve);
|
|
23124
23976
|
const queriedModels = new Set;
|
|
23125
23977
|
const rawLimits = new Map;
|
|
@@ -23151,7 +24003,7 @@ async function registerContext(context) {
|
|
|
23151
24003
|
let storageRecoveryAnnounced = false;
|
|
23152
24004
|
const storageNoticeBySession = new Map;
|
|
23153
24005
|
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)));
|
|
24006
|
+
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
24007
|
};
|
|
23156
24008
|
const noticeStorageRefusal = (sessionID, reason) => {
|
|
23157
24009
|
const message = formatStorageRefusalNotice(reason);
|
|
@@ -23418,6 +24270,14 @@ async function registerContext(context) {
|
|
|
23418
24270
|
}
|
|
23419
24271
|
return unsafe;
|
|
23420
24272
|
};
|
|
24273
|
+
const hostFolds = nativeFoldReplay && nativeFoldMemory ? new HostFoldPolicy({
|
|
24274
|
+
session: context.session,
|
|
24275
|
+
storage: nativeFoldMemory,
|
|
24276
|
+
openReader: openStoreReader,
|
|
24277
|
+
canReplay: (sessionID, reader) => nativeFoldReplay.canReplay(sessionID, reader),
|
|
24278
|
+
threshold: Number(process.env.MMC_OC2_HOST_FOLD_ROWS ?? 1000),
|
|
24279
|
+
log: sessionLog
|
|
24280
|
+
}) : undefined;
|
|
23421
24281
|
const usageController = new AbortController;
|
|
23422
24282
|
const usageDone = (async () => {
|
|
23423
24283
|
try {
|
|
@@ -23428,6 +24288,10 @@ async function registerContext(context) {
|
|
|
23428
24288
|
if (!event.data?.sessionID)
|
|
23429
24289
|
continue;
|
|
23430
24290
|
const sessionID = event.data.sessionID;
|
|
24291
|
+
if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
|
|
24292
|
+
nativeFoldReplay?.onEvent(event);
|
|
24293
|
+
restoredRows.forget(sessionID);
|
|
24294
|
+
}
|
|
23431
24295
|
if (event.type === "session.error" || event.type === "session.execution.failed") {
|
|
23432
24296
|
const error = hiddenTerminalError(event);
|
|
23433
24297
|
if (error !== undefined)
|
|
@@ -23453,6 +24317,7 @@ async function registerContext(context) {
|
|
|
23453
24317
|
pendingMaterializationSessions.delete(sessionID);
|
|
23454
24318
|
lastHeuristicsTurnId.delete(sessionID);
|
|
23455
24319
|
restoredRows.forget(sessionID);
|
|
24320
|
+
await nativeFoldReplay?.forget(sessionID);
|
|
23456
24321
|
generateReplay.forget(sessionID);
|
|
23457
24322
|
systemPromptRefreshSessions.delete(sessionID);
|
|
23458
24323
|
systemPrompt?.clearSession(sessionID);
|
|
@@ -23465,11 +24330,14 @@ async function registerContext(context) {
|
|
|
23465
24330
|
if (event.type !== "session.execution.succeeded")
|
|
23466
24331
|
continue;
|
|
23467
24332
|
const model = liveModels.get(sessionID);
|
|
23468
|
-
if (model)
|
|
24333
|
+
if (model) {
|
|
23469
24334
|
await recordUsage({
|
|
23470
24335
|
sessionID,
|
|
23471
24336
|
model: { providerID: model.providerID, id: model.modelID }
|
|
23472
24337
|
});
|
|
24338
|
+
if (!compactionOff && typeof await nativeFoldReplay?.baseline(sessionID) === "string")
|
|
24339
|
+
hostFolds?.idle(sessionID);
|
|
24340
|
+
}
|
|
23473
24341
|
}
|
|
23474
24342
|
} catch (error) {
|
|
23475
24343
|
if (!usageController.signal.aborted)
|
|
@@ -23504,10 +24372,32 @@ async function registerContext(context) {
|
|
|
23504
24372
|
}
|
|
23505
24373
|
if (compactionOff)
|
|
23506
24374
|
return;
|
|
24375
|
+
if (nativeFoldReplay)
|
|
24376
|
+
rememberHostMedia(draft.messages);
|
|
23507
24377
|
const reader = openStoreReader();
|
|
23508
24378
|
try {
|
|
23509
24379
|
const watermark = reader.latestSequenceForIds(draft.sessionID, draft.messages.flatMap((message) => message.id ? [message.id] : []));
|
|
23510
24380
|
const running = reader.latestRunningCompaction(draft.sessionID);
|
|
24381
|
+
if (nativeFoldReplay) {
|
|
24382
|
+
try {
|
|
24383
|
+
if (await nativeFoldReplay.canReplay(draft.sessionID, reader)) {
|
|
24384
|
+
const state = getOrCreateSessionMeta(storage.require(), draft.sessionID);
|
|
24385
|
+
const summary = await nativeFoldReplay.baseline(draft.sessionID) ?? state.cachedM0Bytes?.toString("utf8") ?? "<session-history></session-history>";
|
|
24386
|
+
if (await nativeFoldReplay.supply({
|
|
24387
|
+
draft,
|
|
24388
|
+
reader,
|
|
24389
|
+
previousCut: reader.latestCompaction(draft.sessionID),
|
|
24390
|
+
summary
|
|
24391
|
+
})) {
|
|
24392
|
+
draft.result = { summary };
|
|
24393
|
+
return;
|
|
24394
|
+
}
|
|
24395
|
+
}
|
|
24396
|
+
} catch (error) {
|
|
24397
|
+
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
24398
|
+
sessionLog(draft.sessionID, `v2 host fold: legacy compaction reason=${JSON.stringify(String(error))}`);
|
|
24399
|
+
}
|
|
24400
|
+
}
|
|
23511
24401
|
const fold = await folds.supply({
|
|
23512
24402
|
sessionID: draft.sessionID,
|
|
23513
24403
|
watermark,
|
|
@@ -23554,12 +24444,88 @@ async function registerContext(context) {
|
|
|
23554
24444
|
withoutSqliteTransformPass(() => warmModelLimitCacheFromCatalog(context));
|
|
23555
24445
|
agents.set(draft.sessionID, draft.agent);
|
|
23556
24446
|
applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface);
|
|
24447
|
+
const admissionDb = db ?? storage.current();
|
|
24448
|
+
const replayFits = (messages) => {
|
|
24449
|
+
const system = structuredClone(draft.system);
|
|
24450
|
+
if (!admissionDb || !draft.tools || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), draft.system, system))
|
|
24451
|
+
return false;
|
|
24452
|
+
const limit = lkgReplayLimit({
|
|
24453
|
+
db: admissionDb,
|
|
24454
|
+
sessionId: draft.sessionID,
|
|
24455
|
+
model: {
|
|
24456
|
+
providerID: draft.model.providerID,
|
|
24457
|
+
modelID: draft.model.id
|
|
24458
|
+
},
|
|
24459
|
+
modelKey: `${draft.model.providerID}/${draft.model.id}`
|
|
24460
|
+
});
|
|
24461
|
+
if (limit === undefined)
|
|
24462
|
+
return false;
|
|
24463
|
+
let toolDefinitionTokens = 0;
|
|
24464
|
+
for (const tool of Object.values(draft.tools)) {
|
|
24465
|
+
if (!tool || typeof tool.description !== "string" || !tool.input)
|
|
24466
|
+
return false;
|
|
24467
|
+
const schema = JSON.stringify(tool.input);
|
|
24468
|
+
if (!schema)
|
|
24469
|
+
return false;
|
|
24470
|
+
toolDefinitionTokens += estimateTokens(tool.description) + estimateTokens(schema);
|
|
24471
|
+
}
|
|
24472
|
+
return measureLkgReplay({
|
|
24473
|
+
messages,
|
|
24474
|
+
limit,
|
|
24475
|
+
estimate: () => estimateFinalWireInputTokens({
|
|
24476
|
+
messages,
|
|
24477
|
+
toolDefinitionTokens,
|
|
24478
|
+
systemPromptTokens: estimateTokens(JSON.stringify(system)),
|
|
24479
|
+
providerID: draft.model.providerID,
|
|
24480
|
+
modelID: draft.model.id,
|
|
24481
|
+
agentName: draft.agent
|
|
24482
|
+
})
|
|
24483
|
+
}).fit === "under";
|
|
24484
|
+
};
|
|
23557
24485
|
let postFold = false;
|
|
23558
24486
|
try {
|
|
23559
|
-
const admissionDb = db ?? storage.current();
|
|
23560
24487
|
if (!compactionOff && admissionDb)
|
|
23561
24488
|
await withAsyncPrivilegedWriter(admissionDb, () => {
|
|
23562
24489
|
return;
|
|
24490
|
+
}, {
|
|
24491
|
+
beforeRetry: (_error) => {
|
|
24492
|
+
let replayBlocked = false;
|
|
24493
|
+
const mapped = adaptPayload(draft);
|
|
24494
|
+
try {
|
|
24495
|
+
const overflowDb = db;
|
|
24496
|
+
if (overflowDb !== undefined && overflowDb !== null && (isEmergencyRecoveryArmed(draft.sessionID) || getOverflowState(overflowDb, draft.sessionID).needsEmergencyRecovery)) {
|
|
24497
|
+
replayBlocked = true;
|
|
24498
|
+
sessionLog(draft.sessionID, "lkg_emergency_armed");
|
|
24499
|
+
} else {
|
|
24500
|
+
const keys = resolveLkgModelKeys(mapped.messages);
|
|
24501
|
+
const replay = replayLkg({
|
|
24502
|
+
sessionId: draft.sessionID,
|
|
24503
|
+
messages: mapped.messages,
|
|
24504
|
+
modelKey: keys.modelKey,
|
|
24505
|
+
providerKey: keys.providerKey
|
|
24506
|
+
});
|
|
24507
|
+
if (replay.ok && !replayFits(replay.messages)) {
|
|
24508
|
+
replayBlocked = true;
|
|
24509
|
+
sessionLog(draft.sessionID, "lkg_replay_does_not_fit");
|
|
24510
|
+
} else if (replay.ok) {
|
|
24511
|
+
restoreLkgSystem();
|
|
24512
|
+
mapped.messages.splice(0, mapped.messages.length, ...replay.messages);
|
|
24513
|
+
mapped.commit();
|
|
24514
|
+
sessionLog(draft.sessionID, "lkg_replay_served");
|
|
24515
|
+
throw new V2LkgAdmissionReplay;
|
|
24516
|
+
} else {
|
|
24517
|
+
sessionLog(draft.sessionID, replay.reason);
|
|
24518
|
+
}
|
|
24519
|
+
}
|
|
24520
|
+
} catch (replayError) {
|
|
24521
|
+
if (replayError instanceof V2LkgAdmissionReplay)
|
|
24522
|
+
throw replayError;
|
|
24523
|
+
replayBlocked = true;
|
|
24524
|
+
sessionLog(draft.sessionID, "lkg_replay_unavailable", replayError);
|
|
24525
|
+
}
|
|
24526
|
+
if (replayBlocked)
|
|
24527
|
+
sessionLog(draft.sessionID, "lkg_replay_declined");
|
|
24528
|
+
}
|
|
23563
24529
|
});
|
|
23564
24530
|
if (admissionDb)
|
|
23565
24531
|
hideSubagentTools(draft, admissionDb);
|
|
@@ -23714,7 +24680,28 @@ async function registerContext(context) {
|
|
|
23714
24680
|
postFold = cut !== undefined;
|
|
23715
24681
|
if (cut && !incoming)
|
|
23716
24682
|
throw new Error("The host checkpoint disappeared from the context draft");
|
|
23717
|
-
|
|
24683
|
+
let nativeRestored;
|
|
24684
|
+
if (cut && nativeFoldReplay && isLocalCheckpoint(cut)) {
|
|
24685
|
+
try {
|
|
24686
|
+
nativeRestored = await nativeFoldReplay.restore(draft.sessionID, cut, `${draft.model.providerID}/${draft.model.id}`, { bounded: true });
|
|
24687
|
+
} catch (error) {
|
|
24688
|
+
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
24689
|
+
sessionLog(draft.sessionID, "v2 host fold: cache unavailable; restoring host rows", error);
|
|
24690
|
+
nativeRestored = await nativeFoldReplay.restoreRead(draft.sessionID, cut, draft.model);
|
|
24691
|
+
}
|
|
24692
|
+
}
|
|
24693
|
+
if (nativeRestored && nativeFoldReplay?.sourceChanged(draft.sessionID)) {
|
|
24694
|
+
historyRefreshSessions.add(draft.sessionID);
|
|
24695
|
+
pendingMaterializationSessions.add(draft.sessionID);
|
|
24696
|
+
}
|
|
24697
|
+
if (cut && incoming && nativeRestored) {
|
|
24698
|
+
const present = new Set(draft.messages.flatMap((message) => message.id ? [message.id] : []));
|
|
24699
|
+
const hidden = nativeRestored.filter((message) => {
|
|
24700
|
+
const id = nativeRowID(message);
|
|
24701
|
+
return !id || !present.has(id);
|
|
24702
|
+
});
|
|
24703
|
+
draft.messages.splice(0, draft.messages.length, ...hidden, ...draft.messages.filter((message) => message !== incoming));
|
|
24704
|
+
} else if (cut && incoming) {
|
|
23718
24705
|
const identity = await folds.observe({
|
|
23719
24706
|
sessionID: draft.sessionID,
|
|
23720
24707
|
cutSeq: cut.seq,
|
|
@@ -23741,6 +24728,14 @@ async function registerContext(context) {
|
|
|
23741
24728
|
} finally {
|
|
23742
24729
|
reader.close();
|
|
23743
24730
|
}
|
|
24731
|
+
let nativeMessages;
|
|
24732
|
+
if (nativeFoldReplay) {
|
|
24733
|
+
try {
|
|
24734
|
+
nativeMessages = copyNativeInput(draft.messages);
|
|
24735
|
+
} catch {
|
|
24736
|
+
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
24737
|
+
}
|
|
24738
|
+
}
|
|
23744
24739
|
const mapped = adaptPayload(draft, admitted);
|
|
23745
24740
|
beginV2LkgRequest(draft.sessionID, `${draft.model.providerID}/${draft.model.id}`, latestLkgResponseIds.get(draft.sessionID));
|
|
23746
24741
|
await transform({}, mapped);
|
|
@@ -23766,6 +24761,14 @@ ${baseline}
|
|
|
23766
24761
|
draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== head));
|
|
23767
24762
|
}
|
|
23768
24763
|
}
|
|
24764
|
+
if (nativeMessages && !checkpoint) {
|
|
24765
|
+
try {
|
|
24766
|
+
await nativeFoldReplay?.capture(draft, nativeMessages);
|
|
24767
|
+
} catch (error) {
|
|
24768
|
+
nativeFoldReplay?.invalidate(draft.sessionID, true);
|
|
24769
|
+
sessionLog(draft.sessionID, "v2 host fold: optional capture unavailable", error);
|
|
24770
|
+
}
|
|
24771
|
+
}
|
|
23769
24772
|
const capturedSlot = getSlot(draft.sessionID);
|
|
23770
24773
|
if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
|
|
23771
24774
|
lkgSystems.capture(draft.sessionID, capturedSlot, systemAtEntry, draft.system);
|
|
@@ -23773,6 +24776,8 @@ ${baseline}
|
|
|
23773
24776
|
} catch (error) {
|
|
23774
24777
|
if (error instanceof V2ContextRefusal)
|
|
23775
24778
|
throw error;
|
|
24779
|
+
if (error instanceof V2LkgAdmissionReplay)
|
|
24780
|
+
return;
|
|
23776
24781
|
if (!compactionOff && (isTransientSqliteError(error) || error instanceof StorageBusyRefusalError)) {
|
|
23777
24782
|
if (isTransientSqliteError(error)) {
|
|
23778
24783
|
try {
|
|
@@ -23800,13 +24805,16 @@ ${baseline}
|
|
|
23800
24805
|
modelKey: keys.modelKey,
|
|
23801
24806
|
providerKey: keys.providerKey
|
|
23802
24807
|
});
|
|
23803
|
-
if (replay.ok) {
|
|
24808
|
+
if (replay.ok && !replayFits(replay.messages)) {
|
|
24809
|
+
sessionLog(draft.sessionID, "lkg_replay_does_not_fit");
|
|
24810
|
+
} else if (replay.ok) {
|
|
23804
24811
|
restoreLkgSystem();
|
|
23805
24812
|
replayMapped.messages.splice(0, replayMapped.messages.length, ...replay.messages);
|
|
23806
24813
|
replayMapped.commit();
|
|
23807
24814
|
return;
|
|
24815
|
+
} else {
|
|
24816
|
+
sessionLog(draft.sessionID, replay.reason);
|
|
23808
24817
|
}
|
|
23809
|
-
sessionLog(draft.sessionID, replay.reason);
|
|
23810
24818
|
}
|
|
23811
24819
|
} catch (replayError) {
|
|
23812
24820
|
replayBlocked = true;
|