@cortexkit/pi-magic-context 0.45.0 → 0.46.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/embedding-worker.js +4 -4
- package/dist/{index-j0mbc5vj.js → index-266qrgss.js} +59 -1
- package/dist/index-2p1e8706.js +30 -0
- package/dist/{index-k0yd1ph9.js → index-4vfrjwf6.js} +129 -166
- package/dist/{index-g0xfx1c2.js → index-phh7e055.js} +16 -1
- package/dist/{index-ttf0cqq8.js → index-sg8zbjs0.js} +23 -24
- package/dist/index-td885aah.js +576 -0
- package/dist/index-vf38qhee.js +150 -0
- package/dist/{index-2bw9k8nx.js → index-vhzmjpsk.js} +1308 -1019
- package/dist/{index-2pbbk3en.js → index-wv28nczk.js} +55 -1
- package/dist/{index-vxjgsr9m.js → index-xvw8zptx.js} +3565 -3349
- package/dist/index.js +3136 -1449
- package/dist/{message-time-backfill-g83dkh8m.js → message-time-backfill-4688z1k2.js} +2 -2
- package/dist/migration-worker.js +11 -6
- package/dist/{read-session-chunk-kmt7a6zj.js → read-session-chunk-tc6yn2pe.js} +5 -5
- package/dist/subagent-entry.js +10 -10
- package/package.json +4 -3
- package/dist/index-4d3cba70.js +0 -10
- package/dist/index-7s5yk3za.js +0 -16
- package/dist/index-e16q5sd7.js +0 -240
|
@@ -31,18 +31,21 @@ import {
|
|
|
31
31
|
getEmbeddingProviderIdentity,
|
|
32
32
|
dominantEmbeddingFailure,
|
|
33
33
|
LocalEmbeddingProvider
|
|
34
|
-
} from "./index-
|
|
34
|
+
} from "./index-sg8zbjs0.js";
|
|
35
35
|
import {
|
|
36
36
|
piModelRefToCanonical,
|
|
37
37
|
modelRefLookupOrder
|
|
38
|
-
} from "./index-
|
|
38
|
+
} from "./index-phh7e055.js";
|
|
39
39
|
import {
|
|
40
40
|
resolveDecisionCalibration,
|
|
41
41
|
calibrationForModelKey,
|
|
42
|
+
protectedToolTagNumbers,
|
|
42
43
|
isRecord,
|
|
43
44
|
TODO_STATUSES,
|
|
44
45
|
TODO_PRIORITIES,
|
|
45
46
|
TITLE_DONE_STATUSES,
|
|
47
|
+
queuePendingOp,
|
|
48
|
+
getPendingOps,
|
|
46
49
|
updateTagStatus,
|
|
47
50
|
getInertWhitespaceAssistantTags,
|
|
48
51
|
getTagNumberByMessageId,
|
|
@@ -54,31 +57,33 @@ import {
|
|
|
54
57
|
hasRawMessageProvider2,
|
|
55
58
|
setRawMessageProvider2,
|
|
56
59
|
cleanUserText2,
|
|
57
|
-
readRawSessionMessages2,
|
|
58
60
|
visitRawSessionMessages2,
|
|
59
61
|
readRawSessionMessageById2,
|
|
60
62
|
readSessionChunk2
|
|
61
|
-
} from "./index-
|
|
63
|
+
} from "./index-xvw8zptx.js";
|
|
62
64
|
import {
|
|
63
65
|
removeSystemReminders,
|
|
64
66
|
hasMeaningfulUserText2,
|
|
65
67
|
extractTexts2,
|
|
66
68
|
getTokenEstimatorFingerprint,
|
|
67
69
|
estimateTokens
|
|
68
|
-
} from "./index-
|
|
70
|
+
} from "./index-266qrgss.js";
|
|
71
|
+
import {
|
|
72
|
+
stableStringify,
|
|
73
|
+
closeQuietly,
|
|
74
|
+
isKnownAutocommit,
|
|
75
|
+
getTableColumnNames,
|
|
76
|
+
resolveOpenCodeDbPath,
|
|
77
|
+
assertOpenCodeStoreGeneration
|
|
78
|
+
} from "./index-td885aah.js";
|
|
69
79
|
import {
|
|
70
80
|
Database,
|
|
81
|
+
prepareCachedStatement,
|
|
71
82
|
withSqliteBackgroundWriter,
|
|
72
83
|
withoutSqliteTransformPass,
|
|
73
84
|
isTransientSqliteError,
|
|
74
85
|
withPrivilegedWriter
|
|
75
|
-
} from "./index-
|
|
76
|
-
import {
|
|
77
|
-
stableStringify,
|
|
78
|
-
resolveOpenCodeDbPath,
|
|
79
|
-
assertOpenCodeStoreGeneration,
|
|
80
|
-
closeQuietly
|
|
81
|
-
} from "./index-e16q5sd7.js";
|
|
86
|
+
} from "./index-wv28nczk.js";
|
|
82
87
|
import {
|
|
83
88
|
isUserHomeDirectory,
|
|
84
89
|
directoryHasGitMetadata,
|
|
@@ -104,10 +109,14 @@ import {
|
|
|
104
109
|
sourceNameForMemory,
|
|
105
110
|
managedAuthorityNoteRow,
|
|
106
111
|
getErrorMessage
|
|
107
|
-
} from "./index-
|
|
112
|
+
} from "./index-4vfrjwf6.js";
|
|
113
|
+
import {
|
|
114
|
+
ensureStorageDirectorySync,
|
|
115
|
+
writeStorageFileAtomicSync
|
|
116
|
+
} from "./index-vf38qhee.js";
|
|
108
117
|
import {
|
|
109
118
|
logSlowWriteTransaction
|
|
110
|
-
} from "./index-
|
|
119
|
+
} from "./index-2p1e8706.js";
|
|
111
120
|
|
|
112
121
|
// ../plugin/src/config/agent-disable.ts
|
|
113
122
|
var COMPACTION_ENABLED_PATH = `compaction${"."}enabled`;
|
|
@@ -610,18 +619,7 @@ function formatCompactTokens(value) {
|
|
|
610
619
|
}
|
|
611
620
|
|
|
612
621
|
// ../plugin/src/config/migrate-config-location.ts
|
|
613
|
-
import {
|
|
614
|
-
closeSync,
|
|
615
|
-
existsSync,
|
|
616
|
-
mkdirSync,
|
|
617
|
-
openSync,
|
|
618
|
-
readFileSync as readFileSync2,
|
|
619
|
-
renameSync,
|
|
620
|
-
rmSync,
|
|
621
|
-
statSync,
|
|
622
|
-
unlinkSync,
|
|
623
|
-
writeFileSync
|
|
624
|
-
} from "node:fs";
|
|
622
|
+
import { existsSync, readFileSync as readFileSync2, rmSync, statSync, unlinkSync } from "node:fs";
|
|
625
623
|
import { homedir } from "node:os";
|
|
626
624
|
import { basename, dirname, isAbsolute, join as join2 } from "node:path";
|
|
627
625
|
|
|
@@ -2280,7 +2278,7 @@ var CONFIG_LOCK_STALE_MS = 4000;
|
|
|
2280
2278
|
function acquireConfigMigrationLock(lockDir) {
|
|
2281
2279
|
for (let attempt = 0;attempt < 2; attempt++) {
|
|
2282
2280
|
try {
|
|
2283
|
-
|
|
2281
|
+
ensureStorageDirectorySync(lockDir, true, false);
|
|
2284
2282
|
return () => {
|
|
2285
2283
|
try {
|
|
2286
2284
|
rmSync(lockDir, { recursive: true, force: true });
|
|
@@ -2305,26 +2303,7 @@ function acquireConfigMigrationLock(lockDir) {
|
|
|
2305
2303
|
return null;
|
|
2306
2304
|
}
|
|
2307
2305
|
function atomicWriteConfigFile(targetPath, content) {
|
|
2308
|
-
|
|
2309
|
-
const tmpPath = join2(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
2310
|
-
let fd = null;
|
|
2311
|
-
try {
|
|
2312
|
-
fd = openSync(tmpPath, "wx", 384);
|
|
2313
|
-
writeFileSync(fd, content);
|
|
2314
|
-
closeSync(fd);
|
|
2315
|
-
fd = null;
|
|
2316
|
-
renameSync(tmpPath, targetPath);
|
|
2317
|
-
} catch (err) {
|
|
2318
|
-
if (fd !== null) {
|
|
2319
|
-
try {
|
|
2320
|
-
closeSync(fd);
|
|
2321
|
-
} catch {}
|
|
2322
|
-
}
|
|
2323
|
-
try {
|
|
2324
|
-
unlinkSync(tmpPath);
|
|
2325
|
-
} catch {}
|
|
2326
|
-
throw err;
|
|
2327
|
-
}
|
|
2306
|
+
writeStorageFileAtomicSync(targetPath, content, true);
|
|
2328
2307
|
}
|
|
2329
2308
|
function movedMarkerContent(targetPath, originalName, originalContent) {
|
|
2330
2309
|
const header = [
|
|
@@ -2378,7 +2357,7 @@ function migrateConfigFile(opts) {
|
|
|
2378
2357
|
if (existingSources.length === 0) {
|
|
2379
2358
|
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
2380
2359
|
}
|
|
2381
|
-
|
|
2360
|
+
ensureStorageDirectorySync(dirname(opts.targetPath), true);
|
|
2382
2361
|
const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
|
|
2383
2362
|
if (!release) {
|
|
2384
2363
|
warnings.push(`Config migration for ${opts.scope} skipped this run (another instance is migrating); will retry on next start.`);
|
|
@@ -3058,6 +3037,9 @@ function escalationBands(effectiveThresholdPercentage) {
|
|
|
3058
3037
|
|
|
3059
3038
|
// ../plugin/src/features/magic-context/merged-reasoning-decisions.ts
|
|
3060
3039
|
var MERGED_REASONING_PARTS_PREFIX = "__merged_reasoning_parts_v1__:";
|
|
3040
|
+
var decodedDecisions = new Map;
|
|
3041
|
+
var decodedDecisionBytes = 0;
|
|
3042
|
+
var MAX_DECODED_DECISION_BYTES = 32 * 1024 * 1024;
|
|
3061
3043
|
function decodeMergedReasoningParts(value) {
|
|
3062
3044
|
if (!value.startsWith(MERGED_REASONING_PARTS_PREFIX))
|
|
3063
3045
|
return null;
|
|
@@ -3078,9 +3060,24 @@ function decodeMergedReasoningParts(value) {
|
|
|
3078
3060
|
function readFrozenMergedReasoningParts(ids) {
|
|
3079
3061
|
const decisions = new Map;
|
|
3080
3062
|
for (const value of ids) {
|
|
3081
|
-
|
|
3063
|
+
let record = decodedDecisions.get(value);
|
|
3064
|
+
if (record === undefined) {
|
|
3065
|
+
record = decodeMergedReasoningParts(value);
|
|
3066
|
+
const bytes = 2 * value.length + 128;
|
|
3067
|
+
if (bytes <= MAX_DECODED_DECISION_BYTES) {
|
|
3068
|
+
while (decodedDecisions.size >= 1e5 || decodedDecisionBytes + bytes > MAX_DECODED_DECISION_BYTES) {
|
|
3069
|
+
const oldest = decodedDecisions.keys().next().value;
|
|
3070
|
+
if (oldest === undefined)
|
|
3071
|
+
break;
|
|
3072
|
+
decodedDecisionBytes -= 2 * oldest.length + 128;
|
|
3073
|
+
decodedDecisions.delete(oldest);
|
|
3074
|
+
}
|
|
3075
|
+
decodedDecisions.set(value, record);
|
|
3076
|
+
decodedDecisionBytes += bytes;
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3082
3079
|
if (record && !decisions.has(record[0]))
|
|
3083
|
-
decisions.set(...record);
|
|
3080
|
+
decisions.set(record[0], [...record[1]]);
|
|
3084
3081
|
}
|
|
3085
3082
|
return decisions;
|
|
3086
3083
|
}
|
|
@@ -3628,7 +3625,15 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
3628
3625
|
piStableIdScheme: null
|
|
3629
3626
|
};
|
|
3630
3627
|
}
|
|
3628
|
+
var sessionMetaExistsStatements = new WeakMap;
|
|
3631
3629
|
function ensureSessionMetaRow(db, sessionId, initialIsSubagent = false) {
|
|
3630
|
+
let exists = sessionMetaExistsStatements.get(db);
|
|
3631
|
+
if (!exists) {
|
|
3632
|
+
exists = prepareCachedStatement(db, "SELECT 1 FROM session_meta WHERE session_id = ?");
|
|
3633
|
+
sessionMetaExistsStatements.set(db, exists);
|
|
3634
|
+
}
|
|
3635
|
+
if (exists.get(sessionId))
|
|
3636
|
+
return;
|
|
3632
3637
|
const defaults = getDefaultSessionMeta(sessionId);
|
|
3633
3638
|
db.prepare("INSERT OR IGNORE INTO session_meta (session_id, harness, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, observed_safe_input_tokens, cache_alert_sent, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, cleared_reasoning_through_tag) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(sessionId, getHarness(), defaults.lastResponseTime, defaults.cacheTtl, defaults.counter, defaults.lastNudgeTokens, defaults.lastNudgeBand ?? "", defaults.lastTransformError ?? "", initialIsSubagent ? 1 : 0, defaults.lastContextPercentage, defaults.lastInputTokens, defaults.observedSafeInputTokens, defaults.cacheAlertSent ? 1 : 0, defaults.timesExecuteThresholdReached, defaults.compartmentInProgress ? 1 : 0, defaults.systemPromptHash ?? "", defaults.clearedReasoningThroughTag);
|
|
3634
3639
|
}
|
|
@@ -3765,6 +3770,10 @@ function clearCachedM0M1(db, sessionId) {
|
|
|
3765
3770
|
// ../plugin/src/features/magic-context/storage-replay-document.ts
|
|
3766
3771
|
var CAS_RETRY_LIMIT = 5;
|
|
3767
3772
|
var MISSING_REPLAY_DOCUMENT_COLUMN = Symbol("missing replay document column");
|
|
3773
|
+
function isRustMarkerAdmissionFenced(db, sessionId) {
|
|
3774
|
+
const row = db.prepare("SELECT COALESCE(json_extract(NULLIF(trailing_blank_decisions, ''), '$.rustMarkerAdmissionFence'), 0) AS fenced FROM session_meta WHERE session_id=?").get(sessionId);
|
|
3775
|
+
return row?.fenced === 1;
|
|
3776
|
+
}
|
|
3768
3777
|
function isPersistedTrailingBlankDecision(value) {
|
|
3769
3778
|
if (value === "keep" || value === "strip")
|
|
3770
3779
|
return true;
|
|
@@ -5431,34 +5440,61 @@ function decode(row) {
|
|
|
5431
5440
|
}
|
|
5432
5441
|
return { ...row, data };
|
|
5433
5442
|
}
|
|
5434
|
-
|
|
5443
|
+
function connect(path, identity = "") {
|
|
5444
|
+
const db = new Database(path, { readonly: true, fileMustExist: true });
|
|
5445
|
+
try {
|
|
5446
|
+
assertOpenCodeStoreGeneration(db, "v2", path);
|
|
5447
|
+
} catch (error) {
|
|
5448
|
+
db.close();
|
|
5449
|
+
throw error;
|
|
5450
|
+
}
|
|
5451
|
+
const counters = debugCounters();
|
|
5452
|
+
counters.openReaders += 1;
|
|
5453
|
+
counters.readersOpened += 1;
|
|
5454
|
+
counters.maxOpenReaders = Math.max(counters.maxOpenReaders, counters.openReaders);
|
|
5455
|
+
return { db, statements: new Map, identity, leases: 0, retired: false };
|
|
5456
|
+
}
|
|
5457
|
+
function closeConnection(connection) {
|
|
5458
|
+
connection.statements.clear();
|
|
5459
|
+
try {
|
|
5460
|
+
connection.db.close();
|
|
5461
|
+
} finally {
|
|
5462
|
+
const counters = debugCounters();
|
|
5463
|
+
counters.openReaders = Math.max(0, counters.openReaders - 1);
|
|
5464
|
+
counters.readersClosed += 1;
|
|
5465
|
+
}
|
|
5466
|
+
}
|
|
5435
5467
|
class V2StoreReader {
|
|
5468
|
+
pool;
|
|
5436
5469
|
db;
|
|
5470
|
+
connection;
|
|
5437
5471
|
closed = false;
|
|
5438
|
-
constructor(path) {
|
|
5439
|
-
this.
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5472
|
+
constructor(path, pool) {
|
|
5473
|
+
this.pool = pool;
|
|
5474
|
+
this.connection = pool ? pool.acquire(path) : connect(path);
|
|
5475
|
+
this.db = this.connection.db;
|
|
5476
|
+
}
|
|
5477
|
+
prepare(sql) {
|
|
5478
|
+
if (this.closed)
|
|
5479
|
+
throw new Error("Store reader is closed");
|
|
5480
|
+
const statements = this.connection.statements;
|
|
5481
|
+
let statement = statements.get(sql);
|
|
5482
|
+
if (!statement) {
|
|
5483
|
+
statement = this.db.prepare(sql);
|
|
5484
|
+
if (statements.size >= 128)
|
|
5485
|
+
statements.clear();
|
|
5486
|
+
statements.set(sql, statement);
|
|
5445
5487
|
}
|
|
5446
|
-
|
|
5447
|
-
counters.openReaders += 1;
|
|
5448
|
-
counters.readersOpened += 1;
|
|
5449
|
-
counters.maxOpenReaders = Math.max(counters.maxOpenReaders, counters.openReaders);
|
|
5488
|
+
return statement;
|
|
5450
5489
|
}
|
|
5451
5490
|
close() {
|
|
5452
5491
|
if (this.closed)
|
|
5453
5492
|
return;
|
|
5454
5493
|
this.closed = true;
|
|
5455
|
-
|
|
5456
|
-
this.
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
counters.openReaders = Math.max(0, counters.openReaders - 1);
|
|
5460
|
-
counters.readersClosed += 1;
|
|
5461
|
-
}
|
|
5494
|
+
if (this.pool)
|
|
5495
|
+
this.pool.release(this.connection);
|
|
5496
|
+
else
|
|
5497
|
+
closeConnection(this.connection);
|
|
5462
5498
|
}
|
|
5463
5499
|
page(sessionID, options = {}) {
|
|
5464
5500
|
return trackDecodeOperation("page", () => {
|
|
@@ -5480,7 +5516,7 @@ class V2StoreReader {
|
|
|
5480
5516
|
predicates.push("type = ?");
|
|
5481
5517
|
parameters.push(options.type);
|
|
5482
5518
|
}
|
|
5483
|
-
const rows = this.
|
|
5519
|
+
const rows = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
|
|
5484
5520
|
WHERE ${predicates.join(" AND ")}
|
|
5485
5521
|
ORDER BY seq ASC LIMIT ?`).all(...parameters, limit).map(decode);
|
|
5486
5522
|
return { rows, cursor: rows.at(-1)?.seq };
|
|
@@ -5498,46 +5534,56 @@ class V2StoreReader {
|
|
|
5498
5534
|
if (pageSize <= 0)
|
|
5499
5535
|
return [];
|
|
5500
5536
|
if (after) {
|
|
5501
|
-
const anchor = this.
|
|
5537
|
+
const anchor = this.prepare("SELECT seq FROM session_message WHERE session_id = ? AND id = ?").get(sessionID, after.id);
|
|
5502
5538
|
if (anchor) {
|
|
5503
|
-
return this.
|
|
5539
|
+
return this.prepare(`SELECT id, session_id, type, seq, time_created, data
|
|
5504
5540
|
FROM session_message WHERE session_id = ? AND seq > ?
|
|
5505
5541
|
AND type IN (${RAW_MESSAGE_TYPE_PARAMETERS}) ORDER BY seq ASC LIMIT ?`).all(sessionID, anchor.seq, ...RAW_MESSAGE_TYPES, pageSize).map(decode);
|
|
5506
5542
|
}
|
|
5507
5543
|
}
|
|
5508
5544
|
const maximumSeq = Number.MAX_SAFE_INTEGER;
|
|
5509
|
-
const rows = this.
|
|
5545
|
+
const rows = this.prepare(V2_MESSAGE_PAGE_SQL).all(afterOrdinal, sessionID, ...RAW_MESSAGE_TYPES, Math.max(0, afterOrdinal - 1), sessionID, ...RAW_MESSAGE_TYPES, finalWatermark - 1, maximumSeq, sessionID, ...RAW_MESSAGE_TYPES, pageSize);
|
|
5510
5546
|
return rows.map(decode);
|
|
5511
5547
|
});
|
|
5512
5548
|
}
|
|
5513
5549
|
messageCount(sessionID) {
|
|
5514
5550
|
return trackDecodeOperation("messageCount", () => {
|
|
5515
5551
|
const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
|
|
5516
|
-
const row = this.
|
|
5552
|
+
const row = this.prepare(`SELECT COUNT(*) AS count FROM session_message
|
|
5517
5553
|
WHERE session_id = ? AND type IN (${rawTypes})`).get(sessionID, ...RAW_MESSAGE_TYPES);
|
|
5518
5554
|
return typeof row?.count === "number" ? row.count : 0;
|
|
5519
5555
|
});
|
|
5520
5556
|
}
|
|
5521
5557
|
sessionDirectoryPage(afterSessionID, limit) {
|
|
5522
|
-
const rows = this.
|
|
5558
|
+
const rows = this.prepare(`SELECT id, COALESCE(directory, '') AS directory FROM session_v2
|
|
5523
5559
|
WHERE id > ? ORDER BY id ASC LIMIT ?`).all(afterSessionID ?? "", limit);
|
|
5524
5560
|
return rows.map((row) => ({ sessionId: row.id, directory: row.directory }));
|
|
5525
5561
|
}
|
|
5526
5562
|
latestMessageTime(sessionID) {
|
|
5527
|
-
const row = this.
|
|
5563
|
+
const row = this.prepare("SELECT MAX(time_created) AS time FROM session_message WHERE session_id = ?").get(sessionID);
|
|
5528
5564
|
return row?.time ?? undefined;
|
|
5529
5565
|
}
|
|
5530
5566
|
isSubagent(sessionID) {
|
|
5531
|
-
const row = this.
|
|
5567
|
+
const row = this.prepare("SELECT parent_id FROM session_v2 WHERE id = ?").get(sessionID);
|
|
5532
5568
|
if (!row)
|
|
5533
5569
|
return null;
|
|
5534
5570
|
return typeof row.parent_id === "string" && row.parent_id.length > 0;
|
|
5535
5571
|
}
|
|
5572
|
+
latestRootSessionInDirectory(directory) {
|
|
5573
|
+
const columns = new Set(this.prepare("PRAGMA table_info(session_v2)").all().map((column) => column.name));
|
|
5574
|
+
const archived = columns.has("time_archived") ? " AND time_archived IS NULL" : "";
|
|
5575
|
+
const order = columns.has("time_updated") ? "time_updated DESC, id DESC" : "id DESC";
|
|
5576
|
+
const row = this.prepare(`SELECT id FROM session_v2
|
|
5577
|
+
WHERE directory = ? AND parent_id IS NULL${archived}
|
|
5578
|
+
AND COALESCE(json_extract(metadata, '$.magic_context'), '') <> 'hidden-run'
|
|
5579
|
+
ORDER BY ${order} LIMIT 1`).get(directory);
|
|
5580
|
+
return row?.id;
|
|
5581
|
+
}
|
|
5536
5582
|
rootSessionActivity(sessionIDs) {
|
|
5537
5583
|
const roots = new Map;
|
|
5538
5584
|
for (let offset = 0;offset < sessionIDs.length; offset += 500) {
|
|
5539
5585
|
const chunk = sessionIDs.slice(offset, offset + 500);
|
|
5540
|
-
const rows = this.
|
|
5586
|
+
const rows = this.prepare(`SELECT id, (
|
|
5541
5587
|
SELECT MAX(time_created) FROM session_message
|
|
5542
5588
|
WHERE session_id = session_v2.id AND type = 'user'
|
|
5543
5589
|
) AS time FROM session_v2
|
|
@@ -5554,7 +5600,7 @@ class V2StoreReader {
|
|
|
5554
5600
|
const result = new Map;
|
|
5555
5601
|
for (let offset = 0;offset < sessionIDs.length; offset += 500) {
|
|
5556
5602
|
const chunk = sessionIDs.slice(offset, offset + 500);
|
|
5557
|
-
const rows = this.
|
|
5603
|
+
const rows = this.prepare(`SELECT session_id, MIN(time_created) AS time FROM session_message
|
|
5558
5604
|
WHERE type = 'user' AND time_created > ? AND session_id IN (${chunk.map(() => "?").join(",")})
|
|
5559
5605
|
GROUP BY session_id`).all(sinceMs, ...chunk);
|
|
5560
5606
|
for (const row of rows)
|
|
@@ -5571,7 +5617,7 @@ class V2StoreReader {
|
|
|
5571
5617
|
const direction = before ? "DESC" : "ASC";
|
|
5572
5618
|
const head = Math.floor((maxChars - truncationMarker.length) / 2);
|
|
5573
5619
|
const tail = maxChars - truncationMarker.length - head;
|
|
5574
|
-
return this.
|
|
5620
|
+
return this.prepare(`WITH users AS (
|
|
5575
5621
|
SELECT seq, time_created, data FROM session_message
|
|
5576
5622
|
WHERE session_id = ? AND type = 'user' AND time_created ${before ? "<=" : ">"} ?
|
|
5577
5623
|
ORDER BY time_created ${direction}, seq ${direction} LIMIT ?
|
|
@@ -5591,14 +5637,14 @@ class V2StoreReader {
|
|
|
5591
5637
|
}
|
|
5592
5638
|
storedMessageCount(sessionID) {
|
|
5593
5639
|
return trackDecodeOperation("storedMessageCount", () => {
|
|
5594
|
-
const row = this.
|
|
5640
|
+
const row = this.prepare("SELECT COUNT(*) AS count FROM session_message WHERE session_id = ?").get(sessionID);
|
|
5595
5641
|
return typeof row?.count === "number" ? row.count : 0;
|
|
5596
5642
|
});
|
|
5597
5643
|
}
|
|
5598
5644
|
messageById(sessionID, id) {
|
|
5599
5645
|
return trackDecodeOperation("messageById", () => {
|
|
5600
5646
|
const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
|
|
5601
|
-
const row = this.
|
|
5647
|
+
const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
|
|
5602
5648
|
WHERE session_id = ? AND id = ? AND type IN (${rawTypes}) LIMIT 1`).get(sessionID, id, ...RAW_MESSAGE_TYPES);
|
|
5603
5649
|
return row ? decode(row) : null;
|
|
5604
5650
|
});
|
|
@@ -5606,7 +5652,7 @@ class V2StoreReader {
|
|
|
5606
5652
|
messageExistsById(sessionID, id) {
|
|
5607
5653
|
return trackDecodeOperation("messageExistsById", () => {
|
|
5608
5654
|
const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
|
|
5609
|
-
const row = this.
|
|
5655
|
+
const row = this.prepare(`SELECT 1 FROM session_message
|
|
5610
5656
|
WHERE id = ? AND session_id = ? AND type IN (${rawTypes}) LIMIT 1`).get(id, sessionID, ...RAW_MESSAGE_TYPES);
|
|
5611
5657
|
return row != null;
|
|
5612
5658
|
});
|
|
@@ -5614,7 +5660,7 @@ class V2StoreReader {
|
|
|
5614
5660
|
messageOrdinalById(sessionID, id) {
|
|
5615
5661
|
return trackDecodeOperation("messageOrdinalById", () => {
|
|
5616
5662
|
const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
|
|
5617
|
-
const row = this.
|
|
5663
|
+
const row = this.prepare(`WITH target AS (
|
|
5618
5664
|
SELECT seq FROM session_message
|
|
5619
5665
|
WHERE session_id = ? AND id = ? AND type IN (${rawTypes})
|
|
5620
5666
|
LIMIT 1
|
|
@@ -5636,7 +5682,7 @@ class V2StoreReader {
|
|
|
5636
5682
|
if (!Number.isSafeInteger(toOrdinal) || toOrdinal < fromOrdinal)
|
|
5637
5683
|
throw new Error("Invalid raw-message range end");
|
|
5638
5684
|
const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
|
|
5639
|
-
const rows = this.
|
|
5685
|
+
const rows = this.prepare(`SELECT id FROM session_message
|
|
5640
5686
|
WHERE session_id = ? AND type IN (${rawTypes})
|
|
5641
5687
|
ORDER BY seq ASC LIMIT ? OFFSET ?`).all(sessionID, ...RAW_MESSAGE_TYPES, toOrdinal - fromOrdinal + 1, fromOrdinal - 1);
|
|
5642
5688
|
return new Map(rows.map((row, index) => [row.id, fromOrdinal + index]));
|
|
@@ -5646,10 +5692,10 @@ class V2StoreReader {
|
|
|
5646
5692
|
return trackDecodeOperation("messageOrdinalPage", () => {
|
|
5647
5693
|
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
|
|
5648
5694
|
throw new Error("Invalid page limit");
|
|
5649
|
-
const rows = after ? this.
|
|
5695
|
+
const rows = after ? this.prepare(`SELECT id, type, seq, json_valid(data) AS valid
|
|
5650
5696
|
FROM session_message
|
|
5651
5697
|
WHERE session_id = ? AND (seq > ? OR (seq = ? AND id > ?))
|
|
5652
|
-
ORDER BY seq ASC, id ASC LIMIT ?`).all(sessionID, after.timeCreated, after.timeCreated, after.id, limit) : this.
|
|
5698
|
+
ORDER BY seq ASC, id ASC LIMIT ?`).all(sessionID, after.timeCreated, after.timeCreated, after.id, limit) : this.prepare(`SELECT id, type, seq, json_valid(data) AS valid
|
|
5653
5699
|
FROM session_message
|
|
5654
5700
|
WHERE session_id = ?
|
|
5655
5701
|
ORDER BY seq ASC, id ASC LIMIT ?`).all(sessionID, limit);
|
|
@@ -5668,7 +5714,7 @@ class V2StoreReader {
|
|
|
5668
5714
|
spanRowStamps(sessionID, after, through) {
|
|
5669
5715
|
if (!Number.isSafeInteger(after) || !Number.isSafeInteger(through))
|
|
5670
5716
|
throw new Error("Invalid seq span");
|
|
5671
|
-
const rows = this.
|
|
5717
|
+
const rows = this.prepare(`SELECT seq, id, time_updated AS updated, length(CAST(data AS BLOB)) AS bytes
|
|
5672
5718
|
FROM session_message WHERE session_id = ? AND seq > ? AND seq <= ?
|
|
5673
5719
|
ORDER BY seq ASC`).all(sessionID, after, through);
|
|
5674
5720
|
const stamps = new Map;
|
|
@@ -5683,7 +5729,7 @@ class V2StoreReader {
|
|
|
5683
5729
|
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1e4)
|
|
5684
5730
|
throw new Error("Invalid page limit");
|
|
5685
5731
|
const rawTypes = RAW_MESSAGE_TYPES.map(() => "?").join(", ");
|
|
5686
|
-
return this.
|
|
5732
|
+
return this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
|
|
5687
5733
|
WHERE session_id = ? AND type IN (${rawTypes}) AND seq <= ?
|
|
5688
5734
|
ORDER BY seq DESC LIMIT ?`).all(sessionID, ...RAW_MESSAGE_TYPES, throughSeq, limit).map(decode);
|
|
5689
5735
|
});
|
|
@@ -5691,14 +5737,18 @@ class V2StoreReader {
|
|
|
5691
5737
|
sequenceForId(sessionID, id) {
|
|
5692
5738
|
if (!id)
|
|
5693
5739
|
return;
|
|
5694
|
-
const row = this.
|
|
5740
|
+
const row = this.prepare("SELECT seq FROM session_message WHERE session_id = ? AND id = ? LIMIT 1").get(sessionID, id);
|
|
5695
5741
|
return typeof row?.seq === "number" ? row.seq : undefined;
|
|
5696
5742
|
}
|
|
5743
|
+
syntheticMessageIDs(sessionID) {
|
|
5744
|
+
const rows = this.prepare("SELECT id FROM session_message WHERE session_id = ? AND type = 'synthetic'").all(sessionID);
|
|
5745
|
+
return new Set(rows.map((row) => row.id));
|
|
5746
|
+
}
|
|
5697
5747
|
forkOrigin(sessionID) {
|
|
5698
|
-
const columns = new Set(this.
|
|
5748
|
+
const columns = new Set(this.prepare("PRAGMA table_info(session_v2)").all().map((column) => column.name));
|
|
5699
5749
|
if (!columns.has("fork_session_id") || !columns.has("fork_boundary"))
|
|
5700
5750
|
return null;
|
|
5701
|
-
const row = this.
|
|
5751
|
+
const row = this.prepare("SELECT fork_session_id, fork_boundary FROM session_v2 WHERE id = ?").get(sessionID);
|
|
5702
5752
|
if (!row?.fork_session_id || !row.fork_boundary)
|
|
5703
5753
|
return null;
|
|
5704
5754
|
try {
|
|
@@ -5714,17 +5764,17 @@ class V2StoreReader {
|
|
|
5714
5764
|
}
|
|
5715
5765
|
}
|
|
5716
5766
|
sessionExists(sessionID) {
|
|
5717
|
-
return this.
|
|
5767
|
+
return this.prepare("SELECT 1 FROM session_v2 WHERE id = ?").get(sessionID) != null;
|
|
5718
5768
|
}
|
|
5719
5769
|
rowStampsThrough(sessionID, throughSeq) {
|
|
5720
|
-
return this.
|
|
5770
|
+
return this.prepare(`SELECT id, type, seq, time_created FROM session_message
|
|
5721
5771
|
WHERE session_id = ? AND seq <= ? ORDER BY seq ASC`).all(sessionID, throughSeq);
|
|
5722
5772
|
}
|
|
5723
5773
|
latestSequenceForIds(sessionID, ids) {
|
|
5724
5774
|
let latest = -1;
|
|
5725
5775
|
for (let offset = 0;offset < ids.length; offset += 500) {
|
|
5726
5776
|
const chunk = ids.slice(offset, offset + 500);
|
|
5727
|
-
const row = this.
|
|
5777
|
+
const row = this.prepare(`SELECT MAX(seq) AS seq FROM session_message
|
|
5728
5778
|
WHERE session_id = ? AND id IN (${chunk.map(() => "?").join(", ")})`).get(sessionID, ...chunk);
|
|
5729
5779
|
if (typeof row?.seq === "number")
|
|
5730
5780
|
latest = Math.max(latest, row.seq);
|
|
@@ -5732,7 +5782,7 @@ class V2StoreReader {
|
|
|
5732
5782
|
return latest;
|
|
5733
5783
|
}
|
|
5734
5784
|
compactionByStatus(sessionID, status) {
|
|
5735
|
-
const row = this.
|
|
5785
|
+
const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
|
|
5736
5786
|
WHERE session_id = ? AND type = 'compaction'
|
|
5737
5787
|
AND json_extract(data, '$.status') = ?
|
|
5738
5788
|
ORDER BY seq DESC LIMIT 1`).get(sessionID, status);
|
|
@@ -5748,16 +5798,16 @@ class V2StoreReader {
|
|
|
5748
5798
|
return trackDecodeOperation("idleRows", () => this.all(sessionID, after, "idle"));
|
|
5749
5799
|
}
|
|
5750
5800
|
earliestSequence(sessionID) {
|
|
5751
|
-
const row = this.
|
|
5801
|
+
const row = this.prepare("SELECT MIN(seq) AS seq FROM session_message WHERE session_id = ?").get(sessionID);
|
|
5752
5802
|
return typeof row?.seq === "number" ? row.seq : undefined;
|
|
5753
5803
|
}
|
|
5754
5804
|
latestSequence(sessionID) {
|
|
5755
|
-
const row = this.
|
|
5805
|
+
const row = this.prepare("SELECT MAX(seq) AS seq FROM session_message WHERE session_id = ?").get(sessionID);
|
|
5756
5806
|
return typeof row?.seq === "number" ? row.seq : -1;
|
|
5757
5807
|
}
|
|
5758
5808
|
assistantSince(sessionID, afterSeq) {
|
|
5759
5809
|
return trackDecodeOperation("assistantSince", () => {
|
|
5760
|
-
const rows = this.
|
|
5810
|
+
const rows = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
|
|
5761
5811
|
WHERE session_id = ? AND type = 'assistant' AND seq > ?
|
|
5762
5812
|
ORDER BY seq ASC`).all(sessionID, afterSeq);
|
|
5763
5813
|
return rows.map((row) => decode(row));
|
|
@@ -5765,7 +5815,7 @@ class V2StoreReader {
|
|
|
5765
5815
|
}
|
|
5766
5816
|
latestAssistant(sessionID) {
|
|
5767
5817
|
return trackDecodeOperation("latestAssistant", () => {
|
|
5768
|
-
const row = this.
|
|
5818
|
+
const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
|
|
5769
5819
|
WHERE session_id = ? AND type = 'assistant'
|
|
5770
5820
|
ORDER BY seq DESC LIMIT 1`).get(sessionID);
|
|
5771
5821
|
return row ? decode(row) : undefined;
|
|
@@ -5773,7 +5823,7 @@ class V2StoreReader {
|
|
|
5773
5823
|
}
|
|
5774
5824
|
latestIdle(sessionID) {
|
|
5775
5825
|
return trackDecodeOperation("latestIdle", () => {
|
|
5776
|
-
const row = this.
|
|
5826
|
+
const row = this.prepare(`SELECT id, session_id, type, seq, time_created, data FROM session_message
|
|
5777
5827
|
WHERE session_id = ? AND type = 'idle'
|
|
5778
5828
|
ORDER BY seq DESC LIMIT 1`).get(sessionID);
|
|
5779
5829
|
return row ? decode(row) : undefined;
|
|
@@ -6919,6 +6969,10 @@ var SESSION_SCOPED_TABLES = [
|
|
|
6919
6969
|
{ table: "tool_owner_backfill_state" },
|
|
6920
6970
|
{ table: "tags", harnessScoped: true },
|
|
6921
6971
|
{ table: "session_meta", harnessScoped: true },
|
|
6972
|
+
{
|
|
6973
|
+
table: "temporal_decisions",
|
|
6974
|
+
extraPredicate: "NOT EXISTS (SELECT 1 FROM session_meta AS remaining WHERE remaining.session_id = temporal_decisions.session_id)"
|
|
6975
|
+
},
|
|
6922
6976
|
{
|
|
6923
6977
|
table: "session_replay_decisions",
|
|
6924
6978
|
extraPredicate: "NOT EXISTS (SELECT 1 FROM session_meta AS remaining WHERE remaining.session_id = session_replay_decisions.session_id)"
|
|
@@ -7158,6 +7212,19 @@ function clearSession(db, sessionId, rustModuleCleanupAcknowledged = false) {
|
|
|
7158
7212
|
}).immediate()));
|
|
7159
7213
|
logSlowWriteTransaction("clear-session", transactionStartedAt);
|
|
7160
7214
|
}
|
|
7215
|
+
// ../plugin/src/shared/provider-response-completion.ts
|
|
7216
|
+
function providerResponseFailed(input) {
|
|
7217
|
+
if (input.error !== undefined && input.error !== null && input.error !== "")
|
|
7218
|
+
return true;
|
|
7219
|
+
const finish = typeof input.finish === "string" ? input.finish.trim().toLowerCase() : "";
|
|
7220
|
+
return ["error", "failed", "abort", "aborted", "interrupted", "cancelled", "canceled"].includes(finish);
|
|
7221
|
+
}
|
|
7222
|
+
function isSuccessfulProviderCompletion(input) {
|
|
7223
|
+
if (providerResponseFailed(input))
|
|
7224
|
+
return false;
|
|
7225
|
+
return typeof input.completedAt === "number" && Number.isFinite(input.completedAt) && input.completedAt > 0 || typeof input.finish === "string" && input.finish.trim().length > 0;
|
|
7226
|
+
}
|
|
7227
|
+
|
|
7161
7228
|
// ../plugin/src/hooks/magic-context/embed-session-state.ts
|
|
7162
7229
|
var embedPauseBySession = new Set;
|
|
7163
7230
|
var embedRunStateBySession = new Map;
|
|
@@ -7372,7 +7439,31 @@ function toCompartment(row) {
|
|
|
7372
7439
|
};
|
|
7373
7440
|
}
|
|
7374
7441
|
function getCompartments(db, sessionId) {
|
|
7375
|
-
const
|
|
7442
|
+
const presentColumns = getTableColumnNames(db, "compartments");
|
|
7443
|
+
const columns = [
|
|
7444
|
+
"id",
|
|
7445
|
+
"session_id",
|
|
7446
|
+
"sequence",
|
|
7447
|
+
"start_message",
|
|
7448
|
+
"end_message",
|
|
7449
|
+
"start_message_id",
|
|
7450
|
+
"end_message_id",
|
|
7451
|
+
"start_block_index",
|
|
7452
|
+
"end_block_index",
|
|
7453
|
+
"title",
|
|
7454
|
+
"content",
|
|
7455
|
+
"p1",
|
|
7456
|
+
"p2",
|
|
7457
|
+
"p3",
|
|
7458
|
+
"p4",
|
|
7459
|
+
"importance",
|
|
7460
|
+
"episode_type",
|
|
7461
|
+
"legacy",
|
|
7462
|
+
"created_at",
|
|
7463
|
+
"rebase_status"
|
|
7464
|
+
].filter((column) => presentColumns.has(column));
|
|
7465
|
+
const rows = db.prepare(`SELECT ${columns.length ? columns.join(", ") : "NULL AS id"}
|
|
7466
|
+
FROM compartments WHERE session_id = ? ORDER BY sequence ASC`).all(sessionId).filter(isCompartmentRow);
|
|
7376
7467
|
return rows.map(toCompartment);
|
|
7377
7468
|
}
|
|
7378
7469
|
function getLastCompartmentEndMessage(db, sessionId) {
|
|
@@ -7486,8 +7577,25 @@ function escapeXmlAttr(s) {
|
|
|
7486
7577
|
function escapeXmlContent(s) {
|
|
7487
7578
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
7488
7579
|
}
|
|
7489
|
-
function
|
|
7490
|
-
|
|
7580
|
+
function getUncoveredCompartmentEndThrough(db, sessionId, endOrdinal = Number.MAX_SAFE_INTEGER) {
|
|
7581
|
+
const end = getUncoveredCompartmentEndsThrough(db, sessionId, endOrdinal)[0];
|
|
7582
|
+
return end ? { endMessageId: end.endMessageId, endMessage: end.endMessage } : null;
|
|
7583
|
+
}
|
|
7584
|
+
function getUncoveredCompartmentEndsThrough(db, sessionId, endOrdinal = Number.MAX_SAFE_INTEGER, afterOrdinal = -1) {
|
|
7585
|
+
const rows = db.prepare(`SELECT k.end_message_id, k.end_message,
|
|
7586
|
+
n.start_message_id AS successor_id, n.start_message AS successor_start FROM compartments k
|
|
7587
|
+
LEFT JOIN compartments n ON n.session_id = k.session_id AND n.sequence = k.sequence + 1
|
|
7588
|
+
WHERE k.session_id = ?1 AND k.end_message <= ?2 AND k.end_message > ?3 AND k.end_block_index IS NOT NULL
|
|
7589
|
+
AND NOT COALESCE(n.sequence IS NOT NULL AND (
|
|
7590
|
+
(n.start_message_id = k.end_message_id AND n.start_block_index > k.end_block_index)
|
|
7591
|
+
OR n.start_message = k.end_message + 1), 0)
|
|
7592
|
+
ORDER BY k.sequence`).all(sessionId, endOrdinal, afterOrdinal);
|
|
7593
|
+
return rows.map((row) => ({
|
|
7594
|
+
endMessageId: row.end_message_id,
|
|
7595
|
+
endMessage: row.end_message,
|
|
7596
|
+
successorStartMessageId: row.successor_id,
|
|
7597
|
+
successorStartMessage: row.successor_start
|
|
7598
|
+
}));
|
|
7491
7599
|
}
|
|
7492
7600
|
function isPartialCompartmentEnd(db, sessionId, messageId) {
|
|
7493
7601
|
return Boolean(db.prepare("SELECT 1 FROM compartments WHERE session_id=? AND end_message_id=? AND end_block_index IS NOT NULL LIMIT 1").get(sessionId, messageId));
|
|
@@ -7859,7 +7967,7 @@ function indexItemsAfterOrdinal(db, sessionId, items, finalWatermark, toSource)
|
|
|
7859
7967
|
return inserted;
|
|
7860
7968
|
}
|
|
7861
7969
|
function harnessSupportsOpenCodeOrphanSweep(harness) {
|
|
7862
|
-
return harness === "opencode"
|
|
7970
|
+
return harness === "opencode";
|
|
7863
7971
|
}
|
|
7864
7972
|
function getMessageHistoryOrphanSweepState(db, harness) {
|
|
7865
7973
|
return db.prepare("SELECT cursor_session_id, last_swept_at FROM message_history_orphan_sweep WHERE harness = ?").get(harness) ?? {};
|
|
@@ -7895,6 +8003,15 @@ function sweepOrphanedOpenCodeMessageIndexesInBackground(db, openReadableOpenCod
|
|
|
7895
8003
|
}
|
|
7896
8004
|
if (!harnessSupportsOpenCodeOrphanSweep(harness)) {
|
|
7897
8005
|
persistMessageHistoryOrphanSweepState(db, cursor, now + unavailableReprobeMs - cooldownMs, harness);
|
|
8006
|
+
if (harness === "opencode2") {
|
|
8007
|
+
return {
|
|
8008
|
+
status: "unavailable",
|
|
8009
|
+
scanned: 0,
|
|
8010
|
+
deleted: 0,
|
|
8011
|
+
cursor,
|
|
8012
|
+
reason: "OpenCode 2 keeps its sessions in session_v2, which this sweep does not read"
|
|
8013
|
+
};
|
|
8014
|
+
}
|
|
7898
8015
|
return { status: "unavailable", scanned: 0, deleted: 0, cursor };
|
|
7899
8016
|
}
|
|
7900
8017
|
let openCodeDb = null;
|
|
@@ -8141,6 +8258,14 @@ class BoundedSessionMap {
|
|
|
8141
8258
|
}
|
|
8142
8259
|
}
|
|
8143
8260
|
|
|
8261
|
+
// ../plugin/src/hooks/magic-context/lkg-measured-request.ts
|
|
8262
|
+
var requests = new BoundedSessionMap(1000);
|
|
8263
|
+
var claimedRequests = new WeakSet;
|
|
8264
|
+
var captures = new BoundedSessionMap(1000);
|
|
8265
|
+
function clearCapturedLkgMeasurement(sessionId) {
|
|
8266
|
+
captures.delete(sessionId);
|
|
8267
|
+
}
|
|
8268
|
+
|
|
8144
8269
|
// ../plugin/src/hooks/magic-context/lkg-slot.ts
|
|
8145
8270
|
var LKG_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
8146
8271
|
var LKG_SINGLE_SLOT_BYTES = 24 * 1024 * 1024;
|
|
@@ -8256,6 +8381,35 @@ function lkgContentDigestFromFields(fields) {
|
|
|
8256
8381
|
}
|
|
8257
8382
|
return hash.digest("base64url");
|
|
8258
8383
|
}
|
|
8384
|
+
var digestMemo = new Map;
|
|
8385
|
+
var DIGEST_MEMO_MAX_BYTES = 16 * 1024 * 1024;
|
|
8386
|
+
var digestMemoBytes = 0;
|
|
8387
|
+
function memoizedLkgContentDigestFromFields(id, fields) {
|
|
8388
|
+
const prior = digestMemo.get(id);
|
|
8389
|
+
if (prior && equalContentFields(fields, prior.fields)) {
|
|
8390
|
+
digestMemo.delete(id);
|
|
8391
|
+
digestMemo.set(id, prior);
|
|
8392
|
+
return prior.digest;
|
|
8393
|
+
}
|
|
8394
|
+
const digest = lkgContentDigestFromFields(fields);
|
|
8395
|
+
if (prior) {
|
|
8396
|
+
digestMemo.delete(id);
|
|
8397
|
+
digestMemoBytes -= prior.bytes;
|
|
8398
|
+
}
|
|
8399
|
+
const bytes = 128 + id.length * 2 + fields.reduce((sum, field) => sum + 16 + (typeof field === "string" ? field.length * 2 : 0), 0);
|
|
8400
|
+
if (bytes <= DIGEST_MEMO_MAX_BYTES) {
|
|
8401
|
+
while (digestMemoBytes + bytes > DIGEST_MEMO_MAX_BYTES || digestMemo.size >= 20000) {
|
|
8402
|
+
const oldest = digestMemo.entries().next().value;
|
|
8403
|
+
if (!oldest)
|
|
8404
|
+
break;
|
|
8405
|
+
digestMemo.delete(oldest[0]);
|
|
8406
|
+
digestMemoBytes -= oldest[1].bytes;
|
|
8407
|
+
}
|
|
8408
|
+
digestMemo.set(id, { fields: [...fields], digest, bytes });
|
|
8409
|
+
digestMemoBytes += bytes;
|
|
8410
|
+
}
|
|
8411
|
+
return digest;
|
|
8412
|
+
}
|
|
8259
8413
|
function equalContentFields(left, right) {
|
|
8260
8414
|
if (left === right)
|
|
8261
8415
|
return true;
|
|
@@ -8295,10 +8449,6 @@ function incrementalLkgContentDigests(entries, prior) {
|
|
|
8295
8449
|
}
|
|
8296
8450
|
return { digests, reusedPrefix };
|
|
8297
8451
|
}
|
|
8298
|
-
function lkgContentDigest(message) {
|
|
8299
|
-
const fields = lkgContentFields(message);
|
|
8300
|
-
return fields ? lkgContentDigestFromFields(fields) : null;
|
|
8301
|
-
}
|
|
8302
8452
|
function touch(sessionId, entry) {
|
|
8303
8453
|
lkgHeapHolder.entries.delete(sessionId);
|
|
8304
8454
|
lkgHeapHolder.entries.set(sessionId, entry);
|
|
@@ -8430,6 +8580,10 @@ function copySlotForRead(slot) {
|
|
|
8430
8580
|
inputContentSignatures: slot.inputContentSignatures ? [...slot.inputContentSignatures] : undefined
|
|
8431
8581
|
};
|
|
8432
8582
|
}
|
|
8583
|
+
function getInMemorySlot(sessionId) {
|
|
8584
|
+
const entry = lkgHeapHolder.entries.get(sessionId);
|
|
8585
|
+
return entry ? copySlotForRead(entry.slot) : undefined;
|
|
8586
|
+
}
|
|
8433
8587
|
function getSlot(sessionId) {
|
|
8434
8588
|
const entry = lkgHeapHolder.entries.get(sessionId);
|
|
8435
8589
|
if (!entry) {
|
|
@@ -8444,12 +8598,16 @@ function getSlot(sessionId) {
|
|
|
8444
8598
|
touch(sessionId, entry);
|
|
8445
8599
|
return copySlotForRead(entry.slot);
|
|
8446
8600
|
}
|
|
8447
|
-
function
|
|
8601
|
+
function forgetInMemorySlot(sessionId) {
|
|
8448
8602
|
const entry = lkgHeapHolder.entries.get(sessionId);
|
|
8449
8603
|
if (entry) {
|
|
8450
8604
|
lkgHeapHolder.entries.delete(sessionId);
|
|
8451
8605
|
totalBytes -= entry.bytes;
|
|
8452
8606
|
}
|
|
8607
|
+
}
|
|
8608
|
+
function dropSlot(sessionId, _reason) {
|
|
8609
|
+
clearCapturedLkgMeasurement(sessionId);
|
|
8610
|
+
forgetInMemorySlot(sessionId);
|
|
8453
8611
|
const backend = persistenceBackend;
|
|
8454
8612
|
if (!backend)
|
|
8455
8613
|
return;
|
|
@@ -8473,7 +8631,10 @@ function noteEntry(sessionId, messages) {
|
|
|
8473
8631
|
const anchorIndex = entryInputIds.indexOf(slot.lastInputMessageId);
|
|
8474
8632
|
if (anchorIndex < 0)
|
|
8475
8633
|
return null;
|
|
8476
|
-
const entryContentDigests = messages.slice(0, anchorIndex + 1).map((message) =>
|
|
8634
|
+
const entryContentDigests = messages.slice(0, anchorIndex + 1).map((message, index) => {
|
|
8635
|
+
const fields = lkgContentFields(message);
|
|
8636
|
+
return fields ? memoizedLkgContentDigestFromFields(entryInputIds[index] ?? "", fields) : null;
|
|
8637
|
+
});
|
|
8477
8638
|
if (entryContentDigests.some((digest) => digest === null))
|
|
8478
8639
|
return null;
|
|
8479
8640
|
const pristineTail = structuredClone(messages.slice(anchorIndex + 1));
|
|
@@ -8927,7 +9088,8 @@ function clampWatermark(value, maxCopiedTag) {
|
|
|
8927
9088
|
}
|
|
8928
9089
|
function copySessionStateForClone(db, sourceSessionId, destinationSessionId, filter) {
|
|
8929
9090
|
return runImmediate(db, () => {
|
|
8930
|
-
|
|
9091
|
+
const hasTemporalDecisions = tableExists(db, "temporal_decisions");
|
|
9092
|
+
if (countRows(db, "compartments", destinationSessionId) > 0 || countRows(db, "tags", destinationSessionId) > 0 || hasTemporalDecisions && countRows(db, "temporal_decisions", destinationSessionId) > 0 || filter.copySessionNotesAndFacts === true && (tableExists(db, "notes") && countRows(db, "notes", destinationSessionId) > 0 || tableExists(db, "session_facts") && countRows(db, "session_facts", destinationSessionId) > 0)) {
|
|
8931
9093
|
return {
|
|
8932
9094
|
kind: "destination-not-empty",
|
|
8933
9095
|
compartmentsCopied: 0,
|
|
@@ -9019,6 +9181,14 @@ function copySessionStateForClone(db, sourceSessionId, destinationSessionId, fil
|
|
|
9019
9181
|
insertPendingOp.run(destinationSessionId, row.tag_id, row.operation, row.queued_at, row.harness);
|
|
9020
9182
|
}
|
|
9021
9183
|
}
|
|
9184
|
+
if (hasTemporalDecisions) {
|
|
9185
|
+
const temporalRows = db.prepare("SELECT message_id,marker FROM temporal_decisions WHERE session_id=?").all(sourceSessionId);
|
|
9186
|
+
const insertTemporal = db.prepare("INSERT INTO temporal_decisions(session_id,message_id,marker) VALUES (?,?,?)");
|
|
9187
|
+
for (const row of temporalRows) {
|
|
9188
|
+
if (filter.includeMessageId(row.message_id))
|
|
9189
|
+
insertTemporal.run(destinationSessionId, mapMessageId(filter, row.message_id), row.marker);
|
|
9190
|
+
}
|
|
9191
|
+
}
|
|
9022
9192
|
const inherited = filter.copySessionNotesAndFacts === true ? copyPiSessionNotesAndFacts(db, sourceSessionId, destinationSessionId, filter) : { notesCopied: 0, factsCopied: 0 };
|
|
9023
9193
|
const meta = db.prepare(`SELECT cleared_reasoning_through_tag, tool_reclaim_watermark,
|
|
9024
9194
|
pi_stable_id_scheme, stripped_placeholder_ids,
|
|
@@ -9552,89 +9722,6 @@ function markNoteChecked(db, noteId) {
|
|
|
9552
9722
|
const now = Date.now();
|
|
9553
9723
|
db.prepare("UPDATE notes SET last_checked_at = ?, updated_at = ? WHERE id = ? AND type = 'smart'").run(now, now, noteId);
|
|
9554
9724
|
}
|
|
9555
|
-
// ../plugin/src/features/magic-context/storage-ops.ts
|
|
9556
|
-
var queuePendingOpStatements = new WeakMap;
|
|
9557
|
-
var getPendingOpsStatements = new WeakMap;
|
|
9558
|
-
var getPendingOpsCountStatements = new WeakMap;
|
|
9559
|
-
var clearPendingOpsStatements = new WeakMap;
|
|
9560
|
-
var removePendingOpStatements = new WeakMap;
|
|
9561
|
-
function getQueuePendingOpStatement(db) {
|
|
9562
|
-
let stmt = queuePendingOpStatements.get(db);
|
|
9563
|
-
if (!stmt) {
|
|
9564
|
-
stmt = db.prepare("INSERT INTO pending_ops (session_id, tag_id, operation, queued_at, harness) VALUES (?, ?, ?, ?, ?)");
|
|
9565
|
-
queuePendingOpStatements.set(db, stmt);
|
|
9566
|
-
}
|
|
9567
|
-
return stmt;
|
|
9568
|
-
}
|
|
9569
|
-
function getPendingOpsStatement(db) {
|
|
9570
|
-
let stmt = getPendingOpsStatements.get(db);
|
|
9571
|
-
if (!stmt) {
|
|
9572
|
-
stmt = db.prepare("SELECT id, session_id, tag_id, operation, queued_at FROM pending_ops WHERE session_id = ? ORDER BY queued_at ASC, id ASC");
|
|
9573
|
-
getPendingOpsStatements.set(db, stmt);
|
|
9574
|
-
}
|
|
9575
|
-
return stmt;
|
|
9576
|
-
}
|
|
9577
|
-
function getClearPendingOpsStatement(db) {
|
|
9578
|
-
let stmt = clearPendingOpsStatements.get(db);
|
|
9579
|
-
if (!stmt) {
|
|
9580
|
-
stmt = db.prepare("DELETE FROM pending_ops WHERE session_id = ?");
|
|
9581
|
-
clearPendingOpsStatements.set(db, stmt);
|
|
9582
|
-
}
|
|
9583
|
-
return stmt;
|
|
9584
|
-
}
|
|
9585
|
-
function getRemovePendingOpStatement(db) {
|
|
9586
|
-
let stmt = removePendingOpStatements.get(db);
|
|
9587
|
-
if (!stmt) {
|
|
9588
|
-
stmt = db.prepare("DELETE FROM pending_ops WHERE session_id = ? AND tag_id = ?");
|
|
9589
|
-
removePendingOpStatements.set(db, stmt);
|
|
9590
|
-
}
|
|
9591
|
-
return stmt;
|
|
9592
|
-
}
|
|
9593
|
-
function isPendingOpRow(row) {
|
|
9594
|
-
if (row === null || typeof row !== "object")
|
|
9595
|
-
return false;
|
|
9596
|
-
const r = row;
|
|
9597
|
-
return typeof r.id === "number" && typeof r.session_id === "string" && typeof r.tag_id === "number" && typeof r.operation === "string" && typeof r.queued_at === "number";
|
|
9598
|
-
}
|
|
9599
|
-
function toPendingOp(row) {
|
|
9600
|
-
if (row.operation !== "drop") {
|
|
9601
|
-
sessionLog(row.session_id, `unknown pending operation "${row.operation}"; ignoring`);
|
|
9602
|
-
return null;
|
|
9603
|
-
}
|
|
9604
|
-
return {
|
|
9605
|
-
id: row.id,
|
|
9606
|
-
sessionId: row.session_id,
|
|
9607
|
-
tagId: row.tag_id,
|
|
9608
|
-
operation: row.operation,
|
|
9609
|
-
queuedAt: row.queued_at
|
|
9610
|
-
};
|
|
9611
|
-
}
|
|
9612
|
-
function queuePendingOp(db, sessionId, tagId, operation, queuedAt = Date.now()) {
|
|
9613
|
-
getQueuePendingOpStatement(db).run(sessionId, tagId, operation, queuedAt, getHarness());
|
|
9614
|
-
}
|
|
9615
|
-
function getPendingOps(db, sessionId) {
|
|
9616
|
-
const rows = getPendingOpsStatement(db).all(sessionId).filter(isPendingOpRow);
|
|
9617
|
-
return rows.map(toPendingOp).filter((op) => op !== null);
|
|
9618
|
-
}
|
|
9619
|
-
function getPendingOpsCount(db, sessionId) {
|
|
9620
|
-
try {
|
|
9621
|
-
let statement = getPendingOpsCountStatements.get(db);
|
|
9622
|
-
if (!statement) {
|
|
9623
|
-
statement = db.prepare("SELECT COUNT(*) AS count FROM pending_ops WHERE session_id = ?");
|
|
9624
|
-
getPendingOpsCountStatements.set(db, statement);
|
|
9625
|
-
}
|
|
9626
|
-
const row = statement.get(sessionId);
|
|
9627
|
-
return typeof row?.count === "number" && Number.isFinite(row.count) ? row.count : null;
|
|
9628
|
-
} catch {
|
|
9629
|
-
return null;
|
|
9630
|
-
}
|
|
9631
|
-
}
|
|
9632
|
-
function clearPendingOps(db, sessionId) {
|
|
9633
|
-
getClearPendingOpsStatement(db).run(sessionId);
|
|
9634
|
-
}
|
|
9635
|
-
function removePendingOp(db, sessionId, tagId) {
|
|
9636
|
-
getRemovePendingOpStatement(db).run(sessionId, tagId);
|
|
9637
|
-
}
|
|
9638
9725
|
// ../plugin/src/features/magic-context/storage-primers.ts
|
|
9639
9726
|
var PRIMER_CANDIDATE_TTL_MS = 90 * 24 * 60 * 60 * 1000;
|
|
9640
9727
|
var PRIMER_CANDIDATE_MAX_AGE_MS = 180 * 24 * 60 * 60 * 1000;
|
|
@@ -9925,6 +10012,7 @@ function bumpProjectUserProfileVersion(db, projectPath = GLOBAL_USER_PROFILE_PRO
|
|
|
9925
10012
|
return state;
|
|
9926
10013
|
}
|
|
9927
10014
|
// ../plugin/src/features/magic-context/storage-source.ts
|
|
10015
|
+
var sourceReadStatements = new WeakMap;
|
|
9928
10016
|
function isSourceContentRow(row) {
|
|
9929
10017
|
if (row === null || typeof row !== "object")
|
|
9930
10018
|
return false;
|
|
@@ -9938,8 +10026,12 @@ function getSourceContents(db, sessionId, tagIds) {
|
|
|
9938
10026
|
if (tagIds.length === 0) {
|
|
9939
10027
|
return new Map;
|
|
9940
10028
|
}
|
|
9941
|
-
|
|
9942
|
-
|
|
10029
|
+
let statement = sourceReadStatements.get(db);
|
|
10030
|
+
if (!statement) {
|
|
10031
|
+
statement = db.prepare("SELECT tag_id, content FROM source_contents WHERE session_id = ? AND tag_id IN (SELECT value FROM json_each(?))");
|
|
10032
|
+
sourceReadStatements.set(db, statement);
|
|
10033
|
+
}
|
|
10034
|
+
const rows = statement.all(sessionId, JSON.stringify(tagIds)).filter(isSourceContentRow);
|
|
9943
10035
|
const sources = new Map;
|
|
9944
10036
|
for (const row of rows) {
|
|
9945
10037
|
sources.set(row.tag_id, row.content);
|
|
@@ -10319,752 +10411,424 @@ function createPromptSurfaceGuidanceEpochCache(runtime) {
|
|
|
10319
10411
|
return cache;
|
|
10320
10412
|
}
|
|
10321
10413
|
|
|
10322
|
-
// src/
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
if (!msg || typeof msg !== "object")
|
|
10326
|
-
return;
|
|
10327
|
-
const byRef = entryIdByRef?.get(msg);
|
|
10328
|
-
if (typeof byRef === "string" && byRef.length > 0)
|
|
10329
|
-
return byRef;
|
|
10330
|
-
const positional = entryIds?.[index];
|
|
10331
|
-
if (typeof positional === "string" && positional.length > 0)
|
|
10332
|
-
return positional;
|
|
10333
|
-
const m = msg;
|
|
10334
|
-
const role = m.role ?? "unknown";
|
|
10335
|
-
return typeof m.timestamp === "number" ? `pi-msg-${index}-${m.timestamp}-${role}` : `pi-msg-${index}-${role}`;
|
|
10414
|
+
// ../plugin/src/config/prune-config-leaf.ts
|
|
10415
|
+
function isPlainObject2(value) {
|
|
10416
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10336
10417
|
}
|
|
10337
|
-
function
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10418
|
+
function pruneNestedConfigLeaf(block, relativePath) {
|
|
10419
|
+
if (relativePath.length === 0)
|
|
10420
|
+
return null;
|
|
10421
|
+
const result = { ...block };
|
|
10422
|
+
let cursor = result;
|
|
10423
|
+
for (let i = 0;i < relativePath.length - 1; i++) {
|
|
10424
|
+
const seg = String(relativePath[i]);
|
|
10425
|
+
const child = cursor[seg];
|
|
10426
|
+
if (!isPlainObject2(child)) {
|
|
10427
|
+
if (!(seg in cursor))
|
|
10428
|
+
return null;
|
|
10429
|
+
delete cursor[seg];
|
|
10430
|
+
return {
|
|
10431
|
+
block: result,
|
|
10432
|
+
removed: relativePath.slice(0, i + 1).map(String).join(".")
|
|
10433
|
+
};
|
|
10434
|
+
}
|
|
10435
|
+
const clonedChild = { ...child };
|
|
10436
|
+
cursor[seg] = clonedChild;
|
|
10437
|
+
cursor = clonedChild;
|
|
10349
10438
|
}
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
};
|
|
10439
|
+
const leaf = String(relativePath[relativePath.length - 1]);
|
|
10440
|
+
if (!(leaf in cursor))
|
|
10441
|
+
return null;
|
|
10442
|
+
delete cursor[leaf];
|
|
10443
|
+
return { block: result, removed: relativePath.map(String).join(".") };
|
|
10356
10444
|
}
|
|
10357
|
-
|
|
10358
|
-
|
|
10445
|
+
|
|
10446
|
+
// src/config/index.ts
|
|
10447
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
10448
|
+
|
|
10449
|
+
// ../plugin/src/config/migrate-dreamer-v2.ts
|
|
10450
|
+
var OLD_VERIFY_TASK = "verify";
|
|
10451
|
+
var OLD_CURATE_TASKS = ["consolidate", "archive-stale", "improve"];
|
|
10452
|
+
var RETIRED_OBJECT_MEMORY_TASKS = ["maintain-memory", ...OLD_CURATE_TASKS];
|
|
10453
|
+
var CANONICAL = [
|
|
10454
|
+
"map-memories",
|
|
10455
|
+
"verify",
|
|
10456
|
+
"verify-broad",
|
|
10457
|
+
"curate",
|
|
10458
|
+
"classify-memories",
|
|
10459
|
+
"retrospective",
|
|
10460
|
+
"maintain-docs",
|
|
10461
|
+
"evaluate-smart-notes",
|
|
10462
|
+
"review-user-memories",
|
|
10463
|
+
"promote-primers",
|
|
10464
|
+
"refresh-primers"
|
|
10465
|
+
];
|
|
10466
|
+
var DEFAULT_BASE_CRON = "0 2 * * *";
|
|
10467
|
+
var DEFAULT_CLASSIFY_CRON = "0 6 * * *";
|
|
10468
|
+
var DEFAULT_RETROSPECTIVE_CRON = "0 5 * * *";
|
|
10469
|
+
var DEFAULT_VERIFY_BROAD_CRON = "0 4 * * 0";
|
|
10470
|
+
function windowToCron(schedule) {
|
|
10471
|
+
if (typeof schedule !== "string")
|
|
10472
|
+
return DEFAULT_BASE_CRON;
|
|
10473
|
+
const m = /^(\d{1,2}):(\d{2})\s*-/.exec(schedule.trim());
|
|
10474
|
+
if (!m)
|
|
10475
|
+
return DEFAULT_BASE_CRON;
|
|
10476
|
+
const hour = Number(m[1]);
|
|
10477
|
+
const minute = Number(m[2]);
|
|
10478
|
+
if (hour >= 24 || minute >= 60)
|
|
10479
|
+
return DEFAULT_BASE_CRON;
|
|
10480
|
+
return `${minute} ${hour} * * *`;
|
|
10359
10481
|
}
|
|
10360
|
-
function
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
return
|
|
10482
|
+
function asObject(value) {
|
|
10483
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
10484
|
+
}
|
|
10485
|
+
function cronIntervalScore(schedule) {
|
|
10486
|
+
const parts = schedule.trim().split(/\s+/);
|
|
10487
|
+
if (parts.length !== 5)
|
|
10488
|
+
return Number.POSITIVE_INFINITY;
|
|
10489
|
+
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
|
|
10490
|
+
if (month !== "*")
|
|
10491
|
+
return 366 * 24 * 60;
|
|
10492
|
+
if (dayOfMonth !== "*")
|
|
10493
|
+
return 31 * 24 * 60;
|
|
10494
|
+
if (dayOfWeek !== "*")
|
|
10495
|
+
return 7 * 24 * 60;
|
|
10496
|
+
const everyHour = /^\*\/(\d+)$/.exec(hour ?? "");
|
|
10497
|
+
if (everyHour)
|
|
10498
|
+
return Math.max(1, Number(everyHour[1])) * 60;
|
|
10499
|
+
if (hour === "*") {
|
|
10500
|
+
const everyMinute = /^\*\/(\d+)$/.exec(minute ?? "");
|
|
10501
|
+
return everyMinute ? Math.max(1, Number(everyMinute[1])) : 60;
|
|
10370
10502
|
}
|
|
10503
|
+
return 24 * 60;
|
|
10371
10504
|
}
|
|
10372
|
-
function
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10505
|
+
function mostFrequentSchedule(schedules) {
|
|
10506
|
+
const enabled = schedules.map((s) => s.trim()).filter(Boolean);
|
|
10507
|
+
if (enabled.length === 0)
|
|
10508
|
+
return "";
|
|
10509
|
+
return enabled.sort((a, b) => cronIntervalScore(a) - cronIntervalScore(b))[0] ?? "";
|
|
10510
|
+
}
|
|
10511
|
+
function withoutBroadInterval(entry) {
|
|
10512
|
+
const { broad_interval_days: _broad, ...rest } = entry;
|
|
10513
|
+
return rest;
|
|
10514
|
+
}
|
|
10515
|
+
function reconcileV2TasksObject(rawConfig, dreamer, tasksObject) {
|
|
10516
|
+
const hasVerifyBroad = "verify-broad" in tasksObject;
|
|
10517
|
+
const hasBroadIntervalAnywhere = Object.values(tasksObject).some((v) => asObject(v) && ("broad_interval_days" in v));
|
|
10518
|
+
const hasStaleKeyFiles = "key-files" in tasksObject;
|
|
10519
|
+
if (hasVerifyBroad && !hasBroadIntervalAnywhere && !hasStaleKeyFiles)
|
|
10520
|
+
return rawConfig;
|
|
10521
|
+
const nextTasks = {};
|
|
10522
|
+
for (const [key, value] of Object.entries(tasksObject)) {
|
|
10523
|
+
if (key === "key-files")
|
|
10381
10524
|
continue;
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
}
|
|
10525
|
+
const obj = asObject(value);
|
|
10526
|
+
nextTasks[key] = obj ? withoutBroadInterval(obj) : value;
|
|
10385
10527
|
}
|
|
10386
|
-
|
|
10528
|
+
if (!hasVerifyBroad) {
|
|
10529
|
+
const verify = asObject(tasksObject.verify);
|
|
10530
|
+
const verifyEnabled = typeof verify?.schedule === "string" && verify.schedule.trim() !== "";
|
|
10531
|
+
nextTasks["verify-broad"] = {
|
|
10532
|
+
schedule: verifyEnabled ? DEFAULT_VERIFY_BROAD_CRON : ""
|
|
10533
|
+
};
|
|
10534
|
+
}
|
|
10535
|
+
return { ...rawConfig, dreamer: { ...dreamer, tasks: nextTasks } };
|
|
10387
10536
|
}
|
|
10388
|
-
function
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
}
|
|
10399
|
-
if (e?.type !== "message")
|
|
10400
|
-
continue;
|
|
10401
|
-
const m = e.message;
|
|
10402
|
-
if (m?.role !== "assistant")
|
|
10403
|
-
continue;
|
|
10404
|
-
if (typeof m.provider !== "string" || m.provider.length === 0 || typeof m.model !== "string" || m.model.length === 0) {
|
|
10405
|
-
continue;
|
|
10537
|
+
function migrateDreamerV2(rawConfig, warnings) {
|
|
10538
|
+
const dreamer = asObject(rawConfig.dreamer);
|
|
10539
|
+
if (!dreamer)
|
|
10540
|
+
return rawConfig;
|
|
10541
|
+
const tasksObject = asObject(dreamer.tasks);
|
|
10542
|
+
const hasRetiredObjectTasks = tasksObject ? RETIRED_OBJECT_MEMORY_TASKS.some((task) => (task in tasksObject)) : false;
|
|
10543
|
+
if (tasksObject && !hasRetiredObjectTasks) {
|
|
10544
|
+
const hasLegacyOutsideTasks = "schedule" in dreamer || "user_memories" in dreamer || "pin_key_files" in dreamer || "task_timeout_minutes" in dreamer || "max_runtime_minutes" in dreamer;
|
|
10545
|
+
if (!hasLegacyOutsideTasks) {
|
|
10546
|
+
return reconcileV2TasksObject(rawConfig, dreamer, tasksObject);
|
|
10406
10547
|
}
|
|
10407
|
-
return switchedAfterLastReply ? `${m.provider}/${m.model}` : findLastModelKeyFromBranch(entries);
|
|
10408
10548
|
}
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
|
|
10412
|
-
const
|
|
10413
|
-
const
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
const
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
|
|
10431
|
-
|
|
10432
|
-
|
|
10433
|
-
|
|
10434
|
-
|
|
10549
|
+
const hasLegacy = "schedule" in dreamer || Array.isArray(dreamer.tasks) || hasRetiredObjectTasks || "user_memories" in dreamer || "pin_key_files" in dreamer || "task_timeout_minutes" in dreamer || "max_runtime_minutes" in dreamer;
|
|
10550
|
+
if (!hasLegacy)
|
|
10551
|
+
return rawConfig;
|
|
10552
|
+
const baseCron = windowToCron(dreamer.schedule);
|
|
10553
|
+
const timeout = typeof dreamer.task_timeout_minutes === "number" ? dreamer.task_timeout_minutes : undefined;
|
|
10554
|
+
const withTimeout = (entry) => timeout !== undefined ? { ...entry, timeout_minutes: timeout } : entry;
|
|
10555
|
+
const classifySchedule = dreamer.disable === true ? "" : DEFAULT_CLASSIFY_CRON;
|
|
10556
|
+
const retrospectiveSchedule = dreamer.disable === true ? "" : DEFAULT_RETROSPECTIVE_CRON;
|
|
10557
|
+
const tasks = {};
|
|
10558
|
+
if (tasksObject) {
|
|
10559
|
+
for (const [key, value] of Object.entries(tasksObject)) {
|
|
10560
|
+
if (RETIRED_OBJECT_MEMORY_TASKS.includes(key))
|
|
10561
|
+
continue;
|
|
10562
|
+
if (asObject(value))
|
|
10563
|
+
tasks[key] = { ...value };
|
|
10564
|
+
}
|
|
10565
|
+
const maintainMemoryEntry = asObject(tasksObject["maintain-memory"]);
|
|
10566
|
+
if (maintainMemoryEntry) {
|
|
10567
|
+
const schedule = typeof maintainMemoryEntry.schedule === "string" ? maintainMemoryEntry.schedule : baseCron;
|
|
10568
|
+
tasks.verify = withTimeout({
|
|
10569
|
+
...withoutBroadInterval(maintainMemoryEntry),
|
|
10570
|
+
...tasks.verify ?? {},
|
|
10571
|
+
schedule: tasks.verify?.schedule ?? schedule
|
|
10572
|
+
});
|
|
10573
|
+
tasks.curate = withTimeout({
|
|
10574
|
+
...withoutBroadInterval(maintainMemoryEntry),
|
|
10575
|
+
...tasks.curate ?? {},
|
|
10576
|
+
schedule: tasks.curate?.schedule ?? schedule
|
|
10435
10577
|
});
|
|
10436
|
-
} catch {}
|
|
10437
|
-
return part;
|
|
10438
|
-
});
|
|
10439
|
-
}
|
|
10440
|
-
function* iterateEntriesToRawMessageRange(entries, afterOrdinal, limit, finalWatermark) {
|
|
10441
|
-
let emitted = 0;
|
|
10442
|
-
const normalizedAfter = Math.max(0, Math.floor(afterOrdinal));
|
|
10443
|
-
const normalizedLimit = Math.max(1, Math.floor(limit));
|
|
10444
|
-
const normalizedWatermark = Math.max(normalizedAfter, Math.floor(finalWatermark));
|
|
10445
|
-
let nextOrdinal = 1;
|
|
10446
|
-
let pendingToolResults = [];
|
|
10447
|
-
const buildToolParts = (results) => results.flatMap(({ msg, version }) => attachPiPartVersion(synthesizeToolResultParts(msg), version));
|
|
10448
|
-
let hasPendingToolParts = false;
|
|
10449
|
-
let pendingFirstRealId = "";
|
|
10450
|
-
let pendingFirstRealVersion = "";
|
|
10451
|
-
let pendingFirstCreatedAt = null;
|
|
10452
|
-
const appendMessage = function* (id, role, version, createdAt, parts) {
|
|
10453
|
-
const ordinal = nextOrdinal++;
|
|
10454
|
-
if (ordinal > normalizedAfter && ordinal <= normalizedWatermark) {
|
|
10455
|
-
emitted++;
|
|
10456
|
-
yield {
|
|
10457
|
-
ordinal,
|
|
10458
|
-
id,
|
|
10459
|
-
role,
|
|
10460
|
-
parts: parts(),
|
|
10461
|
-
version,
|
|
10462
|
-
...createdAt === null ? {} : { createdAt }
|
|
10463
|
-
};
|
|
10464
10578
|
}
|
|
10465
|
-
|
|
10466
|
-
|
|
10467
|
-
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
if (role === "toolResult") {
|
|
10473
|
-
const callId = msg.toolCallId;
|
|
10474
|
-
if (typeof callId !== "string" || callId.length === 0)
|
|
10475
|
-
continue;
|
|
10476
|
-
const version = rawEntryVersion(entry);
|
|
10477
|
-
hasPendingToolParts = true;
|
|
10478
|
-
pendingToolResults.push({ msg, version });
|
|
10479
|
-
if (pendingFirstRealId === "") {
|
|
10480
|
-
pendingFirstRealId = entry.id;
|
|
10481
|
-
pendingFirstRealVersion = version;
|
|
10482
|
-
pendingFirstCreatedAt = parsePiEntryTimestamp(entry);
|
|
10483
|
-
}
|
|
10484
|
-
continue;
|
|
10579
|
+
const oldVerifyEntry = asObject(tasksObject[OLD_VERIFY_TASK]);
|
|
10580
|
+
if (oldVerifyEntry) {
|
|
10581
|
+
tasks.verify = withTimeout({
|
|
10582
|
+
...withoutBroadInterval(oldVerifyEntry),
|
|
10583
|
+
...tasks.verify ?? {},
|
|
10584
|
+
schedule: tasks.verify?.schedule ?? (typeof oldVerifyEntry.schedule === "string" ? oldVerifyEntry.schedule : baseCron)
|
|
10585
|
+
});
|
|
10485
10586
|
}
|
|
10486
|
-
if (
|
|
10487
|
-
const
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
...attachPiPartVersion(synthesizeUserParts(msg), version)
|
|
10492
|
-
]);
|
|
10493
|
-
pendingToolResults = [];
|
|
10494
|
-
hasPendingToolParts = false;
|
|
10495
|
-
pendingFirstRealId = "";
|
|
10496
|
-
pendingFirstRealVersion = "";
|
|
10497
|
-
pendingFirstCreatedAt = null;
|
|
10498
|
-
if (done)
|
|
10499
|
-
break;
|
|
10500
|
-
continue;
|
|
10587
|
+
if (!tasks["verify-broad"]) {
|
|
10588
|
+
const verifyEnabled = typeof tasks.verify?.schedule === "string" && tasks.verify.schedule.trim() !== "";
|
|
10589
|
+
tasks["verify-broad"] = withTimeout({
|
|
10590
|
+
schedule: verifyEnabled ? DEFAULT_VERIFY_BROAD_CRON : ""
|
|
10591
|
+
});
|
|
10501
10592
|
}
|
|
10502
|
-
|
|
10503
|
-
|
|
10504
|
-
|
|
10505
|
-
|
|
10506
|
-
|
|
10507
|
-
|
|
10508
|
-
|
|
10509
|
-
hasPendingToolParts = false;
|
|
10510
|
-
pendingFirstRealId = "";
|
|
10511
|
-
pendingFirstRealVersion = "";
|
|
10512
|
-
pendingFirstCreatedAt = null;
|
|
10513
|
-
if (done)
|
|
10514
|
-
break;
|
|
10515
|
-
}
|
|
10516
|
-
const version = rawEntryVersion(entry);
|
|
10517
|
-
if (yield* appendMessage(entry.id, "assistant", version, parsePiEntryTimestamp(entry), () => attachPiPartVersion(synthesizeAssistantParts(msg), version))) {
|
|
10518
|
-
break;
|
|
10519
|
-
}
|
|
10520
|
-
continue;
|
|
10593
|
+
const oldCurateEntries = OLD_CURATE_TASKS.map((task) => asObject(tasksObject[task])).filter((entry) => Boolean(entry));
|
|
10594
|
+
if (oldCurateEntries.length > 0) {
|
|
10595
|
+
const oldSchedules = oldCurateEntries.map((entry) => typeof entry.schedule === "string" ? entry.schedule : baseCron);
|
|
10596
|
+
tasks.curate = withTimeout({
|
|
10597
|
+
...tasks.curate ?? {},
|
|
10598
|
+
schedule: mostFrequentSchedule(oldSchedules)
|
|
10599
|
+
});
|
|
10521
10600
|
}
|
|
10522
|
-
|
|
10523
|
-
|
|
10601
|
+
for (const task of CANONICAL) {
|
|
10602
|
+
if (!tasks[task]) {
|
|
10603
|
+
const schedule = task === "verify" || task === "curate" || task === "verify-broad" ? "" : task === "classify-memories" ? classifySchedule : task === "retrospective" ? retrospectiveSchedule : task === "maintain-docs" ? "" : baseCron;
|
|
10604
|
+
tasks[task] = withTimeout({ schedule });
|
|
10605
|
+
}
|
|
10524
10606
|
}
|
|
10607
|
+
} else {
|
|
10608
|
+
const legacyArray = Array.isArray(dreamer.tasks) ? dreamer.tasks.filter((t) => typeof t === "string") : null;
|
|
10609
|
+
const verifySelected = legacyArray ? legacyArray.includes(OLD_VERIFY_TASK) : true;
|
|
10610
|
+
const curateSelected = legacyArray ? legacyArray.some((task) => OLD_CURATE_TASKS.includes(task)) : true;
|
|
10611
|
+
tasks.verify = withTimeout({
|
|
10612
|
+
schedule: verifySelected ? baseCron : ""
|
|
10613
|
+
});
|
|
10614
|
+
tasks["verify-broad"] = withTimeout({
|
|
10615
|
+
schedule: verifySelected ? DEFAULT_VERIFY_BROAD_CRON : ""
|
|
10616
|
+
});
|
|
10617
|
+
tasks.curate = withTimeout({
|
|
10618
|
+
schedule: curateSelected ? baseCron : ""
|
|
10619
|
+
});
|
|
10620
|
+
tasks["classify-memories"] = withTimeout({
|
|
10621
|
+
schedule: classifySchedule
|
|
10622
|
+
});
|
|
10623
|
+
tasks.retrospective = withTimeout({
|
|
10624
|
+
schedule: retrospectiveSchedule
|
|
10625
|
+
});
|
|
10626
|
+
tasks["maintain-docs"] = withTimeout({
|
|
10627
|
+
schedule: legacyArray?.includes("maintain-docs") ? baseCron : ""
|
|
10628
|
+
});
|
|
10525
10629
|
}
|
|
10526
|
-
|
|
10527
|
-
|
|
10528
|
-
|
|
10529
|
-
|
|
10530
|
-
|
|
10531
|
-
|
|
10532
|
-
|
|
10533
|
-
|
|
10534
|
-
}
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
if (v.message === null || typeof v.message !== "object")
|
|
10549
|
-
return false;
|
|
10550
|
-
return true;
|
|
10630
|
+
tasks["map-memories"] ??= withTimeout({ schedule: baseCron });
|
|
10631
|
+
tasks["evaluate-smart-notes"] ??= withTimeout({ schedule: baseCron });
|
|
10632
|
+
const um = asObject(dreamer.user_memories);
|
|
10633
|
+
const umEnabled = um ? um.enabled !== false : true;
|
|
10634
|
+
if (um || !tasks["review-user-memories"]) {
|
|
10635
|
+
tasks["review-user-memories"] = withTimeout({
|
|
10636
|
+
...tasks["review-user-memories"] ?? {},
|
|
10637
|
+
schedule: umEnabled ? baseCron : "",
|
|
10638
|
+
...um && typeof um.promotion_threshold === "number" ? { promotion_threshold: um.promotion_threshold } : {}
|
|
10639
|
+
});
|
|
10640
|
+
}
|
|
10641
|
+
const {
|
|
10642
|
+
schedule: _schedule,
|
|
10643
|
+
tasks: _tasks,
|
|
10644
|
+
task_timeout_minutes: _tto,
|
|
10645
|
+
max_runtime_minutes: _max,
|
|
10646
|
+
user_memories: _um,
|
|
10647
|
+
pin_key_files: _pkf,
|
|
10648
|
+
...rest
|
|
10649
|
+
} = dreamer;
|
|
10650
|
+
warnings.push('Migrated legacy dreamer scheduling (schedule window / tasks array / user_memories / pin_key_files) → per-task "dreamer.tasks" in-memory (run `doctor` to persist).');
|
|
10651
|
+
return { ...rawConfig, dreamer: { ...rest, tasks } };
|
|
10551
10652
|
}
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
|
|
10555
|
-
|
|
10556
|
-
|
|
10557
|
-
return
|
|
10653
|
+
|
|
10654
|
+
// ../plugin/src/config/migrate-experimental.ts
|
|
10655
|
+
function migrateLegacyExperimental(rawConfig, warnings) {
|
|
10656
|
+
const experimental = rawConfig.experimental;
|
|
10657
|
+
if (typeof experimental !== "object" || experimental === null) {
|
|
10658
|
+
return rawConfig;
|
|
10558
10659
|
}
|
|
10559
|
-
|
|
10560
|
-
|
|
10561
|
-
const
|
|
10562
|
-
|
|
10563
|
-
|
|
10564
|
-
|
|
10565
|
-
|
|
10566
|
-
|
|
10567
|
-
|
|
10568
|
-
}
|
|
10660
|
+
const exp = experimental;
|
|
10661
|
+
const hasUM = "user_memories" in exp;
|
|
10662
|
+
const hasPKF = "pin_key_files" in exp;
|
|
10663
|
+
const hasMural = "mural" in exp;
|
|
10664
|
+
const TOP_LEVEL_GRADUATED = ["temporal_awareness", "caveman_text_compression"];
|
|
10665
|
+
const MEMORY_GRADUATED = ["auto_search", "git_commit_indexing"];
|
|
10666
|
+
const hasGraduated = TOP_LEVEL_GRADUATED.some((k) => (k in exp)) || MEMORY_GRADUATED.some((k) => (k in exp)) || hasMural;
|
|
10667
|
+
if (!hasUM && !hasPKF && !hasGraduated) {
|
|
10668
|
+
return rawConfig;
|
|
10569
10669
|
}
|
|
10570
|
-
|
|
10571
|
-
}
|
|
10572
|
-
|
|
10573
|
-
const
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
if (
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10670
|
+
const patched = { ...rawConfig };
|
|
10671
|
+
const dreamer = typeof patched.dreamer === "object" && patched.dreamer !== null ? { ...patched.dreamer } : {};
|
|
10672
|
+
const memory = typeof patched.memory === "object" && patched.memory !== null ? { ...patched.memory } : {};
|
|
10673
|
+
const newExperimental = { ...exp };
|
|
10674
|
+
const coerceToObject = (value) => {
|
|
10675
|
+
if (typeof value === "boolean") {
|
|
10676
|
+
return { enabled: value };
|
|
10677
|
+
}
|
|
10678
|
+
if (typeof value === "object" && value !== null) {
|
|
10679
|
+
return { ...value };
|
|
10680
|
+
}
|
|
10681
|
+
return;
|
|
10682
|
+
};
|
|
10683
|
+
const relocate = (key, dest, destLabel) => {
|
|
10684
|
+
if (!(key in exp))
|
|
10685
|
+
return;
|
|
10686
|
+
const oldValue = exp[key];
|
|
10687
|
+
const existing = dest[key];
|
|
10688
|
+
if (existing === undefined) {
|
|
10689
|
+
dest[key] = oldValue;
|
|
10690
|
+
warnings.push(`Migrated "experimental.${key}" → "${destLabel}${key}" in-memory (run \`doctor\` to persist).`);
|
|
10691
|
+
} else if (typeof oldValue === "object" && oldValue !== null && typeof existing === "object" && existing !== null) {
|
|
10692
|
+
dest[key] = {
|
|
10693
|
+
...oldValue,
|
|
10694
|
+
...existing
|
|
10695
|
+
};
|
|
10696
|
+
}
|
|
10697
|
+
delete newExperimental[key];
|
|
10698
|
+
};
|
|
10699
|
+
for (const key of TOP_LEVEL_GRADUATED)
|
|
10700
|
+
relocate(key, patched, "");
|
|
10701
|
+
for (const key of MEMORY_GRADUATED)
|
|
10702
|
+
relocate(key, memory, "memory.");
|
|
10703
|
+
if (hasMural) {
|
|
10704
|
+
const oldMural = coerceToObject(exp.mural);
|
|
10705
|
+
const existingMural = patched.mural;
|
|
10706
|
+
if (existingMural === undefined) {
|
|
10707
|
+
patched.mural = oldMural ?? exp.mural;
|
|
10708
|
+
warnings.push('Deprecated "experimental.mural"; use top-level "mural" instead (migrated in memory; run `doctor` to persist).');
|
|
10709
|
+
} else if (oldMural !== undefined && typeof existingMural === "object" && existingMural !== null && !Array.isArray(existingMural)) {
|
|
10710
|
+
patched.mural = {
|
|
10711
|
+
...oldMural,
|
|
10712
|
+
...existingMural
|
|
10713
|
+
};
|
|
10592
10714
|
}
|
|
10715
|
+
delete newExperimental.mural;
|
|
10593
10716
|
}
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
for (const c of m.content) {
|
|
10606
|
-
if (c === null || typeof c !== "object")
|
|
10607
|
-
continue;
|
|
10608
|
-
const cc = c;
|
|
10609
|
-
if (cc.type === "text" && typeof cc.text === "string") {
|
|
10610
|
-
fragments.push(cc.text);
|
|
10717
|
+
if (hasUM) {
|
|
10718
|
+
const oldUM = coerceToObject(exp.user_memories);
|
|
10719
|
+
if (oldUM !== undefined) {
|
|
10720
|
+
if (dreamer.user_memories === undefined) {
|
|
10721
|
+
dreamer.user_memories = oldUM;
|
|
10722
|
+
warnings.push('Migrated "experimental.user_memories" → "dreamer.user_memories" in-memory (run `doctor` to persist).');
|
|
10723
|
+
} else if (typeof dreamer.user_memories === "object" && dreamer.user_memories !== null) {
|
|
10724
|
+
dreamer.user_memories = {
|
|
10725
|
+
...oldUM,
|
|
10726
|
+
...dreamer.user_memories
|
|
10727
|
+
};
|
|
10611
10728
|
}
|
|
10612
10729
|
}
|
|
10613
|
-
|
|
10614
|
-
`);
|
|
10730
|
+
delete newExperimental.user_memories;
|
|
10615
10731
|
}
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10732
|
+
if (hasPKF) {
|
|
10733
|
+
const oldPKF = coerceToObject(exp.pin_key_files);
|
|
10734
|
+
if (oldPKF !== undefined) {
|
|
10735
|
+
if (dreamer.pin_key_files === undefined) {
|
|
10736
|
+
dreamer.pin_key_files = oldPKF;
|
|
10737
|
+
warnings.push('Migrated "experimental.pin_key_files" → "dreamer.pin_key_files" in-memory (run `doctor` to persist).');
|
|
10738
|
+
} else if (typeof dreamer.pin_key_files === "object" && dreamer.pin_key_files !== null) {
|
|
10739
|
+
dreamer.pin_key_files = {
|
|
10740
|
+
...oldPKF,
|
|
10741
|
+
...dreamer.pin_key_files
|
|
10742
|
+
};
|
|
10743
|
+
} else if (typeof dreamer.pin_key_files === "boolean") {
|
|
10744
|
+
dreamer.pin_key_files = { ...oldPKF, enabled: dreamer.pin_key_files };
|
|
10623
10745
|
}
|
|
10624
10746
|
}
|
|
10625
|
-
|
|
10626
|
-
}
|
|
10627
|
-
function countPiRawMessages(entries) {
|
|
10628
|
-
let count = 0;
|
|
10629
|
-
let pendingTools = false;
|
|
10630
|
-
for (const entry of entries) {
|
|
10631
|
-
if (!isMessageEntry(entry))
|
|
10632
|
-
continue;
|
|
10633
|
-
const message = entry.message;
|
|
10634
|
-
if (message.role === "toolResult") {
|
|
10635
|
-
if (typeof message.toolCallId === "string" && message.toolCallId.length > 0)
|
|
10636
|
-
pendingTools = true;
|
|
10637
|
-
continue;
|
|
10638
|
-
}
|
|
10639
|
-
if (message.role === "user")
|
|
10640
|
-
pendingTools = false;
|
|
10641
|
-
else if (message.role === "assistant" && pendingTools) {
|
|
10642
|
-
count++;
|
|
10643
|
-
pendingTools = false;
|
|
10644
|
-
}
|
|
10645
|
-
count++;
|
|
10747
|
+
delete newExperimental.pin_key_files;
|
|
10646
10748
|
}
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
function isPlainObject2(value) {
|
|
10652
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10653
|
-
}
|
|
10654
|
-
function pruneNestedConfigLeaf(block, relativePath) {
|
|
10655
|
-
if (relativePath.length === 0)
|
|
10656
|
-
return null;
|
|
10657
|
-
const result = { ...block };
|
|
10658
|
-
let cursor = result;
|
|
10659
|
-
for (let i = 0;i < relativePath.length - 1; i++) {
|
|
10660
|
-
const seg = String(relativePath[i]);
|
|
10661
|
-
const child = cursor[seg];
|
|
10662
|
-
if (!isPlainObject2(child)) {
|
|
10663
|
-
if (!(seg in cursor))
|
|
10664
|
-
return null;
|
|
10665
|
-
delete cursor[seg];
|
|
10666
|
-
return {
|
|
10667
|
-
block: result,
|
|
10668
|
-
removed: relativePath.slice(0, i + 1).map(String).join(".")
|
|
10669
|
-
};
|
|
10670
|
-
}
|
|
10671
|
-
const clonedChild = { ...child };
|
|
10672
|
-
cursor[seg] = clonedChild;
|
|
10673
|
-
cursor = clonedChild;
|
|
10749
|
+
patched.experimental = newExperimental;
|
|
10750
|
+
patched.dreamer = dreamer;
|
|
10751
|
+
if (Object.keys(memory).length > 0) {
|
|
10752
|
+
patched.memory = memory;
|
|
10674
10753
|
}
|
|
10675
|
-
|
|
10676
|
-
if (!(leaf in cursor))
|
|
10677
|
-
return null;
|
|
10678
|
-
delete cursor[leaf];
|
|
10679
|
-
return { block: result, removed: relativePath.map(String).join(".") };
|
|
10754
|
+
return patched;
|
|
10680
10755
|
}
|
|
10681
10756
|
|
|
10682
|
-
// src/config/
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
var RETIRED_OBJECT_MEMORY_TASKS = ["maintain-memory", ...OLD_CURATE_TASKS];
|
|
10689
|
-
var CANONICAL = [
|
|
10690
|
-
"map-memories",
|
|
10691
|
-
"verify",
|
|
10692
|
-
"verify-broad",
|
|
10693
|
-
"curate",
|
|
10694
|
-
"classify-memories",
|
|
10695
|
-
"retrospective",
|
|
10696
|
-
"maintain-docs",
|
|
10697
|
-
"evaluate-smart-notes",
|
|
10698
|
-
"review-user-memories",
|
|
10699
|
-
"promote-primers",
|
|
10700
|
-
"refresh-primers"
|
|
10701
|
-
];
|
|
10702
|
-
var DEFAULT_BASE_CRON = "0 2 * * *";
|
|
10703
|
-
var DEFAULT_CLASSIFY_CRON = "0 6 * * *";
|
|
10704
|
-
var DEFAULT_RETROSPECTIVE_CRON = "0 5 * * *";
|
|
10705
|
-
var DEFAULT_VERIFY_BROAD_CRON = "0 4 * * 0";
|
|
10706
|
-
function windowToCron(schedule) {
|
|
10707
|
-
if (typeof schedule !== "string")
|
|
10708
|
-
return DEFAULT_BASE_CRON;
|
|
10709
|
-
const m = /^(\d{1,2}):(\d{2})\s*-/.exec(schedule.trim());
|
|
10710
|
-
if (!m)
|
|
10711
|
-
return DEFAULT_BASE_CRON;
|
|
10712
|
-
const hour = Number(m[1]);
|
|
10713
|
-
const minute = Number(m[2]);
|
|
10714
|
-
if (hour >= 24 || minute >= 60)
|
|
10715
|
-
return DEFAULT_BASE_CRON;
|
|
10716
|
-
return `${minute} ${hour} * * *`;
|
|
10717
|
-
}
|
|
10718
|
-
function asObject(value) {
|
|
10719
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
10720
|
-
}
|
|
10721
|
-
function cronIntervalScore(schedule) {
|
|
10722
|
-
const parts = schedule.trim().split(/\s+/);
|
|
10723
|
-
if (parts.length !== 5)
|
|
10724
|
-
return Number.POSITIVE_INFINITY;
|
|
10725
|
-
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
|
|
10726
|
-
if (month !== "*")
|
|
10727
|
-
return 366 * 24 * 60;
|
|
10728
|
-
if (dayOfMonth !== "*")
|
|
10729
|
-
return 31 * 24 * 60;
|
|
10730
|
-
if (dayOfWeek !== "*")
|
|
10731
|
-
return 7 * 24 * 60;
|
|
10732
|
-
const everyHour = /^\*\/(\d+)$/.exec(hour ?? "");
|
|
10733
|
-
if (everyHour)
|
|
10734
|
-
return Math.max(1, Number(everyHour[1])) * 60;
|
|
10735
|
-
if (hour === "*") {
|
|
10736
|
-
const everyMinute = /^\*\/(\d+)$/.exec(minute ?? "");
|
|
10737
|
-
return everyMinute ? Math.max(1, Number(everyMinute[1])) : 60;
|
|
10738
|
-
}
|
|
10739
|
-
return 24 * 60;
|
|
10740
|
-
}
|
|
10741
|
-
function mostFrequentSchedule(schedules) {
|
|
10742
|
-
const enabled = schedules.map((s) => s.trim()).filter(Boolean);
|
|
10743
|
-
if (enabled.length === 0)
|
|
10744
|
-
return "";
|
|
10745
|
-
return enabled.sort((a, b) => cronIntervalScore(a) - cronIntervalScore(b))[0] ?? "";
|
|
10757
|
+
// ../plugin/src/config/profiles.ts
|
|
10758
|
+
function withoutProfileFields(raw) {
|
|
10759
|
+
const copy = { ...raw };
|
|
10760
|
+
delete copy.profile;
|
|
10761
|
+
delete copy.profiles;
|
|
10762
|
+
return copy;
|
|
10746
10763
|
}
|
|
10747
|
-
function
|
|
10748
|
-
|
|
10749
|
-
|
|
10764
|
+
function readProfileSelection(raw) {
|
|
10765
|
+
if (!Object.hasOwn(raw, "profile"))
|
|
10766
|
+
return { declared: false };
|
|
10767
|
+
const value = raw.profile;
|
|
10768
|
+
if (typeof value !== "string")
|
|
10769
|
+
return { declared: true };
|
|
10770
|
+
const name = value.trim();
|
|
10771
|
+
return name.length > 0 ? { declared: true, name } : { declared: true };
|
|
10750
10772
|
}
|
|
10751
|
-
function
|
|
10752
|
-
const
|
|
10753
|
-
const
|
|
10754
|
-
const
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
for (const [key, value] of Object.entries(tasksObject)) {
|
|
10759
|
-
if (key === "key-files")
|
|
10760
|
-
continue;
|
|
10761
|
-
const obj = asObject(value);
|
|
10762
|
-
nextTasks[key] = obj ? withoutBroadInterval(obj) : value;
|
|
10773
|
+
function resolveConfigProfile(args) {
|
|
10774
|
+
const warnings = [];
|
|
10775
|
+
const userSelection = readProfileSelection(args.userRaw);
|
|
10776
|
+
const projectSelection = readProfileSelection(args.projectRaw);
|
|
10777
|
+
const selection = projectSelection.name ? { name: projectSelection.name, source: "project" } : userSelection.name ? { name: userSelection.name, source: "user" } : undefined;
|
|
10778
|
+
if (projectSelection.declared && !projectSelection.name) {
|
|
10779
|
+
warnings.push("Ignoring invalid profile selection from project config; expected a non-empty string.");
|
|
10763
10780
|
}
|
|
10764
|
-
if (!
|
|
10765
|
-
|
|
10766
|
-
const verifyEnabled = typeof verify?.schedule === "string" && verify.schedule.trim() !== "";
|
|
10767
|
-
nextTasks["verify-broad"] = {
|
|
10768
|
-
schedule: verifyEnabled ? DEFAULT_VERIFY_BROAD_CRON : ""
|
|
10769
|
-
};
|
|
10781
|
+
if (!projectSelection.declared && userSelection.declared && !userSelection.name) {
|
|
10782
|
+
warnings.push("Ignoring invalid profile selection from user config; expected a non-empty string.");
|
|
10770
10783
|
}
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
const hasRetiredObjectTasks = tasksObject ? RETIRED_OBJECT_MEMORY_TASKS.some((task) => (task in tasksObject)) : false;
|
|
10779
|
-
if (tasksObject && !hasRetiredObjectTasks) {
|
|
10780
|
-
const hasLegacyOutsideTasks = "schedule" in dreamer || "user_memories" in dreamer || "pin_key_files" in dreamer || "task_timeout_minutes" in dreamer || "max_runtime_minutes" in dreamer;
|
|
10781
|
-
if (!hasLegacyOutsideTasks) {
|
|
10782
|
-
return reconcileV2TasksObject(rawConfig, dreamer, tasksObject);
|
|
10784
|
+
let profiles = {};
|
|
10785
|
+
if (Object.hasOwn(args.userRaw, "profiles")) {
|
|
10786
|
+
const parsed = ConfigProfilesSchema.safeParse(args.userRaw.profiles);
|
|
10787
|
+
if (parsed.success) {
|
|
10788
|
+
profiles = parsed.data;
|
|
10789
|
+
} else {
|
|
10790
|
+
warnings.push("Ignoring profiles from user config: invalid profile configuration; profiles may contain only historian/dreamer harness model blocks.");
|
|
10783
10791
|
}
|
|
10784
10792
|
}
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
const retrospectiveSchedule = dreamer.disable === true ? "" : DEFAULT_RETROSPECTIVE_CRON;
|
|
10793
|
-
const tasks = {};
|
|
10794
|
-
if (tasksObject) {
|
|
10795
|
-
for (const [key, value] of Object.entries(tasksObject)) {
|
|
10796
|
-
if (RETIRED_OBJECT_MEMORY_TASKS.includes(key))
|
|
10797
|
-
continue;
|
|
10798
|
-
if (asObject(value))
|
|
10799
|
-
tasks[key] = { ...value };
|
|
10800
|
-
}
|
|
10801
|
-
const maintainMemoryEntry = asObject(tasksObject["maintain-memory"]);
|
|
10802
|
-
if (maintainMemoryEntry) {
|
|
10803
|
-
const schedule = typeof maintainMemoryEntry.schedule === "string" ? maintainMemoryEntry.schedule : baseCron;
|
|
10804
|
-
tasks.verify = withTimeout({
|
|
10805
|
-
...withoutBroadInterval(maintainMemoryEntry),
|
|
10806
|
-
...tasks.verify ?? {},
|
|
10807
|
-
schedule: tasks.verify?.schedule ?? schedule
|
|
10808
|
-
});
|
|
10809
|
-
tasks.curate = withTimeout({
|
|
10810
|
-
...withoutBroadInterval(maintainMemoryEntry),
|
|
10811
|
-
...tasks.curate ?? {},
|
|
10812
|
-
schedule: tasks.curate?.schedule ?? schedule
|
|
10813
|
-
});
|
|
10814
|
-
}
|
|
10815
|
-
const oldVerifyEntry = asObject(tasksObject[OLD_VERIFY_TASK]);
|
|
10816
|
-
if (oldVerifyEntry) {
|
|
10817
|
-
tasks.verify = withTimeout({
|
|
10818
|
-
...withoutBroadInterval(oldVerifyEntry),
|
|
10819
|
-
...tasks.verify ?? {},
|
|
10820
|
-
schedule: tasks.verify?.schedule ?? (typeof oldVerifyEntry.schedule === "string" ? oldVerifyEntry.schedule : baseCron)
|
|
10821
|
-
});
|
|
10822
|
-
}
|
|
10823
|
-
if (!tasks["verify-broad"]) {
|
|
10824
|
-
const verifyEnabled = typeof tasks.verify?.schedule === "string" && tasks.verify.schedule.trim() !== "";
|
|
10825
|
-
tasks["verify-broad"] = withTimeout({
|
|
10826
|
-
schedule: verifyEnabled ? DEFAULT_VERIFY_BROAD_CRON : ""
|
|
10827
|
-
});
|
|
10828
|
-
}
|
|
10829
|
-
const oldCurateEntries = OLD_CURATE_TASKS.map((task) => asObject(tasksObject[task])).filter((entry) => Boolean(entry));
|
|
10830
|
-
if (oldCurateEntries.length > 0) {
|
|
10831
|
-
const oldSchedules = oldCurateEntries.map((entry) => typeof entry.schedule === "string" ? entry.schedule : baseCron);
|
|
10832
|
-
tasks.curate = withTimeout({
|
|
10833
|
-
...tasks.curate ?? {},
|
|
10834
|
-
schedule: mostFrequentSchedule(oldSchedules)
|
|
10835
|
-
});
|
|
10836
|
-
}
|
|
10837
|
-
for (const task of CANONICAL) {
|
|
10838
|
-
if (!tasks[task]) {
|
|
10839
|
-
const schedule = task === "verify" || task === "curate" || task === "verify-broad" ? "" : task === "classify-memories" ? classifySchedule : task === "retrospective" ? retrospectiveSchedule : task === "maintain-docs" ? "" : baseCron;
|
|
10840
|
-
tasks[task] = withTimeout({ schedule });
|
|
10841
|
-
}
|
|
10842
|
-
}
|
|
10843
|
-
} else {
|
|
10844
|
-
const legacyArray = Array.isArray(dreamer.tasks) ? dreamer.tasks.filter((t) => typeof t === "string") : null;
|
|
10845
|
-
const verifySelected = legacyArray ? legacyArray.includes(OLD_VERIFY_TASK) : true;
|
|
10846
|
-
const curateSelected = legacyArray ? legacyArray.some((task) => OLD_CURATE_TASKS.includes(task)) : true;
|
|
10847
|
-
tasks.verify = withTimeout({
|
|
10848
|
-
schedule: verifySelected ? baseCron : ""
|
|
10849
|
-
});
|
|
10850
|
-
tasks["verify-broad"] = withTimeout({
|
|
10851
|
-
schedule: verifySelected ? DEFAULT_VERIFY_BROAD_CRON : ""
|
|
10852
|
-
});
|
|
10853
|
-
tasks.curate = withTimeout({
|
|
10854
|
-
schedule: curateSelected ? baseCron : ""
|
|
10855
|
-
});
|
|
10856
|
-
tasks["classify-memories"] = withTimeout({
|
|
10857
|
-
schedule: classifySchedule
|
|
10858
|
-
});
|
|
10859
|
-
tasks.retrospective = withTimeout({
|
|
10860
|
-
schedule: retrospectiveSchedule
|
|
10861
|
-
});
|
|
10862
|
-
tasks["maintain-docs"] = withTimeout({
|
|
10863
|
-
schedule: legacyArray?.includes("maintain-docs") ? baseCron : ""
|
|
10864
|
-
});
|
|
10793
|
+
if (!selection) {
|
|
10794
|
+
return {
|
|
10795
|
+
userBase: withoutProfileFields(args.userRaw),
|
|
10796
|
+
projectBase: withoutProfileFields(args.projectRaw),
|
|
10797
|
+
overlay: {},
|
|
10798
|
+
warnings
|
|
10799
|
+
};
|
|
10865
10800
|
}
|
|
10866
|
-
|
|
10867
|
-
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
...um && typeof um.promotion_threshold === "number" ? { promotion_threshold: um.promotion_threshold } : {}
|
|
10875
|
-
});
|
|
10801
|
+
if (!Object.hasOwn(profiles, selection.name)) {
|
|
10802
|
+
warnings.push(`Unknown profile "${selection.name}" selected by ${selection.source} config; using base config without a profile.`);
|
|
10803
|
+
return {
|
|
10804
|
+
userBase: withoutProfileFields(args.userRaw),
|
|
10805
|
+
projectBase: withoutProfileFields(args.projectRaw),
|
|
10806
|
+
overlay: {},
|
|
10807
|
+
warnings
|
|
10808
|
+
};
|
|
10876
10809
|
}
|
|
10877
|
-
const
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
} = dreamer;
|
|
10886
|
-
warnings.push('Migrated legacy dreamer scheduling (schedule window / tasks array / user_memories / pin_key_files) → per-task "dreamer.tasks" in-memory (run `doctor` to persist).');
|
|
10887
|
-
return { ...rawConfig, dreamer: { ...rest, tasks } };
|
|
10888
|
-
}
|
|
10889
|
-
|
|
10890
|
-
// ../plugin/src/config/migrate-experimental.ts
|
|
10891
|
-
function migrateLegacyExperimental(rawConfig, warnings) {
|
|
10892
|
-
const experimental = rawConfig.experimental;
|
|
10893
|
-
if (typeof experimental !== "object" || experimental === null) {
|
|
10894
|
-
return rawConfig;
|
|
10895
|
-
}
|
|
10896
|
-
const exp = experimental;
|
|
10897
|
-
const hasUM = "user_memories" in exp;
|
|
10898
|
-
const hasPKF = "pin_key_files" in exp;
|
|
10899
|
-
const hasMural = "mural" in exp;
|
|
10900
|
-
const TOP_LEVEL_GRADUATED = ["temporal_awareness", "caveman_text_compression"];
|
|
10901
|
-
const MEMORY_GRADUATED = ["auto_search", "git_commit_indexing"];
|
|
10902
|
-
const hasGraduated = TOP_LEVEL_GRADUATED.some((k) => (k in exp)) || MEMORY_GRADUATED.some((k) => (k in exp)) || hasMural;
|
|
10903
|
-
if (!hasUM && !hasPKF && !hasGraduated) {
|
|
10904
|
-
return rawConfig;
|
|
10905
|
-
}
|
|
10906
|
-
const patched = { ...rawConfig };
|
|
10907
|
-
const dreamer = typeof patched.dreamer === "object" && patched.dreamer !== null ? { ...patched.dreamer } : {};
|
|
10908
|
-
const memory = typeof patched.memory === "object" && patched.memory !== null ? { ...patched.memory } : {};
|
|
10909
|
-
const newExperimental = { ...exp };
|
|
10910
|
-
const coerceToObject = (value) => {
|
|
10911
|
-
if (typeof value === "boolean") {
|
|
10912
|
-
return { enabled: value };
|
|
10913
|
-
}
|
|
10914
|
-
if (typeof value === "object" && value !== null) {
|
|
10915
|
-
return { ...value };
|
|
10916
|
-
}
|
|
10917
|
-
return;
|
|
10918
|
-
};
|
|
10919
|
-
const relocate = (key, dest, destLabel) => {
|
|
10920
|
-
if (!(key in exp))
|
|
10921
|
-
return;
|
|
10922
|
-
const oldValue = exp[key];
|
|
10923
|
-
const existing = dest[key];
|
|
10924
|
-
if (existing === undefined) {
|
|
10925
|
-
dest[key] = oldValue;
|
|
10926
|
-
warnings.push(`Migrated "experimental.${key}" → "${destLabel}${key}" in-memory (run \`doctor\` to persist).`);
|
|
10927
|
-
} else if (typeof oldValue === "object" && oldValue !== null && typeof existing === "object" && existing !== null) {
|
|
10928
|
-
dest[key] = {
|
|
10929
|
-
...oldValue,
|
|
10930
|
-
...existing
|
|
10931
|
-
};
|
|
10932
|
-
}
|
|
10933
|
-
delete newExperimental[key];
|
|
10934
|
-
};
|
|
10935
|
-
for (const key of TOP_LEVEL_GRADUATED)
|
|
10936
|
-
relocate(key, patched, "");
|
|
10937
|
-
for (const key of MEMORY_GRADUATED)
|
|
10938
|
-
relocate(key, memory, "memory.");
|
|
10939
|
-
if (hasMural) {
|
|
10940
|
-
const oldMural = coerceToObject(exp.mural);
|
|
10941
|
-
const existingMural = patched.mural;
|
|
10942
|
-
if (existingMural === undefined) {
|
|
10943
|
-
patched.mural = oldMural ?? exp.mural;
|
|
10944
|
-
warnings.push('Deprecated "experimental.mural"; use top-level "mural" instead (migrated in memory; run `doctor` to persist).');
|
|
10945
|
-
} else if (oldMural !== undefined && typeof existingMural === "object" && existingMural !== null && !Array.isArray(existingMural)) {
|
|
10946
|
-
patched.mural = {
|
|
10947
|
-
...oldMural,
|
|
10948
|
-
...existingMural
|
|
10949
|
-
};
|
|
10950
|
-
}
|
|
10951
|
-
delete newExperimental.mural;
|
|
10952
|
-
}
|
|
10953
|
-
if (hasUM) {
|
|
10954
|
-
const oldUM = coerceToObject(exp.user_memories);
|
|
10955
|
-
if (oldUM !== undefined) {
|
|
10956
|
-
if (dreamer.user_memories === undefined) {
|
|
10957
|
-
dreamer.user_memories = oldUM;
|
|
10958
|
-
warnings.push('Migrated "experimental.user_memories" → "dreamer.user_memories" in-memory (run `doctor` to persist).');
|
|
10959
|
-
} else if (typeof dreamer.user_memories === "object" && dreamer.user_memories !== null) {
|
|
10960
|
-
dreamer.user_memories = {
|
|
10961
|
-
...oldUM,
|
|
10962
|
-
...dreamer.user_memories
|
|
10963
|
-
};
|
|
10964
|
-
}
|
|
10965
|
-
}
|
|
10966
|
-
delete newExperimental.user_memories;
|
|
10967
|
-
}
|
|
10968
|
-
if (hasPKF) {
|
|
10969
|
-
const oldPKF = coerceToObject(exp.pin_key_files);
|
|
10970
|
-
if (oldPKF !== undefined) {
|
|
10971
|
-
if (dreamer.pin_key_files === undefined) {
|
|
10972
|
-
dreamer.pin_key_files = oldPKF;
|
|
10973
|
-
warnings.push('Migrated "experimental.pin_key_files" → "dreamer.pin_key_files" in-memory (run `doctor` to persist).');
|
|
10974
|
-
} else if (typeof dreamer.pin_key_files === "object" && dreamer.pin_key_files !== null) {
|
|
10975
|
-
dreamer.pin_key_files = {
|
|
10976
|
-
...oldPKF,
|
|
10977
|
-
...dreamer.pin_key_files
|
|
10978
|
-
};
|
|
10979
|
-
} else if (typeof dreamer.pin_key_files === "boolean") {
|
|
10980
|
-
dreamer.pin_key_files = { ...oldPKF, enabled: dreamer.pin_key_files };
|
|
10981
|
-
}
|
|
10982
|
-
}
|
|
10983
|
-
delete newExperimental.pin_key_files;
|
|
10984
|
-
}
|
|
10985
|
-
patched.experimental = newExperimental;
|
|
10986
|
-
patched.dreamer = dreamer;
|
|
10987
|
-
if (Object.keys(memory).length > 0) {
|
|
10988
|
-
patched.memory = memory;
|
|
10989
|
-
}
|
|
10990
|
-
return patched;
|
|
10991
|
-
}
|
|
10992
|
-
|
|
10993
|
-
// ../plugin/src/config/profiles.ts
|
|
10994
|
-
function withoutProfileFields(raw) {
|
|
10995
|
-
const copy = { ...raw };
|
|
10996
|
-
delete copy.profile;
|
|
10997
|
-
delete copy.profiles;
|
|
10998
|
-
return copy;
|
|
10999
|
-
}
|
|
11000
|
-
function readProfileSelection(raw) {
|
|
11001
|
-
if (!Object.hasOwn(raw, "profile"))
|
|
11002
|
-
return { declared: false };
|
|
11003
|
-
const value = raw.profile;
|
|
11004
|
-
if (typeof value !== "string")
|
|
11005
|
-
return { declared: true };
|
|
11006
|
-
const name = value.trim();
|
|
11007
|
-
return name.length > 0 ? { declared: true, name } : { declared: true };
|
|
11008
|
-
}
|
|
11009
|
-
function resolveConfigProfile(args) {
|
|
11010
|
-
const warnings = [];
|
|
11011
|
-
const userSelection = readProfileSelection(args.userRaw);
|
|
11012
|
-
const projectSelection = readProfileSelection(args.projectRaw);
|
|
11013
|
-
const selection = projectSelection.name ? { name: projectSelection.name, source: "project" } : userSelection.name ? { name: userSelection.name, source: "user" } : undefined;
|
|
11014
|
-
if (projectSelection.declared && !projectSelection.name) {
|
|
11015
|
-
warnings.push("Ignoring invalid profile selection from project config; expected a non-empty string.");
|
|
11016
|
-
}
|
|
11017
|
-
if (!projectSelection.declared && userSelection.declared && !userSelection.name) {
|
|
11018
|
-
warnings.push("Ignoring invalid profile selection from user config; expected a non-empty string.");
|
|
11019
|
-
}
|
|
11020
|
-
let profiles = {};
|
|
11021
|
-
if (Object.hasOwn(args.userRaw, "profiles")) {
|
|
11022
|
-
const parsed = ConfigProfilesSchema.safeParse(args.userRaw.profiles);
|
|
11023
|
-
if (parsed.success) {
|
|
11024
|
-
profiles = parsed.data;
|
|
11025
|
-
} else {
|
|
11026
|
-
warnings.push("Ignoring profiles from user config: invalid profile configuration; profiles may contain only historian/dreamer harness model blocks.");
|
|
11027
|
-
}
|
|
11028
|
-
}
|
|
11029
|
-
if (!selection) {
|
|
11030
|
-
return {
|
|
11031
|
-
userBase: withoutProfileFields(args.userRaw),
|
|
11032
|
-
projectBase: withoutProfileFields(args.projectRaw),
|
|
11033
|
-
overlay: {},
|
|
11034
|
-
warnings
|
|
11035
|
-
};
|
|
11036
|
-
}
|
|
11037
|
-
if (!Object.hasOwn(profiles, selection.name)) {
|
|
11038
|
-
warnings.push(`Unknown profile "${selection.name}" selected by ${selection.source} config; using base config without a profile.`);
|
|
11039
|
-
return {
|
|
11040
|
-
userBase: withoutProfileFields(args.userRaw),
|
|
11041
|
-
projectBase: withoutProfileFields(args.projectRaw),
|
|
11042
|
-
overlay: {},
|
|
11043
|
-
warnings
|
|
11044
|
-
};
|
|
11045
|
-
}
|
|
11046
|
-
const overlay = profiles[selection.name];
|
|
11047
|
-
return {
|
|
11048
|
-
userBase: withoutProfileFields(args.userRaw),
|
|
11049
|
-
projectBase: withoutProfileFields(args.projectRaw),
|
|
11050
|
-
overlay,
|
|
11051
|
-
activeProfile: selection.name,
|
|
11052
|
-
warnings
|
|
11053
|
-
};
|
|
10810
|
+
const overlay = profiles[selection.name];
|
|
10811
|
+
return {
|
|
10812
|
+
userBase: withoutProfileFields(args.userRaw),
|
|
10813
|
+
projectBase: withoutProfileFields(args.projectRaw),
|
|
10814
|
+
overlay,
|
|
10815
|
+
activeProfile: selection.name,
|
|
10816
|
+
warnings
|
|
10817
|
+
};
|
|
11054
10818
|
}
|
|
11055
10819
|
|
|
11056
10820
|
// ../plugin/src/config/raw-loader.ts
|
|
11057
10821
|
import {
|
|
11058
|
-
closeSync
|
|
10822
|
+
closeSync,
|
|
11059
10823
|
existsSync as existsSync4,
|
|
11060
10824
|
linkSync,
|
|
11061
|
-
openSync
|
|
10825
|
+
openSync,
|
|
11062
10826
|
readFileSync as readFileSync6,
|
|
11063
10827
|
realpathSync,
|
|
11064
|
-
renameSync
|
|
10828
|
+
renameSync,
|
|
11065
10829
|
statSync as statSync4,
|
|
11066
10830
|
unlinkSync as unlinkSync2,
|
|
11067
|
-
writeFileSync
|
|
10831
|
+
writeFileSync
|
|
11068
10832
|
} from "node:fs";
|
|
11069
10833
|
import { basename as basename2, dirname as dirname3, join as join3 } from "node:path";
|
|
11070
10834
|
var MODEL_FIELDS = ["model", "fallback_models"];
|
|
@@ -11269,7 +11033,7 @@ function writeExclusiveBackup(backupPath, bytes, mode) {
|
|
|
11269
11033
|
if (existingBytes.equals(bytes))
|
|
11270
11034
|
return;
|
|
11271
11035
|
if (bytes.subarray(0, existingBytes.length).equals(existingBytes)) {
|
|
11272
|
-
|
|
11036
|
+
renameSync(temporaryPath, backupPath);
|
|
11273
11037
|
return;
|
|
11274
11038
|
}
|
|
11275
11039
|
} finally {
|
|
@@ -11286,14 +11050,14 @@ function writeTemporaryCandidate(configPath, bytes, mode) {
|
|
|
11286
11050
|
const path = join3(directory, `.${stem}.per-harness-${process.pid}-${temporaryFileSequence}.tmp`);
|
|
11287
11051
|
let descriptor;
|
|
11288
11052
|
try {
|
|
11289
|
-
descriptor =
|
|
11290
|
-
|
|
11291
|
-
|
|
11053
|
+
descriptor = openSync(path, "wx", mode);
|
|
11054
|
+
writeFileSync(descriptor, bytes);
|
|
11055
|
+
closeSync(descriptor);
|
|
11292
11056
|
return path;
|
|
11293
11057
|
} catch (error) {
|
|
11294
11058
|
if (descriptor !== undefined) {
|
|
11295
11059
|
try {
|
|
11296
|
-
|
|
11060
|
+
closeSync(descriptor);
|
|
11297
11061
|
} catch {}
|
|
11298
11062
|
}
|
|
11299
11063
|
try {
|
|
@@ -11354,7 +11118,7 @@ function loadRawConfigFile(options) {
|
|
|
11354
11118
|
let temporaryPath;
|
|
11355
11119
|
try {
|
|
11356
11120
|
const writePath = realpathSync(options.configPath);
|
|
11357
|
-
const mode = statSync4(writePath).mode & 511;
|
|
11121
|
+
const mode = options.tier === "user" ? 384 : statSync4(writePath).mode & 511;
|
|
11358
11122
|
writeExclusiveBackup(backupPath, observedBytes, mode);
|
|
11359
11123
|
temporaryPath = writeTemporaryCandidate(writePath, migration.bytes, mode);
|
|
11360
11124
|
options.afterTemporaryWrite?.();
|
|
@@ -11374,7 +11138,7 @@ function loadRawConfigFile(options) {
|
|
|
11374
11138
|
observedBytes = currentBytes;
|
|
11375
11139
|
continue;
|
|
11376
11140
|
}
|
|
11377
|
-
|
|
11141
|
+
renameSync(temporaryPath, writePath);
|
|
11378
11142
|
return {
|
|
11379
11143
|
configPath: options.configPath,
|
|
11380
11144
|
bytes: migration.bytes,
|
|
@@ -11536,7 +11300,7 @@ function substituteConfigVariables(input) {
|
|
|
11536
11300
|
}
|
|
11537
11301
|
|
|
11538
11302
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
11539
|
-
import {
|
|
11303
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
11540
11304
|
import { join as join4 } from "node:path";
|
|
11541
11305
|
var MIN_SANE_LIMIT = 20000;
|
|
11542
11306
|
var MAX_SANE_LIMIT = 3000000;
|
|
@@ -12127,6 +11891,9 @@ function loadPiConfigDetailed(opts = {}, applyRuntimeGlobals = true) {
|
|
|
12127
11891
|
const recoveredTopLevelKeys = [];
|
|
12128
11892
|
const cacheTtlConfigured = Object.hasOwn(rawConfig, "cache_ttl");
|
|
12129
11893
|
const parsed = parsePiConfig(rawConfig, recoveredTopLevelKeys);
|
|
11894
|
+
Object.defineProperty(parsed.config, "cacheTtlConfigured", {
|
|
11895
|
+
value: cacheTtlConfigured
|
|
11896
|
+
});
|
|
12130
11897
|
for (const key of projectRestoredTopLevelKeys) {
|
|
12131
11898
|
if (!recoveredTopLevelKeys.includes(key))
|
|
12132
11899
|
recoveredTopLevelKeys.push(key);
|
|
@@ -16438,16 +16205,13 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
|
|
|
16438
16205
|
return `Tag ${number}'s original tool owner is no longer in stored history.`;
|
|
16439
16206
|
const parts = message?.parts.filter((part) => isRecord4(part) && asToolPart(part)?.callId === tag.messageId) ?? [];
|
|
16440
16207
|
if (!parts.some((part) => isRecord4(part) && asToolPart(part)?.output !== null)) {
|
|
16441
|
-
|
|
16442
|
-
const ownerIndex = messages.findIndex((candidate) => candidate.id === owner);
|
|
16443
|
-
for (const candidate of messages.slice(Math.max(0, ownerIndex + 1))) {
|
|
16208
|
+
visitRawSessionMessages2(sessionId, message.ordinal + 1, Number.MAX_SAFE_INTEGER, (candidate) => {
|
|
16444
16209
|
const matching = candidate.parts.filter((part) => isRecord4(part) && asToolPart(part)?.callId === tag.messageId);
|
|
16445
16210
|
if (matching.some((part) => isRecord4(part) && part.type === "tool_use"))
|
|
16446
|
-
|
|
16211
|
+
return false;
|
|
16447
16212
|
parts.push(...matching);
|
|
16448
|
-
|
|
16449
|
-
|
|
16450
|
-
}
|
|
16213
|
+
return matching.length === 0;
|
|
16214
|
+
});
|
|
16451
16215
|
}
|
|
16452
16216
|
const rendered = parts.map(renderPartFull).filter((part) => part !== null);
|
|
16453
16217
|
return rendered.length ? rendered.join(`
|
|
@@ -16782,77 +16546,418 @@ var encoder = new TextEncoder;
|
|
|
16782
16546
|
function Boolean2(options) {
|
|
16783
16547
|
return Create({ "~kind": "Boolean" }, { type: "boolean" }, options);
|
|
16784
16548
|
}
|
|
16785
|
-
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/types/integer.mjs
|
|
16786
|
-
var IntegerPattern = "-?(?:0|[1-9][0-9]*)";
|
|
16787
|
-
function Integer(options) {
|
|
16788
|
-
return Create({ "~kind": "Integer" }, { type: "integer" }, options);
|
|
16549
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/types/integer.mjs
|
|
16550
|
+
var IntegerPattern = "-?(?:0|[1-9][0-9]*)";
|
|
16551
|
+
function Integer(options) {
|
|
16552
|
+
return Create({ "~kind": "Integer" }, { type: "integer" }, options);
|
|
16553
|
+
}
|
|
16554
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/types/literal.mjs
|
|
16555
|
+
class InvalidLiteralValue extends Error {
|
|
16556
|
+
constructor(value) {
|
|
16557
|
+
super(`Invalid Literal value`);
|
|
16558
|
+
Object.defineProperty(this, "cause", {
|
|
16559
|
+
value: { value },
|
|
16560
|
+
writable: false,
|
|
16561
|
+
configurable: false,
|
|
16562
|
+
enumerable: false
|
|
16563
|
+
});
|
|
16564
|
+
}
|
|
16565
|
+
}
|
|
16566
|
+
function LiteralTypeName(value) {
|
|
16567
|
+
return IsBigInt(value) ? "bigint" : IsBoolean(value) ? "boolean" : IsNumber(value) ? "number" : IsString(value) ? "string" : (() => {
|
|
16568
|
+
throw new InvalidLiteralValue(value);
|
|
16569
|
+
})();
|
|
16570
|
+
}
|
|
16571
|
+
function Literal(value, options) {
|
|
16572
|
+
return Create({ "~kind": "Literal" }, { type: LiteralTypeName(value), const: value }, options);
|
|
16573
|
+
}
|
|
16574
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/types/number.mjs
|
|
16575
|
+
var NumberPattern = "-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?";
|
|
16576
|
+
function Number2(options) {
|
|
16577
|
+
return Create({ "~kind": "Number" }, { type: "number" }, options);
|
|
16578
|
+
}
|
|
16579
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/types/string.mjs
|
|
16580
|
+
var StringPattern = ".*";
|
|
16581
|
+
function String2(options) {
|
|
16582
|
+
return Create({ "~kind": "String" }, { type: "string" }, options);
|
|
16583
|
+
}
|
|
16584
|
+
|
|
16585
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/types/union.mjs
|
|
16586
|
+
function Union(anyOf, options = {}) {
|
|
16587
|
+
return Create({ "~kind": "Union" }, { anyOf }, options);
|
|
16588
|
+
}
|
|
16589
|
+
|
|
16590
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/types/record.mjs
|
|
16591
|
+
var IntegerKey = `^${IntegerPattern}$`;
|
|
16592
|
+
var NumberKey = `^${NumberPattern}$`;
|
|
16593
|
+
var StringKey = `^${StringPattern}$`;
|
|
16594
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/script/token/internal/char.mjs
|
|
16595
|
+
function Range(start, end) {
|
|
16596
|
+
return Array.from({ length: end - start + 1 }, (_, i) => String.fromCharCode(start + i));
|
|
16597
|
+
}
|
|
16598
|
+
var Alpha = [
|
|
16599
|
+
...Range(97, 122),
|
|
16600
|
+
...Range(65, 90)
|
|
16601
|
+
];
|
|
16602
|
+
var Zero = "0";
|
|
16603
|
+
var NonZero = Range(49, 57);
|
|
16604
|
+
var Digit = [Zero, ...NonZero];
|
|
16605
|
+
var UnderScore = "_";
|
|
16606
|
+
var DollarSign = "$";
|
|
16607
|
+
|
|
16608
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/script/token/unsigned_integer.mjs
|
|
16609
|
+
var AllowedDigits = [...Digit, UnderScore];
|
|
16610
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/script/token/ident.mjs
|
|
16611
|
+
var Initial = [...Alpha, UnderScore, DollarSign];
|
|
16612
|
+
var Remaining = [...Initial, ...Digit];
|
|
16613
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/script/token/unsigned_number.mjs
|
|
16614
|
+
var AllowedDigits2 = [...Digit, UnderScore];
|
|
16615
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/engine/helpers/keys.mjs
|
|
16616
|
+
var integerKeyPattern = new RegExp("^(?:0|[1-9][0-9]*)$");
|
|
16617
|
+
|
|
16618
|
+
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/engine/indexed/from_object.mjs
|
|
16619
|
+
var NumericKeyPattern = new RegExp(IntegerKey);
|
|
16620
|
+
// src/read-session-pi.ts
|
|
16621
|
+
var SYNTH_USER_ID_PREFIX = "synth-user-";
|
|
16622
|
+
function resolvePiStableId(msg, index, entryIds, entryIdByRef) {
|
|
16623
|
+
if (!msg || typeof msg !== "object")
|
|
16624
|
+
return;
|
|
16625
|
+
const byRef = entryIdByRef?.get(msg);
|
|
16626
|
+
if (typeof byRef === "string" && byRef.length > 0)
|
|
16627
|
+
return byRef;
|
|
16628
|
+
const positional = entryIds?.[index];
|
|
16629
|
+
if (typeof positional === "string" && positional.length > 0)
|
|
16630
|
+
return positional;
|
|
16631
|
+
const m = msg;
|
|
16632
|
+
const role = m.role ?? "unknown";
|
|
16633
|
+
return typeof m.timestamp === "number" ? `pi-msg-${index}-${m.timestamp}-${role}` : `pi-msg-${index}-${role}`;
|
|
16634
|
+
}
|
|
16635
|
+
function readPiSessionSnapshot(ctx) {
|
|
16636
|
+
const sm = ctx.sessionManager;
|
|
16637
|
+
if (sm === undefined)
|
|
16638
|
+
return { branchEntries: [], rawMessages: [] };
|
|
16639
|
+
const getBranch = sm.getBranch;
|
|
16640
|
+
if (typeof getBranch !== "function")
|
|
16641
|
+
return { branchEntries: [], rawMessages: [] };
|
|
16642
|
+
let entries;
|
|
16643
|
+
try {
|
|
16644
|
+
entries = getBranch.call(sm);
|
|
16645
|
+
} catch {
|
|
16646
|
+
return { branchEntries: [], rawMessages: [] };
|
|
16647
|
+
}
|
|
16648
|
+
if (!Array.isArray(entries))
|
|
16649
|
+
return { branchEntries: [], rawMessages: [] };
|
|
16650
|
+
return {
|
|
16651
|
+
branchEntries: entries,
|
|
16652
|
+
rawMessages: convertEntriesToRawMessages(entries)
|
|
16653
|
+
};
|
|
16654
|
+
}
|
|
16655
|
+
function readPiSessionMessages(ctx) {
|
|
16656
|
+
return readPiSessionSnapshot(ctx).rawMessages;
|
|
16657
|
+
}
|
|
16658
|
+
function readPiSessionMessagePage(ctx, afterOrdinal, limit, finalWatermark) {
|
|
16659
|
+
const sessionManager = ctx.sessionManager;
|
|
16660
|
+
const getBranch = sessionManager?.getBranch;
|
|
16661
|
+
if (typeof getBranch !== "function")
|
|
16662
|
+
return [];
|
|
16663
|
+
try {
|
|
16664
|
+
const entries = getBranch.call(sessionManager);
|
|
16665
|
+
return Array.isArray(entries) ? convertEntriesToRawMessagePage(entries, afterOrdinal, limit, finalWatermark) : [];
|
|
16666
|
+
} catch {
|
|
16667
|
+
return [];
|
|
16668
|
+
}
|
|
16669
|
+
}
|
|
16670
|
+
function findLastModelKeyFromBranch(entries) {
|
|
16671
|
+
if (!Array.isArray(entries))
|
|
16672
|
+
return;
|
|
16673
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
16674
|
+
const e = entries[i];
|
|
16675
|
+
if (!e || typeof e !== "object")
|
|
16676
|
+
continue;
|
|
16677
|
+
const v = e;
|
|
16678
|
+
if (v.type !== "model_change")
|
|
16679
|
+
continue;
|
|
16680
|
+
if (typeof v.provider === "string" && v.provider.length > 0 && typeof v.modelId === "string" && v.modelId.length > 0) {
|
|
16681
|
+
return `${v.provider}/${v.modelId}`;
|
|
16682
|
+
}
|
|
16683
|
+
}
|
|
16684
|
+
return;
|
|
16685
|
+
}
|
|
16686
|
+
function findRestartModelSeedFromBranch(entries) {
|
|
16687
|
+
if (!Array.isArray(entries))
|
|
16688
|
+
return;
|
|
16689
|
+
let switchedAfterLastReply = false;
|
|
16690
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
16691
|
+
const e = entries[i];
|
|
16692
|
+
if (e?.type === "model_change") {
|
|
16693
|
+
if (typeof e.provider === "string" && typeof e.modelId === "string")
|
|
16694
|
+
switchedAfterLastReply = true;
|
|
16695
|
+
continue;
|
|
16696
|
+
}
|
|
16697
|
+
if (e?.type !== "message")
|
|
16698
|
+
continue;
|
|
16699
|
+
const m = e.message;
|
|
16700
|
+
if (m?.role !== "assistant")
|
|
16701
|
+
continue;
|
|
16702
|
+
if (typeof m.provider !== "string" || m.provider.length === 0 || typeof m.model !== "string" || m.model.length === 0) {
|
|
16703
|
+
continue;
|
|
16704
|
+
}
|
|
16705
|
+
return switchedAfterLastReply ? `${m.provider}/${m.model}` : findLastModelKeyFromBranch(entries);
|
|
16706
|
+
}
|
|
16707
|
+
return findLastModelKeyFromBranch(entries);
|
|
16708
|
+
}
|
|
16709
|
+
function rawEntryVersion(entry) {
|
|
16710
|
+
const record = entry;
|
|
16711
|
+
const updated = record.updatedAt ?? record.updated_at ?? record.timestamp;
|
|
16712
|
+
return typeof updated === "string" || typeof updated === "number" ? updated : entry.id;
|
|
16713
|
+
}
|
|
16714
|
+
function parsePiEntryTimestamp(entry) {
|
|
16715
|
+
const record = entry;
|
|
16716
|
+
const raw = record.timestamp;
|
|
16717
|
+
if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 0)
|
|
16718
|
+
return raw;
|
|
16719
|
+
if (typeof raw !== "string" || raw.trim().length === 0)
|
|
16720
|
+
return null;
|
|
16721
|
+
const parsed = Date.parse(raw);
|
|
16722
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
16723
|
+
}
|
|
16724
|
+
function attachPiPartVersion(parts, version) {
|
|
16725
|
+
return parts.map((part) => {
|
|
16726
|
+
if (part === null || typeof part !== "object" || Array.isArray(part))
|
|
16727
|
+
return part;
|
|
16728
|
+
try {
|
|
16729
|
+
Object.defineProperty(part, "__magicContextPartUpdatedAt", {
|
|
16730
|
+
value: version,
|
|
16731
|
+
enumerable: false,
|
|
16732
|
+
configurable: true
|
|
16733
|
+
});
|
|
16734
|
+
} catch {}
|
|
16735
|
+
return part;
|
|
16736
|
+
});
|
|
16737
|
+
}
|
|
16738
|
+
function* iterateEntriesToRawMessageRange(entries, afterOrdinal, limit, finalWatermark) {
|
|
16739
|
+
let emitted = 0;
|
|
16740
|
+
const normalizedAfter = Math.max(0, Math.floor(afterOrdinal));
|
|
16741
|
+
const normalizedLimit = Math.max(1, Math.floor(limit));
|
|
16742
|
+
const normalizedWatermark = Math.max(normalizedAfter, Math.floor(finalWatermark));
|
|
16743
|
+
let nextOrdinal = 1;
|
|
16744
|
+
let pendingToolResults = [];
|
|
16745
|
+
const buildToolParts = (results) => results.flatMap(({ msg, version }) => attachPiPartVersion(synthesizeToolResultParts(msg), version));
|
|
16746
|
+
let hasPendingToolParts = false;
|
|
16747
|
+
let pendingFirstRealId = "";
|
|
16748
|
+
let pendingFirstRealVersion = "";
|
|
16749
|
+
let pendingFirstCreatedAt = null;
|
|
16750
|
+
const appendMessage = function* (id, role, version, createdAt, parts) {
|
|
16751
|
+
const ordinal = nextOrdinal++;
|
|
16752
|
+
if (ordinal > normalizedAfter && ordinal <= normalizedWatermark) {
|
|
16753
|
+
emitted++;
|
|
16754
|
+
yield {
|
|
16755
|
+
ordinal,
|
|
16756
|
+
id,
|
|
16757
|
+
role,
|
|
16758
|
+
parts: parts(),
|
|
16759
|
+
version,
|
|
16760
|
+
...createdAt === null ? {} : { createdAt }
|
|
16761
|
+
};
|
|
16762
|
+
}
|
|
16763
|
+
return emitted >= normalizedLimit || nextOrdinal > normalizedWatermark;
|
|
16764
|
+
};
|
|
16765
|
+
for (const entry of entries) {
|
|
16766
|
+
if (!isMessageEntry(entry))
|
|
16767
|
+
continue;
|
|
16768
|
+
const msg = entry.message;
|
|
16769
|
+
const role = msg.role;
|
|
16770
|
+
if (role === "toolResult") {
|
|
16771
|
+
const callId = msg.toolCallId;
|
|
16772
|
+
if (typeof callId !== "string" || callId.length === 0)
|
|
16773
|
+
continue;
|
|
16774
|
+
const version = rawEntryVersion(entry);
|
|
16775
|
+
hasPendingToolParts = true;
|
|
16776
|
+
pendingToolResults.push({ msg, version });
|
|
16777
|
+
if (pendingFirstRealId === "") {
|
|
16778
|
+
pendingFirstRealId = entry.id;
|
|
16779
|
+
pendingFirstRealVersion = version;
|
|
16780
|
+
pendingFirstCreatedAt = parsePiEntryTimestamp(entry);
|
|
16781
|
+
}
|
|
16782
|
+
continue;
|
|
16783
|
+
}
|
|
16784
|
+
if (role === "user") {
|
|
16785
|
+
const version = rawEntryVersion(entry);
|
|
16786
|
+
const bufferedToolResults = pendingToolResults;
|
|
16787
|
+
const done = yield* appendMessage(entry.id, "user", version, parsePiEntryTimestamp(entry), () => [
|
|
16788
|
+
...buildToolParts(bufferedToolResults),
|
|
16789
|
+
...attachPiPartVersion(synthesizeUserParts(msg), version)
|
|
16790
|
+
]);
|
|
16791
|
+
pendingToolResults = [];
|
|
16792
|
+
hasPendingToolParts = false;
|
|
16793
|
+
pendingFirstRealId = "";
|
|
16794
|
+
pendingFirstRealVersion = "";
|
|
16795
|
+
pendingFirstCreatedAt = null;
|
|
16796
|
+
if (done)
|
|
16797
|
+
break;
|
|
16798
|
+
continue;
|
|
16799
|
+
}
|
|
16800
|
+
if (role === "assistant") {
|
|
16801
|
+
if (hasPendingToolParts) {
|
|
16802
|
+
const bufferedToolResults = pendingToolResults;
|
|
16803
|
+
const pendingId = pendingFirstRealId;
|
|
16804
|
+
const pendingVersion = pendingFirstRealVersion;
|
|
16805
|
+
const done = yield* appendMessage(`${SYNTH_USER_ID_PREFIX}${pendingId}`, "user", pendingVersion, pendingFirstCreatedAt, () => buildToolParts(bufferedToolResults));
|
|
16806
|
+
pendingToolResults = [];
|
|
16807
|
+
hasPendingToolParts = false;
|
|
16808
|
+
pendingFirstRealId = "";
|
|
16809
|
+
pendingFirstRealVersion = "";
|
|
16810
|
+
pendingFirstCreatedAt = null;
|
|
16811
|
+
if (done)
|
|
16812
|
+
break;
|
|
16813
|
+
}
|
|
16814
|
+
const version = rawEntryVersion(entry);
|
|
16815
|
+
if (yield* appendMessage(entry.id, "assistant", version, parsePiEntryTimestamp(entry), () => attachPiPartVersion(synthesizeAssistantParts(msg), version))) {
|
|
16816
|
+
break;
|
|
16817
|
+
}
|
|
16818
|
+
continue;
|
|
16819
|
+
}
|
|
16820
|
+
if (yield* appendMessage(entry.id, typeof role === "string" ? role : "unknown", rawEntryVersion(entry), parsePiEntryTimestamp(entry), () => [])) {
|
|
16821
|
+
break;
|
|
16822
|
+
}
|
|
16823
|
+
}
|
|
16824
|
+
if (hasPendingToolParts && emitted < normalizedLimit && nextOrdinal <= normalizedWatermark) {
|
|
16825
|
+
yield* appendMessage(`${SYNTH_USER_ID_PREFIX}${pendingFirstRealId}`, "user", pendingFirstRealVersion, pendingFirstCreatedAt, () => buildToolParts(pendingToolResults));
|
|
16826
|
+
}
|
|
16827
|
+
}
|
|
16828
|
+
function convertEntriesToRawMessages(entries) {
|
|
16829
|
+
return [
|
|
16830
|
+
...iterateEntriesToRawMessageRange(entries, 0, Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER)
|
|
16831
|
+
];
|
|
16789
16832
|
}
|
|
16790
|
-
|
|
16791
|
-
|
|
16792
|
-
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
16799
|
-
}
|
|
16833
|
+
function convertPiAssistantEntryById(entries, entryId) {
|
|
16834
|
+
for (let index = 0;index < entries.length; index++) {
|
|
16835
|
+
const entry = entries[index];
|
|
16836
|
+
if (!isMessageEntry(entry) || entry.id !== entryId)
|
|
16837
|
+
continue;
|
|
16838
|
+
if (entry.message.role !== "assistant" || entryId.startsWith(SYNTH_USER_ID_PREFIX)) {
|
|
16839
|
+
return convertEntriesToRawMessages(entries).find((message) => message.id === entryId) ?? null;
|
|
16840
|
+
}
|
|
16841
|
+
const raw = convertEntriesToRawMessages([entry])[0];
|
|
16842
|
+
return raw ? { ...raw, ordinal: countPiRawMessages(entries.slice(0, index + 1)) } : null;
|
|
16800
16843
|
}
|
|
16844
|
+
return null;
|
|
16801
16845
|
}
|
|
16802
|
-
function
|
|
16803
|
-
return
|
|
16804
|
-
|
|
16805
|
-
|
|
16846
|
+
function convertEntriesToRawMessagePage(entries, afterOrdinal, limit, finalWatermark) {
|
|
16847
|
+
return [
|
|
16848
|
+
...iterateEntriesToRawMessageRange(entries, afterOrdinal, limit, finalWatermark)
|
|
16849
|
+
];
|
|
16806
16850
|
}
|
|
16807
|
-
function
|
|
16808
|
-
|
|
16851
|
+
function isMessageEntry(value) {
|
|
16852
|
+
if (value === null || typeof value !== "object")
|
|
16853
|
+
return false;
|
|
16854
|
+
const v = value;
|
|
16855
|
+
if (v.type !== "message")
|
|
16856
|
+
return false;
|
|
16857
|
+
if (typeof v.id !== "string")
|
|
16858
|
+
return false;
|
|
16859
|
+
if (v.message === null || typeof v.message !== "object")
|
|
16860
|
+
return false;
|
|
16861
|
+
return true;
|
|
16809
16862
|
}
|
|
16810
|
-
|
|
16811
|
-
|
|
16812
|
-
|
|
16813
|
-
|
|
16863
|
+
function synthesizeUserParts(msg) {
|
|
16864
|
+
const m = msg;
|
|
16865
|
+
if (typeof m.content === "string") {
|
|
16866
|
+
if (m.content.trim().length === 0)
|
|
16867
|
+
return [];
|
|
16868
|
+
return [{ type: "text", text: m.content }];
|
|
16869
|
+
}
|
|
16870
|
+
if (!Array.isArray(m.content))
|
|
16871
|
+
return [];
|
|
16872
|
+
const parts = [];
|
|
16873
|
+
for (const c of m.content) {
|
|
16874
|
+
if (c === null || typeof c !== "object")
|
|
16875
|
+
continue;
|
|
16876
|
+
const cc = c;
|
|
16877
|
+
if (cc.type === "text" && typeof cc.text === "string") {
|
|
16878
|
+
parts.push({ type: "text", text: cc.text });
|
|
16879
|
+
}
|
|
16880
|
+
}
|
|
16881
|
+
return parts;
|
|
16814
16882
|
}
|
|
16815
|
-
|
|
16816
|
-
|
|
16817
|
-
|
|
16818
|
-
|
|
16883
|
+
function synthesizeAssistantParts(msg) {
|
|
16884
|
+
const m = msg;
|
|
16885
|
+
if (!Array.isArray(m.content))
|
|
16886
|
+
return [];
|
|
16887
|
+
const parts = [];
|
|
16888
|
+
for (const c of m.content) {
|
|
16889
|
+
if (c === null || typeof c !== "object")
|
|
16890
|
+
continue;
|
|
16891
|
+
const cc = c;
|
|
16892
|
+
if (cc.type === "text" && typeof cc.text === "string") {
|
|
16893
|
+
parts.push({ type: "text", text: cc.text });
|
|
16894
|
+
} else if (cc.type === "toolCall" && typeof cc.id === "string") {
|
|
16895
|
+
parts.push({
|
|
16896
|
+
type: "tool",
|
|
16897
|
+
tool: typeof cc.name === "string" ? cc.name : "unknown",
|
|
16898
|
+
callID: cc.id,
|
|
16899
|
+
state: {
|
|
16900
|
+
input: cc.arguments ?? {}
|
|
16901
|
+
}
|
|
16902
|
+
});
|
|
16903
|
+
}
|
|
16904
|
+
}
|
|
16905
|
+
return parts;
|
|
16819
16906
|
}
|
|
16820
|
-
|
|
16821
|
-
|
|
16822
|
-
|
|
16823
|
-
|
|
16907
|
+
function synthesizeToolResultParts(msg) {
|
|
16908
|
+
const m = msg;
|
|
16909
|
+
const callID = typeof m.toolCallId === "string" ? m.toolCallId : "";
|
|
16910
|
+
const tool = typeof m.toolName === "string" ? m.toolName : "unknown";
|
|
16911
|
+
if (!callID)
|
|
16912
|
+
return [];
|
|
16913
|
+
let output = "";
|
|
16914
|
+
if (Array.isArray(m.content)) {
|
|
16915
|
+
const fragments = [];
|
|
16916
|
+
for (const c of m.content) {
|
|
16917
|
+
if (c === null || typeof c !== "object")
|
|
16918
|
+
continue;
|
|
16919
|
+
const cc = c;
|
|
16920
|
+
if (cc.type === "text" && typeof cc.text === "string") {
|
|
16921
|
+
fragments.push(cc.text);
|
|
16922
|
+
}
|
|
16923
|
+
}
|
|
16924
|
+
output = fragments.join(`
|
|
16925
|
+
`);
|
|
16926
|
+
}
|
|
16927
|
+
return [
|
|
16928
|
+
{
|
|
16929
|
+
type: "tool",
|
|
16930
|
+
tool,
|
|
16931
|
+
callID,
|
|
16932
|
+
state: {
|
|
16933
|
+
output
|
|
16934
|
+
}
|
|
16935
|
+
}
|
|
16936
|
+
];
|
|
16824
16937
|
}
|
|
16825
|
-
|
|
16826
|
-
|
|
16827
|
-
|
|
16828
|
-
|
|
16829
|
-
|
|
16830
|
-
|
|
16831
|
-
|
|
16832
|
-
|
|
16938
|
+
function countPiRawMessages(entries) {
|
|
16939
|
+
let count = 0;
|
|
16940
|
+
let pendingTools = false;
|
|
16941
|
+
for (const entry of entries) {
|
|
16942
|
+
if (!isMessageEntry(entry))
|
|
16943
|
+
continue;
|
|
16944
|
+
const message = entry.message;
|
|
16945
|
+
if (message.role === "toolResult") {
|
|
16946
|
+
if (typeof message.toolCallId === "string" && message.toolCallId.length > 0)
|
|
16947
|
+
pendingTools = true;
|
|
16948
|
+
continue;
|
|
16949
|
+
}
|
|
16950
|
+
if (message.role === "user")
|
|
16951
|
+
pendingTools = false;
|
|
16952
|
+
else if (message.role === "assistant" && pendingTools) {
|
|
16953
|
+
count++;
|
|
16954
|
+
pendingTools = false;
|
|
16955
|
+
}
|
|
16956
|
+
count++;
|
|
16957
|
+
}
|
|
16958
|
+
return count + Number(pendingTools);
|
|
16833
16959
|
}
|
|
16834
|
-
var Alpha = [
|
|
16835
|
-
...Range(97, 122),
|
|
16836
|
-
...Range(65, 90)
|
|
16837
|
-
];
|
|
16838
|
-
var Zero = "0";
|
|
16839
|
-
var NonZero = Range(49, 57);
|
|
16840
|
-
var Digit = [Zero, ...NonZero];
|
|
16841
|
-
var UnderScore = "_";
|
|
16842
|
-
var DollarSign = "$";
|
|
16843
|
-
|
|
16844
|
-
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/script/token/unsigned_integer.mjs
|
|
16845
|
-
var AllowedDigits = [...Digit, UnderScore];
|
|
16846
|
-
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/script/token/ident.mjs
|
|
16847
|
-
var Initial = [...Alpha, UnderScore, DollarSign];
|
|
16848
|
-
var Remaining = [...Initial, ...Digit];
|
|
16849
|
-
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/script/token/unsigned_number.mjs
|
|
16850
|
-
var AllowedDigits2 = [...Digit, UnderScore];
|
|
16851
|
-
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/engine/helpers/keys.mjs
|
|
16852
|
-
var integerKeyPattern = new RegExp("^(?:0|[1-9][0-9]*)$");
|
|
16853
16960
|
|
|
16854
|
-
// ../../node_modules/.bun/typebox@1.3.27/node_modules/typebox/build/type/engine/indexed/from_object.mjs
|
|
16855
|
-
var NumericKeyPattern = new RegExp(IntegerKey);
|
|
16856
16961
|
// src/tools/ctx-expand.ts
|
|
16857
16962
|
var ParamsSchema = _Object_({
|
|
16858
16963
|
tag: Optional(Union([Number2(), String2()], {
|
|
@@ -17282,9 +17387,8 @@ function getMuralCueState(db, memoryIds) {
|
|
|
17282
17387
|
const ids = Array.from(new Set(memoryIds.filter(Number.isInteger)));
|
|
17283
17388
|
if (ids.length === 0)
|
|
17284
17389
|
return out;
|
|
17285
|
-
const placeholders = ids.map(() => "?").join(", ");
|
|
17286
17390
|
const rejectionCountColumn = hasMuralCueRejectionCountColumn(db) ? "COALESCE(mural_cue_rejection_count, 0) AS mural_cue_rejection_count" : "0 AS mural_cue_rejection_count";
|
|
17287
|
-
const rows = db.prepare(`SELECT id, mural_cue, mural_cue_hash, ${rejectionCountColumn} FROM memories WHERE id IN (
|
|
17391
|
+
const rows = db.prepare(`SELECT id, mural_cue, mural_cue_hash, ${rejectionCountColumn} FROM memories WHERE id IN (SELECT value FROM json_each(?))`).all(JSON.stringify(ids));
|
|
17288
17392
|
for (const row of rows) {
|
|
17289
17393
|
out.set(row.id, {
|
|
17290
17394
|
cue: row.mural_cue ?? null,
|
|
@@ -17468,8 +17572,7 @@ function getUnclassifiedMemoryIds(db, memoryIds) {
|
|
|
17468
17572
|
const ids = Array.from(new Set(memoryIds.filter(Number.isInteger)));
|
|
17469
17573
|
if (ids.length === 0)
|
|
17470
17574
|
return [];
|
|
17471
|
-
const
|
|
17472
|
-
const rows = db.prepare(`SELECT id FROM memories WHERE id IN (${ph}) AND classified_at IS NOT NULL`).all(...ids);
|
|
17575
|
+
const rows = db.prepare("SELECT id FROM memories WHERE id IN (SELECT value FROM json_each(?)) AND classified_at IS NOT NULL").all(JSON.stringify(ids));
|
|
17473
17576
|
const classified = new Set(rows.map((r) => r.id));
|
|
17474
17577
|
return ids.filter((id) => !classified.has(id));
|
|
17475
17578
|
}
|
|
@@ -17749,6 +17852,7 @@ function getMemoriesByProject(db, projectPath, statuses = ["active", "permanent"
|
|
|
17749
17852
|
const rows = getMemoriesByProjectStatement(db, statuses).all(projectPath, ...statuses, expiryCutoff).filter(isMemoryRow);
|
|
17750
17853
|
return rows.map(toMemory);
|
|
17751
17854
|
}
|
|
17855
|
+
var memoryListStatements = new WeakMap;
|
|
17752
17856
|
function sqlPlaceholders(values) {
|
|
17753
17857
|
return values.map(() => "?").join(", ");
|
|
17754
17858
|
}
|
|
@@ -18181,9 +18285,6 @@ function searchMemoriesFTSUnion(db, projectPaths, query, limit = DEFAULT_SEARCH_
|
|
|
18181
18285
|
}
|
|
18182
18286
|
// ../plugin/src/features/magic-context/memory/storage-memory-verifications.ts
|
|
18183
18287
|
var MEMORY_VERIFICATION_SENTINEL = "";
|
|
18184
|
-
function placeholders2(values) {
|
|
18185
|
-
return values.map(() => "?").join(", ");
|
|
18186
|
-
}
|
|
18187
18288
|
function uniqueSortedFiles(files) {
|
|
18188
18289
|
return Array.from(new Set(files.filter((file) => file !== MEMORY_VERIFICATION_SENTINEL))).sort();
|
|
18189
18290
|
}
|
|
@@ -18211,7 +18312,7 @@ function getUnmappedMemoryIds(db, memoryIds) {
|
|
|
18211
18312
|
const ids = Array.from(new Set(memoryIds.filter(Number.isInteger)));
|
|
18212
18313
|
if (ids.length === 0)
|
|
18213
18314
|
return [];
|
|
18214
|
-
const rows = db.prepare(
|
|
18315
|
+
const rows = db.prepare("SELECT DISTINCT memory_id FROM memory_verifications WHERE memory_id IN (SELECT value FROM json_each(?))").all(JSON.stringify(ids));
|
|
18215
18316
|
const mapped = new Set(rows.map((r) => r.memory_id));
|
|
18216
18317
|
return ids.filter((id) => !mapped.has(id));
|
|
18217
18318
|
}
|
|
@@ -18225,8 +18326,8 @@ function getMemoryVerifications(db, memoryIds) {
|
|
|
18225
18326
|
return result;
|
|
18226
18327
|
const rows = db.prepare(`SELECT memory_id, file_path, verified_at, mapped_at, mapping_origin
|
|
18227
18328
|
FROM memory_verifications
|
|
18228
|
-
WHERE memory_id IN (
|
|
18229
|
-
ORDER BY memory_id, file_path`).all(
|
|
18329
|
+
WHERE memory_id IN (SELECT value FROM json_each(?))
|
|
18330
|
+
ORDER BY memory_id, file_path`).all(JSON.stringify(ids));
|
|
18230
18331
|
for (const row of rows) {
|
|
18231
18332
|
const existing = result.get(row.memory_id) ?? {
|
|
18232
18333
|
files: [],
|
|
@@ -18307,10 +18408,10 @@ async function readGitHead(cwd) {
|
|
|
18307
18408
|
const head = stdout?.trim();
|
|
18308
18409
|
return head && /^[0-9a-f]{40}$/i.test(head) ? head : null;
|
|
18309
18410
|
}
|
|
18310
|
-
async function readGitChangedFilesSince(cwd, revision) {
|
|
18411
|
+
async function readGitChangedFilesSince(cwd, revision, knownGitRoot) {
|
|
18311
18412
|
if (!/^[0-9a-f]{7,40}$/i.test(revision))
|
|
18312
18413
|
return null;
|
|
18313
|
-
const gitRoot = await resolveGitTopLevel(cwd);
|
|
18414
|
+
const gitRoot = knownGitRoot ?? await resolveGitTopLevel(cwd);
|
|
18314
18415
|
if (!gitRoot)
|
|
18315
18416
|
return null;
|
|
18316
18417
|
const stdout = await runGit(gitRoot, ["diff", "--name-only", "-z", revision]);
|
|
@@ -18318,8 +18419,8 @@ async function readGitChangedFilesSince(cwd, revision) {
|
|
|
18318
18419
|
return null;
|
|
18319
18420
|
return new Set(stdout.split("\x00").filter(Boolean));
|
|
18320
18421
|
}
|
|
18321
|
-
async function readGitFileChangeTimesSince(cwd, sinceMs) {
|
|
18322
|
-
const gitRoot = await resolveGitTopLevel(cwd);
|
|
18422
|
+
async function readGitFileChangeTimesSince(cwd, sinceMs, knownGitRoot) {
|
|
18423
|
+
const gitRoot = knownGitRoot ?? await resolveGitTopLevel(cwd);
|
|
18323
18424
|
if (!gitRoot)
|
|
18324
18425
|
return null;
|
|
18325
18426
|
const sinceSec = Math.max(0, Math.floor(sinceMs / 1000));
|
|
@@ -18379,6 +18480,7 @@ async function normalizeVerificationFiles(args) {
|
|
|
18379
18480
|
const rootReal = safeRealpath(root) ?? root;
|
|
18380
18481
|
const warnings = [];
|
|
18381
18482
|
const normalized = [];
|
|
18483
|
+
let trackedPaths;
|
|
18382
18484
|
for (const raw of args.files) {
|
|
18383
18485
|
const value = typeof raw === "string" ? raw.trim() : "";
|
|
18384
18486
|
if (!value) {
|
|
@@ -18420,7 +18522,14 @@ async function normalizeVerificationFiles(args) {
|
|
|
18420
18522
|
warnings.push(`Skipped verification path "${value}" because it is not inside the git repo.`);
|
|
18421
18523
|
continue;
|
|
18422
18524
|
}
|
|
18423
|
-
|
|
18525
|
+
if (!trackedPaths) {
|
|
18526
|
+
let trackedOutput = null;
|
|
18527
|
+
try {
|
|
18528
|
+
trackedOutput = await runGit(gitRoot, ["ls-files", "-z", "--full-name"]);
|
|
18529
|
+
} catch {}
|
|
18530
|
+
trackedPaths = new Set(trackedOutput?.split("\x00").filter(Boolean) ?? []);
|
|
18531
|
+
}
|
|
18532
|
+
const tracked = trackedPaths.has(repoRelative) ? repoRelative : await gitTrackedPath(gitRoot, repoRelative);
|
|
18424
18533
|
if (!tracked) {
|
|
18425
18534
|
warnings.push(`Skipped verification path "${value}" because it is not a tracked git file.`);
|
|
18426
18535
|
continue;
|
|
@@ -20060,6 +20169,10 @@ Stamp: file reads, search results and tool outputs the work ahead no longer need
|
|
|
20060
20169
|
Keep: user messages (never stamp one for its directive), your own conversation text, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may still matter.
|
|
20061
20170
|
|
|
20062
20171
|
Look at each tag before stamping it; never blanket-stamp a range like "1-50". Many small targeted stamps beat one sweep. \`drop\` accepts "3-5", "1,2,9", "1-5,8,12-15".`;
|
|
20172
|
+
var CTX_REDUCE_SELF_STAMP_MESSAGE_TEMPLATE = "§N§ is a ctx_reduce call; leave those alone, they are cleaned up automatically.";
|
|
20173
|
+
function ctxReduceSelfStampMessage(tagNumber) {
|
|
20174
|
+
return CTX_REDUCE_SELF_STAMP_MESSAGE_TEMPLATE.replace("§N§", `§${tagNumber}§`);
|
|
20175
|
+
}
|
|
20063
20176
|
|
|
20064
20177
|
// src/tools/ctx-reduce.ts
|
|
20065
20178
|
var ParamsSchema3 = _Object_({
|
|
@@ -20105,11 +20218,18 @@ function createCtxReduceTool(deps) {
|
|
|
20105
20218
|
if (unknownIds.length > 0) {
|
|
20106
20219
|
return err4(`Error: Unknown tag(s) ${formatIds(unknownIds)}. Check available tags in conversation.`);
|
|
20107
20220
|
}
|
|
20221
|
+
const ctxReduceSelfStampIds = new Set(allTags.filter((tag) => tag.toolName?.toLowerCase() === "ctx_reduce").map((tag) => tag.tagNumber));
|
|
20222
|
+
const ctxReduceSelfStampNote = dropIds.filter((id) => ctxReduceSelfStampIds.has(id)).filter((id, index, ids) => ids.indexOf(id) === index).map(ctxReduceSelfStampMessage).join(" ");
|
|
20223
|
+
dropIds = dropIds.filter((id) => !ctxReduceSelfStampIds.has(id));
|
|
20108
20224
|
const activeTags = allTags.filter((tag) => tag.status === "active");
|
|
20109
20225
|
const effectiveFloor = readEpochFloorSnapshot(deps.db, sessionId) ?? deps.resolveFloor?.(ctx) ?? deps.floor ?? deps.protectedTokens ?? 16000;
|
|
20110
20226
|
const windowResult = getProtectionWindowForSession(deps.db, sessionId, effectiveFloor);
|
|
20111
20227
|
const hasToolTags = allTags.some((t) => t.type === "tool");
|
|
20112
|
-
const
|
|
20228
|
+
const windowSet = hasToolTags ? windowResult.tagNumberSet.tagNumbers : typeof deps.protectedTags === "number" && deps.protectedTags > 0 ? new Set(activeTags.map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, deps.protectedTags)) : new Set;
|
|
20229
|
+
const protectedSet = new Set([
|
|
20230
|
+
...windowSet,
|
|
20231
|
+
...protectedToolTagNumbers(activeTags, deps.resolveProtectedTools?.(ctx) ?? deps.protectedTools)
|
|
20232
|
+
]);
|
|
20113
20233
|
const tagStatusMap = new Map(allTags.map((tag) => [tag.tagNumber, tag.status]));
|
|
20114
20234
|
const inertWhitespaceTagNumbers = new Set(getInertWhitespaceAssistantTags(deps.db, sessionId).map((tag) => tag.tagNumber));
|
|
20115
20235
|
const inertDropIds = [
|
|
@@ -20139,7 +20259,14 @@ function createCtxReduceTool(deps) {
|
|
|
20139
20259
|
].filter(Boolean).join(" ");
|
|
20140
20260
|
dropIds = dropIds.filter((id) => !inertWhitespaceTagNumbers.has(id) && tagStatusMap.get(id) !== "dropped" && pendingMap.get(id) !== "drop");
|
|
20141
20261
|
if (dropIds.length === 0) {
|
|
20142
|
-
|
|
20262
|
+
const noActionNotes = [
|
|
20263
|
+
ctxReduceSelfStampNote,
|
|
20264
|
+
inertNote,
|
|
20265
|
+
skippedNote
|
|
20266
|
+
].filter(Boolean);
|
|
20267
|
+
if (!ctxReduceSelfStampNote)
|
|
20268
|
+
noActionNotes.push("No new action is needed.");
|
|
20269
|
+
return ok4(noActionNotes.join(" "));
|
|
20143
20270
|
}
|
|
20144
20271
|
try {
|
|
20145
20272
|
deps.db.transaction(() => {
|
|
@@ -20164,7 +20291,8 @@ function createCtxReduceTool(deps) {
|
|
|
20164
20291
|
parts.push(`drop ${formatIds(immediateDropIds)}`);
|
|
20165
20292
|
if (deferredDropIds.length > 0)
|
|
20166
20293
|
parts.push(`deferred drop ${formatIds(deferredDropIds)}`);
|
|
20167
|
-
|
|
20294
|
+
const held = deferredDropIds.length === 1 ? `Held: §${deferredDropIds[0]} is inside the protected working set; it applies once newer work displaces it.` : deferredDropIds.length > 1 ? `Held: ${deferredDropIds.map((id) => `§${id}`).join(", ")} are inside the protected working set; they apply once newer work displaces them.` : "";
|
|
20295
|
+
return ok4(`Queued: ${parts.join(", ")}.${held ? ` ${held}` : ""}${skippedNote ? ` ${skippedNote}` : ""}${inertNote ? ` ${inertNote}` : ""}${ctxReduceSelfStampNote ? ` ${ctxReduceSelfStampNote}` : ""}`);
|
|
20168
20296
|
}
|
|
20169
20297
|
};
|
|
20170
20298
|
}
|
|
@@ -20395,6 +20523,47 @@ var ftsPlainStatements = new WeakMap;
|
|
|
20395
20523
|
var datedFtsPlainStatements = new WeakMap;
|
|
20396
20524
|
var getBySHAsStatements = new WeakMap;
|
|
20397
20525
|
var datedGetBySHAsStatements = new WeakMap;
|
|
20526
|
+
var embeddingCache = new WeakMap;
|
|
20527
|
+
function getSearchEmbeddings(db, projectPath, modelId) {
|
|
20528
|
+
if (!isKnownAutocommit(db)) {
|
|
20529
|
+
embeddingCache.delete(db);
|
|
20530
|
+
return loadProjectCommitEmbeddings(db, projectPath, modelId);
|
|
20531
|
+
}
|
|
20532
|
+
let cache = embeddingCache.get(db);
|
|
20533
|
+
if (!cache) {
|
|
20534
|
+
cache = {
|
|
20535
|
+
revisionStatement: db.prepare(`SELECT total_changes() AS writes,
|
|
20536
|
+
(SELECT data_version FROM pragma_data_version) AS dataVersion,
|
|
20537
|
+
(SELECT schema_version FROM pragma_schema_version) AS schemaVersion`),
|
|
20538
|
+
revision: "",
|
|
20539
|
+
entries: new Map
|
|
20540
|
+
};
|
|
20541
|
+
embeddingCache.set(db, cache);
|
|
20542
|
+
}
|
|
20543
|
+
const revision = JSON.stringify(cache.revisionStatement.get());
|
|
20544
|
+
if (revision !== cache.revision) {
|
|
20545
|
+
cache.entries.clear();
|
|
20546
|
+
cache.revision = revision;
|
|
20547
|
+
}
|
|
20548
|
+
const key = JSON.stringify([projectPath, modelId]);
|
|
20549
|
+
const cached = cache.entries.get(key);
|
|
20550
|
+
if (cached) {
|
|
20551
|
+
cache.entries.delete(key);
|
|
20552
|
+
cache.entries.set(key, cached);
|
|
20553
|
+
return cached;
|
|
20554
|
+
}
|
|
20555
|
+
const vectors = loadProjectCommitEmbeddings(db, projectPath, modelId);
|
|
20556
|
+
const size = (entries) => [...entries.values()].reduce((sum, vector) => sum + vector.byteLength, 0);
|
|
20557
|
+
if (size(vectors) <= 32 * 1024 * 1024)
|
|
20558
|
+
cache.entries.set(key, vectors);
|
|
20559
|
+
while (cache.entries.size > 16 || [...cache.entries.values()].reduce((sum, entry) => sum + size(entry), 0) > 32 * 1024 * 1024) {
|
|
20560
|
+
const oldest = cache.entries.keys().next().value;
|
|
20561
|
+
if (oldest === undefined)
|
|
20562
|
+
break;
|
|
20563
|
+
cache.entries.delete(oldest);
|
|
20564
|
+
}
|
|
20565
|
+
return vectors;
|
|
20566
|
+
}
|
|
20398
20567
|
function rowToCommit(row) {
|
|
20399
20568
|
return {
|
|
20400
20569
|
sha: row.sha,
|
|
@@ -20491,7 +20660,7 @@ function searchGitCommitsSync(db, projectPath, query, options) {
|
|
|
20491
20660
|
});
|
|
20492
20661
|
const semanticScores = new Map;
|
|
20493
20662
|
if (options.queryEmbedding && options.queryModelId && options.queryModelId !== "off") {
|
|
20494
|
-
const embeddings =
|
|
20663
|
+
const embeddings = getSearchEmbeddings(db, projectPath, options.queryModelId);
|
|
20495
20664
|
for (const [sha, embedding] of embeddings.entries()) {
|
|
20496
20665
|
const similarity = clamp01(cosineSimilarity(options.queryEmbedding, embedding));
|
|
20497
20666
|
if (similarity > 0) {
|
|
@@ -22861,30 +23030,45 @@ function muralImageTokenEstimateForDimensions(width, height) {
|
|
|
22861
23030
|
var muralImageTokenEstimate = muralImageTokenEstimateForDimensions(MURAL_WIDTH, MURAL_HEIGHT);
|
|
22862
23031
|
|
|
22863
23032
|
// ../plugin/src/features/magic-context/mural/resolve-mural.ts
|
|
22864
|
-
function
|
|
23033
|
+
function readMuralPool(db, projectIdentity) {
|
|
22865
23034
|
const memories = getMemoriesByProject(db, projectIdentity, ["active", "permanent"]);
|
|
22866
|
-
|
|
23035
|
+
return {
|
|
23036
|
+
memories,
|
|
23037
|
+
cueState: getMuralCueState(db, memories.map((memory) => memory.id)),
|
|
23038
|
+
contentHashes: new Map
|
|
23039
|
+
};
|
|
23040
|
+
}
|
|
23041
|
+
function poolContentHash(pool, memory) {
|
|
23042
|
+
const cached = pool?.contentHashes.get(memory.id);
|
|
23043
|
+
if (cached?.content === memory.content)
|
|
23044
|
+
return cached.hash;
|
|
23045
|
+
const value = computeCueContentHash(memory.content);
|
|
23046
|
+
pool?.contentHashes.set(memory.id, { content: memory.content, hash: value });
|
|
23047
|
+
return value;
|
|
23048
|
+
}
|
|
23049
|
+
function getMuralCoverage(db, projectIdentity, pool) {
|
|
23050
|
+
const { memories, cueState } = pool ?? readMuralPool(db, projectIdentity);
|
|
22867
23051
|
let cuedMemoryCount = 0;
|
|
22868
23052
|
for (const memory of memories) {
|
|
22869
23053
|
const state = cueState.get(memory.id);
|
|
22870
|
-
if (state && typeof state.cue === "string" && state.cue.trim() !== "" && state.hash !== null && state.hash ===
|
|
23054
|
+
if (state && typeof state.cue === "string" && state.cue.trim() !== "" && state.hash !== null && state.hash === poolContentHash(pool, memory)) {
|
|
22871
23055
|
cuedMemoryCount += 1;
|
|
22872
23056
|
}
|
|
22873
23057
|
}
|
|
22874
23058
|
return { activeMemoryCount: memories.length, cuedMemoryCount };
|
|
22875
23059
|
}
|
|
22876
|
-
function resolveMural(db, projectIdentity, budgetTokens = DEFAULT_MURAL_MEMORY_BUDGET) {
|
|
22877
|
-
const memories = getMemoriesByProject(db, projectIdentity, ["active", "permanent"]);
|
|
23060
|
+
function resolveMural(db, projectIdentity, budgetTokens = DEFAULT_MURAL_MEMORY_BUDGET, pool) {
|
|
23061
|
+
const memories = pool?.memories ?? getMemoriesByProject(db, projectIdentity, ["active", "permanent"]);
|
|
22878
23062
|
const overflow = muralOverflowMemories(memories, budgetTokens);
|
|
22879
23063
|
if (overflow.length === 0)
|
|
22880
23064
|
return [];
|
|
22881
|
-
const cueState = getMuralCueState(db, overflow.map((memory) => memory.id));
|
|
23065
|
+
const cueState = pool?.cueState ?? getMuralCueState(db, overflow.map((memory) => memory.id));
|
|
22882
23066
|
const entries = [];
|
|
22883
23067
|
for (const memory of overflow) {
|
|
22884
23068
|
const state = cueState.get(memory.id);
|
|
22885
23069
|
if (!state || state.cue === null || state.hash === null)
|
|
22886
23070
|
continue;
|
|
22887
|
-
if (state.hash !==
|
|
23071
|
+
if (state.hash !== poolContentHash(pool, memory))
|
|
22888
23072
|
continue;
|
|
22889
23073
|
entries.push({
|
|
22890
23074
|
id: memory.id,
|
|
@@ -22971,13 +23155,14 @@ function muralCoverageGate(cuedMemoryCount, activeMemoryCount) {
|
|
|
22971
23155
|
return cuedMemoryCount >= MIN_MURAL_CUED_MEMORIES || cuedMemoryCount >= MIN_MURAL_COVERAGE * activeMemoryCount;
|
|
22972
23156
|
}
|
|
22973
23157
|
function ensureMuralRendered(db, projectIdentity, budgetTokens = DEFAULT_MURAL_MEMORY_BUDGET) {
|
|
22974
|
-
const
|
|
23158
|
+
const pool = readMuralPool(db, projectIdentity);
|
|
23159
|
+
const coverage = getMuralCoverage(db, projectIdentity, pool);
|
|
22975
23160
|
if (coverage.activeMemoryCount === 0 || !muralCoverageGate(coverage.cuedMemoryCount, coverage.activeMemoryCount)) {
|
|
22976
23161
|
const skipReason = coverage.activeMemoryCount === 0 ? "no active memories" : `only ${coverage.cuedMemoryCount}/${coverage.activeMemoryCount} active memories have current cues (requires ${MIN_MURAL_CUED_MEMORIES} cues or ${MIN_MURAL_COVERAGE * 100}% coverage)`;
|
|
22977
23162
|
log(`[mural] skipped for ${projectIdentity}: ${skipReason}`);
|
|
22978
23163
|
return { hasMural: false, rerendered: false, skipReason };
|
|
22979
23164
|
}
|
|
22980
|
-
const entries = resolveMural(db, projectIdentity, budgetTokens);
|
|
23165
|
+
const entries = resolveMural(db, projectIdentity, budgetTokens, pool);
|
|
22981
23166
|
if (entries.length === 0) {
|
|
22982
23167
|
return { hasMural: false, rerendered: false };
|
|
22983
23168
|
}
|
|
@@ -23206,6 +23391,38 @@ function getOpenCodeDbPath() {
|
|
|
23206
23391
|
return resolveOpenCodeDbPath().path;
|
|
23207
23392
|
}
|
|
23208
23393
|
var cachedWriteDb = null;
|
|
23394
|
+
var cachedRemovalDb = null;
|
|
23395
|
+
var MARKER_BUSY_TIMEOUT_MS = 250;
|
|
23396
|
+
var MARKER_REMOVAL_BUSY_TIMEOUT_MS = 5000;
|
|
23397
|
+
function runMarkerWriteTransaction(db, site, operation) {
|
|
23398
|
+
if (db.inTransaction)
|
|
23399
|
+
return db.transaction(operation).immediate();
|
|
23400
|
+
const startedAt = performance.now();
|
|
23401
|
+
let acquiredAt;
|
|
23402
|
+
let workFinishedAt;
|
|
23403
|
+
let committed = false;
|
|
23404
|
+
try {
|
|
23405
|
+
const result = db.transaction(() => {
|
|
23406
|
+
acquiredAt = performance.now();
|
|
23407
|
+
try {
|
|
23408
|
+
return operation();
|
|
23409
|
+
} finally {
|
|
23410
|
+
workFinishedAt = performance.now();
|
|
23411
|
+
}
|
|
23412
|
+
}).immediate();
|
|
23413
|
+
committed = true;
|
|
23414
|
+
return result;
|
|
23415
|
+
} finally {
|
|
23416
|
+
const finishedAt = performance.now();
|
|
23417
|
+
const acquireMs = (acquiredAt ?? finishedAt) - startedAt;
|
|
23418
|
+
const holdMs = acquiredAt === undefined ? 0 : finishedAt - acquiredAt;
|
|
23419
|
+
const workMs = acquiredAt === undefined ? 0 : (workFinishedAt ?? finishedAt) - acquiredAt;
|
|
23420
|
+
const endMs = workFinishedAt === undefined ? 0 : finishedAt - workFinishedAt;
|
|
23421
|
+
try {
|
|
23422
|
+
log(`[magic-context] sqlite writer site=${site} db=opencode acquire_ms=${Math.round(acquireMs)} hold_ms=${Math.round(holdMs)} work_ms=${Math.round(workMs)} end_ms=${Math.round(endMs)} outcome=${acquiredAt === undefined ? "not_acquired" : committed ? "committed" : "failed"}`);
|
|
23423
|
+
} catch {}
|
|
23424
|
+
}
|
|
23425
|
+
}
|
|
23209
23426
|
var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
23210
23427
|
var REQUIRED_PART_COLUMNS = [
|
|
23211
23428
|
"id",
|
|
@@ -23238,18 +23455,19 @@ function isOpenCodeSchemaCompatible(db, dbPath) {
|
|
|
23238
23455
|
return false;
|
|
23239
23456
|
}
|
|
23240
23457
|
}
|
|
23241
|
-
function getWritableOpenCodeDb() {
|
|
23458
|
+
function getWritableOpenCodeDb(purpose = "publication") {
|
|
23242
23459
|
if (!harnessOwnsOpenCodeStore()) {
|
|
23243
23460
|
throw new Error("OpenCode database is not writable from a Pi-compatible process");
|
|
23244
23461
|
}
|
|
23245
23462
|
const resolution = resolveOpenCodeDbPath();
|
|
23246
23463
|
const dbPath = resolution.path;
|
|
23247
|
-
|
|
23248
|
-
|
|
23464
|
+
const cached = purpose === "removal" ? cachedRemovalDb : cachedWriteDb;
|
|
23465
|
+
if (cached?.path === dbPath) {
|
|
23466
|
+
return cached.db;
|
|
23249
23467
|
}
|
|
23250
|
-
if (
|
|
23468
|
+
if (cached) {
|
|
23251
23469
|
try {
|
|
23252
|
-
closeQuietly(
|
|
23470
|
+
closeQuietly(cached.db);
|
|
23253
23471
|
} catch {}
|
|
23254
23472
|
}
|
|
23255
23473
|
if (!existsSync10(dbPath)) {
|
|
@@ -23262,9 +23480,13 @@ function getWritableOpenCodeDb() {
|
|
|
23262
23480
|
closeQuietly(db);
|
|
23263
23481
|
throw error;
|
|
23264
23482
|
}
|
|
23265
|
-
|
|
23483
|
+
const timeoutMs = purpose === "removal" ? MARKER_REMOVAL_BUSY_TIMEOUT_MS : MARKER_BUSY_TIMEOUT_MS;
|
|
23484
|
+
db.exec(`PRAGMA busy_timeout=${timeoutMs}`);
|
|
23266
23485
|
db.exec("PRAGMA journal_mode=WAL");
|
|
23267
|
-
|
|
23486
|
+
if (purpose === "removal")
|
|
23487
|
+
cachedRemovalDb = { path: dbPath, db };
|
|
23488
|
+
else
|
|
23489
|
+
cachedWriteDb = { path: dbPath, db };
|
|
23268
23490
|
return db;
|
|
23269
23491
|
}
|
|
23270
23492
|
function getNonSummaryMessageSortKey(sessionId, messageId) {
|
|
@@ -23295,10 +23517,10 @@ function findBoundaryUserMessage(sessionId, endMessageId) {
|
|
|
23295
23517
|
AND (time_created < ? OR (time_created = ? AND id <= ?))
|
|
23296
23518
|
AND NOT (
|
|
23297
23519
|
EXISTS (SELECT 1 FROM part p
|
|
23298
|
-
WHERE p.message_id = message.id AND p.session_id = message.session_id
|
|
23520
|
+
WHERE p.message_id = message.id AND +p.session_id = message.session_id
|
|
23299
23521
|
AND COALESCE(json_extract(p.data, '$.type'), '') <> 'compaction')
|
|
23300
23522
|
AND NOT EXISTS (SELECT 1 FROM part p
|
|
23301
|
-
WHERE p.message_id = message.id AND p.session_id = message.session_id
|
|
23523
|
+
WHERE p.message_id = message.id AND +p.session_id = message.session_id
|
|
23302
23524
|
AND COALESCE(json_extract(p.data, '$.type'), '') <> 'compaction'
|
|
23303
23525
|
AND COALESCE(json_extract(p.data, '$.synthetic'), 0) <> 1
|
|
23304
23526
|
AND COALESCE(json_extract(p.data, '$.syntheticTodoMarker'), 0) <> 1)
|
|
@@ -23325,6 +23547,25 @@ function compareOpenCodeMessagesByCanonicalOrder(sessionId, leftMessageId, right
|
|
|
23325
23547
|
return 1;
|
|
23326
23548
|
return 0;
|
|
23327
23549
|
}
|
|
23550
|
+
function isOpenCodeGapHistorianAbsent(sessionId, endId, nextId) {
|
|
23551
|
+
const end = getNonSummaryMessageSortKey(sessionId, endId);
|
|
23552
|
+
const next = getNonSummaryMessageSortKey(sessionId, nextId);
|
|
23553
|
+
if (!end || !next || end.timeCreated > next.timeCreated || end.timeCreated === next.timeCreated && end.id >= next.id)
|
|
23554
|
+
return false;
|
|
23555
|
+
const row = getWritableOpenCodeDb().prepare(`SELECT 1 FROM message m
|
|
23556
|
+
WHERE m.session_id=?
|
|
23557
|
+
AND (m.time_created>? OR (m.time_created=? AND m.id>?))
|
|
23558
|
+
AND (m.time_created<? OR (m.time_created=? AND m.id<?))
|
|
23559
|
+
AND NOT (COALESCE(json_type(m.data,'$.summary'),'')='true' AND COALESCE(json_extract(m.data,'$.finish'),'')='stop')
|
|
23560
|
+
AND NOT (
|
|
23561
|
+
EXISTS (SELECT 1 FROM part p WHERE p.message_id=m.id AND +p.session_id=m.session_id AND COALESCE(json_extract(p.data,'$.type'),'')<>'compaction')
|
|
23562
|
+
AND NOT EXISTS (SELECT 1 FROM part p WHERE p.message_id=m.id AND +p.session_id=m.session_id
|
|
23563
|
+
AND COALESCE(json_extract(p.data,'$.type'),'')<>'compaction'
|
|
23564
|
+
AND COALESCE(json_type(p.data,'$.synthetic'),'')<>'true'
|
|
23565
|
+
AND COALESCE(json_type(p.data,'$.syntheticTodoMarker'),'')<>'true')
|
|
23566
|
+
) LIMIT 1`).get(sessionId, end.timeCreated, end.timeCreated, end.id, next.timeCreated, next.timeCreated, next.id);
|
|
23567
|
+
return !row;
|
|
23568
|
+
}
|
|
23328
23569
|
function removeLegacyMarkerLineageRows(db, args) {
|
|
23329
23570
|
const legacySummaries = db.prepare(`SELECT m.id
|
|
23330
23571
|
FROM message m
|
|
@@ -23387,7 +23628,7 @@ function injectCompactionMarker(args) {
|
|
|
23387
23628
|
time: { created: boundaryTime + 1, completed: boundaryTime + 1 }
|
|
23388
23629
|
});
|
|
23389
23630
|
try {
|
|
23390
|
-
db
|
|
23631
|
+
runMarkerWriteTransaction(db, "compaction-marker-inject", () => {
|
|
23391
23632
|
removeLegacyMarkerLineageRows(db, {
|
|
23392
23633
|
sessionId: args.sessionId,
|
|
23393
23634
|
boundaryMessageId: boundary.id,
|
|
@@ -23418,7 +23659,7 @@ function injectCompactionMarker(args) {
|
|
|
23418
23659
|
time_created = excluded.time_created,
|
|
23419
23660
|
time_updated = excluded.time_updated,
|
|
23420
23661
|
data = excluded.data`).run(summaryPartId, summaryMsgId, args.sessionId, boundaryTime + 1, boundaryTime + 1, JSON.stringify({ type: "text", text: args.summaryText }));
|
|
23421
|
-
})
|
|
23662
|
+
});
|
|
23422
23663
|
log(`[magic-context] compaction-marker: injected boundary at user msg ${boundary.id} (ordinal ~${args.endOrdinal}), summary msg ${summaryMsgId}`);
|
|
23423
23664
|
return {
|
|
23424
23665
|
boundaryMessageId: boundary.id,
|
|
@@ -23432,9 +23673,14 @@ function injectCompactionMarker(args) {
|
|
|
23432
23673
|
}
|
|
23433
23674
|
}
|
|
23434
23675
|
function replaceCompactionMarker(existing, args) {
|
|
23435
|
-
|
|
23676
|
+
let connection;
|
|
23677
|
+
let entered = false;
|
|
23678
|
+
let readyToCommit = false;
|
|
23436
23679
|
try {
|
|
23437
|
-
|
|
23680
|
+
const db = getWritableOpenCodeDb();
|
|
23681
|
+
connection = db;
|
|
23682
|
+
const marker = runMarkerWriteTransaction(db, "compaction-marker-replace", () => {
|
|
23683
|
+
entered = true;
|
|
23438
23684
|
if (existing) {
|
|
23439
23685
|
db.prepare("DELETE FROM part WHERE id = ?").run(existing.summaryPartId);
|
|
23440
23686
|
db.prepare("DELETE FROM message WHERE id = ?").run(existing.summaryMessageId);
|
|
@@ -23444,11 +23690,17 @@ function replaceCompactionMarker(existing, args) {
|
|
|
23444
23690
|
if (!replacement) {
|
|
23445
23691
|
throw new Error(`failed to inject replacement marker at ordinal ${args.endOrdinal}`);
|
|
23446
23692
|
}
|
|
23693
|
+
readyToCommit = true;
|
|
23447
23694
|
return replacement;
|
|
23448
|
-
})
|
|
23695
|
+
});
|
|
23696
|
+
return { kind: "committed", marker };
|
|
23449
23697
|
} catch (error) {
|
|
23450
23698
|
log(`[magic-context] compaction-marker: atomic replacement failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
23451
|
-
|
|
23699
|
+
const definitelyNoCut = !entered || !readyToCommit && connection?.inTransaction === false;
|
|
23700
|
+
return {
|
|
23701
|
+
kind: definitelyNoCut ? "definitely-no-cut" : "uncertain",
|
|
23702
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
23703
|
+
};
|
|
23452
23704
|
}
|
|
23453
23705
|
}
|
|
23454
23706
|
|
|
@@ -23500,6 +23752,21 @@ function existingMarkerAlreadyCoversTarget(sessionId, existing, targetOrdinal, t
|
|
|
23500
23752
|
}
|
|
23501
23753
|
return true;
|
|
23502
23754
|
}
|
|
23755
|
+
function boundaryWouldDiscardUncoveredMessage(db, sessionId, ordinal, boundaryMessageId) {
|
|
23756
|
+
const current = getPersistedCompactionMarkerState(db, sessionId);
|
|
23757
|
+
const partials = getUncoveredCompartmentEndsThrough(db, sessionId, ordinal);
|
|
23758
|
+
for (const partial of partials) {
|
|
23759
|
+
if (current && compareOpenCodeMessagesByCanonicalOrder(sessionId, partial.endMessageId, current.boundaryMessageId) === -1)
|
|
23760
|
+
continue;
|
|
23761
|
+
const ordering = compareOpenCodeMessagesByCanonicalOrder(sessionId, boundaryMessageId, partial.endMessageId);
|
|
23762
|
+
if (ordering !== null && ordering <= 0)
|
|
23763
|
+
continue;
|
|
23764
|
+
if (partial.successorStartMessageId && partial.successorStartMessage !== null && partial.successorStartMessage > partial.endMessage + 1 && isOpenCodeGapHistorianAbsent(sessionId, partial.endMessageId, partial.successorStartMessageId))
|
|
23765
|
+
continue;
|
|
23766
|
+
return true;
|
|
23767
|
+
}
|
|
23768
|
+
return false;
|
|
23769
|
+
}
|
|
23503
23770
|
function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
|
|
23504
23771
|
if (getHarness() !== "opencode") {
|
|
23505
23772
|
return true;
|
|
@@ -23509,9 +23776,6 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
23509
23776
|
sessionLog(sessionId, `compaction-marker: no compartment endMessageId for ordinal ${lastCompartmentEnd}; preserving existing marker`);
|
|
23510
23777
|
return false;
|
|
23511
23778
|
}
|
|
23512
|
-
if (hasPartialCompartmentEndThrough(db, sessionId, lastCompartmentEnd)) {
|
|
23513
|
-
return false;
|
|
23514
|
-
}
|
|
23515
23779
|
const existing = getPersistedCompactionMarkerState(db, sessionId);
|
|
23516
23780
|
const removedSummaryMessageId = existing?.summaryMessageId ?? null;
|
|
23517
23781
|
if (existing) {
|
|
@@ -23524,7 +23788,10 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
23524
23788
|
sessionLog(sessionId, `compaction-marker: no user boundary found at or before endMessageId ${targetEndMessageId} (ordinal ${lastCompartmentEnd}); preserving existing marker`);
|
|
23525
23789
|
return false;
|
|
23526
23790
|
}
|
|
23527
|
-
|
|
23791
|
+
if (boundaryWouldDiscardUncoveredMessage(db, sessionId, lastCompartmentEnd, boundary.id)) {
|
|
23792
|
+
return false;
|
|
23793
|
+
}
|
|
23794
|
+
const replacement = replaceCompactionMarker(existing, {
|
|
23528
23795
|
sessionId,
|
|
23529
23796
|
endOrdinal: lastCompartmentEnd,
|
|
23530
23797
|
endMessageId: targetEndMessageId,
|
|
@@ -23532,7 +23799,8 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
23532
23799
|
directory: directory ?? process.cwd(),
|
|
23533
23800
|
resolvedBoundary: boundary
|
|
23534
23801
|
});
|
|
23535
|
-
if (
|
|
23802
|
+
if (replacement.kind === "committed") {
|
|
23803
|
+
const result = replacement.marker;
|
|
23536
23804
|
persistMarkerStateAndDropReplacedTag(db, sessionId, {
|
|
23537
23805
|
...result,
|
|
23538
23806
|
boundaryOrdinal: lastCompartmentEnd,
|
|
@@ -23552,6 +23820,7 @@ var MEMORY_EPOCH_COMPONENT_PREFIX = "|memory-render:";
|
|
|
23552
23820
|
var MURAL_COMPONENT_PREFIX = "|mural-enabled:";
|
|
23553
23821
|
var BUDGET_COMPONENT_PREFIX = "|render-budgets:";
|
|
23554
23822
|
var RENDERED_BUDGETS_COMPONENT_PREFIX = "|rendered-budgets:";
|
|
23823
|
+
var M0_MEMORY_IDS_COMPONENT_PREFIX = "|m0-memory-ids:";
|
|
23555
23824
|
function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH, muralEnabled = null, renderBudgetIdentity = null, memoryRenderEpoch = MEMORY_RENDER_FORMAT_EPOCH, renderedBudgets = null) {
|
|
23556
23825
|
let encoded = upgradeState ?? "";
|
|
23557
23826
|
if (compartmentRenderEpoch !== null) {
|
|
@@ -23596,7 +23865,8 @@ function decodeCachedM0UpgradeIdentity(value) {
|
|
|
23596
23865
|
value.indexOf(MEMORY_EPOCH_COMPONENT_PREFIX),
|
|
23597
23866
|
value.indexOf(MURAL_COMPONENT_PREFIX),
|
|
23598
23867
|
value.indexOf(BUDGET_COMPONENT_PREFIX),
|
|
23599
|
-
value.indexOf(RENDERED_BUDGETS_COMPONENT_PREFIX)
|
|
23868
|
+
value.indexOf(RENDERED_BUDGETS_COMPONENT_PREFIX),
|
|
23869
|
+
value.indexOf(M0_MEMORY_IDS_COMPONENT_PREFIX)
|
|
23600
23870
|
].filter((index) => index >= 0);
|
|
23601
23871
|
const identityEnd = componentIndexes.length > 0 ? Math.min(...componentIndexes) : value.length;
|
|
23602
23872
|
const upgradeState = value.slice(0, identityEnd);
|
|
@@ -23610,6 +23880,22 @@ function decodeCachedM0UpgradeIdentity(value) {
|
|
|
23610
23880
|
renderedBudgets: component(value, RENDERED_BUDGETS_COMPONENT_PREFIX)
|
|
23611
23881
|
};
|
|
23612
23882
|
}
|
|
23883
|
+
function withCachedM0MemoryIds(identity, ids) {
|
|
23884
|
+
const withoutIds = (identity ?? "").replace(/\|m0-memory-ids:[^|]*/g, "");
|
|
23885
|
+
return `${withoutIds}${M0_MEMORY_IDS_COMPONENT_PREFIX}${JSON.stringify(ids)}`;
|
|
23886
|
+
}
|
|
23887
|
+
function readCachedM0MemoryIds(identity, legacyVisibleIds, maxMemoryId) {
|
|
23888
|
+
const encoded = component(identity ?? "", M0_MEMORY_IDS_COMPONENT_PREFIX);
|
|
23889
|
+
if (encoded !== null) {
|
|
23890
|
+
try {
|
|
23891
|
+
const ids = JSON.parse(encoded);
|
|
23892
|
+
if (Array.isArray(ids) && ids.every((id) => Number.isSafeInteger(id) && id > 0)) {
|
|
23893
|
+
return ids;
|
|
23894
|
+
}
|
|
23895
|
+
} catch {}
|
|
23896
|
+
}
|
|
23897
|
+
return legacyVisibleIds.filter((id) => id <= maxMemoryId);
|
|
23898
|
+
}
|
|
23613
23899
|
function renderBudgetIdentityChanged(cached, current) {
|
|
23614
23900
|
const legacy = /^(m[^-]+)-h\d+$/.exec(cached);
|
|
23615
23901
|
if (legacy && current.startsWith("m") && current.includes("-hp")) {
|
|
@@ -23890,6 +24176,7 @@ function formatGap(seconds) {
|
|
|
23890
24176
|
return days === 0 ? `+${weeks}w` : `+${weeks}w ${days}d`;
|
|
23891
24177
|
}
|
|
23892
24178
|
var TEMPORAL_MARKER_PATTERN = /^<!-- \+[\d]+[mhdw](?: [\d]+[mhdw])? -->\n/;
|
|
24179
|
+
var TEMPORAL_MARKER_REPLAY_PATTERN = /^<!-- \+[\d]+[mhdw](?: [\d]+[mhdw])? -->(?:\n|$)/;
|
|
23893
24180
|
function temporalMarkerPrefix(seconds) {
|
|
23894
24181
|
const marker = formatGap(seconds);
|
|
23895
24182
|
if (!marker)
|
|
@@ -24503,9 +24790,11 @@ function registerMagicContextTools(pi, opts) {
|
|
|
24503
24790
|
pi.registerTool(surfaceTool(createCtxReduceTool({
|
|
24504
24791
|
db: opts.db,
|
|
24505
24792
|
protectedTags: opts.protectedTags ?? 20,
|
|
24793
|
+
protectedTools: opts.protectedTools,
|
|
24794
|
+
resolveProtectedTools: opts.resolveProtectedTools,
|
|
24506
24795
|
resolveProtectedTags: opts.resolveProtectedTags
|
|
24507
24796
|
})));
|
|
24508
24797
|
}
|
|
24509
24798
|
}
|
|
24510
24799
|
|
|
24511
|
-
export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, formatConfigParseStatusLine, formatConfigParseNotice, claimConfigParseFailuresOnce, parseJsoncRecovering, detectConfigFile, MIN_PLAUSIBLE_CONTEXT_LIMIT, catalogOutputReserve, reloadWindowOverlay, getWindowOverlay, resolveWindowOverlayFacts, deriveWindowGeometry, hasTrustedAbsoluteWall, applyProvenInputFloor, formatWindowDerivationLine, isSaneLimit, resolveOutputReserve, getSdkWindowGeometry, getSdkContextLimit, getSdkOutputLimit, getSdkInputLimit, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, migrateMagicContextConfigLocations, getProtectedTokensTierOverrides, MAX_EXECUTE_THRESHOLD, escalationBands, HYGIENE_PROVIDER_UNITS_VERSION, sessionDecisionCalibration, transitionSessionHygieneUnits, computeProtectionWindow, readEpochFloorSnapshot, getProtectionWindowForSession, persistCachedM0, clearCachedM0M1, ReplayDocumentError, readReplayEnvelope, updateReplayDocument, isProviderOverflowFailClosedProven, describeProtectedTailDrainBudgetSkip, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, getHistorianFailureState, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, THINKING_BINDING_RECOVERY_FROZEN_PREFIX, THINKING_BINDING_STRIP_ORDER_END_MARKER, thinkingBindingRecoveryFrozenId, getThinkingBindingRecoveryTarget, armThinkingBindingRecovery, clearThinkingBindingRecoveryIf, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, getCompactionMarkerHealth, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, setSessionWorkMetrics, getSessionWorkMetrics, resolveEpochFloorForPass, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, deleteChunkEmbedBackoffForSession, chunkWindowSourceKey, readSessionActivity, observeSessionActivity, backfillSessionActivity, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, recordSessionProjectIdentity, embedPauseBySession, embedRunStateBySession, autoEmbedAttemptedBySession, autoEmbedIdentityBySession, invalidateAutoEmbedSession, getEmbedDrainUiStatus, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, clearCompressionDepth, clearCompressionDepthRange, isNoContentCompartment, HAS_COMPARTMENT_CONTENT_SQL, queueM0Mutation, getMaxM0MutationId, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, isPartialCompartmentEnd, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, readProjectDocsCanonical,
|
|
24800
|
+
export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, formatConfigParseStatusLine, formatConfigParseNotice, claimConfigParseFailuresOnce, parseJsoncRecovering, detectConfigFile, MIN_PLAUSIBLE_CONTEXT_LIMIT, catalogOutputReserve, reloadWindowOverlay, getWindowOverlay, resolveWindowOverlayFacts, deriveWindowGeometry, hasTrustedAbsoluteWall, applyProvenInputFloor, formatWindowDerivationLine, isSaneLimit, resolveOutputReserve, getSdkWindowGeometry, getSdkContextLimit, getSdkOutputLimit, getSdkInputLimit, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, migrateMagicContextConfigLocations, getProtectedTokensTierOverrides, BoundedSessionMap, MAX_EXECUTE_THRESHOLD, escalationBands, HYGIENE_PROVIDER_UNITS_VERSION, sessionDecisionCalibration, transitionSessionHygieneUnits, computeProtectionWindow, readEpochFloorSnapshot, getProtectionWindowForSession, persistCachedM0, clearCachedM0M1, isRustMarkerAdmissionFenced, ReplayDocumentError, readReplayEnvelope, updateReplayDocument, isProviderOverflowFailClosedProven, describeProtectedTailDrainBudgetSkip, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, getHistorianFailureState, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, THINKING_BINDING_RECOVERY_FROZEN_PREFIX, THINKING_BINDING_STRIP_ORDER_END_MARKER, thinkingBindingRecoveryFrozenId, getThinkingBindingRecoveryTarget, armThinkingBindingRecovery, clearThinkingBindingRecoveryIf, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, getCompactionMarkerHealth, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, setSessionWorkMetrics, getSessionWorkMetrics, resolveEpochFloorForPass, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, deleteChunkEmbedBackoffForSession, chunkWindowSourceKey, readSessionActivity, observeSessionActivity, backfillSessionActivity, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, recordSessionProjectIdentity, embedPauseBySession, embedRunStateBySession, autoEmbedAttemptedBySession, autoEmbedIdentityBySession, invalidateAutoEmbedSession, getEmbedDrainUiStatus, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, clearCompressionDepth, clearCompressionDepthRange, isNoContentCompartment, HAS_COMPARTMENT_CONTENT_SQL, queueM0Mutation, getMaxM0MutationId, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getUncoveredCompartmentEndThrough, isPartialCompartmentEnd, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, readProjectDocsCanonical, providerResponseFailed, isSuccessfulProviderCompletion, registerLkgPersistence, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, contentSnapshotValue, signatureForFields, lkgContentFields, lkgContentDigestFromFields, exactReusablePrefix, incrementalLkgContentDigests, captureSlot, getInMemorySlot, getSlot, dropSlot, noteEntry, encodePiContentDecision, decodePiContentDecision, getPiContentDecisions, freezePiContentDecision, getNativeReplayState, saveNativeToolInputs, addNativeReasoningIds, copySessionStateForClone, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, noteTouchedAt, noteNudgePickIndex, formatNoteNudge, setEmbeddingSessionBusy, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, readPiSessionSnapshot, readPiSessionMessages, readPiSessionMessagePage, findRestartModelSeedFromBranch, iterateEntriesToRawMessageRange, convertEntriesToRawMessages, convertPiAssistantEntryById, convertEntriesToRawMessagePage, countPiRawMessages, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, getMemoryById, setMemoryClassification, archiveMemory, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getTaskScheduleState, getFailingDreamTasks, getSkippedDreamTasks, getMostRecentTaskRunAt, pruneNonCanonicalTaskRows, deleteTaskScheduleRowsForProject, seedTaskScheduleState, writeTaskScheduleState, isRetrospectiveWindowProcessed, recordRetrospectiveWindowProcessed, curateCategoryForMemoryCategory, peekCurateCategoryScope, beginCurateCategoryRun, curateTaskStateAfterSuccess, cosineSimilarity, drainBackgroundBatches, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, describeShadowBackfillWriteRefusal, contentSha256, drainProjectEmbeddingIdentityMaintenance, drainStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, getAutoEmbeddingSessionCoverage, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, isDirectiveShapedProjectRule, takeCurateSafetyRefusalCount, wakePlaneStatus, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, loadPiConfigDetailed, unregisterPiProjectEmbeddings, ensureProjectRegisteredFromPiDirectory, resolvePiHarnessDetection, resolvePiHarnessKind, MEMORY_MURAL_BLOCK, buildMagicContextSection, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, MEMORY_RENDER_FORMAT_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, withCachedM0MemoryIds, readCachedM0MemoryIds, renderBudgetIdentityChanged, renderedBudgetSnapshot, renderedBudgetShrinkReason, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, TEMPORAL_MARKER_REPLAY_PATTERN, temporalMarkerPrefix, renderUserProfileContent, clearInjectionCache, getVisibleMemoryIds, orderHistorianMemories, renderHistorianMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, syncCtxMemoryToolEnabled, registerMagicContextTools };
|