@cortexkit/opencode-magic-context 0.42.3 → 0.42.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/{announcement-3c1vertn.js → announcement-8mgn61fw.js} +1 -1
- package/dist/{conflict-warning-hook-aedp084d.js → conflict-warning-hook-jyj54gbe.js} +4 -4
- package/dist/{derive-budgets-s2pgnnm4.js → derive-budgets-v1fkhjjr.js} +2 -2
- package/dist/features/magic-context/context-authority.d.ts +13 -0
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts +3 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +6 -2
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +3 -0
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts +3 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +4 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +4 -1
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +4 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +5 -2
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +2 -2
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +61 -2
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts +2 -2
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/dropped-token-estimate.d.ts +20 -0
- package/dist/hooks/magic-context/dropped-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +2 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +2 -2
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +4 -1
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +2 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +8 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +21 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-sf6x1ga9.js → index-1ar7b3e9.js} +3 -3
- package/dist/{index-3fe78beq.js → index-4ftb5hcq.js} +9 -1
- package/dist/{index-may8skc8.js → index-bkg2fdj1.js} +15 -1
- package/dist/{index-ecz14qke.js → index-d8mgqezq.js} +2 -2
- package/dist/{index-xdtge3y2.js → index-f9gem5cr.js} +2 -2
- package/dist/{index-wde5446v.js → index-faay035c.js} +196 -56
- package/dist/{index-z8552w7e.js → index-jkrqhc7y.js} +1 -1
- package/dist/{index-3wzdwt6p.js → index-ntbmt6rq.js} +1 -1
- package/dist/{index-gynz8qdc.js → index-p474rw9p.js} +3 -3
- package/dist/{index-dkv2dn46.js → index-qp20p2py.js} +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1441 -126
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +18 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/rust-tool-backends.d.ts +3 -1
- package/dist/plugin/rust-tool-backends.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-447vycpt.js → recomp-orchestrator-c4sa354a.js} +6 -6
- package/dist/{safe-notification-target-q9z81zt3.js → safe-notification-target-fepvcbsj.js} +1 -1
- package/dist/{send-session-notification-2mzgd3zf.js → send-session-notification-xnypkxpx.js} +3 -3
- package/dist/shared/harness.d.ts +2 -1
- package/dist/shared/harness.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +5 -1
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +13 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/status-detail-text.d.ts.map +1 -1
- package/dist/shared/status-summary.d.ts.map +1 -1
- package/dist/shared/user-facing-codes.d.ts +10 -0
- package/dist/shared/user-facing-codes.d.ts.map +1 -1
- package/dist/{storage-meta-session-fkmfhswa.js → storage-meta-session-x3j0q9qy.js} +3 -3
- package/dist/{task-config-hnv93r7p.js → task-config-ys0arma5.js} +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/v2/fold/markers.d.ts +7 -0
- package/dist/v2/fold/markers.d.ts.map +1 -0
- package/dist/v2/fold/owner.d.ts +40 -0
- package/dist/v2/fold/owner.d.ts.map +1 -0
- package/dist/v2/fold/restore.d.ts +11 -0
- package/dist/v2/fold/restore.d.ts.map +1 -0
- package/dist/v2/hidden-completion.d.ts +20 -0
- package/dist/v2/hidden-completion.d.ts.map +1 -0
- package/dist/v2/hooks/channel2.d.ts +8 -0
- package/dist/v2/hooks/channel2.d.ts.map +1 -0
- package/dist/v2/hooks/context.d.ts +7 -0
- package/dist/v2/hooks/context.d.ts.map +1 -0
- package/dist/v2/hooks/dream-trigger.d.ts +19 -0
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -0
- package/dist/v2/hooks/payload.d.ts +12 -0
- package/dist/v2/hooks/payload.d.ts.map +1 -0
- package/dist/v2/hooks/refusal.d.ts +7 -0
- package/dist/v2/hooks/refusal.d.ts.map +1 -0
- package/dist/v2/hooks/store.d.ts +6 -0
- package/dist/v2/hooks/store.d.ts.map +1 -0
- package/dist/v2/hooks/types.d.ts +90 -0
- package/dist/v2/hooks/types.d.ts.map +1 -0
- package/dist/v2/hooks/update-check.d.ts +10 -0
- package/dist/v2/hooks/update-check.d.ts.map +1 -0
- package/dist/v2/server.d.ts +3 -1
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +118582 -4
- package/dist/v2/store-reader.d.ts +2 -0
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/index.js +1 -0
- package/package.json +5 -4
- package/src/features/magic-context/dreamer/task-registry.ts +19 -0
- package/src/shared/harness.ts +2 -1
- package/src/shared/model-suggestion-retry.ts +66 -14
- package/src/shared/prompt-surface-runtime.ts +5 -1
- package/src/shared/rpc-types.ts +13 -0
- package/src/shared/status-detail-text.test.ts +26 -0
- package/src/shared/status-detail-text.ts +11 -0
- package/src/shared/status-summary.ts +2 -0
- package/src/shared/user-facing-codes.test.ts +1 -1
- package/src/shared/user-facing-codes.ts +10 -0
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
sessionLog,
|
|
6
6
|
getLoggerDiagnostics,
|
|
7
7
|
flushLogger
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-qp20p2py.js";
|
|
9
9
|
import {
|
|
10
10
|
withContentLanguageDirective,
|
|
11
11
|
buildPrimaryLanguageDirective,
|
|
@@ -71,6 +71,7 @@ import {
|
|
|
71
71
|
checksumAuthoritySeedRows,
|
|
72
72
|
prepareAuthority,
|
|
73
73
|
drainAuthority,
|
|
74
|
+
getMemoryMirrorStatus,
|
|
74
75
|
applyMirroredNoteCompileFields,
|
|
75
76
|
drainMirrorPages,
|
|
76
77
|
pullMemoryMirrorOnce,
|
|
@@ -191,6 +192,7 @@ import {
|
|
|
191
192
|
isToolPartWithOutput,
|
|
192
193
|
isFilePart,
|
|
193
194
|
buildFileSourceContent,
|
|
195
|
+
assertExecutableToolInput,
|
|
194
196
|
createDroppedInputToolExecuteBeforeHook,
|
|
195
197
|
isEditTool,
|
|
196
198
|
partHasCompletedResult,
|
|
@@ -359,6 +361,7 @@ import {
|
|
|
359
361
|
replaceSourceContent,
|
|
360
362
|
getSourceContents,
|
|
361
363
|
createChildSessionWithFence,
|
|
364
|
+
HiddenCompletionRefusal,
|
|
362
365
|
detectThinkingBindingMismatch,
|
|
363
366
|
isFable51ThinkingBindingModel,
|
|
364
367
|
detectOverflow,
|
|
@@ -472,6 +475,7 @@ import {
|
|
|
472
475
|
verificationFileExists,
|
|
473
476
|
normalizeVerificationFiles,
|
|
474
477
|
recordChildInvocation,
|
|
478
|
+
createV1HiddenCompletionExecutor,
|
|
475
479
|
USER_MEMORY_CANDIDATE_TTL_MS,
|
|
476
480
|
insertUserMemoryCandidates,
|
|
477
481
|
getUserMemoryCandidates,
|
|
@@ -522,6 +526,7 @@ import {
|
|
|
522
526
|
mustMaterialize,
|
|
523
527
|
trimMemoriesToBudgetV2,
|
|
524
528
|
renderMemoryBlockV2,
|
|
529
|
+
materializeM0,
|
|
525
530
|
prepareCachedM0M1Replay,
|
|
526
531
|
hasCompleteCachedM0M1,
|
|
527
532
|
injectM0M1,
|
|
@@ -542,7 +547,7 @@ import {
|
|
|
542
547
|
setRecompTerminal2,
|
|
543
548
|
runManagedRecomp2,
|
|
544
549
|
runManagedUpgrade2
|
|
545
|
-
} from "./index-
|
|
550
|
+
} from "./index-faay035c.js";
|
|
546
551
|
import {
|
|
547
552
|
stripJsonComments,
|
|
548
553
|
isPrototypePollutionKey,
|
|
@@ -568,7 +573,7 @@ import {
|
|
|
568
573
|
deriveHistorianChunkTokens2,
|
|
569
574
|
resolveKnownHistorianContextLimit2,
|
|
570
575
|
resolveHistorianContextLimit2
|
|
571
|
-
} from "./index-
|
|
576
|
+
} from "./index-f9gem5cr.js";
|
|
572
577
|
import {
|
|
573
578
|
resolveOpenCodeDbPath,
|
|
574
579
|
openCodeDbPathExists,
|
|
@@ -589,7 +594,7 @@ import {
|
|
|
589
594
|
assistantAwaitingTools,
|
|
590
595
|
getMessageTimesFromOpenCodeDb,
|
|
591
596
|
findLastAssistantModelFromOpenCodeDb
|
|
592
|
-
} from "./index-
|
|
597
|
+
} from "./index-jkrqhc7y.js";
|
|
593
598
|
import {
|
|
594
599
|
getErrorMessage,
|
|
595
600
|
describeError,
|
|
@@ -598,13 +603,13 @@ import {
|
|
|
598
603
|
clearIgnoredMessages2,
|
|
599
604
|
observeIgnoredNotificationEvent2,
|
|
600
605
|
sendStatusNotification2
|
|
601
|
-
} from "./index-
|
|
606
|
+
} from "./index-p474rw9p.js";
|
|
602
607
|
import {
|
|
603
608
|
detectConflicts,
|
|
604
609
|
resolveCompactionForBoot,
|
|
605
610
|
sendConflictWarning2,
|
|
606
611
|
cleanupConflictWarnings2
|
|
607
|
-
} from "./index-
|
|
612
|
+
} from "./index-d8mgqezq.js";
|
|
608
613
|
import {
|
|
609
614
|
resolveHistorianModel2,
|
|
610
615
|
resolveOpenCodeAgentOverrides2,
|
|
@@ -612,6 +617,7 @@ import {
|
|
|
612
617
|
} from "./index-7k55qm8a.js";
|
|
613
618
|
import {
|
|
614
619
|
CANONICAL_DREAM_TASKS,
|
|
620
|
+
DREAM_TASK_CAPABILITIES,
|
|
615
621
|
formatDreamTaskBacklogs,
|
|
616
622
|
processedDreamTaskItems,
|
|
617
623
|
leaseKindFor,
|
|
@@ -620,7 +626,7 @@ import {
|
|
|
620
626
|
compareTaskOrder,
|
|
621
627
|
buildDreamTaskRuntimeConfigs2,
|
|
622
628
|
userMemoryCollectionEnabled2
|
|
623
|
-
} from "./index-
|
|
629
|
+
} from "./index-bkg2fdj1.js";
|
|
624
630
|
import {
|
|
625
631
|
logSlowWriteTransaction,
|
|
626
632
|
getOrCreateSessionMeta2,
|
|
@@ -630,7 +636,7 @@ import {
|
|
|
630
636
|
retryPendingSessionCleanups2,
|
|
631
637
|
retryPendingRustSessionCleanupsForProject2,
|
|
632
638
|
clearSession2
|
|
633
|
-
} from "./index-
|
|
639
|
+
} from "./index-1ar7b3e9.js";
|
|
634
640
|
import {
|
|
635
641
|
registerNotificationSink2,
|
|
636
642
|
pushNotification2,
|
|
@@ -646,7 +652,7 @@ import {
|
|
|
646
652
|
ANNOUNCEMENT_FOOTER2,
|
|
647
653
|
markAnnouncementSeen2,
|
|
648
654
|
shouldShowAnnouncement2
|
|
649
|
-
} from "./index-
|
|
655
|
+
} from "./index-ntbmt6rq.js";
|
|
650
656
|
import {
|
|
651
657
|
resolvePromptContext2
|
|
652
658
|
} from "./index-fmsr7v69.js";
|
|
@@ -656,12 +662,13 @@ import {
|
|
|
656
662
|
modelRefLookupOrder
|
|
657
663
|
} from "./index-avwt563y.js";
|
|
658
664
|
import {
|
|
665
|
+
setHarness,
|
|
659
666
|
getHarness,
|
|
660
667
|
getDataDir,
|
|
661
668
|
getOpenCodeStorageDir,
|
|
662
669
|
getMagicContextStorageResolution,
|
|
663
670
|
getMagicContextStorageDir
|
|
664
|
-
} from "./index-
|
|
671
|
+
} from "./index-4ftb5hcq.js";
|
|
665
672
|
import {
|
|
666
673
|
__toESM,
|
|
667
674
|
__commonJS
|
|
@@ -12174,7 +12181,7 @@ var SERIAL_LANE_MAX_WAITERS = 16;
|
|
|
12174
12181
|
var SERIAL_LANE_MAX_WAITERS_PER_SESSION = 8;
|
|
12175
12182
|
var SERIAL_LANE_MIN_REMAINING_MS = 25;
|
|
12176
12183
|
var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
|
|
12177
|
-
function
|
|
12184
|
+
function getDefaultSubcConnectionFile() {
|
|
12178
12185
|
return join5(getDataDir(), "cortexkit", "run", "subc-connection.json");
|
|
12179
12186
|
}
|
|
12180
12187
|
function errorChainSome(error, predicate) {
|
|
@@ -12289,7 +12296,7 @@ class SubcModuleTransport {
|
|
|
12289
12296
|
return capabilities;
|
|
12290
12297
|
}
|
|
12291
12298
|
constructor(connectionFile, moduleId = DEFAULT_MODULE_ID, requestTimeoutMs = MODULE_SEND_TIMEOUT_MS, routeSessionPrefix = "") {
|
|
12292
|
-
this.connectionFile = connectionFile
|
|
12299
|
+
this.connectionFile = connectionFile;
|
|
12293
12300
|
this.moduleId = moduleId;
|
|
12294
12301
|
this.requestTimeoutMs = requestTimeoutMs;
|
|
12295
12302
|
this.routeSessionPrefix = routeSessionPrefix;
|
|
@@ -12567,8 +12574,8 @@ class SubcModuleTransport {
|
|
|
12567
12574
|
}
|
|
12568
12575
|
async authorityStatus(args) {
|
|
12569
12576
|
this.authorityProjectRoot = args.project;
|
|
12570
|
-
const { projectRoot, ...body } = args;
|
|
12571
|
-
const response = await this.authorityRequest(args.project, projectRoot ?? this.bindRootForAuthority(), "authority.status", body);
|
|
12577
|
+
const { projectRoot, sessionId, ...body } = args;
|
|
12578
|
+
const response = await this.authorityRequest(sessionId ?? args.project, projectRoot ?? this.bindRootForAuthority(), "authority.status", body);
|
|
12572
12579
|
return { authority: response.authority ?? null };
|
|
12573
12580
|
}
|
|
12574
12581
|
async authorityPrepare(args) {
|
|
@@ -14041,6 +14048,8 @@ function isTimeoutClassError(error) {
|
|
|
14041
14048
|
}
|
|
14042
14049
|
async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
14043
14050
|
let agentSessionId = null;
|
|
14051
|
+
let handle = null;
|
|
14052
|
+
const executor = args.hiddenCompletionExecutor ?? createV1HiddenCompletionExecutor(args.client, args.db, args.sessionDirectory);
|
|
14044
14053
|
let promptSettled = false;
|
|
14045
14054
|
const startedAt = Date.now();
|
|
14046
14055
|
try {
|
|
@@ -14048,19 +14057,22 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
14048
14057
|
projectPath: args.projectIdentity,
|
|
14049
14058
|
memories: chunk.map(toPromptMemory)
|
|
14050
14059
|
});
|
|
14051
|
-
|
|
14052
|
-
client: args.client,
|
|
14053
|
-
db: args.db,
|
|
14060
|
+
handle = await executor.open({
|
|
14054
14061
|
parentSessionId: args.parentSessionId,
|
|
14062
|
+
agent: DREAMER_CLASSIFIER_AGENT,
|
|
14063
|
+
kind: "dreamer-task",
|
|
14064
|
+
system: COMPRESS_CUES_SYSTEM_PROMPT,
|
|
14065
|
+
model: args.model,
|
|
14066
|
+
configuredModels: [...args.model ? [args.model] : [], ...args.fallbackModels ?? []],
|
|
14067
|
+
timeoutMs: sliceMs,
|
|
14055
14068
|
title: "magic-context-dream-compress-cues",
|
|
14056
|
-
directory: args.sessionDirectory
|
|
14069
|
+
directory: args.sessionDirectory,
|
|
14070
|
+
metadata: { task: "compress-cues" }
|
|
14057
14071
|
});
|
|
14058
|
-
|
|
14059
|
-
preferResponseOnMissingData: true
|
|
14060
|
-
});
|
|
14061
|
-
agentSessionId = typeof created?.id === "string" ? created.id : null;
|
|
14072
|
+
agentSessionId = handle.id || null;
|
|
14062
14073
|
if (!agentSessionId)
|
|
14063
14074
|
throw new Error("Could not create compress-cues session.");
|
|
14075
|
+
const opened = handle;
|
|
14064
14076
|
const run = await promptSyncWithValidatedOutputRetry(args.client, {
|
|
14065
14077
|
path: { id: agentSessionId },
|
|
14066
14078
|
query: { directory: args.sessionDirectory },
|
|
@@ -14071,24 +14083,18 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
14071
14083
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
14072
14084
|
}
|
|
14073
14085
|
}, {
|
|
14086
|
+
transport: Object.assign((request) => executor.attempt(opened, request), { childSessionId: opened.childSessionId }),
|
|
14074
14087
|
timeoutMs: sliceMs,
|
|
14075
14088
|
signal,
|
|
14076
14089
|
fallbackModels: args.fallbackModels,
|
|
14077
14090
|
callContext: "dreamer:compress-cues",
|
|
14078
|
-
fetchOutput:
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
|
|
14082
|
-
});
|
|
14083
|
-
return normalizeSDKResponse(messagesResponse, [], {
|
|
14084
|
-
preferResponseOnMissingData: true
|
|
14085
|
-
});
|
|
14086
|
-
},
|
|
14087
|
-
validateOutput: (messages) => {
|
|
14088
|
-
if (hasLengthCappedOutput(messages)) {
|
|
14091
|
+
fetchOutput: () => executor.collect(opened, 50),
|
|
14092
|
+
validateOutput: (completion) => {
|
|
14093
|
+
const messages = completion.messages ?? [];
|
|
14094
|
+
if (completion.lengthCapped) {
|
|
14089
14095
|
throw new Error("compress-cues returned length-capped output");
|
|
14090
14096
|
}
|
|
14091
|
-
const text =
|
|
14097
|
+
const text = completion.text;
|
|
14092
14098
|
if (!text)
|
|
14093
14099
|
throw new Error("compress-cues returned no output");
|
|
14094
14100
|
try {
|
|
@@ -14103,11 +14109,25 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
14103
14109
|
}
|
|
14104
14110
|
});
|
|
14105
14111
|
promptSettled = true;
|
|
14112
|
+
if (args.hiddenCompletionExecutor && args.parentSessionId) {
|
|
14113
|
+
recordChildInvocation({
|
|
14114
|
+
db: args.db,
|
|
14115
|
+
parentSessionId: args.parentSessionId,
|
|
14116
|
+
harness: executor.capabilities.harness,
|
|
14117
|
+
subagent: "dreamer",
|
|
14118
|
+
task: "compress-cues",
|
|
14119
|
+
startedAt,
|
|
14120
|
+
status: "completed",
|
|
14121
|
+
tokens: run.output.usage,
|
|
14122
|
+
providerId: run.output.providerId,
|
|
14123
|
+
modelId: run.output.modelId
|
|
14124
|
+
});
|
|
14125
|
+
}
|
|
14106
14126
|
return args.moduleRoute ? await applyCuesThroughModule(args, chunk, run.validated, signal) : applyCues(args, chunk, run.validated);
|
|
14107
14127
|
} catch (error) {
|
|
14108
14128
|
const desc = describeError(error);
|
|
14109
14129
|
log(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
14110
|
-
if (signal.aborted || error instanceof DreamerProviderOutputFailureError)
|
|
14130
|
+
if (signal.aborted || error instanceof HiddenCompletionRefusal || error instanceof DreamerProviderOutputFailureError)
|
|
14111
14131
|
throw error;
|
|
14112
14132
|
return {
|
|
14113
14133
|
compressed: 0,
|
|
@@ -14119,10 +14139,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
14119
14139
|
}
|
|
14120
14140
|
};
|
|
14121
14141
|
} finally {
|
|
14122
|
-
await
|
|
14123
|
-
client: args.client,
|
|
14124
|
-
sessionId: agentSessionId,
|
|
14125
|
-
sessionDirectory: args.sessionDirectory,
|
|
14142
|
+
await executor.close(handle, {
|
|
14126
14143
|
promptSettled,
|
|
14127
14144
|
privacySensitive: true,
|
|
14128
14145
|
context: "[dreamer] compress-cues",
|
|
@@ -14777,6 +14794,8 @@ async function runClassify(args) {
|
|
|
14777
14794
|
}
|
|
14778
14795
|
async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
14779
14796
|
let agentSessionId = null;
|
|
14797
|
+
let handle = null;
|
|
14798
|
+
const executor = args.hiddenCompletionExecutor ?? createV1HiddenCompletionExecutor(args.client, args.db, args.sessionDirectory);
|
|
14780
14799
|
let promptSettled = false;
|
|
14781
14800
|
const startedAt = Date.now();
|
|
14782
14801
|
const moduleRoute = isModuleRoute(args);
|
|
@@ -14791,19 +14810,22 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
|
14791
14810
|
recordInvocation(args, startedAt, { status: "completed" });
|
|
14792
14811
|
return run;
|
|
14793
14812
|
}
|
|
14794
|
-
|
|
14795
|
-
client: args.client,
|
|
14796
|
-
db: args.db,
|
|
14813
|
+
handle = await executor.open({
|
|
14797
14814
|
parentSessionId: args.parentSessionId,
|
|
14815
|
+
agent: DREAMER_CLASSIFIER_AGENT,
|
|
14816
|
+
kind: "dreamer-task",
|
|
14817
|
+
system: withContentLanguageDirective(CLASSIFY_SYSTEM_PROMPT, args.language),
|
|
14818
|
+
model: args.model,
|
|
14819
|
+
configuredModels: [...args.model ? [args.model] : [], ...args.fallbackModels ?? []],
|
|
14820
|
+
timeoutMs: sliceMs,
|
|
14798
14821
|
title: "magic-context-dream-classify",
|
|
14799
|
-
directory: args.sessionDirectory
|
|
14800
|
-
|
|
14801
|
-
const created = normalizeSDKResponse(createResponse, null, {
|
|
14802
|
-
preferResponseOnMissingData: true
|
|
14822
|
+
directory: args.sessionDirectory,
|
|
14823
|
+
metadata: { task: "classify-memories" }
|
|
14803
14824
|
});
|
|
14804
|
-
agentSessionId =
|
|
14825
|
+
agentSessionId = handle.id || null;
|
|
14805
14826
|
if (!agentSessionId)
|
|
14806
14827
|
throw new Error("Could not create classify session.");
|
|
14828
|
+
const opened = handle;
|
|
14807
14829
|
const run = await promptSyncWithValidatedOutputRetry(args.client, {
|
|
14808
14830
|
path: { id: agentSessionId },
|
|
14809
14831
|
query: { directory: args.sessionDirectory },
|
|
@@ -14814,24 +14836,18 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
|
14814
14836
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
14815
14837
|
}
|
|
14816
14838
|
}, {
|
|
14839
|
+
transport: Object.assign((request) => executor.attempt(opened, request), { childSessionId: opened.childSessionId }),
|
|
14817
14840
|
timeoutMs: sliceMs,
|
|
14818
14841
|
signal,
|
|
14819
14842
|
fallbackModels: args.fallbackModels,
|
|
14820
14843
|
callContext: "dreamer:classify-memories",
|
|
14821
|
-
fetchOutput:
|
|
14822
|
-
|
|
14823
|
-
|
|
14824
|
-
|
|
14825
|
-
});
|
|
14826
|
-
return normalizeSDKResponse(messagesResponse, [], {
|
|
14827
|
-
preferResponseOnMissingData: true
|
|
14828
|
-
});
|
|
14829
|
-
},
|
|
14830
|
-
validateOutput: (messages) => {
|
|
14831
|
-
if (hasLengthCappedOutput(messages)) {
|
|
14844
|
+
fetchOutput: () => executor.collect(opened, 50),
|
|
14845
|
+
validateOutput: (completion) => {
|
|
14846
|
+
const messages = completion.messages ?? [];
|
|
14847
|
+
if (completion.lengthCapped) {
|
|
14832
14848
|
throw new Error("classify returned length-capped output");
|
|
14833
14849
|
}
|
|
14834
|
-
const text =
|
|
14850
|
+
const text = completion.text;
|
|
14835
14851
|
if (!text)
|
|
14836
14852
|
throw new Error("classify returned no output");
|
|
14837
14853
|
try {
|
|
@@ -14846,21 +14862,22 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
|
14846
14862
|
}
|
|
14847
14863
|
});
|
|
14848
14864
|
promptSettled = true;
|
|
14849
|
-
recordInvocation(args, startedAt, {
|
|
14865
|
+
recordInvocation(args, startedAt, {
|
|
14866
|
+
status: "completed",
|
|
14867
|
+
messages: run.output.messages,
|
|
14868
|
+
completion: run.output
|
|
14869
|
+
});
|
|
14850
14870
|
return applyClassifications(args, chunk.map((candidate) => candidate.contextMemory), run.validated);
|
|
14851
14871
|
} catch (error) {
|
|
14852
14872
|
const failure = moduleRoute ? new ClassifyModuleFailureError("module", error) : error;
|
|
14853
14873
|
const desc = describeError(failure);
|
|
14854
14874
|
log(`[dreamer] classify chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
14855
14875
|
recordInvocation(args, startedAt, { status: "failed", error: failure });
|
|
14856
|
-
if (moduleRoute || signal.aborted || failure instanceof DreamerProviderOutputFailureError || getPromptFailureDetail(failure)?.failureClass !== "parse_failed" && getPromptFailureDetail(failure) !== null)
|
|
14876
|
+
if (moduleRoute || failure instanceof HiddenCompletionRefusal || signal.aborted || failure instanceof DreamerProviderOutputFailureError || getPromptFailureDetail(failure)?.failureClass !== "parse_failed" && getPromptFailureDetail(failure) !== null)
|
|
14857
14877
|
throw failure;
|
|
14858
14878
|
return { classified: 0, changed: 0 };
|
|
14859
14879
|
} finally {
|
|
14860
|
-
await
|
|
14861
|
-
client: args.client,
|
|
14862
|
-
sessionId: agentSessionId,
|
|
14863
|
-
sessionDirectory: args.sessionDirectory,
|
|
14880
|
+
await executor.close(handle, {
|
|
14864
14881
|
promptSettled,
|
|
14865
14882
|
privacySensitive: true,
|
|
14866
14883
|
context: "[dreamer] classify",
|
|
@@ -15014,12 +15031,17 @@ function recordInvocation(args, startedAt, params) {
|
|
|
15014
15031
|
recordChildInvocation({
|
|
15015
15032
|
db: args.db,
|
|
15016
15033
|
parentSessionId: args.parentSessionId,
|
|
15017
|
-
harness: "opencode",
|
|
15034
|
+
harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
|
|
15018
15035
|
subagent: "dreamer",
|
|
15019
15036
|
task: "classify-memories",
|
|
15020
15037
|
startedAt,
|
|
15021
15038
|
status: params.status,
|
|
15022
15039
|
messages: params.messages,
|
|
15040
|
+
...params.completion && !params.completion.messages ? {
|
|
15041
|
+
tokens: params.completion.usage,
|
|
15042
|
+
providerId: params.completion.providerId,
|
|
15043
|
+
modelId: params.completion.modelId
|
|
15044
|
+
} : {},
|
|
15023
15045
|
error: params.error
|
|
15024
15046
|
});
|
|
15025
15047
|
}
|
|
@@ -19156,7 +19178,7 @@ function dreamRunFailureDetail(error) {
|
|
|
19156
19178
|
}
|
|
19157
19179
|
const described = describeError(error);
|
|
19158
19180
|
const message = described.brief;
|
|
19159
|
-
const providerFailure = error instanceof Error && error.name === "DreamerProviderOutputFailureError";
|
|
19181
|
+
const providerFailure = error instanceof HiddenCompletionRefusal || error instanceof Error && error.name === "DreamerProviderOutputFailureError";
|
|
19160
19182
|
return {
|
|
19161
19183
|
failure_class: providerFailure ? "provider_error" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
|
|
19162
19184
|
model_attempted: null,
|
|
@@ -19246,13 +19268,20 @@ function formatCurateMemoryOperations(actions) {
|
|
|
19246
19268
|
const noun = actions.length === 1 ? "operation" : "operations";
|
|
19247
19269
|
return `curate: ${actions.length} memory ${noun} applied${actionDetail ? ` (${actionDetail})` : ""}`;
|
|
19248
19270
|
}
|
|
19271
|
+
function requireDreamClient(client) {
|
|
19272
|
+
if (!client)
|
|
19273
|
+
throw new HiddenCompletionRefusal("hidden_tools_unsupported", "This dream task requires the child-session tool transport", true);
|
|
19274
|
+
return client;
|
|
19275
|
+
}
|
|
19249
19276
|
function createDreamTaskExecutor(deps) {
|
|
19250
19277
|
let parentSessionIdPromise;
|
|
19251
19278
|
const resolveParentSessionId = () => {
|
|
19279
|
+
if (deps.hiddenCompletionExecutor)
|
|
19280
|
+
return Promise.resolve(deps.parentSessionId);
|
|
19252
19281
|
if (!parentSessionIdPromise) {
|
|
19253
19282
|
parentSessionIdPromise = (async () => {
|
|
19254
19283
|
try {
|
|
19255
|
-
const listResponse = await deps.client.session.list({
|
|
19284
|
+
const listResponse = await requireDreamClient(deps.client).session.list({
|
|
19256
19285
|
query: { directory: deps.sessionDirectory }
|
|
19257
19286
|
});
|
|
19258
19287
|
const sessions = normalizeSDKResponse(listResponse, [], { preferResponseOnMissingData: true });
|
|
@@ -19366,6 +19395,9 @@ function createDreamTaskExecutor(deps) {
|
|
|
19366
19395
|
return writtenIds.length || deletedIds.length || archivedIds.length || mergedIds.length ? changes : null;
|
|
19367
19396
|
}
|
|
19368
19397
|
try {
|
|
19398
|
+
if (deps.hiddenCompletionExecutor?.capabilities.tools === false && DREAM_TASK_CAPABILITIES[config.task].requiresTools) {
|
|
19399
|
+
throw new HiddenCompletionRefusal("hidden_tools_unsupported", `${config.task} requires tools; opencode2 hidden completions have no tool loop`, true);
|
|
19400
|
+
}
|
|
19369
19401
|
if (config.task === "compress-cues") {
|
|
19370
19402
|
if (deps.mural?.enabled !== true) {
|
|
19371
19403
|
log("[dreamer] compress-cues: skipped (mural is not enabled)");
|
|
@@ -19375,6 +19407,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19375
19407
|
const result = await runCompressCues({
|
|
19376
19408
|
db,
|
|
19377
19409
|
client: deps.client,
|
|
19410
|
+
hiddenCompletionExecutor: deps.hiddenCompletionExecutor,
|
|
19378
19411
|
projectIdentity,
|
|
19379
19412
|
parentSessionId: parent,
|
|
19380
19413
|
sessionDirectory: deps.sessionDirectory,
|
|
@@ -19399,7 +19432,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19399
19432
|
if (config.task === "review-user-memories") {
|
|
19400
19433
|
const result = await reviewUserMemories({
|
|
19401
19434
|
db,
|
|
19402
|
-
client: deps.client,
|
|
19435
|
+
client: requireDreamClient(deps.client),
|
|
19403
19436
|
parentSessionId: parent,
|
|
19404
19437
|
sessionDirectory: deps.sessionDirectory,
|
|
19405
19438
|
holderId,
|
|
@@ -19418,7 +19451,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19418
19451
|
if (config.task === "map-memories") {
|
|
19419
19452
|
const result = await mapMemories({
|
|
19420
19453
|
db,
|
|
19421
|
-
client: deps.client,
|
|
19454
|
+
client: requireDreamClient(deps.client),
|
|
19422
19455
|
projectIdentity,
|
|
19423
19456
|
parentSessionId: parent,
|
|
19424
19457
|
sessionDirectory: deps.sessionDirectory,
|
|
@@ -19455,7 +19488,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19455
19488
|
const memoryBefore = getMemoryCountsByStatus(db, projectIdentity);
|
|
19456
19489
|
const result = await runVerify({
|
|
19457
19490
|
db,
|
|
19458
|
-
client: deps.client,
|
|
19491
|
+
client: requireDreamClient(deps.client),
|
|
19459
19492
|
projectIdentity,
|
|
19460
19493
|
parentSessionId: parent,
|
|
19461
19494
|
sessionDirectory: deps.sessionDirectory,
|
|
@@ -19513,6 +19546,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19513
19546
|
const result = await runClassify({
|
|
19514
19547
|
db,
|
|
19515
19548
|
client: deps.client,
|
|
19549
|
+
hiddenCompletionExecutor: deps.hiddenCompletionExecutor,
|
|
19516
19550
|
projectIdentity,
|
|
19517
19551
|
parentSessionId: parent,
|
|
19518
19552
|
sessionDirectory: deps.sessionDirectory,
|
|
@@ -19538,7 +19572,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19538
19572
|
if (config.task === "promote-primers") {
|
|
19539
19573
|
const result = await promotePrimers({
|
|
19540
19574
|
db,
|
|
19541
|
-
client: deps.client,
|
|
19575
|
+
client: requireDreamClient(deps.client),
|
|
19542
19576
|
projectIdentity,
|
|
19543
19577
|
sessionDirectory: deps.sessionDirectory,
|
|
19544
19578
|
holderId,
|
|
@@ -19555,7 +19589,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19555
19589
|
if (config.task === "refresh-primers") {
|
|
19556
19590
|
const result = await refreshPrimers({
|
|
19557
19591
|
db,
|
|
19558
|
-
client: deps.client,
|
|
19592
|
+
client: requireDreamClient(deps.client),
|
|
19559
19593
|
projectIdentity,
|
|
19560
19594
|
parentSessionId: parent,
|
|
19561
19595
|
sessionDirectory: deps.sessionDirectory,
|
|
@@ -19576,7 +19610,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
19576
19610
|
if (config.task === "evaluate-smart-notes") {
|
|
19577
19611
|
const result = await evaluateSmartNotes({
|
|
19578
19612
|
db,
|
|
19579
|
-
client: deps.client,
|
|
19613
|
+
client: requireDreamClient(deps.client),
|
|
19580
19614
|
projectIdentity,
|
|
19581
19615
|
parentSessionId: parent,
|
|
19582
19616
|
sessionDirectory: deps.sessionDirectory,
|
|
@@ -19743,7 +19777,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
|
|
|
19743
19777
|
let promptSettled = false;
|
|
19744
19778
|
try {
|
|
19745
19779
|
const createResponse = await createChildSessionWithFence({
|
|
19746
|
-
client: deps.client,
|
|
19780
|
+
client: requireDreamClient(deps.client),
|
|
19747
19781
|
db,
|
|
19748
19782
|
parentSessionId: parent ?? undefined,
|
|
19749
19783
|
title: "magic-context-dream-retrospective",
|
|
@@ -19757,7 +19791,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
|
|
|
19757
19791
|
const runChildTurn = async (system, userText) => {
|
|
19758
19792
|
const remainingMs = Math.max(0, deadline - Date.now());
|
|
19759
19793
|
promptSettled = false;
|
|
19760
|
-
const run = await promptSyncWithValidatedOutputRetry(deps.client, {
|
|
19794
|
+
const run = await promptSyncWithValidatedOutputRetry(requireDreamClient(deps.client), {
|
|
19761
19795
|
path: { id: sessionId },
|
|
19762
19796
|
query: { directory: deps.sessionDirectory },
|
|
19763
19797
|
body: {
|
|
@@ -19772,7 +19806,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
|
|
|
19772
19806
|
fallbackModels: config.fallbackModels,
|
|
19773
19807
|
callContext: "dreamer:retrospective",
|
|
19774
19808
|
fetchOutput: async () => {
|
|
19775
|
-
const messagesResponse = await deps.client.session.messages({
|
|
19809
|
+
const messagesResponse = await requireDreamClient(deps.client).session.messages({
|
|
19776
19810
|
path: { id: sessionId },
|
|
19777
19811
|
query: { directory: deps.sessionDirectory, limit: 50 }
|
|
19778
19812
|
});
|
|
@@ -19897,7 +19931,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
|
|
|
19897
19931
|
} finally {
|
|
19898
19932
|
heartbeat.stop();
|
|
19899
19933
|
await teardownChildSession({
|
|
19900
|
-
client: deps.client,
|
|
19934
|
+
client: requireDreamClient(deps.client),
|
|
19901
19935
|
sessionId: childSessionId,
|
|
19902
19936
|
sessionDirectory: deps.sessionDirectory,
|
|
19903
19937
|
promptSettled,
|
|
@@ -19960,7 +19994,7 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
19960
19994
|
curate: curateMemories ? { memories: curateMemories } : undefined
|
|
19961
19995
|
});
|
|
19962
19996
|
const createResponse = await createChildSessionWithFence({
|
|
19963
|
-
client: deps.client,
|
|
19997
|
+
client: requireDreamClient(deps.client),
|
|
19964
19998
|
db,
|
|
19965
19999
|
parentSessionId: parent ?? undefined,
|
|
19966
20000
|
title: `magic-context-dream-${task}`,
|
|
@@ -19974,7 +20008,7 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
19974
20008
|
throw new Error("Dreamer could not create its child session.");
|
|
19975
20009
|
const sessionId = childSessionId;
|
|
19976
20010
|
const remainingMs = Math.max(0, deadline - Date.now());
|
|
19977
|
-
const run = await promptSyncWithValidatedOutputRetry(deps.client, {
|
|
20011
|
+
const run = await promptSyncWithValidatedOutputRetry(requireDreamClient(deps.client), {
|
|
19978
20012
|
path: { id: sessionId },
|
|
19979
20013
|
query: { directory: docsDir },
|
|
19980
20014
|
body: {
|
|
@@ -19989,7 +20023,7 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
19989
20023
|
fallbackModels: config.fallbackModels,
|
|
19990
20024
|
callContext: `dreamer:${task}`,
|
|
19991
20025
|
fetchOutput: async () => {
|
|
19992
|
-
const messagesResponse = await deps.client.session.messages({
|
|
20026
|
+
const messagesResponse = await requireDreamClient(deps.client).session.messages({
|
|
19993
20027
|
path: { id: sessionId },
|
|
19994
20028
|
query: {
|
|
19995
20029
|
directory: docsDir,
|
|
@@ -20064,7 +20098,7 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
20064
20098
|
if (childSessionId)
|
|
20065
20099
|
takeCurateSafetyRefusalCount(childSessionId);
|
|
20066
20100
|
await teardownChildSession({
|
|
20067
|
-
client: deps.client,
|
|
20101
|
+
client: requireDreamClient(deps.client),
|
|
20068
20102
|
sessionId: childSessionId,
|
|
20069
20103
|
sessionDirectory: docsDir,
|
|
20070
20104
|
promptSettled,
|
|
@@ -24972,6 +25006,10 @@ function statusSummaryFromDetail(detail) {
|
|
|
24972
25006
|
if ((detail.loggerDiagnostics?.swallowedWriteCount ?? 0) > 0) {
|
|
24973
25007
|
warnings.push("status_log_unavailable");
|
|
24974
25008
|
}
|
|
25009
|
+
if (detail.memoryMirror?.stalled)
|
|
25010
|
+
warnings.push("memory_mirror_stalled");
|
|
25011
|
+
if (detail.memoryAuthorityMismatch)
|
|
25012
|
+
warnings.push("memory_authority_mismatch");
|
|
24975
25013
|
return {
|
|
24976
25014
|
inputTokens: detail.inputTokens,
|
|
24977
25015
|
usableContextTokens: detail.contextLimit,
|
|
@@ -25108,6 +25146,9 @@ function formatStatusDiagnosticsMarkdown(detail) {
|
|
|
25108
25146
|
`- **${formatCacheTtlDisplay({ value: detail.cacheTtl, source: detail.cacheTtlSource ?? "session", modelKey: detail.cacheTtlModelKey })}**; ${formatCacheLane(detail)}`,
|
|
25109
25147
|
`- **Historian:** ${[historianState, ...historianDetails].join("; ")}`,
|
|
25110
25148
|
...detail.hostBackendsModuleSide ? [`- ${RUST_MODE_HOST_PATHS_LINE}`] : [],
|
|
25149
|
+
...detail.memoryMirror ? [
|
|
25150
|
+
`- **Memory mirror:** cursor ${formatCount2(detail.memoryMirror.cursor)} / ${detail.memoryMirror.feedHead === null ? "unknown" : formatCount2(detail.memoryMirror.feedHead)}; ${formatCount2(detail.memoryMirror.liveRows)} live rows; ${detail.memoryMirror.stalled ? `stalled (${detail.memoryMirror.code})` : "advancing or caught up"}`
|
|
25151
|
+
] : [],
|
|
25111
25152
|
`- **Memory:** ${formatCount2(detail.memoryCount)} active; ${formatCount2(detail.memoryBlockCount)} injected`,
|
|
25112
25153
|
`- **Tags:** ${formatCount2(detail.activeTags)} active, ${formatCount2(detail.droppedTags)} dropped; ${formatCount2(detail.pendingOpsCount)} pending drops`,
|
|
25113
25154
|
`- **Execute threshold:** ${detail.executeThreshold.toFixed(1)}%${detail.executeThresholdClamped ? " (clamped)" : ""}`
|
|
@@ -25118,6 +25159,12 @@ function formatStatusDiagnosticsMarkdown(detail) {
|
|
|
25118
25159
|
if (detail.lastTransformError) {
|
|
25119
25160
|
lines.push(`- **Warning:** ${renderUserFacingFailure("transform_update_failed")}`);
|
|
25120
25161
|
}
|
|
25162
|
+
if (detail.memoryMirror?.stalled) {
|
|
25163
|
+
lines.push(`- **Warning:** ${renderUserFacingFailure("memory_mirror_stalled")}`);
|
|
25164
|
+
}
|
|
25165
|
+
if (detail.memoryAuthorityMismatch) {
|
|
25166
|
+
lines.push(`- **Warning:** ${renderUserFacingFailure("memory_authority_mismatch")}`);
|
|
25167
|
+
}
|
|
25121
25168
|
return lines.join(`
|
|
25122
25169
|
`);
|
|
25123
25170
|
}
|
|
@@ -29005,9 +29052,16 @@ function buildSidebarSnapshotRpcResponse(db, sessionId, directory, liveSessionSt
|
|
|
29005
29052
|
}
|
|
29006
29053
|
function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessionState, injectionBudgetTokens, moduleStatus, compactionEnabled = true) {
|
|
29007
29054
|
const base = buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled);
|
|
29055
|
+
const rustMode = config?.transform_mode === "rust";
|
|
29056
|
+
const projectIdentity = rustMode ? resolveProjectIdentity(directory) : null;
|
|
29057
|
+
const moduleMemoryAuthority = moduleStatus?.authority?.memories;
|
|
29058
|
+
const moduleMemoryState = moduleMemoryAuthority?.state;
|
|
29059
|
+
const moduleFeedHead = moduleStatus?.memory_mirror?.feed_head;
|
|
29008
29060
|
const detail = {
|
|
29009
29061
|
...base,
|
|
29010
|
-
hostBackendsModuleSide:
|
|
29062
|
+
hostBackendsModuleSide: rustMode,
|
|
29063
|
+
memoryMirror: rustMode ? getMemoryMirrorStatus(db, moduleFeedHead) : undefined,
|
|
29064
|
+
memoryAuthorityMismatch: rustMode && moduleStatus?.authority !== undefined && projectIdentity !== null && getAuthorityManagedMarker(db, projectIdentity) !== null && (moduleMemoryState === "TS" || moduleMemoryAuthority === null),
|
|
29011
29065
|
activeProfile: typeof config?.profile === "string" ? config.profile : null,
|
|
29012
29066
|
tagCounter: 0,
|
|
29013
29067
|
activeTags: 0,
|
|
@@ -29461,9 +29515,9 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
29461
29515
|
return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
|
|
29462
29516
|
});
|
|
29463
29517
|
const buildManagedCtx = async (db) => {
|
|
29464
|
-
const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await import("./derive-budgets-
|
|
29518
|
+
const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await import("./derive-budgets-v1fkhjjr.js");
|
|
29465
29519
|
const { resolveHistorianModel } = await import("./model-resolution-dxatzjde.js");
|
|
29466
|
-
const { userMemoryCollectionEnabled } = await import("./task-config-
|
|
29520
|
+
const { userMemoryCollectionEnabled } = await import("./task-config-ys0arma5.js");
|
|
29467
29521
|
const DEFAULT_HISTORIAN_TIMEOUT_MS = 600000;
|
|
29468
29522
|
const historianModel = resolveHistorianModel(config, "opencode");
|
|
29469
29523
|
return {
|
|
@@ -29494,8 +29548,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
29494
29548
|
const db = getDb();
|
|
29495
29549
|
if (!db)
|
|
29496
29550
|
return { ok: false, error: "db unavailable" };
|
|
29497
|
-
const { runManagedRecomp } = await import("./recomp-orchestrator-
|
|
29498
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
29551
|
+
const { runManagedRecomp } = await import("./recomp-orchestrator-c4sa354a.js");
|
|
29552
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-xnypkxpx.js");
|
|
29499
29553
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
29500
29554
|
const ctx = await buildManagedCtx(db);
|
|
29501
29555
|
runManagedRecomp(ctx, sessionId).then((message) => {
|
|
@@ -29513,8 +29567,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
29513
29567
|
const db = getDb();
|
|
29514
29568
|
if (!db)
|
|
29515
29569
|
return { ok: false, error: "db unavailable" };
|
|
29516
|
-
const { runManagedUpgrade } = await import("./recomp-orchestrator-
|
|
29517
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
29570
|
+
const { runManagedUpgrade } = await import("./recomp-orchestrator-c4sa354a.js");
|
|
29571
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-xnypkxpx.js");
|
|
29518
29572
|
log(`[rpc] session-upgrade requested for session ${sessionId}`);
|
|
29519
29573
|
const ctx = await buildManagedCtx(db);
|
|
29520
29574
|
runManagedUpgrade(ctx, sessionId).then((message) => {
|
|
@@ -29530,7 +29584,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
29530
29584
|
if (!db)
|
|
29531
29585
|
return { ok: false, error: "db unavailable" };
|
|
29532
29586
|
try {
|
|
29533
|
-
const { updateSessionMeta } = await import("./storage-meta-session-
|
|
29587
|
+
const { updateSessionMeta } = await import("./storage-meta-session-x3j0q9qy.js");
|
|
29534
29588
|
updateSessionMeta(db, sessionId, { upgradeRemindedAt: Date.now() });
|
|
29535
29589
|
return { ok: true };
|
|
29536
29590
|
} catch (error) {
|
|
@@ -30179,7 +30233,8 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config) {
|
|
|
30179
30233
|
compressedToLite: 0,
|
|
30180
30234
|
compressedToFull: 0,
|
|
30181
30235
|
compressedToUltra: 0,
|
|
30182
|
-
mutatedTextTags: 0
|
|
30236
|
+
mutatedTextTags: 0,
|
|
30237
|
+
textReductions: []
|
|
30183
30238
|
};
|
|
30184
30239
|
if (!config.enabled)
|
|
30185
30240
|
return result;
|
|
@@ -30219,9 +30274,15 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config) {
|
|
|
30219
30274
|
const target = targets.get(tag.tagNumber);
|
|
30220
30275
|
if (!target)
|
|
30221
30276
|
continue;
|
|
30277
|
+
const priorContent = target.getContent?.();
|
|
30222
30278
|
const didMutate = target.setContent(compressed);
|
|
30223
|
-
if (didMutate)
|
|
30279
|
+
if (didMutate) {
|
|
30224
30280
|
result.mutatedTextTags += 1;
|
|
30281
|
+
result.textReductions.push({
|
|
30282
|
+
tagNumber: tag.tagNumber,
|
|
30283
|
+
removedCharacters: Math.max(0, (priorContent?.length ?? originalText.length) - compressed.length)
|
|
30284
|
+
});
|
|
30285
|
+
}
|
|
30225
30286
|
updateCavemanDepth(db, sessionId, tag.tagNumber, targetDepth);
|
|
30226
30287
|
if (targetDepth === DEPTH_LITE)
|
|
30227
30288
|
result.compressedToLite += 1;
|
|
@@ -32018,6 +32079,73 @@ function dropStaleReduceCalls(messages, frozenIds, options = {}) {
|
|
|
32018
32079
|
return { didDrop, newlyStrippedIds };
|
|
32019
32080
|
}
|
|
32020
32081
|
|
|
32082
|
+
// src/hooks/magic-context/dropped-token-estimate.ts
|
|
32083
|
+
var TAG_QUERY_CHUNK_SIZE = 900;
|
|
32084
|
+
var ESTIMATED_CHARACTERS_PER_TOKEN = 3.5;
|
|
32085
|
+
function estimateCharacters(characters) {
|
|
32086
|
+
return Math.ceil(Math.max(0, characters) / ESTIMATED_CHARACTERS_PER_TOKEN);
|
|
32087
|
+
}
|
|
32088
|
+
function persistedCountOrByteEstimate(count, bytes) {
|
|
32089
|
+
return typeof count === "number" && Number.isFinite(count) ? Math.max(0, count) : estimateCharacters(bytes);
|
|
32090
|
+
}
|
|
32091
|
+
function loadPersistedTagTokenCounts(db, sessionId, tagNumbers) {
|
|
32092
|
+
const countsByTag = new Map;
|
|
32093
|
+
for (let offset = 0;offset < tagNumbers.length; offset += TAG_QUERY_CHUNK_SIZE) {
|
|
32094
|
+
const chunk = tagNumbers.slice(offset, offset + TAG_QUERY_CHUNK_SIZE);
|
|
32095
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
32096
|
+
const rows = db.prepare(`SELECT tag_number AS tagNumber,
|
|
32097
|
+
type,
|
|
32098
|
+
byte_size AS byteSize,
|
|
32099
|
+
input_byte_size AS inputByteSize,
|
|
32100
|
+
reasoning_byte_size AS reasoningByteSize,
|
|
32101
|
+
token_count AS tokenCount,
|
|
32102
|
+
input_token_count AS inputTokenCount,
|
|
32103
|
+
reasoning_token_count AS reasoningTokenCount
|
|
32104
|
+
FROM tags
|
|
32105
|
+
WHERE session_id = ? AND tag_number IN (${placeholders})`).all(sessionId, ...chunk);
|
|
32106
|
+
for (const row of rows)
|
|
32107
|
+
countsByTag.set(row.tagNumber, row);
|
|
32108
|
+
}
|
|
32109
|
+
return countsByTag;
|
|
32110
|
+
}
|
|
32111
|
+
function estimateDroppedTokensFromTagReductions(db, sessionId, reductions) {
|
|
32112
|
+
if (reductions.length === 0)
|
|
32113
|
+
return 0;
|
|
32114
|
+
const structuralByTag = new Map;
|
|
32115
|
+
const partialCharactersByTag = new Map;
|
|
32116
|
+
for (const reduction of reductions) {
|
|
32117
|
+
if (reduction.mode === "partial") {
|
|
32118
|
+
partialCharactersByTag.set(reduction.tagNumber, (partialCharactersByTag.get(reduction.tagNumber) ?? 0) + Math.max(0, reduction.removedCharacters));
|
|
32119
|
+
continue;
|
|
32120
|
+
}
|
|
32121
|
+
const prior = structuralByTag.get(reduction.tagNumber);
|
|
32122
|
+
if (!prior || reduction.mode === "full") {
|
|
32123
|
+
structuralByTag.set(reduction.tagNumber, reduction);
|
|
32124
|
+
}
|
|
32125
|
+
}
|
|
32126
|
+
const tagNumbers = [...new Set([...structuralByTag.keys(), ...partialCharactersByTag.keys()])];
|
|
32127
|
+
const countsByTag = loadPersistedTagTokenCounts(db, sessionId, tagNumbers);
|
|
32128
|
+
let total = 0;
|
|
32129
|
+
for (const [tagNumber, reduction] of structuralByTag) {
|
|
32130
|
+
const row = countsByTag.get(tagNumber);
|
|
32131
|
+
if (!row)
|
|
32132
|
+
continue;
|
|
32133
|
+
total += persistedCountOrByteEstimate(row.tokenCount, row.byteSize);
|
|
32134
|
+
if (reduction.mode === "full") {
|
|
32135
|
+
total += persistedCountOrByteEstimate(row.reasoningTokenCount, row.reasoningByteSize);
|
|
32136
|
+
if (row.type === "tool") {
|
|
32137
|
+
total += persistedCountOrByteEstimate(row.inputTokenCount, row.inputByteSize);
|
|
32138
|
+
}
|
|
32139
|
+
}
|
|
32140
|
+
}
|
|
32141
|
+
for (const [tagNumber, removedCharacters] of partialCharactersByTag) {
|
|
32142
|
+
if (structuralByTag.has(tagNumber) || !countsByTag.has(tagNumber))
|
|
32143
|
+
continue;
|
|
32144
|
+
total += estimateCharacters(removedCharacters);
|
|
32145
|
+
}
|
|
32146
|
+
return Math.max(0, Math.round(total));
|
|
32147
|
+
}
|
|
32148
|
+
|
|
32021
32149
|
// src/hooks/magic-context/fold-execution-gate.ts
|
|
32022
32150
|
function foldExecutesThisPass(foldDue, materialized) {
|
|
32023
32151
|
return foldDue && materialized;
|
|
@@ -32088,6 +32216,7 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
32088
32216
|
let emergencyReclaimedTokens = 0;
|
|
32089
32217
|
let deduplicatedTools = 0;
|
|
32090
32218
|
let droppedInjections = 0;
|
|
32219
|
+
const droppedTokenReductions = [];
|
|
32091
32220
|
if (config.emergency) {
|
|
32092
32221
|
const emergency = config.emergency;
|
|
32093
32222
|
const priorInputSample = getEmergencyInputSample(db, sessionId);
|
|
@@ -32123,6 +32252,10 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
32123
32252
|
updateTagDropMode(db, sessionId, tag.tagNumber, skeleton ? "truncated" : "full");
|
|
32124
32253
|
droppedTools++;
|
|
32125
32254
|
emergencyDroppedTools++;
|
|
32255
|
+
droppedTokenReductions.push({
|
|
32256
|
+
tagNumber: tag.tagNumber,
|
|
32257
|
+
mode: result === "removed" ? "full" : "truncated"
|
|
32258
|
+
});
|
|
32126
32259
|
emergencyReclaimedTokens += estimateEmergencyDropReclaimTokens(tag);
|
|
32127
32260
|
}
|
|
32128
32261
|
}
|
|
@@ -32157,12 +32290,18 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
32157
32290
|
const strippedSource = stripTagPrefix(stripped);
|
|
32158
32291
|
if (strippedSource.trim().length === 0) {
|
|
32159
32292
|
const dropResult = target.drop?.() ?? "absent";
|
|
32160
|
-
const
|
|
32293
|
+
const replacement = `[dropped §${tag.tagNumber}§]`;
|
|
32294
|
+
const didReplace = dropResult === "absent" ? target.setContent(replacement) : false;
|
|
32161
32295
|
if (dropResult === "removed" || dropResult === "absent") {
|
|
32162
32296
|
replaceSourceContent(db, sessionId, tag.tagNumber, "");
|
|
32163
32297
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
32164
32298
|
if (dropResult === "removed" || didReplace) {
|
|
32165
32299
|
droppedInjections++;
|
|
32300
|
+
droppedTokenReductions.push(dropResult === "removed" ? { tagNumber: tag.tagNumber, mode: "full" } : {
|
|
32301
|
+
tagNumber: tag.tagNumber,
|
|
32302
|
+
mode: "partial",
|
|
32303
|
+
removedCharacters: Math.max(0, content.length - replacement.length)
|
|
32304
|
+
});
|
|
32166
32305
|
}
|
|
32167
32306
|
}
|
|
32168
32307
|
} else {
|
|
@@ -32170,6 +32309,11 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
32170
32309
|
if (didSet) {
|
|
32171
32310
|
replaceSourceContent(db, sessionId, tag.tagNumber, strippedSource);
|
|
32172
32311
|
droppedInjections++;
|
|
32312
|
+
droppedTokenReductions.push({
|
|
32313
|
+
tagNumber: tag.tagNumber,
|
|
32314
|
+
mode: "partial",
|
|
32315
|
+
removedCharacters: Math.max(0, content.length - stripped.length)
|
|
32316
|
+
});
|
|
32173
32317
|
}
|
|
32174
32318
|
}
|
|
32175
32319
|
}
|
|
@@ -32209,6 +32353,10 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
32209
32353
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
32210
32354
|
if (result === "removed" || result === "truncated") {
|
|
32211
32355
|
deduplicatedTools++;
|
|
32356
|
+
droppedTokenReductions.push({
|
|
32357
|
+
tagNumber: tag.tagNumber,
|
|
32358
|
+
mode: result === "removed" ? "full" : "truncated"
|
|
32359
|
+
});
|
|
32212
32360
|
}
|
|
32213
32361
|
}
|
|
32214
32362
|
}
|
|
@@ -32227,6 +32375,10 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
32227
32375
|
});
|
|
32228
32376
|
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
32229
32377
|
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
32378
|
+
droppedTokenReductions.push(...cavemanResult.textReductions.map((reduction) => ({
|
|
32379
|
+
...reduction,
|
|
32380
|
+
mode: "partial"
|
|
32381
|
+
})));
|
|
32230
32382
|
}
|
|
32231
32383
|
return {
|
|
32232
32384
|
droppedTools,
|
|
@@ -32235,7 +32387,8 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
32235
32387
|
emergencyDroppedTools,
|
|
32236
32388
|
emergencyReclaimedTokens,
|
|
32237
32389
|
compressedTextTags,
|
|
32238
|
-
mutatedTextTags
|
|
32390
|
+
mutatedTextTags,
|
|
32391
|
+
droppedTokenReductions
|
|
32239
32392
|
};
|
|
32240
32393
|
}
|
|
32241
32394
|
function extractToolInfo(part) {
|
|
@@ -32475,7 +32628,7 @@ var RECENT_TOOL_SKELETON_WINDOW = 20;
|
|
|
32475
32628
|
function buildReplacementContent(tagId) {
|
|
32476
32629
|
return `[dropped §${tagId}§]`;
|
|
32477
32630
|
}
|
|
32478
|
-
function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set) {
|
|
32631
|
+
function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced) {
|
|
32479
32632
|
let didMutateMessage = false;
|
|
32480
32633
|
let admitted = false;
|
|
32481
32634
|
let startedAt = 0;
|
|
@@ -32484,6 +32637,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
32484
32637
|
admitted = true;
|
|
32485
32638
|
startedAt = performance.now();
|
|
32486
32639
|
const tags = preloadedTags ?? getTagsBySession(db, sessionId);
|
|
32640
|
+
const tagById = new Map(tags.map((tag) => [tag.tagNumber, tag]));
|
|
32487
32641
|
const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
|
|
32488
32642
|
const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
|
|
32489
32643
|
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
@@ -32516,6 +32670,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
32516
32670
|
continue;
|
|
32517
32671
|
}
|
|
32518
32672
|
didMutateMessage = true;
|
|
32673
|
+
onTagReduced?.({ tagNumber: pendingOp.tagId, mode: "edit_marker" });
|
|
32519
32674
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "edit_marker");
|
|
32520
32675
|
shouldPersistDrop = true;
|
|
32521
32676
|
} else if (skeletonWindow.has(pendingOp.tagId)) {
|
|
@@ -32525,6 +32680,7 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
32525
32680
|
}
|
|
32526
32681
|
if (truncResult === "truncated") {
|
|
32527
32682
|
didMutateMessage = true;
|
|
32683
|
+
onTagReduced?.({ tagNumber: pendingOp.tagId, mode: "truncated" });
|
|
32528
32684
|
}
|
|
32529
32685
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
|
|
32530
32686
|
shouldPersistDrop = true;
|
|
@@ -32535,14 +32691,24 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
32535
32691
|
}
|
|
32536
32692
|
if (dropResult === "removed") {
|
|
32537
32693
|
didMutateMessage = true;
|
|
32694
|
+
onTagReduced?.({ tagNumber: pendingOp.tagId, mode: "full" });
|
|
32538
32695
|
}
|
|
32539
32696
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
|
|
32540
32697
|
shouldPersistDrop = true;
|
|
32541
32698
|
}
|
|
32542
32699
|
} else if (target) {
|
|
32543
|
-
const
|
|
32544
|
-
|
|
32700
|
+
const replacement = buildReplacementContent(pendingOp.tagId);
|
|
32701
|
+
const priorContent = target.getContent?.();
|
|
32702
|
+
const changed = target.setContent(replacement);
|
|
32703
|
+
if (changed) {
|
|
32545
32704
|
didMutateMessage = true;
|
|
32705
|
+
const originalCharacters = typeof priorContent === "string" ? priorContent.length : tagById.get(pendingOp.tagId)?.byteSize ?? replacement.length;
|
|
32706
|
+
onTagReduced?.({
|
|
32707
|
+
tagNumber: pendingOp.tagId,
|
|
32708
|
+
mode: "partial",
|
|
32709
|
+
removedCharacters: Math.max(0, originalCharacters - replacement.length)
|
|
32710
|
+
});
|
|
32711
|
+
}
|
|
32546
32712
|
shouldPersistDrop = true;
|
|
32547
32713
|
} else if (!synthetic) {
|
|
32548
32714
|
shouldPersistDrop = true;
|
|
@@ -33530,6 +33696,10 @@ function clearPendingCompactionMarkerAfterSuccessfulDrain(args) {
|
|
|
33530
33696
|
sessionLog(args.sessionId, "compaction-marker drain: CAS-clear failed but no pending blob remains; another drain already cleared it");
|
|
33531
33697
|
return "cas-lost-already-cleared";
|
|
33532
33698
|
}
|
|
33699
|
+
var defaultCompactionMarkerStrategy = {
|
|
33700
|
+
applyDeferred: applyDeferredCompactionMarker,
|
|
33701
|
+
reconcile: reconcileMarkerRepresentation
|
|
33702
|
+
};
|
|
33533
33703
|
async function abortSessionFailClosed(client, sessionId) {
|
|
33534
33704
|
if (typeof client.session?.abort !== "function") {
|
|
33535
33705
|
throw new Error("OpenCode session.abort is unavailable");
|
|
@@ -33753,7 +33923,7 @@ async function runPostTransformPhase(args) {
|
|
|
33753
33923
|
let heuristicOrReasoningDidMutate = false;
|
|
33754
33924
|
let droppedCount = 0;
|
|
33755
33925
|
let droppedTokens = 0;
|
|
33756
|
-
const
|
|
33926
|
+
const droppedTokenReductions = [];
|
|
33757
33927
|
let emergencyReclaimedTokens = 0;
|
|
33758
33928
|
let emergency = false;
|
|
33759
33929
|
let m0M1InjectedThisPass = false;
|
|
@@ -33775,7 +33945,7 @@ async function runPostTransformPhase(args) {
|
|
|
33775
33945
|
const applyReason = isExplicitFlush ? "explicit_flush" : deferredMaterialize ? "deferred_materialization" : foldExecutedThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
33776
33946
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${formatPendingOpsDepth()}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
33777
33947
|
const tApply = performance.now();
|
|
33778
|
-
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.contextUsage.percentage >= 95 ? newestCtxReduceTagNumbers(getTagsBySession(args.db, args.sessionId)) : args.protectedTagIds, undefined, pendingOps);
|
|
33948
|
+
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.contextUsage.percentage >= 95 ? newestCtxReduceTagNumbers(getTagsBySession(args.db, args.sessionId)) : args.protectedTagIds, undefined, pendingOps, [], new Set, (reduction) => droppedTokenReductions.push(reduction));
|
|
33779
33949
|
if (pendingOpsDidMutate) {
|
|
33780
33950
|
rideSignals.agentDrop = true;
|
|
33781
33951
|
isCacheBustingPass = hasReclaimRide(rideSignals);
|
|
@@ -33828,7 +33998,11 @@ async function runPostTransformPhase(args) {
|
|
|
33828
33998
|
emergencyDroppedTools: cleanup.emergencyDroppedTools,
|
|
33829
33999
|
emergencyReclaimedTokens: cleanup.emergencyReclaimedTokens,
|
|
33830
34000
|
compressedTextTags: cleanup.compressedTextTags + ridingCleanup.compressedTextTags,
|
|
33831
|
-
mutatedTextTags: cleanup.mutatedTextTags + ridingCleanup.mutatedTextTags
|
|
34001
|
+
mutatedTextTags: cleanup.mutatedTextTags + ridingCleanup.mutatedTextTags,
|
|
34002
|
+
droppedTokenReductions: [
|
|
34003
|
+
...cleanup.droppedTokenReductions,
|
|
34004
|
+
...ridingCleanup.droppedTokenReductions
|
|
34005
|
+
]
|
|
33832
34006
|
};
|
|
33833
34007
|
routineCleanupApplied = true;
|
|
33834
34008
|
}
|
|
@@ -33840,6 +34014,7 @@ async function runPostTransformPhase(args) {
|
|
|
33840
34014
|
droppedCount += cleanup.droppedTools + cleanup.deduplicatedTools + cleanup.droppedInjections + cleanup.mutatedTextTags;
|
|
33841
34015
|
emergency ||= cleanup.emergencyDroppedTools > 0;
|
|
33842
34016
|
emergencyReclaimedTokens += cleanup.emergencyReclaimedTokens;
|
|
34017
|
+
droppedTokenReductions.push(...cleanup.droppedTokenReductions);
|
|
33843
34018
|
const t7 = performance.now();
|
|
33844
34019
|
const clearedReasoning = routineCleanupApplied && canUseEmptySentinels ? clearOldReasoning(args.messages, args.reasoningByMessage, args.messageTagNumbers, args.clearReasoningAge) : 0;
|
|
33845
34020
|
if (routineCleanupApplied && canUseEmptySentinels) {
|
|
@@ -33927,7 +34102,7 @@ async function runPostTransformPhase(args) {
|
|
|
33927
34102
|
}
|
|
33928
34103
|
autoReclaimTargetCount = syntheticPendingOps.length;
|
|
33929
34104
|
if (syntheticPendingOps.length > 0) {
|
|
33930
|
-
autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTagIds, undefined, [], syntheticPendingOps, editMarkerTagIds);
|
|
34105
|
+
autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, args.targets, args.protectedTagIds, undefined, [], syntheticPendingOps, editMarkerTagIds, (reduction) => droppedTokenReductions.push(reduction));
|
|
33931
34106
|
if (autoReclaimDidMutate) {
|
|
33932
34107
|
droppedCount += syntheticPendingOps.length;
|
|
33933
34108
|
autoReclaimDidMutateThisPass = true;
|
|
@@ -33965,7 +34140,7 @@ async function runPostTransformPhase(args) {
|
|
|
33965
34140
|
updateSessionMeta2(args.db, args.sessionId, { lastTransformError: getErrorMessage(error) });
|
|
33966
34141
|
}
|
|
33967
34142
|
if (isCacheBustingPass) {
|
|
33968
|
-
droppedTokens =
|
|
34143
|
+
droppedTokens = estimateDroppedTokensFromTagReductions(args.db, args.sessionId, droppedTokenReductions);
|
|
33969
34144
|
}
|
|
33970
34145
|
const replaySnapshot = !compactionOff ? loadPostprocessReplaySnapshot(args.db, args.sessionId) : undefined;
|
|
33971
34146
|
if (canUseEmptySentinels && !compactionOff && replaySnapshot) {
|
|
@@ -34131,7 +34306,7 @@ async function runPostTransformPhase(args) {
|
|
|
34131
34306
|
suppressV12HistoryDrain = true;
|
|
34132
34307
|
sessionLog(args.sessionId, `compaction-marker drain: pending ordinal ${pending.ordinal} is newer than consumed boundary ${args.pendingCompartmentInjection?.compartmentEndMessage ?? "<none>"}; preserving deferred history refresh signal`);
|
|
34133
34308
|
} else {
|
|
34134
|
-
const outcome =
|
|
34309
|
+
const outcome = (args.compactionMarkerStrategy ?? defaultCompactionMarkerStrategy).applyDeferred(args.db, args.sessionId, pending, args.sessionDirectory);
|
|
34135
34310
|
switch (outcome.kind) {
|
|
34136
34311
|
case "applied":
|
|
34137
34312
|
case "already-current":
|
|
@@ -34156,7 +34331,7 @@ async function runPostTransformPhase(args) {
|
|
|
34156
34331
|
}
|
|
34157
34332
|
}
|
|
34158
34333
|
if (!compactionOff) {
|
|
34159
|
-
|
|
34334
|
+
(args.compactionMarkerStrategy ?? defaultCompactionMarkerStrategy).reconcile(args.messages, persistedCompactionMarkerState, {
|
|
34160
34335
|
db: args.db,
|
|
34161
34336
|
sessionId: args.sessionId,
|
|
34162
34337
|
tagger: args.tagger,
|
|
@@ -34848,6 +35023,10 @@ function responseValue(response) {
|
|
|
34848
35023
|
throw new Error("module transform returned a non-object response");
|
|
34849
35024
|
}
|
|
34850
35025
|
function mirrorProjectionKey(response) {
|
|
35026
|
+
const memoryMirrorHead = response.memory_mirror_head;
|
|
35027
|
+
if (typeof memoryMirrorHead === "number" && Number.isSafeInteger(memoryMirrorHead) && memoryMirrorHead >= 0) {
|
|
35028
|
+
return JSON.stringify(["memory-feed", memoryMirrorHead]);
|
|
35029
|
+
}
|
|
34851
35030
|
const rowVersion = response.row_version;
|
|
34852
35031
|
if (typeof rowVersion !== "number" || !Number.isSafeInteger(rowVersion) || rowVersion < 0) {
|
|
34853
35032
|
return null;
|
|
@@ -36940,7 +37119,7 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
36940
37119
|
sessionLog(args.sessionId, `transform: skipping compartment start, no eligible history before protected tail (beyond ${lastObservedCompartmentEnd})`);
|
|
36941
37120
|
updateSessionMeta2(args.db, args.sessionId, { compartmentInProgress: false });
|
|
36942
37121
|
compartmentInProgress = false;
|
|
36943
|
-
} else if (!args.client) {
|
|
37122
|
+
} else if (!args.client && !args.hiddenCompletionExecutor) {
|
|
36944
37123
|
sessionLog(args.sessionId, "transform: cannot start compartment agent without client");
|
|
36945
37124
|
updateSessionMeta2(args.db, args.sessionId, { compartmentInProgress: false });
|
|
36946
37125
|
compartmentInProgress = false;
|
|
@@ -36948,6 +37127,8 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
36948
37127
|
sessionLog(args.sessionId, "transform: compartmentInProgress flag set, starting agent");
|
|
36949
37128
|
startCompartmentAgent({
|
|
36950
37129
|
client: args.client,
|
|
37130
|
+
hiddenCompletionExecutor: args.hiddenCompletionExecutor,
|
|
37131
|
+
compactionMarkerStrategy: args.compactionMarkerStrategy,
|
|
36951
37132
|
db: args.db,
|
|
36952
37133
|
sessionId: args.sessionId,
|
|
36953
37134
|
historianChunkTokens: args.historianChunkTokens,
|
|
@@ -36976,10 +37157,12 @@ async function runCompartmentPhaseImpl(args) {
|
|
|
36976
37157
|
let awaitedCompartmentRun = false;
|
|
36977
37158
|
if (historianRunnable && args.canRunCompartments && !args.skipAwaitForThisPass && args.contextUsage.percentage >= BLOCK_UNTIL_DONE_PERCENTAGE) {
|
|
36978
37159
|
let activeRun = getActiveCompartmentRun(args.sessionId);
|
|
36979
|
-
if (!activeRun && hasEligibleHistoryForCompartment() && args.client) {
|
|
37160
|
+
if (!activeRun && hasEligibleHistoryForCompartment() && (args.client || args.hiddenCompletionExecutor)) {
|
|
36980
37161
|
sessionLog(args.sessionId, `transform: 95% reached (${args.contextUsage.percentage.toFixed(1)}%), force-starting compartment agent and blocking`);
|
|
36981
37162
|
startCompartmentAgent({
|
|
36982
37163
|
client: args.client,
|
|
37164
|
+
hiddenCompletionExecutor: args.hiddenCompletionExecutor,
|
|
37165
|
+
compactionMarkerStrategy: args.compactionMarkerStrategy,
|
|
36983
37166
|
db: args.db,
|
|
36984
37167
|
sessionId: args.sessionId,
|
|
36985
37168
|
historianChunkTokens: args.historianChunkTokens,
|
|
@@ -37214,7 +37397,16 @@ function scheduleTsAuthorityRecovery(args) {
|
|
|
37214
37397
|
}
|
|
37215
37398
|
});
|
|
37216
37399
|
}
|
|
37400
|
+
function resolveTransformHostSeams(deps) {
|
|
37401
|
+
return {
|
|
37402
|
+
hostRawMessages: deps.hostRawMessages ?? readRawSessionMessages,
|
|
37403
|
+
hostProtectedTailBoundary: deps.hostProtectedTailBoundary ?? resolveOpenCodeProtectedTailBoundary,
|
|
37404
|
+
hostModelFallback: deps.hostModelFallback ?? findLastAssistantModelFromOpenCodeDb,
|
|
37405
|
+
hostRefuse: deps.hostRefuse ?? abortSessionFailClosed
|
|
37406
|
+
};
|
|
37407
|
+
}
|
|
37217
37408
|
function createTransform(deps) {
|
|
37409
|
+
const host = resolveTransformHostSeams(deps);
|
|
37218
37410
|
const loadedSessions = new Set;
|
|
37219
37411
|
const rustModeTransform = deps.transformMode === "rust" && deps.rustModeModuleClient ? createRustModeTransform(deps, {
|
|
37220
37412
|
moduleClient: deps.rustModeModuleClient,
|
|
@@ -37250,7 +37442,7 @@ function createTransform(deps) {
|
|
|
37250
37442
|
logTransformTiming(sessionId, "findSessionId", startTime, `messages=${messages.length}`);
|
|
37251
37443
|
const db = deps.db;
|
|
37252
37444
|
if (deps.client !== undefined) {
|
|
37253
|
-
scheduleReconciliation(db, sessionId,
|
|
37445
|
+
scheduleReconciliation(db, sessionId, host.hostRawMessages);
|
|
37254
37446
|
}
|
|
37255
37447
|
const tUserMsg = performance.now();
|
|
37256
37448
|
const currentTurnId = findLastUserMessageId(messages);
|
|
@@ -37353,7 +37545,7 @@ function createTransform(deps) {
|
|
|
37353
37545
|
}
|
|
37354
37546
|
const compartmentDirectory = sessionDirectory;
|
|
37355
37547
|
const historianRunnable = deps.historianRunnable !== false;
|
|
37356
|
-
const canRunCompartments = fullFeatureMode && !compactionOff && historianRunnable && deps.client !== undefined && compartmentDirectory.length > 0;
|
|
37548
|
+
const canRunCompartments = fullFeatureMode && !compactionOff && historianRunnable && (deps.client !== undefined || deps.hiddenCompletionExecutor !== undefined) && compartmentDirectory.length > 0;
|
|
37357
37549
|
const fallbackModelId = deps.getFallbackModelId?.(sessionId);
|
|
37358
37550
|
const tModelDetect = performance.now();
|
|
37359
37551
|
const persistedUsageBeforeResets = contextUsagePassSnapshot(sessionMeta).persistedUsage;
|
|
@@ -37458,7 +37650,7 @@ function createTransform(deps) {
|
|
|
37458
37650
|
}
|
|
37459
37651
|
let modelForBudget = deps.liveModelBySession?.get(sessionId);
|
|
37460
37652
|
if (!modelForBudget) {
|
|
37461
|
-
const recovered =
|
|
37653
|
+
const recovered = host.hostModelFallback(sessionId);
|
|
37462
37654
|
if (recovered) {
|
|
37463
37655
|
modelForBudget = recovered;
|
|
37464
37656
|
deps.liveModelBySession?.set(sessionId, recovered);
|
|
@@ -37514,7 +37706,7 @@ function createTransform(deps) {
|
|
|
37514
37706
|
if (!canRunCompartments)
|
|
37515
37707
|
return null;
|
|
37516
37708
|
if (_boundarySnapshotCache === undefined || emergencyTailScale) {
|
|
37517
|
-
const snapshot =
|
|
37709
|
+
const snapshot = host.hostProtectedTailBoundary({
|
|
37518
37710
|
db,
|
|
37519
37711
|
sessionId: resolvedSessionId,
|
|
37520
37712
|
mode: "transform-force",
|
|
@@ -37546,7 +37738,7 @@ function createTransform(deps) {
|
|
|
37546
37738
|
boundarySnapshot = getRunnableBoundaryForCompartment(scale);
|
|
37547
37739
|
}
|
|
37548
37740
|
if (false) {}
|
|
37549
|
-
if (!canRunCompartments || !deps.client || !boundarySnapshot || !hasRunnableCompartmentWindow(boundarySnapshot)) {
|
|
37741
|
+
if (!canRunCompartments || !deps.client && !deps.hiddenCompletionExecutor || !boundarySnapshot || !hasRunnableCompartmentWindow(boundarySnapshot)) {
|
|
37550
37742
|
return false;
|
|
37551
37743
|
}
|
|
37552
37744
|
if (getActiveCompartmentRun(sessionId)) {
|
|
@@ -37555,6 +37747,8 @@ function createTransform(deps) {
|
|
|
37555
37747
|
updateSessionMeta2(db, sessionId, { compartmentInProgress: true });
|
|
37556
37748
|
startCompartmentAgent({
|
|
37557
37749
|
client: deps.client,
|
|
37750
|
+
hiddenCompletionExecutor: deps.hiddenCompletionExecutor,
|
|
37751
|
+
compactionMarkerStrategy: deps.compactionMarkerStrategy,
|
|
37558
37752
|
db,
|
|
37559
37753
|
sessionId,
|
|
37560
37754
|
historianChunkTokens: deps.getHistorianChunkTokens?.() ?? 20000,
|
|
@@ -37761,6 +37955,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
37761
37955
|
const rawGetNotifParams = deps.getNotificationParams;
|
|
37762
37956
|
const tCompartmentPhase = performance.now();
|
|
37763
37957
|
const compartmentPhase = await runCompartmentPhase({
|
|
37958
|
+
hiddenCompletionExecutor: deps.hiddenCompletionExecutor,
|
|
37959
|
+
compactionMarkerStrategy: deps.compactionMarkerStrategy,
|
|
37764
37960
|
canRunCompartments,
|
|
37765
37961
|
fullFeatureMode,
|
|
37766
37962
|
compactionOff,
|
|
@@ -37871,6 +38067,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
37871
38067
|
const protectedCutoff = protectionWindow.cutoff;
|
|
37872
38068
|
const tPostProcess = performance.now();
|
|
37873
38069
|
const postTransformResult = await runPostTransformPhase({
|
|
38070
|
+
compactionMarkerStrategy: deps.compactionMarkerStrategy ?? defaultCompactionMarkerStrategy,
|
|
37874
38071
|
sessionId,
|
|
37875
38072
|
db,
|
|
37876
38073
|
messages,
|
|
@@ -37988,7 +38185,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
37988
38185
|
throw new EmergencyFailClosedError(`Emergency recovery notification was ${notification}`);
|
|
37989
38186
|
}
|
|
37990
38187
|
try {
|
|
37991
|
-
await
|
|
38188
|
+
await host.hostRefuse(deps.client, sessionId);
|
|
37992
38189
|
} catch (error) {
|
|
37993
38190
|
sessionLog(sessionId, "transform: emergency fail-closed abort failed; refusing to return a sendable prompt:", getErrorMessage(error));
|
|
37994
38191
|
throw new EmergencyFailClosedError("Emergency recovery abort failed", {
|
|
@@ -39785,7 +39982,7 @@ function createMagicContextHook(deps) {
|
|
|
39785
39982
|
};
|
|
39786
39983
|
const rustMemorySyncRequestedSessions = new Set;
|
|
39787
39984
|
const authorityRecoveryModuleClient = deps.rustModeModuleClient ?? (() => {
|
|
39788
|
-
const transport = new SubcModuleTransport(deps.config.subc?.connection_file);
|
|
39985
|
+
const transport = new SubcModuleTransport(deps.config.subc?.connection_file ?? getDefaultSubcConnectionFile());
|
|
39789
39986
|
const client = {
|
|
39790
39987
|
call: (args) => transport.call(args),
|
|
39791
39988
|
stateSyncCapabilities: (args) => transport.stateSyncCapabilities(args),
|
|
@@ -39839,13 +40036,14 @@ function createMagicContextHook(deps) {
|
|
|
39839
40036
|
const syncModuleNotes = () => syncModuleDomain("notes");
|
|
39840
40037
|
const syncModuleMemories = () => syncModuleDomain("memories");
|
|
39841
40038
|
const rustToolBackends = deps.config.transform_mode === "rust" && rustModeModuleClient ? {
|
|
39842
|
-
authorityState: async ({ projectPath, projectRoot, domain }) => {
|
|
40039
|
+
authorityState: async ({ projectPath, projectRoot, sessionId, domain }) => {
|
|
39843
40040
|
if (!rustModeModuleClient.authorityStatus)
|
|
39844
40041
|
return null;
|
|
39845
40042
|
const result = await rustModeModuleClient.authorityStatus({
|
|
39846
40043
|
context_store_uuid: ensureContextStoreUuid(db),
|
|
39847
40044
|
project: projectPath,
|
|
39848
40045
|
projectRoot,
|
|
40046
|
+
sessionId,
|
|
39849
40047
|
domain
|
|
39850
40048
|
});
|
|
39851
40049
|
return result.authority?.state ?? null;
|
|
@@ -39930,7 +40128,8 @@ function createMagicContextHook(deps) {
|
|
|
39930
40128
|
content,
|
|
39931
40129
|
category,
|
|
39932
40130
|
ids,
|
|
39933
|
-
reason
|
|
40131
|
+
reason,
|
|
40132
|
+
limit
|
|
39934
40133
|
}) => {
|
|
39935
40134
|
const response = await rustModeModuleClient.call({
|
|
39936
40135
|
sessionId,
|
|
@@ -39945,6 +40144,7 @@ function createMagicContextHook(deps) {
|
|
|
39945
40144
|
category,
|
|
39946
40145
|
ids,
|
|
39947
40146
|
reason,
|
|
40147
|
+
limit,
|
|
39948
40148
|
memory_project: memoryProject
|
|
39949
40149
|
}
|
|
39950
40150
|
}
|
|
@@ -41070,6 +41270,9 @@ function memoryAuthorityRefusal(args) {
|
|
|
41070
41270
|
const isMutation = args.action !== undefined && ["write", "update", "archive", "merge"].includes(args.action);
|
|
41071
41271
|
return renderCapabilityRefusal(isMutation ? "memory_write" : "memory_access");
|
|
41072
41272
|
}
|
|
41273
|
+
function memoryAuthorityMismatchRefusal() {
|
|
41274
|
+
return renderUserFacingFailure("memory_authority_mismatch");
|
|
41275
|
+
}
|
|
41073
41276
|
function moduleMemoryText(response, args) {
|
|
41074
41277
|
let value = response;
|
|
41075
41278
|
if (value !== null && typeof value === "object" && "result" in value) {
|
|
@@ -41339,13 +41542,14 @@ function createCtxMemoryTool(deps) {
|
|
|
41339
41542
|
}) : { skip: null, successor: null };
|
|
41340
41543
|
if (curatePreflight.skip)
|
|
41341
41544
|
return curatePreflight.skip;
|
|
41342
|
-
|
|
41545
|
+
{
|
|
41343
41546
|
const marker = getAuthorityManagedMarker(deps.db, projectPath);
|
|
41344
41547
|
let authorityState = null;
|
|
41345
41548
|
try {
|
|
41346
41549
|
authorityState = await deps.rustToolBackends?.authorityState?.({
|
|
41347
41550
|
projectPath,
|
|
41348
41551
|
projectRoot: toolContext.directory,
|
|
41552
|
+
sessionId: toolContext.sessionID,
|
|
41349
41553
|
domain: "memories"
|
|
41350
41554
|
}) ?? null;
|
|
41351
41555
|
} catch (error) {
|
|
@@ -41382,7 +41586,8 @@ function createCtxMemoryTool(deps) {
|
|
|
41382
41586
|
content: moduleArgs.content,
|
|
41383
41587
|
category: moduleArgs.category,
|
|
41384
41588
|
ids: moduleArgs.ids,
|
|
41385
|
-
reason: moduleArgs.reason
|
|
41589
|
+
reason: moduleArgs.reason,
|
|
41590
|
+
limit: moduleArgs.action === "list" ? normalizeLimit2(moduleArgs.limit) : undefined
|
|
41386
41591
|
}), moduleArgs);
|
|
41387
41592
|
return text ?? memoryAuthorityRefusal(args);
|
|
41388
41593
|
} catch (error) {
|
|
@@ -41393,6 +41598,9 @@ function createCtxMemoryTool(deps) {
|
|
|
41393
41598
|
return memoryAuthorityRefusal(args);
|
|
41394
41599
|
}
|
|
41395
41600
|
}
|
|
41601
|
+
if (marker && (authorityState === null || authorityState === "TS")) {
|
|
41602
|
+
return memoryAuthorityMismatchRefusal();
|
|
41603
|
+
}
|
|
41396
41604
|
if (marker || authorityState === "PREPARING" || authorityState === "DRAINING") {
|
|
41397
41605
|
return memoryAuthorityRefusal(args);
|
|
41398
41606
|
}
|
|
@@ -42417,6 +42625,7 @@ function createCtxNoteTool(deps) {
|
|
|
42417
42625
|
notesAuthority = await deps.rustToolBackends.authorityState({
|
|
42418
42626
|
projectPath: projectIdentity,
|
|
42419
42627
|
projectRoot: toolContext.directory,
|
|
42628
|
+
sessionId,
|
|
42420
42629
|
domain: "notes"
|
|
42421
42630
|
});
|
|
42422
42631
|
} catch (error) {
|
|
@@ -43383,6 +43592,1111 @@ function json(body, status = 200) {
|
|
|
43383
43592
|
});
|
|
43384
43593
|
}
|
|
43385
43594
|
|
|
43595
|
+
// src/v2/fold/markers.ts
|
|
43596
|
+
var v2CompactionMarkerStrategy = {
|
|
43597
|
+
setPending: () => {},
|
|
43598
|
+
publish: () => false,
|
|
43599
|
+
applyDeferred: () => ({ kind: "already-current" }),
|
|
43600
|
+
reconcile: () => false
|
|
43601
|
+
};
|
|
43602
|
+
|
|
43603
|
+
// src/v2/fold/owner.ts
|
|
43604
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
43605
|
+
var foldDigest = (value) => createHash15("sha256").update(value).digest("hex");
|
|
43606
|
+
|
|
43607
|
+
class FoldOwner {
|
|
43608
|
+
storage;
|
|
43609
|
+
pending = new Map;
|
|
43610
|
+
constructor(storage) {
|
|
43611
|
+
this.storage = storage;
|
|
43612
|
+
}
|
|
43613
|
+
async serial(sessionID, operation) {
|
|
43614
|
+
const previous = this.pending.get(sessionID) ?? Promise.resolve();
|
|
43615
|
+
const next = previous.catch(() => {}).then(operation);
|
|
43616
|
+
this.pending.set(sessionID, next);
|
|
43617
|
+
try {
|
|
43618
|
+
return await next;
|
|
43619
|
+
} finally {
|
|
43620
|
+
if (this.pending.get(sessionID) === next)
|
|
43621
|
+
this.pending.delete(sessionID);
|
|
43622
|
+
}
|
|
43623
|
+
}
|
|
43624
|
+
key(sessionID) {
|
|
43625
|
+
return `fold/v1/${sessionID}`;
|
|
43626
|
+
}
|
|
43627
|
+
async read(sessionID) {
|
|
43628
|
+
return await this.storage.get(this.key(sessionID));
|
|
43629
|
+
}
|
|
43630
|
+
async supply(args) {
|
|
43631
|
+
return this.serial(args.sessionID, async () => {
|
|
43632
|
+
const previous = await this.read(args.sessionID);
|
|
43633
|
+
const same = previous && (args.runningCut !== undefined ? previous.cutSeq === args.runningCut : previous.cutSeq === undefined && previous.watermark === args.watermark);
|
|
43634
|
+
if (same)
|
|
43635
|
+
return previous;
|
|
43636
|
+
const submitted = args.materialize();
|
|
43637
|
+
const next = {
|
|
43638
|
+
watermark: args.watermark,
|
|
43639
|
+
cutSeq: args.runningCut,
|
|
43640
|
+
submitted,
|
|
43641
|
+
submittedSha: foldDigest(submitted)
|
|
43642
|
+
};
|
|
43643
|
+
await this.storage.set(this.key(args.sessionID), next);
|
|
43644
|
+
return next;
|
|
43645
|
+
});
|
|
43646
|
+
}
|
|
43647
|
+
async observe(args) {
|
|
43648
|
+
return this.serial(args.sessionID, async () => {
|
|
43649
|
+
let state = await this.read(args.sessionID);
|
|
43650
|
+
const renderedSha = foldDigest(JSON.stringify(args.rendered));
|
|
43651
|
+
if (!state) {
|
|
43652
|
+
args.onHard("boot_recovery");
|
|
43653
|
+
state = {
|
|
43654
|
+
watermark: args.cutSeq,
|
|
43655
|
+
submitted: args.summary,
|
|
43656
|
+
submittedSha: foldDigest(args.summary),
|
|
43657
|
+
reason: "boot_recovery"
|
|
43658
|
+
};
|
|
43659
|
+
}
|
|
43660
|
+
const reason = args.cutSeq < state.watermark ? "host_cut_before_watermark" : state.submittedSha !== foldDigest(args.summary) || state.renderedSha && state.renderedSha !== renderedSha ? "host_rerender" : undefined;
|
|
43661
|
+
if (reason && state.rejectedSha !== renderedSha) {
|
|
43662
|
+
args.onHard(reason);
|
|
43663
|
+
state.reason = reason;
|
|
43664
|
+
state.rejectedSha = renderedSha;
|
|
43665
|
+
}
|
|
43666
|
+
if (state.cutSeq === undefined && args.cutSeq >= state.watermark)
|
|
43667
|
+
state.cutSeq = args.cutSeq;
|
|
43668
|
+
if (!state.rendered && reason !== "host_cut_before_watermark") {
|
|
43669
|
+
state.rendered = structuredClone(args.rendered);
|
|
43670
|
+
state.renderedSha = renderedSha;
|
|
43671
|
+
state.renderedSummary = args.summary;
|
|
43672
|
+
}
|
|
43673
|
+
await this.storage.set(this.key(args.sessionID), state);
|
|
43674
|
+
return state;
|
|
43675
|
+
});
|
|
43676
|
+
}
|
|
43677
|
+
}
|
|
43678
|
+
|
|
43679
|
+
// src/v2/fold/restore.ts
|
|
43680
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
43681
|
+
var imageMimes = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
|
|
43682
|
+
function attachmentParts(files) {
|
|
43683
|
+
const seen = new Map;
|
|
43684
|
+
return files.flatMap((file) => {
|
|
43685
|
+
if (imageMimes.has(file.mime) && file.source.type === "inline" && file.mention?.text) {
|
|
43686
|
+
const key = JSON.stringify([
|
|
43687
|
+
file.mime,
|
|
43688
|
+
file.name ?? null,
|
|
43689
|
+
file.description ?? null,
|
|
43690
|
+
file.mention.text
|
|
43691
|
+
]);
|
|
43692
|
+
const payloads = seen.get(key) ?? new Set;
|
|
43693
|
+
if (payloads.has(file.data))
|
|
43694
|
+
return [];
|
|
43695
|
+
payloads.add(file.data);
|
|
43696
|
+
seen.set(key, payloads);
|
|
43697
|
+
}
|
|
43698
|
+
const uri = file.source.type === "uri" ? file.source.uri : undefined;
|
|
43699
|
+
const location = uri?.startsWith("file:") ? fileURLToPath2(uri) : undefined;
|
|
43700
|
+
if (file.mime === "text/plain" || file.mime === "application/x-directory") {
|
|
43701
|
+
const directory = file.mime === "application/x-directory";
|
|
43702
|
+
return [
|
|
43703
|
+
{
|
|
43704
|
+
type: "text",
|
|
43705
|
+
text: `
|
|
43706
|
+
|
|
43707
|
+
${[
|
|
43708
|
+
directory ? `Attached directory: ${location ?? file.name ?? uri ?? "directory"}` : `Attached file: ${file.name ?? uri ?? "inline attachment"}`,
|
|
43709
|
+
file.description === undefined ? undefined : `Description: ${file.description}`,
|
|
43710
|
+
directory && !file.data.length ? undefined : "",
|
|
43711
|
+
directory && !file.data.length ? undefined : Buffer.from(file.data, "base64").toString("utf8")
|
|
43712
|
+
].filter((line) => line !== undefined).join(`
|
|
43713
|
+
`)}`,
|
|
43714
|
+
metadata: {
|
|
43715
|
+
attachment: {
|
|
43716
|
+
source: file.source,
|
|
43717
|
+
name: file.name,
|
|
43718
|
+
description: file.description
|
|
43719
|
+
}
|
|
43720
|
+
}
|
|
43721
|
+
}
|
|
43722
|
+
];
|
|
43723
|
+
}
|
|
43724
|
+
if (!imageMimes.has(file.mime) && file.mime !== "application/pdf")
|
|
43725
|
+
return [];
|
|
43726
|
+
return [
|
|
43727
|
+
...location ? [{ type: "text", text: `Attached file: ${location}` }] : [],
|
|
43728
|
+
{
|
|
43729
|
+
type: "media",
|
|
43730
|
+
mediaType: file.mime,
|
|
43731
|
+
data: file.data,
|
|
43732
|
+
filename: file.name,
|
|
43733
|
+
metadata: file.description === undefined ? undefined : { description: file.description }
|
|
43734
|
+
}
|
|
43735
|
+
];
|
|
43736
|
+
});
|
|
43737
|
+
}
|
|
43738
|
+
function restoreRow(row, model) {
|
|
43739
|
+
const data = row.data;
|
|
43740
|
+
const make = (role, content, metadata = data.metadata) => ({
|
|
43741
|
+
id: row.id,
|
|
43742
|
+
role,
|
|
43743
|
+
content,
|
|
43744
|
+
...metadata === undefined ? {} : { metadata }
|
|
43745
|
+
});
|
|
43746
|
+
if (row.type === "user") {
|
|
43747
|
+
const skills = data.skills ?? [];
|
|
43748
|
+
const content = [
|
|
43749
|
+
...skills.flatMap((skill) => skill.text === undefined ? [] : [{ type: "text", text: skill.text }]),
|
|
43750
|
+
...data.text ? [{ type: "text", text: data.text }] : [],
|
|
43751
|
+
...attachmentParts(data.files ?? [])
|
|
43752
|
+
];
|
|
43753
|
+
return content.length ? [
|
|
43754
|
+
make("user", content, {
|
|
43755
|
+
...data.metadata ?? {},
|
|
43756
|
+
...data.agents?.length ? { agents: data.agents } : {}
|
|
43757
|
+
})
|
|
43758
|
+
] : [];
|
|
43759
|
+
}
|
|
43760
|
+
if (["synthetic", "skill", "system"].includes(row.type))
|
|
43761
|
+
return [
|
|
43762
|
+
make(row.type === "system" ? "system" : "user", [
|
|
43763
|
+
{ type: "text", text: data.text ?? "" }
|
|
43764
|
+
])
|
|
43765
|
+
];
|
|
43766
|
+
if (row.type === "location-switched")
|
|
43767
|
+
return [
|
|
43768
|
+
make("user", [
|
|
43769
|
+
{
|
|
43770
|
+
type: "text",
|
|
43771
|
+
text: `The working directory has been changed to ${data.location.directory}.`
|
|
43772
|
+
}
|
|
43773
|
+
])
|
|
43774
|
+
];
|
|
43775
|
+
if (row.type === "shell")
|
|
43776
|
+
return data.metadata?.background === true ? [] : [
|
|
43777
|
+
make("user", [
|
|
43778
|
+
{
|
|
43779
|
+
type: "text",
|
|
43780
|
+
text: `The following shell command was executed by the user:
|
|
43781
|
+
|
|
43782
|
+
Command:
|
|
43783
|
+
${data.command}
|
|
43784
|
+
|
|
43785
|
+
Output:
|
|
43786
|
+
${data.output?.output ?? ""}`
|
|
43787
|
+
}
|
|
43788
|
+
])
|
|
43789
|
+
];
|
|
43790
|
+
if (row.type !== "assistant")
|
|
43791
|
+
return [];
|
|
43792
|
+
const previousModel = data.model;
|
|
43793
|
+
const sameProvider = previousModel?.providerID === model.providerID;
|
|
43794
|
+
const sameModel = sameProvider && previousModel?.id === model.id;
|
|
43795
|
+
const reuse = sameModel && data.error === undefined;
|
|
43796
|
+
const metadata = (state) => state === undefined ? undefined : { [model.providerID]: state };
|
|
43797
|
+
const content = [];
|
|
43798
|
+
const results = [];
|
|
43799
|
+
for (const part of data.content ?? []) {
|
|
43800
|
+
if (part.type === "text") {
|
|
43801
|
+
if (part.text !== "")
|
|
43802
|
+
content.push({
|
|
43803
|
+
type: "text",
|
|
43804
|
+
text: part.text,
|
|
43805
|
+
providerMetadata: reuse ? metadata(part.state) : undefined
|
|
43806
|
+
});
|
|
43807
|
+
continue;
|
|
43808
|
+
}
|
|
43809
|
+
if (part.type === "reasoning") {
|
|
43810
|
+
if (part.text !== "" || reuse && part.state !== undefined)
|
|
43811
|
+
content.push({
|
|
43812
|
+
type: reuse || data.error === undefined ? "reasoning" : "text",
|
|
43813
|
+
text: part.text,
|
|
43814
|
+
providerMetadata: reuse ? metadata(part.state) : undefined
|
|
43815
|
+
});
|
|
43816
|
+
continue;
|
|
43817
|
+
}
|
|
43818
|
+
const state = part.state;
|
|
43819
|
+
const completed = state.status === "completed" || state.status === "error";
|
|
43820
|
+
const toolReuse = reuse || sameModel && part.executed === true && completed;
|
|
43821
|
+
let input = state.input;
|
|
43822
|
+
if (state.status === "streaming" && typeof input === "string") {
|
|
43823
|
+
try {
|
|
43824
|
+
input = JSON.parse(input);
|
|
43825
|
+
} catch {}
|
|
43826
|
+
}
|
|
43827
|
+
content.push({
|
|
43828
|
+
type: "tool-call",
|
|
43829
|
+
id: part.id,
|
|
43830
|
+
name: part.name,
|
|
43831
|
+
input,
|
|
43832
|
+
providerExecuted: part.executed,
|
|
43833
|
+
providerMetadata: toolReuse ? metadata(part.providerState) : undefined
|
|
43834
|
+
});
|
|
43835
|
+
if (!completed)
|
|
43836
|
+
continue;
|
|
43837
|
+
const toolContent = state.content ?? [];
|
|
43838
|
+
const single = toolContent.length === 1 ? toolContent[0] : undefined;
|
|
43839
|
+
const result = {
|
|
43840
|
+
type: "tool-result",
|
|
43841
|
+
id: part.id,
|
|
43842
|
+
name: part.name,
|
|
43843
|
+
providerExecuted: part.executed,
|
|
43844
|
+
providerMetadata: toolReuse ? metadata(part.providerResultState ?? part.providerState) : sameProvider ? metadata(part.providerResultState) : undefined,
|
|
43845
|
+
result: state.status === "error" ? { error: state.error, content: toolContent } : single?.type === "text" ? { type: "text", value: single.text } : { type: "content", value: toolContent },
|
|
43846
|
+
...state.status === "error" ? { resultType: "error" } : {}
|
|
43847
|
+
};
|
|
43848
|
+
if (part.executed === true)
|
|
43849
|
+
content.push(result);
|
|
43850
|
+
else
|
|
43851
|
+
results.push({ role: "tool", content: [result] });
|
|
43852
|
+
}
|
|
43853
|
+
return [...content.length ? [make("assistant", content)] : [], ...results];
|
|
43854
|
+
}
|
|
43855
|
+
|
|
43856
|
+
// src/v2/hidden-completion.ts
|
|
43857
|
+
function meter(system, prompt, text) {
|
|
43858
|
+
return {
|
|
43859
|
+
input: estimateTokens(system) + estimateTokens(prompt),
|
|
43860
|
+
output: estimateTokens(text),
|
|
43861
|
+
cacheRead: 0,
|
|
43862
|
+
cacheWrite: 0
|
|
43863
|
+
};
|
|
43864
|
+
}
|
|
43865
|
+
async function createV2HiddenCompletionExecutor(host, currentModel) {
|
|
43866
|
+
const runs = new WeakMap;
|
|
43867
|
+
const pending = new Map;
|
|
43868
|
+
const modelKey = (model) => `${model.providerID}/${model.modelID}`;
|
|
43869
|
+
const requireModel = async (sessionID) => {
|
|
43870
|
+
const model = sessionID ? await currentModel(sessionID) : null;
|
|
43871
|
+
if (!model)
|
|
43872
|
+
throw new HiddenCompletionRefusal("hidden_model_unsupported", "Hidden completion requires an existing session with a resolved current model", true);
|
|
43873
|
+
return model;
|
|
43874
|
+
};
|
|
43875
|
+
const refuseModel = (requested, actual, terminal = false) => {
|
|
43876
|
+
throw new HiddenCompletionRefusal("hidden_model_unsupported", `Hidden completion model ${requested} is unavailable on opencode2; use the session model ${actual} in historian.model or dreaming task model configuration, or unset the configured model`, terminal);
|
|
43877
|
+
};
|
|
43878
|
+
await host.hook("generate", async (draft) => {
|
|
43879
|
+
const last = draft.messages.at(-1);
|
|
43880
|
+
if (last?.role !== "user" || last.content.length !== 1)
|
|
43881
|
+
return;
|
|
43882
|
+
const part = last.content[0];
|
|
43883
|
+
if (part?.type !== "text" || typeof part.text !== "string")
|
|
43884
|
+
return;
|
|
43885
|
+
const attempt = pending.get(part.text);
|
|
43886
|
+
if (!attempt || draft.sessionID !== attempt.run.identity.parentSessionId)
|
|
43887
|
+
return;
|
|
43888
|
+
const actual = `${draft.model.providerID}/${draft.model.id}`;
|
|
43889
|
+
if (modelKey(attempt.model) !== actual)
|
|
43890
|
+
refuseModel(modelKey(attempt.model), actual);
|
|
43891
|
+
if (attempt.request.signal?.aborted)
|
|
43892
|
+
throw new Error("Hidden completion prompt aborted");
|
|
43893
|
+
const body = attempt.request.body;
|
|
43894
|
+
if (typeof body.variant === "string" && body.variant !== draft.model.variant) {
|
|
43895
|
+
refuseModel(`${actual} (${body.variant})`, `${actual} (${draft.model.variant ?? "default variant"})`);
|
|
43896
|
+
}
|
|
43897
|
+
const parts = body.parts;
|
|
43898
|
+
if (!Array.isArray(parts) || parts.some((item) => item.type !== "text" || typeof item.text !== "string")) {
|
|
43899
|
+
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", "Hidden completion accepts text-only calibrated prompts", true);
|
|
43900
|
+
}
|
|
43901
|
+
draft.system = [
|
|
43902
|
+
{
|
|
43903
|
+
type: "text",
|
|
43904
|
+
text: typeof body.system === "string" ? body.system : attempt.run.identity.system
|
|
43905
|
+
}
|
|
43906
|
+
];
|
|
43907
|
+
draft.messages = [
|
|
43908
|
+
{ role: "user", content: parts.map((item) => ({ type: "text", text: item.text })) }
|
|
43909
|
+
];
|
|
43910
|
+
draft.tools = {};
|
|
43911
|
+
if (attempt.run.identity.maxOutputTokens !== undefined)
|
|
43912
|
+
draft.options.maxOutputTokens = attempt.run.identity.maxOutputTokens;
|
|
43913
|
+
attempt.shaped = true;
|
|
43914
|
+
});
|
|
43915
|
+
return {
|
|
43916
|
+
capabilities: { tools: false, harness: "opencode2" },
|
|
43917
|
+
async open(identity) {
|
|
43918
|
+
const model = await requireModel(identity.parentSessionId);
|
|
43919
|
+
const configured = (identity.configuredModels ?? (identity.model ? [identity.model] : [])).map(toModelEntry).filter((entry) => entry !== undefined);
|
|
43920
|
+
if (configured.length && !configured.some((entry) => entry.model === modelKey(model))) {
|
|
43921
|
+
refuseModel(configured.map((entry) => entry.model).join(", "), modelKey(model), true);
|
|
43922
|
+
}
|
|
43923
|
+
const handle = { id: `mc:hidden:${crypto.randomUUID()}` };
|
|
43924
|
+
runs.set(handle, { identity });
|
|
43925
|
+
return handle;
|
|
43926
|
+
},
|
|
43927
|
+
async attempt(handle, request) {
|
|
43928
|
+
const run = runs.get(handle);
|
|
43929
|
+
if (!run)
|
|
43930
|
+
throw new Error("Unknown hidden completion run");
|
|
43931
|
+
const sessionID = run.identity.parentSessionId;
|
|
43932
|
+
const actual = await requireModel(sessionID);
|
|
43933
|
+
if (sessionID === undefined)
|
|
43934
|
+
throw new Error("Hidden completion session id missing");
|
|
43935
|
+
const requested = request.body.model ?? actual;
|
|
43936
|
+
if (modelKey(requested) !== modelKey(actual))
|
|
43937
|
+
refuseModel(modelKey(requested), modelKey(actual));
|
|
43938
|
+
if (request.signal?.aborted)
|
|
43939
|
+
throw new Error("Hidden completion prompt aborted");
|
|
43940
|
+
const marker = `${handle.id}:${crypto.randomUUID()}`;
|
|
43941
|
+
const state = { run, request, model: actual, shaped: false };
|
|
43942
|
+
pending.set(marker, state);
|
|
43943
|
+
try {
|
|
43944
|
+
const generation = host.generate({ sessionID, prompt: marker }, { signal: request.signal });
|
|
43945
|
+
const result = await new Promise((resolve, reject) => {
|
|
43946
|
+
const abort = () => reject(new Error("Hidden completion prompt aborted"));
|
|
43947
|
+
request.signal?.addEventListener("abort", abort, { once: true });
|
|
43948
|
+
generation.then(resolve, reject).finally(() => {
|
|
43949
|
+
request.signal?.removeEventListener("abort", abort);
|
|
43950
|
+
pending.delete(marker);
|
|
43951
|
+
});
|
|
43952
|
+
if (request.signal?.aborted)
|
|
43953
|
+
abort();
|
|
43954
|
+
});
|
|
43955
|
+
if (!state.shaped)
|
|
43956
|
+
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", "Host did not dispatch the hidden generate hook", true);
|
|
43957
|
+
const prompt = request.body.parts.map((part) => part.text).join(`
|
|
43958
|
+
`);
|
|
43959
|
+
const system = typeof request.body.system === "string" ? request.body.system : run.identity.system;
|
|
43960
|
+
const usage = meter(system, prompt, result.text);
|
|
43961
|
+
usage.input += run.usage?.input ?? 0;
|
|
43962
|
+
usage.output += run.usage?.output ?? 0;
|
|
43963
|
+
run.usage = usage;
|
|
43964
|
+
run.completion = {
|
|
43965
|
+
text: result.text,
|
|
43966
|
+
usage,
|
|
43967
|
+
lengthCapped: false,
|
|
43968
|
+
providerId: actual.providerID,
|
|
43969
|
+
modelId: actual.modelID
|
|
43970
|
+
};
|
|
43971
|
+
} finally {
|
|
43972
|
+
if (!request.signal?.aborted)
|
|
43973
|
+
pending.delete(marker);
|
|
43974
|
+
}
|
|
43975
|
+
},
|
|
43976
|
+
async collect(handle) {
|
|
43977
|
+
const completion = runs.get(handle)?.completion;
|
|
43978
|
+
if (!completion)
|
|
43979
|
+
throw new Error("Hidden completion has no settled output");
|
|
43980
|
+
return completion;
|
|
43981
|
+
},
|
|
43982
|
+
async close() {}
|
|
43983
|
+
};
|
|
43984
|
+
}
|
|
43985
|
+
|
|
43986
|
+
// src/v2/store-reader.ts
|
|
43987
|
+
import { join as join11 } from "node:path";
|
|
43988
|
+
function sourceDatabaseFilename(channel, env = process.env) {
|
|
43989
|
+
return env.OPENCODE_DB ?? (["latest", "dev", "beta", "next", "prod"].includes(channel) || env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true" ? "opencode.db" : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`);
|
|
43990
|
+
}
|
|
43991
|
+
function gaDatabasePath(dataHome, channel = "latest", env = process.env) {
|
|
43992
|
+
const filename = sourceDatabaseFilename(channel, env);
|
|
43993
|
+
return filename === ":memory:" ? filename : join11(dataHome, "opencode", filename);
|
|
43994
|
+
}
|
|
43995
|
+
function decode(row) {
|
|
43996
|
+
const data = JSON.parse(row.data);
|
|
43997
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
43998
|
+
throw new Error(`Invalid session_message data at seq ${row.seq}`);
|
|
43999
|
+
}
|
|
44000
|
+
if (row.type === "idle" && !["succeeded", "failed", "interrupted"].includes(String(data.outcome))) {
|
|
44001
|
+
throw new Error(`Invalid idle outcome at seq ${row.seq}`);
|
|
44002
|
+
}
|
|
44003
|
+
return { ...row, data };
|
|
44004
|
+
}
|
|
44005
|
+
|
|
44006
|
+
class V2StoreReader {
|
|
44007
|
+
db;
|
|
44008
|
+
constructor(path) {
|
|
44009
|
+
this.db = new Database(path, { readonly: true, fileMustExist: true });
|
|
44010
|
+
}
|
|
44011
|
+
close() {
|
|
44012
|
+
this.db.close();
|
|
44013
|
+
}
|
|
44014
|
+
page(sessionID, options = {}) {
|
|
44015
|
+
const limit = options.limit ?? 100;
|
|
44016
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
|
|
44017
|
+
throw new Error("Invalid page limit");
|
|
44018
|
+
const after = options.after ?? -1;
|
|
44019
|
+
if (!Number.isSafeInteger(after))
|
|
44020
|
+
throw new Error("Invalid seq cursor");
|
|
44021
|
+
const rows = this.db.prepare(`SELECT id, session_id, type, seq, data FROM session_message
|
|
44022
|
+
WHERE session_id = ? AND seq > ? ${options.type ? "AND type = ?" : ""}
|
|
44023
|
+
ORDER BY seq ASC LIMIT ?`).all(...options.type ? [sessionID, after, options.type, limit] : [sessionID, after, limit]).map(decode);
|
|
44024
|
+
return { rows, cursor: rows.at(-1)?.seq };
|
|
44025
|
+
}
|
|
44026
|
+
latestCompaction(sessionID) {
|
|
44027
|
+
const row = this.db.prepare(`SELECT id, session_id, type, seq, data FROM session_message
|
|
44028
|
+
WHERE session_id = ? AND type = 'compaction' AND json_extract(data, '$.status') = 'completed'
|
|
44029
|
+
ORDER BY seq DESC LIMIT 1`).get(sessionID);
|
|
44030
|
+
return row ? decode(row) : undefined;
|
|
44031
|
+
}
|
|
44032
|
+
idleRows(sessionID, after = -1) {
|
|
44033
|
+
return this.all(sessionID, after, "idle");
|
|
44034
|
+
}
|
|
44035
|
+
window(sessionID) {
|
|
44036
|
+
return this.db.transaction(() => {
|
|
44037
|
+
const cut = this.latestCompaction(sessionID);
|
|
44038
|
+
return this.all(sessionID, cut ? cut.seq - 1 : -1);
|
|
44039
|
+
})();
|
|
44040
|
+
}
|
|
44041
|
+
history(sessionID) {
|
|
44042
|
+
return this.all(sessionID, -1);
|
|
44043
|
+
}
|
|
44044
|
+
all(sessionID, after, type) {
|
|
44045
|
+
const rows = [];
|
|
44046
|
+
for (;; ) {
|
|
44047
|
+
const page = this.page(sessionID, { after, type });
|
|
44048
|
+
rows.push(...page.rows);
|
|
44049
|
+
if (page.rows.length < 100 || page.cursor === undefined)
|
|
44050
|
+
return rows;
|
|
44051
|
+
after = page.cursor;
|
|
44052
|
+
}
|
|
44053
|
+
}
|
|
44054
|
+
}
|
|
44055
|
+
|
|
44056
|
+
// src/v2/hooks/channel2.ts
|
|
44057
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
44058
|
+
async function deliverSynthetic(context, sessionID, text) {
|
|
44059
|
+
const id = `msg_${randomBytes2(12).toString("hex")}`;
|
|
44060
|
+
await context.storage.set(`synthetic/${sessionID}/${id}`, { id });
|
|
44061
|
+
await context.session.synthetic({ sessionID, id, text, delivery: "steer" });
|
|
44062
|
+
return id;
|
|
44063
|
+
}
|
|
44064
|
+
async function isAdmittedSynthetic(context, sessionID, id) {
|
|
44065
|
+
const record = await context.storage.get(`synthetic/${sessionID}/${id}`);
|
|
44066
|
+
return record !== null && typeof record === "object" && "id" in record && record.id === id;
|
|
44067
|
+
}
|
|
44068
|
+
async function deliverPendingChannel2(context, db, sessionID, baseline) {
|
|
44069
|
+
if (getChannel2NudgeState(db, sessionID) !== "pending")
|
|
44070
|
+
return;
|
|
44071
|
+
const evaluation = evaluateChannel2(baseline);
|
|
44072
|
+
if (!evaluation.evaluable || !evaluation.shouldTrigger)
|
|
44073
|
+
return;
|
|
44074
|
+
const token = randomBytes2(16).toString("hex");
|
|
44075
|
+
if (!claimChannel2NudgeState(db, sessionID, token))
|
|
44076
|
+
return;
|
|
44077
|
+
try {
|
|
44078
|
+
await deliverSynthetic(context, sessionID, buildChannel2Reminder(evaluation.reclaimableTokens, reclaimableToolOutputCount(baseline?.baselineParts ?? [])));
|
|
44079
|
+
} catch (error) {
|
|
44080
|
+
casChannel2NudgeClaim(db, sessionID, "pending", token);
|
|
44081
|
+
throw error;
|
|
44082
|
+
}
|
|
44083
|
+
casChannel2NudgeClaim(db, sessionID, "delivered", token);
|
|
44084
|
+
}
|
|
44085
|
+
|
|
44086
|
+
// src/v2/hooks/dream-trigger.ts
|
|
44087
|
+
function startDreamTrigger(context, args) {
|
|
44088
|
+
const controller = new AbortController;
|
|
44089
|
+
const done = (async () => {
|
|
44090
|
+
try {
|
|
44091
|
+
for await (const value of context.event.subscribe({ signal: controller.signal })) {
|
|
44092
|
+
if (controller.signal.aborted)
|
|
44093
|
+
break;
|
|
44094
|
+
const event = value;
|
|
44095
|
+
if (event.type !== "session.execution.succeeded" || !event.data?.sessionID)
|
|
44096
|
+
continue;
|
|
44097
|
+
const db = openDatabase();
|
|
44098
|
+
if (!db)
|
|
44099
|
+
continue;
|
|
44100
|
+
try {
|
|
44101
|
+
await runDueTasksForProject({
|
|
44102
|
+
db,
|
|
44103
|
+
projectIdentity: args.projectIdentity(),
|
|
44104
|
+
tasks: buildDreamTaskRuntimeConfigs2(args.config, "opencode", args.language, args.mural?.model),
|
|
44105
|
+
executor: createDreamTaskExecutor({
|
|
44106
|
+
hiddenCompletionExecutor: args.executor,
|
|
44107
|
+
parentSessionId: event.data.sessionID,
|
|
44108
|
+
sessionDirectory: context.location.directory,
|
|
44109
|
+
openOpenCodeDb: () => null,
|
|
44110
|
+
language: args.language,
|
|
44111
|
+
mural: args.mural
|
|
44112
|
+
})
|
|
44113
|
+
});
|
|
44114
|
+
} catch (error) {
|
|
44115
|
+
console.warn("[magic-context] v2 dream scheduling failed", error);
|
|
44116
|
+
}
|
|
44117
|
+
}
|
|
44118
|
+
} catch (error) {
|
|
44119
|
+
if (!controller.signal.aborted)
|
|
44120
|
+
console.warn("[magic-context] v2 dream event subscription failed", error);
|
|
44121
|
+
}
|
|
44122
|
+
})();
|
|
44123
|
+
return {
|
|
44124
|
+
async dispose() {
|
|
44125
|
+
controller.abort();
|
|
44126
|
+
await done;
|
|
44127
|
+
}
|
|
44128
|
+
};
|
|
44129
|
+
}
|
|
44130
|
+
|
|
44131
|
+
// src/v2/hooks/payload.ts
|
|
44132
|
+
var HEAD_IDS = ["__magic_context_v2_m0__", "__magic_context_v2_m1__"];
|
|
44133
|
+
function adaptPayload(draft, admittedIDs = new Set) {
|
|
44134
|
+
const existingHeads = new Map(draft.messages.filter((m) => HEAD_IDS.some((id) => m.id === id)).map((m) => [m.id, m]));
|
|
44135
|
+
const source = draft.messages.filter((m) => !existingHeads.has(m.id));
|
|
44136
|
+
const results = new Map;
|
|
44137
|
+
for (const message of source) {
|
|
44138
|
+
for (const part of message.content) {
|
|
44139
|
+
if (part.type === "tool-result" && typeof part.id === "string") {
|
|
44140
|
+
const queue = results.get(part.id) ?? [];
|
|
44141
|
+
queue.push({ part, message });
|
|
44142
|
+
results.set(part.id, queue);
|
|
44143
|
+
}
|
|
44144
|
+
}
|
|
44145
|
+
}
|
|
44146
|
+
const paired = new Set;
|
|
44147
|
+
const bridges = new Map;
|
|
44148
|
+
const originals = new Map;
|
|
44149
|
+
const nativeTool = (call, result) => {
|
|
44150
|
+
const value = result?.part.result?.value;
|
|
44151
|
+
const output = typeof value === "string" ? value : value === undefined ? "" : JSON.stringify(value);
|
|
44152
|
+
const part = {
|
|
44153
|
+
type: "tool",
|
|
44154
|
+
callID: call?.id ?? result?.part.id,
|
|
44155
|
+
tool: call?.name ?? result?.part.name,
|
|
44156
|
+
state: {
|
|
44157
|
+
input: structuredClone(call?.input ?? {}),
|
|
44158
|
+
status: result ? "completed" : "running",
|
|
44159
|
+
...result ? { output } : {}
|
|
44160
|
+
}
|
|
44161
|
+
};
|
|
44162
|
+
bridges.set(part, { call, result: result?.part, resultMessage: result?.message, output });
|
|
44163
|
+
if (result)
|
|
44164
|
+
paired.add(result.part);
|
|
44165
|
+
return part;
|
|
44166
|
+
};
|
|
44167
|
+
const callParts = new Map;
|
|
44168
|
+
for (const message of source) {
|
|
44169
|
+
for (const part of message.content) {
|
|
44170
|
+
if (part.type === "tool-call")
|
|
44171
|
+
callParts.set(part, nativeTool(part, results.get(String(part.id))?.shift()));
|
|
44172
|
+
}
|
|
44173
|
+
}
|
|
44174
|
+
const messages = [];
|
|
44175
|
+
for (const message of source) {
|
|
44176
|
+
const parts = [];
|
|
44177
|
+
for (const content of message.content) {
|
|
44178
|
+
if (paired.has(content))
|
|
44179
|
+
continue;
|
|
44180
|
+
const part = callParts.get(content) ?? (content.type === "tool-result" ? nativeTool(undefined, { part: content, message }) : structuredClone(content));
|
|
44181
|
+
if (message.id && admittedIDs.has(message.id))
|
|
44182
|
+
part.synthetic = true;
|
|
44183
|
+
parts.push(part);
|
|
44184
|
+
}
|
|
44185
|
+
if (!parts.length && message.content.length)
|
|
44186
|
+
continue;
|
|
44187
|
+
const mapped = {
|
|
44188
|
+
info: {
|
|
44189
|
+
id: message.id,
|
|
44190
|
+
sessionID: draft.sessionID,
|
|
44191
|
+
role: message.role,
|
|
44192
|
+
...{
|
|
44193
|
+
providerID: draft.model.providerID,
|
|
44194
|
+
modelID: draft.model.id,
|
|
44195
|
+
agent: draft.agent,
|
|
44196
|
+
tools: draft.tools
|
|
44197
|
+
}
|
|
44198
|
+
},
|
|
44199
|
+
parts
|
|
44200
|
+
};
|
|
44201
|
+
originals.set(mapped, message);
|
|
44202
|
+
messages.push(mapped);
|
|
44203
|
+
}
|
|
44204
|
+
return {
|
|
44205
|
+
messages,
|
|
44206
|
+
commit() {
|
|
44207
|
+
let head = 0;
|
|
44208
|
+
const rendered = [];
|
|
44209
|
+
for (const message of messages) {
|
|
44210
|
+
const original = originals.get(message);
|
|
44211
|
+
const id = message.info.syntheticHead ? HEAD_IDS[head++] : original?.id;
|
|
44212
|
+
const content = [];
|
|
44213
|
+
const following = [];
|
|
44214
|
+
for (const candidate of message.parts) {
|
|
44215
|
+
const part = candidate;
|
|
44216
|
+
const bridge = bridges.get(part);
|
|
44217
|
+
if (!bridge) {
|
|
44218
|
+
const { synthetic: _synthetic, ...clean } = part;
|
|
44219
|
+
content.push(clean);
|
|
44220
|
+
continue;
|
|
44221
|
+
}
|
|
44222
|
+
const state = part.state;
|
|
44223
|
+
if (bridge.call)
|
|
44224
|
+
content.push({ ...bridge.call, input: state.input });
|
|
44225
|
+
if (bridge.result && bridge.resultMessage) {
|
|
44226
|
+
const result = {
|
|
44227
|
+
...bridge.result,
|
|
44228
|
+
result: state.output === bridge.output ? bridge.result.result : { type: "text", value: state.output }
|
|
44229
|
+
};
|
|
44230
|
+
if (bridge.resultMessage === original)
|
|
44231
|
+
content.push(result);
|
|
44232
|
+
else
|
|
44233
|
+
following.push({ ...bridge.resultMessage, content: [result] });
|
|
44234
|
+
}
|
|
44235
|
+
}
|
|
44236
|
+
if (content.length || !original?.content.length) {
|
|
44237
|
+
const value = {
|
|
44238
|
+
...original,
|
|
44239
|
+
id,
|
|
44240
|
+
role: message.info.role ?? "user",
|
|
44241
|
+
content
|
|
44242
|
+
};
|
|
44243
|
+
const existing = id ? existingHeads.get(id) : undefined;
|
|
44244
|
+
rendered.push(existing ? Object.assign(existing, { content }) : value);
|
|
44245
|
+
}
|
|
44246
|
+
rendered.push(...following);
|
|
44247
|
+
}
|
|
44248
|
+
draft.messages.splice(0, draft.messages.length, ...rendered);
|
|
44249
|
+
}
|
|
44250
|
+
};
|
|
44251
|
+
}
|
|
44252
|
+
|
|
44253
|
+
// src/v2/hooks/refusal.ts
|
|
44254
|
+
class V2ContextRefusal extends Error {
|
|
44255
|
+
constructor(message = "Context full — /ctx-flush or /clear to continue.", options) {
|
|
44256
|
+
super(message, options);
|
|
44257
|
+
this.name = "V2ContextRefusal";
|
|
44258
|
+
}
|
|
44259
|
+
}
|
|
44260
|
+
async function interruptBeforeProvider(session, sessionID) {
|
|
44261
|
+
let timer;
|
|
44262
|
+
try {
|
|
44263
|
+
const result = await Promise.race([
|
|
44264
|
+
session.interrupt({ sessionID }),
|
|
44265
|
+
new Promise((_, reject) => {
|
|
44266
|
+
timer = setTimeout(() => reject(new Error("interrupt exceeded 2000 ms")), 2000);
|
|
44267
|
+
})
|
|
44268
|
+
]);
|
|
44269
|
+
if (result.interrupted !== true)
|
|
44270
|
+
throw new Error("interrupt arrived after the turn became idle");
|
|
44271
|
+
} catch (cause) {
|
|
44272
|
+
throw new V2ContextRefusal(undefined, { cause });
|
|
44273
|
+
} finally {
|
|
44274
|
+
clearTimeout(timer);
|
|
44275
|
+
}
|
|
44276
|
+
}
|
|
44277
|
+
|
|
44278
|
+
// src/v2/hooks/store.ts
|
|
44279
|
+
var isRawRow = (row) => ["user", "synthetic", "assistant", "skill", "shell", "system"].includes(row.type);
|
|
44280
|
+
function rawMessages(rows, history = rows) {
|
|
44281
|
+
const ordinals = new Map(history.filter(isRawRow).map((row, index) => [row.id, index + 1]));
|
|
44282
|
+
return rows.filter(isRawRow).map((row) => ({
|
|
44283
|
+
id: row.id,
|
|
44284
|
+
ordinal: ordinals.get(row.id),
|
|
44285
|
+
role: row.type === "assistant" ? "assistant" : "user",
|
|
44286
|
+
createdAt: row.data.time?.created,
|
|
44287
|
+
parts: row.type === "assistant" ? (row.data.content ?? []).map((part) => {
|
|
44288
|
+
if (part.type !== "tool")
|
|
44289
|
+
return { ...part };
|
|
44290
|
+
const state = part.state;
|
|
44291
|
+
const content = state.content;
|
|
44292
|
+
return {
|
|
44293
|
+
type: "tool",
|
|
44294
|
+
tool: part.name,
|
|
44295
|
+
callID: part.id,
|
|
44296
|
+
state: {
|
|
44297
|
+
...state,
|
|
44298
|
+
output: content?.filter((p) => p.type === "text").map((p) => p.text).join(`
|
|
44299
|
+
`) ?? ""
|
|
44300
|
+
}
|
|
44301
|
+
};
|
|
44302
|
+
}) : [{ type: "text", text: row.data.text ?? "" }]
|
|
44303
|
+
}));
|
|
44304
|
+
}
|
|
44305
|
+
|
|
44306
|
+
// src/v2/hooks/context.ts
|
|
44307
|
+
function createHostSeams(context, read, liveModels) {
|
|
44308
|
+
return {
|
|
44309
|
+
hostRawMessages: read,
|
|
44310
|
+
hostProtectedTailBoundary: (args) => resolveOpenCodeProtectedTailBoundary({
|
|
44311
|
+
...args,
|
|
44312
|
+
cacheNamespace: `opencode2:${args.sessionId}`
|
|
44313
|
+
}),
|
|
44314
|
+
hostModelFallback: (sessionID) => liveModels.get(sessionID) ?? null,
|
|
44315
|
+
hostRefuse: (_client, sessionID) => interruptBeforeProvider(context.session, sessionID)
|
|
44316
|
+
};
|
|
44317
|
+
}
|
|
44318
|
+
async function registerContext(context) {
|
|
44319
|
+
const directory = context.location.directory;
|
|
44320
|
+
const config = loadPluginConfigDetailed(directory).config;
|
|
44321
|
+
if (!config.enabled || !isCompactionEnabled(config))
|
|
44322
|
+
return;
|
|
44323
|
+
const folds = new FoldOwner(context.storage);
|
|
44324
|
+
const limits = new Map;
|
|
44325
|
+
const queriedModels = new Set;
|
|
44326
|
+
const liveModels = new Map;
|
|
44327
|
+
const hostGenerate = context.session.generate?.bind(context.session);
|
|
44328
|
+
const hiddenCompletionExecutor = hostGenerate ? await createV2HiddenCompletionExecutor({
|
|
44329
|
+
hook: (name, callback) => context.session.hook(name, callback),
|
|
44330
|
+
generate: (input, options) => hostGenerate(input, options)
|
|
44331
|
+
}, (sessionID) => liveModels.get(sessionID) ?? null) : undefined;
|
|
44332
|
+
const dreamTrigger = hiddenCompletionExecutor && config.dreamer && !config.dreamer.disable ? startDreamTrigger(context, {
|
|
44333
|
+
config: config.dreamer,
|
|
44334
|
+
executor: hiddenCompletionExecutor,
|
|
44335
|
+
projectIdentity: () => resolveProjectIdentity(directory) ?? directory,
|
|
44336
|
+
language: config.language,
|
|
44337
|
+
mural: config.mural
|
|
44338
|
+
}) : undefined;
|
|
44339
|
+
const historianModels = resolveHistorianModel2(config, "opencode");
|
|
44340
|
+
const usage = new Map;
|
|
44341
|
+
const channel1 = new Map;
|
|
44342
|
+
const variants = new Map;
|
|
44343
|
+
const agents = new Map;
|
|
44344
|
+
const historyRefreshSessions = new Set;
|
|
44345
|
+
const pendingMaterializationSessions = new Set;
|
|
44346
|
+
const lastHeuristicsTurnId = new Map;
|
|
44347
|
+
const rawProviders = new Map;
|
|
44348
|
+
let passDuties;
|
|
44349
|
+
let toolDuties;
|
|
44350
|
+
await context.tool.hook("execute.before", (draft) => assertExecutableToolInput(draft.input));
|
|
44351
|
+
await context.tool.hook("execute.after", async (draft) => {
|
|
44352
|
+
if (!db || draft.status !== "completed")
|
|
44353
|
+
return;
|
|
44354
|
+
try {
|
|
44355
|
+
toolDuties ??= createToolExecuteAfterHook({ db, channel1StateBySession: channel1 });
|
|
44356
|
+
const content = draft.result?.content;
|
|
44357
|
+
const text = typeof content === "string" ? content : Array.isArray(content) ? content.filter((part) => part.type === "text").map((part) => part.text).join(`
|
|
44358
|
+
`) : "";
|
|
44359
|
+
const output = { output: text };
|
|
44360
|
+
await toolDuties({ ...draft, args: draft.input }, output);
|
|
44361
|
+
if (draft.result && output.output !== text) {
|
|
44362
|
+
if (typeof content === "string")
|
|
44363
|
+
draft.result.content = output.output;
|
|
44364
|
+
else if (Array.isArray(content) && output.output.startsWith(text))
|
|
44365
|
+
content.push({ type: "text", text: output.output.slice(text.length) });
|
|
44366
|
+
}
|
|
44367
|
+
const baseline = channel1.get(draft.sessionID);
|
|
44368
|
+
await deliverPendingChannel2(context, db, draft.sessionID, baseline);
|
|
44369
|
+
} catch (error) {
|
|
44370
|
+
console.warn("[magic-context] v2 Channel 2 delivery deferred", error);
|
|
44371
|
+
}
|
|
44372
|
+
});
|
|
44373
|
+
const read = (sessionID) => {
|
|
44374
|
+
const reader = new V2StoreReader(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
44375
|
+
try {
|
|
44376
|
+
return rawMessages(reader.history(sessionID));
|
|
44377
|
+
} finally {
|
|
44378
|
+
reader.close();
|
|
44379
|
+
}
|
|
44380
|
+
};
|
|
44381
|
+
const pagedRead = Object.assign(read, {
|
|
44382
|
+
readPage: (sessionID, after, limit, watermark) => read(sessionID).filter((m) => m.ordinal > after && m.ordinal <= watermark).slice(0, limit),
|
|
44383
|
+
getCount: (sessionID) => read(sessionID).length
|
|
44384
|
+
});
|
|
44385
|
+
let transform;
|
|
44386
|
+
let db;
|
|
44387
|
+
const refuseIfUnsafe = async (draft) => {
|
|
44388
|
+
let unsafe = false;
|
|
44389
|
+
try {
|
|
44390
|
+
db ??= openDatabase();
|
|
44391
|
+
if (!db || !isDatabasePersisted(db))
|
|
44392
|
+
throw new Error("context storage is not durable");
|
|
44393
|
+
getOrCreateSessionMeta2(db, draft.sessionID);
|
|
44394
|
+
const reader = new V2StoreReader(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
44395
|
+
try {
|
|
44396
|
+
const latest = reader.history(draft.sessionID).filter((row) => row.type === "assistant").at(-1);
|
|
44397
|
+
const tokens = latest?.data.tokens;
|
|
44398
|
+
const modelKey = `${draft.model.providerID}/${draft.model.id}`;
|
|
44399
|
+
if (!queriedModels.has(modelKey)) {
|
|
44400
|
+
const catalog = await context.catalog.model.list({
|
|
44401
|
+
location: context.location
|
|
44402
|
+
});
|
|
44403
|
+
for (const model of catalog.data)
|
|
44404
|
+
limits.set(`${model.providerID}/${model.id}`, model.limit.context);
|
|
44405
|
+
queriedModels.add(modelKey);
|
|
44406
|
+
}
|
|
44407
|
+
const limit = limits.get(modelKey);
|
|
44408
|
+
if (tokens && limit && Number.isFinite(limit) && limit > 0) {
|
|
44409
|
+
const inputTokens = tokens.input + tokens.cache.read + tokens.cache.write;
|
|
44410
|
+
unsafe = inputTokens / limit >= 0.95;
|
|
44411
|
+
const completed = latest?.data.time?.completed;
|
|
44412
|
+
if (typeof completed === "number")
|
|
44413
|
+
updateSessionMeta2(db, draft.sessionID, { lastResponseTime: completed });
|
|
44414
|
+
usage.set(draft.sessionID, {
|
|
44415
|
+
usage: { inputTokens, percentage: inputTokens / limit * 100 },
|
|
44416
|
+
hasUsageTokens: true,
|
|
44417
|
+
updatedAt: Date.now()
|
|
44418
|
+
});
|
|
44419
|
+
}
|
|
44420
|
+
} finally {
|
|
44421
|
+
reader.close();
|
|
44422
|
+
}
|
|
44423
|
+
} catch {
|
|
44424
|
+
unsafe = true;
|
|
44425
|
+
}
|
|
44426
|
+
if (unsafe)
|
|
44427
|
+
await interruptBeforeProvider(context.session, draft.sessionID);
|
|
44428
|
+
return unsafe;
|
|
44429
|
+
};
|
|
44430
|
+
const materialize = (draft) => {
|
|
44431
|
+
db ??= openDatabase();
|
|
44432
|
+
if (!db || !isDatabasePersisted(db))
|
|
44433
|
+
throw new Error("context storage is not durable");
|
|
44434
|
+
const state = getOrCreateSessionMeta2(db, draft.sessionID);
|
|
44435
|
+
return materializeM0({
|
|
44436
|
+
db,
|
|
44437
|
+
sessionId: draft.sessionID,
|
|
44438
|
+
state,
|
|
44439
|
+
projectPath: resolveProjectIdentity(directory) ?? directory,
|
|
44440
|
+
projectDirectory: directory,
|
|
44441
|
+
memoryEnabled: config.memory.enabled,
|
|
44442
|
+
memoryInjectionBudgetTokens: config.memory.injection_budget_tokens,
|
|
44443
|
+
hardSignals: {
|
|
44444
|
+
systemHash: foldDigest(JSON.stringify(draft.system)),
|
|
44445
|
+
toolSetHash: "",
|
|
44446
|
+
modelKey: `${draft.model.providerID}/${draft.model.id}`,
|
|
44447
|
+
cacheExpired: false,
|
|
44448
|
+
lastResponseTime: state.lastResponseTime
|
|
44449
|
+
}
|
|
44450
|
+
}).m0Text;
|
|
44451
|
+
};
|
|
44452
|
+
await context.session.hook("compaction", async (draft) => {
|
|
44453
|
+
const reader = new V2StoreReader(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
44454
|
+
try {
|
|
44455
|
+
const rows = reader.history(draft.sessionID);
|
|
44456
|
+
const ids = new Set(draft.messages.map((message) => message.id));
|
|
44457
|
+
const watermark = Math.max(-1, ...rows.filter((row) => ids.has(row.id)).map((row) => row.seq));
|
|
44458
|
+
const running = rows.filter((row) => row.type === "compaction" && row.data.status === "running").at(-1);
|
|
44459
|
+
const fold = await folds.supply({
|
|
44460
|
+
sessionID: draft.sessionID,
|
|
44461
|
+
watermark,
|
|
44462
|
+
runningCut: running?.seq,
|
|
44463
|
+
materialize: () => materialize(draft)
|
|
44464
|
+
});
|
|
44465
|
+
draft.result = { summary: fold.submitted };
|
|
44466
|
+
} catch (cause) {
|
|
44467
|
+
await interruptBeforeProvider(context.session, draft.sessionID);
|
|
44468
|
+
throw new V2ContextRefusal("Magic Context could not preserve the host checkpoint.", {
|
|
44469
|
+
cause
|
|
44470
|
+
});
|
|
44471
|
+
} finally {
|
|
44472
|
+
reader.close();
|
|
44473
|
+
}
|
|
44474
|
+
});
|
|
44475
|
+
await context.session.hook("context", async (draft) => {
|
|
44476
|
+
let postFold = false;
|
|
44477
|
+
try {
|
|
44478
|
+
if (await refuseIfUnsafe(draft))
|
|
44479
|
+
return;
|
|
44480
|
+
if (!db)
|
|
44481
|
+
return;
|
|
44482
|
+
const storage = db;
|
|
44483
|
+
updateSessionMeta2(db, draft.sessionID, {
|
|
44484
|
+
systemPromptHash: foldDigest(JSON.stringify(draft.system))
|
|
44485
|
+
});
|
|
44486
|
+
await preloadTokenizer();
|
|
44487
|
+
passDuties ??= createChatMessageHook({
|
|
44488
|
+
db,
|
|
44489
|
+
liveModelBySession: liveModels,
|
|
44490
|
+
variantBySession: variants,
|
|
44491
|
+
agentBySession: agents,
|
|
44492
|
+
historyRefreshSessions,
|
|
44493
|
+
pendingMaterializationSessions,
|
|
44494
|
+
lastHeuristicsTurnId,
|
|
44495
|
+
systemPromptRefreshSessions: new Set,
|
|
44496
|
+
cacheTtlConfig: config.cache_ttl,
|
|
44497
|
+
upgradeReminder: (sessionID) => maybeSendUpgradeReminder({
|
|
44498
|
+
db: storage,
|
|
44499
|
+
client: undefined,
|
|
44500
|
+
getNotificationParams: () => ({}),
|
|
44501
|
+
sendStatusNotification: async (_client, id, text) => {
|
|
44502
|
+
pushNotification2("toast", { message: text, variant: "info" }, id);
|
|
44503
|
+
return "queued";
|
|
44504
|
+
}
|
|
44505
|
+
}, sessionID)
|
|
44506
|
+
});
|
|
44507
|
+
await passDuties({
|
|
44508
|
+
sessionID: draft.sessionID,
|
|
44509
|
+
agent: draft.agent,
|
|
44510
|
+
variant: draft.model.variant,
|
|
44511
|
+
model: { providerID: draft.model.providerID, modelID: draft.model.id }
|
|
44512
|
+
});
|
|
44513
|
+
if (!rawProviders.has(draft.sessionID))
|
|
44514
|
+
rawProviders.set(draft.sessionID, setRawMessageProvider(draft.sessionID, {
|
|
44515
|
+
readMessages: () => read(draft.sessionID)
|
|
44516
|
+
}));
|
|
44517
|
+
transform ??= createTransform({
|
|
44518
|
+
db,
|
|
44519
|
+
tagger: createTagger(),
|
|
44520
|
+
scheduler: createScheduler({
|
|
44521
|
+
executeThresholdPercentage: config.execute_threshold_percentage
|
|
44522
|
+
}),
|
|
44523
|
+
contextUsageMap: usage,
|
|
44524
|
+
protectedTokens: config.protected_tokens,
|
|
44525
|
+
protectedTokenTierOverrides: getProtectedTokensTierOverrides(config),
|
|
44526
|
+
executeThresholdPercentage: config.execute_threshold_percentage,
|
|
44527
|
+
liveModelBySession: liveModels,
|
|
44528
|
+
channel1StateBySession: channel1,
|
|
44529
|
+
historyRefreshSessions,
|
|
44530
|
+
pendingMaterializationSessions,
|
|
44531
|
+
lastHeuristicsTurnId,
|
|
44532
|
+
variantBySession: variants,
|
|
44533
|
+
clearReasoningAge: config.clear_reasoning_age,
|
|
44534
|
+
directory,
|
|
44535
|
+
projectPath: directory,
|
|
44536
|
+
hiddenCompletionExecutor,
|
|
44537
|
+
historianRunnable: hiddenCompletionExecutor !== undefined && config.historian?.disable !== true,
|
|
44538
|
+
historianModel: historianModels.primary,
|
|
44539
|
+
fallbackModels: historianModels.fallbacks,
|
|
44540
|
+
historianTimeoutMs: config.historian_timeout_ms,
|
|
44541
|
+
historianMaxOutputTokens: config.historian?.maxTokens,
|
|
44542
|
+
historianTwoPass: config.historian?.two_pass,
|
|
44543
|
+
compactionMarkerStrategy: v2CompactionMarkerStrategy,
|
|
44544
|
+
memoryConfig: {
|
|
44545
|
+
enabled: config.memory.enabled,
|
|
44546
|
+
injectionBudgetTokens: config.memory.injection_budget_tokens,
|
|
44547
|
+
autoPromote: config.memory.auto_promote
|
|
44548
|
+
},
|
|
44549
|
+
...createHostSeams(context, pagedRead, liveModels)
|
|
44550
|
+
});
|
|
44551
|
+
const admitted = new Set;
|
|
44552
|
+
for (const message of draft.messages) {
|
|
44553
|
+
if (message.id && await isAdmittedSynthetic(context, draft.sessionID, message.id))
|
|
44554
|
+
admitted.add(message.id);
|
|
44555
|
+
}
|
|
44556
|
+
const reader = new V2StoreReader(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
44557
|
+
let checkpoint;
|
|
44558
|
+
let submitted;
|
|
44559
|
+
try {
|
|
44560
|
+
const cut = reader.latestCompaction(draft.sessionID);
|
|
44561
|
+
const incoming = cut && draft.messages.find((message) => message.id === cut.id);
|
|
44562
|
+
postFold = cut !== undefined;
|
|
44563
|
+
if (cut && !incoming)
|
|
44564
|
+
throw new Error("The host checkpoint disappeared from the context draft");
|
|
44565
|
+
if (cut && incoming) {
|
|
44566
|
+
const identity = await folds.observe({
|
|
44567
|
+
sessionID: draft.sessionID,
|
|
44568
|
+
cutSeq: cut.seq,
|
|
44569
|
+
summary: cut.data.summary ?? "",
|
|
44570
|
+
rendered: incoming,
|
|
44571
|
+
onHard: (reason) => {
|
|
44572
|
+
console.warn(`[magic-context] HARD reason=${reason} session=${draft.sessionID}`);
|
|
44573
|
+
materialize(draft);
|
|
44574
|
+
pendingMaterializationSessions.add(draft.sessionID);
|
|
44575
|
+
}
|
|
44576
|
+
});
|
|
44577
|
+
checkpoint = structuredClone(identity.rendered ?? incoming);
|
|
44578
|
+
submitted = identity.rendered ? identity.renderedSummary ?? identity.submitted : cut.data.summary ?? "";
|
|
44579
|
+
const all = reader.history(draft.sessionID);
|
|
44580
|
+
const boundaryID = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id = ?").get(draft.sessionID)?.id;
|
|
44581
|
+
const boundary = all.find((row) => row.id === boundaryID)?.seq ?? -1;
|
|
44582
|
+
const present = new Set(draft.messages.map((message) => message.id));
|
|
44583
|
+
const restored = all.filter((row) => row.seq > boundary && row.seq <= cut.seq && !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model));
|
|
44584
|
+
draft.messages.splice(0, draft.messages.length, ...restored, ...draft.messages.filter((message) => message !== incoming));
|
|
44585
|
+
}
|
|
44586
|
+
} finally {
|
|
44587
|
+
reader.close();
|
|
44588
|
+
}
|
|
44589
|
+
const mapped = adaptPayload(draft, admitted);
|
|
44590
|
+
await transform({}, mapped);
|
|
44591
|
+
mapped.commit();
|
|
44592
|
+
if (checkpoint && submitted !== undefined) {
|
|
44593
|
+
const head = draft.messages.find((message) => message.id === HEAD_IDS[0]);
|
|
44594
|
+
const baseline = head?.content.find((part) => part.type === "text")?.text;
|
|
44595
|
+
if (typeof baseline === "string") {
|
|
44596
|
+
for (const part of checkpoint.content)
|
|
44597
|
+
if (part.type === "text" && typeof part.text === "string") {
|
|
44598
|
+
part.text = part.text.replace(`<summary>
|
|
44599
|
+
${submitted}
|
|
44600
|
+
</summary>`, `<summary>
|
|
44601
|
+
${baseline}
|
|
44602
|
+
</summary>`);
|
|
44603
|
+
}
|
|
44604
|
+
const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
|
|
44605
|
+
if (volatile && head)
|
|
44606
|
+
volatile.content.push(...head.content.filter((part) => part.type !== "text"));
|
|
44607
|
+
draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== head));
|
|
44608
|
+
}
|
|
44609
|
+
}
|
|
44610
|
+
} catch (error) {
|
|
44611
|
+
if (error instanceof V2ContextRefusal)
|
|
44612
|
+
throw error;
|
|
44613
|
+
if (postFold) {
|
|
44614
|
+
await interruptBeforeProvider(context.session, draft.sessionID);
|
|
44615
|
+
throw new V2ContextRefusal("Magic Context could not restore the unarchived host history.", { cause: error });
|
|
44616
|
+
}
|
|
44617
|
+
console.warn("[magic-context] v2 context unavailable", error);
|
|
44618
|
+
}
|
|
44619
|
+
});
|
|
44620
|
+
return {
|
|
44621
|
+
async dispose() {
|
|
44622
|
+
await dreamTrigger?.dispose();
|
|
44623
|
+
for (const release of rawProviders.values())
|
|
44624
|
+
release();
|
|
44625
|
+
rawProviders.clear();
|
|
44626
|
+
}
|
|
44627
|
+
};
|
|
44628
|
+
}
|
|
44629
|
+
|
|
44630
|
+
// src/v2/hooks/update-check.ts
|
|
44631
|
+
import { existsSync as existsSync13, readFileSync as readFileSync7 } from "node:fs";
|
|
44632
|
+
import { dirname as dirname8, join as join12 } from "node:path";
|
|
44633
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
44634
|
+
function packageInfo() {
|
|
44635
|
+
let directory = dirname8(fileURLToPath3(import.meta.url));
|
|
44636
|
+
for (;; ) {
|
|
44637
|
+
try {
|
|
44638
|
+
const pkg = JSON.parse(readFileSync7(join12(directory, "package.json"), "utf8"));
|
|
44639
|
+
if (pkg.name === "@cortexkit/opencode-magic-context" && typeof pkg.version === "string") {
|
|
44640
|
+
return {
|
|
44641
|
+
version: pkg.version,
|
|
44642
|
+
development: existsSync13(join12(directory, "src/v2/server.ts"))
|
|
44643
|
+
};
|
|
44644
|
+
}
|
|
44645
|
+
} catch {}
|
|
44646
|
+
const parent = dirname8(directory);
|
|
44647
|
+
if (parent === directory)
|
|
44648
|
+
throw new Error("Magic Context package manifest is unavailable");
|
|
44649
|
+
directory = parent;
|
|
44650
|
+
}
|
|
44651
|
+
}
|
|
44652
|
+
function startUpdateChecks(context, check = (signal) => {
|
|
44653
|
+
return packageInfo().development ? Promise.resolve(null) : getLatestVersion("latest", { signal });
|
|
44654
|
+
}) {
|
|
44655
|
+
const controller = new AbortController;
|
|
44656
|
+
const done = (async () => {
|
|
44657
|
+
try {
|
|
44658
|
+
for await (const _event of context.event.subscribe({ signal: controller.signal })) {
|
|
44659
|
+
if (controller.signal.aborted)
|
|
44660
|
+
break;
|
|
44661
|
+
const last = await context.storage.get("version-check-at");
|
|
44662
|
+
if (typeof last === "number" && Date.now() - last < 60 * 60 * 1000)
|
|
44663
|
+
continue;
|
|
44664
|
+
await context.storage.set("version-check-at", Date.now());
|
|
44665
|
+
const latest = await check(controller.signal);
|
|
44666
|
+
const comparison = latest ? compareSemverCore(latest, packageInfo().version) : null;
|
|
44667
|
+
if (!controller.signal.aborted && comparison !== null && comparison > 0) {
|
|
44668
|
+
pushNotification2("toast", {
|
|
44669
|
+
message: `Magic Context ${latest} is available. Update the plugin to install it.`,
|
|
44670
|
+
variant: "info"
|
|
44671
|
+
});
|
|
44672
|
+
}
|
|
44673
|
+
}
|
|
44674
|
+
} catch (error) {
|
|
44675
|
+
if (!controller.signal.aborted)
|
|
44676
|
+
console.warn("[magic-context] v2 update check unavailable", error);
|
|
44677
|
+
}
|
|
44678
|
+
})();
|
|
44679
|
+
return {
|
|
44680
|
+
done,
|
|
44681
|
+
async dispose() {
|
|
44682
|
+
controller.abort();
|
|
44683
|
+
await done;
|
|
44684
|
+
}
|
|
44685
|
+
};
|
|
44686
|
+
}
|
|
44687
|
+
|
|
44688
|
+
// src/v2/server.ts
|
|
44689
|
+
async function setup(context) {
|
|
44690
|
+
setHarness("opencode2");
|
|
44691
|
+
const duties = await registerContext(context);
|
|
44692
|
+
const checks = loadPluginConfigDetailed(context.location.directory).config.auto_update === false ? undefined : startUpdateChecks(context);
|
|
44693
|
+
console.info("[magic-context] @cortexkit/opencode-magic-context v2 setup");
|
|
44694
|
+
return async () => {
|
|
44695
|
+
await checks?.dispose();
|
|
44696
|
+
await duties?.dispose();
|
|
44697
|
+
};
|
|
44698
|
+
}
|
|
44699
|
+
|
|
43386
44700
|
// src/index.ts
|
|
43387
44701
|
var BOOT_SERVER_DEADLINE_MS = 15000;
|
|
43388
44702
|
var RESOLVED_CONFIG_TIMEOUT_MS = 2000;
|
|
@@ -43435,7 +44749,7 @@ var server = async (ctx) => {
|
|
|
43435
44749
|
if (hasBannerEntries)
|
|
43436
44750
|
setTimeout(async () => {
|
|
43437
44751
|
try {
|
|
43438
|
-
const { sendStatusNotification } = await import("./send-session-notification-
|
|
44752
|
+
const { sendStatusNotification } = await import("./send-session-notification-xnypkxpx.js");
|
|
43439
44753
|
const clientWithSessions = ctx.client;
|
|
43440
44754
|
const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
|
|
43441
44755
|
const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
|
|
@@ -43452,7 +44766,7 @@ var server = async (ctx) => {
|
|
|
43452
44766
|
log(`[magic-context] opencode_db_missing path=${openCodeDbResolution.path} source=${openCodeDbResolution.source}`);
|
|
43453
44767
|
setTimeout(async () => {
|
|
43454
44768
|
try {
|
|
43455
|
-
const { sendStatusNotification } = await import("./send-session-notification-
|
|
44769
|
+
const { sendStatusNotification } = await import("./send-session-notification-xnypkxpx.js");
|
|
43456
44770
|
const clientWithSessions = ctx.client;
|
|
43457
44771
|
const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
|
|
43458
44772
|
const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
|
|
@@ -43484,9 +44798,9 @@ var server = async (ctx) => {
|
|
|
43484
44798
|
}
|
|
43485
44799
|
conflictMs = performance.now() - conflictStartedAt;
|
|
43486
44800
|
const liveSessionState = createLiveSessionState();
|
|
43487
|
-
const rustModeModuleTransport = pluginConfig.transform_mode === "rust" ? new SubcModuleTransport(pluginConfig.subc?.connection_file) : undefined;
|
|
44801
|
+
const rustModeModuleTransport = pluginConfig.transform_mode === "rust" ? new SubcModuleTransport(pluginConfig.subc?.connection_file ?? getDefaultSubcConnectionFile()) : undefined;
|
|
43488
44802
|
const rustModeModuleClient = rustModeModuleTransport;
|
|
43489
|
-
const sessionCleanupModuleClient = pluginConfig.enabled ? rustModeModuleTransport ?? new SubcModuleTransport(pluginConfig.subc?.connection_file) : undefined;
|
|
44803
|
+
const sessionCleanupModuleClient = pluginConfig.enabled ? rustModeModuleTransport ?? new SubcModuleTransport(pluginConfig.subc?.connection_file ?? getDefaultSubcConnectionFile()) : undefined;
|
|
43490
44804
|
const hooksPhase = await runBootPhaseWithinBudget(bootBudget, "hooks", () => createSessionHooksAsync({
|
|
43491
44805
|
ctx,
|
|
43492
44806
|
pluginConfig,
|
|
@@ -43698,12 +45012,12 @@ var server = async (ctx) => {
|
|
|
43698
45012
|
{
|
|
43699
45013
|
const fence = getSchemaFenceRejection();
|
|
43700
45014
|
if (fence) {
|
|
43701
|
-
import("./conflict-warning-hook-
|
|
45015
|
+
import("./conflict-warning-hook-jyj54gbe.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
|
|
43702
45016
|
}
|
|
43703
45017
|
}
|
|
43704
45018
|
const serverUrl = ctx.serverUrl;
|
|
43705
45019
|
const serverUrlStr = serverUrl instanceof URL ? serverUrl.toString().replace(/\/$/, "") : typeof serverUrl === "string" ? serverUrl.replace(/\/$/, "") : undefined;
|
|
43706
|
-
import("./send-session-notification-
|
|
45020
|
+
import("./send-session-notification-xnypkxpx.js").then(({ setNotificationServerUrl }) => {
|
|
43707
45021
|
setNotificationServerUrl(serverUrlStr);
|
|
43708
45022
|
});
|
|
43709
45023
|
if (conflictResult?.hasConflict) {
|
|
@@ -43717,7 +45031,7 @@ var server = async (ctx) => {
|
|
|
43717
45031
|
}
|
|
43718
45032
|
if (pluginConfig.enabled && !conflictResult?.hasConflict) {
|
|
43719
45033
|
setTimeout(() => {
|
|
43720
|
-
import("./announcement-
|
|
45034
|
+
import("./announcement-8mgn61fw.js").then(({
|
|
43721
45035
|
shouldShowAnnouncement,
|
|
43722
45036
|
ANNOUNCEMENT_VERSION,
|
|
43723
45037
|
ANNOUNCEMENT_FEATURES,
|
|
@@ -43726,7 +45040,7 @@ var server = async (ctx) => {
|
|
|
43726
45040
|
}) => {
|
|
43727
45041
|
if (!shouldShowAnnouncement())
|
|
43728
45042
|
return;
|
|
43729
|
-
return import("./conflict-warning-hook-
|
|
45043
|
+
return import("./conflict-warning-hook-jyj54gbe.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER, markAnnouncementSeen));
|
|
43730
45044
|
}).catch(() => {});
|
|
43731
45045
|
}, 8000);
|
|
43732
45046
|
}
|
|
@@ -43882,7 +45196,8 @@ var server = async (ctx) => {
|
|
|
43882
45196
|
};
|
|
43883
45197
|
var plugin = {
|
|
43884
45198
|
id: "opencode-magic-context",
|
|
43885
|
-
server
|
|
45199
|
+
server,
|
|
45200
|
+
setup
|
|
43886
45201
|
};
|
|
43887
45202
|
var src_default = plugin;
|
|
43888
45203
|
export {
|