@cortexkit/pi-magic-context 0.35.1 → 0.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -20
- package/dist/{index-zmyx6nf5.js → index-npnqc564.js} +8 -1
- package/dist/{index-gxftx2a4.js → index-zxgbtsnj.js} +1252 -380
- package/dist/index.js +483 -208
- package/dist/{safe-notification-target-ng8ygena.js → safe-notification-target-0s6j4m9f.js} +1 -1
- package/dist/subagent-entry.js +2 -2
- package/package.json +20 -4
package/dist/index.js
CHANGED
|
@@ -128,6 +128,7 @@ import {
|
|
|
128
128
|
getCompartmentsByEndMessageId,
|
|
129
129
|
getContextStoreUuid,
|
|
130
130
|
getDatabasePath,
|
|
131
|
+
getDroppedTagsByNumbers,
|
|
131
132
|
getEmbeddingCoverageStatus,
|
|
132
133
|
getEmergencyInputSample,
|
|
133
134
|
getErrorMessage,
|
|
@@ -246,6 +247,7 @@ import {
|
|
|
246
247
|
normalizeText,
|
|
247
248
|
normalizeTodoStateJson,
|
|
248
249
|
normalizeVerificationFiles,
|
|
250
|
+
ompModelRefToCanonical,
|
|
249
251
|
openDatabase,
|
|
250
252
|
openDatabaseAsync,
|
|
251
253
|
parkGitSweepNonIndexable,
|
|
@@ -256,6 +258,7 @@ import {
|
|
|
256
258
|
peelLeadingMcTagNotation,
|
|
257
259
|
persistCachedM0,
|
|
258
260
|
piModelRefToCanonical,
|
|
261
|
+
preloadTokenizer,
|
|
259
262
|
prependTag,
|
|
260
263
|
primeInMemoryTailRawMessageCache,
|
|
261
264
|
primeTailRawMessageCache,
|
|
@@ -309,6 +312,7 @@ import {
|
|
|
309
312
|
resolveGitTopLevel,
|
|
310
313
|
resolveLimit,
|
|
311
314
|
resolveModelConfigOrDefault,
|
|
315
|
+
resolveModelRefForOmp,
|
|
312
316
|
resolveModelRefForPi,
|
|
313
317
|
resolveMuralWire,
|
|
314
318
|
resolvePiStableId,
|
|
@@ -373,7 +377,7 @@ import {
|
|
|
373
377
|
withMigrationLanguageDirective,
|
|
374
378
|
withRawMessageProvider,
|
|
375
379
|
withRawSessionMessageCache
|
|
376
|
-
} from "./index-
|
|
380
|
+
} from "./index-zxgbtsnj.js";
|
|
377
381
|
import {
|
|
378
382
|
pushNotification
|
|
379
383
|
} from "./index-hw34xmzk.js";
|
|
@@ -385,7 +389,7 @@ import {
|
|
|
385
389
|
log,
|
|
386
390
|
sessionLog,
|
|
387
391
|
setHarness
|
|
388
|
-
} from "./index-
|
|
392
|
+
} from "./index-npnqc564.js";
|
|
389
393
|
import {
|
|
390
394
|
__require,
|
|
391
395
|
__toESM
|
|
@@ -1948,6 +1952,7 @@ function createCloneFilter(entries) {
|
|
|
1948
1952
|
const rawMessages = convertEntriesToRawMessages([...entries]);
|
|
1949
1953
|
const rawOrdinalById = new Map(rawMessages.map((message) => [message.id, message.ordinal]));
|
|
1950
1954
|
const validStateIds = new Set(rawOrdinalById.keys());
|
|
1955
|
+
const validOrdinals = new Set(rawOrdinalById.values());
|
|
1951
1956
|
for (const entry of entries) {
|
|
1952
1957
|
const id = entryId(entry);
|
|
1953
1958
|
if (id)
|
|
@@ -1957,6 +1962,8 @@ function createCloneFilter(entries) {
|
|
|
1957
1962
|
return {
|
|
1958
1963
|
resolveBoundaryOrdinal: (id) => rawOrdinalById.get(id),
|
|
1959
1964
|
includeMessageId,
|
|
1965
|
+
copySessionNotesAndFacts: true,
|
|
1966
|
+
mapOrdinal: (ordinal) => validOrdinals.has(ordinal) ? ordinal : undefined,
|
|
1960
1967
|
includeTag: (tag) => {
|
|
1961
1968
|
if (tag.type === "tool") {
|
|
1962
1969
|
return typeof tag.toolOwnerMessageId === "string" && includeMessageId(tag.toolOwnerMessageId);
|
|
@@ -2034,7 +2041,7 @@ async function handlePiCloneSessionStart(event, ctx, deps) {
|
|
|
2034
2041
|
if (result.pendingMarkerMigrated) {
|
|
2035
2042
|
deps.signalPendingMarker(destinationSessionId);
|
|
2036
2043
|
}
|
|
2037
|
-
writeLog(`[magic-context][pi] clone-inheritance: migrated compartments=${result.compartmentsCopied} tags=${result.tagsCopied} source=${sourceSessionId} dest=${destinationSessionId} reason=fork`);
|
|
2044
|
+
writeLog(`[magic-context][pi] clone-inheritance: migrated compartments=${result.compartmentsCopied} tags=${result.tagsCopied} notes=${result.notesCopied} facts=${result.factsCopied} source=${sourceSessionId} dest=${destinationSessionId} reason=fork`);
|
|
2038
2045
|
return result;
|
|
2039
2046
|
} catch (error) {
|
|
2040
2047
|
writeLog(`[magic-context][pi] clone-inheritance: failed source=${sourceSessionId} dest=${destinationSessionId} stage=${stage} error=${error instanceof Error ? error.message : String(error)}; run /ctx-wrapup to rebuild, or re-clone`);
|
|
@@ -2064,7 +2071,13 @@ function isEmptySidekickResult(text) {
|
|
|
2064
2071
|
|
|
2065
2072
|
// src/subagent-runner.ts
|
|
2066
2073
|
import * as childProcess from "node:child_process";
|
|
2067
|
-
import {
|
|
2074
|
+
import {
|
|
2075
|
+
existsSync as existsSync3,
|
|
2076
|
+
mkdtempSync,
|
|
2077
|
+
readFileSync as readFileSync2,
|
|
2078
|
+
rmSync,
|
|
2079
|
+
writeFileSync as writeFileSync2
|
|
2080
|
+
} from "node:fs";
|
|
2068
2081
|
import { createRequire } from "node:module";
|
|
2069
2082
|
import { homedir, tmpdir } from "node:os";
|
|
2070
2083
|
import {
|
|
@@ -2087,13 +2100,14 @@ var state = {
|
|
|
2087
2100
|
noticeEmitted: false,
|
|
2088
2101
|
failure: null
|
|
2089
2102
|
};
|
|
2090
|
-
function recordStaleFence(persistedVersion, supportedVersion) {
|
|
2103
|
+
function recordStaleFence(persistedVersion, supportedVersion, reason = "newer_schema") {
|
|
2091
2104
|
state.consecutiveFailures += 1;
|
|
2092
2105
|
state.totalFailures += 1;
|
|
2093
2106
|
const latched = state.consecutiveFailures >= STALE_CHILD_SPAWN_LATCH_THRESHOLD;
|
|
2094
2107
|
state.latched ||= latched;
|
|
2095
2108
|
const failure = {
|
|
2096
2109
|
failureClass: STALE_CHILD_SPAWN_FAILURE,
|
|
2110
|
+
reason,
|
|
2097
2111
|
persistedVersion,
|
|
2098
2112
|
supportedVersion,
|
|
2099
2113
|
consecutiveFailures: state.consecutiveFailures,
|
|
@@ -2120,7 +2134,7 @@ function probeChildSpawnFence(db) {
|
|
|
2120
2134
|
return recordStaleFence(persistedVersion, LATEST_SUPPORTED_VERSION);
|
|
2121
2135
|
}
|
|
2122
2136
|
} catch {
|
|
2123
|
-
return
|
|
2137
|
+
return recordStaleFence(LATEST_SUPPORTED_VERSION, LATEST_SUPPORTED_VERSION, "read_error");
|
|
2124
2138
|
}
|
|
2125
2139
|
state.consecutiveFailures = 0;
|
|
2126
2140
|
state.latched = false;
|
|
@@ -2263,7 +2277,61 @@ function resolveSubagentEntryPath() {
|
|
|
2263
2277
|
var SUBAGENT_ENTRY_PATH = resolveSubagentEntryPath();
|
|
2264
2278
|
var TERMINAL_DRAIN_GRACE_MS = 2000;
|
|
2265
2279
|
var MAGIC_CONTEXT_PI_SUBAGENT_ENV = "MAGIC_CONTEXT_PI_SUBAGENT";
|
|
2266
|
-
|
|
2280
|
+
function packageRootIsOmp(packageRoot) {
|
|
2281
|
+
try {
|
|
2282
|
+
const manifest = JSON.parse(readFileSync2(join2(packageRoot, "package.json"), "utf-8"));
|
|
2283
|
+
return manifest.name === "@oh-my-pi/pi-coding-agent";
|
|
2284
|
+
} catch {
|
|
2285
|
+
return false;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
function expandHomePath(value) {
|
|
2289
|
+
if (value === "~")
|
|
2290
|
+
return homedir();
|
|
2291
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
2292
|
+
return resolvePath(homedir(), value.slice(2));
|
|
2293
|
+
}
|
|
2294
|
+
return resolvePath(value);
|
|
2295
|
+
}
|
|
2296
|
+
function isOmpHostProcess() {
|
|
2297
|
+
const execName = basename(process.execPath).toLowerCase();
|
|
2298
|
+
if (/^omp(?:\.exe)?$/.test(execName))
|
|
2299
|
+
return true;
|
|
2300
|
+
const packageOverride = process.env.PI_PACKAGE_DIR?.trim();
|
|
2301
|
+
if (packageOverride && packageRootIsOmp(expandHomePath(packageOverride))) {
|
|
2302
|
+
return true;
|
|
2303
|
+
}
|
|
2304
|
+
let current = process.argv[1] ? dirname(resolvePath(process.argv[1])) : "";
|
|
2305
|
+
while (current) {
|
|
2306
|
+
if (packageRootIsOmp(current))
|
|
2307
|
+
return true;
|
|
2308
|
+
const parent = dirname(current);
|
|
2309
|
+
if (parent === current)
|
|
2310
|
+
break;
|
|
2311
|
+
current = parent;
|
|
2312
|
+
}
|
|
2313
|
+
return false;
|
|
2314
|
+
}
|
|
2315
|
+
function normalizedOmpProfile() {
|
|
2316
|
+
const raw = (process.env.OMP_PROFILE ?? process.env.PI_PROFILE)?.trim();
|
|
2317
|
+
return raw && raw !== "default" && /^[a-z0-9][a-z0-9._-]{0,63}$/.test(raw) ? raw : undefined;
|
|
2318
|
+
}
|
|
2319
|
+
function getHostAgentSettingsDir() {
|
|
2320
|
+
if (!isOmpHostProcess())
|
|
2321
|
+
return join2(homedir(), ".pi", "agent");
|
|
2322
|
+
const configRoot = join2(homedir(), process.env.PI_CONFIG_DIR?.trim() || ".omp");
|
|
2323
|
+
const profile = normalizedOmpProfile();
|
|
2324
|
+
if (profile)
|
|
2325
|
+
return join2(configRoot, "profiles", profile, "agent");
|
|
2326
|
+
const configured = process.env.PI_CODING_AGENT_DIR?.trim();
|
|
2327
|
+
return configured ? resolvePath(configured) : join2(configRoot, "agent");
|
|
2328
|
+
}
|
|
2329
|
+
function modelRefToCanonicalForHost(ref) {
|
|
2330
|
+
return isOmpHostProcess() ? ompModelRefToCanonical(ref) : piModelRefToCanonical(ref);
|
|
2331
|
+
}
|
|
2332
|
+
function resolveModelRefForHost(ref) {
|
|
2333
|
+
return isOmpHostProcess() ? resolveModelRefForOmp(ref) : resolveModelRefForPi(ref);
|
|
2334
|
+
}
|
|
2267
2335
|
var configuredSubagentExtensions;
|
|
2268
2336
|
function configurePiSubagentExtensions(extensions) {
|
|
2269
2337
|
configuredSubagentExtensions = extensions?.slice();
|
|
@@ -2271,7 +2339,7 @@ function configurePiSubagentExtensions(extensions) {
|
|
|
2271
2339
|
function resolveSubagentExtensionEntry(entry) {
|
|
2272
2340
|
const trimmed = entry.trim();
|
|
2273
2341
|
const isNpmSource = trimmed.startsWith("npm:");
|
|
2274
|
-
return !isNpmSource && !isAbsolute(trimmed) ? resolvePath(
|
|
2342
|
+
return !isNpmSource && !isAbsolute(trimmed) ? resolvePath(getHostAgentSettingsDir(), trimmed) : trimmed;
|
|
2275
2343
|
}
|
|
2276
2344
|
var PI_READ_ONLY_BUILTINS = ["read", "grep", "find", "ls"];
|
|
2277
2345
|
var PI_AFT_READ_TOOLS = ["aft_outline", "aft_zoom", "aft_search"];
|
|
@@ -2309,6 +2377,32 @@ var STRICT_TOOL_ALLOWLIST_ENTRIES = [
|
|
|
2309
2377
|
];
|
|
2310
2378
|
var STRICT_TOOL_ALLOWLIST = new Map(STRICT_TOOL_ALLOWLIST_ENTRIES);
|
|
2311
2379
|
var ZERO_TOOL_PROMPT_REQUIRED_AGENTS = new Set(STRICT_TOOL_ALLOWLIST_ENTRIES.filter(([, tools]) => tools.length === 0).map(([agent]) => agent));
|
|
2380
|
+
var OMP_TOOL_ALIASES = {
|
|
2381
|
+
find: "glob",
|
|
2382
|
+
ls: "glob"
|
|
2383
|
+
};
|
|
2384
|
+
var OMP_ALLOWLISTABLE_TOOLS = {
|
|
2385
|
+
read: true,
|
|
2386
|
+
grep: true,
|
|
2387
|
+
glob: true,
|
|
2388
|
+
bash: true,
|
|
2389
|
+
edit: true,
|
|
2390
|
+
write: true
|
|
2391
|
+
};
|
|
2392
|
+
function resolveHostToolAllowlist(tools, ompHost = isOmpHostProcess()) {
|
|
2393
|
+
if (!ompHost)
|
|
2394
|
+
return tools;
|
|
2395
|
+
const resolved = [];
|
|
2396
|
+
const seen = new Set;
|
|
2397
|
+
for (const tool of tools) {
|
|
2398
|
+
const mapped = OMP_TOOL_ALIASES[tool] ?? tool;
|
|
2399
|
+
if (OMP_ALLOWLISTABLE_TOOLS[mapped] !== true || seen.has(mapped))
|
|
2400
|
+
continue;
|
|
2401
|
+
seen.add(mapped);
|
|
2402
|
+
resolved.push(mapped);
|
|
2403
|
+
}
|
|
2404
|
+
return resolved;
|
|
2405
|
+
}
|
|
2312
2406
|
function inferAccountingSubagent(agent) {
|
|
2313
2407
|
if (agent.includes("sidekick"))
|
|
2314
2408
|
return "sidekick";
|
|
@@ -2882,11 +2976,11 @@ function replaceProviderPrefix(ref, provider) {
|
|
|
2882
2976
|
function resolveProviderModelAttempt(model) {
|
|
2883
2977
|
if (typeof model !== "string" || model.length === 0)
|
|
2884
2978
|
return;
|
|
2885
|
-
const canonicalRef =
|
|
2979
|
+
const canonicalRef = modelRefToCanonicalForHost(model);
|
|
2886
2980
|
const canonicalProvider = providerPrefix(canonicalRef);
|
|
2887
2981
|
if (!canonicalProvider)
|
|
2888
2982
|
return;
|
|
2889
|
-
const translatedRef =
|
|
2983
|
+
const translatedRef = resolveModelRefForHost(canonicalRef);
|
|
2890
2984
|
const translatedProvider = providerPrefix(translatedRef);
|
|
2891
2985
|
const cachedProvider = PI_PROVIDER_FORM_CACHE.get(canonicalProvider);
|
|
2892
2986
|
if (!translatedProvider || translatedProvider === canonicalProvider && cachedProvider === undefined) {
|
|
@@ -2906,14 +3000,14 @@ function isProviderCredentialFailure(result, attempt) {
|
|
|
2906
3000
|
}
|
|
2907
3001
|
var PROMPT_ARGV_MAX_BYTES = 96 * 1024;
|
|
2908
3002
|
function buildArgs(options, opts) {
|
|
3003
|
+
const ompHost = isOmpHostProcess();
|
|
2909
3004
|
const args = [
|
|
2910
3005
|
"--print",
|
|
2911
3006
|
"--mode",
|
|
2912
3007
|
"json",
|
|
2913
3008
|
"--no-session",
|
|
2914
3009
|
"--no-skills",
|
|
2915
|
-
"--no-prompt-templates",
|
|
2916
|
-
"--no-context-files"
|
|
3010
|
+
...ompHost ? ["--no-rules"] : ["--no-prompt-templates", "--no-context-files"]
|
|
2917
3011
|
];
|
|
2918
3012
|
if (opts?.disableDiscoveredExtensions || opts?.subagentExtensions !== undefined) {
|
|
2919
3013
|
args.push("--no-extensions");
|
|
@@ -2936,8 +3030,9 @@ function buildArgs(options, opts) {
|
|
|
2936
3030
|
sessionLog(options.accountingSessionId ?? "pi-subagent", `Pi subagent agent "${options.agent}" has no strict tool allow-list; forcing --no-tools`);
|
|
2937
3031
|
args.push("--no-tools");
|
|
2938
3032
|
} else {
|
|
2939
|
-
|
|
2940
|
-
|
|
3033
|
+
const hostTools = resolveHostToolAllowlist(strictTools, ompHost);
|
|
3034
|
+
if (hostTools.length > 0) {
|
|
3035
|
+
args.push("--tools", hostTools.join(","));
|
|
2941
3036
|
} else {
|
|
2942
3037
|
args.push("--no-tools");
|
|
2943
3038
|
}
|
|
@@ -2946,7 +3041,7 @@ function buildArgs(options, opts) {
|
|
|
2946
3041
|
args.push("--system-prompt", opts.systemPromptPath);
|
|
2947
3042
|
}
|
|
2948
3043
|
if (typeof options.model === "string" && options.model.length > 0) {
|
|
2949
|
-
args.push("--model", opts?.modelRef ??
|
|
3044
|
+
args.push("--model", opts?.modelRef ?? resolveModelRefForHost(options.model));
|
|
2950
3045
|
}
|
|
2951
3046
|
if (options.thinkingLevel) {
|
|
2952
3047
|
args.push("--thinking", options.thinkingLevel);
|
|
@@ -3206,16 +3301,16 @@ function claimExpectedState(db, expected) {
|
|
|
3206
3301
|
WHERE id = ? AND type = 'smart' AND status = 'pending'
|
|
3207
3302
|
AND content = ? AND surface_condition IS ? AND updated_at = ?${statusClause}`).run(...params).changes > 0;
|
|
3208
3303
|
}
|
|
3209
|
-
function getDueCompiledSmartNoteChecks(db, projectPath, now, limit) {
|
|
3210
|
-
return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && (note.checkQuarantinedUntil === null || note.checkQuarantinedUntil <= now) && (note.checkNextDueAt === null || note.checkNextDueAt <= now)).sort((a, b) => (a.checkNextDueAt ?? 0) - (b.checkNextDueAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
3304
|
+
function getDueCompiledSmartNoteChecks(db, projectPath, now, limit, retinaHandoff = false) {
|
|
3305
|
+
return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && (note.checkQuarantinedUntil === null || note.checkQuarantinedUntil <= now) && (note.checkNextDueAt === null || note.checkNextDueAt <= now)).sort((a, b) => (a.checkNextDueAt ?? 0) - (b.checkNextDueAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
3211
3306
|
}
|
|
3212
|
-
function getSmartNotesNeedingCompilation(db, projectPath, now, limit) {
|
|
3213
|
-
return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => (note.checkNextDueAt === null || note.checkNextDueAt <= now) && (note.checkStatus === "uncompiled" || note.checkStatus === "failing" || note.compiledCheck === null || note.policyVersion !== SMART_NOTE_CHECK_POLICY_VERSION)).sort((a, b) => a.createdAt - b.createdAt || a.id - b.id).slice(0, Math.max(1, limit));
|
|
3307
|
+
function getSmartNotesNeedingCompilation(db, projectPath, now, limit, retinaHandoff = false) {
|
|
3308
|
+
return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => (note.checkNextDueAt === null || note.checkNextDueAt <= now) && (note.checkStatus === "uncompiled" || note.checkStatus === "failing" || note.compiledCheck === null || note.policyVersion !== SMART_NOTE_CHECK_POLICY_VERSION)).sort((a, b) => a.createdAt - b.createdAt || a.id - b.id).slice(0, Math.max(1, limit));
|
|
3214
3309
|
}
|
|
3215
|
-
function getStaleCompiledSmartNotes(db, projectPath, now, limit) {
|
|
3310
|
+
function getStaleCompiledSmartNotes(db, projectPath, now, limit, retinaHandoff = false) {
|
|
3216
3311
|
const staleBefore = now - SMART_NOTE_CHECK_MAX_STALENESS_MS;
|
|
3217
3312
|
const livenessBefore = now - SMART_NOTE_CHECK_LIVENESS_RECHECK_MS;
|
|
3218
|
-
return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && note.checkFalseSinceAt !== null && note.checkFalseSinceAt <= staleBefore && (note.checkLastLivenessAt === null || note.checkLastLivenessAt <= livenessBefore)).sort((a, b) => (a.checkFalseSinceAt ?? 0) - (b.checkFalseSinceAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
3313
|
+
return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && note.checkFalseSinceAt !== null && note.checkFalseSinceAt <= staleBefore && (note.checkLastLivenessAt === null || note.checkLastLivenessAt <= livenessBefore)).sort((a, b) => (a.checkFalseSinceAt ?? 0) - (b.checkFalseSinceAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
3219
3314
|
}
|
|
3220
3315
|
function storeCompiledSmartNoteCheck(db, args) {
|
|
3221
3316
|
db.prepare(`UPDATE notes
|
|
@@ -3666,7 +3761,7 @@ async function sendIgnoredMessageNow(client, sessionId, text, params, forcePersi
|
|
|
3666
3761
|
queueIgnoredNotification({ client, sessionId, text, params, forcePersist });
|
|
3667
3762
|
return "queued";
|
|
3668
3763
|
}
|
|
3669
|
-
const { waitForSafeNotificationTarget } = await import("./safe-notification-target-
|
|
3764
|
+
const { waitForSafeNotificationTarget } = await import("./safe-notification-target-0s6j4m9f.js");
|
|
3670
3765
|
if (await waitForSafeNotificationTarget(client, sessionId) === "skip") {
|
|
3671
3766
|
sessionLog(sessionId, "notification skipped (session not titled yet)");
|
|
3672
3767
|
return "skipped";
|
|
@@ -3743,25 +3838,31 @@ async function sendIgnoredMessage(client, sessionId, text, params, forcePersist
|
|
|
3743
3838
|
|
|
3744
3839
|
// ../plugin/src/hooks/magic-context/child-session-spawn.ts
|
|
3745
3840
|
var STALE_PLUGIN_RESTART_NOTICE = "Magic Context: plugin build is older than its database — restart OpenCode";
|
|
3746
|
-
|
|
3841
|
+
var SCHEMA_PROBE_FAILURE_NOTICE = `Magic Context: unable to verify the database schema before spawning a child — run ${FAIL_CLOSED_DOCTOR_COMMAND}`;
|
|
3842
|
+
async function surfaceSchemaFenceFailure(args, failure) {
|
|
3747
3843
|
if (!args.parentSessionId)
|
|
3748
3844
|
return;
|
|
3749
|
-
|
|
3750
|
-
|
|
3845
|
+
const notice = failure.reason === "read_error" ? SCHEMA_PROBE_FAILURE_NOTICE : STALE_PLUGIN_RESTART_NOTICE;
|
|
3846
|
+
if (args.db) {
|
|
3847
|
+
try {
|
|
3751
3848
|
updateSessionMeta(args.db, args.parentSessionId, {
|
|
3752
|
-
lastTransformError:
|
|
3849
|
+
lastTransformError: notice
|
|
3753
3850
|
});
|
|
3851
|
+
} catch (error) {
|
|
3852
|
+
sessionLog(args.parentSessionId, `schema-fence warning persistence failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3754
3853
|
}
|
|
3854
|
+
}
|
|
3855
|
+
try {
|
|
3755
3856
|
pushNotification("toast", {
|
|
3756
3857
|
title: "Magic Context",
|
|
3757
|
-
message:
|
|
3858
|
+
message: notice,
|
|
3758
3859
|
variant: "error",
|
|
3759
3860
|
duration: 1e4
|
|
3760
3861
|
}, args.parentSessionId);
|
|
3761
3862
|
pushNotification("action", { action: "refresh-sidebar" }, args.parentSessionId);
|
|
3762
|
-
await sendIgnoredMessage(args.client, args.parentSessionId,
|
|
3863
|
+
await sendIgnoredMessage(args.client, args.parentSessionId, notice, args.notificationParams ?? {}, true);
|
|
3763
3864
|
} catch (error) {
|
|
3764
|
-
sessionLog(args.parentSessionId, `
|
|
3865
|
+
sessionLog(args.parentSessionId, `schema-fence warning delivery failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3765
3866
|
}
|
|
3766
3867
|
}
|
|
3767
3868
|
async function createChildSessionWithFence(args) {
|
|
@@ -3774,7 +3875,7 @@ async function createChildSessionWithFence(args) {
|
|
|
3774
3875
|
if (args.onFenceLatched)
|
|
3775
3876
|
await args.onFenceLatched(verdict.failure);
|
|
3776
3877
|
else
|
|
3777
|
-
await
|
|
3878
|
+
await surfaceSchemaFenceFailure(args, verdict.failure);
|
|
3778
3879
|
}
|
|
3779
3880
|
return null;
|
|
3780
3881
|
}
|
|
@@ -4166,7 +4267,7 @@ function parseFields(json) {
|
|
|
4166
4267
|
}
|
|
4167
4268
|
|
|
4168
4269
|
// ../plugin/src/features/magic-context/mural/compress-cues.ts
|
|
4169
|
-
import { createHash as
|
|
4270
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
4170
4271
|
|
|
4171
4272
|
// ../plugin/src/features/magic-context/dreamer/storage-dream-state.ts
|
|
4172
4273
|
var getDreamStateStatements = new WeakMap;
|
|
@@ -4215,13 +4316,15 @@ function rowKeys(leaseKey) {
|
|
|
4215
4316
|
return {
|
|
4216
4317
|
holder: "dreaming_lease_holder",
|
|
4217
4318
|
heartbeat: "dreaming_lease_heartbeat",
|
|
4218
|
-
expiry: "dreaming_lease_expiry"
|
|
4319
|
+
expiry: "dreaming_lease_expiry",
|
|
4320
|
+
generation: "dreaming_lease_generation"
|
|
4219
4321
|
};
|
|
4220
4322
|
}
|
|
4221
4323
|
return {
|
|
4222
4324
|
holder: `lease:${leaseKey}:holder`,
|
|
4223
4325
|
heartbeat: `lease:${leaseKey}:heartbeat`,
|
|
4224
|
-
expiry: `lease:${leaseKey}:expiry
|
|
4326
|
+
expiry: `lease:${leaseKey}:expiry`,
|
|
4327
|
+
generation: `lease:${leaseKey}:generation`
|
|
4225
4328
|
};
|
|
4226
4329
|
}
|
|
4227
4330
|
function getLeaseExpiry(db, keys) {
|
|
@@ -4239,6 +4342,13 @@ function isLeaseActive(db, leaseKey = DREAMING_LEASE_KEY) {
|
|
|
4239
4342
|
function getLeaseHolder(db, leaseKey = DREAMING_LEASE_KEY) {
|
|
4240
4343
|
return getDreamState(db, rowKeys(leaseKey).holder);
|
|
4241
4344
|
}
|
|
4345
|
+
function getLeaseGeneration(db, leaseKey = DREAMING_LEASE_KEY) {
|
|
4346
|
+
const value = getDreamState(db, rowKeys(leaseKey).generation);
|
|
4347
|
+
if (!value)
|
|
4348
|
+
return null;
|
|
4349
|
+
const generation = Number(value);
|
|
4350
|
+
return Number.isSafeInteger(generation) && generation > 0 ? generation : null;
|
|
4351
|
+
}
|
|
4242
4352
|
function peekLeaseHolderAndExpiry(db, expectedHolder, leaseKey = DREAMING_LEASE_KEY) {
|
|
4243
4353
|
const keys = rowKeys(leaseKey);
|
|
4244
4354
|
const holder = getDreamState(db, keys.holder);
|
|
@@ -4250,6 +4360,9 @@ function peekLeaseHolderAndExpiry(db, expectedHolder, leaseKey = DREAMING_LEASE_
|
|
|
4250
4360
|
const expiry = Number(expiryStr);
|
|
4251
4361
|
return Number.isFinite(expiry) && expiry >= Date.now();
|
|
4252
4362
|
}
|
|
4363
|
+
function leaseOwnershipMatches(db, expectedHolder, expectedGeneration, leaseKey = DREAMING_LEASE_KEY) {
|
|
4364
|
+
return getLeaseGeneration(db, leaseKey) === expectedGeneration && peekLeaseHolderAndExpiry(db, expectedHolder, leaseKey);
|
|
4365
|
+
}
|
|
4253
4366
|
function runImmediate(db, body) {
|
|
4254
4367
|
db.exec("BEGIN IMMEDIATE");
|
|
4255
4368
|
let committed = false;
|
|
@@ -4266,26 +4379,30 @@ function runImmediate(db, body) {
|
|
|
4266
4379
|
}
|
|
4267
4380
|
}
|
|
4268
4381
|
}
|
|
4269
|
-
function
|
|
4382
|
+
function acquireLeaseWithAcquisition(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
|
|
4270
4383
|
const keys = rowKeys(leaseKey);
|
|
4271
4384
|
return runImmediate(db, () => {
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
return false;
|
|
4276
|
-
}
|
|
4385
|
+
const existingHolder = getLeaseHolder(db, leaseKey);
|
|
4386
|
+
if (isLeaseActive(db, leaseKey) && existingHolder && existingHolder !== holderId) {
|
|
4387
|
+
return null;
|
|
4277
4388
|
}
|
|
4278
4389
|
const now = Date.now();
|
|
4390
|
+
const priorGeneration = getLeaseGeneration(db, leaseKey) ?? 0;
|
|
4391
|
+
const generation = existingHolder === holderId ? Math.max(1, priorGeneration) : priorGeneration + 1;
|
|
4279
4392
|
setDreamState(db, keys.holder, holderId);
|
|
4280
4393
|
setDreamState(db, keys.heartbeat, String(now));
|
|
4281
4394
|
setDreamState(db, keys.expiry, String(now + LEASE_DURATION_MS));
|
|
4282
|
-
|
|
4395
|
+
setDreamState(db, keys.generation, String(generation));
|
|
4396
|
+
return { acquiredAt: now, generation };
|
|
4283
4397
|
});
|
|
4284
4398
|
}
|
|
4285
|
-
function
|
|
4399
|
+
function acquireLease(db, holderId, leaseKey = DREAMING_LEASE_KEY) {
|
|
4400
|
+
return acquireLeaseWithAcquisition(db, holderId, leaseKey) !== null;
|
|
4401
|
+
}
|
|
4402
|
+
function renewLease(db, holderId, leaseKey = DREAMING_LEASE_KEY, expectedGeneration) {
|
|
4286
4403
|
const keys = rowKeys(leaseKey);
|
|
4287
4404
|
return runImmediate(db, () => {
|
|
4288
|
-
if (getLeaseHolder(db, leaseKey) !== holderId || !isLeaseActive(db, leaseKey)) {
|
|
4405
|
+
if (getLeaseHolder(db, leaseKey) !== holderId || !isLeaseActive(db, leaseKey) || expectedGeneration !== undefined && getLeaseGeneration(db, leaseKey) !== expectedGeneration) {
|
|
4289
4406
|
return false;
|
|
4290
4407
|
}
|
|
4291
4408
|
const now = Date.now();
|
|
@@ -4303,9 +4420,12 @@ function runLeaseGuardedWrite(db, holderId, leaseKey, fn) {
|
|
|
4303
4420
|
});
|
|
4304
4421
|
}
|
|
4305
4422
|
var LEASE_HEARTBEAT_INTERVAL_MS = 60 * 1000;
|
|
4306
|
-
function startLeaseHeartbeat(db, holderId, leaseKey, onLost,
|
|
4423
|
+
function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalOrAcquisition = LEASE_HEARTBEAT_INTERVAL_MS) {
|
|
4424
|
+
const intervalMs = typeof intervalOrAcquisition === "number" ? intervalOrAcquisition : LEASE_HEARTBEAT_INTERVAL_MS;
|
|
4425
|
+
const acquisition = typeof intervalOrAcquisition === "number" ? undefined : intervalOrAcquisition;
|
|
4307
4426
|
let lost = false;
|
|
4308
|
-
let
|
|
4427
|
+
let expectedGeneration = acquisition?.generation ?? getLeaseGeneration(db, leaseKey);
|
|
4428
|
+
let lastConfirmedAt = acquisition?.acquiredAt ?? Date.now();
|
|
4309
4429
|
const declareLost = (reason) => {
|
|
4310
4430
|
if (lost)
|
|
4311
4431
|
return;
|
|
@@ -4316,15 +4436,25 @@ function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalMs = LEASE_
|
|
|
4316
4436
|
if (lost)
|
|
4317
4437
|
return;
|
|
4318
4438
|
try {
|
|
4319
|
-
if (renewLease(db, holderId, leaseKey)) {
|
|
4439
|
+
if (renewLease(db, holderId, leaseKey, expectedGeneration === null ? undefined : expectedGeneration)) {
|
|
4320
4440
|
lastConfirmedAt = Date.now();
|
|
4321
4441
|
return;
|
|
4322
4442
|
}
|
|
4443
|
+
if (expectedGeneration !== null && getLeaseGeneration(db, leaseKey) !== expectedGeneration) {
|
|
4444
|
+
declareLost("lease generation changed — another holder acquired it");
|
|
4445
|
+
return;
|
|
4446
|
+
}
|
|
4323
4447
|
if (Date.now() - lastConfirmedAt > LEASE_DURATION_MS) {
|
|
4324
4448
|
declareLost("lease lapsed past TTL — another holder may have run");
|
|
4325
4449
|
return;
|
|
4326
4450
|
}
|
|
4327
|
-
|
|
4451
|
+
const reacquired = acquireLeaseWithAcquisition(db, holderId, leaseKey);
|
|
4452
|
+
if (reacquired) {
|
|
4453
|
+
if (expectedGeneration !== null && reacquired.generation !== expectedGeneration) {
|
|
4454
|
+
declareLost("lease generation changed during reacquisition");
|
|
4455
|
+
return;
|
|
4456
|
+
}
|
|
4457
|
+
expectedGeneration = reacquired.generation;
|
|
4328
4458
|
lastConfirmedAt = Date.now();
|
|
4329
4459
|
return;
|
|
4330
4460
|
}
|
|
@@ -4393,6 +4523,16 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
|
|
|
4393
4523
|
}
|
|
4394
4524
|
|
|
4395
4525
|
// ../plugin/src/features/magic-context/dreamer/module-apply.ts
|
|
4526
|
+
class DreamerModuleBusyError extends Error {
|
|
4527
|
+
state;
|
|
4528
|
+
transient = true;
|
|
4529
|
+
constructor(state2) {
|
|
4530
|
+
super(`Rust memory authority is ${state2}; dreamer mutation deferred until authority settles.`);
|
|
4531
|
+
this.state = state2;
|
|
4532
|
+
this.name = "DreamerModuleBusyError";
|
|
4533
|
+
}
|
|
4534
|
+
}
|
|
4535
|
+
|
|
4396
4536
|
class DreamerModuleFailureError extends Error {
|
|
4397
4537
|
transient = true;
|
|
4398
4538
|
constructor(operation, cause) {
|
|
@@ -4414,9 +4554,12 @@ async function resolveDreamerModuleRoute(args) {
|
|
|
4414
4554
|
projectRoot: args.projectRoot,
|
|
4415
4555
|
domain: "memories"
|
|
4416
4556
|
});
|
|
4417
|
-
|
|
4557
|
+
const authority = result.authority;
|
|
4558
|
+
if (authority?.state === "DRAINING")
|
|
4559
|
+
throw new DreamerModuleBusyError(authority.state);
|
|
4560
|
+
if (authority?.state !== "MODULE")
|
|
4418
4561
|
return;
|
|
4419
|
-
const generation =
|
|
4562
|
+
const generation = authority.generation;
|
|
4420
4563
|
if (typeof generation !== "number")
|
|
4421
4564
|
throw new Error("Rust authority status omitted generation");
|
|
4422
4565
|
return {
|
|
@@ -4450,6 +4593,68 @@ function getModuleMemoryIdentities(db, projectIdentity, contextIds) {
|
|
|
4450
4593
|
] : []));
|
|
4451
4594
|
}
|
|
4452
4595
|
|
|
4596
|
+
// ../plugin/src/features/magic-context/dreamer/provider-output-failure.ts
|
|
4597
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
4598
|
+
var MAX_NEAR_ZERO_OUTPUT_TOKENS = 32;
|
|
4599
|
+
|
|
4600
|
+
class DreamerProviderOutputFailureError extends Error {
|
|
4601
|
+
fingerprint;
|
|
4602
|
+
outputTokens;
|
|
4603
|
+
reasoningTokens;
|
|
4604
|
+
transient = true;
|
|
4605
|
+
constructor(fingerprint, outputTokens, reasoningTokens, responseText) {
|
|
4606
|
+
const preview = responseText.trim().replace(/\s+/g, " ").slice(0, 160);
|
|
4607
|
+
super(`dreamer provider-outage completion (output_tokens=${outputTokens}, reasoning_tokens=${reasoningTokens}): ${JSON.stringify(preview)}`);
|
|
4608
|
+
this.fingerprint = fingerprint;
|
|
4609
|
+
this.outputTokens = outputTokens;
|
|
4610
|
+
this.reasoningTokens = reasoningTokens;
|
|
4611
|
+
this.name = "DreamerProviderOutputFailureError";
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
function finiteTokenCount(value) {
|
|
4615
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
4616
|
+
}
|
|
4617
|
+
function completionShape(value) {
|
|
4618
|
+
if (!isRecord(value))
|
|
4619
|
+
return null;
|
|
4620
|
+
const info = isRecord(value.info) ? value.info : value;
|
|
4621
|
+
if (info.role !== "assistant")
|
|
4622
|
+
return null;
|
|
4623
|
+
const time = isRecord(info.time) ? info.time : null;
|
|
4624
|
+
const tokens = isRecord(info.tokens) ? info.tokens : null;
|
|
4625
|
+
return {
|
|
4626
|
+
createdAt: typeof time?.created === "number" ? time.created : 0,
|
|
4627
|
+
finish: typeof info.finish === "string" ? info.finish : typeof info.finish_reason === "string" ? info.finish_reason : typeof info.finishReason === "string" ? info.finishReason : null,
|
|
4628
|
+
error: info.error,
|
|
4629
|
+
outputTokens: finiteTokenCount(tokens?.output),
|
|
4630
|
+
reasoningTokens: finiteTokenCount(tokens?.reasoning)
|
|
4631
|
+
};
|
|
4632
|
+
}
|
|
4633
|
+
function latestAssistantCompletion(messages) {
|
|
4634
|
+
if (!Array.isArray(messages))
|
|
4635
|
+
return null;
|
|
4636
|
+
let latest = null;
|
|
4637
|
+
for (const message of messages) {
|
|
4638
|
+
const completion = completionShape(message);
|
|
4639
|
+
if (completion && (!latest || completion.createdAt >= latest.createdAt))
|
|
4640
|
+
latest = completion;
|
|
4641
|
+
}
|
|
4642
|
+
return latest;
|
|
4643
|
+
}
|
|
4644
|
+
function providerOutputFailureFromInvalidManifest(messages, responseText) {
|
|
4645
|
+
const completion = latestAssistantCompletion(messages);
|
|
4646
|
+
if (completion?.finish?.toLowerCase() !== "stop")
|
|
4647
|
+
return null;
|
|
4648
|
+
if (completion.error != null || completion.outputTokens === null || completion.outputTokens > MAX_NEAR_ZERO_OUTPUT_TOKENS || completion.reasoningTokens !== 0) {
|
|
4649
|
+
return null;
|
|
4650
|
+
}
|
|
4651
|
+
const normalized = responseText.trim().replace(/\s+/g, " ").toLowerCase();
|
|
4652
|
+
if (!normalized)
|
|
4653
|
+
return null;
|
|
4654
|
+
const fingerprint = createHash2("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
4655
|
+
return new DreamerProviderOutputFailureError(fingerprint, completion.outputTokens, completion.reasoningTokens, responseText);
|
|
4656
|
+
}
|
|
4657
|
+
|
|
4453
4658
|
// ../plugin/src/features/magic-context/mural/compress-cues-prompt.ts
|
|
4454
4659
|
var CUE_BUDGET_HIGH = 90;
|
|
4455
4660
|
var CUE_BUDGET_LOW = 50;
|
|
@@ -4622,7 +4827,7 @@ async function runCompressCues(args) {
|
|
|
4622
4827
|
chunks.push(candidates.slice(i, i + COMPRESS_CUES_CHUNK_SIZE));
|
|
4623
4828
|
}
|
|
4624
4829
|
const abortController = new AbortController;
|
|
4625
|
-
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
|
|
4830
|
+
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
|
|
4626
4831
|
try {
|
|
4627
4832
|
let consecutiveTimeouts = 0;
|
|
4628
4833
|
let timeoutStreakElapsedMs = [];
|
|
@@ -4717,7 +4922,14 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
4717
4922
|
const text = extractLatestAssistantText(messages);
|
|
4718
4923
|
if (!text)
|
|
4719
4924
|
throw new Error("compress-cues returned no output");
|
|
4720
|
-
|
|
4925
|
+
try {
|
|
4926
|
+
parseCuesManifest(text);
|
|
4927
|
+
} catch (error) {
|
|
4928
|
+
const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
|
|
4929
|
+
if (providerFailure)
|
|
4930
|
+
throw providerFailure;
|
|
4931
|
+
throw error;
|
|
4932
|
+
}
|
|
4721
4933
|
return text;
|
|
4722
4934
|
}
|
|
4723
4935
|
});
|
|
@@ -4725,7 +4937,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
4725
4937
|
} catch (error) {
|
|
4726
4938
|
const desc = describeError(error);
|
|
4727
4939
|
log(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
4728
|
-
if (signal.aborted)
|
|
4940
|
+
if (signal.aborted || error instanceof DreamerProviderOutputFailureError)
|
|
4729
4941
|
throw error;
|
|
4730
4942
|
return {
|
|
4731
4943
|
compressed: 0,
|
|
@@ -4833,7 +5045,7 @@ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
|
|
|
4833
5045
|
log(`[dreamer] compress-cues: skipped cue for memory ${entry.id} (${failure.reason}; rejection ${rejectionCount}/${CUE_REJECTION_LATCH_THRESHOLD})`);
|
|
4834
5046
|
}
|
|
4835
5047
|
}
|
|
4836
|
-
const commandId = `mural-cues:${route.moduleCommandId}:${
|
|
5048
|
+
const commandId = `mural-cues:${route.moduleCommandId}:${createHash3("sha256").update(chunk.map((candidate) => candidate.memory.id).join(",")).digest("hex").slice(0, 24)}`;
|
|
4837
5049
|
let response;
|
|
4838
5050
|
try {
|
|
4839
5051
|
response = await route.moduleClient.call({
|
|
@@ -5275,7 +5487,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
5275
5487
|
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, leaseKey, (reason) => {
|
|
5276
5488
|
log(`[dreamer] user-memories: lease lost (${reason}) — aborting`);
|
|
5277
5489
|
abortController.abort();
|
|
5278
|
-
});
|
|
5490
|
+
}, args.leaseAcquisition);
|
|
5279
5491
|
try {
|
|
5280
5492
|
const createResponse = await createChildSessionWithFence({
|
|
5281
5493
|
client: args.client,
|
|
@@ -5398,7 +5610,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
5398
5610
|
}
|
|
5399
5611
|
|
|
5400
5612
|
// ../plugin/src/features/magic-context/dreamer/classify.ts
|
|
5401
|
-
import { createHash as
|
|
5613
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
5402
5614
|
|
|
5403
5615
|
// ../plugin/src/plugin/rust-tool-backends.ts
|
|
5404
5616
|
function isRustAuthorityDrainingError(error) {
|
|
@@ -5782,7 +5994,7 @@ async function runClassify(args) {
|
|
|
5782
5994
|
chunks.push(toClassify.slice(i, i + CLASSIFY_CHUNK_SIZE));
|
|
5783
5995
|
}
|
|
5784
5996
|
const abortController = new AbortController;
|
|
5785
|
-
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
|
|
5997
|
+
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
|
|
5786
5998
|
try {
|
|
5787
5999
|
for (let i = 0;i < chunks.length; i += 1) {
|
|
5788
6000
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
@@ -5862,7 +6074,14 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
|
5862
6074
|
const text = extractLatestAssistantText(messages);
|
|
5863
6075
|
if (!text)
|
|
5864
6076
|
throw new Error("classify returned no output");
|
|
5865
|
-
|
|
6077
|
+
try {
|
|
6078
|
+
parseClassifyManifest(text);
|
|
6079
|
+
} catch (error) {
|
|
6080
|
+
const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
|
|
6081
|
+
if (providerFailure)
|
|
6082
|
+
throw providerFailure;
|
|
6083
|
+
throw error;
|
|
6084
|
+
}
|
|
5866
6085
|
return text;
|
|
5867
6086
|
}
|
|
5868
6087
|
});
|
|
@@ -5873,7 +6092,7 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
|
5873
6092
|
const desc = describeError(failure);
|
|
5874
6093
|
log(`[dreamer] classify chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
5875
6094
|
recordInvocation(args, startedAt, { status: "failed", error: failure });
|
|
5876
|
-
if (moduleRoute || signal.aborted)
|
|
6095
|
+
if (moduleRoute || signal.aborted || failure instanceof DreamerProviderOutputFailureError)
|
|
5877
6096
|
throw failure;
|
|
5878
6097
|
return { classified: 0, changed: 0 };
|
|
5879
6098
|
} finally {
|
|
@@ -5902,7 +6121,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
|
|
|
5902
6121
|
v: 1,
|
|
5903
6122
|
session_id: args.moduleSessionId,
|
|
5904
6123
|
task: "classify",
|
|
5905
|
-
command_id: `classify:${args.moduleCommandId ?? Date.now()}:${
|
|
6124
|
+
command_id: `classify:${args.moduleCommandId ?? Date.now()}:${createHash4("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`,
|
|
5906
6125
|
authority_generation: args.moduleAuthorityGeneration,
|
|
5907
6126
|
payload: {
|
|
5908
6127
|
prompt_body: prompt,
|
|
@@ -6540,7 +6759,7 @@ function throwIfAborted2(signal) {
|
|
|
6540
6759
|
}
|
|
6541
6760
|
|
|
6542
6761
|
// ../plugin/src/features/magic-context/smart-notes/compiler.ts
|
|
6543
|
-
import { createHash as
|
|
6762
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
6544
6763
|
|
|
6545
6764
|
// ../plugin/src/features/magic-context/smart-notes/compiler-prompt.ts
|
|
6546
6765
|
var SMART_NOTE_COMPILER_SYSTEM_PROMPT = `You are the Magic Context smart-note compiler for the magic-context system.
|
|
@@ -6964,7 +7183,7 @@ function manifestAdvisoryWarnings(code, manifest) {
|
|
|
6964
7183
|
return warnings;
|
|
6965
7184
|
}
|
|
6966
7185
|
function hashCheck(surfaceCondition, compiledCheck, manifest, checkCron) {
|
|
6967
|
-
return
|
|
7186
|
+
return createHash5("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
|
|
6968
7187
|
}
|
|
6969
7188
|
function extractJsonObject(output) {
|
|
6970
7189
|
const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
@@ -7055,7 +7274,7 @@ var MAX_FAILURES_BEFORE_REAUTHOR = 3;
|
|
|
7055
7274
|
async function runDueCompiledSmartNoteChecks(args) {
|
|
7056
7275
|
const startedAt = Date.now();
|
|
7057
7276
|
const now = args.now ?? startedAt;
|
|
7058
|
-
const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS);
|
|
7277
|
+
const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS, args.retinaHandoff);
|
|
7059
7278
|
let ran = 0;
|
|
7060
7279
|
let surfaced = 0;
|
|
7061
7280
|
let failed = 0;
|
|
@@ -7185,7 +7404,8 @@ async function evaluateSmartNotes(args) {
|
|
|
7185
7404
|
const projectRoot = args.sessionDirectory ?? args.projectIdentity;
|
|
7186
7405
|
const moduleBridge = getModuleNoteEvaluationBridge(args.projectIdentity);
|
|
7187
7406
|
await moduleBridge?.sync();
|
|
7188
|
-
const
|
|
7407
|
+
const pendingNotes = () => getPendingSmartNotes(args.db, args.projectIdentity).filter((note) => !args.retinaHandoff || note.compileStatus !== "compiled");
|
|
7408
|
+
const pendingAtStart = pendingNotes().length;
|
|
7189
7409
|
if (pendingAtStart === 0) {
|
|
7190
7410
|
log("[dreamer] smart notes: no pending notes");
|
|
7191
7411
|
return { surfaced: 0, pending: 0, ran: false };
|
|
@@ -7204,12 +7424,12 @@ async function evaluateSmartNotes(args) {
|
|
|
7204
7424
|
leaseAbortController.abort(new Error("Dream lease lost during smart notes"));
|
|
7205
7425
|
log("[dreamer] smart notes: lease lost — aborting");
|
|
7206
7426
|
args.onLeaseLost?.("smart notes");
|
|
7207
|
-
});
|
|
7427
|
+
}, args.leaseAcquisition);
|
|
7208
7428
|
let surfaced = 0;
|
|
7209
7429
|
let didWork = false;
|
|
7210
7430
|
try {
|
|
7211
7431
|
if (moduleBridge) {
|
|
7212
|
-
const candidates2 =
|
|
7432
|
+
const candidates2 = pendingNotes().slice(0, MAX_COMPILE_PER_RUN);
|
|
7213
7433
|
for (const note of candidates2) {
|
|
7214
7434
|
if (Date.now() >= args.deadline)
|
|
7215
7435
|
break;
|
|
@@ -7230,7 +7450,7 @@ async function evaluateSmartNotes(args) {
|
|
|
7230
7450
|
surfaced += 1;
|
|
7231
7451
|
}
|
|
7232
7452
|
await moduleBridge.sync();
|
|
7233
|
-
const pending2 =
|
|
7453
|
+
const pending2 = pendingNotes().length;
|
|
7234
7454
|
return { surfaced, pending: pending2, ran: didWork };
|
|
7235
7455
|
}
|
|
7236
7456
|
const dueRun = await runDueCompiledSmartNoteChecks({
|
|
@@ -7240,11 +7460,12 @@ async function evaluateSmartNotes(args) {
|
|
|
7240
7460
|
maxChecks: 10,
|
|
7241
7461
|
sweepBudgetMs: 1e4,
|
|
7242
7462
|
leaseHeld,
|
|
7243
|
-
signal: leaseAbortController.signal
|
|
7463
|
+
signal: leaseAbortController.signal,
|
|
7464
|
+
retinaHandoff: args.retinaHandoff
|
|
7244
7465
|
});
|
|
7245
7466
|
surfaced += dueRun.surfaced;
|
|
7246
7467
|
didWork ||= dueRun.ran > 0;
|
|
7247
|
-
const candidates = getSmartNotesNeedingCompilation(args.db, args.projectIdentity, Date.now(), MAX_COMPILE_PER_RUN);
|
|
7468
|
+
const candidates = getSmartNotesNeedingCompilation(args.db, args.projectIdentity, Date.now(), MAX_COMPILE_PER_RUN, args.retinaHandoff);
|
|
7248
7469
|
for (const note of candidates) {
|
|
7249
7470
|
if (Date.now() >= args.deadline)
|
|
7250
7471
|
break;
|
|
@@ -7254,7 +7475,7 @@ async function evaluateSmartNotes(args) {
|
|
|
7254
7475
|
if (compiled)
|
|
7255
7476
|
surfaced += 1;
|
|
7256
7477
|
}
|
|
7257
|
-
const stale = getStaleCompiledSmartNotes(args.db, args.projectIdentity, Date.now(), MAX_FALLBACK_PER_RUN);
|
|
7478
|
+
const stale = getStaleCompiledSmartNotes(args.db, args.projectIdentity, Date.now(), MAX_FALLBACK_PER_RUN, args.retinaHandoff);
|
|
7258
7479
|
for (const note of stale) {
|
|
7259
7480
|
if (Date.now() >= args.deadline)
|
|
7260
7481
|
break;
|
|
@@ -7264,7 +7485,7 @@ async function evaluateSmartNotes(args) {
|
|
|
7264
7485
|
if (met)
|
|
7265
7486
|
surfaced += 1;
|
|
7266
7487
|
}
|
|
7267
|
-
const fallbackNotes =
|
|
7488
|
+
const fallbackNotes = pendingNotes().filter((note) => note.checkStatus === "fallback").slice(0, MAX_FALLBACK_PER_RUN);
|
|
7268
7489
|
for (const note of fallbackNotes) {
|
|
7269
7490
|
if (Date.now() >= args.deadline)
|
|
7270
7491
|
break;
|
|
@@ -7515,7 +7736,7 @@ Output exactly JSON: {"met": false}`;
|
|
|
7515
7736
|
}
|
|
7516
7737
|
|
|
7517
7738
|
// ../plugin/src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
|
|
7518
|
-
import { existsSync as existsSync5, readFileSync as
|
|
7739
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
7519
7740
|
import { join as join3 } from "node:path";
|
|
7520
7741
|
|
|
7521
7742
|
// ../plugin/src/features/magic-context/dreamer/protected-regions.ts
|
|
@@ -7620,7 +7841,7 @@ function snapshotMaintainDocsFiles(docsDir) {
|
|
|
7620
7841
|
const path4 = join3(docsDir, name);
|
|
7621
7842
|
try {
|
|
7622
7843
|
if (existsSync5(path4)) {
|
|
7623
|
-
snapshot.set(name,
|
|
7844
|
+
snapshot.set(name, readFileSync3(path4, "utf8"));
|
|
7624
7845
|
}
|
|
7625
7846
|
} catch {}
|
|
7626
7847
|
}
|
|
@@ -7630,7 +7851,7 @@ function enforceMaintainDocsProtectedRegions(args) {
|
|
|
7630
7851
|
for (const [fileName, original] of args.snapshot) {
|
|
7631
7852
|
const path4 = join3(args.docsDir, fileName);
|
|
7632
7853
|
try {
|
|
7633
|
-
const current =
|
|
7854
|
+
const current = readFileSync3(path4, "utf8");
|
|
7634
7855
|
const { text, violated } = enforceProtectedRegions(original, current);
|
|
7635
7856
|
if (!violated) {
|
|
7636
7857
|
continue;
|
|
@@ -7644,7 +7865,7 @@ function enforceMaintainDocsProtectedRegions(args) {
|
|
|
7644
7865
|
}
|
|
7645
7866
|
|
|
7646
7867
|
// ../plugin/src/features/magic-context/dreamer/map-memories.ts
|
|
7647
|
-
import { createHash as
|
|
7868
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
7648
7869
|
|
|
7649
7870
|
// ../plugin/src/features/magic-context/dreamer/map-memories-prompt.ts
|
|
7650
7871
|
import { existsSync as existsSync6, statSync } from "node:fs";
|
|
@@ -7761,7 +7982,7 @@ async function mapMemories(args) {
|
|
|
7761
7982
|
}
|
|
7762
7983
|
result.remaining = inputs.length;
|
|
7763
7984
|
const abortController = new AbortController;
|
|
7764
|
-
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
|
|
7985
|
+
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
|
|
7765
7986
|
try {
|
|
7766
7987
|
for (let i = 0;i < batches.length; i += 1) {
|
|
7767
7988
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
@@ -7905,7 +8126,7 @@ async function applyBatchMappings(args, batch, manifestText) {
|
|
|
7905
8126
|
memory_project: args.projectIdentity,
|
|
7906
8127
|
context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
|
|
7907
8128
|
authority_generation: args.moduleRoute.moduleAuthorityGeneration,
|
|
7908
|
-
command_id: `${args.moduleRoute.moduleCommandId}:${
|
|
8129
|
+
command_id: `${args.moduleRoute.moduleCommandId}:${createHash6("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
|
|
7909
8130
|
rows
|
|
7910
8131
|
}
|
|
7911
8132
|
}
|
|
@@ -8130,7 +8351,7 @@ async function promotePrimers(args) {
|
|
|
8130
8351
|
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => {
|
|
8131
8352
|
leaseLost = true;
|
|
8132
8353
|
log("[dreamer] primers: lease lost during promote-primers — aborting");
|
|
8133
|
-
});
|
|
8354
|
+
}, args.leaseAcquisition);
|
|
8134
8355
|
try {
|
|
8135
8356
|
assertLeaseHeld("prune start");
|
|
8136
8357
|
result.pruned = pruneExpiredPrimerCandidatesForProject(args.db, args.projectIdentity, Date.now(), PRIMER_CANDIDATE_TTL_MS);
|
|
@@ -8362,7 +8583,7 @@ async function refreshPrimers(args) {
|
|
|
8362
8583
|
if (primers.length === 0)
|
|
8363
8584
|
return result;
|
|
8364
8585
|
const abortController = new AbortController;
|
|
8365
|
-
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
|
|
8586
|
+
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
|
|
8366
8587
|
try {
|
|
8367
8588
|
for (let i = 0;i < primers.length; i += 1) {
|
|
8368
8589
|
const primer = primers[i];
|
|
@@ -8965,68 +9186,6 @@ function insertDreamRun(db, run) {
|
|
|
8965
9186
|
// ../plugin/src/features/magic-context/dreamer/verify.ts
|
|
8966
9187
|
import { createHash as createHash7 } from "node:crypto";
|
|
8967
9188
|
|
|
8968
|
-
// ../plugin/src/features/magic-context/dreamer/provider-output-failure.ts
|
|
8969
|
-
import { createHash as createHash6 } from "node:crypto";
|
|
8970
|
-
var MAX_NEAR_ZERO_OUTPUT_TOKENS = 32;
|
|
8971
|
-
|
|
8972
|
-
class DreamerProviderOutputFailureError extends Error {
|
|
8973
|
-
fingerprint;
|
|
8974
|
-
outputTokens;
|
|
8975
|
-
reasoningTokens;
|
|
8976
|
-
transient = true;
|
|
8977
|
-
constructor(fingerprint, outputTokens, reasoningTokens, responseText) {
|
|
8978
|
-
const preview = responseText.trim().replace(/\s+/g, " ").slice(0, 160);
|
|
8979
|
-
super(`verify provider-outage completion (output_tokens=${outputTokens}, reasoning_tokens=${reasoningTokens}): ${JSON.stringify(preview)}`);
|
|
8980
|
-
this.fingerprint = fingerprint;
|
|
8981
|
-
this.outputTokens = outputTokens;
|
|
8982
|
-
this.reasoningTokens = reasoningTokens;
|
|
8983
|
-
this.name = "DreamerProviderOutputFailureError";
|
|
8984
|
-
}
|
|
8985
|
-
}
|
|
8986
|
-
function finiteTokenCount(value) {
|
|
8987
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
8988
|
-
}
|
|
8989
|
-
function completionShape(value) {
|
|
8990
|
-
if (!isRecord(value))
|
|
8991
|
-
return null;
|
|
8992
|
-
const info = isRecord(value.info) ? value.info : value;
|
|
8993
|
-
if (info.role !== "assistant")
|
|
8994
|
-
return null;
|
|
8995
|
-
const time = isRecord(info.time) ? info.time : null;
|
|
8996
|
-
const tokens = isRecord(info.tokens) ? info.tokens : null;
|
|
8997
|
-
return {
|
|
8998
|
-
createdAt: typeof time?.created === "number" ? time.created : 0,
|
|
8999
|
-
finish: typeof info.finish === "string" ? info.finish : typeof info.finish_reason === "string" ? info.finish_reason : typeof info.finishReason === "string" ? info.finishReason : null,
|
|
9000
|
-
error: info.error,
|
|
9001
|
-
outputTokens: finiteTokenCount(tokens?.output),
|
|
9002
|
-
reasoningTokens: finiteTokenCount(tokens?.reasoning)
|
|
9003
|
-
};
|
|
9004
|
-
}
|
|
9005
|
-
function latestAssistantCompletion(messages) {
|
|
9006
|
-
if (!Array.isArray(messages))
|
|
9007
|
-
return null;
|
|
9008
|
-
let latest = null;
|
|
9009
|
-
for (const message of messages) {
|
|
9010
|
-
const completion = completionShape(message);
|
|
9011
|
-
if (completion && (!latest || completion.createdAt >= latest.createdAt))
|
|
9012
|
-
latest = completion;
|
|
9013
|
-
}
|
|
9014
|
-
return latest;
|
|
9015
|
-
}
|
|
9016
|
-
function providerOutputFailureFromInvalidManifest(messages, responseText) {
|
|
9017
|
-
const completion = latestAssistantCompletion(messages);
|
|
9018
|
-
if (completion?.finish?.toLowerCase() !== "stop")
|
|
9019
|
-
return null;
|
|
9020
|
-
if (completion.error != null || completion.outputTokens === null || completion.outputTokens > MAX_NEAR_ZERO_OUTPUT_TOKENS || completion.reasoningTokens !== 0) {
|
|
9021
|
-
return null;
|
|
9022
|
-
}
|
|
9023
|
-
const normalized = responseText.trim().replace(/\s+/g, " ").toLowerCase();
|
|
9024
|
-
if (!normalized)
|
|
9025
|
-
return null;
|
|
9026
|
-
const fingerprint = createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
9027
|
-
return new DreamerProviderOutputFailureError(fingerprint, completion.outputTokens, completion.reasoningTokens, responseText);
|
|
9028
|
-
}
|
|
9029
|
-
|
|
9030
9189
|
// ../plugin/src/features/magic-context/dreamer/verify-gate.ts
|
|
9031
9190
|
import path5 from "node:path";
|
|
9032
9191
|
function minOf(values) {
|
|
@@ -9271,7 +9430,7 @@ async function runVerify(args) {
|
|
|
9271
9430
|
batches.push(gate.inScope.slice(i, i + VERIFY_BATCH_SIZE));
|
|
9272
9431
|
}
|
|
9273
9432
|
const abortController = new AbortController;
|
|
9274
|
-
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
|
|
9433
|
+
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort(), args.leaseAcquisition);
|
|
9275
9434
|
let consecutiveProviderFailures = 0;
|
|
9276
9435
|
let priorProviderFailureFingerprint = null;
|
|
9277
9436
|
let lastProviderFailure = null;
|
|
@@ -9607,6 +9766,9 @@ function createDreamTaskExecutor(deps) {
|
|
|
9607
9766
|
return async (config, ctx) => {
|
|
9608
9767
|
const { db, projectIdentity, holderId, leaseKey } = ctx;
|
|
9609
9768
|
const startedAt = Date.now();
|
|
9769
|
+
const leaseAcquisition = ctx.leaseAcquisition ?? acquireLeaseWithAcquisition(db, holderId, leaseKey) ?? (() => {
|
|
9770
|
+
throw new Error("Dream lease unavailable during executor setup");
|
|
9771
|
+
})();
|
|
9610
9772
|
const deadline = startedAt + config.timeoutMinutes * 60 * 1000;
|
|
9611
9773
|
const backlogAtStart = getDreamTaskBacklog(db, projectIdentity, config.task);
|
|
9612
9774
|
const reportProgress = (processed) => {
|
|
@@ -9624,7 +9786,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9624
9786
|
};
|
|
9625
9787
|
const parent = await resolveParentSessionId();
|
|
9626
9788
|
let moduleRoute;
|
|
9627
|
-
if (config.task === "map-memories" || config.task === "compress-cues" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
|
|
9789
|
+
if (config.task === "map-memories" || config.task === "compress-cues" || config.task === "classify-memories" || config.task === "verify" || config.task === "verify-broad" || config.task === "retrospective") {
|
|
9628
9790
|
try {
|
|
9629
9791
|
moduleRoute = await resolveDreamerModuleRoute({
|
|
9630
9792
|
db,
|
|
@@ -9638,6 +9800,9 @@ function createDreamTaskExecutor(deps) {
|
|
|
9638
9800
|
throw new DreamerModuleFailureError("authority.status", error);
|
|
9639
9801
|
}
|
|
9640
9802
|
}
|
|
9803
|
+
if (!leaseOwnershipMatches(db, holderId, leaseAcquisition.generation, leaseKey)) {
|
|
9804
|
+
throw new Error("Dream lease lost during executor setup");
|
|
9805
|
+
}
|
|
9641
9806
|
const recordRun = (status, error, extra) => {
|
|
9642
9807
|
try {
|
|
9643
9808
|
insertDreamRun(db, {
|
|
@@ -9710,6 +9875,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9710
9875
|
holderId,
|
|
9711
9876
|
leaseKey,
|
|
9712
9877
|
deadline,
|
|
9878
|
+
leaseAcquisition,
|
|
9713
9879
|
model: config.model ?? deps.mural.model ?? deps.dreamerModel,
|
|
9714
9880
|
fallbackModels: config.fallbackModels,
|
|
9715
9881
|
moduleRoute,
|
|
@@ -9733,6 +9899,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9733
9899
|
holderId,
|
|
9734
9900
|
leaseKey,
|
|
9735
9901
|
deadline,
|
|
9902
|
+
leaseAcquisition,
|
|
9736
9903
|
promotionThreshold: config.promotionThreshold ?? 3,
|
|
9737
9904
|
model: config.model,
|
|
9738
9905
|
fallbackModels: config.fallbackModels,
|
|
@@ -9752,6 +9919,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9752
9919
|
holderId,
|
|
9753
9920
|
leaseKey,
|
|
9754
9921
|
deadline,
|
|
9922
|
+
leaseAcquisition,
|
|
9755
9923
|
model: config.model,
|
|
9756
9924
|
fallbackModels: config.fallbackModels,
|
|
9757
9925
|
moduleRoute,
|
|
@@ -9777,6 +9945,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9777
9945
|
holderId,
|
|
9778
9946
|
leaseKey,
|
|
9779
9947
|
deadline,
|
|
9948
|
+
leaseAcquisition,
|
|
9780
9949
|
forceBroad: config.task === "verify-broad",
|
|
9781
9950
|
model: config.model,
|
|
9782
9951
|
fallbackModels: config.fallbackModels,
|
|
@@ -9810,40 +9979,15 @@ function createDreamTaskExecutor(deps) {
|
|
|
9810
9979
|
}
|
|
9811
9980
|
if (config.task === "classify-memories") {
|
|
9812
9981
|
let moduleArgs;
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
context_store_uuid: contextStoreUuid,
|
|
9823
|
-
project: projectIdentity,
|
|
9824
|
-
projectRoot: deps.sessionDirectory,
|
|
9825
|
-
domain: "memories"
|
|
9826
|
-
});
|
|
9827
|
-
} catch (error) {
|
|
9828
|
-
throw new ClassifyModuleFailureError("authority.status", error);
|
|
9829
|
-
}
|
|
9830
|
-
if (authority.authority?.state === "MODULE") {
|
|
9831
|
-
const generation = authority.authority.generation;
|
|
9832
|
-
if (typeof generation !== "number") {
|
|
9833
|
-
throw new ClassifyModuleFailureError("authority.status", new Error("response omitted generation"));
|
|
9834
|
-
}
|
|
9835
|
-
const moduleClient = {
|
|
9836
|
-
call: (callArgs) => moduleTransport.call(callArgs)
|
|
9837
|
-
};
|
|
9838
|
-
moduleArgs = {
|
|
9839
|
-
moduleClient,
|
|
9840
|
-
moduleSessionId: projectIdentity,
|
|
9841
|
-
moduleProjectRoot: deps.sessionDirectory,
|
|
9842
|
-
moduleContextStoreUuid: contextStoreUuid,
|
|
9843
|
-
moduleAuthorityGeneration: generation,
|
|
9844
|
-
moduleCommandId: `${startedAt}:${holderId}`
|
|
9845
|
-
};
|
|
9846
|
-
}
|
|
9982
|
+
if (moduleRoute) {
|
|
9983
|
+
moduleArgs = {
|
|
9984
|
+
moduleClient: moduleRoute.moduleClient,
|
|
9985
|
+
moduleSessionId: moduleRoute.moduleSessionId,
|
|
9986
|
+
moduleProjectRoot: moduleRoute.moduleProjectRoot,
|
|
9987
|
+
moduleContextStoreUuid: moduleRoute.moduleContextStoreUuid,
|
|
9988
|
+
moduleAuthorityGeneration: moduleRoute.moduleAuthorityGeneration,
|
|
9989
|
+
moduleCommandId: moduleRoute.moduleCommandId
|
|
9990
|
+
};
|
|
9847
9991
|
}
|
|
9848
9992
|
const result = await runClassify({
|
|
9849
9993
|
db,
|
|
@@ -9854,6 +9998,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9854
9998
|
holderId,
|
|
9855
9999
|
leaseKey,
|
|
9856
10000
|
deadline,
|
|
10001
|
+
leaseAcquisition,
|
|
9857
10002
|
model: config.model,
|
|
9858
10003
|
fallbackModels: config.fallbackModels,
|
|
9859
10004
|
...moduleArgs,
|
|
@@ -9877,6 +10022,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9877
10022
|
holderId,
|
|
9878
10023
|
leaseKey,
|
|
9879
10024
|
deadline,
|
|
10025
|
+
leaseAcquisition,
|
|
9880
10026
|
promotionThreshold: config.promotionThreshold ?? 2,
|
|
9881
10027
|
ensureProjectRegistered: deps.ensureProjectRegistered
|
|
9882
10028
|
});
|
|
@@ -9894,6 +10040,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
9894
10040
|
holderId,
|
|
9895
10041
|
leaseKey,
|
|
9896
10042
|
deadline,
|
|
10043
|
+
leaseAcquisition,
|
|
9897
10044
|
model: config.model,
|
|
9898
10045
|
fallbackModels: config.fallbackModels,
|
|
9899
10046
|
language: config.language ?? deps.language,
|
|
@@ -9914,8 +10061,10 @@ function createDreamTaskExecutor(deps) {
|
|
|
9914
10061
|
holderId,
|
|
9915
10062
|
leaseKey,
|
|
9916
10063
|
deadline,
|
|
10064
|
+
leaseAcquisition,
|
|
9917
10065
|
model: config.model,
|
|
9918
|
-
fallbackModels: config.fallbackModels
|
|
10066
|
+
fallbackModels: config.fallbackModels,
|
|
10067
|
+
retinaHandoff: deps.retinaHandoff
|
|
9919
10068
|
});
|
|
9920
10069
|
recordRun("completed", null, {
|
|
9921
10070
|
smartNotesSurfaced: result.surfaced,
|
|
@@ -10058,7 +10207,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
|
|
|
10058
10207
|
const heartbeat = startLeaseHeartbeat(db, holderId, leaseKey, () => {
|
|
10059
10208
|
leaseLost = true;
|
|
10060
10209
|
abortController.abort();
|
|
10061
|
-
});
|
|
10210
|
+
}, ctx.leaseAcquisition);
|
|
10062
10211
|
let childSessionId = null;
|
|
10063
10212
|
try {
|
|
10064
10213
|
const createResponse = await createChildSessionWithFence({
|
|
@@ -10248,7 +10397,7 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
10248
10397
|
const heartbeat = startLeaseHeartbeat(db, holderId, leaseKey, () => {
|
|
10249
10398
|
leaseLost = true;
|
|
10250
10399
|
abortController.abort();
|
|
10251
|
-
});
|
|
10400
|
+
}, ctx.leaseAcquisition);
|
|
10252
10401
|
let childSessionId = null;
|
|
10253
10402
|
try {
|
|
10254
10403
|
const createResponse = await createChildSessionWithFence({
|
|
@@ -10431,15 +10580,15 @@ async function runDomainGroup(deps, group, cb) {
|
|
|
10431
10580
|
const { db, projectIdentity, executor } = deps;
|
|
10432
10581
|
const leaseKey = leaseKeyFor(group[0].config.task, projectIdentity);
|
|
10433
10582
|
const holderId = crypto.randomUUID();
|
|
10434
|
-
let
|
|
10435
|
-
if (!
|
|
10583
|
+
let acquisition = acquireLeaseWithAcquisition(db, holderId, leaseKey);
|
|
10584
|
+
if (!acquisition && cb?.leaseWaitMs) {
|
|
10436
10585
|
const deadline = Date.now() + cb.leaseWaitMs;
|
|
10437
|
-
while (!
|
|
10586
|
+
while (!acquisition && Date.now() < deadline) {
|
|
10438
10587
|
await new Promise((resolve) => setTimeout(resolve, LEASE_WAIT_POLL_MS));
|
|
10439
|
-
|
|
10588
|
+
acquisition = acquireLeaseWithAcquisition(db, holderId, leaseKey);
|
|
10440
10589
|
}
|
|
10441
10590
|
}
|
|
10442
|
-
if (!
|
|
10591
|
+
if (!acquisition) {
|
|
10443
10592
|
log(`[dreamer] domain lease busy (${leaseKey}) — deferring ${group.length} task(s)`);
|
|
10444
10593
|
for (const due of group)
|
|
10445
10594
|
cb?.onBusy?.(due.config.task);
|
|
@@ -10447,7 +10596,7 @@ async function runDomainGroup(deps, group, cb) {
|
|
|
10447
10596
|
}
|
|
10448
10597
|
try {
|
|
10449
10598
|
for (const due of [...group].sort((a, b) => compareTaskOrder(a.config.task, b.config.task))) {
|
|
10450
|
-
if (!
|
|
10599
|
+
if (!leaseOwnershipMatches(db, holderId, acquisition.generation, leaseKey)) {
|
|
10451
10600
|
log(`[dreamer] domain lease lost (${leaseKey}) — stopping remaining task(s)`);
|
|
10452
10601
|
break;
|
|
10453
10602
|
}
|
|
@@ -10466,7 +10615,13 @@ async function runDomainGroup(deps, group, cb) {
|
|
|
10466
10615
|
}
|
|
10467
10616
|
let outcome;
|
|
10468
10617
|
try {
|
|
10469
|
-
outcome = await executor(due.config, {
|
|
10618
|
+
outcome = await executor(due.config, {
|
|
10619
|
+
db,
|
|
10620
|
+
projectIdentity,
|
|
10621
|
+
holderId,
|
|
10622
|
+
leaseKey,
|
|
10623
|
+
leaseAcquisition: acquisition
|
|
10624
|
+
});
|
|
10470
10625
|
} catch (error) {
|
|
10471
10626
|
outcome = { status: "failed", transient: true, error: String(error) };
|
|
10472
10627
|
}
|
|
@@ -10873,6 +11028,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
10873
11028
|
dreamerModel: dreamerConfig.model,
|
|
10874
11029
|
mural: reg.mural,
|
|
10875
11030
|
memoryInjectionBudgetTokens: reg.memoryInjectionBudgetTokens,
|
|
11031
|
+
retinaHandoff: reg.retinaHandoff,
|
|
10876
11032
|
transformMode: reg.transformMode,
|
|
10877
11033
|
moduleClient: reg.moduleClient,
|
|
10878
11034
|
onProgress: (progress, completedTask) => reg.onDreamerProgress?.(progress, completedTask)
|
|
@@ -10916,7 +11072,8 @@ async function runCompiledSmartNoteSweep(reg, db) {
|
|
|
10916
11072
|
const result = await runDueCompiledSmartNoteChecks({
|
|
10917
11073
|
db,
|
|
10918
11074
|
projectIdentity: reg.projectIdentity,
|
|
10919
|
-
projectRoot: reg.directory
|
|
11075
|
+
projectRoot: reg.directory,
|
|
11076
|
+
retinaHandoff: reg.retinaHandoff
|
|
10920
11077
|
});
|
|
10921
11078
|
if (result.ran > 0) {
|
|
10922
11079
|
log(`[dreamer] compiled smart-note sweep ${reg.projectIdentity}: ran=${result.ran} surfaced=${result.surfaced} logic_failed=${result.failed} network_failed=${result.networkFailed}`);
|
|
@@ -10991,7 +11148,7 @@ async function sweepGitCommits(args) {
|
|
|
10991
11148
|
}
|
|
10992
11149
|
|
|
10993
11150
|
// src/dreamer/pi-session-api.ts
|
|
10994
|
-
import { readFileSync as
|
|
11151
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
10995
11152
|
import { createRequire as createRequire2 } from "node:module";
|
|
10996
11153
|
import { pathToFileURL } from "node:url";
|
|
10997
11154
|
var PI_CODING_AGENT_MODULE = "@earendil-works/pi-coding-agent";
|
|
@@ -11047,7 +11204,7 @@ async function loadDefaultPiSessionApi(loaders) {
|
|
|
11047
11204
|
throw new Error("Pi session APIs unavailable: expected SessionManager.listAll on pi-coding-agent");
|
|
11048
11205
|
}
|
|
11049
11206
|
const loadEntriesFromFile = mod.loadEntriesFromFile ?? ((filePath) => {
|
|
11050
|
-
const content =
|
|
11207
|
+
const content = readFileSync4(filePath, "utf8");
|
|
11051
11208
|
return mod.parseSessionEntries?.(content) ?? [];
|
|
11052
11209
|
});
|
|
11053
11210
|
return {
|
|
@@ -11237,6 +11394,7 @@ function registerPiDreamerProject(opts) {
|
|
|
11237
11394
|
dreamerConfig: opts.config,
|
|
11238
11395
|
language: opts.language,
|
|
11239
11396
|
gitCommitIndexing: opts.gitCommitIndexing,
|
|
11397
|
+
retinaHandoff: opts.retinaHandoff,
|
|
11240
11398
|
ensureRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
11241
11399
|
retrospectiveRawProvider: () => new PiRetrospectiveRawProvider({ projectCwd: opts.projectDir }),
|
|
11242
11400
|
primerRawProviderFactory: createPiPrimerRawProviderFactory()
|
|
@@ -11261,7 +11419,8 @@ function registerPiDreamerProject(opts) {
|
|
|
11261
11419
|
primerRawProviderFactory: createPiPrimerRawProviderFactory(),
|
|
11262
11420
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(opts.config),
|
|
11263
11421
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
11264
|
-
language: opts.language
|
|
11422
|
+
language: opts.language,
|
|
11423
|
+
retinaHandoff: opts.retinaHandoff
|
|
11265
11424
|
}),
|
|
11266
11425
|
task
|
|
11267
11426
|
});
|
|
@@ -11866,6 +12025,7 @@ function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity, n
|
|
|
11866
12025
|
return;
|
|
11867
12026
|
autoEmbedAttemptedBySession.add(sessionId);
|
|
11868
12027
|
(async () => {
|
|
12028
|
+
let completedDrainWithWork = false;
|
|
11869
12029
|
try {
|
|
11870
12030
|
await new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
11871
12031
|
await ensureProjectRegisteredFromPiDirectory(projectDir, deps.db);
|
|
@@ -11876,9 +12036,13 @@ function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity, n
|
|
|
11876
12036
|
if (remaining <= 0)
|
|
11877
12037
|
return;
|
|
11878
12038
|
notify(`Embedding ${remaining} compartment${remaining === 1 ? "" : "s"} of history in the background…`);
|
|
11879
|
-
const { text } = await runEmbedDrain(deps.db, projectIdentity, sessionId);
|
|
12039
|
+
const { text, level } = await runEmbedDrain(deps.db, projectIdentity, sessionId);
|
|
12040
|
+
completedDrainWithWork = level === "success";
|
|
11880
12041
|
notify(text.replace(/^## \/ctx-embed\n\n/, ""));
|
|
11881
|
-
} catch {}
|
|
12042
|
+
} catch {} finally {
|
|
12043
|
+
if (!completedDrainWithWork)
|
|
12044
|
+
autoEmbedAttemptedBySession.delete(sessionId);
|
|
12045
|
+
}
|
|
11882
12046
|
})();
|
|
11883
12047
|
}
|
|
11884
12048
|
|
|
@@ -16283,6 +16447,9 @@ var EMPTY_PI_HARD_SIGNALS = {
|
|
|
16283
16447
|
cacheExpired: false,
|
|
16284
16448
|
lastResponseTime: 0
|
|
16285
16449
|
};
|
|
16450
|
+
function renderBudgetIdentityPi(state2) {
|
|
16451
|
+
return `m${state2.injectionBudgetTokens ?? DEFAULT_MEMORY_BUDGET_TOKENS}-h${state2.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS}`;
|
|
16452
|
+
}
|
|
16286
16453
|
var injectionTokenCountsBySession = new Map;
|
|
16287
16454
|
var cachedMuralBySession = new Map;
|
|
16288
16455
|
function rememberPiMuralPayload(sessionId, dataUrl, contentHash) {
|
|
@@ -16400,7 +16567,9 @@ function getCachedMarkers(db, state2, compartmentsForNormalization) {
|
|
|
16400
16567
|
lastBaselineEndMessageId: cachedBoundary,
|
|
16401
16568
|
systemHash: meta.cachedM0SystemHash ?? "",
|
|
16402
16569
|
modelKey: meta.cachedM0ModelKey ?? "",
|
|
16403
|
-
projectIdentity: meta.cachedM0ProjectIdentity ?? null
|
|
16570
|
+
projectIdentity: meta.cachedM0ProjectIdentity ?? null,
|
|
16571
|
+
muralEnabled: cachedUpgradeIdentity.muralEnabled ?? false,
|
|
16572
|
+
renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? ""
|
|
16404
16573
|
};
|
|
16405
16574
|
}
|
|
16406
16575
|
function lastBaselineEndMessageId(compartments) {
|
|
@@ -16432,7 +16601,9 @@ function readCurrentMarkersFromCompartments(db, state2, compartments, projectDoc
|
|
|
16432
16601
|
lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
|
|
16433
16602
|
systemHash: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
|
|
16434
16603
|
modelKey: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey,
|
|
16435
|
-
projectIdentity: state2.projectIdentity
|
|
16604
|
+
projectIdentity: state2.projectIdentity,
|
|
16605
|
+
muralEnabled: state2.muralEnabled === true,
|
|
16606
|
+
renderBudgetIdentity: renderBudgetIdentityPi(state2)
|
|
16436
16607
|
};
|
|
16437
16608
|
}
|
|
16438
16609
|
function mustMaterializePi(state2, db, currentCompartmentsOverride) {
|
|
@@ -16453,6 +16624,9 @@ function mustMaterializePi(state2, db, currentCompartmentsOverride) {
|
|
|
16453
16624
|
if (cached.compartmentRenderEpoch !== current.compartmentRenderEpoch) {
|
|
16454
16625
|
return { value: true, reason: "compartment_render_epoch" };
|
|
16455
16626
|
}
|
|
16627
|
+
if (cached.muralEnabled !== current.muralEnabled || cached.renderBudgetIdentity !== current.renderBudgetIdentity) {
|
|
16628
|
+
return { value: true, reason: "render_config" };
|
|
16629
|
+
}
|
|
16456
16630
|
const hard = state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS;
|
|
16457
16631
|
if (hard.modelKey !== "" && hard.modelKey !== (meta.cachedM0ModelKey ?? "")) {
|
|
16458
16632
|
return { value: true, reason: "model_change" };
|
|
@@ -16590,7 +16764,9 @@ function readFrozenM0InputsPi(state2, db, docs = readProjectDocsForPiM0(state2),
|
|
|
16590
16764
|
lastBaselineEndMessageId: lastBaselineEndMessageId(compartments),
|
|
16591
16765
|
systemHash: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).systemHash,
|
|
16592
16766
|
modelKey: (state2.hardSignals ?? EMPTY_PI_HARD_SIGNALS).modelKey,
|
|
16593
|
-
projectIdentity: state2.projectIdentity
|
|
16767
|
+
projectIdentity: state2.projectIdentity,
|
|
16768
|
+
muralEnabled: state2.muralEnabled === true,
|
|
16769
|
+
renderBudgetIdentity: renderBudgetIdentityPi(state2)
|
|
16594
16770
|
};
|
|
16595
16771
|
return { docs, markers, compartments, memories, userProfile, workspace };
|
|
16596
16772
|
});
|
|
@@ -16677,7 +16853,7 @@ function materializeM0Pi(state2, db) {
|
|
|
16677
16853
|
projectDocsHash: snapshotMarkers.projectDocsHash,
|
|
16678
16854
|
materializedAt: snapshotMarkers.materializedAt,
|
|
16679
16855
|
sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
|
|
16680
|
-
upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch),
|
|
16856
|
+
upgradeState: encodeCachedM0UpgradeIdentity(snapshotMarkers.upgradeState, snapshotMarkers.compartmentRenderEpoch, snapshotMarkers.muralEnabled, snapshotMarkers.renderBudgetIdentity),
|
|
16681
16857
|
systemHash: snapshotMarkers.systemHash,
|
|
16682
16858
|
modelKey: snapshotMarkers.modelKey,
|
|
16683
16859
|
projectIdentity: snapshotMarkers.projectIdentity
|
|
@@ -16887,7 +17063,9 @@ function markersFromCachedPiRow(row, compartmentsForNormalization) {
|
|
|
16887
17063
|
lastBaselineEndMessageId: typeof row.cached_m0_last_baseline_end_message_id === "string" && row.cached_m0_last_baseline_end_message_id.length > 0 ? row.cached_m0_last_baseline_end_message_id : null,
|
|
16888
17064
|
systemHash: row.cached_m0_system_hash ?? "",
|
|
16889
17065
|
modelKey: row.cached_m0_model_key ?? "",
|
|
16890
|
-
projectIdentity: row.cached_m0_project_identity ?? null
|
|
17066
|
+
projectIdentity: row.cached_m0_project_identity ?? null,
|
|
17067
|
+
muralEnabled: cachedUpgradeIdentity.muralEnabled ?? false,
|
|
17068
|
+
renderBudgetIdentity: cachedUpgradeIdentity.renderBudgetIdentity ?? ""
|
|
16891
17069
|
};
|
|
16892
17070
|
}
|
|
16893
17071
|
function cachedPiRowMatchesSnapshot(args) {
|
|
@@ -21772,10 +21950,14 @@ function processSystemPromptForCache(args) {
|
|
|
21772
21950
|
const dateMatch = systemPrompt.match(DATE_PATTERN);
|
|
21773
21951
|
const liveDate = dateMatch ? dateMatch[0] : null;
|
|
21774
21952
|
const stickyDate = stickyDateBySession.get(sessionId);
|
|
21953
|
+
const stableCandidate = liveDate && stickyDate && liveDate !== stickyDate ? systemPrompt.replace(DATE_PATTERN, stickyDate) : systemPrompt;
|
|
21954
|
+
const stableCandidateHash = createHash10("md5").update(promptSurfaceHashMaterial(stableCandidate, args.promptSurfacePreset)).digest("hex");
|
|
21955
|
+
const contentOrPresetChanged = !isFirstHash && stableCandidateHash !== previousHash;
|
|
21956
|
+
const dateMayAdvance = isCacheBusting || contentOrPresetChanged;
|
|
21775
21957
|
if (liveDate && !stickyDate) {
|
|
21776
21958
|
stickyDateBySession.set(sessionId, liveDate);
|
|
21777
21959
|
} else if (liveDate && stickyDate && liveDate !== stickyDate) {
|
|
21778
|
-
if (
|
|
21960
|
+
if (dateMayAdvance) {
|
|
21779
21961
|
stickyDateBySession.set(sessionId, liveDate);
|
|
21780
21962
|
sessionLog(sessionId, `system prompt date updated: ${stickyDate} → ${liveDate} (cache-busting pass)`);
|
|
21781
21963
|
} else {
|
|
@@ -21812,6 +21994,37 @@ function clearPiSystemPromptSession(sessionId) {
|
|
|
21812
21994
|
}
|
|
21813
21995
|
|
|
21814
21996
|
// src/temporal-awareness-pi.ts
|
|
21997
|
+
function withoutPiLeadingTemporalMarker(text) {
|
|
21998
|
+
const { tagPrefix, body } = peelLeadingMcTagNotation(text);
|
|
21999
|
+
return tagPrefix + body.replace(TEMPORAL_MARKER_PATTERN, "");
|
|
22000
|
+
}
|
|
22001
|
+
function stripPiLeadingTemporalMarker(message) {
|
|
22002
|
+
if (!message || typeof message !== "object")
|
|
22003
|
+
return false;
|
|
22004
|
+
const userMessage = message;
|
|
22005
|
+
if (userMessage.role !== "user")
|
|
22006
|
+
return false;
|
|
22007
|
+
if (typeof userMessage.content === "string") {
|
|
22008
|
+
const stripped2 = withoutPiLeadingTemporalMarker(userMessage.content);
|
|
22009
|
+
if (stripped2 === userMessage.content)
|
|
22010
|
+
return false;
|
|
22011
|
+
userMessage.content = stripped2;
|
|
22012
|
+
return true;
|
|
22013
|
+
}
|
|
22014
|
+
if (!Array.isArray(userMessage.content))
|
|
22015
|
+
return false;
|
|
22016
|
+
const firstTextIndex = userMessage.content.findIndex((part) => part?.type === "text");
|
|
22017
|
+
if (firstTextIndex < 0)
|
|
22018
|
+
return false;
|
|
22019
|
+
const firstText = userMessage.content[firstTextIndex];
|
|
22020
|
+
const stripped = withoutPiLeadingTemporalMarker(firstText.text);
|
|
22021
|
+
if (stripped === firstText.text)
|
|
22022
|
+
return false;
|
|
22023
|
+
const content = userMessage.content.slice();
|
|
22024
|
+
content[firstTextIndex] = { ...firstText, text: stripped };
|
|
22025
|
+
userMessage.content = content;
|
|
22026
|
+
return true;
|
|
22027
|
+
}
|
|
21815
22028
|
function injectPiTemporalMarkers(messages) {
|
|
21816
22029
|
let injected = 0;
|
|
21817
22030
|
let prevTimestampMs;
|
|
@@ -22636,7 +22849,7 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
|
|
|
22636
22849
|
const messageId = message.info.id;
|
|
22637
22850
|
if (messageId === undefined)
|
|
22638
22851
|
continue;
|
|
22639
|
-
currentSourcesByMessageId.set(messageId, message.parts.filter((part) => part.kind === "text").map((part) => stripTagPrefix(part.getText() ?? "")));
|
|
22852
|
+
currentSourcesByMessageId.set(messageId, message.parts.filter((part) => part.kind === "text").map((part) => withoutPiLeadingTemporalMarker(stripTagPrefix(part.getText() ?? ""))));
|
|
22640
22853
|
}
|
|
22641
22854
|
const legacyRowsByMessageId = new Map;
|
|
22642
22855
|
const versionedMessageIds = new Set;
|
|
@@ -22682,7 +22895,7 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
|
|
|
22682
22895
|
if (legacyRows.length === 0)
|
|
22683
22896
|
continue;
|
|
22684
22897
|
legacyRows.sort((left, right) => left.ordinal - right.ordinal);
|
|
22685
|
-
const vectorMatches = legacyRows.length === currentSources.length && legacyRows.every((row, index) => row.ordinal === index && sourceCache.get(row.tagId) === currentSources[index]);
|
|
22898
|
+
const vectorMatches = legacyRows.length === currentSources.length && legacyRows.every((row, index) => row.ordinal === index && withoutPiLeadingTemporalMarker(sourceCache.get(row.tagId) ?? "") === currentSources[index]);
|
|
22686
22899
|
if (!vectorMatches)
|
|
22687
22900
|
driftedMessageIds.add(messageId);
|
|
22688
22901
|
}
|
|
@@ -22990,6 +23203,30 @@ function buildPiAlignedEntryIds(entries) {
|
|
|
22990
23203
|
}
|
|
22991
23204
|
return ids;
|
|
22992
23205
|
}
|
|
23206
|
+
function stripMcOwnedPiCompactionSummary(messages, entryIds, branchEntries) {
|
|
23207
|
+
const summaryMessage = messages[0];
|
|
23208
|
+
if (summaryMessage?.role !== "compactionSummary")
|
|
23209
|
+
return false;
|
|
23210
|
+
let compaction;
|
|
23211
|
+
for (let index = branchEntries.length - 1;index >= 0; index -= 1) {
|
|
23212
|
+
const entry = branchEntries[index];
|
|
23213
|
+
if (entry?.type === "compaction") {
|
|
23214
|
+
compaction = entry;
|
|
23215
|
+
break;
|
|
23216
|
+
}
|
|
23217
|
+
}
|
|
23218
|
+
if (compaction?.fromHook !== true)
|
|
23219
|
+
return false;
|
|
23220
|
+
const details = compaction.details;
|
|
23221
|
+
if (details?.source !== "magic-context")
|
|
23222
|
+
return false;
|
|
23223
|
+
if (summaryMessage.summary !== compaction.summary || summaryMessage.tokensBefore !== compaction.tokensBefore || entryIds[0] !== undefined) {
|
|
23224
|
+
return false;
|
|
23225
|
+
}
|
|
23226
|
+
messages.splice(0, 1);
|
|
23227
|
+
entryIds.splice(0, 1);
|
|
23228
|
+
return true;
|
|
23229
|
+
}
|
|
22993
23230
|
function getPiBranchEntryLookup(entries) {
|
|
22994
23231
|
const cached = piBranchLookupByProjection.get(entries);
|
|
22995
23232
|
if (cached)
|
|
@@ -23351,6 +23588,9 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
23351
23588
|
const alignedEntryIds = branchLookup?.alignedEntryIds ?? null;
|
|
23352
23589
|
const resolvedEntryIds = alignedEntryIds?.length === event.messages.length ? alignedEntryIds : branchEntries === null ? null : collectMessageEntryIdsByRef(ctx, event.messages, sessionId, branchEntries);
|
|
23353
23590
|
const strictEntryIds = resolvedEntryIds ? [...resolvedEntryIds] : null;
|
|
23591
|
+
if (strictEntryIds && branchEntries && options.injection && !options.compactionOff && stripMcOwnedPiCompactionSummary(event.messages, strictEntryIds, branchEntries)) {
|
|
23592
|
+
logTransformTiming(sessionId, "mcCompactionSummarySuppression", tEntryBranch);
|
|
23593
|
+
}
|
|
23354
23594
|
if (strictEntryIds && options.injection && !options.compactionOff) {
|
|
23355
23595
|
const removed = trimPiMessagesToCachedBoundary(options.db, sessionId, event.messages, strictEntryIds);
|
|
23356
23596
|
if (removed > 0) {
|
|
@@ -24482,10 +24722,10 @@ async function runPipeline(args) {
|
|
|
24482
24722
|
}
|
|
24483
24723
|
const targetTagNumbers = [...targets.keys()];
|
|
24484
24724
|
const tGetTags = performance.now();
|
|
24485
|
-
const
|
|
24486
|
-
logTransformTiming(args.sessionId, "
|
|
24725
|
+
const flushedDroppedTags = getDroppedTagsByNumbers(args.db, args.sessionId, targetTagNumbers);
|
|
24726
|
+
logTransformTiming(args.sessionId, "getDroppedTagsByNumbers", tGetTags, `targets=${targetTagNumbers.length} fetched=${flushedDroppedTags.length}`);
|
|
24487
24727
|
const tFlushed = performance.now();
|
|
24488
|
-
didMutateFromFlushedStatuses = applyFlushedStatuses(args.sessionId, args.db, targets,
|
|
24728
|
+
didMutateFromFlushedStatuses = applyFlushedStatuses(args.sessionId, args.db, targets, flushedDroppedTags);
|
|
24489
24729
|
logTransformTiming(args.sessionId, "applyFlushedStatuses", tFlushed);
|
|
24490
24730
|
logTransformTiming(args.sessionId, "batchFinalize:flushed", tFlushed);
|
|
24491
24731
|
const messageIdToMaxTag = buildMessageIdToMaxTag(targets);
|
|
@@ -24729,6 +24969,10 @@ async function runPipeline(args) {
|
|
|
24729
24969
|
hardSignals: piHardSignals,
|
|
24730
24970
|
muralEnabled: args.injection.muralEnabled === true
|
|
24731
24971
|
}, args.db, args.messages, args.entryIds, args.isCacheBusting || deferredHistoryRefresh || executedWorkThisPass);
|
|
24972
|
+
if (args.temporalAwareness && injectionResult.skippedVisibleMessages > 0) {
|
|
24973
|
+
const firstRetainedMessage = args.messages[injectionResult.syntheticLeadingCount];
|
|
24974
|
+
stripPiLeadingTemporalMarker(firstRetainedMessage);
|
|
24975
|
+
}
|
|
24732
24976
|
if (args.isCacheBusting) {
|
|
24733
24977
|
historyRefreshSessions.delete(args.sessionId);
|
|
24734
24978
|
historyWasConsumedThisPass = true;
|
|
@@ -26907,6 +27151,14 @@ var MIGRATION_SYSTEM_PROMPT = "You re-organize a software project's long-term me
|
|
|
26907
27151
|
var LKG_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
26908
27152
|
var LKG_SINGLE_SLOT_BYTES = 24 * 1024 * 1024;
|
|
26909
27153
|
var slots = new Map;
|
|
27154
|
+
var LKG_SNAPSHOT_ARRAY = Symbol("array");
|
|
27155
|
+
var LKG_SNAPSHOT_OBJECT = Symbol("object");
|
|
27156
|
+
var LKG_SNAPSHOT_KEY = Symbol("key");
|
|
27157
|
+
var LKG_SNAPSHOT_STRING = Symbol("string");
|
|
27158
|
+
var LKG_SNAPSHOT_NUMBER = Symbol("number");
|
|
27159
|
+
var LKG_SNAPSHOT_BOOLEAN = Symbol("boolean");
|
|
27160
|
+
var LKG_SNAPSHOT_NULL = Symbol("null");
|
|
27161
|
+
var LKG_SNAPSHOT_UNDEFINED = Symbol("undefined");
|
|
26910
27162
|
|
|
26911
27163
|
// ../plugin/src/hooks/magic-context/recomp-orchestrator.ts
|
|
26912
27164
|
function isRecompFailure(message) {
|
|
@@ -27452,15 +27704,17 @@ ${c.content}
|
|
|
27452
27704
|
// package.json
|
|
27453
27705
|
var package_default = {
|
|
27454
27706
|
name: "@cortexkit/pi-magic-context",
|
|
27455
|
-
version: "0.
|
|
27707
|
+
version: "0.36.1",
|
|
27456
27708
|
type: "module",
|
|
27457
|
-
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
27709
|
+
description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
|
|
27458
27710
|
main: "dist/index.js",
|
|
27459
27711
|
license: "MIT",
|
|
27460
27712
|
author: "ualtinok",
|
|
27461
27713
|
keywords: [
|
|
27462
27714
|
"pi",
|
|
27463
27715
|
"pi-coding-agent",
|
|
27716
|
+
"omp",
|
|
27717
|
+
"oh-my-pi",
|
|
27464
27718
|
"extension",
|
|
27465
27719
|
"context",
|
|
27466
27720
|
"memory",
|
|
@@ -27478,8 +27732,9 @@ var package_default = {
|
|
|
27478
27732
|
"README.md"
|
|
27479
27733
|
],
|
|
27480
27734
|
scripts: {
|
|
27481
|
-
build: "rm -f dist/index.js dist/subagent-entry.js dist/*-*.js && bun build src/index.ts src/subagent-entry.ts --outdir dist --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external @huggingface/transformers --external node:sqlite",
|
|
27482
|
-
|
|
27735
|
+
build: "tsc -p ../retina-local-fs/tsconfig.build.json && rm -f dist/index.js dist/subagent-entry.js dist/*-*.js && bun build src/index.ts src/subagent-entry.ts --outdir dist --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external @huggingface/transformers --external node:sqlite",
|
|
27736
|
+
"build:e2e-argv": "bun build src/subagent-runner.ts --outfile ../../tests/docker/.generated/subagent-runner-e2e.mjs --target node --format esm --external node:sqlite",
|
|
27737
|
+
typecheck: "tsc -p ../retina-local-fs/tsconfig.build.json && tsc --noEmit",
|
|
27483
27738
|
test: "bun test",
|
|
27484
27739
|
lint: "biome check src",
|
|
27485
27740
|
"lint:fix": "biome check --write src",
|
|
@@ -27510,6 +27765,14 @@ var package_default = {
|
|
|
27510
27765
|
"@earendil-works/pi-coding-agent": "^0.80.2",
|
|
27511
27766
|
"@earendil-works/pi-tui": "^0.80.2"
|
|
27512
27767
|
},
|
|
27768
|
+
peerDependenciesMeta: {
|
|
27769
|
+
"@earendil-works/pi-coding-agent": {
|
|
27770
|
+
optional: true
|
|
27771
|
+
},
|
|
27772
|
+
"@earendil-works/pi-tui": {
|
|
27773
|
+
optional: true
|
|
27774
|
+
}
|
|
27775
|
+
},
|
|
27513
27776
|
exports: {
|
|
27514
27777
|
".": {
|
|
27515
27778
|
import: "./dist/index.js"
|
|
@@ -27519,6 +27782,11 @@ var package_default = {
|
|
|
27519
27782
|
extensions: [
|
|
27520
27783
|
"./dist/index.js"
|
|
27521
27784
|
]
|
|
27785
|
+
},
|
|
27786
|
+
omp: {
|
|
27787
|
+
extensions: [
|
|
27788
|
+
"./dist/index.js"
|
|
27789
|
+
]
|
|
27522
27790
|
}
|
|
27523
27791
|
};
|
|
27524
27792
|
|
|
@@ -28555,6 +28823,9 @@ async function handlePiSessionBeforeCompact(args) {
|
|
|
28555
28823
|
info("session_before_compact: cancelling — magic-context owns compaction");
|
|
28556
28824
|
return { cancel: true };
|
|
28557
28825
|
}
|
|
28826
|
+
function canonicalPiModelKey(provider, model) {
|
|
28827
|
+
return piModelRefToCanonical(`${provider}/${model}`);
|
|
28828
|
+
}
|
|
28558
28829
|
function persistPiMessageEndModelMeta(args) {
|
|
28559
28830
|
if (!args.message || typeof args.message !== "object")
|
|
28560
28831
|
return;
|
|
@@ -28562,7 +28833,7 @@ function persistPiMessageEndModelMeta(args) {
|
|
|
28562
28833
|
if (msg.role !== "assistant" || typeof msg.provider !== "string" || msg.provider.length === 0 || typeof msg.model !== "string" || msg.model.length === 0) {
|
|
28563
28834
|
return;
|
|
28564
28835
|
}
|
|
28565
|
-
const modelKey =
|
|
28836
|
+
const modelKey = canonicalPiModelKey(msg.provider, msg.model);
|
|
28566
28837
|
recordPiLiveModel(args.sessionId, modelKey);
|
|
28567
28838
|
const cacheTtl = resolveCacheTtl(args.cacheTtlConfig, modelKey);
|
|
28568
28839
|
const currentMeta = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
@@ -29268,6 +29539,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
29268
29539
|
config: dreamerConfig,
|
|
29269
29540
|
embeddingConfig: bootProjectDeps.config.embedding,
|
|
29270
29541
|
memoryEnabled: bootProjectDeps.config.memory.enabled,
|
|
29542
|
+
retinaHandoff: bootProjectDeps.config.smart_notes.retina_handoff,
|
|
29271
29543
|
language: bootProjectDeps.config.language,
|
|
29272
29544
|
gitCommitIndexing: bootProjectDeps.config.memory.git_commit_indexing,
|
|
29273
29545
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|
|
@@ -29277,6 +29549,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
29277
29549
|
info(bootProjectDeps.dreamerEnabled ? "registered dreamer: DISABLED (no dreamer config)" : "registered dreamer: DISABLED (dreamer.disable=true or no dreamer config)");
|
|
29278
29550
|
}
|
|
29279
29551
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
29552
|
+
await preloadTokenizer();
|
|
29280
29553
|
try {
|
|
29281
29554
|
if (ctx.hasUI && shouldShowAnnouncement()) {
|
|
29282
29555
|
const featureText = ANNOUNCEMENT_FEATURES.map((line) => ` • ${line}`).join(`
|
|
@@ -29312,6 +29585,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
29312
29585
|
config: effectiveDreamerConfig,
|
|
29313
29586
|
embeddingConfig: effectiveConfig.embedding,
|
|
29314
29587
|
memoryEnabled: effectiveConfig.memory.enabled,
|
|
29588
|
+
retinaHandoff: effectiveConfig.smart_notes.retina_handoff,
|
|
29315
29589
|
language: effectiveConfig.language,
|
|
29316
29590
|
gitCommitIndexing: effectiveConfig.memory.git_commit_indexing,
|
|
29317
29591
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|
|
@@ -29371,7 +29645,7 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
|
|
|
29371
29645
|
}
|
|
29372
29646
|
const isCacheBusting = sessionId ? hasSystemPromptRefresh(sessionId) : true;
|
|
29373
29647
|
const promptSurfaceModel = ctx.model;
|
|
29374
|
-
const promptSurfaceModelKey = typeof promptSurfaceModel?.provider === "string" && promptSurfaceModel.provider.length > 0 && typeof promptSurfaceModel.id === "string" && promptSurfaceModel.id.length > 0 ?
|
|
29648
|
+
const promptSurfaceModelKey = typeof promptSurfaceModel?.provider === "string" && promptSurfaceModel.provider.length > 0 && typeof promptSurfaceModel.id === "string" && promptSurfaceModel.id.length > 0 ? canonicalPiModelKey(promptSurfaceModel.provider, promptSurfaceModel.id) : undefined;
|
|
29375
29649
|
const promptSurface = sessionId ? promptSurfaceGuidanceEpochs.resolve(sessionId, effectiveConfig.prompt_surface, promptSurfaceModelKey) : promptSurfaceRuntime.resolveGuidance(effectiveConfig.prompt_surface, promptSurfaceModelKey);
|
|
29376
29650
|
const block = buildMagicContextBlock({
|
|
29377
29651
|
db,
|
|
@@ -29656,5 +29930,6 @@ export {
|
|
|
29656
29930
|
src_default as default,
|
|
29657
29931
|
capturePiTodowriteMessageIfCompatible,
|
|
29658
29932
|
capturePiTodowriteArgsIfCompatible,
|
|
29933
|
+
canonicalPiModelKey,
|
|
29659
29934
|
__test
|
|
29660
29935
|
};
|