@cortexkit/pi-magic-context 0.17.2 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +931 -279
- package/dist/subagent-entry.js +296 -119
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11277,7 +11277,7 @@ function finalize(ctx, schema) {
|
|
|
11277
11277
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
11278
11278
|
} else if (ctx.target === "draft-04") {
|
|
11279
11279
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
11280
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
11280
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
11281
11281
|
if (ctx.external?.uri) {
|
|
11282
11282
|
const id = ctx.external.registry.get(schema)?.id;
|
|
11283
11283
|
if (!id)
|
|
@@ -11538,7 +11538,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
|
|
|
11538
11538
|
if (val === undefined) {
|
|
11539
11539
|
if (ctx.unrepresentable === "throw") {
|
|
11540
11540
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
11541
|
-
}
|
|
11541
|
+
}
|
|
11542
11542
|
} else if (typeof val === "bigint") {
|
|
11543
11543
|
if (ctx.unrepresentable === "throw") {
|
|
11544
11544
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -14891,10 +14891,63 @@ var init_magic_context = __esm(() => {
|
|
|
14891
14891
|
});
|
|
14892
14892
|
});
|
|
14893
14893
|
|
|
14894
|
-
// ../plugin/src/shared/
|
|
14895
|
-
|
|
14894
|
+
// ../plugin/src/shared/harness.ts
|
|
14895
|
+
function setHarness(value) {
|
|
14896
|
+
if (harnessLocked && currentHarness !== value) {
|
|
14897
|
+
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
14898
|
+
}
|
|
14899
|
+
currentHarness = value;
|
|
14900
|
+
harnessLocked = true;
|
|
14901
|
+
}
|
|
14902
|
+
function getHarness() {
|
|
14903
|
+
return currentHarness;
|
|
14904
|
+
}
|
|
14905
|
+
var currentHarness = "opencode", harnessLocked = false;
|
|
14906
|
+
|
|
14907
|
+
// ../plugin/src/shared/data-path.ts
|
|
14896
14908
|
import * as os from "node:os";
|
|
14897
14909
|
import * as path from "node:path";
|
|
14910
|
+
function getDataDir() {
|
|
14911
|
+
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
14912
|
+
}
|
|
14913
|
+
function getMagicContextTempDir(harness = getHarness()) {
|
|
14914
|
+
return path.join(os.tmpdir(), harness, "magic-context");
|
|
14915
|
+
}
|
|
14916
|
+
function getMagicContextLogPath(harness = getHarness()) {
|
|
14917
|
+
return path.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
14918
|
+
}
|
|
14919
|
+
function getProjectMagicContextDir(directory) {
|
|
14920
|
+
return path.join(directory, ".opencode", "magic-context");
|
|
14921
|
+
}
|
|
14922
|
+
function getProjectMagicContextHistorianDir(directory) {
|
|
14923
|
+
return path.join(getProjectMagicContextDir(directory), "historian");
|
|
14924
|
+
}
|
|
14925
|
+
function getOpenCodeStorageDir() {
|
|
14926
|
+
return path.join(getDataDir(), "opencode", "storage");
|
|
14927
|
+
}
|
|
14928
|
+
function getMagicContextStorageDir() {
|
|
14929
|
+
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
14930
|
+
}
|
|
14931
|
+
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
14932
|
+
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
14933
|
+
}
|
|
14934
|
+
function getCacheDir() {
|
|
14935
|
+
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
14936
|
+
}
|
|
14937
|
+
var init_data_path = () => {};
|
|
14938
|
+
|
|
14939
|
+
// ../plugin/src/shared/logger.ts
|
|
14940
|
+
import * as fs from "node:fs";
|
|
14941
|
+
import * as path2 from "node:path";
|
|
14942
|
+
function ensureDir(filePath) {
|
|
14943
|
+
const dir = path2.dirname(filePath);
|
|
14944
|
+
if (dir === lastEnsuredDir)
|
|
14945
|
+
return;
|
|
14946
|
+
try {
|
|
14947
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
14948
|
+
lastEnsuredDir = dir;
|
|
14949
|
+
} catch {}
|
|
14950
|
+
}
|
|
14898
14951
|
function flush() {
|
|
14899
14952
|
if (flushTimer) {
|
|
14900
14953
|
clearTimeout(flushTimer);
|
|
@@ -14905,6 +14958,8 @@ function flush() {
|
|
|
14905
14958
|
const data = buffer.join("");
|
|
14906
14959
|
buffer = [];
|
|
14907
14960
|
try {
|
|
14961
|
+
const logFile = getMagicContextLogPath();
|
|
14962
|
+
ensureDir(logFile);
|
|
14908
14963
|
fs.appendFileSync(logFile, data);
|
|
14909
14964
|
} catch {}
|
|
14910
14965
|
}
|
|
@@ -14935,9 +14990,9 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
|
14935
14990
|
function sessionLog(sessionId, message, data) {
|
|
14936
14991
|
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
14937
14992
|
}
|
|
14938
|
-
var
|
|
14993
|
+
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
|
|
14939
14994
|
var init_logger = __esm(() => {
|
|
14940
|
-
|
|
14995
|
+
init_data_path();
|
|
14941
14996
|
buffer = [];
|
|
14942
14997
|
if (!isTestEnv) {
|
|
14943
14998
|
process.on("exit", flush);
|
|
@@ -14961,30 +15016,47 @@ function cosineSimilarity(a, b) {
|
|
|
14961
15016
|
return denominator === 0 ? 0 : dotProduct / denominator;
|
|
14962
15017
|
}
|
|
14963
15018
|
|
|
14964
|
-
// ../plugin/src/
|
|
14965
|
-
import
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
|
|
14969
|
-
}
|
|
14970
|
-
function getOpenCodeStorageDir() {
|
|
14971
|
-
return path2.join(getDataDir(), "opencode", "storage");
|
|
15019
|
+
// ../plugin/src/features/magic-context/memory/normalize-hash.ts
|
|
15020
|
+
import { createHash } from "node:crypto";
|
|
15021
|
+
function normalizeMemoryContent(content) {
|
|
15022
|
+
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
14972
15023
|
}
|
|
14973
|
-
function
|
|
14974
|
-
|
|
15024
|
+
function computeNormalizedHash(content) {
|
|
15025
|
+
const normalized = normalizeMemoryContent(content);
|
|
15026
|
+
return createHash("md5").update(normalized).digest("hex");
|
|
14975
15027
|
}
|
|
14976
|
-
|
|
14977
|
-
|
|
15028
|
+
var init_normalize_hash = () => {};
|
|
15029
|
+
|
|
15030
|
+
// ../plugin/src/features/magic-context/memory/embedding-identity.ts
|
|
15031
|
+
function normalizeEndpoint(endpoint) {
|
|
15032
|
+
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
14978
15033
|
}
|
|
14979
|
-
function
|
|
14980
|
-
|
|
15034
|
+
function getEmbeddingProviderIdentity(config2) {
|
|
15035
|
+
if (config2.provider === "off") {
|
|
15036
|
+
return "embedding-provider:off";
|
|
15037
|
+
}
|
|
15038
|
+
const identityInput = config2.provider === "openai-compatible" ? {
|
|
15039
|
+
provider: "openai-compatible",
|
|
15040
|
+
model: config2.model.trim(),
|
|
15041
|
+
endpoint: normalizeEndpoint(config2.endpoint),
|
|
15042
|
+
apiKeyPresent: Boolean(config2.api_key?.trim())
|
|
15043
|
+
} : {
|
|
15044
|
+
provider: "local",
|
|
15045
|
+
model: config2.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
15046
|
+
endpoint: "",
|
|
15047
|
+
apiKeyPresent: false
|
|
15048
|
+
};
|
|
15049
|
+
return `embedding-provider:${computeNormalizedHash(JSON.stringify(identityInput))}`;
|
|
14981
15050
|
}
|
|
14982
|
-
var
|
|
15051
|
+
var init_embedding_identity = __esm(() => {
|
|
15052
|
+
init_magic_context();
|
|
15053
|
+
init_normalize_hash();
|
|
15054
|
+
});
|
|
14983
15055
|
|
|
14984
15056
|
// ../plugin/src/features/magic-context/memory/embedding-local.ts
|
|
14985
|
-
import { mkdirSync } from "node:fs";
|
|
15057
|
+
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
14986
15058
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
14987
|
-
import { join as
|
|
15059
|
+
import { join as join2 } from "node:path";
|
|
14988
15060
|
async function acquireModelLoadLock(lockPath) {
|
|
14989
15061
|
const waitStart = Date.now();
|
|
14990
15062
|
while (true) {
|
|
@@ -15099,7 +15171,7 @@ class LocalEmbeddingProvider {
|
|
|
15099
15171
|
initPromise = null;
|
|
15100
15172
|
constructor(model = DEFAULT_LOCAL_EMBEDDING_MODEL) {
|
|
15101
15173
|
this.model = model;
|
|
15102
|
-
this.modelId =
|
|
15174
|
+
this.modelId = getEmbeddingProviderIdentity({ provider: "local", model });
|
|
15103
15175
|
}
|
|
15104
15176
|
async initialize() {
|
|
15105
15177
|
if (this.pipeline) {
|
|
@@ -15118,15 +15190,15 @@ class LocalEmbeddingProvider {
|
|
|
15118
15190
|
if (LogLevel && "ERROR" in LogLevel) {
|
|
15119
15191
|
env.logLevel = LogLevel.ERROR;
|
|
15120
15192
|
}
|
|
15121
|
-
const modelCacheDir =
|
|
15193
|
+
const modelCacheDir = join2(getMagicContextStorageDir(), "models");
|
|
15122
15194
|
try {
|
|
15123
|
-
|
|
15195
|
+
mkdirSync2(modelCacheDir, { recursive: true });
|
|
15124
15196
|
env.cacheDir = modelCacheDir;
|
|
15125
15197
|
} catch {
|
|
15126
15198
|
log("[magic-context] could not create model cache dir, using library default");
|
|
15127
15199
|
}
|
|
15128
15200
|
const createPipeline = transformersModule.pipeline;
|
|
15129
|
-
const lockPath =
|
|
15201
|
+
const lockPath = join2(modelCacheDir, ".load.lock");
|
|
15130
15202
|
const releaseLock = await acquireModelLoadLock(lockPath);
|
|
15131
15203
|
const stopHeartbeat = startLockHeartbeat(lockPath);
|
|
15132
15204
|
try {
|
|
@@ -15241,12 +15313,13 @@ var init_embedding_local = __esm(() => {
|
|
|
15241
15313
|
init_magic_context();
|
|
15242
15314
|
init_data_path();
|
|
15243
15315
|
init_logger();
|
|
15316
|
+
init_embedding_identity();
|
|
15244
15317
|
STALE_LOCK_MS = 3 * 60000;
|
|
15245
15318
|
MAX_LOCK_WAIT_MS = 5 * 60000;
|
|
15246
15319
|
});
|
|
15247
15320
|
|
|
15248
15321
|
// ../plugin/src/features/magic-context/memory/embedding-openai.ts
|
|
15249
|
-
function
|
|
15322
|
+
function normalizeEndpoint2(endpoint) {
|
|
15250
15323
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
15251
15324
|
}
|
|
15252
15325
|
|
|
@@ -15261,10 +15334,15 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
15261
15334
|
openLogged = false;
|
|
15262
15335
|
halfOpenProbeInFlight = false;
|
|
15263
15336
|
constructor(options) {
|
|
15264
|
-
this.endpoint =
|
|
15337
|
+
this.endpoint = normalizeEndpoint2(options.endpoint);
|
|
15265
15338
|
this.model = options.model?.trim() ?? "";
|
|
15266
15339
|
this.apiKey = options.apiKey?.trim() ?? "";
|
|
15267
|
-
this.modelId =
|
|
15340
|
+
this.modelId = getEmbeddingProviderIdentity({
|
|
15341
|
+
provider: "openai-compatible",
|
|
15342
|
+
endpoint: this.endpoint,
|
|
15343
|
+
model: this.model,
|
|
15344
|
+
...this.apiKey ? { api_key: this.apiKey } : {}
|
|
15345
|
+
});
|
|
15268
15346
|
}
|
|
15269
15347
|
async initialize() {
|
|
15270
15348
|
if (this.initialized)
|
|
@@ -15446,20 +15524,10 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
15446
15524
|
var FAILURE_THRESHOLD = 3, FAILURE_WINDOW_MS = 60000, OPEN_DURATION_MS, FETCH_TIMEOUT_MS = 30000;
|
|
15447
15525
|
var init_embedding_openai = __esm(() => {
|
|
15448
15526
|
init_logger();
|
|
15527
|
+
init_embedding_identity();
|
|
15449
15528
|
OPEN_DURATION_MS = 5 * 60000;
|
|
15450
15529
|
});
|
|
15451
15530
|
|
|
15452
|
-
// ../plugin/src/features/magic-context/memory/normalize-hash.ts
|
|
15453
|
-
import { createHash } from "node:crypto";
|
|
15454
|
-
function normalizeMemoryContent(content) {
|
|
15455
|
-
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
15456
|
-
}
|
|
15457
|
-
function computeNormalizedHash(content) {
|
|
15458
|
-
const normalized = normalizeMemoryContent(content);
|
|
15459
|
-
return createHash("md5").update(normalized).digest("hex");
|
|
15460
|
-
}
|
|
15461
|
-
var init_normalize_hash = () => {};
|
|
15462
|
-
|
|
15463
15531
|
// ../plugin/src/features/magic-context/memory/storage-memory-embeddings.ts
|
|
15464
15532
|
var exports_storage_memory_embeddings = {};
|
|
15465
15533
|
__export(exports_storage_memory_embeddings, {
|
|
@@ -15604,17 +15672,8 @@ function resolveEmbeddingConfig(config2) {
|
|
|
15604
15672
|
}
|
|
15605
15673
|
return { provider: "off" };
|
|
15606
15674
|
}
|
|
15607
|
-
function
|
|
15608
|
-
|
|
15609
|
-
return "off";
|
|
15610
|
-
}
|
|
15611
|
-
if (config2.provider === "openai-compatible") {
|
|
15612
|
-
const endpoint = config2.endpoint.trim();
|
|
15613
|
-
const model = config2.model.trim();
|
|
15614
|
-
const keyHash = config2.api_key ? computeNormalizedHash(config2.api_key) : "nokey";
|
|
15615
|
-
return `openai-compat:${endpoint}:${model}:${keyHash}`;
|
|
15616
|
-
}
|
|
15617
|
-
return config2.model.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL;
|
|
15675
|
+
function resolveProviderIdentity(config2) {
|
|
15676
|
+
return getEmbeddingProviderIdentity(config2);
|
|
15618
15677
|
}
|
|
15619
15678
|
function createProvider(config2) {
|
|
15620
15679
|
if (config2.provider === "off") {
|
|
@@ -15638,10 +15697,10 @@ function getOrCreateProvider() {
|
|
|
15638
15697
|
}
|
|
15639
15698
|
function initializeEmbedding(config2) {
|
|
15640
15699
|
const nextConfig = resolveEmbeddingConfig(config2);
|
|
15641
|
-
const
|
|
15700
|
+
const nextProviderIdentity = resolveProviderIdentity(nextConfig);
|
|
15642
15701
|
const previousProvider = provider;
|
|
15643
|
-
const
|
|
15644
|
-
if (
|
|
15702
|
+
const previousProviderIdentity = previousProvider?.modelId ?? resolveProviderIdentity(embeddingConfig);
|
|
15703
|
+
if (previousProviderIdentity === nextProviderIdentity) {
|
|
15645
15704
|
embeddingConfig = nextConfig;
|
|
15646
15705
|
return;
|
|
15647
15706
|
}
|
|
@@ -15789,9 +15848,9 @@ var DEFAULT_EMBEDDING_CONFIG, embeddingConfig, provider = null, loadUnembeddedMe
|
|
|
15789
15848
|
var init_embedding = __esm(() => {
|
|
15790
15849
|
init_magic_context();
|
|
15791
15850
|
init_logger();
|
|
15851
|
+
init_embedding_identity();
|
|
15792
15852
|
init_embedding_local();
|
|
15793
15853
|
init_embedding_openai();
|
|
15794
|
-
init_normalize_hash();
|
|
15795
15854
|
init_storage_memory_embeddings();
|
|
15796
15855
|
DEFAULT_EMBEDDING_CONFIG = {
|
|
15797
15856
|
provider: "local",
|
|
@@ -15983,7 +16042,7 @@ var exports_native_binding = {};
|
|
|
15983
16042
|
__export(exports_native_binding, {
|
|
15984
16043
|
resolveBetterSqliteNativeBinding: () => resolveBetterSqliteNativeBinding
|
|
15985
16044
|
});
|
|
15986
|
-
import { existsSync, mkdirSync as
|
|
16045
|
+
import { existsSync, mkdirSync as mkdirSync3, writeFileSync } from "node:fs";
|
|
15987
16046
|
import { createRequire } from "node:module";
|
|
15988
16047
|
import * as path4 from "node:path";
|
|
15989
16048
|
function logInfo(message) {
|
|
@@ -16083,7 +16142,7 @@ async function resolveBetterSqliteNativeBinding() {
|
|
|
16083
16142
|
}
|
|
16084
16143
|
logWarn(`cached binary at ${cachedPath} has wrong ABI (${cachedProbe.actual ?? "unknown"} != ${expected}); refetching`);
|
|
16085
16144
|
}
|
|
16086
|
-
|
|
16145
|
+
mkdirSync3(path4.dirname(cachedPath), { recursive: true });
|
|
16087
16146
|
const nodeFileBytes = await downloadElectronPrebuild(pkgVersion, expected);
|
|
16088
16147
|
writeFileSync(cachedPath, nodeFileBytes);
|
|
16089
16148
|
logInfo(`cached Electron prebuild at ${cachedPath} (${(nodeFileBytes.length / 1024).toFixed(1)} KB)`);
|
|
@@ -16151,9 +16210,9 @@ __export(exports_read_session_db, {
|
|
|
16151
16210
|
findLastAssistantModelFromOpenCodeDb: () => findLastAssistantModelFromOpenCodeDb,
|
|
16152
16211
|
closeReadOnlySessionDb: () => closeReadOnlySessionDb
|
|
16153
16212
|
});
|
|
16154
|
-
import { join as
|
|
16213
|
+
import { join as join4 } from "node:path";
|
|
16155
16214
|
function getOpenCodeDbPath() {
|
|
16156
|
-
return
|
|
16215
|
+
return join4(getDataDir(), "opencode", "opencode.db");
|
|
16157
16216
|
}
|
|
16158
16217
|
function closeCachedReadOnlyDb() {
|
|
16159
16218
|
if (!cachedReadOnlyDb) {
|
|
@@ -16251,21 +16310,22 @@ __export(exports_rpc_notifications, {
|
|
|
16251
16310
|
drainNotifications: () => drainNotifications
|
|
16252
16311
|
});
|
|
16253
16312
|
function pushNotification(type, payload, sessionId) {
|
|
16254
|
-
queue2.push({ type, payload, sessionId });
|
|
16313
|
+
queue2.push({ id: nextNotificationId++, type, payload, sessionId });
|
|
16255
16314
|
if (queue2.length > 100) {
|
|
16256
16315
|
queue2 = queue2.slice(-50);
|
|
16257
16316
|
}
|
|
16258
16317
|
}
|
|
16259
|
-
function drainNotifications() {
|
|
16318
|
+
function drainNotifications(lastReceivedId = 0) {
|
|
16260
16319
|
lastDrainAt = Date.now();
|
|
16261
|
-
|
|
16262
|
-
|
|
16263
|
-
|
|
16320
|
+
if (lastReceivedId > 0) {
|
|
16321
|
+
queue2 = queue2.filter((notification) => notification.id > lastReceivedId);
|
|
16322
|
+
}
|
|
16323
|
+
return [...queue2];
|
|
16264
16324
|
}
|
|
16265
16325
|
function isTuiConnected() {
|
|
16266
16326
|
return lastDrainAt > 0 && Date.now() - lastDrainAt < TUI_CONNECTED_WINDOW_MS;
|
|
16267
16327
|
}
|
|
16268
|
-
var queue2, lastDrainAt = 0, TUI_CONNECTED_WINDOW_MS = 3000;
|
|
16328
|
+
var queue2, nextNotificationId = 1, lastDrainAt = 0, TUI_CONNECTED_WINDOW_MS = 3000;
|
|
16269
16329
|
var init_rpc_notifications = __esm(() => {
|
|
16270
16330
|
queue2 = [];
|
|
16271
16331
|
});
|
|
@@ -23877,10 +23937,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23877
23937
|
replacer = null;
|
|
23878
23938
|
indent = EMPTY;
|
|
23879
23939
|
};
|
|
23880
|
-
var
|
|
23940
|
+
var join12 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
23881
23941
|
var join_content = (inside, value, gap) => {
|
|
23882
23942
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
23883
|
-
return
|
|
23943
|
+
return join12(comment, inside, gap);
|
|
23884
23944
|
};
|
|
23885
23945
|
var stringify_string = (holder, key, value) => {
|
|
23886
23946
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -23902,13 +23962,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23902
23962
|
if (i !== 0) {
|
|
23903
23963
|
inside += COMMA;
|
|
23904
23964
|
}
|
|
23905
|
-
const before =
|
|
23965
|
+
const before = join12(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
23906
23966
|
inside += before || LF + deeper_gap;
|
|
23907
23967
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
23908
23968
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
23909
23969
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
23910
23970
|
}
|
|
23911
|
-
inside +=
|
|
23971
|
+
inside += join12(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
23912
23972
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
23913
23973
|
};
|
|
23914
23974
|
var object_stringify = (value, gap) => {
|
|
@@ -23929,13 +23989,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
23929
23989
|
inside += COMMA;
|
|
23930
23990
|
}
|
|
23931
23991
|
first = false;
|
|
23932
|
-
const before =
|
|
23992
|
+
const before = join12(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
23933
23993
|
inside += before || LF + deeper_gap;
|
|
23934
23994
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
23935
23995
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
23936
23996
|
};
|
|
23937
23997
|
keys.forEach(iteratee);
|
|
23938
|
-
inside +=
|
|
23998
|
+
inside += join12(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
23939
23999
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
23940
24000
|
};
|
|
23941
24001
|
function stringify(key, holder, gap) {
|
|
@@ -24030,7 +24090,7 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
24030
24090
|
// src/index.ts
|
|
24031
24091
|
init_embedding();
|
|
24032
24092
|
import { createRequire as createRequire2 } from "node:module";
|
|
24033
|
-
import { join as
|
|
24093
|
+
import { join as join14 } from "node:path";
|
|
24034
24094
|
|
|
24035
24095
|
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
24036
24096
|
import { execSync } from "node:child_process";
|
|
@@ -157083,21 +157143,6 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
157083
157143
|
toolOnlyRanges
|
|
157084
157144
|
};
|
|
157085
157145
|
}
|
|
157086
|
-
|
|
157087
|
-
// ../plugin/src/shared/harness.ts
|
|
157088
|
-
var currentHarness = "opencode";
|
|
157089
|
-
var harnessLocked = false;
|
|
157090
|
-
function setHarness(value) {
|
|
157091
|
-
if (harnessLocked && currentHarness !== value) {
|
|
157092
|
-
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
157093
|
-
}
|
|
157094
|
-
currentHarness = value;
|
|
157095
|
-
harnessLocked = true;
|
|
157096
|
-
}
|
|
157097
|
-
function getHarness() {
|
|
157098
|
-
return currentHarness;
|
|
157099
|
-
}
|
|
157100
|
-
|
|
157101
157146
|
// ../plugin/src/features/magic-context/compression-depth-storage.ts
|
|
157102
157147
|
var incrementDepthStatements = new WeakMap;
|
|
157103
157148
|
var totalDepthStatements = new WeakMap;
|
|
@@ -157773,8 +157818,8 @@ function escapeXmlContent(s) {
|
|
|
157773
157818
|
}
|
|
157774
157819
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
157775
157820
|
init_data_path();
|
|
157776
|
-
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as
|
|
157777
|
-
import { join as
|
|
157821
|
+
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as mkdirSync4 } from "node:fs";
|
|
157822
|
+
import { join as join6 } from "node:path";
|
|
157778
157823
|
|
|
157779
157824
|
// ../plugin/src/shared/error-message.ts
|
|
157780
157825
|
function getErrorMessage(error51) {
|
|
@@ -157991,6 +158036,9 @@ var MIGRATIONS = [
|
|
|
157991
158036
|
embedding BLOB NOT NULL,
|
|
157992
158037
|
model_id TEXT NOT NULL,
|
|
157993
158038
|
created_at INTEGER NOT NULL,
|
|
158039
|
+
-- FK-cascade audit (v12): git_commit_embeddings.sha -> git_commits.sha
|
|
158040
|
+
-- uses ON DELETE CASCADE, so SQLite PRAGMA foreign_keys must be ON on
|
|
158041
|
+
-- every connection and v12 cleans historical orphan rows.
|
|
157994
158042
|
FOREIGN KEY(sha) REFERENCES git_commits(sha) ON DELETE CASCADE
|
|
157995
158043
|
);
|
|
157996
158044
|
|
|
@@ -158111,6 +158159,48 @@ var MIGRATIONS = [
|
|
|
158111
158159
|
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
158112
158160
|
`);
|
|
158113
158161
|
}
|
|
158162
|
+
},
|
|
158163
|
+
{
|
|
158164
|
+
version: 11,
|
|
158165
|
+
description: "Add todo state synthesis columns to session_meta",
|
|
158166
|
+
up: (db) => {
|
|
158167
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
158168
|
+
if (!cols.some((c) => c.name === "last_todo_state")) {
|
|
158169
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN last_todo_state TEXT DEFAULT ''");
|
|
158170
|
+
}
|
|
158171
|
+
if (!cols.some((c) => c.name === "todo_synthetic_call_id")) {
|
|
158172
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_call_id TEXT DEFAULT ''");
|
|
158173
|
+
}
|
|
158174
|
+
if (!cols.some((c) => c.name === "todo_synthetic_anchor_message_id")) {
|
|
158175
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_anchor_message_id TEXT DEFAULT ''");
|
|
158176
|
+
}
|
|
158177
|
+
if (!cols.some((c) => c.name === "todo_synthetic_state_json")) {
|
|
158178
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_state_json TEXT DEFAULT ''");
|
|
158179
|
+
}
|
|
158180
|
+
}
|
|
158181
|
+
},
|
|
158182
|
+
{
|
|
158183
|
+
version: 12,
|
|
158184
|
+
description: "Clean orphan rows from FK-cascade embedding tables",
|
|
158185
|
+
up: (db) => {
|
|
158186
|
+
const hasTable = (name2) => Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name2));
|
|
158187
|
+
const memoryEmbeddings = hasTable("memory_embeddings") ? db.prepare(`DELETE FROM memory_embeddings
|
|
158188
|
+
WHERE memory_id NOT IN (SELECT id FROM memories)`).run().changes : 0;
|
|
158189
|
+
log(`[migrations] v12 cleaned ${memoryEmbeddings} orphan memory_embeddings row(s)`);
|
|
158190
|
+
const gitCommitEmbeddings = hasTable("git_commit_embeddings") ? db.prepare(`DELETE FROM git_commit_embeddings
|
|
158191
|
+
WHERE sha NOT IN (SELECT sha FROM git_commits)`).run().changes : 0;
|
|
158192
|
+
log(`[migrations] v12 cleaned ${gitCommitEmbeddings} orphan git_commit_embeddings row(s)`);
|
|
158193
|
+
}
|
|
158194
|
+
},
|
|
158195
|
+
{
|
|
158196
|
+
version: 13,
|
|
158197
|
+
description: "Add pending_compaction_marker_state column for deferred marker drain",
|
|
158198
|
+
up: (db) => {
|
|
158199
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
158200
|
+
if (!cols.some((c) => c.name === "pending_compaction_marker_state")) {
|
|
158201
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN pending_compaction_marker_state TEXT");
|
|
158202
|
+
}
|
|
158203
|
+
}
|
|
158114
158204
|
}
|
|
158115
158205
|
];
|
|
158116
158206
|
function ensureMigrationsTable(db) {
|
|
@@ -158178,6 +158268,28 @@ function runMigrations(db) {
|
|
|
158178
158268
|
log(`[migrations] schema version now: ${MIGRATIONS[MIGRATIONS.length - 1].version}`);
|
|
158179
158269
|
}
|
|
158180
158270
|
|
|
158271
|
+
// ../plugin/src/shared/stable-json.ts
|
|
158272
|
+
function stableStringify(value, seen = new WeakSet) {
|
|
158273
|
+
if (value === undefined)
|
|
158274
|
+
return "undefined";
|
|
158275
|
+
if (value === null || typeof value !== "object")
|
|
158276
|
+
return JSON.stringify(value) ?? String(value);
|
|
158277
|
+
if (seen.has(value))
|
|
158278
|
+
return '"[Circular]"';
|
|
158279
|
+
seen.add(value);
|
|
158280
|
+
if (Array.isArray(value)) {
|
|
158281
|
+
return `[${value.map((item) => stableStringify(item, seen)).join(",")}]`;
|
|
158282
|
+
}
|
|
158283
|
+
const entries = Object.entries(value).sort(([a], [b]) => {
|
|
158284
|
+
if (a < b)
|
|
158285
|
+
return -1;
|
|
158286
|
+
if (a > b)
|
|
158287
|
+
return 1;
|
|
158288
|
+
return 0;
|
|
158289
|
+
});
|
|
158290
|
+
return `{${entries.map(([key, child]) => `${JSON.stringify(key)}:${stableStringify(child, seen)}`).join(",")}}`;
|
|
158291
|
+
}
|
|
158292
|
+
|
|
158181
158293
|
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
158182
158294
|
var measurements = new Map;
|
|
158183
158295
|
var fingerprints = new Map;
|
|
@@ -158213,11 +158325,11 @@ function loadToolDefinitionMeasurements(db) {
|
|
|
158213
158325
|
init_data_path();
|
|
158214
158326
|
init_logger();
|
|
158215
158327
|
import { existsSync as existsSync2 } from "node:fs";
|
|
158216
|
-
import { join as
|
|
158328
|
+
import { join as join5 } from "node:path";
|
|
158217
158329
|
var LEASE_DURATION_MS = 5 * 60 * 1000;
|
|
158218
158330
|
var LEASE_RENEWAL_MS = 60 * 1000;
|
|
158219
158331
|
function resolveOpencodeDbPath() {
|
|
158220
|
-
return
|
|
158332
|
+
return join5(getDataDir(), "opencode", "opencode.db");
|
|
158221
158333
|
}
|
|
158222
158334
|
function ensureBackfillStateTable(db) {
|
|
158223
158335
|
db.exec(`
|
|
@@ -158460,20 +158572,20 @@ var persistenceByDatabase = new WeakMap;
|
|
|
158460
158572
|
var persistenceErrorByDatabase = new WeakMap;
|
|
158461
158573
|
function resolveDatabasePath() {
|
|
158462
158574
|
const dbDir = getMagicContextStorageDir();
|
|
158463
|
-
return { dbDir, dbPath:
|
|
158575
|
+
return { dbDir, dbPath: join6(dbDir, "context.db") };
|
|
158464
158576
|
}
|
|
158465
158577
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
158466
158578
|
if (existsSync3(targetDbPath))
|
|
158467
158579
|
return;
|
|
158468
158580
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
158469
|
-
const legacyDbPath =
|
|
158581
|
+
const legacyDbPath = join6(legacyDir, "context.db");
|
|
158470
158582
|
if (!existsSync3(legacyDbPath))
|
|
158471
158583
|
return;
|
|
158472
158584
|
log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
158473
|
-
|
|
158585
|
+
mkdirSync4(targetDbDir, { recursive: true });
|
|
158474
158586
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
158475
158587
|
const src = `${legacyDbPath}${suffix}`;
|
|
158476
|
-
const dst =
|
|
158588
|
+
const dst = join6(targetDbDir, `context.db${suffix}`);
|
|
158477
158589
|
if (existsSync3(src)) {
|
|
158478
158590
|
try {
|
|
158479
158591
|
copyFileSync(src, dst);
|
|
@@ -158482,8 +158594,8 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
158482
158594
|
}
|
|
158483
158595
|
}
|
|
158484
158596
|
}
|
|
158485
|
-
const legacyModelsDir =
|
|
158486
|
-
const targetModelsDir =
|
|
158597
|
+
const legacyModelsDir = join6(legacyDir, "models");
|
|
158598
|
+
const targetModelsDir = join6(targetDbDir, "models");
|
|
158487
158599
|
if (existsSync3(legacyModelsDir) && !existsSync3(targetModelsDir)) {
|
|
158488
158600
|
try {
|
|
158489
158601
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
@@ -158493,9 +158605,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
158493
158605
|
}
|
|
158494
158606
|
}
|
|
158495
158607
|
function initializeDatabase(db) {
|
|
158608
|
+
db.exec("PRAGMA foreign_keys=ON");
|
|
158496
158609
|
db.exec("PRAGMA journal_mode=WAL");
|
|
158497
158610
|
db.exec("PRAGMA busy_timeout=5000");
|
|
158498
|
-
db.exec("PRAGMA foreign_keys=ON");
|
|
158499
158611
|
db.exec(`
|
|
158500
158612
|
CREATE TABLE IF NOT EXISTS tags (
|
|
158501
158613
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -158593,6 +158705,9 @@ function initializeDatabase(db) {
|
|
|
158593
158705
|
);
|
|
158594
158706
|
|
|
158595
158707
|
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
158708
|
+
-- FK-cascade audit (v12): memory_embeddings.memory_id -> memories.id
|
|
158709
|
+
-- uses ON DELETE CASCADE, so SQLite PRAGMA foreign_keys must be ON on
|
|
158710
|
+
-- every connection and v12 cleans historical orphan rows.
|
|
158596
158711
|
memory_id INTEGER PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
158597
158712
|
embedding BLOB NOT NULL,
|
|
158598
158713
|
model_id TEXT
|
|
@@ -158685,6 +158800,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158685
158800
|
note_nudge_trigger_message_id TEXT DEFAULT '',
|
|
158686
158801
|
note_nudge_sticky_text TEXT DEFAULT '',
|
|
158687
158802
|
note_nudge_sticky_message_id TEXT DEFAULT '',
|
|
158803
|
+
last_todo_state TEXT DEFAULT '',
|
|
158804
|
+
todo_synthetic_call_id TEXT DEFAULT '',
|
|
158805
|
+
todo_synthetic_anchor_message_id TEXT DEFAULT '',
|
|
158806
|
+
todo_synthetic_state_json TEXT DEFAULT '',
|
|
158688
158807
|
is_subagent INTEGER DEFAULT 0,
|
|
158689
158808
|
last_context_percentage REAL DEFAULT 0,
|
|
158690
158809
|
last_input_tokens INTEGER DEFAULT 0,
|
|
@@ -158696,7 +158815,13 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158696
158815
|
system_prompt_hash TEXT DEFAULT '',
|
|
158697
158816
|
memory_block_cache TEXT DEFAULT '',
|
|
158698
158817
|
memory_block_count INTEGER DEFAULT 0,
|
|
158699
|
-
memory_block_ids TEXT DEFAULT ''
|
|
158818
|
+
memory_block_ids TEXT DEFAULT '',
|
|
158819
|
+
-- pending_compaction_marker_state: intentionally NULLABLE without a
|
|
158820
|
+
-- default. Absence of a deferred marker is SQL NULL; presence is a
|
|
158821
|
+
-- valid JSON blob written via setPendingCompactionMarkerState.
|
|
158822
|
+
-- Excluded from healNullTextColumns. Readers filter IS NOT NULL AND
|
|
158823
|
+
-- != empty-string defensively. Plan v6 section 3.
|
|
158824
|
+
pending_compaction_marker_state TEXT
|
|
158700
158825
|
);
|
|
158701
158826
|
|
|
158702
158827
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
@@ -158749,6 +158874,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158749
158874
|
ensureColumn(db, "session_meta", "note_nudge_trigger_message_id", "TEXT DEFAULT ''");
|
|
158750
158875
|
ensureColumn(db, "session_meta", "note_nudge_sticky_text", "TEXT DEFAULT ''");
|
|
158751
158876
|
ensureColumn(db, "session_meta", "note_nudge_sticky_message_id", "TEXT DEFAULT ''");
|
|
158877
|
+
ensureColumn(db, "session_meta", "last_todo_state", "TEXT DEFAULT ''");
|
|
158878
|
+
ensureColumn(db, "session_meta", "todo_synthetic_call_id", "TEXT DEFAULT ''");
|
|
158879
|
+
ensureColumn(db, "session_meta", "todo_synthetic_anchor_message_id", "TEXT DEFAULT ''");
|
|
158880
|
+
ensureColumn(db, "session_meta", "todo_synthetic_state_json", "TEXT DEFAULT ''");
|
|
158752
158881
|
ensureColumn(db, "session_meta", "note_last_read_at", "INTEGER DEFAULT 0");
|
|
158753
158882
|
ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
|
|
158754
158883
|
ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
|
|
@@ -158780,6 +158909,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
158780
158909
|
ensureColumn(db, "session_meta", "recomp_partial_range_end", "INTEGER DEFAULT 0");
|
|
158781
158910
|
ensureColumn(db, "session_meta", "detected_context_limit", "INTEGER DEFAULT 0");
|
|
158782
158911
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
158912
|
+
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
158783
158913
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
158784
158914
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
158785
158915
|
ensureColumn(db, "source_contents", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -158813,6 +158943,10 @@ function healNullTextColumns(db) {
|
|
|
158813
158943
|
["note_nudge_trigger_message_id", ""],
|
|
158814
158944
|
["note_nudge_sticky_text", ""],
|
|
158815
158945
|
["note_nudge_sticky_message_id", ""],
|
|
158946
|
+
["last_todo_state", ""],
|
|
158947
|
+
["todo_synthetic_call_id", ""],
|
|
158948
|
+
["todo_synthetic_anchor_message_id", ""],
|
|
158949
|
+
["todo_synthetic_state_json", ""],
|
|
158816
158950
|
["system_prompt_hash", ""],
|
|
158817
158951
|
["stripped_placeholder_ids", ""],
|
|
158818
158952
|
["memory_block_cache", ""],
|
|
@@ -158865,7 +158999,7 @@ function openDatabase() {
|
|
|
158865
158999
|
}
|
|
158866
159000
|
try {
|
|
158867
159001
|
migrateLegacyStorageIfNeeded(dbPath, dbDir);
|
|
158868
|
-
|
|
159002
|
+
mkdirSync4(dbDir, { recursive: true });
|
|
158869
159003
|
const db = new Database(dbPath);
|
|
158870
159004
|
initializeDatabase(db);
|
|
158871
159005
|
runMigrations(db);
|
|
@@ -158906,7 +159040,8 @@ var META_COLUMNS = {
|
|
|
158906
159040
|
systemPromptTokens: "system_prompt_tokens",
|
|
158907
159041
|
conversationTokens: "conversation_tokens",
|
|
158908
159042
|
toolCallTokens: "tool_call_tokens",
|
|
158909
|
-
clearedReasoningThroughTag: "cleared_reasoning_through_tag"
|
|
159043
|
+
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
159044
|
+
lastTodoState: "last_todo_state"
|
|
158910
159045
|
};
|
|
158911
159046
|
var BOOLEAN_META_KEYS = new Set(["isSubagent", "compartmentInProgress"]);
|
|
158912
159047
|
function isStringOrNull(value) {
|
|
@@ -158919,7 +159054,7 @@ function isSessionMetaRow(row) {
|
|
|
158919
159054
|
if (row === null || typeof row !== "object")
|
|
158920
159055
|
return false;
|
|
158921
159056
|
const r = row;
|
|
158922
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag);
|
|
159057
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state);
|
|
158923
159058
|
}
|
|
158924
159059
|
function getDefaultSessionMeta(sessionId) {
|
|
158925
159060
|
return {
|
|
@@ -158939,7 +159074,8 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
158939
159074
|
systemPromptTokens: 0,
|
|
158940
159075
|
conversationTokens: 0,
|
|
158941
159076
|
toolCallTokens: 0,
|
|
158942
|
-
clearedReasoningThroughTag: 0
|
|
159077
|
+
clearedReasoningThroughTag: 0,
|
|
159078
|
+
lastTodoState: ""
|
|
158943
159079
|
};
|
|
158944
159080
|
}
|
|
158945
159081
|
function ensureSessionMetaRow(db, sessionId) {
|
|
@@ -158951,6 +159087,7 @@ function toSessionMeta(row) {
|
|
|
158951
159087
|
const transformErrorRaw = typeof row.last_transform_error === "string" ? row.last_transform_error : "";
|
|
158952
159088
|
const cacheTtlRaw = typeof row.cache_ttl === "string" && row.cache_ttl.length > 0 ? row.cache_ttl : "5m";
|
|
158953
159089
|
const systemPromptHashRaw = row.system_prompt_hash == null ? "" : row.system_prompt_hash;
|
|
159090
|
+
const lastTodoStateRaw = typeof row.last_todo_state === "string" ? row.last_todo_state : "";
|
|
158954
159091
|
const numOrZero = (value) => typeof value === "number" ? value : 0;
|
|
158955
159092
|
return {
|
|
158956
159093
|
sessionId: row.session_id,
|
|
@@ -158969,7 +159106,8 @@ function toSessionMeta(row) {
|
|
|
158969
159106
|
systemPromptTokens: numOrZero(row.system_prompt_tokens),
|
|
158970
159107
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
158971
159108
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
158972
|
-
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag)
|
|
159109
|
+
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
159110
|
+
lastTodoState: lastTodoStateRaw
|
|
158973
159111
|
};
|
|
158974
159112
|
}
|
|
158975
159113
|
|
|
@@ -159166,6 +159304,28 @@ function setStrippedPlaceholderIds(db, sessionId, ids) {
|
|
|
159166
159304
|
const json2 = ids.size > 0 ? JSON.stringify([...ids]) : "";
|
|
159167
159305
|
db.prepare("UPDATE session_meta SET stripped_placeholder_ids = ? WHERE session_id = ?").run(json2, sessionId);
|
|
159168
159306
|
}
|
|
159307
|
+
function isPendingCompactionMarker(value) {
|
|
159308
|
+
return typeof value === "object" && value !== null && typeof value.ordinal === "number" && typeof value.endMessageId === "string" && typeof value.publishedAt === "number";
|
|
159309
|
+
}
|
|
159310
|
+
function getPendingCompactionMarkerState(db, sessionId) {
|
|
159311
|
+
const row = db.prepare("SELECT pending_compaction_marker_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
159312
|
+
const raw = row?.pending_compaction_marker_state;
|
|
159313
|
+
if (raw === null || raw === undefined || raw === "")
|
|
159314
|
+
return null;
|
|
159315
|
+
try {
|
|
159316
|
+
const parsed = JSON.parse(raw);
|
|
159317
|
+
if (isPendingCompactionMarker(parsed)) {
|
|
159318
|
+
return parsed;
|
|
159319
|
+
}
|
|
159320
|
+
} catch {}
|
|
159321
|
+
return null;
|
|
159322
|
+
}
|
|
159323
|
+
function clearPendingCompactionMarkerStateIf(db, sessionId, expected) {
|
|
159324
|
+
const expectedBlob = stableStringify(expected);
|
|
159325
|
+
const result = db.prepare(`UPDATE session_meta SET pending_compaction_marker_state = NULL
|
|
159326
|
+
WHERE session_id = ? AND pending_compaction_marker_state = ?`).run(sessionId, expectedBlob);
|
|
159327
|
+
return result.changes > 0;
|
|
159328
|
+
}
|
|
159169
159329
|
// ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
|
|
159170
159330
|
init_logger();
|
|
159171
159331
|
await init_read_session_db();
|
|
@@ -159185,7 +159345,7 @@ function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
|
159185
159345
|
|
|
159186
159346
|
// ../plugin/src/features/magic-context/storage-meta-session.ts
|
|
159187
159347
|
function getOrCreateSessionMeta(db, sessionId) {
|
|
159188
|
-
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
159348
|
+
const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, system_prompt_tokens, conversation_tokens, tool_call_tokens, cleared_reasoning_through_tag, last_todo_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
159189
159349
|
if (isSessionMetaRow(result)) {
|
|
159190
159350
|
return toSessionMeta(result);
|
|
159191
159351
|
}
|
|
@@ -159751,14 +159911,118 @@ function expandFallbackChain(chain) {
|
|
|
159751
159911
|
}
|
|
159752
159912
|
return models;
|
|
159753
159913
|
}
|
|
159914
|
+
function getAgentFallbackModels(agent) {
|
|
159915
|
+
const requirement = AGENT_MODEL_REQUIREMENTS[agent];
|
|
159916
|
+
if (!requirement)
|
|
159917
|
+
return;
|
|
159918
|
+
return expandFallbackChain(requirement.fallbackChain);
|
|
159919
|
+
}
|
|
159754
159920
|
|
|
159755
159921
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
159756
159922
|
init_data_path();
|
|
159757
|
-
init_logger();
|
|
159758
159923
|
import { createHash as createHash3 } from "node:crypto";
|
|
159759
159924
|
import { existsSync as existsSync4, readFileSync } from "node:fs";
|
|
159760
159925
|
import { homedir as homedir2, platform } from "node:os";
|
|
159761
|
-
import { join as
|
|
159926
|
+
import { join as join7 } from "node:path";
|
|
159927
|
+
|
|
159928
|
+
// ../plugin/src/shared/jsonc-parser.ts
|
|
159929
|
+
function stripJsonComments(content) {
|
|
159930
|
+
let result = "";
|
|
159931
|
+
let inString = false;
|
|
159932
|
+
let escaped = false;
|
|
159933
|
+
let inLineComment = false;
|
|
159934
|
+
let inBlockComment = false;
|
|
159935
|
+
for (let index = 0;index < content.length; index += 1) {
|
|
159936
|
+
const char = content[index];
|
|
159937
|
+
const next = content[index + 1];
|
|
159938
|
+
if (inLineComment) {
|
|
159939
|
+
if (char === `
|
|
159940
|
+
`) {
|
|
159941
|
+
inLineComment = false;
|
|
159942
|
+
result += char;
|
|
159943
|
+
}
|
|
159944
|
+
continue;
|
|
159945
|
+
}
|
|
159946
|
+
if (inBlockComment) {
|
|
159947
|
+
if (char === "*" && next === "/") {
|
|
159948
|
+
inBlockComment = false;
|
|
159949
|
+
index += 1;
|
|
159950
|
+
}
|
|
159951
|
+
continue;
|
|
159952
|
+
}
|
|
159953
|
+
if (inString) {
|
|
159954
|
+
result += char;
|
|
159955
|
+
if (escaped) {
|
|
159956
|
+
escaped = false;
|
|
159957
|
+
} else if (char === "\\") {
|
|
159958
|
+
escaped = true;
|
|
159959
|
+
} else if (char === '"') {
|
|
159960
|
+
inString = false;
|
|
159961
|
+
}
|
|
159962
|
+
continue;
|
|
159963
|
+
}
|
|
159964
|
+
if (char === '"') {
|
|
159965
|
+
inString = true;
|
|
159966
|
+
result += char;
|
|
159967
|
+
continue;
|
|
159968
|
+
}
|
|
159969
|
+
if (char === "/" && next === "/") {
|
|
159970
|
+
inLineComment = true;
|
|
159971
|
+
index += 1;
|
|
159972
|
+
continue;
|
|
159973
|
+
}
|
|
159974
|
+
if (char === "/" && next === "*") {
|
|
159975
|
+
inBlockComment = true;
|
|
159976
|
+
index += 1;
|
|
159977
|
+
continue;
|
|
159978
|
+
}
|
|
159979
|
+
result += char;
|
|
159980
|
+
}
|
|
159981
|
+
return result;
|
|
159982
|
+
}
|
|
159983
|
+
function stripTrailingCommas(content) {
|
|
159984
|
+
let result = "";
|
|
159985
|
+
let inString = false;
|
|
159986
|
+
let escaped = false;
|
|
159987
|
+
for (let index = 0;index < content.length; index += 1) {
|
|
159988
|
+
const char = content[index];
|
|
159989
|
+
if (inString) {
|
|
159990
|
+
result += char;
|
|
159991
|
+
if (escaped) {
|
|
159992
|
+
escaped = false;
|
|
159993
|
+
} else if (char === "\\") {
|
|
159994
|
+
escaped = true;
|
|
159995
|
+
} else if (char === '"') {
|
|
159996
|
+
inString = false;
|
|
159997
|
+
}
|
|
159998
|
+
continue;
|
|
159999
|
+
}
|
|
160000
|
+
if (char === '"') {
|
|
160001
|
+
inString = true;
|
|
160002
|
+
result += char;
|
|
160003
|
+
continue;
|
|
160004
|
+
}
|
|
160005
|
+
if (char === ",") {
|
|
160006
|
+
let lookahead = index + 1;
|
|
160007
|
+
while (lookahead < content.length && /\s/.test(content[lookahead] ?? "")) {
|
|
160008
|
+
lookahead += 1;
|
|
160009
|
+
}
|
|
160010
|
+
const next = content[lookahead];
|
|
160011
|
+
if (next === "}" || next === "]") {
|
|
160012
|
+
continue;
|
|
160013
|
+
}
|
|
160014
|
+
}
|
|
160015
|
+
result += char;
|
|
160016
|
+
}
|
|
160017
|
+
return result;
|
|
160018
|
+
}
|
|
160019
|
+
function parseJsonc(content) {
|
|
160020
|
+
const normalized = stripTrailingCommas(stripJsonComments(content));
|
|
160021
|
+
return JSON.parse(normalized);
|
|
160022
|
+
}
|
|
160023
|
+
|
|
160024
|
+
// ../plugin/src/shared/models-dev-cache.ts
|
|
160025
|
+
init_logger();
|
|
159762
160026
|
var RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
159763
160027
|
var apiCache = null;
|
|
159764
160028
|
var recentlySeenApiSizes = new Set;
|
|
@@ -159774,15 +160038,15 @@ function getModelsJsonPath() {
|
|
|
159774
160038
|
const cacheBase = getCacheDir();
|
|
159775
160039
|
const source = process.env.OPENCODE_MODELS_URL?.trim();
|
|
159776
160040
|
const filename = source && source !== "https://models.dev" ? `models-${hashFast(source)}.json` : "models.json";
|
|
159777
|
-
return
|
|
160041
|
+
return join7(cacheBase, "opencode", filename);
|
|
159778
160042
|
}
|
|
159779
160043
|
function getOpencodeConfigPath() {
|
|
159780
160044
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
159781
|
-
const configDir = envDir ? envDir : platform() === "win32" ?
|
|
159782
|
-
const jsonc =
|
|
160045
|
+
const configDir = envDir ? envDir : platform() === "win32" ? join7(homedir2(), ".config", "opencode") : join7(process.env.XDG_CONFIG_HOME || join7(homedir2(), ".config"), "opencode");
|
|
160046
|
+
const jsonc = join7(configDir, "opencode.jsonc");
|
|
159783
160047
|
if (existsSync4(jsonc))
|
|
159784
160048
|
return jsonc;
|
|
159785
|
-
const json2 =
|
|
160049
|
+
const json2 = join7(configDir, "opencode.json");
|
|
159786
160050
|
if (existsSync4(json2))
|
|
159787
160051
|
return json2;
|
|
159788
160052
|
return null;
|
|
@@ -159833,9 +160097,7 @@ function loadModelsDevMetadataFromFile() {
|
|
|
159833
160097
|
try {
|
|
159834
160098
|
const configPath = getOpencodeConfigPath();
|
|
159835
160099
|
if (configPath && existsSync4(configPath)) {
|
|
159836
|
-
|
|
159837
|
-
raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
|
|
159838
|
-
const config2 = JSON.parse(raw);
|
|
160100
|
+
const config2 = parseJsonc(readFileSync(configPath, "utf-8"));
|
|
159839
160101
|
if (config2.provider && typeof config2.provider === "object") {
|
|
159840
160102
|
for (const [providerId, provider2] of Object.entries(config2.provider)) {
|
|
159841
160103
|
if (!provider2?.models || typeof provider2.models !== "object")
|
|
@@ -160160,12 +160422,12 @@ init_logger();
|
|
|
160160
160422
|
// src/subagent-runner.ts
|
|
160161
160423
|
import * as childProcess from "node:child_process";
|
|
160162
160424
|
import { existsSync as existsSync5 } from "node:fs";
|
|
160163
|
-
import { dirname as
|
|
160425
|
+
import { dirname as dirname3, resolve as resolvePath } from "node:path";
|
|
160164
160426
|
import { createInterface } from "node:readline";
|
|
160165
160427
|
import { fileURLToPath } from "node:url";
|
|
160166
160428
|
function resolveSubagentEntryPath() {
|
|
160167
160429
|
try {
|
|
160168
|
-
const here =
|
|
160430
|
+
const here = dirname3(fileURLToPath(import.meta.url));
|
|
160169
160431
|
const candidate = resolvePath(here, "subagent-entry.js");
|
|
160170
160432
|
if (existsSync5(candidate))
|
|
160171
160433
|
return candidate;
|
|
@@ -160607,69 +160869,6 @@ ${sidekickText}
|
|
|
160607
160869
|
});
|
|
160608
160870
|
}
|
|
160609
160871
|
|
|
160610
|
-
// ../plugin/src/features/magic-context/dreamer/queue.ts
|
|
160611
|
-
function enqueueDream(db, projectIdentity, reason, force = false) {
|
|
160612
|
-
const now = Date.now();
|
|
160613
|
-
return db.transaction(() => {
|
|
160614
|
-
const staleThresholdMs = force ? 2 * 60 * 1000 : 120 * 60 * 1000;
|
|
160615
|
-
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run([projectIdentity, now - staleThresholdMs]);
|
|
160616
|
-
const existing = db.prepare("SELECT id FROM dream_queue WHERE project_path = ?").get(projectIdentity);
|
|
160617
|
-
if (existing) {
|
|
160618
|
-
return null;
|
|
160619
|
-
}
|
|
160620
|
-
const result = db.prepare("INSERT INTO dream_queue (project_path, reason, enqueued_at) VALUES (?, ?, ?)").run(projectIdentity, reason, now);
|
|
160621
|
-
return {
|
|
160622
|
-
id: Number(result.lastInsertRowid),
|
|
160623
|
-
projectIdentity,
|
|
160624
|
-
reason,
|
|
160625
|
-
enqueuedAt: now,
|
|
160626
|
-
startedAt: null
|
|
160627
|
-
};
|
|
160628
|
-
})();
|
|
160629
|
-
}
|
|
160630
|
-
function peekQueue(db, projectIdentity) {
|
|
160631
|
-
const row = projectIdentity ? db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL AND project_path = ? ORDER BY enqueued_at ASC LIMIT 1").get(projectIdentity) : db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
|
|
160632
|
-
if (!row)
|
|
160633
|
-
return null;
|
|
160634
|
-
return {
|
|
160635
|
-
id: row.id,
|
|
160636
|
-
projectIdentity: row.project_path,
|
|
160637
|
-
reason: row.reason,
|
|
160638
|
-
enqueuedAt: row.enqueued_at,
|
|
160639
|
-
startedAt: null
|
|
160640
|
-
};
|
|
160641
|
-
}
|
|
160642
|
-
function dequeueNext(db, projectIdentity) {
|
|
160643
|
-
const now = Date.now();
|
|
160644
|
-
return db.transaction(() => {
|
|
160645
|
-
const entry = peekQueue(db, projectIdentity);
|
|
160646
|
-
if (!entry)
|
|
160647
|
-
return null;
|
|
160648
|
-
const result = db.prepare("UPDATE dream_queue SET started_at = ? WHERE id = ? AND started_at IS NULL").run(now, entry.id);
|
|
160649
|
-
if (result.changes === 0)
|
|
160650
|
-
return null;
|
|
160651
|
-
return { ...entry, startedAt: now };
|
|
160652
|
-
})();
|
|
160653
|
-
}
|
|
160654
|
-
function removeDreamEntry(db, id) {
|
|
160655
|
-
db.prepare("DELETE FROM dream_queue WHERE id = ?").run(id);
|
|
160656
|
-
}
|
|
160657
|
-
function resetDreamEntry(db, id) {
|
|
160658
|
-
db.prepare("UPDATE dream_queue SET started_at = NULL, retry_count = COALESCE(retry_count, 0) + 1 WHERE id = ?").run(id);
|
|
160659
|
-
}
|
|
160660
|
-
function getEntryRetryCount(db, id) {
|
|
160661
|
-
const row = db.prepare("SELECT retry_count FROM dream_queue WHERE id = ?").get(id);
|
|
160662
|
-
return row?.retry_count ?? 0;
|
|
160663
|
-
}
|
|
160664
|
-
function clearStaleEntries(db, maxAgeMs) {
|
|
160665
|
-
const cutoff = Date.now() - maxAgeMs;
|
|
160666
|
-
const result = db.prepare("DELETE FROM dream_queue WHERE started_at IS NOT NULL AND started_at < ?").run(cutoff);
|
|
160667
|
-
return result.changes;
|
|
160668
|
-
}
|
|
160669
|
-
|
|
160670
|
-
// src/commands/ctx-dream.ts
|
|
160671
|
-
init_logger();
|
|
160672
|
-
|
|
160673
160872
|
// ../plugin/src/features/magic-context/dreamer/storage-dream-state.ts
|
|
160674
160873
|
var getDreamStateStatements = new WeakMap;
|
|
160675
160874
|
var setDreamStateStatements = new WeakMap;
|
|
@@ -160765,15 +160964,137 @@ function releaseLease(db, holderId) {
|
|
|
160765
160964
|
deleteDreamState(db, LEASE_EXPIRY_KEY);
|
|
160766
160965
|
})();
|
|
160767
160966
|
}
|
|
160967
|
+
|
|
160968
|
+
// ../plugin/src/features/magic-context/dreamer/queue.ts
|
|
160969
|
+
function hasActiveDreamLease(db) {
|
|
160970
|
+
try {
|
|
160971
|
+
return isLeaseActive(db);
|
|
160972
|
+
} catch (error51) {
|
|
160973
|
+
if (String(error51).includes("no such table: dream_state")) {
|
|
160974
|
+
return false;
|
|
160975
|
+
}
|
|
160976
|
+
throw error51;
|
|
160977
|
+
}
|
|
160978
|
+
}
|
|
160979
|
+
function enqueueDream(db, projectIdentity, reason, force = false) {
|
|
160980
|
+
const now = Date.now();
|
|
160981
|
+
return db.transaction(() => {
|
|
160982
|
+
if (!hasActiveDreamLease(db)) {
|
|
160983
|
+
const staleThresholdMs = force ? 2 * 60 * 1000 : 120 * 60 * 1000;
|
|
160984
|
+
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run([projectIdentity, now - staleThresholdMs]);
|
|
160985
|
+
}
|
|
160986
|
+
const existing = db.prepare("SELECT id FROM dream_queue WHERE project_path = ?").get(projectIdentity);
|
|
160987
|
+
if (existing) {
|
|
160988
|
+
return null;
|
|
160989
|
+
}
|
|
160990
|
+
const result = db.prepare("INSERT INTO dream_queue (project_path, reason, enqueued_at) VALUES (?, ?, ?)").run(projectIdentity, reason, now);
|
|
160991
|
+
return {
|
|
160992
|
+
id: Number(result.lastInsertRowid),
|
|
160993
|
+
projectIdentity,
|
|
160994
|
+
reason,
|
|
160995
|
+
enqueuedAt: now,
|
|
160996
|
+
startedAt: null
|
|
160997
|
+
};
|
|
160998
|
+
})();
|
|
160999
|
+
}
|
|
161000
|
+
function peekQueue(db, projectIdentity) {
|
|
161001
|
+
const row = projectIdentity ? db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL AND project_path = ? ORDER BY enqueued_at ASC LIMIT 1").get(projectIdentity) : db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
|
|
161002
|
+
if (!row)
|
|
161003
|
+
return null;
|
|
161004
|
+
return {
|
|
161005
|
+
id: row.id,
|
|
161006
|
+
projectIdentity: row.project_path,
|
|
161007
|
+
reason: row.reason,
|
|
161008
|
+
enqueuedAt: row.enqueued_at,
|
|
161009
|
+
startedAt: null
|
|
161010
|
+
};
|
|
161011
|
+
}
|
|
161012
|
+
function dequeueNext(db, projectIdentity) {
|
|
161013
|
+
const now = Date.now();
|
|
161014
|
+
return db.transaction(() => {
|
|
161015
|
+
const entry = peekQueue(db, projectIdentity);
|
|
161016
|
+
if (!entry)
|
|
161017
|
+
return null;
|
|
161018
|
+
const result = db.prepare("UPDATE dream_queue SET started_at = ? WHERE id = ? AND started_at IS NULL").run(now, entry.id);
|
|
161019
|
+
if (result.changes === 0)
|
|
161020
|
+
return null;
|
|
161021
|
+
return { ...entry, startedAt: now };
|
|
161022
|
+
})();
|
|
161023
|
+
}
|
|
161024
|
+
function removeDreamEntry(db, id) {
|
|
161025
|
+
db.prepare("DELETE FROM dream_queue WHERE id = ?").run(id);
|
|
161026
|
+
}
|
|
161027
|
+
function resetDreamEntry(db, id) {
|
|
161028
|
+
db.prepare("UPDATE dream_queue SET started_at = NULL, retry_count = COALESCE(retry_count, 0) + 1 WHERE id = ?").run(id);
|
|
161029
|
+
}
|
|
161030
|
+
function getEntryRetryCount(db, id) {
|
|
161031
|
+
const row = db.prepare("SELECT retry_count FROM dream_queue WHERE id = ?").get(id);
|
|
161032
|
+
return row?.retry_count ?? 0;
|
|
161033
|
+
}
|
|
161034
|
+
function clearStaleEntries(db, maxAgeMs) {
|
|
161035
|
+
const cutoff = Date.now() - maxAgeMs;
|
|
161036
|
+
const result = db.prepare("DELETE FROM dream_queue WHERE started_at IS NOT NULL AND started_at < ?").run(cutoff);
|
|
161037
|
+
return result.changes;
|
|
161038
|
+
}
|
|
161039
|
+
|
|
161040
|
+
// src/commands/ctx-dream.ts
|
|
161041
|
+
init_logger();
|
|
160768
161042
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
160769
161043
|
import { existsSync as existsSync6 } from "node:fs";
|
|
160770
|
-
import { join as
|
|
161044
|
+
import { join as join8 } from "node:path";
|
|
160771
161045
|
|
|
160772
161046
|
// ../plugin/src/shared/index.ts
|
|
160773
161047
|
init_logger();
|
|
160774
161048
|
|
|
160775
161049
|
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
160776
161050
|
init_logger();
|
|
161051
|
+
|
|
161052
|
+
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
161053
|
+
function resolveFallbackChain(agentName, userFallbacks) {
|
|
161054
|
+
const userList = normalizeUserFallbacks(userFallbacks);
|
|
161055
|
+
if (userList.length > 0) {
|
|
161056
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
161057
|
+
}
|
|
161058
|
+
const builtin = getAgentFallbackModels(agentName);
|
|
161059
|
+
if (!builtin || builtin.length === 0)
|
|
161060
|
+
return [];
|
|
161061
|
+
return dedupe(builtin.filter(isValidModelSpec));
|
|
161062
|
+
}
|
|
161063
|
+
function normalizeUserFallbacks(userFallbacks) {
|
|
161064
|
+
if (!userFallbacks)
|
|
161065
|
+
return [];
|
|
161066
|
+
if (typeof userFallbacks === "string") {
|
|
161067
|
+
const trimmed = userFallbacks.trim();
|
|
161068
|
+
return trimmed ? [trimmed] : [];
|
|
161069
|
+
}
|
|
161070
|
+
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
161071
|
+
}
|
|
161072
|
+
function isValidModelSpec(spec) {
|
|
161073
|
+
const slash = spec.indexOf("/");
|
|
161074
|
+
return slash > 0 && slash < spec.length - 1;
|
|
161075
|
+
}
|
|
161076
|
+
function dedupe(list) {
|
|
161077
|
+
const seen = new Set;
|
|
161078
|
+
const out = [];
|
|
161079
|
+
for (const item of list) {
|
|
161080
|
+
if (seen.has(item))
|
|
161081
|
+
continue;
|
|
161082
|
+
seen.add(item);
|
|
161083
|
+
out.push(item);
|
|
161084
|
+
}
|
|
161085
|
+
return out;
|
|
161086
|
+
}
|
|
161087
|
+
function parseProviderModel(spec) {
|
|
161088
|
+
const slash = spec.indexOf("/");
|
|
161089
|
+
if (slash < 1 || slash >= spec.length - 1)
|
|
161090
|
+
return null;
|
|
161091
|
+
return {
|
|
161092
|
+
providerID: spec.slice(0, slash).trim(),
|
|
161093
|
+
modelID: spec.slice(slash + 1).trim()
|
|
161094
|
+
};
|
|
161095
|
+
}
|
|
161096
|
+
|
|
161097
|
+
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
160777
161098
|
function extractMessage(error51) {
|
|
160778
161099
|
if (typeof error51 === "string")
|
|
160779
161100
|
return error51;
|
|
@@ -160828,6 +161149,9 @@ function parseModelSuggestion(error51) {
|
|
|
160828
161149
|
};
|
|
160829
161150
|
}
|
|
160830
161151
|
async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
161152
|
+
if (signal?.aborted) {
|
|
161153
|
+
throw new Error("prompt aborted by external signal");
|
|
161154
|
+
}
|
|
160831
161155
|
const controller = new AbortController;
|
|
160832
161156
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
160833
161157
|
const onExternalAbort = () => controller.abort();
|
|
@@ -160850,16 +161174,39 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
160850
161174
|
signal?.removeEventListener("abort", onExternalAbort);
|
|
160851
161175
|
}
|
|
160852
161176
|
}
|
|
160853
|
-
|
|
160854
|
-
|
|
161177
|
+
function isNonRetryable(error51, externalSignal) {
|
|
161178
|
+
if (externalSignal?.aborted)
|
|
161179
|
+
return true;
|
|
161180
|
+
if (error51 instanceof Error) {
|
|
161181
|
+
if (error51.name === "AbortError")
|
|
161182
|
+
return true;
|
|
161183
|
+
if (error51.message === "prompt aborted by external signal")
|
|
161184
|
+
return true;
|
|
161185
|
+
if (/^prompt timed out after \d+ms$/.test(error51.message))
|
|
161186
|
+
return true;
|
|
161187
|
+
}
|
|
161188
|
+
if (detectOverflow(error51).isOverflow)
|
|
161189
|
+
return true;
|
|
161190
|
+
return false;
|
|
161191
|
+
}
|
|
161192
|
+
function shortErr(error51) {
|
|
161193
|
+
if (error51 instanceof Error) {
|
|
161194
|
+
return error51.name && error51.name !== "Error" ? `${error51.name}: ${error51.message}` : error51.message;
|
|
161195
|
+
}
|
|
161196
|
+
return extractMessage(error51);
|
|
161197
|
+
}
|
|
161198
|
+
async function attemptOnce(client, args, timeoutMs, signal, callContext, label) {
|
|
160855
161199
|
try {
|
|
160856
|
-
await promptWithTimeout(client, args, timeoutMs,
|
|
161200
|
+
await promptWithTimeout(client, args, timeoutMs, signal);
|
|
161201
|
+
return;
|
|
160857
161202
|
} catch (error51) {
|
|
161203
|
+
if (isNonRetryable(error51, signal))
|
|
161204
|
+
throw error51;
|
|
160858
161205
|
const suggestion = parseModelSuggestion(error51);
|
|
160859
161206
|
if (!suggestion || !args.body.model) {
|
|
160860
161207
|
throw error51;
|
|
160861
161208
|
}
|
|
160862
|
-
log(
|
|
161209
|
+
log(`[${callContext}] ${label}: model not found, retrying with suggestion`, {
|
|
160863
161210
|
original: `${suggestion.providerID}/${suggestion.modelID}`,
|
|
160864
161211
|
suggested: suggestion.suggestion
|
|
160865
161212
|
});
|
|
@@ -160872,9 +161219,55 @@ async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
|
160872
161219
|
modelID: suggestion.suggestion
|
|
160873
161220
|
}
|
|
160874
161221
|
}
|
|
160875
|
-
}, timeoutMs,
|
|
161222
|
+
}, timeoutMs, signal);
|
|
160876
161223
|
}
|
|
160877
161224
|
}
|
|
161225
|
+
async function promptSyncWithModelSuggestionRetry(client, args, options = {}) {
|
|
161226
|
+
const timeoutMs = options.timeoutMs ?? 300000;
|
|
161227
|
+
const callContext = options.callContext ?? "subagent";
|
|
161228
|
+
const fallbacks = options.fallbackModels ?? [];
|
|
161229
|
+
const explicitPrimaryLabel = args.body.model?.providerID && args.body.model.modelID ? `${args.body.model.providerID}/${args.body.model.modelID}` : "primary";
|
|
161230
|
+
let lastError = null;
|
|
161231
|
+
try {
|
|
161232
|
+
await attemptOnce(client, args, timeoutMs, options.signal, callContext, explicitPrimaryLabel);
|
|
161233
|
+
return;
|
|
161234
|
+
} catch (error51) {
|
|
161235
|
+
lastError = error51;
|
|
161236
|
+
if (isNonRetryable(error51, options.signal))
|
|
161237
|
+
throw error51;
|
|
161238
|
+
if (fallbacks.length === 0) {
|
|
161239
|
+
throw error51;
|
|
161240
|
+
}
|
|
161241
|
+
log(`[${callContext}] primary (${explicitPrimaryLabel}) failed: ${shortErr(error51)}; trying ${fallbacks.length} fallback(s)`);
|
|
161242
|
+
}
|
|
161243
|
+
for (let i = 0;i < fallbacks.length; i += 1) {
|
|
161244
|
+
const parsed = parseProviderModel(fallbacks[i]);
|
|
161245
|
+
if (!parsed) {
|
|
161246
|
+
log(`[${callContext}] skipping invalid fallback spec: ${fallbacks[i]}`);
|
|
161247
|
+
continue;
|
|
161248
|
+
}
|
|
161249
|
+
const label = `${parsed.providerID}/${parsed.modelID}`;
|
|
161250
|
+
const attemptArgs = {
|
|
161251
|
+
...args,
|
|
161252
|
+
body: { ...args.body, model: parsed }
|
|
161253
|
+
};
|
|
161254
|
+
try {
|
|
161255
|
+
await attemptOnce(client, attemptArgs, timeoutMs, options.signal, callContext, label);
|
|
161256
|
+
log(`[${callContext}] fallback succeeded with ${label} (attempt ${i + 2}/${fallbacks.length + 1})`);
|
|
161257
|
+
return;
|
|
161258
|
+
} catch (error51) {
|
|
161259
|
+
lastError = error51;
|
|
161260
|
+
if (isNonRetryable(error51, options.signal))
|
|
161261
|
+
throw error51;
|
|
161262
|
+
const remaining = fallbacks.length - i - 1;
|
|
161263
|
+
if (remaining > 0) {
|
|
161264
|
+
log(`[${callContext}] ${label} failed: ${shortErr(error51)}; ${remaining} fallback(s) left`);
|
|
161265
|
+
}
|
|
161266
|
+
}
|
|
161267
|
+
}
|
|
161268
|
+
log(`[${callContext}] all models exhausted; tried: ${[explicitPrimaryLabel, ...fallbacks].join(", ")}; last error: ${shortErr(lastError)}`);
|
|
161269
|
+
throw lastError ?? new Error("All fallback models failed");
|
|
161270
|
+
}
|
|
160878
161271
|
// ../plugin/src/shared/normalize-sdk-response.ts
|
|
160879
161272
|
function normalizeSDKResponse(response, fallback, options) {
|
|
160880
161273
|
if (response === null || response === undefined) {
|
|
@@ -162052,7 +162445,12 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
162052
162445
|
system: DREAMER_SYSTEM_PROMPT,
|
|
162053
162446
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
162054
162447
|
}
|
|
162055
|
-
}, {
|
|
162448
|
+
}, {
|
|
162449
|
+
timeoutMs: Math.min(remainingMs, 5 * 60 * 1000),
|
|
162450
|
+
signal: abortController.signal,
|
|
162451
|
+
fallbackModels: args.fallbackModels,
|
|
162452
|
+
callContext: "dreamer:user-memories"
|
|
162453
|
+
});
|
|
162056
162454
|
const messagesResponse = await args.client.session.messages({
|
|
162057
162455
|
path: { id: agentSessionId },
|
|
162058
162456
|
query: { directory: args.sessionDirectory }
|
|
@@ -162111,7 +162509,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
162111
162509
|
}
|
|
162112
162510
|
return result;
|
|
162113
162511
|
} catch (error51) {
|
|
162114
|
-
|
|
162512
|
+
const errorDescription = describeError(error51);
|
|
162513
|
+
log(`[dreamer] user-memories: review failed: ${errorDescription.brief}`, errorDescription.stackHead ? { stackHead: errorDescription.stackHead } : undefined);
|
|
162115
162514
|
return result;
|
|
162116
162515
|
} finally {
|
|
162117
162516
|
clearInterval(leaseInterval);
|
|
@@ -162143,6 +162542,7 @@ function insertDreamRun(db, run) {
|
|
|
162143
162542
|
|
|
162144
162543
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
162145
162544
|
var dreamProjectDirectories = new Map;
|
|
162545
|
+
var CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
162146
162546
|
function registerDreamProjectDirectory(projectIdentity, directory) {
|
|
162147
162547
|
dreamProjectDirectories.set(projectIdentity, directory);
|
|
162148
162548
|
}
|
|
@@ -162159,8 +162559,27 @@ function countNewIds(beforeIds, afterIds) {
|
|
|
162159
162559
|
}
|
|
162160
162560
|
return count;
|
|
162161
162561
|
}
|
|
162562
|
+
function getCircuitBreakerSignature(error51, brief) {
|
|
162563
|
+
if (error51 instanceof Error && error51.name && error51.name !== "Error") {
|
|
162564
|
+
return error51.name;
|
|
162565
|
+
}
|
|
162566
|
+
const namedError = error51;
|
|
162567
|
+
if (namedError && typeof namedError === "object" && typeof namedError.name === "string" && namedError.name.length > 0 && namedError.name !== "Error") {
|
|
162568
|
+
return namedError.name;
|
|
162569
|
+
}
|
|
162570
|
+
return brief.split(":")[0]?.trim().split(/\s+/)[0] || brief || "unknown";
|
|
162571
|
+
}
|
|
162572
|
+
function shouldSkipCircuitBreaker(error51, brief) {
|
|
162573
|
+
const namedError = error51;
|
|
162574
|
+
const name2 = error51 instanceof Error ? error51.name : namedError && typeof namedError === "object" && typeof namedError.name === "string" ? namedError.name : "";
|
|
162575
|
+
const combined = `${name2} ${brief}`.toLowerCase();
|
|
162576
|
+
return name2 === "AbortError" || combined.includes("lease");
|
|
162577
|
+
}
|
|
162578
|
+
function logWithStackHead(message, stackHead) {
|
|
162579
|
+
log(message, stackHead ? { stackHead } : undefined);
|
|
162580
|
+
}
|
|
162162
162581
|
function getOpenCodeDbPath2() {
|
|
162163
|
-
return
|
|
162582
|
+
return join8(getDataDir(), "opencode", "opencode.db");
|
|
162164
162583
|
}
|
|
162165
162584
|
function openOpenCodeDb() {
|
|
162166
162585
|
const dbPath = getOpenCodeDbPath2();
|
|
@@ -162235,9 +162654,11 @@ async function identifyKeyFilesForSession(args) {
|
|
|
162235
162654
|
try {
|
|
162236
162655
|
if (!renewLease(args.db, args.holderId)) {
|
|
162237
162656
|
log(`[key-files][${args.sessionId}] lease renewal failed — aborting`);
|
|
162657
|
+
args.onLeaseLost?.(`key-files:${args.sessionId}`);
|
|
162238
162658
|
abortController.abort();
|
|
162239
162659
|
}
|
|
162240
|
-
} catch {
|
|
162660
|
+
} catch (error51) {
|
|
162661
|
+
args.onLeaseLost?.(`key-files:${args.sessionId}`, error51);
|
|
162241
162662
|
abortController.abort();
|
|
162242
162663
|
}
|
|
162243
162664
|
}, 60000);
|
|
@@ -162264,7 +162685,12 @@ async function identifyKeyFilesForSession(args) {
|
|
|
162264
162685
|
system: KEY_FILES_SYSTEM_PROMPT,
|
|
162265
162686
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
162266
162687
|
}
|
|
162267
|
-
}, {
|
|
162688
|
+
}, {
|
|
162689
|
+
timeoutMs: Math.min(remainingMs, 300000),
|
|
162690
|
+
signal: abortController.signal,
|
|
162691
|
+
fallbackModels: args.fallbackModels,
|
|
162692
|
+
callContext: `dreamer:key-files:${args.sessionId.slice(0, 12)}`
|
|
162693
|
+
});
|
|
162268
162694
|
const messagesResponse = await args.client.session.messages({
|
|
162269
162695
|
path: { id: agentSessionId },
|
|
162270
162696
|
query: { directory: args.sessionDirectory }
|
|
@@ -162287,6 +162713,10 @@ async function identifyKeyFilesForSession(args) {
|
|
|
162287
162713
|
log(`[key-files][${args.sessionId}] could not parse agent output — using heuristic fallback`);
|
|
162288
162714
|
applyHeuristicFallback();
|
|
162289
162715
|
} catch (error51) {
|
|
162716
|
+
if (args.isLeaseLost?.() || abortController.signal.aborted) {
|
|
162717
|
+
log(`[key-files][${args.sessionId}] lease lost during identification — skipping heuristic fallback`);
|
|
162718
|
+
throw error51;
|
|
162719
|
+
}
|
|
162290
162720
|
log(`[key-files][${args.sessionId}] identification failed: ${getErrorMessage(error51)} — using heuristic fallback`);
|
|
162291
162721
|
try {
|
|
162292
162722
|
applyHeuristicFallback();
|
|
@@ -162327,6 +162757,10 @@ async function identifyKeyFiles(args) {
|
|
|
162327
162757
|
}
|
|
162328
162758
|
log(`[key-files] evaluating ${sessionIds.length} active session(s) for ${args.projectIdentity}`);
|
|
162329
162759
|
for (const sessionId of sessionIds) {
|
|
162760
|
+
if (args.isLeaseLost?.()) {
|
|
162761
|
+
log("[key-files] lease lost — stopping key-file identification");
|
|
162762
|
+
break;
|
|
162763
|
+
}
|
|
162330
162764
|
if (Date.now() > args.deadline) {
|
|
162331
162765
|
log("[key-files] deadline reached — stopping key-file identification");
|
|
162332
162766
|
break;
|
|
@@ -162337,6 +162771,9 @@ async function identifyKeyFiles(args) {
|
|
|
162337
162771
|
parentSessionId: args.parentSessionId,
|
|
162338
162772
|
sessionDirectory: args.sessionDirectory,
|
|
162339
162773
|
holderId: args.holderId,
|
|
162774
|
+
fallbackModels: args.fallbackModels,
|
|
162775
|
+
onLeaseLost: args.onLeaseLost,
|
|
162776
|
+
isLeaseLost: args.isLeaseLost,
|
|
162340
162777
|
deadline: args.deadline,
|
|
162341
162778
|
sessionId,
|
|
162342
162779
|
config: args.config
|
|
@@ -162390,8 +162827,53 @@ async function runDream(args) {
|
|
|
162390
162827
|
const deadline = startedAt + args.maxRuntimeMinutes * 60 * 1000;
|
|
162391
162828
|
const lastDreamAt = getDreamState(args.db, `last_dream_at:${args.projectIdentity}`) ?? getDreamState(args.db, "last_dream_at");
|
|
162392
162829
|
log(`[dreamer] last dream at: ${lastDreamAt ?? "never"} (project=${args.projectIdentity})`);
|
|
162830
|
+
let lastErrorSignature = null;
|
|
162831
|
+
let consecutiveSameErrorFailures = 0;
|
|
162832
|
+
let circuitBreakerTripped = false;
|
|
162833
|
+
let lostLease = false;
|
|
162834
|
+
let lostLeaseReason = null;
|
|
162835
|
+
let lostLeaseRecorded = false;
|
|
162836
|
+
const markLeaseLost = (phase, error51) => {
|
|
162837
|
+
const detail = error51 ? `: ${getErrorMessage(error51)}` : "";
|
|
162838
|
+
lostLeaseReason = `Dream lease lost during ${phase}${detail}`;
|
|
162839
|
+
if (!lostLease) {
|
|
162840
|
+
log(`[dreamer] FATAL: ${lostLeaseReason}; aborting all remaining dream work`);
|
|
162841
|
+
} else {
|
|
162842
|
+
log(`[dreamer] FATAL: ${lostLeaseReason}; dream work is already aborting`);
|
|
162843
|
+
}
|
|
162844
|
+
lostLease = true;
|
|
162845
|
+
};
|
|
162846
|
+
const recordLeaseLostTask = (phase) => {
|
|
162847
|
+
if (lostLeaseRecorded)
|
|
162848
|
+
return;
|
|
162849
|
+
lostLeaseRecorded = true;
|
|
162850
|
+
result.tasks.push({
|
|
162851
|
+
name: "lease-lost",
|
|
162852
|
+
durationMs: 0,
|
|
162853
|
+
result: "",
|
|
162854
|
+
error: lostLeaseReason ?? `Dream lease lost during ${phase}; aborted remaining work`
|
|
162855
|
+
});
|
|
162856
|
+
};
|
|
162857
|
+
const verifyLeaseStillHeld = (phase) => {
|
|
162858
|
+
if (lostLease)
|
|
162859
|
+
return false;
|
|
162860
|
+
try {
|
|
162861
|
+
if (!renewLease(args.db, holderId)) {
|
|
162862
|
+
markLeaseLost(phase);
|
|
162863
|
+
return false;
|
|
162864
|
+
}
|
|
162865
|
+
return true;
|
|
162866
|
+
} catch (error51) {
|
|
162867
|
+
markLeaseLost(phase, error51);
|
|
162868
|
+
return false;
|
|
162869
|
+
}
|
|
162870
|
+
};
|
|
162393
162871
|
try {
|
|
162394
162872
|
for (const taskName of args.tasks) {
|
|
162873
|
+
if (!verifyLeaseStillHeld(`before task ${taskName}`)) {
|
|
162874
|
+
recordLeaseLostTask(`before task ${taskName}`);
|
|
162875
|
+
break;
|
|
162876
|
+
}
|
|
162395
162877
|
if (Date.now() > deadline) {
|
|
162396
162878
|
log(`[dreamer] deadline reached, stopping after ${result.tasks.length} tasks`);
|
|
162397
162879
|
break;
|
|
@@ -162404,18 +162886,20 @@ async function runDream(args) {
|
|
|
162404
162886
|
try {
|
|
162405
162887
|
if (!renewLease(args.db, holderId)) {
|
|
162406
162888
|
log(`[dreamer] task ${taskName}: lease renewal failed — aborting LLM call`);
|
|
162889
|
+
markLeaseLost(`task ${taskName} lease renewal`);
|
|
162407
162890
|
taskAbortController.abort();
|
|
162408
162891
|
}
|
|
162409
162892
|
} catch (err) {
|
|
162410
162893
|
log(`[dreamer] task ${taskName}: lease renewal threw — aborting LLM call: ${err}`);
|
|
162894
|
+
markLeaseLost(`task ${taskName} lease renewal`, err);
|
|
162411
162895
|
taskAbortController.abort();
|
|
162412
162896
|
}
|
|
162413
162897
|
}, 60000);
|
|
162414
162898
|
try {
|
|
162415
162899
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
162416
162900
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
162417
|
-
architecture: existsSync6(
|
|
162418
|
-
structure: existsSync6(
|
|
162901
|
+
architecture: existsSync6(join8(docsDir, "ARCHITECTURE.md")),
|
|
162902
|
+
structure: existsSync6(join8(docsDir, "STRUCTURE.md"))
|
|
162419
162903
|
} : undefined;
|
|
162420
162904
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
162421
162905
|
id: um.id,
|
|
@@ -162450,8 +162934,13 @@ async function runDream(args) {
|
|
|
162450
162934
|
}
|
|
162451
162935
|
}, {
|
|
162452
162936
|
timeoutMs: args.taskTimeoutMinutes * 60 * 1000,
|
|
162453
|
-
signal: taskAbortController.signal
|
|
162937
|
+
signal: taskAbortController.signal,
|
|
162938
|
+
fallbackModels: args.fallbackModels,
|
|
162939
|
+
callContext: `dreamer:${taskName}`
|
|
162454
162940
|
});
|
|
162941
|
+
if (lostLease) {
|
|
162942
|
+
throw new Error(lostLeaseReason ?? `Dream lease lost during ${taskName}`);
|
|
162943
|
+
}
|
|
162455
162944
|
const messagesResponse = await args.client.session.messages({
|
|
162456
162945
|
path: { id: agentSessionId },
|
|
162457
162946
|
query: { directory: args.sessionDirectory ?? args.projectIdentity }
|
|
@@ -162470,16 +162959,43 @@ async function runDream(args) {
|
|
|
162470
162959
|
durationMs,
|
|
162471
162960
|
result: taskResult
|
|
162472
162961
|
});
|
|
162962
|
+
lastErrorSignature = null;
|
|
162963
|
+
consecutiveSameErrorFailures = 0;
|
|
162473
162964
|
} catch (error51) {
|
|
162474
162965
|
const durationMs = Date.now() - taskStartedAt;
|
|
162475
|
-
const
|
|
162476
|
-
|
|
162966
|
+
const errorDescription = describeError(error51);
|
|
162967
|
+
logWithStackHead(`[dreamer] task ${taskName}: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162477
162968
|
result.tasks.push({
|
|
162478
162969
|
name: taskName,
|
|
162479
162970
|
durationMs,
|
|
162480
162971
|
result: null,
|
|
162481
|
-
error:
|
|
162972
|
+
error: errorDescription.brief
|
|
162482
162973
|
});
|
|
162974
|
+
if (lostLease) {
|
|
162975
|
+
lastErrorSignature = null;
|
|
162976
|
+
consecutiveSameErrorFailures = 0;
|
|
162977
|
+
} else if (shouldSkipCircuitBreaker(error51, errorDescription.brief)) {
|
|
162978
|
+
lastErrorSignature = null;
|
|
162979
|
+
consecutiveSameErrorFailures = 0;
|
|
162980
|
+
} else {
|
|
162981
|
+
const signature = getCircuitBreakerSignature(error51, errorDescription.brief);
|
|
162982
|
+
if (signature === lastErrorSignature) {
|
|
162983
|
+
consecutiveSameErrorFailures += 1;
|
|
162984
|
+
} else {
|
|
162985
|
+
lastErrorSignature = signature;
|
|
162986
|
+
consecutiveSameErrorFailures = 1;
|
|
162987
|
+
}
|
|
162988
|
+
if (consecutiveSameErrorFailures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
162989
|
+
circuitBreakerTripped = true;
|
|
162990
|
+
log(`[dreamer] circuit breaker: ${consecutiveSameErrorFailures} consecutive ${signature} failures — aborting remaining tasks`);
|
|
162991
|
+
result.tasks.push({
|
|
162992
|
+
name: "circuit-breaker",
|
|
162993
|
+
durationMs: 0,
|
|
162994
|
+
result: "",
|
|
162995
|
+
error: `Aborted remaining tasks: ${consecutiveSameErrorFailures} consecutive ${signature} failures. Configure dreamer model/fallback_models in magic-context.jsonc.`
|
|
162996
|
+
});
|
|
162997
|
+
}
|
|
162998
|
+
}
|
|
162483
162999
|
} finally {
|
|
162484
163000
|
clearInterval(leaseRenewalInterval);
|
|
162485
163001
|
if (agentSessionId) {
|
|
@@ -162491,10 +163007,32 @@ async function runDream(args) {
|
|
|
162491
163007
|
});
|
|
162492
163008
|
}
|
|
162493
163009
|
}
|
|
163010
|
+
if (lostLease) {
|
|
163011
|
+
recordLeaseLostTask(`task ${taskName}`);
|
|
163012
|
+
break;
|
|
163013
|
+
}
|
|
163014
|
+
if (circuitBreakerTripped) {
|
|
163015
|
+
break;
|
|
163016
|
+
}
|
|
163017
|
+
}
|
|
163018
|
+
if (lostLease) {
|
|
163019
|
+
log("[dreamer] lease lost: skipping all post-task phases");
|
|
163020
|
+
recordLeaseLostTask("post-task phases");
|
|
163021
|
+
} else if (circuitBreakerTripped) {
|
|
163022
|
+
log("[dreamer] circuit breaker: skipping post-task phases");
|
|
163023
|
+
result.tasks.push({
|
|
163024
|
+
name: "post-task-phases",
|
|
163025
|
+
durationMs: 0,
|
|
163026
|
+
result: "",
|
|
163027
|
+
error: "Skipped post-task phases after circuit breaker tripped; configure dreamer model/fallback_models in magic-context.jsonc."
|
|
163028
|
+
});
|
|
162494
163029
|
}
|
|
162495
|
-
if (args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
163030
|
+
if (!circuitBreakerTripped && !lostLease && args.experimentalUserMemories?.enabled && Date.now() <= deadline) {
|
|
162496
163031
|
const umStart = Date.now();
|
|
162497
163032
|
try {
|
|
163033
|
+
if (!verifyLeaseStillHeld("before user-memory review")) {
|
|
163034
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost before user-memory review");
|
|
163035
|
+
}
|
|
162498
163036
|
const reviewResult = await reviewUserMemories({
|
|
162499
163037
|
db: args.db,
|
|
162500
163038
|
client: args.client,
|
|
@@ -162502,8 +163040,12 @@ async function runDream(args) {
|
|
|
162502
163040
|
sessionDirectory: args.sessionDirectory,
|
|
162503
163041
|
holderId,
|
|
162504
163042
|
deadline,
|
|
162505
|
-
promotionThreshold: args.experimentalUserMemories.promotionThreshold
|
|
163043
|
+
promotionThreshold: args.experimentalUserMemories.promotionThreshold,
|
|
163044
|
+
fallbackModels: args.fallbackModels
|
|
162506
163045
|
});
|
|
163046
|
+
if (!verifyLeaseStillHeld("after user-memory review")) {
|
|
163047
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost after user-memory review");
|
|
163048
|
+
}
|
|
162507
163049
|
const umOutput = `promoted=${reviewResult.promoted} merged=${reviewResult.merged} dismissed=${reviewResult.dismissed} consumed=${reviewResult.candidatesConsumed}`;
|
|
162508
163050
|
if (reviewResult.promoted > 0 || reviewResult.merged > 0 || reviewResult.dismissed > 0) {
|
|
162509
163051
|
log(`[dreamer] user-memories: ${umOutput}`);
|
|
@@ -162514,17 +163056,23 @@ async function runDream(args) {
|
|
|
162514
163056
|
result: umOutput
|
|
162515
163057
|
});
|
|
162516
163058
|
} catch (error51) {
|
|
162517
|
-
|
|
163059
|
+
const errorDescription = describeError(error51);
|
|
163060
|
+
logWithStackHead(`[dreamer] user-memory review failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162518
163061
|
result.tasks.push({
|
|
162519
163062
|
name: "user memories",
|
|
162520
163063
|
durationMs: Date.now() - umStart,
|
|
162521
163064
|
result: "",
|
|
162522
|
-
error:
|
|
163065
|
+
error: errorDescription.brief
|
|
162523
163066
|
});
|
|
162524
163067
|
}
|
|
163068
|
+
if (lostLease)
|
|
163069
|
+
recordLeaseLostTask("user-memory review");
|
|
162525
163070
|
}
|
|
162526
|
-
if (Date.now() <= deadline) {
|
|
163071
|
+
if (!circuitBreakerTripped && !lostLease && Date.now() <= deadline) {
|
|
162527
163072
|
try {
|
|
163073
|
+
if (!verifyLeaseStillHeld("before smart-note evaluation")) {
|
|
163074
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost before smart-note evaluation");
|
|
163075
|
+
}
|
|
162528
163076
|
await evaluateSmartNotes({
|
|
162529
163077
|
db: args.db,
|
|
162530
163078
|
client: args.client,
|
|
@@ -162533,15 +163081,27 @@ async function runDream(args) {
|
|
|
162533
163081
|
sessionDirectory: args.sessionDirectory,
|
|
162534
163082
|
holderId,
|
|
162535
163083
|
deadline,
|
|
162536
|
-
result
|
|
163084
|
+
result,
|
|
163085
|
+
fallbackModels: args.fallbackModels,
|
|
163086
|
+
onLeaseLost: markLeaseLost,
|
|
163087
|
+
isLeaseLost: () => lostLease
|
|
162537
163088
|
});
|
|
163089
|
+
if (!verifyLeaseStillHeld("after smart-note evaluation")) {
|
|
163090
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost after smart-note evaluation");
|
|
163091
|
+
}
|
|
162538
163092
|
} catch (error51) {
|
|
162539
|
-
|
|
163093
|
+
const errorDescription = describeError(error51);
|
|
163094
|
+
logWithStackHead(`[dreamer] smart note evaluation failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162540
163095
|
}
|
|
163096
|
+
if (lostLease)
|
|
163097
|
+
recordLeaseLostTask("smart-note evaluation");
|
|
162541
163098
|
}
|
|
162542
|
-
if (args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
163099
|
+
if (!circuitBreakerTripped && !lostLease && args.experimentalPinKeyFiles?.enabled && Date.now() <= deadline) {
|
|
162543
163100
|
const kfStart = Date.now();
|
|
162544
163101
|
try {
|
|
163102
|
+
if (!verifyLeaseStillHeld("before key-file identification")) {
|
|
163103
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost before key-file identification");
|
|
163104
|
+
}
|
|
162545
163105
|
await identifyKeyFiles({
|
|
162546
163106
|
db: args.db,
|
|
162547
163107
|
client: args.client,
|
|
@@ -162550,22 +163110,31 @@ async function runDream(args) {
|
|
|
162550
163110
|
sessionDirectory: args.sessionDirectory ?? args.projectIdentity,
|
|
162551
163111
|
holderId,
|
|
162552
163112
|
deadline,
|
|
162553
|
-
config: args.experimentalPinKeyFiles
|
|
163113
|
+
config: args.experimentalPinKeyFiles,
|
|
163114
|
+
fallbackModels: args.fallbackModels,
|
|
163115
|
+
onLeaseLost: markLeaseLost,
|
|
163116
|
+
isLeaseLost: () => lostLease
|
|
162554
163117
|
});
|
|
163118
|
+
if (!verifyLeaseStillHeld("after key-file identification")) {
|
|
163119
|
+
throw new Error(lostLeaseReason ?? "Dream lease lost after key-file identification");
|
|
163120
|
+
}
|
|
162555
163121
|
result.tasks.push({
|
|
162556
163122
|
name: "key files",
|
|
162557
163123
|
durationMs: Date.now() - kfStart,
|
|
162558
163124
|
result: "completed"
|
|
162559
163125
|
});
|
|
162560
163126
|
} catch (error51) {
|
|
162561
|
-
|
|
163127
|
+
const errorDescription = describeError(error51);
|
|
163128
|
+
logWithStackHead(`[key-files] identification phase failed: ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162562
163129
|
result.tasks.push({
|
|
162563
163130
|
name: "key files",
|
|
162564
163131
|
durationMs: Date.now() - kfStart,
|
|
162565
163132
|
result: "",
|
|
162566
|
-
error:
|
|
163133
|
+
error: errorDescription.brief
|
|
162567
163134
|
});
|
|
162568
163135
|
}
|
|
163136
|
+
if (lostLease)
|
|
163137
|
+
recordLeaseLostTask("key-file identification");
|
|
162569
163138
|
}
|
|
162570
163139
|
} finally {
|
|
162571
163140
|
releaseLease(args.db, holderId);
|
|
@@ -162598,9 +163167,15 @@ async function runDream(args) {
|
|
|
162598
163167
|
smartNotesPending: result.smartNotesPending,
|
|
162599
163168
|
memoryChanges: persistedMemoryChanges
|
|
162600
163169
|
});
|
|
162601
|
-
const POST_TASK_NAMES = new Set([
|
|
163170
|
+
const POST_TASK_NAMES = new Set([
|
|
163171
|
+
"smart-notes",
|
|
163172
|
+
"user memories",
|
|
163173
|
+
"key files",
|
|
163174
|
+
"post-task-phases",
|
|
163175
|
+
"circuit-breaker"
|
|
163176
|
+
]);
|
|
162602
163177
|
const hasSuccessfulTask = result.tasks.some((t) => !t.error && !POST_TASK_NAMES.has(t.name));
|
|
162603
|
-
if (hasSuccessfulTask) {
|
|
163178
|
+
if (hasSuccessfulTask && !lostLease) {
|
|
162604
163179
|
setDreamState(args.db, `last_dream_at:${args.projectIdentity}`, String(result.finishedAt));
|
|
162605
163180
|
setDreamState(args.db, "last_dream_at", String(result.finishedAt));
|
|
162606
163181
|
}
|
|
@@ -162649,9 +163224,11 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162649
163224
|
try {
|
|
162650
163225
|
if (!renewLease(args.db, args.holderId)) {
|
|
162651
163226
|
log("[dreamer] smart notes: lease renewal failed — aborting");
|
|
163227
|
+
args.onLeaseLost?.("smart notes");
|
|
162652
163228
|
abortController.abort();
|
|
162653
163229
|
}
|
|
162654
|
-
} catch {
|
|
163230
|
+
} catch (error51) {
|
|
163231
|
+
args.onLeaseLost?.("smart notes", error51);
|
|
162655
163232
|
abortController.abort();
|
|
162656
163233
|
}
|
|
162657
163234
|
}, 60000);
|
|
@@ -162677,7 +163254,12 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162677
163254
|
system: DREAMER_SYSTEM_PROMPT,
|
|
162678
163255
|
parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
|
|
162679
163256
|
}
|
|
162680
|
-
}, {
|
|
163257
|
+
}, {
|
|
163258
|
+
timeoutMs: Math.min(remainingMs, 300000),
|
|
163259
|
+
signal: abortController.signal,
|
|
163260
|
+
fallbackModels: args.fallbackModels,
|
|
163261
|
+
callContext: "dreamer:smart-notes"
|
|
163262
|
+
});
|
|
162681
163263
|
const messagesResponse = await args.client.session.messages({
|
|
162682
163264
|
path: { id: agentSessionId },
|
|
162683
163265
|
query: { directory: args.sessionDirectory ?? args.projectIdentity }
|
|
@@ -162736,15 +163318,15 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
|
|
|
162736
163318
|
});
|
|
162737
163319
|
} catch (error51) {
|
|
162738
163320
|
const durationMs = Date.now() - taskStartedAt;
|
|
162739
|
-
const
|
|
163321
|
+
const errorDescription = describeError(error51);
|
|
162740
163322
|
args.result.smartNotesSurfaced = 0;
|
|
162741
163323
|
args.result.smartNotesPending = pendingNotes.length;
|
|
162742
|
-
|
|
163324
|
+
logWithStackHead(`[dreamer] smart notes: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
162743
163325
|
args.result.tasks.push({
|
|
162744
163326
|
name: "smart-notes",
|
|
162745
163327
|
durationMs,
|
|
162746
163328
|
result: null,
|
|
162747
|
-
error:
|
|
163329
|
+
error: errorDescription.brief
|
|
162748
163330
|
});
|
|
162749
163331
|
} finally {
|
|
162750
163332
|
clearInterval(leaseInterval);
|
|
@@ -162777,7 +163359,8 @@ async function processDreamQueue(args) {
|
|
|
162777
163359
|
maxRuntimeMinutes: args.maxRuntimeMinutes,
|
|
162778
163360
|
sessionDirectory: projectDirectory,
|
|
162779
163361
|
experimentalUserMemories: args.experimentalUserMemories,
|
|
162780
|
-
experimentalPinKeyFiles: args.experimentalPinKeyFiles
|
|
163362
|
+
experimentalPinKeyFiles: args.experimentalPinKeyFiles,
|
|
163363
|
+
fallbackModels: args.fallbackModels
|
|
162781
163364
|
});
|
|
162782
163365
|
} catch (error51) {
|
|
162783
163366
|
log(`[dreamer] runDream threw for ${entry.projectIdentity}: ${getErrorMessage(error51)}`);
|
|
@@ -163501,7 +164084,8 @@ async function sweepProject(reg, origin) {
|
|
|
163501
164084
|
maxRuntimeMinutes: reg.dreamerConfig.max_runtime_minutes,
|
|
163502
164085
|
experimentalUserMemories: reg.experimentalUserMemories,
|
|
163503
164086
|
experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
|
|
163504
|
-
projectIdentity: registrationIdentity
|
|
164087
|
+
projectIdentity: registrationIdentity,
|
|
164088
|
+
fallbackModels: resolveFallbackChain(DREAMER_AGENT, reg.dreamerConfig.fallback_models)
|
|
163505
164089
|
});
|
|
163506
164090
|
} catch (error51) {
|
|
163507
164091
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.directory}:`, error51);
|
|
@@ -163923,7 +164507,6 @@ function createScheduler(config2) {
|
|
|
163923
164507
|
}
|
|
163924
164508
|
};
|
|
163925
164509
|
}
|
|
163926
|
-
|
|
163927
164510
|
// ../plugin/src/features/magic-context/tagger.ts
|
|
163928
164511
|
var TOOL_COMPOSITE_KEY_SEP = "\x00";
|
|
163929
164512
|
function makeToolCompositeKey(ownerMsgId, callId) {
|
|
@@ -164962,16 +165545,24 @@ function trimMemoriesToBudget(sessionId, memories, budgetTokens) {
|
|
|
164962
165545
|
function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectPath, injectionBudgetTokens, temporalAwareness) {
|
|
164963
165546
|
const cached2 = injectionCache.get(sessionId);
|
|
164964
165547
|
if (!isCacheBusting && cached2) {
|
|
164965
|
-
if (cached2.
|
|
164966
|
-
|
|
164967
|
-
|
|
164968
|
-
|
|
164969
|
-
|
|
164970
|
-
|
|
164971
|
-
|
|
165548
|
+
if (cached2.kind === "empty") {
|
|
165549
|
+
return null;
|
|
165550
|
+
}
|
|
165551
|
+
const prepared = cached2.injection;
|
|
165552
|
+
if (prepared.compartmentEndMessageId === null) {
|
|
165553
|
+
sessionLog(sessionId, "compartment injection cache in degraded mode (null boundary), forcing rebuild");
|
|
165554
|
+
} else {
|
|
165555
|
+
if (prepared.compartmentEndMessageId.length > 0) {
|
|
165556
|
+
const cutoffIndex2 = messages.findIndex((message) => message.info.id === prepared.compartmentEndMessageId);
|
|
165557
|
+
if (cutoffIndex2 >= 0) {
|
|
165558
|
+
const remaining = messages.slice(cutoffIndex2 + 1);
|
|
165559
|
+
messages.splice(0, messages.length, ...remaining);
|
|
165560
|
+
} else {
|
|
165561
|
+
sessionLog(sessionId, `compartment injection: cached boundary ${prepared.compartmentEndMessageId} not in messages (already trimmed), reusing cache`);
|
|
165562
|
+
}
|
|
164972
165563
|
}
|
|
165564
|
+
return { ...prepared, rebuiltFromDb: false };
|
|
164973
165565
|
}
|
|
164974
|
-
return cached2;
|
|
164975
165566
|
}
|
|
164976
165567
|
const compartments = getCompartments(db, sessionId);
|
|
164977
165568
|
const facts = getSessionFacts(db, sessionId);
|
|
@@ -165003,7 +165594,11 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165003
165594
|
}
|
|
165004
165595
|
}
|
|
165005
165596
|
if (compartments.length === 0 && facts.length === 0 && !memoryBlock) {
|
|
165006
|
-
injectionCache.
|
|
165597
|
+
injectionCache.set(sessionId, {
|
|
165598
|
+
kind: "empty",
|
|
165599
|
+
compartmentEndMessageId: "",
|
|
165600
|
+
renderedBytes: 0
|
|
165601
|
+
});
|
|
165007
165602
|
return null;
|
|
165008
165603
|
}
|
|
165009
165604
|
let dateRanges;
|
|
@@ -165036,9 +165631,10 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165036
165631
|
compartmentCount: 0,
|
|
165037
165632
|
skippedVisibleMessages: 0,
|
|
165038
165633
|
factCount: facts.length,
|
|
165039
|
-
memoryCount
|
|
165634
|
+
memoryCount,
|
|
165635
|
+
rebuiltFromDb: true
|
|
165040
165636
|
};
|
|
165041
|
-
injectionCache.set(sessionId, result2);
|
|
165637
|
+
injectionCache.set(sessionId, { kind: "populated", injection: result2 });
|
|
165042
165638
|
return result2;
|
|
165043
165639
|
}
|
|
165044
165640
|
const lastCompartment = compartments[compartments.length - 1];
|
|
@@ -165056,9 +165652,10 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165056
165652
|
compartmentCount: compartments.length,
|
|
165057
165653
|
skippedVisibleMessages: 0,
|
|
165058
165654
|
factCount: facts.length,
|
|
165059
|
-
memoryCount
|
|
165655
|
+
memoryCount,
|
|
165656
|
+
rebuiltFromDb: true
|
|
165060
165657
|
};
|
|
165061
|
-
injectionCache.set(sessionId, result2);
|
|
165658
|
+
injectionCache.set(sessionId, { kind: "populated", injection: result2 });
|
|
165062
165659
|
return result2;
|
|
165063
165660
|
}
|
|
165064
165661
|
let skippedVisibleMessages = 0;
|
|
@@ -165067,17 +165664,20 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
165067
165664
|
skippedVisibleMessages = cutoffIndex + 1;
|
|
165068
165665
|
const remaining = messages.slice(cutoffIndex + 1);
|
|
165069
165666
|
messages.splice(0, messages.length, ...remaining);
|
|
165667
|
+
} else {
|
|
165668
|
+
sessionLog(sessionId, `compartment injection entering degraded mode: boundary ${lastEndMessageId} not in visible messages`);
|
|
165070
165669
|
}
|
|
165071
165670
|
const result = {
|
|
165072
165671
|
block,
|
|
165073
165672
|
compartmentEndMessage: lastEnd,
|
|
165074
|
-
compartmentEndMessageId: lastEndMessageId,
|
|
165673
|
+
compartmentEndMessageId: cutoffIndex >= 0 ? lastEndMessageId : null,
|
|
165075
165674
|
compartmentCount: compartments.length,
|
|
165076
165675
|
skippedVisibleMessages,
|
|
165077
165676
|
factCount: facts.length,
|
|
165078
|
-
memoryCount
|
|
165677
|
+
memoryCount,
|
|
165678
|
+
rebuiltFromDb: true
|
|
165079
165679
|
};
|
|
165080
|
-
injectionCache.set(sessionId, result);
|
|
165680
|
+
injectionCache.set(sessionId, { kind: "populated", injection: result });
|
|
165081
165681
|
return result;
|
|
165082
165682
|
}
|
|
165083
165683
|
|
|
@@ -165299,8 +165899,9 @@ function tagTranscript(sessionId, transcript, tagger, db, options = {}) {
|
|
|
165299
165899
|
continue;
|
|
165300
165900
|
const messageId = message.info.id;
|
|
165301
165901
|
let textOrdinal = 0;
|
|
165302
|
-
|
|
165303
|
-
|
|
165902
|
+
const parts = message.parts;
|
|
165903
|
+
for (let partIndex = 0;partIndex < parts.length; partIndex += 1) {
|
|
165904
|
+
const part = parts[partIndex];
|
|
165304
165905
|
if (part === undefined)
|
|
165305
165906
|
continue;
|
|
165306
165907
|
if (part.kind === "text") {
|
|
@@ -166619,7 +167220,7 @@ function injectSessionHistoryIntoPi(db, sessionId, piMessages, isCacheBusting, p
|
|
|
166619
167220
|
};
|
|
166620
167221
|
}
|
|
166621
167222
|
const boundaryId = prepared.compartmentEndMessageId;
|
|
166622
|
-
const skippedVisible = boundaryId.length > 0 ? trimPiMessagesToBoundary(piMessages, entryIds, boundaryId) : prepared.skippedVisibleMessages;
|
|
167223
|
+
const skippedVisible = boundaryId != null && boundaryId.length > 0 ? trimPiMessagesToBoundary(piMessages, entryIds, boundaryId) : prepared.skippedVisibleMessages;
|
|
166623
167224
|
const historyBlock = `<session-history>
|
|
166624
167225
|
${prepared.block}
|
|
166625
167226
|
</session-history>`;
|
|
@@ -167669,17 +168270,17 @@ function getReducedRecompTokenBudget(currentBudget) {
|
|
|
167669
168270
|
}
|
|
167670
168271
|
|
|
167671
168272
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
167672
|
-
|
|
167673
|
-
import {
|
|
167674
|
-
import { join as
|
|
168273
|
+
init_data_path();
|
|
168274
|
+
import { mkdirSync as mkdirSync5, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
168275
|
+
import { join as join9 } from "node:path";
|
|
167675
168276
|
var HISTORIAN_STATE_INLINE_THRESHOLD = 30000;
|
|
167676
|
-
|
|
167677
|
-
function maybeWriteHistorianStateFile(sessionId, existingState) {
|
|
168277
|
+
function maybeWriteHistorianStateFile(sessionId, existingState, directory) {
|
|
167678
168278
|
if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
|
|
167679
168279
|
return;
|
|
167680
168280
|
try {
|
|
167681
|
-
|
|
167682
|
-
|
|
168281
|
+
const dir = getProjectMagicContextHistorianDir(directory);
|
|
168282
|
+
mkdirSync5(dir, { recursive: true });
|
|
168283
|
+
const path5 = join9(dir, `state-${sessionId}-${Date.now()}.xml`);
|
|
167683
168284
|
writeFileSync2(path5, existingState, "utf8");
|
|
167684
168285
|
return path5;
|
|
167685
168286
|
} catch {
|
|
@@ -167779,7 +168380,7 @@ async function runPiHistorian(deps) {
|
|
|
167779
168380
|
const existingState = priorCompartments.length > 0 || priorFacts.length > 0 ? buildExistingStateXml(priorCompartments, priorFacts, memoryBlock) : memoryBlock ? `${memoryBlock}
|
|
167780
168381
|
|
|
167781
168382
|
This is your first run. No existing compartments or facts.` : "This is your first run. No existing state.";
|
|
167782
|
-
stateFilePath = maybeWriteHistorianStateFile(sessionId, existingState);
|
|
168383
|
+
stateFilePath = maybeWriteHistorianStateFile(sessionId, existingState, directory);
|
|
167783
168384
|
if (stateFilePath) {
|
|
167784
168385
|
sessionLog(sessionId, `pi-historian: existing state offloaded to file (${existingState.length} chars) → ${stateFilePath}`);
|
|
167785
168386
|
}
|
|
@@ -169887,7 +170488,7 @@ init_logger();
|
|
|
169887
170488
|
init_data_path();
|
|
169888
170489
|
init_logger();
|
|
169889
170490
|
await init_sqlite();
|
|
169890
|
-
import { join as
|
|
170491
|
+
import { join as join10 } from "node:path";
|
|
169891
170492
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
169892
170493
|
function randomBase62(length) {
|
|
169893
170494
|
const chars = [];
|
|
@@ -169908,7 +170509,7 @@ function generatePartId(timestampMs, counter = 0n) {
|
|
|
169908
170509
|
return generateId("prt", timestampMs, counter);
|
|
169909
170510
|
}
|
|
169910
170511
|
function getOpenCodeDbPath3() {
|
|
169911
|
-
return
|
|
170512
|
+
return join10(getDataDir(), "opencode", "opencode.db");
|
|
169912
170513
|
}
|
|
169913
170514
|
var cachedWriteDb = null;
|
|
169914
170515
|
var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
@@ -170399,7 +171000,8 @@ async function runCompressorPass2(args) {
|
|
|
170399
171000
|
targetTokens,
|
|
170400
171001
|
outputCount,
|
|
170401
171002
|
outputDepth,
|
|
170402
|
-
historianTimeoutMs
|
|
171003
|
+
historianTimeoutMs,
|
|
171004
|
+
fallbackModels
|
|
170403
171005
|
} = args;
|
|
170404
171006
|
const prompt = buildCompressorPrompt(compartments, currentTokens, targetTokens, outputDepth, outputCount);
|
|
170405
171007
|
let agentSessionId = null;
|
|
@@ -170421,7 +171023,11 @@ async function runCompressorPass2(args) {
|
|
|
170421
171023
|
agent: HISTORIAN_AGENT2,
|
|
170422
171024
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
170423
171025
|
}
|
|
170424
|
-
}, {
|
|
171026
|
+
}, {
|
|
171027
|
+
timeoutMs: historianTimeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
171028
|
+
fallbackModels,
|
|
171029
|
+
callContext: "compressor"
|
|
171030
|
+
});
|
|
170425
171031
|
const messagesResponse = await client.session.messages({
|
|
170426
171032
|
path: { id: agentSessionId },
|
|
170427
171033
|
query: { directory }
|
|
@@ -170461,11 +171067,13 @@ async function runCompressorPass2(args) {
|
|
|
170461
171067
|
}
|
|
170462
171068
|
|
|
170463
171069
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
170464
|
-
import { mkdirSync as
|
|
170465
|
-
import {
|
|
170466
|
-
import { join as join12 } from "node:path";
|
|
171070
|
+
import { mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
171071
|
+
import { join as join11 } from "node:path";
|
|
170467
171072
|
init_magic_context();
|
|
170468
|
-
|
|
171073
|
+
init_data_path();
|
|
171074
|
+
function historianResponseDumpDir(directory) {
|
|
171075
|
+
return getProjectMagicContextHistorianDir(directory);
|
|
171076
|
+
}
|
|
170469
171077
|
var MAX_HISTORIAN_RETRIES = 2;
|
|
170470
171078
|
async function runValidatedHistorianPass(args) {
|
|
170471
171079
|
const firstRun = await runHistorianPrompt({
|
|
@@ -170559,7 +171167,8 @@ async function runHistorianPrompt(args) {
|
|
|
170559
171167
|
timeoutMs,
|
|
170560
171168
|
dumpLabel,
|
|
170561
171169
|
modelOverride,
|
|
170562
|
-
agentId = HISTORIAN_AGENT
|
|
171170
|
+
agentId = HISTORIAN_AGENT,
|
|
171171
|
+
fallbackModels
|
|
170563
171172
|
} = args;
|
|
170564
171173
|
let agentSessionId = null;
|
|
170565
171174
|
try {
|
|
@@ -170586,7 +171195,11 @@ async function runHistorianPrompt(args) {
|
|
|
170586
171195
|
...modelOverride ? { model: modelOverride } : {},
|
|
170587
171196
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
170588
171197
|
}
|
|
170589
|
-
}, {
|
|
171198
|
+
}, {
|
|
171199
|
+
timeoutMs: timeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
171200
|
+
fallbackModels: modelOverride ? undefined : fallbackModels,
|
|
171201
|
+
callContext: agentId === HISTORIAN_EDITOR_AGENT ? "historian:editor" : "historian"
|
|
171202
|
+
});
|
|
170590
171203
|
sessionLog(parentSessionId, `historian: prompt completed (attempt ${retryIndex + 1}/${MAX_HISTORIAN_RETRIES + 1})`);
|
|
170591
171204
|
break;
|
|
170592
171205
|
} catch (error51) {
|
|
@@ -170612,7 +171225,7 @@ async function runHistorianPrompt(args) {
|
|
|
170612
171225
|
if (!result) {
|
|
170613
171226
|
return { ok: false, error: "Historian returned no assistant output." };
|
|
170614
171227
|
}
|
|
170615
|
-
const dumpPath = dumpHistorianResponse(parentSessionId, dumpLabel ?? "historian-response", result);
|
|
171228
|
+
const dumpPath = dumpHistorianResponse(parentSessionId, sessionDirectory, dumpLabel ?? "historian-response", result);
|
|
170616
171229
|
return { ok: true, result, dumpPath };
|
|
170617
171230
|
} catch (modelError) {
|
|
170618
171231
|
const desc = describeError(modelError);
|
|
@@ -170704,12 +171317,13 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
170704
171317
|
});
|
|
170705
171318
|
}
|
|
170706
171319
|
}
|
|
170707
|
-
function dumpHistorianResponse(sessionId, label, text) {
|
|
171320
|
+
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
170708
171321
|
try {
|
|
170709
|
-
|
|
171322
|
+
const dumpDir = historianResponseDumpDir(directory);
|
|
171323
|
+
mkdirSync6(dumpDir, { recursive: true });
|
|
170710
171324
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
170711
171325
|
const safeLabel = sanitizeDumpName(label);
|
|
170712
|
-
const dumpPath =
|
|
171326
|
+
const dumpPath = join11(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
170713
171327
|
writeFileSync3(dumpPath, text, "utf8");
|
|
170714
171328
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
170715
171329
|
label,
|
|
@@ -170934,9 +171548,18 @@ async function executePartialRecompInternal(deps, range) {
|
|
|
170934
171548
|
}
|
|
170935
171549
|
setRecompPartialRange(db, sessionId, null);
|
|
170936
171550
|
clearCompressionDepthRange(db, sessionId, snapStart, snapEnd);
|
|
170937
|
-
|
|
170938
|
-
|
|
171551
|
+
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
171552
|
+
clearInjectionCache(sessionId);
|
|
171553
|
+
}
|
|
171554
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
170939
171555
|
const lastEnd = merged[merged.length - 1]?.endMessage ?? snapEnd;
|
|
171556
|
+
if (deps.experimentalCompactionMarkers && lastEnd > 0) {
|
|
171557
|
+
updateCompactionMarkerAfterPublication(db, sessionId, lastEnd, deps.directory);
|
|
171558
|
+
const stalePending = getPendingCompactionMarkerState(db, sessionId);
|
|
171559
|
+
if (stalePending) {
|
|
171560
|
+
clearPendingCompactionMarkerStateIf(db, sessionId, stalePending);
|
|
171561
|
+
}
|
|
171562
|
+
}
|
|
170940
171563
|
return { compartmentCount: merged.length, lastEndMessage: lastEnd };
|
|
170941
171564
|
};
|
|
170942
171565
|
const protectedTailStart = getProtectedTailStartOrdinal(sessionId);
|
|
@@ -171042,6 +171665,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
171042
171665
|
dumpLabelBase: `partial-recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
171043
171666
|
timeoutMs: historianTimeoutMs,
|
|
171044
171667
|
fallbackModelId: deps.fallbackModelId,
|
|
171668
|
+
fallbackModels: deps.fallbackModels,
|
|
171045
171669
|
twoPass: deps.historianTwoPass,
|
|
171046
171670
|
callbacks: {
|
|
171047
171671
|
onRepairRetry: async (error51) => {
|
|
@@ -171150,8 +171774,10 @@ async function executeContextRecompInternal(deps) {
|
|
|
171150
171774
|
if (!promoted2)
|
|
171151
171775
|
return null;
|
|
171152
171776
|
clearCompressionDepth(db, sessionId);
|
|
171153
|
-
|
|
171154
|
-
|
|
171777
|
+
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
171778
|
+
clearInjectionCache(sessionId);
|
|
171779
|
+
}
|
|
171780
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
171155
171781
|
if (deps.directory && deps.memoryEnabled !== false && deps.autoPromote !== false) {
|
|
171156
171782
|
promoteSessionFactsToMemory(db, sessionId, resolveProjectIdentity(deps.directory), promoted2.facts);
|
|
171157
171783
|
}
|
|
@@ -171161,6 +171787,10 @@ async function executeContextRecompInternal(deps) {
|
|
|
171161
171787
|
}
|
|
171162
171788
|
if (deps.experimentalCompactionMarkers && lastCompartmentEnd2 > 0) {
|
|
171163
171789
|
updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd2, deps.directory);
|
|
171790
|
+
const stalePending = getPendingCompactionMarkerState(db, sessionId);
|
|
171791
|
+
if (stalePending) {
|
|
171792
|
+
clearPendingCompactionMarkerStateIf(db, sessionId, stalePending);
|
|
171793
|
+
}
|
|
171164
171794
|
}
|
|
171165
171795
|
return [
|
|
171166
171796
|
`Persisted ${promoted2.compartments.length} compartment${promoted2.compartments.length === 1 ? "" : "s"} from ${passCount} successful pass${passCount === 1 ? "" : "es"}.`,
|
|
@@ -171226,7 +171856,7 @@ Nothing was written.`;
|
|
|
171226
171856
|
|
|
171227
171857
|
This is your first run. No existing compartments or facts.` : "This is your first run. No existing state.";
|
|
171228
171858
|
cleanupHistorianStateFile(currentStateFilePath);
|
|
171229
|
-
currentStateFilePath = maybeWriteHistorianStateFile(sessionId, existingState);
|
|
171859
|
+
currentStateFilePath = maybeWriteHistorianStateFile(sessionId, existingState, sessionDirectory);
|
|
171230
171860
|
const prompt = buildCompartmentAgentPrompt(existingState, `Messages ${chunk.startIndex}-${chunk.endIndex}:
|
|
171231
171861
|
|
|
171232
171862
|
${chunk.text}`, { stateFilePath: currentStateFilePath });
|
|
@@ -171244,6 +171874,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
171244
171874
|
dumpLabelBase: `recomp-${sessionId}-${chunk.startIndex}-${chunk.endIndex}-pass-${passCount + 1}`,
|
|
171245
171875
|
timeoutMs: historianTimeoutMs,
|
|
171246
171876
|
fallbackModelId: deps.fallbackModelId,
|
|
171877
|
+
fallbackModels: deps.fallbackModels,
|
|
171247
171878
|
twoPass: deps.historianTwoPass,
|
|
171248
171879
|
callbacks: {
|
|
171249
171880
|
onRepairRetry: async (error51) => {
|
|
@@ -171321,8 +171952,10 @@ Nothing was written.`;
|
|
|
171321
171952
|
clearRecompStaging(db, sessionId);
|
|
171322
171953
|
}
|
|
171323
171954
|
clearCompressionDepth(db, sessionId);
|
|
171324
|
-
|
|
171325
|
-
|
|
171955
|
+
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
171956
|
+
clearInjectionCache(sessionId);
|
|
171957
|
+
}
|
|
171958
|
+
deps.onCompartmentStatePublished?.(sessionId);
|
|
171326
171959
|
const finalCompartments = promoted?.compartments ?? candidateCompartments;
|
|
171327
171960
|
const finalFacts = promoted?.facts ?? candidateFacts;
|
|
171328
171961
|
if (deps.directory && deps.memoryEnabled !== false && deps.autoPromote !== false) {
|
|
@@ -171341,6 +171974,7 @@ Nothing was written.`;
|
|
|
171341
171974
|
directory: sessionDirectory,
|
|
171342
171975
|
historyBudgetTokens: deps.historyBudgetTokens,
|
|
171343
171976
|
historianTimeoutMs,
|
|
171977
|
+
fallbackModels: deps.fallbackModels,
|
|
171344
171978
|
minCompartmentRatio: deps.compressorMinCompartmentRatio,
|
|
171345
171979
|
maxMergeDepth: deps.compressorMaxMergeDepth
|
|
171346
171980
|
});
|
|
@@ -171370,21 +172004,39 @@ Staging data preserved for resume on next attempt.`;
|
|
|
171370
172004
|
|
|
171371
172005
|
// ../plugin/src/hooks/magic-context/compartment-runner.ts
|
|
171372
172006
|
var activeRuns = new Map;
|
|
172007
|
+
function markActiveCompartmentRunPublished(sessionId) {
|
|
172008
|
+
const activeRun = activeRuns.get(sessionId);
|
|
172009
|
+
if (activeRun)
|
|
172010
|
+
activeRun.published = true;
|
|
172011
|
+
}
|
|
172012
|
+
function withPublishedCallback(deps) {
|
|
172013
|
+
return {
|
|
172014
|
+
...deps,
|
|
172015
|
+
onCompartmentStatePublished: (sid) => {
|
|
172016
|
+
markActiveCompartmentRunPublished(sid);
|
|
172017
|
+
deps.onCompartmentStatePublished?.(sid);
|
|
172018
|
+
}
|
|
172019
|
+
};
|
|
172020
|
+
}
|
|
171373
172021
|
async function executeContextRecomp(deps, options = {}) {
|
|
171374
172022
|
const { sessionId } = deps;
|
|
171375
172023
|
if (activeRuns.has(sessionId)) {
|
|
171376
172024
|
return "## Magic Recomp\n\nHistorian is already running for this session. Wait for it to finish, then try `/ctx-recomp` again.";
|
|
171377
172025
|
}
|
|
171378
|
-
const
|
|
171379
|
-
|
|
172026
|
+
const runnerDeps = withPublishedCallback(deps);
|
|
172027
|
+
const promise2 = options.range ? executePartialRecompInternal(runnerDeps, options.range) : executeContextRecompInternal(runnerDeps);
|
|
172028
|
+
const wrappedPromise = promise2.then(() => {
|
|
171380
172029
|
return;
|
|
171381
172030
|
}).catch((err) => {
|
|
171382
172031
|
sessionLog(sessionId, "compartment agent: recomp unhandled rejection:", err);
|
|
171383
|
-
})
|
|
172032
|
+
});
|
|
172033
|
+
activeRuns.set(sessionId, { promise: wrappedPromise, published: false });
|
|
171384
172034
|
try {
|
|
171385
172035
|
return await promise2;
|
|
171386
172036
|
} finally {
|
|
171387
|
-
activeRuns.
|
|
172037
|
+
if (activeRuns.get(sessionId)?.promise === wrappedPromise) {
|
|
172038
|
+
activeRuns.delete(sessionId);
|
|
172039
|
+
}
|
|
171388
172040
|
}
|
|
171389
172041
|
}
|
|
171390
172042
|
|
|
@@ -171877,7 +172529,7 @@ import {
|
|
|
171877
172529
|
// package.json
|
|
171878
172530
|
var package_default = {
|
|
171879
172531
|
name: "@cortexkit/pi-magic-context",
|
|
171880
|
-
version: "0.
|
|
172532
|
+
version: "0.19.0",
|
|
171881
172533
|
type: "module",
|
|
171882
172534
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
171883
172535
|
main: "dist/index.js",
|
|
@@ -172416,12 +173068,12 @@ function readHistorianState(db, sessionId, meta3) {
|
|
|
172416
173068
|
init_magic_context();
|
|
172417
173069
|
import { existsSync as existsSync8, readFileSync as readFileSync3 } from "node:fs";
|
|
172418
173070
|
import { homedir as homedir4 } from "node:os";
|
|
172419
|
-
import { join as
|
|
173071
|
+
import { join as join12 } from "node:path";
|
|
172420
173072
|
|
|
172421
173073
|
// ../plugin/src/config/variable.ts
|
|
172422
173074
|
import { existsSync as existsSync7, readFileSync as readFileSync2 } from "node:fs";
|
|
172423
173075
|
import { homedir as homedir3 } from "node:os";
|
|
172424
|
-
import { dirname as
|
|
173076
|
+
import { dirname as dirname4, isAbsolute, resolve } from "node:path";
|
|
172425
173077
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
172426
173078
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
172427
173079
|
function substituteConfigVariables(input) {
|
|
@@ -172440,7 +173092,7 @@ function substituteConfigVariables(input) {
|
|
|
172440
173092
|
if (fileMatches.length === 0) {
|
|
172441
173093
|
return { text, warnings };
|
|
172442
173094
|
}
|
|
172443
|
-
const configDir = input.configPath ?
|
|
173095
|
+
const configDir = input.configPath ? dirname4(input.configPath) : process.cwd();
|
|
172444
173096
|
let output = "";
|
|
172445
173097
|
let cursor = 0;
|
|
172446
173098
|
for (const match of fileMatches) {
|
|
@@ -172484,12 +173136,12 @@ function substituteConfigVariables(input) {
|
|
|
172484
173136
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
172485
173137
|
var CONFIG_FILE_NAME = "magic-context";
|
|
172486
173138
|
function getProjectConfigPaths(cwd) {
|
|
172487
|
-
const basePath =
|
|
173139
|
+
const basePath = join12(cwd, ".pi", CONFIG_FILE_NAME);
|
|
172488
173140
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
172489
173141
|
}
|
|
172490
173142
|
function getUserConfigPaths() {
|
|
172491
173143
|
const home = process.env.HOME ?? homedir4();
|
|
172492
|
-
const basePath =
|
|
173144
|
+
const basePath = join12(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
172493
173145
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
172494
173146
|
}
|
|
172495
173147
|
function resolveFirstExisting(paths) {
|
|
@@ -172646,7 +173298,7 @@ function stripTagPrefixFromAssistantMessage(message) {
|
|
|
172646
173298
|
// src/system-prompt.ts
|
|
172647
173299
|
import { createHash as createHash4 } from "node:crypto";
|
|
172648
173300
|
import { existsSync as existsSync9, readFileSync as readFileSync4, realpathSync } from "node:fs";
|
|
172649
|
-
import { join as
|
|
173301
|
+
import { join as join13, resolve as resolve2, sep } from "node:path";
|
|
172650
173302
|
|
|
172651
173303
|
// ../plugin/src/agents/magic-context-prompt.ts
|
|
172652
173304
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
@@ -172748,7 +173400,7 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
172748
173400
|
function readProjectDocs(directory) {
|
|
172749
173401
|
const sections = [];
|
|
172750
173402
|
for (const filename of DOC_FILES) {
|
|
172751
|
-
const filePath =
|
|
173403
|
+
const filePath = join13(directory, filename);
|
|
172752
173404
|
try {
|
|
172753
173405
|
if (existsSync9(filePath)) {
|
|
172754
173406
|
const content = readFileSync4(filePath, "utf-8").trim();
|
|
@@ -177979,7 +178631,7 @@ function resolveDreamerFromConfig(config2) {
|
|
|
177979
178631
|
}
|
|
177980
178632
|
async function src_default2(pi) {
|
|
177981
178633
|
const storageDir = getMagicContextStorageDir();
|
|
177982
|
-
const dbPath =
|
|
178634
|
+
const dbPath = join14(storageDir, "context.db");
|
|
177983
178635
|
let db;
|
|
177984
178636
|
try {
|
|
177985
178637
|
db = openDatabase();
|