@cortexkit/pi-magic-context 0.21.6 → 0.21.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1317 -358
- package/dist/subagent-entry.js +343 -74
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8163,10 +8163,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8163
8163
|
replacer = null;
|
|
8164
8164
|
indent = EMPTY;
|
|
8165
8165
|
};
|
|
8166
|
-
var
|
|
8166
|
+
var join10 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
8167
8167
|
var join_content = (inside, value, gap) => {
|
|
8168
8168
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
8169
|
-
return
|
|
8169
|
+
return join10(comment, inside, gap);
|
|
8170
8170
|
};
|
|
8171
8171
|
var stringify_string = (holder, key, value) => {
|
|
8172
8172
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -8188,13 +8188,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8188
8188
|
if (i !== 0) {
|
|
8189
8189
|
inside += COMMA;
|
|
8190
8190
|
}
|
|
8191
|
-
const before =
|
|
8191
|
+
const before = join10(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
8192
8192
|
inside += before || LF + deeper_gap;
|
|
8193
8193
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
8194
8194
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
8195
8195
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
8196
8196
|
}
|
|
8197
|
-
inside +=
|
|
8197
|
+
inside += join10(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
8198
8198
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
8199
8199
|
};
|
|
8200
8200
|
var object_stringify = (value, gap) => {
|
|
@@ -8215,13 +8215,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8215
8215
|
inside += COMMA;
|
|
8216
8216
|
}
|
|
8217
8217
|
first = false;
|
|
8218
|
-
const before =
|
|
8218
|
+
const before = join10(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
8219
8219
|
inside += before || LF + deeper_gap;
|
|
8220
8220
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
8221
8221
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
8222
8222
|
};
|
|
8223
8223
|
keys.forEach(iteratee);
|
|
8224
|
-
inside +=
|
|
8224
|
+
inside += join10(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
8225
8225
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
8226
8226
|
};
|
|
8227
8227
|
function stringify(key, holder, gap) {
|
|
@@ -8343,7 +8343,57 @@ var init_rpc_notifications = __esm(() => {
|
|
|
8343
8343
|
|
|
8344
8344
|
// src/index.ts
|
|
8345
8345
|
import { createRequire as createRequire4 } from "node:module";
|
|
8346
|
-
import { join as
|
|
8346
|
+
import { join as join20 } from "node:path";
|
|
8347
|
+
|
|
8348
|
+
// ../plugin/src/config/agent-disable.ts
|
|
8349
|
+
function isDreamerRunnable(config) {
|
|
8350
|
+
return !!config.dreamer && config.dreamer.disable !== true;
|
|
8351
|
+
}
|
|
8352
|
+
function clonePlainObject(value) {
|
|
8353
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
8354
|
+
return;
|
|
8355
|
+
}
|
|
8356
|
+
return { ...value };
|
|
8357
|
+
}
|
|
8358
|
+
function migrateLegacyEnabledForAgent(args) {
|
|
8359
|
+
const agent = clonePlainObject(args.patched[args.agentName]);
|
|
8360
|
+
if (!agent || !("enabled" in agent))
|
|
8361
|
+
return;
|
|
8362
|
+
const enabled = agent.enabled;
|
|
8363
|
+
const disable = agent.disable;
|
|
8364
|
+
delete agent.enabled;
|
|
8365
|
+
if (args.agentName === "historian") {
|
|
8366
|
+
args.warnings.push('Removed invalid "historian.enabled" in-memory (run doctor to persist).');
|
|
8367
|
+
args.patched.historian = agent;
|
|
8368
|
+
return;
|
|
8369
|
+
}
|
|
8370
|
+
if (args.agentName === "dreamer") {
|
|
8371
|
+
if (disable !== true && enabled === false) {
|
|
8372
|
+
agent.disable = true;
|
|
8373
|
+
args.warnings.push('Migrated "dreamer.enabled=false" → "dreamer.disable=true" in-memory (run doctor to persist). This now also disables manual /ctx-dream; for manual-only remove disable and set schedule="".');
|
|
8374
|
+
}
|
|
8375
|
+
args.patched.dreamer = agent;
|
|
8376
|
+
return;
|
|
8377
|
+
}
|
|
8378
|
+
if (disable !== true && enabled === false) {
|
|
8379
|
+
agent.disable = true;
|
|
8380
|
+
args.warnings.push('Migrated "sidekick.enabled=false" → "sidekick.disable=true" in-memory (run doctor to persist).');
|
|
8381
|
+
}
|
|
8382
|
+
args.patched.sidekick = agent;
|
|
8383
|
+
}
|
|
8384
|
+
function migrateLegacyAgentEnabledInMemory(rawConfig, warnings) {
|
|
8385
|
+
const shouldPatch = ["dreamer", "sidekick", "historian"].some((key) => {
|
|
8386
|
+
const agent = rawConfig[key];
|
|
8387
|
+
return typeof agent === "object" && agent !== null && !Array.isArray(agent) && "enabled" in agent;
|
|
8388
|
+
});
|
|
8389
|
+
if (!shouldPatch)
|
|
8390
|
+
return rawConfig;
|
|
8391
|
+
const patched = { ...rawConfig };
|
|
8392
|
+
migrateLegacyEnabledForAgent({ patched, agentName: "dreamer", warnings });
|
|
8393
|
+
migrateLegacyEnabledForAgent({ patched, agentName: "sidekick", warnings });
|
|
8394
|
+
migrateLegacyEnabledForAgent({ patched, agentName: "historian", warnings });
|
|
8395
|
+
return patched;
|
|
8396
|
+
}
|
|
8347
8397
|
|
|
8348
8398
|
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
8349
8399
|
import { execSync } from "node:child_process";
|
|
@@ -141830,6 +141880,40 @@ function parseReportedLimit(message) {
|
|
|
141830
141880
|
}
|
|
141831
141881
|
return;
|
|
141832
141882
|
}
|
|
141883
|
+
// ../plugin/src/features/magic-context/compartment-lease.ts
|
|
141884
|
+
var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
141885
|
+
var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
|
|
141886
|
+
function acquireCompartmentLease(db, sessionId, holderId) {
|
|
141887
|
+
const acquiredAt = Date.now();
|
|
141888
|
+
const expiresAt = acquiredAt + COMPARTMENT_LEASE_TTL_MS;
|
|
141889
|
+
const result = db.prepare(`INSERT INTO compartment_state_lease (session_id, holder_id, acquired_at, expires_at)
|
|
141890
|
+
VALUES (?, ?, ?, ?)
|
|
141891
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
141892
|
+
holder_id = excluded.holder_id,
|
|
141893
|
+
acquired_at = excluded.acquired_at,
|
|
141894
|
+
expires_at = excluded.expires_at
|
|
141895
|
+
WHERE compartment_state_lease.holder_id = excluded.holder_id
|
|
141896
|
+
OR compartment_state_lease.expires_at <= ?`).run(sessionId, holderId, acquiredAt, expiresAt, acquiredAt);
|
|
141897
|
+
if (result.changes !== 1) {
|
|
141898
|
+
return null;
|
|
141899
|
+
}
|
|
141900
|
+
return { sessionId, holderId, acquiredAt, expiresAt };
|
|
141901
|
+
}
|
|
141902
|
+
function renewCompartmentLease(db, sessionId, holderId) {
|
|
141903
|
+
const now = Date.now();
|
|
141904
|
+
const expiresAt = now + COMPARTMENT_LEASE_TTL_MS;
|
|
141905
|
+
const result = db.prepare(`UPDATE compartment_state_lease
|
|
141906
|
+
SET expires_at = ?, acquired_at = ?
|
|
141907
|
+
WHERE session_id = ? AND holder_id = ? AND expires_at > ?`).run(expiresAt, now, sessionId, holderId, now);
|
|
141908
|
+
return result.changes === 1;
|
|
141909
|
+
}
|
|
141910
|
+
function releaseCompartmentLease(db, sessionId, holderId) {
|
|
141911
|
+
db.prepare("DELETE FROM compartment_state_lease WHERE session_id = ? AND holder_id = ?").run(sessionId, holderId);
|
|
141912
|
+
}
|
|
141913
|
+
function isCompartmentLeaseHeld(db, sessionId, holderId) {
|
|
141914
|
+
const row = db.prepare("SELECT 1 FROM compartment_state_lease WHERE session_id = ? AND holder_id = ? AND expires_at > ?").get(sessionId, holderId, Date.now());
|
|
141915
|
+
return row != null;
|
|
141916
|
+
}
|
|
141833
141917
|
|
|
141834
141918
|
// ../plugin/src/features/magic-context/compartment-storage.ts
|
|
141835
141919
|
var insertCompartmentStatements = new WeakMap;
|
|
@@ -141940,6 +142024,38 @@ function replaceAllCompartmentState(db, sessionId, compartments, facts) {
|
|
|
141940
142024
|
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
141941
142025
|
})();
|
|
141942
142026
|
}
|
|
142027
|
+
function replaceAllCompartmentStateAndBumpDepth(db, holderId, sessionId, compartments, facts, depthStartOrdinal, depthEndOrdinal) {
|
|
142028
|
+
const now = Date.now();
|
|
142029
|
+
db.exec("BEGIN IMMEDIATE");
|
|
142030
|
+
let finished = false;
|
|
142031
|
+
try {
|
|
142032
|
+
if (!isCompartmentLeaseHeld(db, sessionId, holderId)) {
|
|
142033
|
+
db.exec("ROLLBACK");
|
|
142034
|
+
finished = true;
|
|
142035
|
+
return false;
|
|
142036
|
+
}
|
|
142037
|
+
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
142038
|
+
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
142039
|
+
insertCompartmentRows(db, sessionId, compartments, now);
|
|
142040
|
+
insertFactRows(db, sessionId, facts, now);
|
|
142041
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
142042
|
+
if (depthEndOrdinal >= depthStartOrdinal) {
|
|
142043
|
+
const stmt = getIncrementDepthStatement(db);
|
|
142044
|
+
for (let ordinal = depthStartOrdinal;ordinal <= depthEndOrdinal; ordinal += 1) {
|
|
142045
|
+
stmt.run(sessionId, ordinal, getHarness());
|
|
142046
|
+
}
|
|
142047
|
+
}
|
|
142048
|
+
db.exec("COMMIT");
|
|
142049
|
+
finished = true;
|
|
142050
|
+
return true;
|
|
142051
|
+
} finally {
|
|
142052
|
+
if (!finished) {
|
|
142053
|
+
try {
|
|
142054
|
+
db.exec("ROLLBACK");
|
|
142055
|
+
} catch {}
|
|
142056
|
+
}
|
|
142057
|
+
}
|
|
142058
|
+
}
|
|
141943
142059
|
function buildCompartmentBlock(compartments, facts, memoryBlock, dateRanges) {
|
|
141944
142060
|
const lines = [];
|
|
141945
142061
|
if (memoryBlock) {
|
|
@@ -142007,12 +142123,37 @@ function getRecompStaging(db, sessionId) {
|
|
|
142007
142123
|
lastEndMessage: lastEnd
|
|
142008
142124
|
};
|
|
142009
142125
|
}
|
|
142010
|
-
function promoteRecompStaging(db, sessionId) {
|
|
142126
|
+
function promoteRecompStaging(db, sessionId, holderId) {
|
|
142011
142127
|
const now = Date.now();
|
|
142012
|
-
|
|
142128
|
+
if (!holderId) {
|
|
142129
|
+
return db.transaction(() => {
|
|
142130
|
+
const staging = getRecompStaging(db, sessionId);
|
|
142131
|
+
if (!staging || staging.compartments.length === 0)
|
|
142132
|
+
return null;
|
|
142133
|
+
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
142134
|
+
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
142135
|
+
insertCompartmentRows(db, sessionId, staging.compartments, now);
|
|
142136
|
+
insertFactRows(db, sessionId, staging.facts, now);
|
|
142137
|
+
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
142138
|
+
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
142139
|
+
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
142140
|
+
return { compartments: staging.compartments, facts: staging.facts };
|
|
142141
|
+
})();
|
|
142142
|
+
}
|
|
142143
|
+
db.exec("BEGIN IMMEDIATE");
|
|
142144
|
+
let finished = false;
|
|
142145
|
+
try {
|
|
142146
|
+
if (!isCompartmentLeaseHeld(db, sessionId, holderId)) {
|
|
142147
|
+
db.exec("ROLLBACK");
|
|
142148
|
+
finished = true;
|
|
142149
|
+
return null;
|
|
142150
|
+
}
|
|
142013
142151
|
const staging = getRecompStaging(db, sessionId);
|
|
142014
|
-
if (!staging || staging.compartments.length === 0)
|
|
142152
|
+
if (!staging || staging.compartments.length === 0) {
|
|
142153
|
+
db.exec("ROLLBACK");
|
|
142154
|
+
finished = true;
|
|
142015
142155
|
return null;
|
|
142156
|
+
}
|
|
142016
142157
|
db.prepare("DELETE FROM compartments WHERE session_id = ?").run(sessionId);
|
|
142017
142158
|
db.prepare("DELETE FROM session_facts WHERE session_id = ?").run(sessionId);
|
|
142018
142159
|
insertCompartmentRows(db, sessionId, staging.compartments, now);
|
|
@@ -142020,8 +142161,16 @@ function promoteRecompStaging(db, sessionId) {
|
|
|
142020
142161
|
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
142021
142162
|
db.prepare("DELETE FROM recomp_facts WHERE session_id = ?").run(sessionId);
|
|
142022
142163
|
db.prepare("UPDATE session_meta SET memory_block_cache = '', memory_block_ids = '' WHERE session_id = ?").run(sessionId);
|
|
142164
|
+
db.exec("COMMIT");
|
|
142165
|
+
finished = true;
|
|
142023
142166
|
return { compartments: staging.compartments, facts: staging.facts };
|
|
142024
|
-
}
|
|
142167
|
+
} finally {
|
|
142168
|
+
if (!finished) {
|
|
142169
|
+
try {
|
|
142170
|
+
db.exec("ROLLBACK");
|
|
142171
|
+
} catch {}
|
|
142172
|
+
}
|
|
142173
|
+
}
|
|
142025
142174
|
}
|
|
142026
142175
|
function invalidateAllMemoryBlockCaches(db) {
|
|
142027
142176
|
try {
|
|
@@ -142669,6 +142818,65 @@ var MIGRATIONS = [
|
|
|
142669
142818
|
db.exec("ALTER TABLE session_meta ADD COLUMN pending_pi_compaction_marker_state TEXT");
|
|
142670
142819
|
}
|
|
142671
142820
|
}
|
|
142821
|
+
},
|
|
142822
|
+
{
|
|
142823
|
+
version: 19,
|
|
142824
|
+
description: "Add compartment state lease table",
|
|
142825
|
+
up: (db) => {
|
|
142826
|
+
db.exec(`
|
|
142827
|
+
CREATE TABLE IF NOT EXISTS compartment_state_lease (
|
|
142828
|
+
session_id TEXT PRIMARY KEY NOT NULL,
|
|
142829
|
+
holder_id TEXT NOT NULL,
|
|
142830
|
+
acquired_at INTEGER NOT NULL,
|
|
142831
|
+
expires_at INTEGER NOT NULL
|
|
142832
|
+
);
|
|
142833
|
+
CREATE INDEX IF NOT EXISTS idx_compartment_state_lease_expires
|
|
142834
|
+
ON compartment_state_lease(expires_at);
|
|
142835
|
+
`);
|
|
142836
|
+
}
|
|
142837
|
+
},
|
|
142838
|
+
{
|
|
142839
|
+
version: 20,
|
|
142840
|
+
description: "Add subagent invocation token accounting",
|
|
142841
|
+
up: (db) => {
|
|
142842
|
+
db.exec(`
|
|
142843
|
+
CREATE TABLE IF NOT EXISTS subagent_invocations (
|
|
142844
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
142845
|
+
session_id TEXT NOT NULL,
|
|
142846
|
+
harness TEXT NOT NULL,
|
|
142847
|
+
subagent TEXT NOT NULL,
|
|
142848
|
+
task TEXT,
|
|
142849
|
+
provider_id TEXT,
|
|
142850
|
+
model_id TEXT,
|
|
142851
|
+
started_at INTEGER NOT NULL,
|
|
142852
|
+
ended_at INTEGER,
|
|
142853
|
+
status TEXT NOT NULL,
|
|
142854
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
142855
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
142856
|
+
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
|
|
142857
|
+
cache_write_tokens INTEGER NOT NULL DEFAULT 0,
|
|
142858
|
+
error TEXT,
|
|
142859
|
+
parent_invocation_id INTEGER
|
|
142860
|
+
);
|
|
142861
|
+
CREATE INDEX IF NOT EXISTS idx_sai_session_started
|
|
142862
|
+
ON subagent_invocations(session_id, started_at DESC);
|
|
142863
|
+
CREATE INDEX IF NOT EXISTS idx_sai_subagent
|
|
142864
|
+
ON subagent_invocations(subagent, started_at DESC);
|
|
142865
|
+
`);
|
|
142866
|
+
}
|
|
142867
|
+
},
|
|
142868
|
+
{
|
|
142869
|
+
version: 21,
|
|
142870
|
+
description: "Add session lifetime work metrics",
|
|
142871
|
+
up: (db) => {
|
|
142872
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
142873
|
+
if (!cols.some((c) => c.name === "new_work_tokens")) {
|
|
142874
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN new_work_tokens INTEGER NOT NULL DEFAULT 0");
|
|
142875
|
+
}
|
|
142876
|
+
if (!cols.some((c) => c.name === "total_input_tokens")) {
|
|
142877
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN total_input_tokens INTEGER NOT NULL DEFAULT 0");
|
|
142878
|
+
}
|
|
142879
|
+
}
|
|
142672
142880
|
}
|
|
142673
142881
|
];
|
|
142674
142882
|
function ensureMigrationsTable(db) {
|
|
@@ -143124,6 +143332,15 @@ function initializeDatabase(db) {
|
|
|
143124
143332
|
);
|
|
143125
143333
|
CREATE INDEX IF NOT EXISTS idx_compartments_session ON compartments(session_id);
|
|
143126
143334
|
|
|
143335
|
+
CREATE TABLE IF NOT EXISTS compartment_state_lease (
|
|
143336
|
+
session_id TEXT PRIMARY KEY NOT NULL,
|
|
143337
|
+
holder_id TEXT NOT NULL,
|
|
143338
|
+
acquired_at INTEGER NOT NULL,
|
|
143339
|
+
expires_at INTEGER NOT NULL
|
|
143340
|
+
);
|
|
143341
|
+
CREATE INDEX IF NOT EXISTS idx_compartment_state_lease_expires
|
|
143342
|
+
ON compartment_state_lease(expires_at);
|
|
143343
|
+
|
|
143127
143344
|
CREATE TABLE IF NOT EXISTS compression_depth (
|
|
143128
143345
|
session_id TEXT NOT NULL,
|
|
143129
143346
|
message_ordinal INTEGER NOT NULL,
|
|
@@ -143320,12 +143537,37 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143320
143537
|
-- is a valid JSON blob written via setPendingPiCompactionMarkerState.
|
|
143321
143538
|
-- Excluded from healNullTextColumns.
|
|
143322
143539
|
pending_pi_compaction_marker_state TEXT,
|
|
143540
|
+
new_work_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143541
|
+
total_input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143323
143542
|
-- deferred_execute_state: intentionally NULLABLE without a default.
|
|
143324
143543
|
-- Absence is SQL NULL; presence is a JSON blob written via
|
|
143325
143544
|
-- setDeferredExecutePendingIfAbsent. Excluded from healNullTextColumns.
|
|
143326
143545
|
deferred_execute_state TEXT
|
|
143327
143546
|
);
|
|
143328
143547
|
|
|
143548
|
+
CREATE TABLE IF NOT EXISTS subagent_invocations (
|
|
143549
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
143550
|
+
session_id TEXT NOT NULL,
|
|
143551
|
+
harness TEXT NOT NULL,
|
|
143552
|
+
subagent TEXT NOT NULL,
|
|
143553
|
+
task TEXT,
|
|
143554
|
+
provider_id TEXT,
|
|
143555
|
+
model_id TEXT,
|
|
143556
|
+
started_at INTEGER NOT NULL,
|
|
143557
|
+
ended_at INTEGER,
|
|
143558
|
+
status TEXT NOT NULL,
|
|
143559
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143560
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143561
|
+
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143562
|
+
cache_write_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143563
|
+
error TEXT,
|
|
143564
|
+
parent_invocation_id INTEGER
|
|
143565
|
+
);
|
|
143566
|
+
CREATE INDEX IF NOT EXISTS idx_sai_session_started
|
|
143567
|
+
ON subagent_invocations(session_id, started_at DESC);
|
|
143568
|
+
CREATE INDEX IF NOT EXISTS idx_sai_subagent
|
|
143569
|
+
ON subagent_invocations(subagent, started_at DESC);
|
|
143570
|
+
|
|
143329
143571
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
143330
143572
|
CREATE INDEX IF NOT EXISTS idx_tags_session_message_id ON tags(session_id, message_id);
|
|
143331
143573
|
CREATE INDEX IF NOT EXISTS idx_pending_ops_session ON pending_ops(session_id);
|
|
@@ -143417,6 +143659,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143417
143659
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
143418
143660
|
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
143419
143661
|
ensureColumn(db, "session_meta", "pending_pi_compaction_marker_state", "TEXT");
|
|
143662
|
+
ensureColumn(db, "session_meta", "new_work_tokens", "INTEGER NOT NULL DEFAULT 0");
|
|
143663
|
+
ensureColumn(db, "session_meta", "total_input_tokens", "INTEGER NOT NULL DEFAULT 0");
|
|
143420
143664
|
ensureColumn(db, "session_meta", "deferred_execute_state", "TEXT");
|
|
143421
143665
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
143422
143666
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -143480,7 +143724,9 @@ function healNullIntegerColumns(db) {
|
|
|
143480
143724
|
["tool_call_tokens", 0],
|
|
143481
143725
|
["note_nudge_trigger_pending", 0],
|
|
143482
143726
|
["observed_safe_input_tokens", 0],
|
|
143483
|
-
["cache_alert_sent", 0]
|
|
143727
|
+
["cache_alert_sent", 0],
|
|
143728
|
+
["new_work_tokens", 0],
|
|
143729
|
+
["total_input_tokens", 0]
|
|
143484
143730
|
];
|
|
143485
143731
|
for (const [column, fallback] of columns) {
|
|
143486
143732
|
try {
|
|
@@ -144046,6 +144292,7 @@ function getPendingPiCompactionMarkerState(db, sessionId) {
|
|
|
144046
144292
|
return parsed;
|
|
144047
144293
|
}
|
|
144048
144294
|
} catch {}
|
|
144295
|
+
db.prepare("UPDATE session_meta SET pending_pi_compaction_marker_state = NULL WHERE session_id = ? AND pending_pi_compaction_marker_state = ?").run(sessionId, raw);
|
|
144049
144296
|
return null;
|
|
144050
144297
|
}
|
|
144051
144298
|
function setPendingPiCompactionMarkerState(db, sessionId, state) {
|
|
@@ -144089,6 +144336,12 @@ function clearDeferredExecutePendingIfMatches(db, sessionId, expected) {
|
|
|
144089
144336
|
WHERE session_id = ? AND deferred_execute_state = ?`).run(sessionId, expectedBlob);
|
|
144090
144337
|
return result.changes > 0;
|
|
144091
144338
|
}
|
|
144339
|
+
function setSessionWorkMetrics(db, sessionId, newWorkTokens, totalInputTokens) {
|
|
144340
|
+
ensureSessionMetaRow(db, sessionId);
|
|
144341
|
+
db.prepare(`UPDATE session_meta
|
|
144342
|
+
SET new_work_tokens = ?, total_input_tokens = ?
|
|
144343
|
+
WHERE session_id = ?`).run(Math.max(0, Math.floor(newWorkTokens)), Math.max(0, Math.floor(totalInputTokens)), sessionId);
|
|
144344
|
+
}
|
|
144092
144345
|
// ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
|
|
144093
144346
|
init_logger();
|
|
144094
144347
|
await init_read_session_db();
|
|
@@ -144404,6 +144657,19 @@ function getSourceContents(db, sessionId, tagIds) {
|
|
|
144404
144657
|
}
|
|
144405
144658
|
return sources;
|
|
144406
144659
|
}
|
|
144660
|
+
// ../plugin/src/features/magic-context/storage-subagent-invocations.ts
|
|
144661
|
+
function clampToken(value) {
|
|
144662
|
+
return Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
144663
|
+
}
|
|
144664
|
+
function recordSubagentInvocation(db, input) {
|
|
144665
|
+
const result = db.prepare(`INSERT INTO subagent_invocations (
|
|
144666
|
+
session_id, harness, subagent, task, provider_id, model_id,
|
|
144667
|
+
started_at, ended_at, status,
|
|
144668
|
+
input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,
|
|
144669
|
+
error, parent_invocation_id
|
|
144670
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(input.sessionId, input.harness, input.subagent, input.task ?? null, input.providerId ?? null, input.modelId ?? null, input.startedAt, input.endedAt, input.status, clampToken(input.inputTokens), clampToken(input.outputTokens), clampToken(input.cacheReadTokens), clampToken(input.cacheWriteTokens), input.error ?? null, input.parentInvocationId ?? null);
|
|
144671
|
+
return Number(result.lastInsertRowid);
|
|
144672
|
+
}
|
|
144407
144673
|
// ../plugin/src/features/magic-context/storage-tags.ts
|
|
144408
144674
|
var insertTagStatements = new WeakMap;
|
|
144409
144675
|
var updateTagStatusStatements = new WeakMap;
|
|
@@ -145266,10 +145532,98 @@ function isTodoItem(value) {
|
|
|
145266
145532
|
return typeof todo.content === "string" && typeof todo.status === "string" && (todo.priority === undefined || typeof todo.priority === "string");
|
|
145267
145533
|
}
|
|
145268
145534
|
|
|
145535
|
+
// ../plugin/src/shared/announcement.ts
|
|
145536
|
+
init_data_path();
|
|
145537
|
+
import * as fs2 from "node:fs";
|
|
145538
|
+
import * as path5 from "node:path";
|
|
145539
|
+
var ANNOUNCEMENT_VERSION = "0.21.7";
|
|
145540
|
+
var ANNOUNCEMENT_FEATURES = [
|
|
145541
|
+
"Pi parity sweep: 44 audit findings fixed, including a critical SHIP-BLOCKER where /ctx-flush did not drain the pending Pi compaction queue.",
|
|
145542
|
+
"Pi historian recovery fix: empty/no-op historian returns now clear emergency recovery so sessions cannot loop forever at 95%.",
|
|
145543
|
+
"trimPiMessagesToBoundary now sweeps non-contiguous tool-result orphans, fixing provider 400s after compaction in long Pi sessions.",
|
|
145544
|
+
"Hidden subagent tool isolation: historian, dreamer, and sidekick can no longer spawn subagents or run unsafe tools.",
|
|
145545
|
+
"TUI sidebar and /ctx-status header now show execute threshold inline: '47.5% / 65%' on the left, '475K / 1.0M' on the right.",
|
|
145546
|
+
"doctor --issue now caps GitHub issue bodies at ~60KB with a dedicated 'Recent errors' section so reports stay submittable."
|
|
145547
|
+
];
|
|
145548
|
+
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
|
|
145549
|
+
var STATE_FILENAME = "last_announced_version";
|
|
145550
|
+
function getStateFilePath() {
|
|
145551
|
+
return path5.join(getMagicContextStorageDir(), STATE_FILENAME);
|
|
145552
|
+
}
|
|
145553
|
+
function readLastAnnouncedVersion() {
|
|
145554
|
+
try {
|
|
145555
|
+
const file = getStateFilePath();
|
|
145556
|
+
if (!fs2.existsSync(file))
|
|
145557
|
+
return "";
|
|
145558
|
+
return fs2.readFileSync(file, "utf-8").trim();
|
|
145559
|
+
} catch {
|
|
145560
|
+
return "";
|
|
145561
|
+
}
|
|
145562
|
+
}
|
|
145563
|
+
function markAnnouncementSeen(version) {
|
|
145564
|
+
if (!version)
|
|
145565
|
+
return;
|
|
145566
|
+
try {
|
|
145567
|
+
const dir = getMagicContextStorageDir();
|
|
145568
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
145569
|
+
fs2.writeFileSync(getStateFilePath(), version);
|
|
145570
|
+
} catch {}
|
|
145571
|
+
}
|
|
145572
|
+
function shouldShowAnnouncement() {
|
|
145573
|
+
if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0)
|
|
145574
|
+
return false;
|
|
145575
|
+
return readLastAnnouncedVersion() !== ANNOUNCEMENT_VERSION;
|
|
145576
|
+
}
|
|
145577
|
+
|
|
145269
145578
|
// src/index.ts
|
|
145270
145579
|
init_data_path();
|
|
145271
145580
|
init_logger();
|
|
145272
145581
|
|
|
145582
|
+
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
145583
|
+
function resolveFallbackChain(agentName, userFallbacks) {
|
|
145584
|
+
const userList = normalizeUserFallbacks(userFallbacks);
|
|
145585
|
+
if (userList.length > 0) {
|
|
145586
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
145587
|
+
}
|
|
145588
|
+
const builtin = getAgentFallbackModels(agentName);
|
|
145589
|
+
if (!builtin || builtin.length === 0)
|
|
145590
|
+
return [];
|
|
145591
|
+
return dedupe(builtin.filter(isValidModelSpec));
|
|
145592
|
+
}
|
|
145593
|
+
function normalizeUserFallbacks(userFallbacks) {
|
|
145594
|
+
if (!userFallbacks)
|
|
145595
|
+
return [];
|
|
145596
|
+
if (typeof userFallbacks === "string") {
|
|
145597
|
+
const trimmed = userFallbacks.trim();
|
|
145598
|
+
return trimmed ? [trimmed] : [];
|
|
145599
|
+
}
|
|
145600
|
+
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
145601
|
+
}
|
|
145602
|
+
function isValidModelSpec(spec) {
|
|
145603
|
+
const slash = spec.indexOf("/");
|
|
145604
|
+
return slash > 0 && slash < spec.length - 1;
|
|
145605
|
+
}
|
|
145606
|
+
function dedupe(list) {
|
|
145607
|
+
const seen = new Set;
|
|
145608
|
+
const out = [];
|
|
145609
|
+
for (const item of list) {
|
|
145610
|
+
if (seen.has(item))
|
|
145611
|
+
continue;
|
|
145612
|
+
seen.add(item);
|
|
145613
|
+
out.push(item);
|
|
145614
|
+
}
|
|
145615
|
+
return out;
|
|
145616
|
+
}
|
|
145617
|
+
function parseProviderModel(spec) {
|
|
145618
|
+
const slash = spec.indexOf("/");
|
|
145619
|
+
if (slash < 1 || slash >= spec.length - 1)
|
|
145620
|
+
return null;
|
|
145621
|
+
return {
|
|
145622
|
+
providerID: spec.slice(0, slash).trim(),
|
|
145623
|
+
modelID: spec.slice(slash + 1).trim()
|
|
145624
|
+
};
|
|
145625
|
+
}
|
|
145626
|
+
|
|
145273
145627
|
// ../plugin/src/features/magic-context/sidekick/core.ts
|
|
145274
145628
|
var SIDEKICK_SYSTEM_PROMPT = `You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.
|
|
145275
145629
|
|
|
@@ -145295,17 +145649,108 @@ init_logger();
|
|
|
145295
145649
|
|
|
145296
145650
|
// src/subagent-runner.ts
|
|
145297
145651
|
import * as childProcess from "node:child_process";
|
|
145298
|
-
import { existsSync as
|
|
145652
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
145299
145653
|
import { createRequire as createRequire3 } from "node:module";
|
|
145300
|
-
import { dirname as dirname3, join as
|
|
145654
|
+
import { dirname as dirname3, join as join9, resolve as resolvePath } from "node:path";
|
|
145301
145655
|
import { createInterface } from "node:readline";
|
|
145302
145656
|
import { fileURLToPath } from "node:url";
|
|
145657
|
+
|
|
145658
|
+
// ../plugin/src/features/magic-context/subagent-token-capture.ts
|
|
145659
|
+
init_logger();
|
|
145660
|
+
function asNumber(value) {
|
|
145661
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
145662
|
+
}
|
|
145663
|
+
function tokenObjectFromMessage(message) {
|
|
145664
|
+
const info = message.info;
|
|
145665
|
+
if (info && typeof info === "object") {
|
|
145666
|
+
const tokens2 = info.tokens;
|
|
145667
|
+
if (tokens2 && typeof tokens2 === "object")
|
|
145668
|
+
return tokens2;
|
|
145669
|
+
}
|
|
145670
|
+
const tokens = message.tokens;
|
|
145671
|
+
if (tokens && typeof tokens === "object")
|
|
145672
|
+
return tokens;
|
|
145673
|
+
return null;
|
|
145674
|
+
}
|
|
145675
|
+
function isAssistantMessage(message) {
|
|
145676
|
+
if (!message || typeof message !== "object")
|
|
145677
|
+
return false;
|
|
145678
|
+
const record = message;
|
|
145679
|
+
const info = record.info;
|
|
145680
|
+
if (info && typeof info === "object") {
|
|
145681
|
+
return info.role === "assistant";
|
|
145682
|
+
}
|
|
145683
|
+
return record.role === "assistant";
|
|
145684
|
+
}
|
|
145685
|
+
function modelFromMessage(message) {
|
|
145686
|
+
const info = message.info;
|
|
145687
|
+
const source = info && typeof info === "object" ? info : message;
|
|
145688
|
+
return {
|
|
145689
|
+
providerId: typeof source.providerID === "string" ? source.providerID : typeof source.providerId === "string" ? source.providerId : null,
|
|
145690
|
+
modelId: typeof source.modelID === "string" ? source.modelID : typeof source.modelId === "string" ? source.modelId : null
|
|
145691
|
+
};
|
|
145692
|
+
}
|
|
145693
|
+
function emptyTokenTotals() {
|
|
145694
|
+
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
145695
|
+
}
|
|
145696
|
+
function sumTokensFromChildMessages(messages) {
|
|
145697
|
+
const totals = emptyTokenTotals();
|
|
145698
|
+
for (const message of messages) {
|
|
145699
|
+
if (!isAssistantMessage(message))
|
|
145700
|
+
continue;
|
|
145701
|
+
const tokens = tokenObjectFromMessage(message);
|
|
145702
|
+
if (!tokens)
|
|
145703
|
+
continue;
|
|
145704
|
+
const cache = tokens.cache && typeof tokens.cache === "object" ? tokens.cache : {};
|
|
145705
|
+
totals.input += asNumber(tokens.input);
|
|
145706
|
+
totals.output += asNumber(tokens.output);
|
|
145707
|
+
totals.cacheRead += asNumber(cache.read ?? tokens.cacheRead ?? tokens.cache_read);
|
|
145708
|
+
totals.cacheWrite += asNumber(cache.write ?? tokens.cacheWrite ?? tokens.cache_write);
|
|
145709
|
+
}
|
|
145710
|
+
return totals;
|
|
145711
|
+
}
|
|
145712
|
+
function findLastAssistantModel(messages) {
|
|
145713
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
145714
|
+
const message = messages[index];
|
|
145715
|
+
if (isAssistantMessage(message))
|
|
145716
|
+
return modelFromMessage(message);
|
|
145717
|
+
}
|
|
145718
|
+
return { providerId: null, modelId: null };
|
|
145719
|
+
}
|
|
145720
|
+
function recordChildInvocation(input) {
|
|
145721
|
+
const tokens = input.tokens ?? sumTokensFromChildMessages(input.messages ?? []);
|
|
145722
|
+
const model = input.providerId !== undefined || input.modelId !== undefined ? { providerId: input.providerId ?? null, modelId: input.modelId ?? null } : findLastAssistantModel(input.messages ?? []);
|
|
145723
|
+
try {
|
|
145724
|
+
return recordSubagentInvocation(input.db, {
|
|
145725
|
+
sessionId: input.parentSessionId,
|
|
145726
|
+
harness: input.harness,
|
|
145727
|
+
subagent: input.subagent,
|
|
145728
|
+
task: input.task ?? null,
|
|
145729
|
+
providerId: model.providerId,
|
|
145730
|
+
modelId: model.modelId,
|
|
145731
|
+
startedAt: input.startedAt,
|
|
145732
|
+
endedAt: input.endedAt ?? Date.now(),
|
|
145733
|
+
status: input.status,
|
|
145734
|
+
inputTokens: tokens.input,
|
|
145735
|
+
outputTokens: tokens.output,
|
|
145736
|
+
cacheReadTokens: tokens.cacheRead,
|
|
145737
|
+
cacheWriteTokens: tokens.cacheWrite,
|
|
145738
|
+
error: input.error ? describeError(input.error).brief : null,
|
|
145739
|
+
parentInvocationId: input.parentInvocationId ?? null
|
|
145740
|
+
});
|
|
145741
|
+
} catch (error) {
|
|
145742
|
+
sessionLog(input.parentSessionId, "subagent token accounting failed:", describeError(error).brief);
|
|
145743
|
+
return null;
|
|
145744
|
+
}
|
|
145745
|
+
}
|
|
145746
|
+
|
|
145747
|
+
// src/subagent-runner.ts
|
|
145303
145748
|
function resolveBundledPiCli() {
|
|
145304
145749
|
try {
|
|
145305
145750
|
const require_ = createRequire3(import.meta.url);
|
|
145306
145751
|
const pkgJson = require_.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
145307
|
-
const cliPath =
|
|
145308
|
-
if (
|
|
145752
|
+
const cliPath = join9(dirname3(pkgJson), "dist/cli.js");
|
|
145753
|
+
if (existsSync7(cliPath))
|
|
145309
145754
|
return cliPath;
|
|
145310
145755
|
return null;
|
|
145311
145756
|
} catch {
|
|
@@ -145316,7 +145761,7 @@ function resolveSubagentEntryPath() {
|
|
|
145316
145761
|
try {
|
|
145317
145762
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
145318
145763
|
const candidate = resolvePath(here, "subagent-entry.js");
|
|
145319
|
-
if (
|
|
145764
|
+
if (existsSync7(candidate))
|
|
145320
145765
|
return candidate;
|
|
145321
145766
|
return;
|
|
145322
145767
|
} catch {
|
|
@@ -145329,6 +145774,17 @@ var DREAMER_ACTION_AGENTS = new Set([
|
|
|
145329
145774
|
"dreamer",
|
|
145330
145775
|
"magic-context-dreamer"
|
|
145331
145776
|
]);
|
|
145777
|
+
function inferAccountingSubagent(agent) {
|
|
145778
|
+
if (agent.includes("sidekick"))
|
|
145779
|
+
return "sidekick";
|
|
145780
|
+
if (agent.includes("dreamer"))
|
|
145781
|
+
return "dreamer";
|
|
145782
|
+
if (agent.includes("compressor"))
|
|
145783
|
+
return "compressor";
|
|
145784
|
+
if (agent.includes("recomp"))
|
|
145785
|
+
return "recomp";
|
|
145786
|
+
return "historian";
|
|
145787
|
+
}
|
|
145332
145788
|
|
|
145333
145789
|
class PiSubagentRunner {
|
|
145334
145790
|
harness = "pi";
|
|
@@ -145348,22 +145804,67 @@ class PiSubagentRunner {
|
|
|
145348
145804
|
this.spawnImpl = options.spawnImpl ?? childProcess.spawn;
|
|
145349
145805
|
}
|
|
145350
145806
|
async run(options) {
|
|
145807
|
+
const models = [options.model, ...options.fallbackModels ?? []].filter((model) => typeof model === "string" && model.length > 0);
|
|
145808
|
+
const attempts = models.length > 0 ? models : [undefined];
|
|
145809
|
+
let lastResult = null;
|
|
145810
|
+
for (let index = 0;index < attempts.length; index += 1) {
|
|
145811
|
+
const model = attempts[index];
|
|
145812
|
+
const attemptOptions = {
|
|
145813
|
+
...options,
|
|
145814
|
+
model,
|
|
145815
|
+
fallbackModels: undefined
|
|
145816
|
+
};
|
|
145817
|
+
const result = await this.runOnce(attemptOptions);
|
|
145818
|
+
if (result.ok)
|
|
145819
|
+
return result;
|
|
145820
|
+
lastResult = result;
|
|
145821
|
+
if (index >= attempts.length - 1 || !isFallbackEligible(result.reason)) {
|
|
145822
|
+
return result;
|
|
145823
|
+
}
|
|
145824
|
+
}
|
|
145825
|
+
return lastResult ?? this.runOnce({ ...options, fallbackModels: undefined });
|
|
145826
|
+
}
|
|
145827
|
+
async runOnce(options) {
|
|
145351
145828
|
const startTime = Date.now();
|
|
145829
|
+
let recordedAccounting = false;
|
|
145830
|
+
const recordAccounting = (result, messages = []) => {
|
|
145831
|
+
if (!options.accountingSessionId || recordedAccounting)
|
|
145832
|
+
return;
|
|
145833
|
+
recordedAccounting = true;
|
|
145834
|
+
recordChildInvocation({
|
|
145835
|
+
db: openDatabase(),
|
|
145836
|
+
parentSessionId: options.accountingSessionId,
|
|
145837
|
+
harness: "pi",
|
|
145838
|
+
subagent: options.accountingSubagent ?? inferAccountingSubagent(options.agent),
|
|
145839
|
+
task: options.accountingTask ?? null,
|
|
145840
|
+
startedAt: startTime,
|
|
145841
|
+
status: result.ok ? "completed" : result.reason === "abort" ? "aborted" : "failed",
|
|
145842
|
+
messages,
|
|
145843
|
+
providerId: typeof options.model === "string" ? options.model.split("/")[0] : null,
|
|
145844
|
+
modelId: typeof options.model === "string" ? options.model.split("/").slice(1).join("/") : null,
|
|
145845
|
+
error: result.ok ? null : result.error,
|
|
145846
|
+
parentInvocationId: options.accountingParentInvocationId ?? null
|
|
145847
|
+
});
|
|
145848
|
+
};
|
|
145352
145849
|
if (options.signal?.aborted) {
|
|
145353
|
-
|
|
145850
|
+
const result = {
|
|
145354
145851
|
ok: false,
|
|
145355
145852
|
reason: "abort",
|
|
145356
145853
|
error: "pi subagent aborted by caller",
|
|
145357
145854
|
durationMs: Date.now() - startTime
|
|
145358
145855
|
};
|
|
145856
|
+
recordAccounting(result);
|
|
145857
|
+
return result;
|
|
145359
145858
|
}
|
|
145360
145859
|
const args = buildArgs(options);
|
|
145361
145860
|
return new Promise((resolve2) => {
|
|
145861
|
+
let accountingMessages = [];
|
|
145362
145862
|
let settled = false;
|
|
145363
145863
|
const settle = (result) => {
|
|
145364
145864
|
if (settled)
|
|
145365
145865
|
return;
|
|
145366
145866
|
settled = true;
|
|
145867
|
+
recordAccounting(result, accountingMessages);
|
|
145367
145868
|
resolve2(result);
|
|
145368
145869
|
};
|
|
145369
145870
|
const emitProgress = (event) => {
|
|
@@ -145433,6 +145934,7 @@ class PiSubagentRunner {
|
|
|
145433
145934
|
let lastEventType = null;
|
|
145434
145935
|
let lastEventTimestamp = 0;
|
|
145435
145936
|
const accumulatedMessages = [];
|
|
145937
|
+
accountingMessages = accumulatedMessages;
|
|
145436
145938
|
rl.on("line", (line) => {
|
|
145437
145939
|
if (line.length === 0)
|
|
145438
145940
|
return;
|
|
@@ -145484,7 +145986,7 @@ class PiSubagentRunner {
|
|
|
145484
145986
|
const m = e.message;
|
|
145485
145987
|
if (m.role === "assistant") {
|
|
145486
145988
|
const hasToolCall = Array.isArray(m.content) && m.content.some((c) => typeof c === "object" && c !== null && c.type === "toolCall");
|
|
145487
|
-
const isTerminalStopReason = typeof m.stopReason === "string" && (m.stopReason === "stop" || m.stopReason === "length" || m.stopReason === "
|
|
145989
|
+
const isTerminalStopReason = typeof m.stopReason === "string" && (m.stopReason === "stop" || m.stopReason === "length" || m.stopReason === "aborted");
|
|
145488
145990
|
if (isTerminalStopReason && !hasToolCall) {
|
|
145489
145991
|
sawAgentEnd = true;
|
|
145490
145992
|
const result = extractFinalAssistant(accumulatedMessages);
|
|
@@ -145506,6 +146008,10 @@ class PiSubagentRunner {
|
|
|
145506
146008
|
}
|
|
145507
146009
|
if (sawAgentEnd && !drainTimerStarted) {
|
|
145508
146010
|
drainTimerStarted = true;
|
|
146011
|
+
if (timeoutHandle) {
|
|
146012
|
+
clearTimeout(timeoutHandle);
|
|
146013
|
+
timeoutHandle = undefined;
|
|
146014
|
+
}
|
|
145509
146015
|
drainTimerHandle = setTimeout(() => {
|
|
145510
146016
|
if (settled)
|
|
145511
146017
|
return;
|
|
@@ -145588,6 +146094,20 @@ class PiSubagentRunner {
|
|
|
145588
146094
|
});
|
|
145589
146095
|
return;
|
|
145590
146096
|
}
|
|
146097
|
+
if (code !== 0 || signal !== null) {
|
|
146098
|
+
settle({
|
|
146099
|
+
ok: false,
|
|
146100
|
+
reason: "non_zero_exit",
|
|
146101
|
+
error: `pi exited (code=${code}, signal=${signal}) after terminal assistant event. stderr: ${stderr.slice(0, 500) || "(empty)"}`,
|
|
146102
|
+
durationMs: Date.now() - startTime,
|
|
146103
|
+
meta: {
|
|
146104
|
+
stderr: stderr.length > 0 ? stderr : undefined,
|
|
146105
|
+
exitCode: code,
|
|
146106
|
+
signal
|
|
146107
|
+
}
|
|
146108
|
+
});
|
|
146109
|
+
return;
|
|
146110
|
+
}
|
|
145591
146111
|
if (finalStopReason === "error" || finalStopReason === "aborted" || finalStopReason === "length") {
|
|
145592
146112
|
settle({
|
|
145593
146113
|
ok: false,
|
|
@@ -145649,6 +146169,9 @@ class PiSubagentRunner {
|
|
|
145649
146169
|
});
|
|
145650
146170
|
}
|
|
145651
146171
|
}
|
|
146172
|
+
function isFallbackEligible(reason) {
|
|
146173
|
+
return reason === "model_failed" || reason === "truncated" || reason === "non_zero_exit" || reason === "no_assistant";
|
|
146174
|
+
}
|
|
145652
146175
|
function buildArgs(options) {
|
|
145653
146176
|
const args = [
|
|
145654
146177
|
"--print",
|
|
@@ -145659,7 +146182,8 @@ function buildArgs(options) {
|
|
|
145659
146182
|
"--no-skills",
|
|
145660
146183
|
"--no-prompt-templates"
|
|
145661
146184
|
];
|
|
145662
|
-
|
|
146185
|
+
const shouldLoadSubagentExtension = SUBAGENT_ENTRY_PATH && (options.agent === "sidekick" || DREAMER_ACTION_AGENTS.has(options.agent));
|
|
146186
|
+
if (shouldLoadSubagentExtension) {
|
|
145663
146187
|
args.push("--extension", SUBAGENT_ENTRY_PATH);
|
|
145664
146188
|
if (DREAMER_ACTION_AGENTS.has(options.agent)) {
|
|
145665
146189
|
args.push("--magic-context-dreamer-actions");
|
|
@@ -145668,11 +146192,8 @@ function buildArgs(options) {
|
|
|
145668
146192
|
if (options.systemPrompt && options.systemPrompt.length > 0) {
|
|
145669
146193
|
args.push("--system-prompt", options.systemPrompt);
|
|
145670
146194
|
}
|
|
145671
|
-
|
|
145672
|
-
|
|
145673
|
-
args.push("--models", models.join(","));
|
|
145674
|
-
} else if (models.length === 1) {
|
|
145675
|
-
args.push("--model", models[0]);
|
|
146195
|
+
if (typeof options.model === "string" && options.model.length > 0) {
|
|
146196
|
+
args.push("--model", options.model);
|
|
145676
146197
|
}
|
|
145677
146198
|
if (options.thinkingLevel) {
|
|
145678
146199
|
args.push("--thinking", options.thinkingLevel);
|
|
@@ -145762,10 +146283,13 @@ function registerCtxAugCommand(pi, config) {
|
|
|
145762
146283
|
systemPrompt: config.systemPrompt ?? SIDEKICK_SYSTEM_PROMPT,
|
|
145763
146284
|
userMessage: prompt,
|
|
145764
146285
|
model: config.model,
|
|
146286
|
+
fallbackModels: config.fallbackModels,
|
|
145765
146287
|
timeoutMs: config.timeoutMs ?? 30000,
|
|
145766
146288
|
cwd: ctx.cwd,
|
|
145767
146289
|
signal: ctx.signal,
|
|
145768
|
-
thinkingLevel: config.thinking_level
|
|
146290
|
+
thinkingLevel: config.thinking_level,
|
|
146291
|
+
accountingSessionId: sessionLabel,
|
|
146292
|
+
accountingSubagent: "sidekick"
|
|
145769
146293
|
});
|
|
145770
146294
|
if (!result.ok) {
|
|
145771
146295
|
log(`[magic-context][pi] /ctx-aug: sidekick failed (${result.reason}): ${result.error}`);
|
|
@@ -145972,61 +146496,14 @@ function clearStaleEntries(db, maxAgeMs) {
|
|
|
145972
146496
|
// src/commands/ctx-dream.ts
|
|
145973
146497
|
init_logger();
|
|
145974
146498
|
// ../plugin/src/features/magic-context/dreamer/runner.ts
|
|
145975
|
-
import { existsSync as
|
|
145976
|
-
import { join as
|
|
146499
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
146500
|
+
import { join as join12 } from "node:path";
|
|
145977
146501
|
|
|
145978
146502
|
// ../plugin/src/shared/index.ts
|
|
145979
146503
|
init_logger();
|
|
145980
146504
|
|
|
145981
146505
|
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
145982
146506
|
init_logger();
|
|
145983
|
-
|
|
145984
|
-
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
145985
|
-
function resolveFallbackChain(agentName, userFallbacks) {
|
|
145986
|
-
const userList = normalizeUserFallbacks(userFallbacks);
|
|
145987
|
-
if (userList.length > 0) {
|
|
145988
|
-
return dedupe(userList.filter(isValidModelSpec));
|
|
145989
|
-
}
|
|
145990
|
-
const builtin = getAgentFallbackModels(agentName);
|
|
145991
|
-
if (!builtin || builtin.length === 0)
|
|
145992
|
-
return [];
|
|
145993
|
-
return dedupe(builtin.filter(isValidModelSpec));
|
|
145994
|
-
}
|
|
145995
|
-
function normalizeUserFallbacks(userFallbacks) {
|
|
145996
|
-
if (!userFallbacks)
|
|
145997
|
-
return [];
|
|
145998
|
-
if (typeof userFallbacks === "string") {
|
|
145999
|
-
const trimmed = userFallbacks.trim();
|
|
146000
|
-
return trimmed ? [trimmed] : [];
|
|
146001
|
-
}
|
|
146002
|
-
return userFallbacks.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
146003
|
-
}
|
|
146004
|
-
function isValidModelSpec(spec) {
|
|
146005
|
-
const slash = spec.indexOf("/");
|
|
146006
|
-
return slash > 0 && slash < spec.length - 1;
|
|
146007
|
-
}
|
|
146008
|
-
function dedupe(list) {
|
|
146009
|
-
const seen = new Set;
|
|
146010
|
-
const out = [];
|
|
146011
|
-
for (const item of list) {
|
|
146012
|
-
if (seen.has(item))
|
|
146013
|
-
continue;
|
|
146014
|
-
seen.add(item);
|
|
146015
|
-
out.push(item);
|
|
146016
|
-
}
|
|
146017
|
-
return out;
|
|
146018
|
-
}
|
|
146019
|
-
function parseProviderModel(spec) {
|
|
146020
|
-
const slash = spec.indexOf("/");
|
|
146021
|
-
if (slash < 1 || slash >= spec.length - 1)
|
|
146022
|
-
return null;
|
|
146023
|
-
return {
|
|
146024
|
-
providerID: spec.slice(0, slash).trim(),
|
|
146025
|
-
modelID: spec.slice(slash + 1).trim()
|
|
146026
|
-
};
|
|
146027
|
-
}
|
|
146028
|
-
|
|
146029
|
-
// ../plugin/src/shared/model-suggestion-retry.ts
|
|
146030
146507
|
function extractMessage(error) {
|
|
146031
146508
|
if (typeof error === "string")
|
|
146032
146509
|
return error;
|
|
@@ -146267,20 +146744,20 @@ init_logger();
|
|
|
146267
146744
|
await init_sqlite();
|
|
146268
146745
|
|
|
146269
146746
|
// ../plugin/src/features/magic-context/key-files/identify-key-files.ts
|
|
146270
|
-
import { readFileSync as
|
|
146271
|
-
import { join as
|
|
146747
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
146748
|
+
import { join as join11 } from "node:path";
|
|
146272
146749
|
init_logger();
|
|
146273
146750
|
|
|
146274
146751
|
// ../plugin/src/features/magic-context/key-files/aft-availability.ts
|
|
146275
146752
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
146276
|
-
import { existsSync as
|
|
146753
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
146277
146754
|
import { homedir as homedir3 } from "node:os";
|
|
146278
|
-
import { join as
|
|
146755
|
+
import { join as join10 } from "node:path";
|
|
146279
146756
|
var overrideAvailability = null;
|
|
146280
|
-
function parseConfig(
|
|
146281
|
-
if (!
|
|
146757
|
+
function parseConfig(path6) {
|
|
146758
|
+
if (!existsSync8(path6))
|
|
146282
146759
|
return null;
|
|
146283
|
-
return import_comment_json.parse(
|
|
146760
|
+
return import_comment_json.parse(readFileSync4(path6, "utf-8"));
|
|
146284
146761
|
}
|
|
146285
146762
|
function entryMatchesAft(entry) {
|
|
146286
146763
|
const value = Array.isArray(entry) ? entry[0] : entry;
|
|
@@ -146302,15 +146779,15 @@ function hasAftAtKeys(value, keys) {
|
|
|
146302
146779
|
function getAftAvailability() {
|
|
146303
146780
|
const home = process.env.HOME || homedir3();
|
|
146304
146781
|
const opencodePaths = [
|
|
146305
|
-
|
|
146306
|
-
|
|
146782
|
+
join10(home, ".config", "opencode", "opencode.jsonc"),
|
|
146783
|
+
join10(home, ".config", "opencode", "opencode.json")
|
|
146307
146784
|
];
|
|
146308
|
-
const piPaths = [
|
|
146785
|
+
const piPaths = [join10(home, ".pi", "agent", "settings.json")];
|
|
146309
146786
|
const checkedPaths = [...opencodePaths, ...piPaths];
|
|
146310
146787
|
let opencode = false;
|
|
146311
|
-
for (const
|
|
146788
|
+
for (const path6 of opencodePaths) {
|
|
146312
146789
|
try {
|
|
146313
|
-
const config = parseConfig(
|
|
146790
|
+
const config = parseConfig(path6);
|
|
146314
146791
|
if (hasAftAtKeys(config, ["plugin", "plugins", "mcp", "mcp_servers"])) {
|
|
146315
146792
|
opencode = true;
|
|
146316
146793
|
break;
|
|
@@ -146318,9 +146795,9 @@ function getAftAvailability() {
|
|
|
146318
146795
|
} catch {}
|
|
146319
146796
|
}
|
|
146320
146797
|
let pi = false;
|
|
146321
|
-
for (const
|
|
146798
|
+
for (const path6 of piPaths) {
|
|
146322
146799
|
try {
|
|
146323
|
-
const config = parseConfig(
|
|
146800
|
+
const config = parseConfig(path6);
|
|
146324
146801
|
if (hasAftAtKeys(config, ["packages", "extensions"])) {
|
|
146325
146802
|
pi = true;
|
|
146326
146803
|
break;
|
|
@@ -146769,7 +147246,7 @@ async function runKeyFilesTask(args) {
|
|
|
146769
147246
|
if (row.staleReason !== null || row.generationConfigHash !== configHash)
|
|
146770
147247
|
return false;
|
|
146771
147248
|
try {
|
|
146772
|
-
return sha256(
|
|
147249
|
+
return sha256(readFileSync5(join11(projectPath, row.path))) === row.contentHash;
|
|
146773
147250
|
} catch {
|
|
146774
147251
|
return false;
|
|
146775
147252
|
}
|
|
@@ -147693,6 +148170,17 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
147693
148170
|
}
|
|
147694
148171
|
|
|
147695
148172
|
// ../plugin/src/features/magic-context/user-memory/storage-user-memory.ts
|
|
148173
|
+
function insertUserMemoryCandidates(db, candidates) {
|
|
148174
|
+
if (candidates.length === 0)
|
|
148175
|
+
return;
|
|
148176
|
+
const now = Date.now();
|
|
148177
|
+
const stmt = db.prepare("INSERT INTO user_memory_candidates (content, session_id, source_compartment_start, source_compartment_end, created_at) VALUES (?, ?, ?, ?, ?)");
|
|
148178
|
+
db.transaction(() => {
|
|
148179
|
+
for (const c of candidates) {
|
|
148180
|
+
stmt.run(c.content, c.sessionId, c.sourceCompartmentStart ?? null, c.sourceCompartmentEnd ?? null, now);
|
|
148181
|
+
}
|
|
148182
|
+
})();
|
|
148183
|
+
}
|
|
147696
148184
|
function getUserMemoryCandidates(db) {
|
|
147697
148185
|
const rows = db.prepare("SELECT id, content, session_id, source_compartment_start, source_compartment_end, created_at FROM user_memory_candidates ORDER BY created_at ASC").all();
|
|
147698
148186
|
return rows.map((r) => ({
|
|
@@ -147799,6 +148287,23 @@ Return valid JSON (no markdown fencing):
|
|
|
147799
148287
|
|
|
147800
148288
|
If no promotions are warranted, return empty arrays. Always consume reviewed candidates so they don't accumulate indefinitely.`;
|
|
147801
148289
|
let agentSessionId = null;
|
|
148290
|
+
const startedAt = Date.now();
|
|
148291
|
+
let invocationRecorded = false;
|
|
148292
|
+
const recordInvocation = (params) => {
|
|
148293
|
+
if (!args.parentSessionId || invocationRecorded)
|
|
148294
|
+
return;
|
|
148295
|
+
invocationRecorded = true;
|
|
148296
|
+
recordChildInvocation({
|
|
148297
|
+
db: args.db,
|
|
148298
|
+
parentSessionId: args.parentSessionId,
|
|
148299
|
+
harness: "opencode",
|
|
148300
|
+
subagent: "user_memory_review",
|
|
148301
|
+
startedAt,
|
|
148302
|
+
status: params.status,
|
|
148303
|
+
messages: params.messages,
|
|
148304
|
+
error: params.error
|
|
148305
|
+
});
|
|
148306
|
+
};
|
|
147802
148307
|
const abortController = new AbortController;
|
|
147803
148308
|
const leaseInterval = setInterval(() => {
|
|
147804
148309
|
try {
|
|
@@ -147820,8 +148325,11 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
147820
148325
|
});
|
|
147821
148326
|
const created = normalizeSDKResponse(createResponse, null, { preferResponseOnMissingData: true });
|
|
147822
148327
|
agentSessionId = typeof created?.id === "string" ? created.id : null;
|
|
147823
|
-
if (!agentSessionId)
|
|
147824
|
-
|
|
148328
|
+
if (!agentSessionId) {
|
|
148329
|
+
const error = new Error("Could not create user memory review session.");
|
|
148330
|
+
recordInvocation({ status: "failed", error });
|
|
148331
|
+
throw error;
|
|
148332
|
+
}
|
|
147825
148333
|
log(`[dreamer] user-memories: child session created ${agentSessionId}`);
|
|
147826
148334
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
147827
148335
|
await promptSyncWithModelSuggestionRetry(args.client, {
|
|
@@ -147845,6 +148353,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
147845
148353
|
const messages = normalizeSDKResponse(messagesResponse, [], {
|
|
147846
148354
|
preferResponseOnMissingData: true
|
|
147847
148355
|
});
|
|
148356
|
+
recordInvocation({ status: "completed", messages });
|
|
147848
148357
|
const responseText = extractLatestAssistantText(messages);
|
|
147849
148358
|
if (!responseText) {
|
|
147850
148359
|
log("[dreamer] user-memories: no response from review agent");
|
|
@@ -147966,11 +148475,11 @@ function logWithStackHead(message, stackHead) {
|
|
|
147966
148475
|
log(message, stackHead ? { stackHead } : undefined);
|
|
147967
148476
|
}
|
|
147968
148477
|
function getOpenCodeDbPath2() {
|
|
147969
|
-
return
|
|
148478
|
+
return join12(getDataDir(), "opencode", "opencode.db");
|
|
147970
148479
|
}
|
|
147971
148480
|
function openOpenCodeDb() {
|
|
147972
148481
|
const dbPath = getOpenCodeDbPath2();
|
|
147973
|
-
if (!
|
|
148482
|
+
if (!existsSync9(dbPath)) {
|
|
147974
148483
|
log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
|
|
147975
148484
|
return null;
|
|
147976
148485
|
}
|
|
@@ -148084,6 +148593,24 @@ async function runDream(args) {
|
|
|
148084
148593
|
log(`[dreamer] starting task: ${taskName}`);
|
|
148085
148594
|
const taskStartedAt = Date.now();
|
|
148086
148595
|
let agentSessionId = null;
|
|
148596
|
+
const invocationStartedAt = Date.now();
|
|
148597
|
+
let invocationRecorded = false;
|
|
148598
|
+
const recordInvocation = (params) => {
|
|
148599
|
+
if (!parentSessionId || invocationRecorded)
|
|
148600
|
+
return;
|
|
148601
|
+
invocationRecorded = true;
|
|
148602
|
+
recordChildInvocation({
|
|
148603
|
+
db: args.db,
|
|
148604
|
+
parentSessionId,
|
|
148605
|
+
harness: "opencode",
|
|
148606
|
+
subagent: "dreamer",
|
|
148607
|
+
task: taskName,
|
|
148608
|
+
startedAt: invocationStartedAt,
|
|
148609
|
+
status: params.status,
|
|
148610
|
+
messages: params.messages,
|
|
148611
|
+
error: params.error
|
|
148612
|
+
});
|
|
148613
|
+
};
|
|
148087
148614
|
const taskAbortController = new AbortController;
|
|
148088
148615
|
const leaseRenewalInterval = setInterval(() => {
|
|
148089
148616
|
try {
|
|
@@ -148101,8 +148628,8 @@ async function runDream(args) {
|
|
|
148101
148628
|
try {
|
|
148102
148629
|
const docsDir = args.sessionDirectory ?? args.projectIdentity;
|
|
148103
148630
|
const existingDocs = taskName === "maintain-docs" ? {
|
|
148104
|
-
architecture:
|
|
148105
|
-
structure:
|
|
148631
|
+
architecture: existsSync9(join12(docsDir, "ARCHITECTURE.md")),
|
|
148632
|
+
structure: existsSync9(join12(docsDir, "STRUCTURE.md"))
|
|
148106
148633
|
} : undefined;
|
|
148107
148634
|
const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
|
|
148108
148635
|
id: um.id,
|
|
@@ -148124,7 +148651,9 @@ async function runDream(args) {
|
|
|
148124
148651
|
const createdSession = normalizeSDKResponse(createResponse, null, { preferResponseOnMissingData: true });
|
|
148125
148652
|
agentSessionId = typeof createdSession?.id === "string" ? createdSession.id : null;
|
|
148126
148653
|
if (!agentSessionId) {
|
|
148127
|
-
|
|
148654
|
+
const error = new Error("Dreamer could not create its child session.");
|
|
148655
|
+
recordInvocation({ status: "failed", error });
|
|
148656
|
+
throw error;
|
|
148128
148657
|
}
|
|
148129
148658
|
log(`[dreamer] task ${taskName}: child session created ${agentSessionId}`);
|
|
148130
148659
|
await promptSyncWithModelSuggestionRetry(args.client, {
|
|
@@ -148151,6 +148680,7 @@ async function runDream(args) {
|
|
|
148151
148680
|
const messages = normalizeSDKResponse(messagesResponse, [], {
|
|
148152
148681
|
preferResponseOnMissingData: true
|
|
148153
148682
|
});
|
|
148683
|
+
recordInvocation({ status: "completed", messages });
|
|
148154
148684
|
const taskResult = extractLatestAssistantText(messages);
|
|
148155
148685
|
if (!taskResult) {
|
|
148156
148686
|
throw new Error("Dreamer returned no assistant output.");
|
|
@@ -148165,6 +148695,7 @@ async function runDream(args) {
|
|
|
148165
148695
|
lastErrorSignature = null;
|
|
148166
148696
|
consecutiveSameErrorFailures = 0;
|
|
148167
148697
|
} catch (error) {
|
|
148698
|
+
recordInvocation({ status: lostLease ? "aborted" : "failed", error });
|
|
148168
148699
|
const durationMs = Date.now() - taskStartedAt;
|
|
148169
148700
|
const errorDescription = describeError(error);
|
|
148170
148701
|
logWithStackHead(`[dreamer] task ${taskName}: failed after ${(durationMs / 1000).toFixed(1)}s — ${errorDescription.brief}`, errorDescription.stackHead);
|
|
@@ -148434,6 +148965,24 @@ ${noteDescriptions}
|
|
|
148434
148965
|
Only include notes whose conditions you could definitively evaluate against external signals. Skip notes where you cannot determine the status (they will be re-evaluated next run, or eventually archived as stale).`;
|
|
148435
148966
|
const taskStartedAt = Date.now();
|
|
148436
148967
|
let agentSessionId = null;
|
|
148968
|
+
const startedAt = Date.now();
|
|
148969
|
+
let invocationRecorded = false;
|
|
148970
|
+
const recordInvocation = (params) => {
|
|
148971
|
+
if (!args.parentSessionId || invocationRecorded)
|
|
148972
|
+
return;
|
|
148973
|
+
invocationRecorded = true;
|
|
148974
|
+
recordChildInvocation({
|
|
148975
|
+
db: args.db,
|
|
148976
|
+
parentSessionId: args.parentSessionId,
|
|
148977
|
+
harness: "opencode",
|
|
148978
|
+
subagent: "dreamer",
|
|
148979
|
+
task: "smart-notes",
|
|
148980
|
+
startedAt,
|
|
148981
|
+
status: params.status,
|
|
148982
|
+
messages: params.messages,
|
|
148983
|
+
error: params.error
|
|
148984
|
+
});
|
|
148985
|
+
};
|
|
148437
148986
|
const abortController = new AbortController;
|
|
148438
148987
|
const leaseInterval = setInterval(() => {
|
|
148439
148988
|
try {
|
|
@@ -148457,8 +149006,11 @@ Only include notes whose conditions you could definitively evaluate against exte
|
|
|
148457
149006
|
});
|
|
148458
149007
|
const created = normalizeSDKResponse(createResponse, null, { preferResponseOnMissingData: true });
|
|
148459
149008
|
agentSessionId = typeof created?.id === "string" ? created.id : null;
|
|
148460
|
-
if (!agentSessionId)
|
|
148461
|
-
|
|
149009
|
+
if (!agentSessionId) {
|
|
149010
|
+
const error = new Error("Could not create smart note evaluation session.");
|
|
149011
|
+
recordInvocation({ status: "failed", error });
|
|
149012
|
+
throw error;
|
|
149013
|
+
}
|
|
148462
149014
|
log(`[dreamer] smart notes: child session created ${agentSessionId}`);
|
|
148463
149015
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
148464
149016
|
await promptSyncWithModelSuggestionRetry(args.client, {
|
|
@@ -148482,6 +149034,7 @@ Only include notes whose conditions you could definitively evaluate against exte
|
|
|
148482
149034
|
const messages = normalizeSDKResponse(messagesResponse, [], {
|
|
148483
149035
|
preferResponseOnMissingData: true
|
|
148484
149036
|
});
|
|
149037
|
+
recordInvocation({ status: "completed", messages });
|
|
148485
149038
|
const output = extractLatestAssistantText(messages);
|
|
148486
149039
|
if (!output)
|
|
148487
149040
|
throw new Error("Smart note evaluation returned no output.");
|
|
@@ -149518,10 +150071,10 @@ function mergeDefs(...defs) {
|
|
|
149518
150071
|
function cloneDef(schema) {
|
|
149519
150072
|
return mergeDefs(schema._zod.def);
|
|
149520
150073
|
}
|
|
149521
|
-
function getElementAtPath(obj,
|
|
149522
|
-
if (!
|
|
150074
|
+
function getElementAtPath(obj, path6) {
|
|
150075
|
+
if (!path6)
|
|
149523
150076
|
return obj;
|
|
149524
|
-
return
|
|
150077
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
149525
150078
|
}
|
|
149526
150079
|
function promiseAllObject(promisesObj) {
|
|
149527
150080
|
const keys = Object.keys(promisesObj);
|
|
@@ -149929,11 +150482,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
149929
150482
|
}
|
|
149930
150483
|
return false;
|
|
149931
150484
|
}
|
|
149932
|
-
function prefixIssues(
|
|
150485
|
+
function prefixIssues(path6, issues) {
|
|
149933
150486
|
return issues.map((iss) => {
|
|
149934
150487
|
var _a2;
|
|
149935
150488
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
149936
|
-
iss.path.unshift(
|
|
150489
|
+
iss.path.unshift(path6);
|
|
149937
150490
|
return iss;
|
|
149938
150491
|
});
|
|
149939
150492
|
}
|
|
@@ -150080,16 +150633,16 @@ function flattenError(error, mapper = (issue2) => issue2.message) {
|
|
|
150080
150633
|
}
|
|
150081
150634
|
function formatError(error, mapper = (issue2) => issue2.message) {
|
|
150082
150635
|
const fieldErrors = { _errors: [] };
|
|
150083
|
-
const processError = (error2,
|
|
150636
|
+
const processError = (error2, path6 = []) => {
|
|
150084
150637
|
for (const issue2 of error2.issues) {
|
|
150085
150638
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
150086
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
150639
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
150087
150640
|
} else if (issue2.code === "invalid_key") {
|
|
150088
|
-
processError({ issues: issue2.issues }, [...
|
|
150641
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150089
150642
|
} else if (issue2.code === "invalid_element") {
|
|
150090
|
-
processError({ issues: issue2.issues }, [...
|
|
150643
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150091
150644
|
} else {
|
|
150092
|
-
const fullpath = [...
|
|
150645
|
+
const fullpath = [...path6, ...issue2.path];
|
|
150093
150646
|
if (fullpath.length === 0) {
|
|
150094
150647
|
fieldErrors._errors.push(mapper(issue2));
|
|
150095
150648
|
} else {
|
|
@@ -150116,17 +150669,17 @@ function formatError(error, mapper = (issue2) => issue2.message) {
|
|
|
150116
150669
|
}
|
|
150117
150670
|
function treeifyError(error, mapper = (issue2) => issue2.message) {
|
|
150118
150671
|
const result = { errors: [] };
|
|
150119
|
-
const processError = (error2,
|
|
150672
|
+
const processError = (error2, path6 = []) => {
|
|
150120
150673
|
var _a2, _b;
|
|
150121
150674
|
for (const issue2 of error2.issues) {
|
|
150122
150675
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
150123
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
150676
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
150124
150677
|
} else if (issue2.code === "invalid_key") {
|
|
150125
|
-
processError({ issues: issue2.issues }, [...
|
|
150678
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150126
150679
|
} else if (issue2.code === "invalid_element") {
|
|
150127
|
-
processError({ issues: issue2.issues }, [...
|
|
150680
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
150128
150681
|
} else {
|
|
150129
|
-
const fullpath = [...
|
|
150682
|
+
const fullpath = [...path6, ...issue2.path];
|
|
150130
150683
|
if (fullpath.length === 0) {
|
|
150131
150684
|
result.errors.push(mapper(issue2));
|
|
150132
150685
|
continue;
|
|
@@ -150158,8 +150711,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
|
|
|
150158
150711
|
}
|
|
150159
150712
|
function toDotPath(_path) {
|
|
150160
150713
|
const segs = [];
|
|
150161
|
-
const
|
|
150162
|
-
for (const seg of
|
|
150714
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
150715
|
+
for (const seg of path6) {
|
|
150163
150716
|
if (typeof seg === "number")
|
|
150164
150717
|
segs.push(`[${seg}]`);
|
|
150165
150718
|
else if (typeof seg === "symbol")
|
|
@@ -162618,13 +163171,13 @@ function resolveRef(ref, ctx) {
|
|
|
162618
163171
|
if (!ref.startsWith("#")) {
|
|
162619
163172
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
162620
163173
|
}
|
|
162621
|
-
const
|
|
162622
|
-
if (
|
|
163174
|
+
const path6 = ref.slice(1).split("/").filter(Boolean);
|
|
163175
|
+
if (path6.length === 0) {
|
|
162623
163176
|
return ctx.rootSchema;
|
|
162624
163177
|
}
|
|
162625
163178
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
162626
|
-
if (
|
|
162627
|
-
const key =
|
|
163179
|
+
if (path6[0] === defsKey) {
|
|
163180
|
+
const key = path6[1];
|
|
162628
163181
|
if (!key || !ctx.defs[key]) {
|
|
162629
163182
|
throw new Error(`Reference not found: ${ref}`);
|
|
162630
163183
|
}
|
|
@@ -163093,7 +163646,6 @@ var DEFAULT_DREAMER_TASKS = [
|
|
|
163093
163646
|
];
|
|
163094
163647
|
var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional();
|
|
163095
163648
|
var DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.object({
|
|
163096
|
-
enabled: exports_external.boolean().default(false),
|
|
163097
163649
|
schedule: exports_external.string().default("02:00-06:00"),
|
|
163098
163650
|
max_runtime_minutes: exports_external.number().min(10).default(120),
|
|
163099
163651
|
tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS),
|
|
@@ -163111,7 +163663,6 @@ var DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.objec
|
|
|
163111
163663
|
thinking_level: PiThinkingLevelSchema
|
|
163112
163664
|
}));
|
|
163113
163665
|
var SidekickConfigSchema = AgentOverrideConfigSchema.extend({
|
|
163114
|
-
enabled: exports_external.boolean().default(false),
|
|
163115
163666
|
timeout_ms: exports_external.number().default(30000),
|
|
163116
163667
|
system_prompt: exports_external.string().optional(),
|
|
163117
163668
|
thinking_level: PiThinkingLevelSchema
|
|
@@ -163295,9 +163846,9 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
163295
163846
|
}
|
|
163296
163847
|
|
|
163297
163848
|
// ../plugin/src/features/magic-context/memory/embedding-local.ts
|
|
163298
|
-
import { mkdirSync as
|
|
163849
|
+
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
163299
163850
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
163300
|
-
import { dirname as dirname4, join as
|
|
163851
|
+
import { dirname as dirname4, join as join13 } from "node:path";
|
|
163301
163852
|
import { pathToFileURL } from "node:url";
|
|
163302
163853
|
init_data_path();
|
|
163303
163854
|
init_logger();
|
|
@@ -163364,7 +163915,7 @@ async function injectWasmOrtForElectron() {
|
|
|
163364
163915
|
const { createRequire: createRequireFn } = await import("node:module");
|
|
163365
163916
|
const requireFn = createRequireFn(import.meta.url);
|
|
163366
163917
|
const pkgPath = requireFn.resolve("onnxruntime-web/package.json");
|
|
163367
|
-
const distDir =
|
|
163918
|
+
const distDir = join13(dirname4(pkgPath), "dist");
|
|
163368
163919
|
const wasmPathsPrefix = `${pathToFileURL(distDir).href}/`;
|
|
163369
163920
|
if (ortWeb.env?.wasm) {
|
|
163370
163921
|
ortWeb.env.wasm.wasmPaths = wasmPathsPrefix;
|
|
@@ -163475,15 +164026,15 @@ class LocalEmbeddingProvider {
|
|
|
163475
164026
|
if (LogLevel && "ERROR" in LogLevel) {
|
|
163476
164027
|
env.logLevel = LogLevel.ERROR;
|
|
163477
164028
|
}
|
|
163478
|
-
const modelCacheDir =
|
|
164029
|
+
const modelCacheDir = join13(getMagicContextStorageDir(), "models");
|
|
163479
164030
|
try {
|
|
163480
|
-
|
|
164031
|
+
mkdirSync5(modelCacheDir, { recursive: true });
|
|
163481
164032
|
env.cacheDir = modelCacheDir;
|
|
163482
164033
|
} catch {
|
|
163483
164034
|
log("[magic-context] could not create model cache dir, using library default");
|
|
163484
164035
|
}
|
|
163485
164036
|
const createPipeline = transformersModule.pipeline;
|
|
163486
|
-
const lockPath =
|
|
164037
|
+
const lockPath = join13(modelCacheDir, ".load.lock");
|
|
163487
164038
|
const releaseLock = await acquireModelLoadLock(lockPath);
|
|
163488
164039
|
const stopHeartbeat = startLockHeartbeat(lockPath);
|
|
163489
164040
|
try {
|
|
@@ -164651,7 +165202,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
164651
165202
|
const db = openDatabase();
|
|
164652
165203
|
await args.ensureRegistered(args.directory, db);
|
|
164653
165204
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
164654
|
-
const dreamingEnabled = Boolean(args.dreamerConfig
|
|
165205
|
+
const dreamingEnabled = Boolean(args.dreamerConfig && args.dreamerConfig.disable !== true && args.dreamerConfig.schedule?.trim());
|
|
164655
165206
|
const embeddingSweepEnabled = snapshot?.enabled ?? false;
|
|
164656
165207
|
const commitIndexingEnabled = snapshot?.gitCommitEnabled ?? false;
|
|
164657
165208
|
if (!dreamingEnabled && !embeddingSweepEnabled && !commitIndexingEnabled) {
|
|
@@ -164707,7 +165258,7 @@ function runTick(origin) {
|
|
|
164707
165258
|
})();
|
|
164708
165259
|
}
|
|
164709
165260
|
async function sweepProject(reg, origin, db = openDatabase(), gitCommitEnabled = getProjectEmbeddingSnapshot(reg.projectIdentity)?.gitCommitEnabled === true) {
|
|
164710
|
-
const dreamingEnabled = Boolean(reg.dreamerConfig
|
|
165261
|
+
const dreamingEnabled = Boolean(reg.dreamerConfig && reg.dreamerConfig.disable !== true && reg.dreamerConfig.schedule?.trim());
|
|
164711
165262
|
if (gitCommitEnabled && reg.gitCommitIndexing) {
|
|
164712
165263
|
await sweepGitCommits({
|
|
164713
165264
|
directory: reg.directory,
|
|
@@ -164835,12 +165386,12 @@ function handleUntrustedLoad(db, projectIdentity, directory, detailed) {
|
|
|
164835
165386
|
}
|
|
164836
165387
|
|
|
164837
165388
|
// src/config/index.ts
|
|
164838
|
-
import { existsSync as
|
|
165389
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
|
|
164839
165390
|
import { homedir as homedir5 } from "node:os";
|
|
164840
|
-
import { join as
|
|
165391
|
+
import { join as join14 } from "node:path";
|
|
164841
165392
|
|
|
164842
165393
|
// ../plugin/src/config/variable.ts
|
|
164843
|
-
import { existsSync as
|
|
165394
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6 } from "node:fs";
|
|
164844
165395
|
import { homedir as homedir4 } from "node:os";
|
|
164845
165396
|
import { dirname as dirname5, isAbsolute, resolve as resolve3 } from "node:path";
|
|
164846
165397
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
@@ -164898,13 +165449,13 @@ function substituteConfigVariables(input) {
|
|
|
164898
165449
|
} else if (!isAbsolute(filePath)) {
|
|
164899
165450
|
filePath = resolve3(configDir, filePath);
|
|
164900
165451
|
}
|
|
164901
|
-
if (!
|
|
165452
|
+
if (!existsSync10(filePath)) {
|
|
164902
165453
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
164903
165454
|
continue;
|
|
164904
165455
|
}
|
|
164905
165456
|
let contents;
|
|
164906
165457
|
try {
|
|
164907
|
-
contents =
|
|
165458
|
+
contents = readFileSync6(filePath, "utf-8").trim();
|
|
164908
165459
|
} catch (error51) {
|
|
164909
165460
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
164910
165461
|
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
@@ -164920,39 +165471,39 @@ function substituteConfigVariables(input) {
|
|
|
164920
165471
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
164921
165472
|
var CONFIG_FILE_NAME = "magic-context";
|
|
164922
165473
|
function getProjectConfigPaths(cwd) {
|
|
164923
|
-
const basePath =
|
|
165474
|
+
const basePath = join14(cwd, ".pi", CONFIG_FILE_NAME);
|
|
164924
165475
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
164925
165476
|
}
|
|
164926
165477
|
function getUserConfigPaths() {
|
|
164927
165478
|
const home = process.env.HOME ?? homedir5();
|
|
164928
|
-
const basePath =
|
|
165479
|
+
const basePath = join14(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
164929
165480
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
164930
165481
|
}
|
|
164931
165482
|
function resolveFirstExisting(paths) {
|
|
164932
|
-
return paths.find((
|
|
165483
|
+
return paths.find((path6) => existsSync11(path6));
|
|
164933
165484
|
}
|
|
164934
|
-
function loadConfigFile(
|
|
165485
|
+
function loadConfigFile(path6, scope) {
|
|
164935
165486
|
try {
|
|
164936
|
-
const rawText =
|
|
165487
|
+
const rawText = readFileSync7(path6, "utf-8");
|
|
164937
165488
|
const substituted = substituteConfigVariables({
|
|
164938
165489
|
text: rawText,
|
|
164939
|
-
configPath:
|
|
165490
|
+
configPath: path6
|
|
164940
165491
|
});
|
|
164941
165492
|
return {
|
|
164942
|
-
path:
|
|
165493
|
+
path: path6,
|
|
164943
165494
|
scope,
|
|
164944
165495
|
config: import_comment_json2.parse(substituted.text),
|
|
164945
|
-
warnings: substituted.warnings.map((warning) => `${
|
|
165496
|
+
warnings: substituted.warnings.map((warning) => `${path6}: ${warning}`),
|
|
164946
165497
|
loadOutcome: substituted.warnings.length > 0 ? "substitution-failure" : "ok"
|
|
164947
165498
|
};
|
|
164948
165499
|
} catch (error51) {
|
|
164949
165500
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
164950
165501
|
return {
|
|
164951
|
-
path:
|
|
165502
|
+
path: path6,
|
|
164952
165503
|
scope,
|
|
164953
165504
|
config: {},
|
|
164954
165505
|
warnings: [
|
|
164955
|
-
`${
|
|
165506
|
+
`${path6}: failed to load config: ${message}; using defaults for this file.`
|
|
164956
165507
|
],
|
|
164957
165508
|
loadOutcome: typeof error51.code === "string" ? "project-file-io-error" : "project-file-parse-error"
|
|
164958
165509
|
};
|
|
@@ -164990,9 +165541,11 @@ function mergeRawConfigs(base, override) {
|
|
|
164990
165541
|
return merged;
|
|
164991
165542
|
}
|
|
164992
165543
|
function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
164993
|
-
const
|
|
165544
|
+
const preMigrationWarnings = [];
|
|
165545
|
+
const migrated = migrateLegacyAgentEnabledInMemory(rawConfig, preMigrationWarnings);
|
|
165546
|
+
const parsed = MagicContextConfigSchema.safeParse(migrated);
|
|
164994
165547
|
if (parsed.success) {
|
|
164995
|
-
return { config: parsed.data, warnings:
|
|
165548
|
+
return { config: parsed.data, warnings: preMigrationWarnings };
|
|
164996
165549
|
}
|
|
164997
165550
|
const defaults = MagicContextConfigSchema.parse({});
|
|
164998
165551
|
const errorPaths = new Set;
|
|
@@ -165002,8 +165555,8 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
165002
165555
|
errorPaths.add(String(topKey));
|
|
165003
165556
|
}
|
|
165004
165557
|
}
|
|
165005
|
-
const patched = { ...
|
|
165006
|
-
const warnings = [];
|
|
165558
|
+
const patched = { ...migrated };
|
|
165559
|
+
const warnings = [...preMigrationWarnings];
|
|
165007
165560
|
for (const key of errorPaths) {
|
|
165008
165561
|
recoveredTopLevelKeys.push(key);
|
|
165009
165562
|
const isAgentConfig = key === "historian" || key === "dreamer" || key === "sidekick";
|
|
@@ -165077,9 +165630,9 @@ function bindSubstitutionFailures(loaded) {
|
|
|
165077
165630
|
}
|
|
165078
165631
|
const emptyPaths = collectEmptyStringPaths(loaded.config);
|
|
165079
165632
|
return loaded.warnings.map((message) => {
|
|
165080
|
-
const matchedPath = emptyPaths.find((
|
|
165081
|
-
const tail =
|
|
165082
|
-
return message.includes(
|
|
165633
|
+
const matchedPath = emptyPaths.find((path6) => {
|
|
165634
|
+
const tail = path6.split(".").at(-1) ?? path6;
|
|
165635
|
+
return message.includes(path6) || message.toLowerCase().includes(tail.toLowerCase());
|
|
165083
165636
|
});
|
|
165084
165637
|
return {
|
|
165085
165638
|
keyPath: matchedPath ?? "<unknown>",
|
|
@@ -165175,7 +165728,7 @@ var sessionCounter = 0;
|
|
|
165175
165728
|
var piSubagentRunnerFactory = () => new PiSubagentRunner;
|
|
165176
165729
|
var startDreamScheduleTimerFn = startDreamScheduleTimer;
|
|
165177
165730
|
function registerPiDreamerProject(opts) {
|
|
165178
|
-
if (
|
|
165731
|
+
if (opts.config.disable === true) {
|
|
165179
165732
|
return;
|
|
165180
165733
|
}
|
|
165181
165734
|
const existing = registeredProjects2.get(opts.projectIdentity);
|
|
@@ -165410,7 +165963,7 @@ function registerCtxDreamCommand(pi, deps) {
|
|
|
165410
165963
|
if (deps.dreamerEnabled === false) {
|
|
165411
165964
|
sendCtxStatusMessage(pi, {
|
|
165412
165965
|
title: "/ctx-dream",
|
|
165413
|
-
text: "## /ctx-dream\n\nDreamer is
|
|
165966
|
+
text: "## /ctx-dream\n\nDreamer is disabled for this project (`dreamer.disable=true`).",
|
|
165414
165967
|
level: "info"
|
|
165415
165968
|
}, {
|
|
165416
165969
|
projectDir: project.projectDir,
|
|
@@ -165456,6 +166009,8 @@ function registerCtxDreamCommand(pi, deps) {
|
|
|
165456
166009
|
let summary;
|
|
165457
166010
|
if (!result) {
|
|
165458
166011
|
summary = "Dream queued, but another worker is already processing the queue.";
|
|
166012
|
+
} else if (result.tasks.length === 0) {
|
|
166013
|
+
summary = "Dreamer is configured, but no dream tasks are enabled for this project.";
|
|
165459
166014
|
} else {
|
|
165460
166015
|
const taskLines = result.tasks.map((task) => {
|
|
165461
166016
|
const status = task.error ? `error: ${task.error}` : "ok";
|
|
@@ -165848,6 +166403,57 @@ function createTagger() {
|
|
|
165848
166403
|
};
|
|
165849
166404
|
}
|
|
165850
166405
|
|
|
166406
|
+
// ../plugin/src/features/magic-context/work-metrics.ts
|
|
166407
|
+
function asNumber2(value) {
|
|
166408
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
166409
|
+
}
|
|
166410
|
+
function getPiUsage(entry) {
|
|
166411
|
+
if (!entry || typeof entry !== "object")
|
|
166412
|
+
return null;
|
|
166413
|
+
const record2 = entry;
|
|
166414
|
+
const message = record2.message && typeof record2.message === "object" ? record2.message : record2;
|
|
166415
|
+
if (message.role !== "assistant")
|
|
166416
|
+
return null;
|
|
166417
|
+
if (!message.usage || typeof message.usage !== "object")
|
|
166418
|
+
return null;
|
|
166419
|
+
const usage = message.usage;
|
|
166420
|
+
return {
|
|
166421
|
+
input: asNumber2(usage.input),
|
|
166422
|
+
output: asNumber2(usage.output),
|
|
166423
|
+
cacheRead: asNumber2(usage.cacheRead ?? usage.cache_read),
|
|
166424
|
+
cacheWrite: asNumber2(usage.cacheWrite ?? usage.cache_write)
|
|
166425
|
+
};
|
|
166426
|
+
}
|
|
166427
|
+
function computePiWorkMetrics(sessionEntries) {
|
|
166428
|
+
let previousPrompt = 0;
|
|
166429
|
+
let phasePeak = 0;
|
|
166430
|
+
let newWorkTokens = 0;
|
|
166431
|
+
let totalInputTokens = 0;
|
|
166432
|
+
let lastOutput = 0;
|
|
166433
|
+
let sawAssistant = false;
|
|
166434
|
+
for (const entry of sessionEntries) {
|
|
166435
|
+
const usage = getPiUsage(entry);
|
|
166436
|
+
if (!usage)
|
|
166437
|
+
continue;
|
|
166438
|
+
const prompt = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
166439
|
+
if (sawAssistant && prompt < previousPrompt) {
|
|
166440
|
+
totalInputTokens += phasePeak;
|
|
166441
|
+
phasePeak = prompt;
|
|
166442
|
+
} else {
|
|
166443
|
+
phasePeak = Math.max(phasePeak, prompt);
|
|
166444
|
+
}
|
|
166445
|
+
newWorkTokens += Math.max(0, prompt - previousPrompt);
|
|
166446
|
+
previousPrompt = prompt;
|
|
166447
|
+
lastOutput = usage.output;
|
|
166448
|
+
sawAssistant = true;
|
|
166449
|
+
}
|
|
166450
|
+
if (sawAssistant) {
|
|
166451
|
+
totalInputTokens += phasePeak;
|
|
166452
|
+
newWorkTokens += lastOutput;
|
|
166453
|
+
}
|
|
166454
|
+
return { newWorkTokens, totalInputTokens };
|
|
166455
|
+
}
|
|
166456
|
+
|
|
165851
166457
|
// ../plugin/src/hooks/magic-context/apply-operations.ts
|
|
165852
166458
|
var USER_DROP_PREVIEW_CHARS = 250;
|
|
165853
166459
|
function buildReplacementContent(tagId, target) {
|
|
@@ -167787,7 +168393,7 @@ function stripNestedSystemReminders(text) {
|
|
|
167787
168393
|
return result;
|
|
167788
168394
|
}
|
|
167789
168395
|
function extractUserPromptText(message) {
|
|
167790
|
-
return stripNestedSystemReminders(collectUserPromptParts(message)).replace(
|
|
168396
|
+
return stripNestedSystemReminders(collectUserPromptParts(message)).replace(/<!--[\s\S]*?-->/g, "").replace(/<ctx-search-hint>[\s\S]*?<\/ctx-search-hint>/g, "").replace(/<ctx-search-auto>[\s\S]*?<\/ctx-search-auto>/g, "").replace(/<instruction[^>]*>[\s\S]*?<\/instruction>/g, "").replace(/<sidekick-augmentation>[\s\S]*?<\/sidekick-augmentation>/g, "").replace(/<\/?[a-zA-Z][^<>]*>/g, "").replace(/§\d+§\s*/g, "").replace(/[ \t]+\n/g, `
|
|
167791
168397
|
`).replace(/\n{3,}/g, `
|
|
167792
168398
|
|
|
167793
168399
|
`).trim();
|
|
@@ -167958,18 +168564,28 @@ function applyDeferredPiCompactionMarker(deps, sessionId, pending) {
|
|
|
167958
168564
|
return { kind: "stale-skip", reason: "target-superseded" };
|
|
167959
168565
|
}
|
|
167960
168566
|
const branchEntries = deps.readBranchEntries();
|
|
167961
|
-
|
|
168567
|
+
const pendingFirstKeptIndex = findEntryIndex(branchEntries, pending.firstKeptEntryId);
|
|
168568
|
+
if (pendingFirstKeptIndex < 0) {
|
|
167962
168569
|
return { kind: "stale-skip", reason: "entry-removed" };
|
|
167963
168570
|
}
|
|
167964
168571
|
const latestFirstKept = findLatestCompactionFirstKept(branchEntries);
|
|
167965
|
-
if (latestFirstKept
|
|
167966
|
-
|
|
168572
|
+
if (latestFirstKept !== null) {
|
|
168573
|
+
const latestFirstKeptIndex = findEntryIndex(branchEntries, latestFirstKept);
|
|
168574
|
+
if (latestFirstKeptIndex >= pendingFirstKeptIndex) {
|
|
168575
|
+
return { kind: "already-current" };
|
|
168576
|
+
}
|
|
167967
168577
|
}
|
|
167968
|
-
deps.appendCompaction(pending.summary, pending.firstKeptEntryId, pending.tokensBefore, {
|
|
168578
|
+
const compactionId = deps.appendCompaction(pending.summary, pending.firstKeptEntryId, pending.tokensBefore, {
|
|
167969
168579
|
source: "magic-context",
|
|
167970
168580
|
lastCompactedOrdinal: pending.ordinal
|
|
167971
168581
|
}, true);
|
|
167972
|
-
|
|
168582
|
+
if (typeof compactionId !== "string" || compactionId.length === 0) {
|
|
168583
|
+
return {
|
|
168584
|
+
kind: "retryable-failure",
|
|
168585
|
+
error: new Error("Pi appendCompaction returned no compaction id")
|
|
168586
|
+
};
|
|
168587
|
+
}
|
|
168588
|
+
sessionLog(sessionId, `Pi compaction-marker drain: applied compactionId=${compactionId} firstKept=${pending.firstKeptEntryId} endMessageId=${pending.endMessageId} ordinal=${pending.ordinal} tokensBefore=${pending.tokensBefore}`);
|
|
167973
168589
|
return { kind: "applied", firstKeptEntryId: pending.firstKeptEntryId };
|
|
167974
168590
|
} catch (err) {
|
|
167975
168591
|
const error51 = err instanceof Error ? err : new Error(String(err));
|
|
@@ -167995,6 +168611,9 @@ function getEntryId(entry) {
|
|
|
167995
168611
|
const id = entry.id;
|
|
167996
168612
|
return typeof id === "string" ? id : null;
|
|
167997
168613
|
}
|
|
168614
|
+
function findEntryIndex(branchEntries, entryId) {
|
|
168615
|
+
return branchEntries.findIndex((entry) => getEntryId(entry) === entryId);
|
|
168616
|
+
}
|
|
167998
168617
|
|
|
167999
168618
|
// src/detect-recent-commit.ts
|
|
168000
168619
|
var COMMIT_LOOKBACK = 5;
|
|
@@ -168347,36 +168966,70 @@ function trimPiMessagesToBoundary(piMessages, entryIds, cutoffMessageId) {
|
|
|
168347
168966
|
}
|
|
168348
168967
|
if (cutoffIndex < 0)
|
|
168349
168968
|
return 0;
|
|
168350
|
-
const
|
|
168351
|
-
for (let i = 0;i <= cutoffIndex; i++)
|
|
168352
|
-
|
|
168353
|
-
|
|
168354
|
-
|
|
168355
|
-
|
|
168356
|
-
|
|
168357
|
-
|
|
168358
|
-
for (const
|
|
168359
|
-
|
|
168360
|
-
|
|
168969
|
+
const remove = new Set;
|
|
168970
|
+
for (let i = 0;i <= cutoffIndex; i++)
|
|
168971
|
+
remove.add(i);
|
|
168972
|
+
let changed = true;
|
|
168973
|
+
while (changed) {
|
|
168974
|
+
changed = false;
|
|
168975
|
+
const removedCallIds = new Set;
|
|
168976
|
+
const removedResultIds = new Set;
|
|
168977
|
+
for (const index of remove) {
|
|
168978
|
+
const msg = piMessages[index];
|
|
168979
|
+
if (!msg)
|
|
168980
|
+
continue;
|
|
168981
|
+
if (msg.role === "assistant") {
|
|
168982
|
+
for (const callId of getPiToolCallIds(msg))
|
|
168983
|
+
removedCallIds.add(callId);
|
|
168984
|
+
} else if (msg.role === "toolResult") {
|
|
168985
|
+
const callId = getPiToolResultCallId(msg);
|
|
168986
|
+
if (callId)
|
|
168987
|
+
removedResultIds.add(callId);
|
|
168361
168988
|
}
|
|
168362
168989
|
}
|
|
168363
|
-
|
|
168364
|
-
|
|
168365
|
-
|
|
168366
|
-
while (i < piMessages.length) {
|
|
168990
|
+
for (let i = 0;i < piMessages.length; i++) {
|
|
168991
|
+
if (remove.has(i))
|
|
168992
|
+
continue;
|
|
168367
168993
|
const msg = piMessages[i];
|
|
168368
|
-
if (msg
|
|
168369
|
-
|
|
168370
|
-
|
|
168371
|
-
|
|
168372
|
-
|
|
168994
|
+
if (!msg)
|
|
168995
|
+
continue;
|
|
168996
|
+
if (msg.role === "toolResult") {
|
|
168997
|
+
const callId = getPiToolResultCallId(msg);
|
|
168998
|
+
if (callId && removedCallIds.has(callId)) {
|
|
168999
|
+
remove.add(i);
|
|
169000
|
+
changed = true;
|
|
169001
|
+
}
|
|
169002
|
+
continue;
|
|
169003
|
+
}
|
|
169004
|
+
if (msg.role === "assistant") {
|
|
169005
|
+
const callIds = getPiToolCallIds(msg);
|
|
169006
|
+
if (callIds.some((callId) => removedResultIds.has(callId))) {
|
|
169007
|
+
remove.add(i);
|
|
169008
|
+
changed = true;
|
|
169009
|
+
}
|
|
168373
169010
|
}
|
|
168374
169011
|
}
|
|
168375
169012
|
}
|
|
168376
|
-
const
|
|
168377
|
-
piMessages.
|
|
169013
|
+
const kept = piMessages.filter((_, index) => !remove.has(index));
|
|
169014
|
+
const removed = piMessages.length - kept.length;
|
|
169015
|
+
piMessages.splice(0, piMessages.length, ...kept);
|
|
168378
169016
|
return removed;
|
|
168379
169017
|
}
|
|
169018
|
+
function getPiToolCallIds(message) {
|
|
169019
|
+
if (!Array.isArray(message.content))
|
|
169020
|
+
return [];
|
|
169021
|
+
const ids = [];
|
|
169022
|
+
for (const part of message.content) {
|
|
169023
|
+
if (part && typeof part === "object" && part.type === "toolCall" && typeof part.id === "string") {
|
|
169024
|
+
ids.push(part.id);
|
|
169025
|
+
}
|
|
169026
|
+
}
|
|
169027
|
+
return ids;
|
|
169028
|
+
}
|
|
169029
|
+
function getPiToolResultCallId(message) {
|
|
169030
|
+
const callId = message.toolCallId;
|
|
169031
|
+
return typeof callId === "string" && callId.length > 0 ? callId : null;
|
|
169032
|
+
}
|
|
168380
169033
|
function injectHistoryBlockIntoFirstUserMessage(piMessages, historyBlock) {
|
|
168381
169034
|
for (let i = 0;i < piMessages.length; i++) {
|
|
168382
169035
|
const msg = piMessages[i];
|
|
@@ -168468,6 +169121,7 @@ ${prepared.block}
|
|
|
168468
169121
|
// src/note-visibility-pi.ts
|
|
168469
169122
|
var NOTE_TOOL_NAME = "ctx_note";
|
|
168470
169123
|
var READ_ACTION = "read";
|
|
169124
|
+
var WHOLE_MESSAGE_PLACEHOLDER_TEXT = "[dropped]";
|
|
168471
169125
|
function hasVisibleNoteReadCallPi(messages) {
|
|
168472
169126
|
for (let i = messages.length - 1;i >= 0; i--) {
|
|
168473
169127
|
const raw = messages[i];
|
|
@@ -168479,6 +169133,8 @@ function hasVisibleNoteReadCallPi(messages) {
|
|
|
168479
169133
|
if (!Array.isArray(msg.content))
|
|
168480
169134
|
continue;
|
|
168481
169135
|
for (const part of msg.content) {
|
|
169136
|
+
if (isSentinelPart(part))
|
|
169137
|
+
continue;
|
|
168482
169138
|
if (!part || typeof part !== "object")
|
|
168483
169139
|
continue;
|
|
168484
169140
|
const p = part;
|
|
@@ -168496,6 +169152,12 @@ function hasVisibleNoteReadCallPi(messages) {
|
|
|
168496
169152
|
}
|
|
168497
169153
|
return false;
|
|
168498
169154
|
}
|
|
169155
|
+
function isSentinelPart(part) {
|
|
169156
|
+
if (!part || typeof part !== "object")
|
|
169157
|
+
return false;
|
|
169158
|
+
const p = part;
|
|
169159
|
+
return p.type === "text" && typeof p.text === "string" && (p.text === "" || p.text === WHOLE_MESSAGE_PLACEHOLDER_TEXT);
|
|
169160
|
+
}
|
|
168499
169161
|
|
|
168500
169162
|
// src/nudge-injector.ts
|
|
168501
169163
|
var INSTRUCTION_NAME_PATTERN = /<instruction\s+name="([^"]+)">/;
|
|
@@ -168553,12 +169215,12 @@ function createAssistantNudgeMessage(text, messages) {
|
|
|
168553
169215
|
function findLatestAssistantMessage(messages) {
|
|
168554
169216
|
for (let i = messages.length - 1;i >= 0; i--) {
|
|
168555
169217
|
const message = messages[i];
|
|
168556
|
-
if (
|
|
169218
|
+
if (isAssistantMessage2(message))
|
|
168557
169219
|
return message;
|
|
168558
169220
|
}
|
|
168559
169221
|
return;
|
|
168560
169222
|
}
|
|
168561
|
-
function
|
|
169223
|
+
function isAssistantMessage2(message) {
|
|
168562
169224
|
return getRole(message) === "assistant";
|
|
168563
169225
|
}
|
|
168564
169226
|
function createZeroUsage() {
|
|
@@ -169060,6 +169722,8 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169060
169722
|
sessionLog(sessionId, `compressor: history block ~${totalTokens} tokens within budget ${historyBudgetTokens}, skipping`);
|
|
169061
169723
|
return false;
|
|
169062
169724
|
}
|
|
169725
|
+
const overage = totalTokens - historyBudgetTokens;
|
|
169726
|
+
sessionLog(sessionId, `compressor: history block ~${totalTokens} tokens exceeds budget ${historyBudgetTokens} by ~${overage} tokens`);
|
|
169063
169727
|
const lastEndMessage = compartments[compartments.length - 1]?.endMessage ?? 0;
|
|
169064
169728
|
const floor = Math.max(1, Math.ceil(lastEndMessage / minCompartmentRatio));
|
|
169065
169729
|
const floorHeadroom = compartments.length - floor;
|
|
@@ -169068,6 +169732,17 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169068
169732
|
return false;
|
|
169069
169733
|
}
|
|
169070
169734
|
const scored = scoreCompartments(db, sessionId, compartments);
|
|
169735
|
+
const depthHistogram = new Map;
|
|
169736
|
+
for (const scoredCompartment of scored) {
|
|
169737
|
+
const bucket = Math.round(scoredCompartment.averageDepth);
|
|
169738
|
+
depthHistogram.set(bucket, (depthHistogram.get(bucket) ?? 0) + 1);
|
|
169739
|
+
}
|
|
169740
|
+
const histText = [...depthHistogram.entries()].sort((a, b) => a[0] - b[0]).map(([depth, count]) => `d${depth}=${count}`).join(" ");
|
|
169741
|
+
const histKey = `${scored.length}|${histText}`;
|
|
169742
|
+
if (lastDepthHistogramBySession.get(sessionId) !== histKey) {
|
|
169743
|
+
lastDepthHistogramBySession.set(sessionId, histKey);
|
|
169744
|
+
sessionLog(sessionId, `compressor: depth histogram (${scored.length} total) ${histText}`);
|
|
169745
|
+
}
|
|
169071
169746
|
const band = selectPiCompressionBand(scored, {
|
|
169072
169747
|
maxPickable: maxCompartmentsPerPass,
|
|
169073
169748
|
maxMergeDepth,
|
|
@@ -169086,7 +169761,7 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169086
169761
|
const outputDepth = Math.min(5, Math.max(1, Math.round(avgDepth) + 1));
|
|
169087
169762
|
const mergeRatio = COMPRESSOR_MERGE_RATIO_BY_DEPTH[outputDepth] ?? 2;
|
|
169088
169763
|
const outputCount = mergeRatio > 0 ? Math.max(1, Math.ceil(band.length / mergeRatio)) : 1;
|
|
169089
|
-
sessionLog(sessionId, `compressor: picked ${band.length}
|
|
169764
|
+
sessionLog(sessionId, `compressor: scored ${compartments.length}, picked ${band.length} contiguous (${selectedCompartments[0]?.startMessage}-${selectedCompartments[selectedCompartments.length - 1]?.endMessage}, ~${selectedTokens} tokens), avg_depth=${avgDepth.toFixed(1)} → output_depth=${outputDepth} (ratio=${mergeRatio}, target=${outputCount} compartments)`);
|
|
169090
169765
|
if (outputDepth === 5) {
|
|
169091
169766
|
const compressed = selectedCompartments.map((c) => ({
|
|
169092
169767
|
startMessage: c.startMessage,
|
|
@@ -169106,7 +169781,8 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169106
169781
|
originalStart: selectedCompartments[0]?.startMessage ?? 0,
|
|
169107
169782
|
originalEnd: selectedCompartments[selectedCompartments.length - 1]?.endMessage ?? 0,
|
|
169108
169783
|
facts,
|
|
169109
|
-
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${compressed.length})
|
|
169784
|
+
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${compressed.length})`,
|
|
169785
|
+
holderId: deps.compartmentLeaseHolderId
|
|
169110
169786
|
});
|
|
169111
169787
|
if (ok2)
|
|
169112
169788
|
onPublished?.();
|
|
@@ -169137,7 +169813,8 @@ async function runPiCompressionPassIfNeeded(deps) {
|
|
|
169137
169813
|
originalStart: selectedCompartments[0]?.startMessage ?? 0,
|
|
169138
169814
|
originalEnd: selectedCompartments[selectedCompartments.length - 1]?.endMessage ?? 0,
|
|
169139
169815
|
facts,
|
|
169140
|
-
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})
|
|
169816
|
+
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})`,
|
|
169817
|
+
holderId: deps.compartmentLeaseHolderId
|
|
169141
169818
|
});
|
|
169142
169819
|
if (ok)
|
|
169143
169820
|
onPublished?.();
|
|
@@ -169154,7 +169831,9 @@ async function runCompressorPass(args) {
|
|
|
169154
169831
|
fallbackModels: args.fallbackModels,
|
|
169155
169832
|
timeoutMs: args.historianTimeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
169156
169833
|
cwd: args.directory,
|
|
169157
|
-
thinkingLevel: args.thinkingLevel
|
|
169834
|
+
thinkingLevel: args.thinkingLevel,
|
|
169835
|
+
accountingSessionId: args.sessionId,
|
|
169836
|
+
accountingSubagent: "compressor"
|
|
169158
169837
|
});
|
|
169159
169838
|
if (!result.ok) {
|
|
169160
169839
|
sessionLog(args.sessionId, `compressor: subagent failed (${result.reason}): ${result.error}`);
|
|
@@ -169246,12 +169925,20 @@ function finalizeCompression(args) {
|
|
|
169246
169925
|
sequence: leading.length + compressed.length + i
|
|
169247
169926
|
}))
|
|
169248
169927
|
];
|
|
169249
|
-
|
|
169250
|
-
|
|
169928
|
+
const published = args.holderId ? replaceAllCompartmentStateAndBumpDepth(db, args.holderId, sessionId, allCompartments, args.facts, originalStart, originalEnd) : (() => {
|
|
169929
|
+
replaceAllCompartmentState(db, sessionId, allCompartments, args.facts);
|
|
169930
|
+
incrementCompressionDepth(db, sessionId, originalStart, originalEnd);
|
|
169931
|
+
return true;
|
|
169932
|
+
})();
|
|
169933
|
+
if (!published) {
|
|
169934
|
+
sessionLog(sessionId, "compressor: publish skipped because compartment lease is no longer held");
|
|
169935
|
+
return false;
|
|
169936
|
+
}
|
|
169251
169937
|
sessionLog(sessionId, `compressor: completed ${args.logLabel}`);
|
|
169252
169938
|
return true;
|
|
169253
169939
|
}
|
|
169254
169940
|
var lastCompressorRunBySession = new Map;
|
|
169941
|
+
var lastDepthHistogramBySession = new Map;
|
|
169255
169942
|
function isPiCompressorOnCooldown(sessionId, cooldownMs) {
|
|
169256
169943
|
const last = lastCompressorRunBySession.get(sessionId);
|
|
169257
169944
|
return last !== undefined && Date.now() - last < cooldownMs;
|
|
@@ -169261,6 +169948,7 @@ function markPiCompressorRun(sessionId) {
|
|
|
169261
169948
|
}
|
|
169262
169949
|
function clearPiCompressorState(sessionId) {
|
|
169263
169950
|
lastCompressorRunBySession.delete(sessionId);
|
|
169951
|
+
lastDepthHistogramBySession.delete(sessionId);
|
|
169264
169952
|
}
|
|
169265
169953
|
|
|
169266
169954
|
// ../plugin/src/hooks/magic-context/compartment-runner-drop-queue.ts
|
|
@@ -169491,27 +170179,27 @@ function getReducedRecompTokenBudget(currentBudget) {
|
|
|
169491
170179
|
|
|
169492
170180
|
// ../plugin/src/hooks/magic-context/historian-state-file.ts
|
|
169493
170181
|
init_data_path();
|
|
169494
|
-
import { mkdirSync as
|
|
169495
|
-
import { join as
|
|
170182
|
+
import { mkdirSync as mkdirSync6, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
170183
|
+
import { join as join15 } from "node:path";
|
|
169496
170184
|
var HISTORIAN_STATE_INLINE_THRESHOLD = 30000;
|
|
169497
170185
|
function maybeWriteHistorianStateFile(sessionId, existingState, directory) {
|
|
169498
170186
|
if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
|
|
169499
170187
|
return;
|
|
169500
170188
|
try {
|
|
169501
170189
|
const dir = getProjectMagicContextHistorianDir(directory);
|
|
169502
|
-
|
|
169503
|
-
const
|
|
169504
|
-
|
|
169505
|
-
return
|
|
170190
|
+
mkdirSync6(dir, { recursive: true });
|
|
170191
|
+
const path6 = join15(dir, `state-${sessionId}-${Date.now()}.xml`);
|
|
170192
|
+
writeFileSync3(path6, existingState, "utf8");
|
|
170193
|
+
return path6;
|
|
169506
170194
|
} catch {
|
|
169507
170195
|
return;
|
|
169508
170196
|
}
|
|
169509
170197
|
}
|
|
169510
|
-
function cleanupHistorianStateFile(
|
|
169511
|
-
if (!
|
|
170198
|
+
function cleanupHistorianStateFile(path6) {
|
|
170199
|
+
if (!path6)
|
|
169512
170200
|
return;
|
|
169513
170201
|
try {
|
|
169514
|
-
unlinkSync(
|
|
170202
|
+
unlinkSync(path6);
|
|
169515
170203
|
} catch {}
|
|
169516
170204
|
}
|
|
169517
170205
|
|
|
@@ -169628,7 +170316,7 @@ function convertEntriesToRawMessages(entries) {
|
|
|
169628
170316
|
if (pendingToolParts.length > 0) {
|
|
169629
170317
|
result.push({
|
|
169630
170318
|
ordinal: nextOrdinal++,
|
|
169631
|
-
id: pendingFirstRealId
|
|
170319
|
+
id: `synth-user-${pendingFirstRealId}`,
|
|
169632
170320
|
role: "user",
|
|
169633
170321
|
parts: pendingToolParts
|
|
169634
170322
|
});
|
|
@@ -169653,7 +170341,7 @@ function convertEntriesToRawMessages(entries) {
|
|
|
169653
170341
|
if (pendingToolParts.length > 0) {
|
|
169654
170342
|
result.push({
|
|
169655
170343
|
ordinal: nextOrdinal,
|
|
169656
|
-
id: pendingFirstRealId
|
|
170344
|
+
id: `synth-user-${pendingFirstRealId}`,
|
|
169657
170345
|
role: "user",
|
|
169658
170346
|
parts: pendingToolParts
|
|
169659
170347
|
});
|
|
@@ -169776,6 +170464,7 @@ async function runPiHistorian(deps) {
|
|
|
169776
170464
|
memoryEnabled,
|
|
169777
170465
|
autoPromote,
|
|
169778
170466
|
onPublished,
|
|
170467
|
+
compartmentLeaseHolderId,
|
|
169779
170468
|
readBranchEntries,
|
|
169780
170469
|
notifyIssue
|
|
169781
170470
|
} = deps;
|
|
@@ -169802,23 +170491,27 @@ async function runPiHistorian(deps) {
|
|
|
169802
170491
|
const existingValidationError = validateStoredCompartments(priorCompartments);
|
|
169803
170492
|
if (existingValidationError) {
|
|
169804
170493
|
sessionLog(sessionId, `historian failure: source=existing-validation reason="${existingValidationError}"`);
|
|
170494
|
+
incrementHistorianFailure(db, sessionId, existingValidationError);
|
|
169805
170495
|
await notify(`Historian skipped: existing stored compartments are invalid: ${existingValidationError}`);
|
|
169806
170496
|
return;
|
|
169807
170497
|
}
|
|
169808
170498
|
const offset = priorCompartments.length > 0 ? priorCompartments[priorCompartments.length - 1].endMessage + 1 : 1;
|
|
169809
170499
|
const protectedTailStart = getProtectedTailStartOrdinal(sessionId);
|
|
169810
170500
|
if (protectedTailStart <= offset) {
|
|
169811
|
-
sessionLog(sessionId, `historian
|
|
170501
|
+
sessionLog(sessionId, `historian no-op: protectedTailStart=${protectedTailStart} <= offset=${offset} — nothing to compact`);
|
|
170502
|
+
clearEmergencyRecovery(db, sessionId);
|
|
169812
170503
|
return;
|
|
169813
170504
|
}
|
|
169814
170505
|
const chunk = readSessionChunk(sessionId, historianChunkTokens, offset, protectedTailStart);
|
|
169815
170506
|
if (!chunk.text || chunk.messageCount === 0) {
|
|
169816
|
-
sessionLog(sessionId, `historian
|
|
170507
|
+
sessionLog(sessionId, `historian no-op: chunk empty after filtering (messageCount=${chunk.messageCount}, textLen=${chunk.text?.length ?? 0}) range=${offset}-${protectedTailStart - 1}`);
|
|
170508
|
+
clearEmergencyRecovery(db, sessionId);
|
|
169817
170509
|
return;
|
|
169818
170510
|
}
|
|
169819
170511
|
const chunkCoverageError = validateChunkCoverage(chunk);
|
|
169820
170512
|
if (chunkCoverageError) {
|
|
169821
170513
|
sessionLog(sessionId, `historian failure: source=chunk-coverage reason="${chunkCoverageError}" chunkRange=${chunk.startIndex}-${chunk.endIndex}`);
|
|
170514
|
+
incrementHistorianFailure(db, sessionId, chunkCoverageError);
|
|
169822
170515
|
await notify(`Historian skipped: raw chunk could not be safely chunked: ${chunkCoverageError}`);
|
|
169823
170516
|
return;
|
|
169824
170517
|
}
|
|
@@ -169884,7 +170577,9 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169884
170577
|
timeoutMs: historianTimeoutMs,
|
|
169885
170578
|
cwd: directory,
|
|
169886
170579
|
thinkingLevel,
|
|
169887
|
-
onProgress: buildProgressLogger("first")
|
|
170580
|
+
onProgress: buildProgressLogger("first"),
|
|
170581
|
+
accountingSessionId: sessionId,
|
|
170582
|
+
accountingSubagent: "historian"
|
|
169888
170583
|
});
|
|
169889
170584
|
let validatedPass = await validateHistorianResult(firstResult, sessionId, chunk, priorCompartments, sequenceOffset);
|
|
169890
170585
|
let validatedDraftText = firstResult.ok ? firstResult.assistantText : null;
|
|
@@ -169900,7 +170595,9 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169900
170595
|
timeoutMs: historianTimeoutMs,
|
|
169901
170596
|
cwd: directory,
|
|
169902
170597
|
thinkingLevel,
|
|
169903
|
-
onProgress: buildProgressLogger("repair")
|
|
170598
|
+
onProgress: buildProgressLogger("repair"),
|
|
170599
|
+
accountingSessionId: sessionId,
|
|
170600
|
+
accountingSubagent: "historian"
|
|
169904
170601
|
});
|
|
169905
170602
|
validatedPass = await validateHistorianResult(repairResult, sessionId, chunk, priorCompartments, sequenceOffset);
|
|
169906
170603
|
if (validatedPass.kind === "ok" && repairResult.ok) {
|
|
@@ -169923,11 +170620,12 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169923
170620
|
systemPrompt: HISTORIAN_EDITOR_SYSTEM_PROMPT,
|
|
169924
170621
|
userMessage: buildHistorianEditorPrompt(draftAssistantText),
|
|
169925
170622
|
model: historianModel,
|
|
169926
|
-
fallbackModels,
|
|
169927
170623
|
timeoutMs: historianTimeoutMs,
|
|
169928
170624
|
cwd: directory,
|
|
169929
170625
|
thinkingLevel,
|
|
169930
|
-
onProgress: buildProgressLogger("editor")
|
|
170626
|
+
onProgress: buildProgressLogger("editor"),
|
|
170627
|
+
accountingSessionId: sessionId,
|
|
170628
|
+
accountingSubagent: "historian_editor"
|
|
169931
170629
|
});
|
|
169932
170630
|
const editorPass = await validateHistorianResult(editorResult, sessionId, chunk, priorCompartments, sequenceOffset);
|
|
169933
170631
|
if (editorPass.kind === "ok") {
|
|
@@ -169961,10 +170659,30 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169961
170659
|
sessionLog(sessionId, `historian: native compaction queue lookup failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
169962
170660
|
}
|
|
169963
170661
|
}
|
|
169964
|
-
|
|
170662
|
+
if (!compartmentLeaseHolderId) {
|
|
170663
|
+
sessionLog(sessionId, "historian publish skipped: missing compartment lease holder");
|
|
170664
|
+
return;
|
|
170665
|
+
}
|
|
170666
|
+
let published = false;
|
|
170667
|
+
db.exec("BEGIN IMMEDIATE");
|
|
170668
|
+
try {
|
|
170669
|
+
if (!isCompartmentLeaseHeld(db, sessionId, compartmentLeaseHolderId)) {
|
|
170670
|
+
db.exec("ROLLBACK");
|
|
170671
|
+
sessionLog(sessionId, "historian publish skipped: compartment lease no longer held");
|
|
170672
|
+
return;
|
|
170673
|
+
}
|
|
169965
170674
|
appendCompartments(db, sessionId, newCompartments);
|
|
169966
170675
|
replaceSessionFacts(db, sessionId, validatedPass.facts ?? []);
|
|
169967
170676
|
clearHistorianFailureState(db, sessionId);
|
|
170677
|
+
clearEmergencyRecovery(db, sessionId);
|
|
170678
|
+
if (validatedPass.userObservations?.length) {
|
|
170679
|
+
insertUserMemoryCandidates(db, validatedPass.userObservations.map((obs) => ({
|
|
170680
|
+
content: obs,
|
|
170681
|
+
sessionId,
|
|
170682
|
+
sourceCompartmentStart: newCompartments[0]?.startMessage,
|
|
170683
|
+
sourceCompartmentEnd: lastNewEnd
|
|
170684
|
+
})));
|
|
170685
|
+
}
|
|
169968
170686
|
if (firstKeptEntryId && lastNewEndMessageId) {
|
|
169969
170687
|
setPendingPiCompactionMarkerState(db, sessionId, {
|
|
169970
170688
|
firstKeptEntryId,
|
|
@@ -169975,13 +170693,24 @@ ${chunk.text}`, { stateFilePath });
|
|
|
169975
170693
|
publishedAt: Date.now()
|
|
169976
170694
|
});
|
|
169977
170695
|
}
|
|
169978
|
-
|
|
170696
|
+
db.exec("COMMIT");
|
|
170697
|
+
published = true;
|
|
170698
|
+
} finally {
|
|
170699
|
+
if (!published) {
|
|
170700
|
+
try {
|
|
170701
|
+
db.exec("ROLLBACK");
|
|
170702
|
+
} catch {}
|
|
170703
|
+
}
|
|
170704
|
+
}
|
|
169979
170705
|
onNoteTrigger(db, sessionId, "historian_complete");
|
|
169980
170706
|
onPublished?.();
|
|
169981
170707
|
if (memoryEnabled !== false && autoPromote !== false) {
|
|
169982
170708
|
promoteSessionFactsToMemory(db, sessionId, projectPath, validatedPass.facts ?? []);
|
|
169983
170709
|
}
|
|
169984
170710
|
queueDropsForCompartmentalizedMessages(db, sessionId, lastNewEnd);
|
|
170711
|
+
if (validatedPass.userObservations?.length) {
|
|
170712
|
+
sessionLog(sessionId, `stored ${validatedPass.userObservations.length} user memory candidate(s)`);
|
|
170713
|
+
}
|
|
169985
170714
|
sessionLog(sessionId, `historian: published ${newCompartments.length} compartment(s), ${validatedPass.facts?.length ?? 0} fact(s) covering messages ${chunk.startIndex}-${lastNewEnd}`);
|
|
169986
170715
|
completedSuccessfully = true;
|
|
169987
170716
|
});
|
|
@@ -170453,8 +171182,8 @@ function stripPiDroppedPlaceholderMessages(args) {
|
|
|
170453
171182
|
|
|
170454
171183
|
// src/system-prompt.ts
|
|
170455
171184
|
import { createHash as createHash8 } from "node:crypto";
|
|
170456
|
-
import { existsSync as
|
|
170457
|
-
import { join as
|
|
171185
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
|
|
171186
|
+
import { join as join17 } from "node:path";
|
|
170458
171187
|
|
|
170459
171188
|
// ../plugin/src/agents/magic-context-prompt.ts
|
|
170460
171189
|
function getToolHistoryGuidance(dropToolStructure) {
|
|
@@ -170544,16 +171273,16 @@ Prefer many small targeted operations over one large blanket operation. Compress
|
|
|
170544
171273
|
}
|
|
170545
171274
|
|
|
170546
171275
|
// ../plugin/src/hooks/magic-context/key-files-block.ts
|
|
170547
|
-
import { readFileSync as
|
|
170548
|
-
import { join as
|
|
171276
|
+
import { readFileSync as readFileSync8, realpathSync as realpathSync3 } from "node:fs";
|
|
171277
|
+
import { join as join16, sep as sep2 } from "node:path";
|
|
170549
171278
|
init_logger();
|
|
170550
171279
|
var cachedKeyFilesBySession = new Map;
|
|
170551
171280
|
var staleUpdates = new Map;
|
|
170552
171281
|
function staleKey(update) {
|
|
170553
171282
|
return `${update.projectPath}\x00${update.path}\x00${update.generatedAtWitness}\x00${update.staleReason}`;
|
|
170554
171283
|
}
|
|
170555
|
-
function queueStaleUpdate(projectPath,
|
|
170556
|
-
const update = { projectPath, path:
|
|
171284
|
+
function queueStaleUpdate(projectPath, path6, generatedAtWitness, staleReason) {
|
|
171285
|
+
const update = { projectPath, path: path6, generatedAtWitness, staleReason };
|
|
170557
171286
|
staleUpdates.set(staleKey(update), update);
|
|
170558
171287
|
}
|
|
170559
171288
|
function flushStaleUpdates(db) {
|
|
@@ -170598,13 +171327,13 @@ function buildKeyFilesBlock(db, projectPath, config2 = { enabled: true, tokenBud
|
|
|
170598
171327
|
let nextStale = null;
|
|
170599
171328
|
let observed = false;
|
|
170600
171329
|
try {
|
|
170601
|
-
const absPath =
|
|
171330
|
+
const absPath = join16(projectPath, row.path);
|
|
170602
171331
|
const real = realpathSync3(absPath);
|
|
170603
171332
|
if (!isUnderProject(projectPath, real)) {
|
|
170604
171333
|
nextStale = "missing";
|
|
170605
171334
|
observed = true;
|
|
170606
171335
|
} else {
|
|
170607
|
-
const diskHash = sha256(
|
|
171336
|
+
const diskHash = sha256(readFileSync8(real));
|
|
170608
171337
|
if (diskHash !== row.contentHash)
|
|
170609
171338
|
nextStale = "content_drift";
|
|
170610
171339
|
observed = true;
|
|
@@ -170681,10 +171410,10 @@ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
170681
171410
|
function readProjectDocs(directory) {
|
|
170682
171411
|
const sections = [];
|
|
170683
171412
|
for (const filename of DOC_FILES) {
|
|
170684
|
-
const filePath =
|
|
171413
|
+
const filePath = join17(directory, filename);
|
|
170685
171414
|
try {
|
|
170686
|
-
if (
|
|
170687
|
-
const content =
|
|
171415
|
+
if (existsSync12(filePath)) {
|
|
171416
|
+
const content = readFileSync9(filePath, "utf-8").trim();
|
|
170688
171417
|
if (content.length > 0) {
|
|
170689
171418
|
sections.push(`<${filename}>
|
|
170690
171419
|
${escapeXmlContent(content)}
|
|
@@ -171438,6 +172167,16 @@ var recentReduceBySession = new Map;
|
|
|
171438
172167
|
var liveModelBySession = new Map;
|
|
171439
172168
|
var toolUsageSinceUserTurn = new Map;
|
|
171440
172169
|
var latestUserMessageBySession = new Map;
|
|
172170
|
+
var RECENT_REDUCE_TTL_MS = 5 * 60 * 1000;
|
|
172171
|
+
function hasRecentPiCtxReduceExecution(sessionId) {
|
|
172172
|
+
const recordedAt = recentReduceBySession.get(sessionId);
|
|
172173
|
+
if (recordedAt === undefined)
|
|
172174
|
+
return false;
|
|
172175
|
+
if (Date.now() - recordedAt <= RECENT_REDUCE_TTL_MS)
|
|
172176
|
+
return true;
|
|
172177
|
+
recentReduceBySession.delete(sessionId);
|
|
172178
|
+
return false;
|
|
172179
|
+
}
|
|
171441
172180
|
function logTransformTiming(sessionId, stage, start, extra) {
|
|
171442
172181
|
const elapsed = (performance.now() - start).toFixed(1);
|
|
171443
172182
|
const suffix = extra ? ` ${extra}` : "";
|
|
@@ -171527,7 +172266,7 @@ function recordPiToolExecution(sessionId) {
|
|
|
171527
172266
|
function onPiNewUserMessage(args) {
|
|
171528
172267
|
const sessionMeta = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
171529
172268
|
const turnUsage = toolUsageSinceUserTurn.get(args.sessionId);
|
|
171530
|
-
const agentAlreadyReduced =
|
|
172269
|
+
const agentAlreadyReduced = hasRecentPiCtxReduceExecution(args.sessionId);
|
|
171531
172270
|
if (!sessionMeta.isSubagent && !agentAlreadyReduced && getPersistedStickyTurnReminder(args.db, args.sessionId) === null && turnUsage !== undefined && turnUsage >= TOOL_HEAVY_TURN_REMINDER_THRESHOLD) {
|
|
171532
172271
|
setPersistedStickyTurnReminder(args.db, args.sessionId, TOOL_HEAVY_TURN_REMINDER_TEXT);
|
|
171533
172272
|
}
|
|
@@ -171648,7 +172387,8 @@ function collectMessageEntryIdsByRef(ctx, messages, sessionId, preloadedBranchEn
|
|
|
171648
172387
|
continue;
|
|
171649
172388
|
}
|
|
171650
172389
|
const fingerprint = piMessageEntryFingerprint(msg);
|
|
171651
|
-
const
|
|
172390
|
+
const fingerprintBucket = fingerprint ? entryIdsByFingerprint.get(fingerprint) : undefined;
|
|
172391
|
+
const fingerprintId = fingerprintBucket?.length === 1 && !consumedFingerprintIds.has(fingerprintBucket[0]) ? fingerprintBucket[0] : undefined;
|
|
171652
172392
|
if (typeof fingerprintId === "string") {
|
|
171653
172393
|
consumedFingerprintIds.add(fingerprintId);
|
|
171654
172394
|
result[i] = fingerprintId;
|
|
@@ -171784,8 +172524,10 @@ function registerPiContextHandler(pi, options) {
|
|
|
171784
172524
|
});
|
|
171785
172525
|
clearHistorianFailureState(options.db, sessionId);
|
|
171786
172526
|
clearPersistedReasoningWatermark(options.db, sessionId);
|
|
171787
|
-
|
|
171788
|
-
|
|
172527
|
+
if (modelChanged) {
|
|
172528
|
+
clearDetectedContextLimit(options.db, sessionId);
|
|
172529
|
+
clearEmergencyRecovery(options.db, sessionId);
|
|
172530
|
+
}
|
|
171789
172531
|
sessionMetaForUsage.lastContextPercentage = 0;
|
|
171790
172532
|
sessionMetaForUsage.lastInputTokens = 0;
|
|
171791
172533
|
sessionMetaForUsage.observedSafeInputTokens = 0;
|
|
@@ -171855,6 +172597,10 @@ function registerPiContextHandler(pi, options) {
|
|
|
171855
172597
|
setDeferredExecutePendingIfAbsent(options.db, sessionId, flagPayload);
|
|
171856
172598
|
}
|
|
171857
172599
|
schedulerDecision = midTurnAdjustedSchedulerDecision;
|
|
172600
|
+
const deferredExecutePending = peekDeferredExecutePending(options.db, sessionId);
|
|
172601
|
+
if (deferredExecutePending !== null && schedulerDecision === "defer" && !midTurn) {
|
|
172602
|
+
schedulerDecision = "execute";
|
|
172603
|
+
}
|
|
171858
172604
|
sessionLog(sessionId, `[boundary-exec] base=${schedulerDecisionEarly} bypass=${bypassReason} midTurn=${midTurn} effective=${midTurnAdjustedSchedulerDecision} sideEffect=${sideEffect}`);
|
|
171859
172605
|
const forceMaterialization = usagePercentage >= FORCE_MATERIALIZATION_PERCENTAGE;
|
|
171860
172606
|
const isEmergency = usagePercentage >= EMERGENCY_BLOCK_PERCENTAGE;
|
|
@@ -171933,7 +172679,7 @@ function registerPiContextHandler(pi, options) {
|
|
|
171933
172679
|
db: options.db,
|
|
171934
172680
|
messages: outputMessages,
|
|
171935
172681
|
entryIds: entryIds ?? null,
|
|
171936
|
-
hasRecentReduceCall:
|
|
172682
|
+
hasRecentReduceCall: hasRecentPiCtxReduceExecution(sessionId),
|
|
171937
172683
|
isCacheBustingPass: cacheBustingPass
|
|
171938
172684
|
});
|
|
171939
172685
|
} catch (err) {
|
|
@@ -171960,8 +172706,7 @@ function registerPiContextHandler(pi, options) {
|
|
|
171960
172706
|
db: options.db,
|
|
171961
172707
|
messages: outputMessages,
|
|
171962
172708
|
projectIdentity,
|
|
171963
|
-
entryIds: strictEntryIds
|
|
171964
|
-
isCacheBusting
|
|
172709
|
+
entryIds: strictEntryIds
|
|
171965
172710
|
});
|
|
171966
172711
|
} catch (err) {
|
|
171967
172712
|
sessionLog(sessionId, `note nudges failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -172002,6 +172747,12 @@ function registerPiContextHandler(pi, options) {
|
|
|
172002
172747
|
} catch (err) {
|
|
172003
172748
|
sessionLog(sessionId, `synthetic todowrite injection failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
172004
172749
|
}
|
|
172750
|
+
try {
|
|
172751
|
+
const metrics = computePiWorkMetrics(outputMessages);
|
|
172752
|
+
setSessionWorkMetrics(options.db, sessionId, metrics.newWorkTokens, metrics.totalInputTokens);
|
|
172753
|
+
} catch (err) {
|
|
172754
|
+
sessionLog(sessionId, `work-metrics update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
172755
|
+
}
|
|
172005
172756
|
logTransformTiming(sessionId, "postTransformPhase", tPostTransform);
|
|
172006
172757
|
sessionLog(sessionId, `transform completed in ${(performance.now() - transformStartTime).toFixed(1)}ms (${outputMessages.length} messages, ${result.targetCount} targets, watermark: ${result.reasoningWatermark})`);
|
|
172007
172758
|
clearLastTransformErrorIfSet(options.db, sessionId);
|
|
@@ -172084,6 +172835,13 @@ function resolveHistoryBudgetTokensForPi(args) {
|
|
|
172084
172835
|
contextLimit: derivedLimit
|
|
172085
172836
|
}) / 100) * historyBudgetPercentage);
|
|
172086
172837
|
}
|
|
172838
|
+
function startPiCompartmentLeaseRenewal(db, sessionId, holderId) {
|
|
172839
|
+
return setInterval(() => {
|
|
172840
|
+
if (!renewCompartmentLease(db, sessionId, holderId)) {
|
|
172841
|
+
sessionLog(sessionId, "compartment lease renewal failed; publish will be skipped if holder is stale");
|
|
172842
|
+
}
|
|
172843
|
+
}, COMPARTMENT_LEASE_RENEWAL_MS);
|
|
172844
|
+
}
|
|
172087
172845
|
function maybeFireCompressor(args) {
|
|
172088
172846
|
const { ctx, sessionId, db, historian } = args;
|
|
172089
172847
|
const compressor = historian.compressor;
|
|
@@ -172109,30 +172867,46 @@ function maybeFireCompressor(args) {
|
|
|
172109
172867
|
});
|
|
172110
172868
|
if (!historyBudgetTokens || historyBudgetTokens <= 0)
|
|
172111
172869
|
return;
|
|
172112
|
-
const
|
|
172113
|
-
|
|
172114
|
-
sessionId,
|
|
172115
|
-
|
|
172116
|
-
|
|
172117
|
-
|
|
172118
|
-
|
|
172119
|
-
|
|
172120
|
-
|
|
172121
|
-
|
|
172122
|
-
|
|
172123
|
-
|
|
172124
|
-
|
|
172125
|
-
|
|
172126
|
-
|
|
172127
|
-
|
|
172128
|
-
|
|
172129
|
-
|
|
172130
|
-
|
|
172131
|
-
|
|
172132
|
-
|
|
172133
|
-
|
|
172870
|
+
const holderId = crypto2.randomUUID();
|
|
172871
|
+
const runPromise = (async () => {
|
|
172872
|
+
const lease2 = acquireCompartmentLease(db, sessionId, holderId);
|
|
172873
|
+
if (!lease2) {
|
|
172874
|
+
sessionLog(sessionId, "compressor skipped: compartment lease held by another process");
|
|
172875
|
+
return false;
|
|
172876
|
+
}
|
|
172877
|
+
const renewal = startPiCompartmentLeaseRenewal(db, sessionId, holderId);
|
|
172878
|
+
try {
|
|
172879
|
+
return await runPiCompressionPassIfNeeded({
|
|
172880
|
+
db,
|
|
172881
|
+
sessionId,
|
|
172882
|
+
directory: ctx.cwd,
|
|
172883
|
+
runner: historian.runner,
|
|
172884
|
+
historianModel: historian.model,
|
|
172885
|
+
fallbackModels: historian.fallbackModels,
|
|
172886
|
+
historyBudgetTokens,
|
|
172887
|
+
historianTimeoutMs: historian.timeoutMs,
|
|
172888
|
+
thinkingLevel: historian.thinkingLevel,
|
|
172889
|
+
minCompartmentRatio: compressor.minCompartmentRatio,
|
|
172890
|
+
maxMergeDepth: compressor.maxMergeDepth,
|
|
172891
|
+
maxCompartmentsPerPass: compressor.maxCompartmentsPerPass,
|
|
172892
|
+
graceCompartments: compressor.graceCompartments,
|
|
172893
|
+
compartmentLeaseHolderId: holderId,
|
|
172894
|
+
onPublished: () => {
|
|
172895
|
+
const sessionStillActive = isContextHandlerSessionActive(sessionId);
|
|
172896
|
+
signalPiDeferredHistoryRefresh(sessionId);
|
|
172897
|
+
signalPiDeferredMaterialization(sessionId);
|
|
172898
|
+
if (sessionStillActive) {
|
|
172899
|
+
historian.onStatusChange?.(ctx, sessionId);
|
|
172900
|
+
} else {
|
|
172901
|
+
sessionLog(sessionId, "compressor publication recorded after session clear; status callback skipped");
|
|
172902
|
+
}
|
|
172903
|
+
}
|
|
172904
|
+
});
|
|
172905
|
+
} finally {
|
|
172906
|
+
clearInterval(renewal);
|
|
172907
|
+
releaseCompartmentLease(db, sessionId, holderId);
|
|
172134
172908
|
}
|
|
172135
|
-
}).then((didPublish) => {
|
|
172909
|
+
})().then((didPublish) => {
|
|
172136
172910
|
if (didPublish === true) {
|
|
172137
172911
|
markPiCompressorRun(sessionId);
|
|
172138
172912
|
}
|
|
@@ -172170,37 +172944,53 @@ function sendPiIgnoredNotification(ctx, message) {
|
|
|
172170
172944
|
}
|
|
172171
172945
|
function spawnPiHistorianRun(args) {
|
|
172172
172946
|
const { ctx, sessionId, db, historian, provider: provider2, unregister } = args;
|
|
172173
|
-
const
|
|
172174
|
-
|
|
172175
|
-
sessionId,
|
|
172176
|
-
|
|
172177
|
-
|
|
172178
|
-
|
|
172179
|
-
readBranchEntries: resolvePiReadBranchEntries(ctx),
|
|
172180
|
-
runner: historian.runner,
|
|
172181
|
-
historianModel: historian.model,
|
|
172182
|
-
fallbackModels: historian.fallbackModels,
|
|
172183
|
-
historianChunkTokens: historian.historianChunkTokens,
|
|
172184
|
-
historianTimeoutMs: historian.timeoutMs,
|
|
172185
|
-
twoPass: historian.twoPass,
|
|
172186
|
-
thinkingLevel: historian.thinkingLevel,
|
|
172187
|
-
memoryEnabled: historian.memoryEnabled,
|
|
172188
|
-
autoPromote: historian.autoPromote,
|
|
172189
|
-
onPublished: () => {
|
|
172190
|
-
if (!isContextHandlerSessionActive(sessionId)) {
|
|
172191
|
-
sessionLog(sessionId, "historian publication ignored: session was cleared");
|
|
172192
|
-
return;
|
|
172193
|
-
}
|
|
172194
|
-
try {
|
|
172195
|
-
clearEmergencyRecovery(db, sessionId);
|
|
172196
|
-
} catch (err) {
|
|
172197
|
-
sessionLog(sessionId, `historian: clearEmergencyRecovery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
172198
|
-
}
|
|
172199
|
-
signalPiDeferredHistoryRefresh(sessionId);
|
|
172200
|
-
signalPiDeferredMaterialization(sessionId);
|
|
172201
|
-
historian.onStatusChange?.(ctx, sessionId);
|
|
172947
|
+
const holderId = crypto2.randomUUID();
|
|
172948
|
+
const runPromise = (async () => {
|
|
172949
|
+
const lease2 = acquireCompartmentLease(db, sessionId, holderId);
|
|
172950
|
+
if (!lease2) {
|
|
172951
|
+
sessionLog(sessionId, "historian skipped: compartment lease held by another process");
|
|
172952
|
+
return;
|
|
172202
172953
|
}
|
|
172203
|
-
|
|
172954
|
+
const renewal = startPiCompartmentLeaseRenewal(db, sessionId, holderId);
|
|
172955
|
+
try {
|
|
172956
|
+
await runPiHistorian({
|
|
172957
|
+
db,
|
|
172958
|
+
sessionId,
|
|
172959
|
+
directory: ctx.cwd,
|
|
172960
|
+
provider: provider2,
|
|
172961
|
+
appendCompaction: resolvePiAppendCompaction(ctx),
|
|
172962
|
+
readBranchEntries: resolvePiReadBranchEntries(ctx),
|
|
172963
|
+
runner: historian.runner,
|
|
172964
|
+
historianModel: historian.model,
|
|
172965
|
+
fallbackModels: historian.fallbackModels,
|
|
172966
|
+
historianChunkTokens: historian.historianChunkTokens,
|
|
172967
|
+
historianTimeoutMs: historian.timeoutMs,
|
|
172968
|
+
twoPass: historian.twoPass,
|
|
172969
|
+
thinkingLevel: historian.thinkingLevel,
|
|
172970
|
+
memoryEnabled: historian.memoryEnabled,
|
|
172971
|
+
autoPromote: historian.autoPromote,
|
|
172972
|
+
compartmentLeaseHolderId: holderId,
|
|
172973
|
+
onPublished: () => {
|
|
172974
|
+
const sessionStillActive = isContextHandlerSessionActive(sessionId);
|
|
172975
|
+
try {
|
|
172976
|
+
clearEmergencyRecovery(db, sessionId);
|
|
172977
|
+
} catch (err) {
|
|
172978
|
+
sessionLog(sessionId, `historian: clearEmergencyRecovery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
172979
|
+
}
|
|
172980
|
+
signalPiDeferredHistoryRefresh(sessionId);
|
|
172981
|
+
signalPiDeferredMaterialization(sessionId);
|
|
172982
|
+
if (sessionStillActive) {
|
|
172983
|
+
historian.onStatusChange?.(ctx, sessionId);
|
|
172984
|
+
} else {
|
|
172985
|
+
sessionLog(sessionId, "historian publication recorded after session clear; status callback skipped");
|
|
172986
|
+
}
|
|
172987
|
+
}
|
|
172988
|
+
});
|
|
172989
|
+
} finally {
|
|
172990
|
+
clearInterval(renewal);
|
|
172991
|
+
releaseCompartmentLease(db, sessionId, holderId);
|
|
172992
|
+
}
|
|
172993
|
+
})().finally(() => {
|
|
172204
172994
|
inFlightHistorian.delete(sessionId);
|
|
172205
172995
|
unregister();
|
|
172206
172996
|
if (isContextHandlerSessionActive(sessionId)) {
|
|
@@ -172221,12 +173011,11 @@ function resolvePiReadBranchEntries(ctx) {
|
|
|
172221
173011
|
if (typeof sm?.getBranch !== "function")
|
|
172222
173012
|
return;
|
|
172223
173013
|
return () => {
|
|
172224
|
-
|
|
172225
|
-
|
|
172226
|
-
|
|
172227
|
-
} catch {
|
|
172228
|
-
return [];
|
|
173014
|
+
const entries = sm.getBranch?.call(sm);
|
|
173015
|
+
if (!Array.isArray(entries)) {
|
|
173016
|
+
throw new Error("Pi sessionManager.getBranch() did not return an array");
|
|
172229
173017
|
}
|
|
173018
|
+
return entries;
|
|
172230
173019
|
};
|
|
172231
173020
|
}
|
|
172232
173021
|
function maybeFireHistorian(args) {
|
|
@@ -172328,6 +173117,7 @@ Historian previously failed ${failureState.failureCount} time(s), so magic-conte
|
|
|
172328
173117
|
async function runPipeline(args) {
|
|
172329
173118
|
let executedWorkThisPass = false;
|
|
172330
173119
|
let historyWasConsumedThisPass = false;
|
|
173120
|
+
let materializationSatisfiedThisPass = false;
|
|
172331
173121
|
let suppressDeferredHistoryDrain = false;
|
|
172332
173122
|
let casLost = false;
|
|
172333
173123
|
const deferredHistoryWasPendingAtPassStart = deferredHistoryRefreshSessions.has(args.sessionId);
|
|
@@ -172349,7 +173139,7 @@ async function runPipeline(args) {
|
|
|
172349
173139
|
return findLatestUserMessageIdPi(args.messages, ids)?.messageId ?? null;
|
|
172350
173140
|
})();
|
|
172351
173141
|
const alreadyRanHeuristicsThisTurn = currentTurnId !== null && lastHeuristicsTurnIdBySession.get(args.sessionId) === currentTurnId;
|
|
172352
|
-
const shouldRunHeuristics = args.heuristics !== undefined && (args.forceMaterialization === true || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
|
|
173142
|
+
const shouldRunHeuristics = args.heuristics !== undefined && (args.forceMaterialization === true || hasPendingMaterialization(args.sessionId) || deferredMaterializationSessions.has(args.sessionId) || args.schedulerDecision === "execute" && !alreadyRanHeuristicsThisTurn);
|
|
172353
173143
|
const tTag = performance.now();
|
|
172354
173144
|
const { targets } = tagTranscript(args.sessionId, transcript, args.tagger, args.db, {
|
|
172355
173145
|
skipPrefixInjection: !args.ctxReduceEnabled
|
|
@@ -172372,22 +173162,26 @@ async function runPipeline(args) {
|
|
|
172372
173162
|
const hasPendingMaterializeSignal = hasPendingMaterialization(args.sessionId);
|
|
172373
173163
|
const deferredMaterializationWasPending = deferredMaterializationSessions.has(args.sessionId);
|
|
172374
173164
|
const deferredHistoryRefreshWasPending = deferredHistoryWasPendingAtPassStart;
|
|
173165
|
+
const deferredExecuteWasPending = peekDeferredExecutePending(args.db, args.sessionId) !== null;
|
|
172375
173166
|
const pendingOps = getPendingOps(args.db, args.sessionId);
|
|
172376
|
-
const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal;
|
|
173167
|
+
const baseShouldApplyPendingOps = args.schedulerDecision === "execute" || args.forceMaterialization || hasPendingMaterializeSignal || deferredExecuteWasPending;
|
|
172377
173168
|
const canConsumeDeferredLate = baseShouldApplyPendingOps || shouldRunHeuristics;
|
|
172378
173169
|
const deferredMaterialize = canConsumeDeferredLate && deferredMaterializationWasPending;
|
|
172379
173170
|
const deferredHistoryRefresh = canConsumeDeferredLate && deferredHistoryRefreshWasPending;
|
|
172380
173171
|
const shouldApplyPendingOps = baseShouldApplyPendingOps || deferredMaterialize;
|
|
172381
173172
|
if (shouldApplyPendingOps) {
|
|
172382
|
-
const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
173173
|
+
const applyReason = hasPendingMaterializeSignal ? "explicit_flush" : deferredExecuteWasPending ? "deferred_boundary_execute" : deferredMaterialize ? "deferred_publication" : args.forceMaterialization ? "force_materialization" : `scheduler_execute (scheduler=${args.schedulerDecision})`;
|
|
172383
173174
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
172384
173175
|
try {
|
|
172385
173176
|
const tApplyPending = performance.now();
|
|
172386
173177
|
applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, pendingOps);
|
|
172387
173178
|
logTransformTiming(args.sessionId, "applyPendingOperations", tApplyPending);
|
|
172388
173179
|
executedWorkThisPass = true;
|
|
173180
|
+
materializationSatisfiedThisPass = true;
|
|
172389
173181
|
if (hasPendingMaterializeSignal) {
|
|
172390
|
-
|
|
173182
|
+
if (args.heuristics === undefined) {
|
|
173183
|
+
consumePendingMaterialization(args.sessionId);
|
|
173184
|
+
}
|
|
172391
173185
|
}
|
|
172392
173186
|
if (deferredMaterialize) {
|
|
172393
173187
|
consumeDeferredMaterialization(args.sessionId);
|
|
@@ -172467,6 +173261,9 @@ async function runPipeline(args) {
|
|
|
172467
173261
|
}, activeTags);
|
|
172468
173262
|
heuristicsExecuted = true;
|
|
172469
173263
|
executedWorkThisPass = true;
|
|
173264
|
+
if (hasPendingMaterializeSignal) {
|
|
173265
|
+
consumePendingMaterialization(args.sessionId);
|
|
173266
|
+
}
|
|
172470
173267
|
if (currentTurnId !== null) {
|
|
172471
173268
|
lastHeuristicsTurnIdBySession.set(args.sessionId, currentTurnId);
|
|
172472
173269
|
}
|
|
@@ -172501,7 +173298,9 @@ async function runPipeline(args) {
|
|
|
172501
173298
|
}
|
|
172502
173299
|
logTransformTiming(args.sessionId, "clearOldReasoning", tClearReasoning);
|
|
172503
173300
|
logTransformTiming(args.sessionId, "watermarkCleanup", tClearReasoning);
|
|
172504
|
-
|
|
173301
|
+
if (combinedWatermark > prevWatermark || clearOutcome.cleared > 0 || stripOutcome.stripped > 0) {
|
|
173302
|
+
executedWorkThisPass = true;
|
|
173303
|
+
}
|
|
172505
173304
|
} catch (err) {
|
|
172506
173305
|
sessionLog(args.sessionId, `reasoning clearing failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
172507
173306
|
}
|
|
@@ -172531,7 +173330,7 @@ async function runPipeline(args) {
|
|
|
172531
173330
|
messages: args.messages,
|
|
172532
173331
|
isCacheBusting: args.isCacheBusting
|
|
172533
173332
|
});
|
|
172534
|
-
const deferredHistoryDrainEligible = historyWasConsumedThisPass && deferredHistoryWasPendingAtPassStart && !suppressDeferredHistoryDrain && !casLost;
|
|
173333
|
+
const deferredHistoryDrainEligible = historyWasConsumedThisPass && materializationSatisfiedThisPass && (deferredHistoryWasPendingAtPassStart || hasPendingMaterializeSignal) && !suppressDeferredHistoryDrain && !casLost;
|
|
172535
173334
|
if (deferredHistoryDrainEligible) {
|
|
172536
173335
|
try {
|
|
172537
173336
|
const pending = getPendingPiCompactionMarkerState(args.db, args.sessionId);
|
|
@@ -172621,7 +173420,7 @@ function applyStickyTurnReminder(args) {
|
|
|
172621
173420
|
const messageIdByIndex = buildPiMessageIdByIndex(args.messages, args.entryIds);
|
|
172622
173421
|
if (reminder.messageId) {
|
|
172623
173422
|
const reinjected = appendReminderToUserMessageByIdPi(args.messages, messageIdByIndex, reminder.messageId, reminder.text);
|
|
172624
|
-
if (!reinjected && args.isCacheBustingPass && args.entryIds !== null) {
|
|
173423
|
+
if (!reinjected && args.isCacheBustingPass && args.entryIds !== null && !args.entryIds.includes(undefined) && !args.entryIds.includes(reminder.messageId)) {
|
|
172625
173424
|
clearPersistedStickyTurnReminder(args.db, args.sessionId);
|
|
172626
173425
|
}
|
|
172627
173426
|
return args.messages;
|
|
@@ -172638,14 +173437,15 @@ function applyStickyTurnReminder(args) {
|
|
|
172638
173437
|
return args.messages;
|
|
172639
173438
|
}
|
|
172640
173439
|
function applyNoteNudges(args) {
|
|
172641
|
-
const { sessionId, db, messages, projectIdentity, entryIds
|
|
173440
|
+
const { sessionId, db, messages, projectIdentity, entryIds } = args;
|
|
172642
173441
|
const messageIdByIndex = buildPiMessageIdByIndex(messages, entryIds);
|
|
173442
|
+
const replayMessageIdByIndex = buildPiMessageIdByIndex(messages, entryIds, true);
|
|
172643
173443
|
for (const anchor of getNoteNudgeAnchors(db, sessionId)) {
|
|
172644
|
-
appendReminderToUserMessageByIdPi(messages,
|
|
173444
|
+
appendReminderToUserMessageByIdPi(messages, replayMessageIdByIndex, anchor.messageId, anchor.text);
|
|
172645
173445
|
}
|
|
172646
173446
|
for (const decision of getAutoSearchHintDecisions(db, sessionId)) {
|
|
172647
173447
|
if (decision.decision === "hint") {
|
|
172648
|
-
appendReminderToUserMessageByIdPi(messages,
|
|
173448
|
+
appendReminderToUserMessageByIdPi(messages, replayMessageIdByIndex, decision.messageId, decision.text);
|
|
172649
173449
|
}
|
|
172650
173450
|
}
|
|
172651
173451
|
const latestUser = findLatestUserMessageIdPi(messages, messageIdByIndex);
|
|
@@ -172661,14 +173461,18 @@ function applyNoteNudges(args) {
|
|
|
172661
173461
|
|
|
172662
173462
|
<instruction name="deferred_notes">${deferredNoteText}</instruction>`;
|
|
172663
173463
|
const anchoredId = latestUser?.messageId ?? null;
|
|
173464
|
+
if (!anchoredId) {
|
|
173465
|
+
sessionLog(sessionId, "Pi note-nudge: latest user message has no resolved SessionEntry id; deferring delivery to next pass");
|
|
173466
|
+
return messages;
|
|
173467
|
+
}
|
|
172664
173468
|
const outcome = markNoteNudgeDelivered(db, sessionId, noteInstruction, anchoredId);
|
|
172665
|
-
if (latestUser &&
|
|
173469
|
+
if (latestUser && outcome.ok) {
|
|
172666
173470
|
appendReminderToPiUserMessage(messages[latestUser.index], noteInstruction);
|
|
172667
|
-
} else if (
|
|
173471
|
+
} else if (!outcome.ok) {
|
|
172668
173472
|
sessionLog(sessionId, `Pi note-nudge delivery skipped wire append: ${outcome.kind}`);
|
|
172669
173473
|
}
|
|
172670
173474
|
}
|
|
172671
|
-
if (
|
|
173475
|
+
if (entryIds !== null && !entryIds.includes(undefined)) {
|
|
172672
173476
|
const visibleIds = new Set(entryIds.filter((id) => typeof id === "string"));
|
|
172673
173477
|
pruneNoteNudgeAnchors(db, sessionId, visibleIds);
|
|
172674
173478
|
pruneAutoSearchHintDecisions(db, sessionId, visibleIds);
|
|
@@ -172700,7 +173504,7 @@ function hasMeaningfulUserTextPi(message) {
|
|
|
172700
173504
|
}
|
|
172701
173505
|
return false;
|
|
172702
173506
|
}
|
|
172703
|
-
function buildPiMessageIdByIndex(messages, entryIds) {
|
|
173507
|
+
function buildPiMessageIdByIndex(messages, entryIds, includeMessageIdFallback = false) {
|
|
172704
173508
|
const ids = new Map;
|
|
172705
173509
|
for (let index = 0;index < messages.length; index += 1) {
|
|
172706
173510
|
const entryId = entryIds?.[index];
|
|
@@ -172708,9 +173512,11 @@ function buildPiMessageIdByIndex(messages, entryIds) {
|
|
|
172708
173512
|
ids.set(index, entryId);
|
|
172709
173513
|
continue;
|
|
172710
173514
|
}
|
|
172711
|
-
|
|
172712
|
-
|
|
172713
|
-
|
|
173515
|
+
if (includeMessageIdFallback) {
|
|
173516
|
+
const messageId = messages[index]?.id;
|
|
173517
|
+
if (typeof messageId === "string") {
|
|
173518
|
+
ids.set(index, messageId);
|
|
173519
|
+
}
|
|
172714
173520
|
}
|
|
172715
173521
|
}
|
|
172716
173522
|
return ids;
|
|
@@ -172841,7 +173647,7 @@ init_logger();
|
|
|
172841
173647
|
init_data_path();
|
|
172842
173648
|
init_logger();
|
|
172843
173649
|
await init_sqlite();
|
|
172844
|
-
import { join as
|
|
173650
|
+
import { join as join18 } from "node:path";
|
|
172845
173651
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
172846
173652
|
function randomBase62(length) {
|
|
172847
173653
|
const chars = [];
|
|
@@ -172862,7 +173668,7 @@ function generatePartId(timestampMs, counter = 0n) {
|
|
|
172862
173668
|
return generateId("prt", timestampMs, counter);
|
|
172863
173669
|
}
|
|
172864
173670
|
function getOpenCodeDbPath3() {
|
|
172865
|
-
return
|
|
173671
|
+
return join18(getDataDir(), "opencode", "opencode.db");
|
|
172866
173672
|
}
|
|
172867
173673
|
var cachedWriteDb = null;
|
|
172868
173674
|
var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
|
|
@@ -173031,7 +173837,7 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
173031
173837
|
// ../plugin/src/hooks/magic-context/compartment-runner-compressor.ts
|
|
173032
173838
|
init_logger();
|
|
173033
173839
|
var HISTORIAN_AGENT2 = "historian";
|
|
173034
|
-
var
|
|
173840
|
+
var lastDepthHistogramBySession2 = new Map;
|
|
173035
173841
|
function cavemanLevelForDepth2(outputDepth) {
|
|
173036
173842
|
if (outputDepth <= 1)
|
|
173037
173843
|
return null;
|
|
@@ -173045,6 +173851,10 @@ function cavemanLevelForDepth2(outputDepth) {
|
|
|
173045
173851
|
}
|
|
173046
173852
|
async function runCompressionPassIfNeeded(deps) {
|
|
173047
173853
|
const { db, sessionId, historyBudgetTokens } = deps;
|
|
173854
|
+
if (deps.historianRunnable === false) {
|
|
173855
|
+
sessionLog(sessionId, "compressor: skipped because historian.disable=true");
|
|
173856
|
+
return false;
|
|
173857
|
+
}
|
|
173048
173858
|
const minCompartmentRatio = deps.minCompartmentRatio ?? DEFAULT_COMPRESSOR_MIN_COMPARTMENT_RATIO;
|
|
173049
173859
|
const maxMergeDepth = deps.maxMergeDepth ?? DEFAULT_COMPRESSOR_MAX_MERGE_DEPTH;
|
|
173050
173860
|
const compartments = getCompartments(db, sessionId);
|
|
@@ -173084,8 +173894,8 @@ ${c.content}
|
|
|
173084
173894
|
}
|
|
173085
173895
|
const histText = [...depthHistogram.entries()].sort((a, b) => a[0] - b[0]).map(([d, n]) => `d${d}=${n}`).join(" ");
|
|
173086
173896
|
const histKey = `${scored.length}|${histText}`;
|
|
173087
|
-
if (
|
|
173088
|
-
|
|
173897
|
+
if (lastDepthHistogramBySession2.get(sessionId) !== histKey) {
|
|
173898
|
+
lastDepthHistogramBySession2.set(sessionId, histKey);
|
|
173089
173899
|
sessionLog(sessionId, `compressor: depth histogram (${scored.length} total) ${histText}`);
|
|
173090
173900
|
}
|
|
173091
173901
|
const floorHeadroom = compartments.length - floor;
|
|
@@ -173131,7 +173941,8 @@ ${c.content}
|
|
|
173131
173941
|
originalStart: selectedCompartments[0].startMessage,
|
|
173132
173942
|
originalEnd: selectedCompartments[selectedCompartments.length - 1].endMessage,
|
|
173133
173943
|
facts,
|
|
173134
|
-
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${selectedCompartments.length})
|
|
173944
|
+
logLabel: `depth-5 title-only collapse (${selectedCompartments.length} → ${selectedCompartments.length})`,
|
|
173945
|
+
holderId: deps.compartmentLeaseHolderId
|
|
173135
173946
|
});
|
|
173136
173947
|
}
|
|
173137
173948
|
try {
|
|
@@ -173161,7 +173972,8 @@ ${c.content}
|
|
|
173161
173972
|
originalStart: selectedCompartments[0].startMessage,
|
|
173162
173973
|
originalEnd: selectedCompartments[selectedCompartments.length - 1].endMessage,
|
|
173163
173974
|
facts,
|
|
173164
|
-
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})
|
|
173975
|
+
logLabel: `depth-${outputDepth} (${selectedCompartments.length} → ${finalCompressed.length})`,
|
|
173976
|
+
holderId: deps.compartmentLeaseHolderId
|
|
173165
173977
|
});
|
|
173166
173978
|
} catch (error51) {
|
|
173167
173979
|
sessionLog(sessionId, "compressor: unexpected error:", getErrorMessage(error51));
|
|
@@ -173286,7 +174098,8 @@ function finalizeCompression2(args) {
|
|
|
173286
174098
|
originalStart,
|
|
173287
174099
|
originalEnd,
|
|
173288
174100
|
facts,
|
|
173289
|
-
logLabel
|
|
174101
|
+
logLabel,
|
|
174102
|
+
holderId
|
|
173290
174103
|
} = args;
|
|
173291
174104
|
const compressedStart = compressed[0].startMessage;
|
|
173292
174105
|
const compressedEnd = compressed[compressed.length - 1].endMessage;
|
|
@@ -173337,8 +174150,16 @@ function finalizeCompression2(args) {
|
|
|
173337
174150
|
content: c.content
|
|
173338
174151
|
}))
|
|
173339
174152
|
];
|
|
173340
|
-
|
|
173341
|
-
|
|
174153
|
+
const factInputs = facts.map((f) => ({ category: f.category, content: f.content }));
|
|
174154
|
+
const published = holderId ? replaceAllCompartmentStateAndBumpDepth(db, holderId, sessionId, allCompartments, factInputs, originalStart, originalEnd) : (() => {
|
|
174155
|
+
replaceAllCompartmentState(db, sessionId, allCompartments, factInputs);
|
|
174156
|
+
incrementCompressionDepth(db, sessionId, originalStart, originalEnd);
|
|
174157
|
+
return true;
|
|
174158
|
+
})();
|
|
174159
|
+
if (!published) {
|
|
174160
|
+
sessionLog(sessionId, "compressor: publish skipped because compartment lease is no longer held");
|
|
174161
|
+
return false;
|
|
174162
|
+
}
|
|
173342
174163
|
sessionLog(sessionId, `compressor: completed ${logLabel}`);
|
|
173343
174164
|
return true;
|
|
173344
174165
|
}
|
|
@@ -173357,6 +174178,27 @@ async function runCompressorPass2(args) {
|
|
|
173357
174178
|
} = args;
|
|
173358
174179
|
const prompt = buildCompressorPrompt(compartments, currentTokens, targetTokens, outputDepth, outputCount);
|
|
173359
174180
|
let agentSessionId = null;
|
|
174181
|
+
const startedAt = Date.now();
|
|
174182
|
+
let invocationRecorded = false;
|
|
174183
|
+
const recordInvocation = (params) => {
|
|
174184
|
+
if (invocationRecorded)
|
|
174185
|
+
return;
|
|
174186
|
+
invocationRecorded = true;
|
|
174187
|
+
try {
|
|
174188
|
+
recordChildInvocation({
|
|
174189
|
+
db: openDatabase(),
|
|
174190
|
+
parentSessionId: sessionId,
|
|
174191
|
+
harness: "opencode",
|
|
174192
|
+
subagent: "compressor",
|
|
174193
|
+
startedAt,
|
|
174194
|
+
status: params.status,
|
|
174195
|
+
messages: params.messages,
|
|
174196
|
+
error: params.error
|
|
174197
|
+
});
|
|
174198
|
+
} catch (error51) {
|
|
174199
|
+
sessionLog(sessionId, "subagent token accounting unavailable", getErrorMessage(error51));
|
|
174200
|
+
}
|
|
174201
|
+
};
|
|
173360
174202
|
try {
|
|
173361
174203
|
const createResponse = await client.session.create({
|
|
173362
174204
|
body: { parentID: sessionId, title: "magic-context-compressor" },
|
|
@@ -173366,6 +174208,7 @@ async function runCompressorPass2(args) {
|
|
|
173366
174208
|
agentSessionId = typeof createdSession?.id === "string" ? createdSession.id : null;
|
|
173367
174209
|
if (!agentSessionId) {
|
|
173368
174210
|
sessionLog(sessionId, "compressor: could not create child session");
|
|
174211
|
+
recordInvocation({ status: "failed", error: "could not create child session" });
|
|
173369
174212
|
return null;
|
|
173370
174213
|
}
|
|
173371
174214
|
await promptSyncWithModelSuggestionRetry(client, {
|
|
@@ -173387,6 +174230,7 @@ async function runCompressorPass2(args) {
|
|
|
173387
174230
|
const messages = normalizeSDKResponse(messagesResponse, [], {
|
|
173388
174231
|
preferResponseOnMissingData: true
|
|
173389
174232
|
});
|
|
174233
|
+
recordInvocation({ status: "completed", messages });
|
|
173390
174234
|
const result = extractLatestAssistantText(messages);
|
|
173391
174235
|
if (!result) {
|
|
173392
174236
|
sessionLog(sessionId, "compressor: historian returned no output");
|
|
@@ -173407,6 +174251,7 @@ async function runCompressorPass2(args) {
|
|
|
173407
174251
|
}
|
|
173408
174252
|
return snapped.result;
|
|
173409
174253
|
} catch (error51) {
|
|
174254
|
+
recordInvocation({ status: "failed", error: error51 });
|
|
173410
174255
|
sessionLog(sessionId, "compressor: historian call failed:", getErrorMessage(error51));
|
|
173411
174256
|
return null;
|
|
173412
174257
|
} finally {
|
|
@@ -173419,8 +174264,8 @@ async function runCompressorPass2(args) {
|
|
|
173419
174264
|
}
|
|
173420
174265
|
|
|
173421
174266
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
173422
|
-
import { mkdirSync as
|
|
173423
|
-
import { join as
|
|
174267
|
+
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
174268
|
+
import { join as join19 } from "node:path";
|
|
173424
174269
|
init_data_path();
|
|
173425
174270
|
function historianResponseDumpDir(directory) {
|
|
173426
174271
|
return getProjectMagicContextHistorianDir(directory);
|
|
@@ -173445,7 +174290,8 @@ async function runValidatedHistorianPass(args) {
|
|
|
173445
174290
|
...args,
|
|
173446
174291
|
draftXml: firstRun.result,
|
|
173447
174292
|
draftValidation: firstValidation,
|
|
173448
|
-
draftDumpPath: firstRun.dumpPath
|
|
174293
|
+
draftDumpPath: firstRun.dumpPath,
|
|
174294
|
+
draftInvocationId: firstRun.invocationId ?? null
|
|
173449
174295
|
}) : firstValidation;
|
|
173450
174296
|
cleanupHistorianDump(args.parentSessionId, firstRun.dumpPath);
|
|
173451
174297
|
return finalResult;
|
|
@@ -173471,7 +174317,8 @@ async function runValidatedHistorianPass(args) {
|
|
|
173471
174317
|
...args,
|
|
173472
174318
|
draftXml: repairRun.result,
|
|
173473
174319
|
draftValidation: repairValidation,
|
|
173474
|
-
draftDumpPath: repairRun.dumpPath
|
|
174320
|
+
draftDumpPath: repairRun.dumpPath,
|
|
174321
|
+
draftInvocationId: repairRun.invocationId ?? null
|
|
173475
174322
|
}) : repairValidation;
|
|
173476
174323
|
cleanupHistorianDump(args.parentSessionId, repairRun.dumpPath);
|
|
173477
174324
|
return finalResult;
|
|
@@ -173492,7 +174339,8 @@ async function runEditorPassOrFallback(args) {
|
|
|
173492
174339
|
prompt: buildHistorianEditorPrompt(args.draftXml),
|
|
173493
174340
|
timeoutMs: args.timeoutMs,
|
|
173494
174341
|
dumpLabel: `${args.dumpLabelBase}-editor`,
|
|
173495
|
-
agentId: HISTORIAN_EDITOR_AGENT
|
|
174342
|
+
agentId: HISTORIAN_EDITOR_AGENT,
|
|
174343
|
+
parentInvocationId: args.draftInvocationId ?? null
|
|
173496
174344
|
});
|
|
173497
174345
|
if (!editorRun.ok || !editorRun.result) {
|
|
173498
174346
|
sessionLog(args.parentSessionId, "historian two-pass: editor call failed", {
|
|
@@ -173519,9 +174367,29 @@ async function runHistorianPrompt(args) {
|
|
|
173519
174367
|
dumpLabel,
|
|
173520
174368
|
modelOverride,
|
|
173521
174369
|
agentId = HISTORIAN_AGENT,
|
|
173522
|
-
fallbackModels
|
|
174370
|
+
fallbackModels,
|
|
174371
|
+
subagentKind,
|
|
174372
|
+
parentInvocationId
|
|
173523
174373
|
} = args;
|
|
173524
174374
|
let agentSessionId = null;
|
|
174375
|
+
const startedAt = Date.now();
|
|
174376
|
+
let invocationRecorded = false;
|
|
174377
|
+
const recordInvocation = (params) => {
|
|
174378
|
+
if (invocationRecorded)
|
|
174379
|
+
return null;
|
|
174380
|
+
invocationRecorded = true;
|
|
174381
|
+
return recordChildInvocation({
|
|
174382
|
+
db: openDatabase(),
|
|
174383
|
+
parentSessionId,
|
|
174384
|
+
harness: "opencode",
|
|
174385
|
+
subagent: agentId === HISTORIAN_EDITOR_AGENT ? "historian_editor" : subagentKind ?? "historian",
|
|
174386
|
+
startedAt,
|
|
174387
|
+
status: params.status,
|
|
174388
|
+
messages: params.messages,
|
|
174389
|
+
error: params.error,
|
|
174390
|
+
parentInvocationId: agentId === HISTORIAN_EDITOR_AGENT ? parentInvocationId ?? null : null
|
|
174391
|
+
});
|
|
174392
|
+
};
|
|
173525
174393
|
try {
|
|
173526
174394
|
sessionLog(parentSessionId, `historian: creating child session (agent=${agentId}, model=${modelOverride ? `${modelOverride.providerID}/${modelOverride.modelID}` : `agent:${agentId}`})`);
|
|
173527
174395
|
const createResponse = await client.session.create({
|
|
@@ -173534,6 +174402,10 @@ async function runHistorianPrompt(args) {
|
|
|
173534
174402
|
const createdSession = normalizeSDKResponse(createResponse, null, { preferResponseOnMissingData: true });
|
|
173535
174403
|
agentSessionId = typeof createdSession?.id === "string" ? createdSession.id : null;
|
|
173536
174404
|
if (!agentSessionId) {
|
|
174405
|
+
recordInvocation({
|
|
174406
|
+
status: "failed",
|
|
174407
|
+
error: "Historian could not create its child session."
|
|
174408
|
+
});
|
|
173537
174409
|
return { ok: false, error: "Historian could not create its child session." };
|
|
173538
174410
|
}
|
|
173539
174411
|
for (let retryIndex = 0;retryIndex <= MAX_HISTORIAN_RETRIES; retryIndex += 1) {
|
|
@@ -173572,15 +174444,21 @@ async function runHistorianPrompt(args) {
|
|
|
173572
174444
|
const messages = normalizeSDKResponse(messagesResponse, [], {
|
|
173573
174445
|
preferResponseOnMissingData: true
|
|
173574
174446
|
});
|
|
174447
|
+
const invocationId = recordInvocation({ status: "completed", messages });
|
|
173575
174448
|
const result = extractLatestAssistantText(messages);
|
|
173576
174449
|
if (!result) {
|
|
173577
|
-
return {
|
|
174450
|
+
return {
|
|
174451
|
+
ok: false,
|
|
174452
|
+
error: "Historian returned no assistant output.",
|
|
174453
|
+
invocationId: invocationId ?? undefined
|
|
174454
|
+
};
|
|
173578
174455
|
}
|
|
173579
174456
|
const dumpPath = dumpHistorianResponse(parentSessionId, sessionDirectory, dumpLabel ?? "historian-response", result);
|
|
173580
|
-
return { ok: true, result, dumpPath };
|
|
174457
|
+
return { ok: true, result, dumpPath, invocationId: invocationId ?? undefined };
|
|
173581
174458
|
} catch (modelError) {
|
|
173582
174459
|
const desc = describeError(modelError);
|
|
173583
174460
|
sessionLog(parentSessionId, `historian prompt failed: ${desc.brief} promptLength=${prompt.length}${desc.stackHead ? ` stackHead="${desc.stackHead}"` : ""}`);
|
|
174461
|
+
recordInvocation({ status: "failed", error: modelError });
|
|
173584
174462
|
return {
|
|
173585
174463
|
ok: false,
|
|
173586
174464
|
error: `Historian failed while processing this session: ${desc.brief}`
|
|
@@ -173671,11 +174549,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
173671
174549
|
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
173672
174550
|
try {
|
|
173673
174551
|
const dumpDir = historianResponseDumpDir(directory);
|
|
173674
|
-
|
|
174552
|
+
mkdirSync7(dumpDir, { recursive: true });
|
|
173675
174553
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
173676
174554
|
const safeLabel = sanitizeDumpName(label);
|
|
173677
|
-
const dumpPath =
|
|
173678
|
-
|
|
174555
|
+
const dumpPath = join19(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
174556
|
+
writeFileSync4(dumpPath, text, "utf8");
|
|
173679
174557
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
173680
174558
|
label,
|
|
173681
174559
|
dumpPath
|
|
@@ -173856,6 +174734,12 @@ async function executePartialRecompInternal(deps, range) {
|
|
|
173856
174734
|
getNotificationParams
|
|
173857
174735
|
} = deps;
|
|
173858
174736
|
const notifParams = () => getNotificationParams?.() ?? {};
|
|
174737
|
+
const holderId = deps.compartmentLeaseHolderId;
|
|
174738
|
+
if (!holderId) {
|
|
174739
|
+
return `## Magic Recomp — Failed
|
|
174740
|
+
|
|
174741
|
+
Could not acquire the compartment-state lease for this session.`;
|
|
174742
|
+
}
|
|
173859
174743
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
173860
174744
|
try {
|
|
173861
174745
|
let promoteFinal = function() {
|
|
@@ -173892,7 +174776,7 @@ async function executePartialRecompInternal(deps, range) {
|
|
|
173892
174776
|
return null;
|
|
173893
174777
|
}
|
|
173894
174778
|
saveRecompStagingPass(db, sessionId, passCount + 1, merged, currentFacts);
|
|
173895
|
-
const promoted = promoteRecompStaging(db, sessionId);
|
|
174779
|
+
const promoted = promoteRecompStaging(db, sessionId, holderId);
|
|
173896
174780
|
if (!promoted) {
|
|
173897
174781
|
log("[magic-context] partial recomp promote returned null");
|
|
173898
174782
|
return null;
|
|
@@ -174100,6 +174984,7 @@ Staging preserved for resume on next attempt.`;
|
|
|
174100
174984
|
}
|
|
174101
174985
|
|
|
174102
174986
|
// ../plugin/src/hooks/magic-context/compartment-runner-recomp.ts
|
|
174987
|
+
init_logger();
|
|
174103
174988
|
async function executeContextRecompInternal(deps) {
|
|
174104
174989
|
const {
|
|
174105
174990
|
client,
|
|
@@ -174111,6 +174996,12 @@ async function executeContextRecompInternal(deps) {
|
|
|
174111
174996
|
getNotificationParams
|
|
174112
174997
|
} = deps;
|
|
174113
174998
|
const notifParams = () => getNotificationParams?.() ?? {};
|
|
174999
|
+
const holderId = deps.compartmentLeaseHolderId;
|
|
175000
|
+
if (!holderId) {
|
|
175001
|
+
return `## Magic Recomp — Skipped
|
|
175002
|
+
|
|
175003
|
+
Could not acquire the compartment-state lease for this session.`;
|
|
175004
|
+
}
|
|
174114
175005
|
let currentStateFilePath;
|
|
174115
175006
|
updateSessionMeta(db, sessionId, { compartmentInProgress: true });
|
|
174116
175007
|
try {
|
|
@@ -174147,7 +175038,7 @@ Found ${existingStaging.compartments.length} staged compartment(s) from ${existi
|
|
|
174147
175038
|
if (mergedError)
|
|
174148
175039
|
return null;
|
|
174149
175040
|
saveRecompStagingPass(db, sessionId, passCount, candidateCompartments, candidateFacts);
|
|
174150
|
-
const promoted2 = promoteRecompStaging(db, sessionId);
|
|
175041
|
+
const promoted2 = promoteRecompStaging(db, sessionId, holderId);
|
|
174151
175042
|
if (!promoted2)
|
|
174152
175043
|
return null;
|
|
174153
175044
|
clearCompressionDepth(db, sessionId);
|
|
@@ -174228,6 +175119,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
174228
175119
|
fallbackModelId: deps.fallbackModelId,
|
|
174229
175120
|
fallbackModels: deps.fallbackModels,
|
|
174230
175121
|
twoPass: deps.historianTwoPass,
|
|
175122
|
+
subagentKind: "recomp",
|
|
174231
175123
|
callbacks: {
|
|
174232
175124
|
onRepairRetry: async (error51) => {
|
|
174233
175125
|
await sendIgnoredMessage(client, sessionId, `## Magic Recomp
|
|
@@ -174298,10 +175190,12 @@ Recomp completed ${passCount} pass${passCount === 1 ? "" : "es"} but produced an
|
|
|
174298
175190
|
Nothing was written.`;
|
|
174299
175191
|
}
|
|
174300
175192
|
saveRecompStagingPass(db, sessionId, passCount, candidateCompartments, candidateFacts);
|
|
174301
|
-
const promoted = promoteRecompStaging(db, sessionId);
|
|
175193
|
+
const promoted = promoteRecompStaging(db, sessionId, holderId);
|
|
174302
175194
|
if (!promoted) {
|
|
174303
|
-
|
|
174304
|
-
|
|
175195
|
+
sessionLog(sessionId, "recomp publish skipped: compartment lease no longer held");
|
|
175196
|
+
return `## Magic Recomp — Skipped
|
|
175197
|
+
|
|
175198
|
+
Another process acquired the compartment-state lease before recomp could publish. No state was written.`;
|
|
174305
175199
|
}
|
|
174306
175200
|
clearCompressionDepth(db, sessionId);
|
|
174307
175201
|
if (deps.preserveInjectionCacheUntilConsumed !== true) {
|
|
@@ -174370,12 +175264,32 @@ function withPublishedCallback(deps) {
|
|
|
174370
175264
|
}
|
|
174371
175265
|
};
|
|
174372
175266
|
}
|
|
174373
|
-
|
|
175267
|
+
function startLeaseRenewal(deps, holderId) {
|
|
175268
|
+
return setInterval(() => {
|
|
175269
|
+
if (!renewCompartmentLease(deps.db, deps.sessionId, holderId)) {
|
|
175270
|
+
sessionLog(deps.sessionId, "compartment lease renewal failed; publish will be skipped if holder is stale");
|
|
175271
|
+
}
|
|
175272
|
+
}, COMPARTMENT_LEASE_RENEWAL_MS);
|
|
175273
|
+
}
|
|
175274
|
+
async function executeContextRecompWithResult(deps, options = {}) {
|
|
174374
175275
|
const { sessionId } = deps;
|
|
174375
175276
|
if (activeRuns.has(sessionId)) {
|
|
174376
|
-
return
|
|
175277
|
+
return {
|
|
175278
|
+
message: "## Magic Recomp\n\nHistorian is already running for this session. Wait for it to finish, then try `/ctx-recomp` again.",
|
|
175279
|
+
published: false
|
|
175280
|
+
};
|
|
175281
|
+
}
|
|
175282
|
+
const holderId = crypto.randomUUID();
|
|
175283
|
+
const lease2 = acquireCompartmentLease(deps.db, sessionId, holderId);
|
|
175284
|
+
if (!lease2) {
|
|
175285
|
+
sessionLog(sessionId, "recomp skipped: compartment lease held by another process");
|
|
175286
|
+
return {
|
|
175287
|
+
message: "## Magic Recomp\n\nAnother process is already mutating compartment state for this session. Wait for it to finish, then try `/ctx-recomp` again.",
|
|
175288
|
+
published: false
|
|
175289
|
+
};
|
|
174377
175290
|
}
|
|
174378
|
-
const
|
|
175291
|
+
const renewal = startLeaseRenewal(deps, holderId);
|
|
175292
|
+
const runnerDeps = withPublishedCallback({ ...deps, compartmentLeaseHolderId: holderId });
|
|
174379
175293
|
const promise2 = options.range ? executePartialRecompInternal(runnerDeps, options.range) : executeContextRecompInternal(runnerDeps);
|
|
174380
175294
|
const wrappedPromise = promise2.then(() => {
|
|
174381
175295
|
return;
|
|
@@ -174384,8 +175298,14 @@ async function executeContextRecomp(deps, options = {}) {
|
|
|
174384
175298
|
});
|
|
174385
175299
|
activeRuns.set(sessionId, { promise: wrappedPromise, published: false });
|
|
174386
175300
|
try {
|
|
174387
|
-
|
|
175301
|
+
const message = await promise2;
|
|
175302
|
+
return {
|
|
175303
|
+
message,
|
|
175304
|
+
published: activeRuns.get(sessionId)?.published === true
|
|
175305
|
+
};
|
|
174388
175306
|
} finally {
|
|
175307
|
+
clearInterval(renewal);
|
|
175308
|
+
releaseCompartmentLease(deps.db, sessionId, holderId);
|
|
174389
175309
|
if (activeRuns.get(sessionId)?.promise === wrappedPromise) {
|
|
174390
175310
|
activeRuns.delete(sessionId);
|
|
174391
175311
|
}
|
|
@@ -174558,7 +175478,7 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
174558
175478
|
projectIdentity: ctx.cwd
|
|
174559
175479
|
});
|
|
174560
175480
|
try {
|
|
174561
|
-
const result = await
|
|
175481
|
+
const result = await executeContextRecompWithResult({
|
|
174562
175482
|
client: createPiRecompClient({
|
|
174563
175483
|
runner: deps.runner,
|
|
174564
175484
|
model: deps.historianModel,
|
|
@@ -174566,6 +175486,7 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
174566
175486
|
timeoutMs: deps.historianTimeoutMs,
|
|
174567
175487
|
thinkingLevel: deps.historianThinkingLevel,
|
|
174568
175488
|
directory: ctx.cwd,
|
|
175489
|
+
accountingSessionId: sessionId,
|
|
174569
175490
|
notify: (text) => {
|
|
174570
175491
|
sendCtxStatusMessage(pi, {
|
|
174571
175492
|
title: "/ctx-recomp",
|
|
@@ -174584,9 +175505,12 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
174584
175505
|
}, parsed.kind === "partial" ? { range: parsed.range } : {});
|
|
174585
175506
|
sendCtxStatusMessage(pi, {
|
|
174586
175507
|
title: "/ctx-recomp",
|
|
174587
|
-
text: result,
|
|
174588
|
-
level: inferLevel(result)
|
|
175508
|
+
text: result.message,
|
|
175509
|
+
level: inferLevel(result.message)
|
|
174589
175510
|
});
|
|
175511
|
+
if (!result.published) {
|
|
175512
|
+
return;
|
|
175513
|
+
}
|
|
174590
175514
|
queueAndApplyPiRecompMarker({ db: deps.db, sessionId, ctx });
|
|
174591
175515
|
signalPiHistoryRefresh(sessionId);
|
|
174592
175516
|
signalPiPendingMaterialization(sessionId);
|
|
@@ -174749,7 +175673,9 @@ function createPiRecompClient(args) {
|
|
|
174749
175673
|
fallbackModels: args.fallbackModels,
|
|
174750
175674
|
timeoutMs: args.timeoutMs,
|
|
174751
175675
|
cwd: args.directory,
|
|
174752
|
-
thinkingLevel: args.thinkingLevel
|
|
175676
|
+
thinkingLevel: args.thinkingLevel,
|
|
175677
|
+
accountingSessionId: args.accountingSessionId,
|
|
175678
|
+
accountingSubagent: "recomp"
|
|
174753
175679
|
});
|
|
174754
175680
|
if (!result.ok) {
|
|
174755
175681
|
throw new Error(`Pi recomp historian failed (${result.reason}): ${result.error}`);
|
|
@@ -174780,8 +175706,8 @@ function createPiRecompClient(args) {
|
|
|
174780
175706
|
function readPathId(input) {
|
|
174781
175707
|
if (typeof input !== "object" || input === null)
|
|
174782
175708
|
return "";
|
|
174783
|
-
const
|
|
174784
|
-
return typeof
|
|
175709
|
+
const path6 = input.path;
|
|
175710
|
+
return typeof path6?.id === "string" ? path6.id : "";
|
|
174785
175711
|
}
|
|
174786
175712
|
function readBody(input) {
|
|
174787
175713
|
if (typeof input !== "object" || input === null)
|
|
@@ -174932,10 +175858,20 @@ import {
|
|
|
174932
175858
|
truncateToWidth,
|
|
174933
175859
|
visibleWidth
|
|
174934
175860
|
} from "@earendil-works/pi-tui";
|
|
175861
|
+
|
|
175862
|
+
// ../plugin/src/shared/format-threshold.ts
|
|
175863
|
+
function formatThresholdPercent(value) {
|
|
175864
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
175865
|
+
return "—";
|
|
175866
|
+
const rounded = Math.round(value);
|
|
175867
|
+
if (Math.abs(value - rounded) < 0.05)
|
|
175868
|
+
return String(rounded);
|
|
175869
|
+
return value.toFixed(1);
|
|
175870
|
+
}
|
|
174935
175871
|
// package.json
|
|
174936
175872
|
var package_default = {
|
|
174937
175873
|
name: "@cortexkit/pi-magic-context",
|
|
174938
|
-
version: "0.21.
|
|
175874
|
+
version: "0.21.8",
|
|
174939
175875
|
type: "module",
|
|
174940
175876
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
174941
175877
|
main: "dist/index.js",
|
|
@@ -175099,7 +176035,7 @@ function renderInner(s, theme, innerWidth) {
|
|
|
175099
176035
|
lines.push(theme.fg("muted", "Tags"));
|
|
175100
176036
|
lines.push(`Active ${s.activeTags} (~${formatBytes(s.activeBytes)}) · Dropped ${s.droppedTags} · Total ${s.totalTags}`);
|
|
175101
176037
|
lines.push(theme.fg("muted", "Rolling Nudges / Context"));
|
|
175102
|
-
lines.push(`Execute threshold ${s.executeThreshold}% · Anchor ${fmt2(s.lastNudgeTokens)} tok · Interval ${fmt2(s.nudgeInterval)} tok · Next ${fmt2(s.nextNudgeAfter)} tok`);
|
|
176038
|
+
lines.push(`Execute threshold ${formatThresholdPercent(s.executeThreshold)}% · Anchor ${fmt2(s.lastNudgeTokens)} tok · Interval ${fmt2(s.nudgeInterval)} tok · Next ${fmt2(s.nextNudgeAfter)} tok`);
|
|
175103
176039
|
lines.push(`Protected tags ${s.protectedTagCount} · Subagent ${s.isSubagent ? "yes" : "no"} · History block ~${fmt2(s.historyBlockTokens)} tok${s.compressionBudget ? ` · Budget ~${fmt2(s.compressionBudget)} tok (${s.compressionUsage} used)` : ""}`);
|
|
175104
176040
|
if (s.lastTransformError)
|
|
175105
176041
|
lines.push(theme.fg("error", `⚠ ${s.lastTransformError}`));
|
|
@@ -175447,7 +176383,7 @@ function buildStatusDetails(deps, sessionId) {
|
|
|
175447
176383
|
status: ["pending", "ready"]
|
|
175448
176384
|
}).length,
|
|
175449
176385
|
dreamer: {
|
|
175450
|
-
enabled: deps.dreamer?.
|
|
176386
|
+
enabled: deps.dreamer?.runnable === true,
|
|
175451
176387
|
schedule: deps.dreamer?.schedule ?? null,
|
|
175452
176388
|
lastRunAt: readNumberState(deps.db, `last_dream_at:${deps.projectIdentity}`)
|
|
175453
176389
|
},
|
|
@@ -180661,7 +181597,7 @@ var PLUGIN_VERSION = (() => {
|
|
|
180661
181597
|
setHarness("pi");
|
|
180662
181598
|
function resolveSidekickFromConfig(config2) {
|
|
180663
181599
|
const sidekick = config2.sidekick;
|
|
180664
|
-
if (!sidekick
|
|
181600
|
+
if (!sidekick || sidekick.disable === true)
|
|
180665
181601
|
return;
|
|
180666
181602
|
const model = sidekick.model?.trim();
|
|
180667
181603
|
if (!model || model.length === 0)
|
|
@@ -180670,18 +181606,20 @@ function resolveSidekickFromConfig(config2) {
|
|
|
180670
181606
|
model,
|
|
180671
181607
|
systemPrompt: sidekick.system_prompt,
|
|
180672
181608
|
timeoutMs: sidekick.timeout_ms,
|
|
180673
|
-
thinking_level: sidekick.thinking_level
|
|
181609
|
+
thinking_level: sidekick.thinking_level,
|
|
181610
|
+
fallbackModels: resolveFallbackChain("sidekick", sidekick.fallback_models)
|
|
180674
181611
|
};
|
|
180675
181612
|
}
|
|
180676
181613
|
function resolveHistorianFromConfig(config2) {
|
|
180677
181614
|
const historian = config2.historian;
|
|
181615
|
+
if (historian?.disable === true)
|
|
181616
|
+
return;
|
|
180678
181617
|
const model = historian?.model?.trim();
|
|
180679
181618
|
if (!model || model.length === 0)
|
|
180680
181619
|
return;
|
|
180681
181620
|
const historianContextLimit = resolveHistorianContextLimit(model);
|
|
180682
181621
|
const historianChunkTokens = deriveHistorianChunkTokens(historianContextLimit);
|
|
180683
|
-
const
|
|
180684
|
-
const fallbackModels = typeof fbRaw === "string" ? [fbRaw] : fbRaw;
|
|
181622
|
+
const fallbackModels = resolveFallbackChain("historian", historian?.fallback_models);
|
|
180685
181623
|
return {
|
|
180686
181624
|
runner: new PiSubagentRunner,
|
|
180687
181625
|
model,
|
|
@@ -180730,11 +181668,11 @@ function resolveAutoSearchFromConfig(config2) {
|
|
|
180730
181668
|
};
|
|
180731
181669
|
}
|
|
180732
181670
|
function resolveDreamerFromConfig(config2) {
|
|
180733
|
-
return config2.dreamer;
|
|
181671
|
+
return config2.dreamer?.disable === true ? undefined : config2.dreamer;
|
|
180734
181672
|
}
|
|
180735
181673
|
async function src_default2(pi) {
|
|
180736
181674
|
const storageDir = getMagicContextStorageDir();
|
|
180737
|
-
const dbPath =
|
|
181675
|
+
const dbPath = join20(storageDir, "context.db");
|
|
180738
181676
|
let db;
|
|
180739
181677
|
try {
|
|
180740
181678
|
db = openDatabase();
|
|
@@ -180750,6 +181688,7 @@ async function src_default2(pi) {
|
|
|
180750
181688
|
const pendingPiMarkerSessions = getSessionsWithPendingPiMarker(db);
|
|
180751
181689
|
for (const sid of pendingPiMarkerSessions) {
|
|
180752
181690
|
signalPiDeferredHistoryRefresh(sid);
|
|
181691
|
+
signalPiPendingMaterialization(sid);
|
|
180753
181692
|
}
|
|
180754
181693
|
if (pendingPiMarkerSessions.length > 0) {
|
|
180755
181694
|
log(`${PREFIX2} rehydrated ${pendingPiMarkerSessions.length} Pi deferred compaction marker session(s)`);
|
|
@@ -180781,7 +181720,7 @@ async function src_default2(pi) {
|
|
|
180781
181720
|
allowDreamerActions: false,
|
|
180782
181721
|
ctxReduceEnabled: config2.ctx_reduce_enabled === true,
|
|
180783
181722
|
protectedTags: config2.protected_tags ?? 20,
|
|
180784
|
-
dreamerEnabled: config2
|
|
181723
|
+
dreamerEnabled: isDreamerRunnable(config2)
|
|
180785
181724
|
});
|
|
180786
181725
|
info(`registered tools: ctx_search, ctx_memory, ctx_note, ctx_expand${config2.ctx_reduce_enabled === true ? ", ctx_reduce" : ""}`);
|
|
180787
181726
|
const historianConfig = resolveHistorianFromConfig(config2);
|
|
@@ -180825,7 +181764,7 @@ async function src_default2(pi) {
|
|
|
180825
181764
|
info(autoSearchConfig.enabled ? `registered auto-search hint (threshold=${autoSearchConfig.scoreThreshold}, minChars=${autoSearchConfig.minPromptChars})` : "registered auto-search hint: DISABLED (experimental.auto_search.enabled=false)");
|
|
180826
181765
|
const sidekickConfig = resolveSidekickFromConfig(config2);
|
|
180827
181766
|
registerCtxAugCommand(pi, sidekickConfig);
|
|
180828
|
-
info(sidekickConfig ? `registered /ctx-aug (sidekick model=${sidekickConfig.model})` : "registered /ctx-aug (sidekick disabled — set sidekick.
|
|
181767
|
+
info(sidekickConfig ? `registered /ctx-aug (sidekick model=${sidekickConfig.model})` : "registered /ctx-aug (sidekick disabled — set sidekick.disable=false and sidekick.model in config)");
|
|
180829
181768
|
registerCtxStatusCommand(pi, {
|
|
180830
181769
|
db,
|
|
180831
181770
|
projectIdentity,
|
|
@@ -180837,7 +181776,7 @@ async function src_default2(pi) {
|
|
|
180837
181776
|
commitClusterTrigger: config2.commit_cluster_trigger,
|
|
180838
181777
|
executeThresholdTokens: config2.execute_threshold_tokens,
|
|
180839
181778
|
dreamer: {
|
|
180840
|
-
|
|
181779
|
+
runnable: isDreamerRunnable(config2),
|
|
180841
181780
|
schedule: config2.dreamer?.schedule
|
|
180842
181781
|
}
|
|
180843
181782
|
});
|
|
@@ -180863,7 +181802,7 @@ async function src_default2(pi) {
|
|
|
180863
181802
|
projectDir,
|
|
180864
181803
|
projectIdentity,
|
|
180865
181804
|
resolveProject: resolveCurrentProject,
|
|
180866
|
-
dreamerEnabled: config2
|
|
181805
|
+
dreamerEnabled: isDreamerRunnable(config2),
|
|
180867
181806
|
onProjectSeen: (identity) => seenDreamerProjectIdentities.add(identity)
|
|
180868
181807
|
});
|
|
180869
181808
|
info("registered /ctx-dream");
|
|
@@ -180879,11 +181818,28 @@ async function src_default2(pi) {
|
|
|
180879
181818
|
gitCommitIndexing: config2.experimental.git_commit_indexing,
|
|
180880
181819
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|
|
180881
181820
|
});
|
|
180882
|
-
info(
|
|
181821
|
+
info(`registered dreamer (schedule=${dreamerConfig.schedule || "manual-only"}, tasks=[${dreamerConfig.tasks.join(",")}])`);
|
|
180883
181822
|
} else {
|
|
180884
|
-
info("registered dreamer: DISABLED (no dreamer config)");
|
|
181823
|
+
info(isDreamerRunnable(config2) ? "registered dreamer: DISABLED (no dreamer config)" : "registered dreamer: DISABLED (dreamer.disable=true or no dreamer config)");
|
|
180885
181824
|
}
|
|
180886
181825
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
181826
|
+
try {
|
|
181827
|
+
if (ctx.hasUI && shouldShowAnnouncement()) {
|
|
181828
|
+
const featureText = ANNOUNCEMENT_FEATURES.map((line) => ` • ${line}`).join(`
|
|
181829
|
+
`);
|
|
181830
|
+
const sections = [
|
|
181831
|
+
`✨ Magic Context v${ANNOUNCEMENT_VERSION} — what's new:`,
|
|
181832
|
+
"",
|
|
181833
|
+
featureText
|
|
181834
|
+
];
|
|
181835
|
+
if (ANNOUNCEMENT_FOOTER && ANNOUNCEMENT_FOOTER.trim().length > 0) {
|
|
181836
|
+
sections.push("", ANNOUNCEMENT_FOOTER);
|
|
181837
|
+
}
|
|
181838
|
+
ctx.ui.notify(sections.join(`
|
|
181839
|
+
`), "info");
|
|
181840
|
+
markAnnouncementSeen(ANNOUNCEMENT_VERSION);
|
|
181841
|
+
}
|
|
181842
|
+
} catch {}
|
|
180887
181843
|
try {
|
|
180888
181844
|
const currentProject = resolveCurrentProject(ctx);
|
|
180889
181845
|
seenDreamerProjectIdentities.add(currentProject.projectIdentity);
|
|
@@ -180915,16 +181871,16 @@ async function src_default2(pi) {
|
|
|
180915
181871
|
cwd: currentProject.projectDir,
|
|
180916
181872
|
sessionId,
|
|
180917
181873
|
memoryEnabled: config2.memory.enabled,
|
|
180918
|
-
injectDocs: config2.dreamer?.inject_docs ?? true,
|
|
181874
|
+
injectDocs: isDreamerRunnable(config2) && (config2.dreamer?.inject_docs ?? true),
|
|
180919
181875
|
includeGuidance: true,
|
|
180920
181876
|
protectedTags: config2.protected_tags,
|
|
180921
181877
|
ctxReduceEnabled: config2.ctx_reduce_enabled,
|
|
180922
|
-
dreamerEnabled: config2
|
|
181878
|
+
dreamerEnabled: isDreamerRunnable(config2),
|
|
180923
181879
|
dropToolStructure: config2.drop_tool_structure,
|
|
180924
181880
|
temporalAwarenessEnabled: config2.experimental?.temporal_awareness ?? false,
|
|
180925
181881
|
cavemanTextCompressionEnabled: config2.ctx_reduce_enabled === false && config2.experimental?.caveman_text_compression?.enabled === true,
|
|
180926
|
-
userMemoriesEnabled:
|
|
180927
|
-
pinKeyFilesEnabled:
|
|
181882
|
+
userMemoriesEnabled: config2.dreamer?.user_memories?.enabled ?? false,
|
|
181883
|
+
pinKeyFilesEnabled: config2.dreamer?.pin_key_files?.enabled ?? false,
|
|
180928
181884
|
pinKeyFilesTokenBudget: config2.dreamer?.pin_key_files?.token_budget ?? 1e4,
|
|
180929
181885
|
isCacheBusting,
|
|
180930
181886
|
existingSystemPrompt: event.systemPrompt
|
|
@@ -181063,7 +182019,7 @@ ${block}` : event.systemPrompt;
|
|
|
181063
182019
|
continue;
|
|
181064
182020
|
if (typeof b.name !== "string")
|
|
181065
182021
|
continue;
|
|
181066
|
-
if (
|
|
182022
|
+
if (b.name !== "todowrite") {
|
|
181067
182023
|
continue;
|
|
181068
182024
|
}
|
|
181069
182025
|
const args = b.arguments;
|
|
@@ -181149,6 +182105,9 @@ ${block}` : event.systemPrompt;
|
|
|
181149
182105
|
});
|
|
181150
182106
|
}
|
|
181151
182107
|
export {
|
|
182108
|
+
resolveSidekickFromConfig,
|
|
182109
|
+
resolveHistorianFromConfig,
|
|
182110
|
+
resolveDreamerFromConfig,
|
|
181152
182111
|
persistPiPressureFromMessageEnd,
|
|
181153
182112
|
persistPiMessageEndModelMeta,
|
|
181154
182113
|
src_default2 as default
|