@cortexkit/pi-magic-context 0.22.5 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3336 -995
- package/dist/subagent-entry.js +965 -289
- package/package.json +2 -1
package/dist/subagent-entry.js
CHANGED
|
@@ -46,6 +46,111 @@ var __export = (target, all) => {
|
|
|
46
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
47
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
48
48
|
|
|
49
|
+
// ../plugin/src/shared/harness.ts
|
|
50
|
+
function setHarness(value) {
|
|
51
|
+
if (harnessLocked && currentHarness !== value) {
|
|
52
|
+
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
53
|
+
}
|
|
54
|
+
currentHarness = value;
|
|
55
|
+
harnessLocked = true;
|
|
56
|
+
}
|
|
57
|
+
function getHarness() {
|
|
58
|
+
return currentHarness;
|
|
59
|
+
}
|
|
60
|
+
var currentHarness = "opencode", harnessLocked = false;
|
|
61
|
+
|
|
62
|
+
// ../plugin/src/shared/data-path.ts
|
|
63
|
+
import * as os from "node:os";
|
|
64
|
+
import * as path from "node:path";
|
|
65
|
+
function getDataDir() {
|
|
66
|
+
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
67
|
+
}
|
|
68
|
+
function getMagicContextTempDir(harness = getHarness()) {
|
|
69
|
+
return path.join(os.tmpdir(), harness, "magic-context");
|
|
70
|
+
}
|
|
71
|
+
function getMagicContextLogPath(harness = getHarness()) {
|
|
72
|
+
return path.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
73
|
+
}
|
|
74
|
+
function getProjectMagicContextDir(directory) {
|
|
75
|
+
return path.join(directory, ".opencode", "magic-context");
|
|
76
|
+
}
|
|
77
|
+
function getProjectMagicContextHistorianDir(directory) {
|
|
78
|
+
return path.join(getProjectMagicContextDir(directory), "historian");
|
|
79
|
+
}
|
|
80
|
+
function getOpenCodeStorageDir() {
|
|
81
|
+
return path.join(getDataDir(), "opencode", "storage");
|
|
82
|
+
}
|
|
83
|
+
function getMagicContextStorageDir() {
|
|
84
|
+
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
85
|
+
}
|
|
86
|
+
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
87
|
+
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
88
|
+
}
|
|
89
|
+
var init_data_path = () => {};
|
|
90
|
+
|
|
91
|
+
// ../plugin/src/shared/logger.ts
|
|
92
|
+
import * as fs from "node:fs";
|
|
93
|
+
import * as path2 from "node:path";
|
|
94
|
+
function ensureDir(filePath) {
|
|
95
|
+
const dir = path2.dirname(filePath);
|
|
96
|
+
if (dir === lastEnsuredDir)
|
|
97
|
+
return;
|
|
98
|
+
try {
|
|
99
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
100
|
+
lastEnsuredDir = dir;
|
|
101
|
+
} catch {}
|
|
102
|
+
}
|
|
103
|
+
function flush() {
|
|
104
|
+
if (flushTimer) {
|
|
105
|
+
clearTimeout(flushTimer);
|
|
106
|
+
flushTimer = null;
|
|
107
|
+
}
|
|
108
|
+
if (buffer.length === 0)
|
|
109
|
+
return;
|
|
110
|
+
const data = buffer.join("");
|
|
111
|
+
buffer = [];
|
|
112
|
+
try {
|
|
113
|
+
const logFile = getMagicContextLogPath();
|
|
114
|
+
ensureDir(logFile);
|
|
115
|
+
fs.appendFileSync(logFile, data);
|
|
116
|
+
} catch {}
|
|
117
|
+
}
|
|
118
|
+
function scheduleFlush() {
|
|
119
|
+
if (flushTimer)
|
|
120
|
+
return;
|
|
121
|
+
flushTimer = setTimeout(() => {
|
|
122
|
+
flushTimer = null;
|
|
123
|
+
flush();
|
|
124
|
+
}, FLUSH_INTERVAL_MS);
|
|
125
|
+
}
|
|
126
|
+
function log(message, data) {
|
|
127
|
+
if (isTestEnv)
|
|
128
|
+
return;
|
|
129
|
+
try {
|
|
130
|
+
const timestamp = new Date().toISOString();
|
|
131
|
+
const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
|
|
132
|
+
${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
133
|
+
buffer.push(`[${timestamp}] ${message}${serialized}
|
|
134
|
+
`);
|
|
135
|
+
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
136
|
+
flush();
|
|
137
|
+
} else {
|
|
138
|
+
scheduleFlush();
|
|
139
|
+
}
|
|
140
|
+
} catch {}
|
|
141
|
+
}
|
|
142
|
+
function sessionLog(sessionId, message, data) {
|
|
143
|
+
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
144
|
+
}
|
|
145
|
+
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
|
|
146
|
+
var init_logger = __esm(() => {
|
|
147
|
+
init_data_path();
|
|
148
|
+
buffer = [];
|
|
149
|
+
if (!isTestEnv) {
|
|
150
|
+
process.on("exit", flush);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
49
154
|
// ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
|
|
50
155
|
var require_esprima = __commonJS((exports, module) => {
|
|
51
156
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
@@ -7804,53 +7909,10 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7804
7909
|
});
|
|
7805
7910
|
|
|
7806
7911
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
7912
|
+
init_data_path();
|
|
7807
7913
|
import { copyFileSync, cpSync, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "node:fs";
|
|
7808
7914
|
import { dirname as dirname2, join as join4 } from "node:path";
|
|
7809
7915
|
|
|
7810
|
-
// ../plugin/src/shared/data-path.ts
|
|
7811
|
-
import * as os from "node:os";
|
|
7812
|
-
import * as path from "node:path";
|
|
7813
|
-
|
|
7814
|
-
// ../plugin/src/shared/harness.ts
|
|
7815
|
-
var currentHarness = "opencode";
|
|
7816
|
-
var harnessLocked = false;
|
|
7817
|
-
function setHarness(value) {
|
|
7818
|
-
if (harnessLocked && currentHarness !== value) {
|
|
7819
|
-
throw new Error(`Magic Context: harness already locked to "${currentHarness}"; cannot change to "${value}"`);
|
|
7820
|
-
}
|
|
7821
|
-
currentHarness = value;
|
|
7822
|
-
harnessLocked = true;
|
|
7823
|
-
}
|
|
7824
|
-
function getHarness() {
|
|
7825
|
-
return currentHarness;
|
|
7826
|
-
}
|
|
7827
|
-
|
|
7828
|
-
// ../plugin/src/shared/data-path.ts
|
|
7829
|
-
function getDataDir() {
|
|
7830
|
-
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
7831
|
-
}
|
|
7832
|
-
function getMagicContextTempDir(harness = getHarness()) {
|
|
7833
|
-
return path.join(os.tmpdir(), harness, "magic-context");
|
|
7834
|
-
}
|
|
7835
|
-
function getMagicContextLogPath(harness = getHarness()) {
|
|
7836
|
-
return path.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
7837
|
-
}
|
|
7838
|
-
function getProjectMagicContextDir(directory) {
|
|
7839
|
-
return path.join(directory, ".opencode", "magic-context");
|
|
7840
|
-
}
|
|
7841
|
-
function getProjectMagicContextHistorianDir(directory) {
|
|
7842
|
-
return path.join(getProjectMagicContextDir(directory), "historian");
|
|
7843
|
-
}
|
|
7844
|
-
function getOpenCodeStorageDir() {
|
|
7845
|
-
return path.join(getDataDir(), "opencode", "storage");
|
|
7846
|
-
}
|
|
7847
|
-
function getMagicContextStorageDir() {
|
|
7848
|
-
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
7849
|
-
}
|
|
7850
|
-
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
7851
|
-
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
7852
|
-
}
|
|
7853
|
-
|
|
7854
7916
|
// ../plugin/src/shared/error-message.ts
|
|
7855
7917
|
function getErrorMessage(error) {
|
|
7856
7918
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -7927,69 +7989,8 @@ function safeString(value) {
|
|
|
7927
7989
|
}
|
|
7928
7990
|
}
|
|
7929
7991
|
|
|
7930
|
-
// ../plugin/src/
|
|
7931
|
-
|
|
7932
|
-
import * as path2 from "node:path";
|
|
7933
|
-
var isTestEnv = false;
|
|
7934
|
-
var buffer = [];
|
|
7935
|
-
var flushTimer = null;
|
|
7936
|
-
var FLUSH_INTERVAL_MS = 500;
|
|
7937
|
-
var BUFFER_SIZE_LIMIT = 50;
|
|
7938
|
-
var lastEnsuredDir = null;
|
|
7939
|
-
function ensureDir(filePath) {
|
|
7940
|
-
const dir = path2.dirname(filePath);
|
|
7941
|
-
if (dir === lastEnsuredDir)
|
|
7942
|
-
return;
|
|
7943
|
-
try {
|
|
7944
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
7945
|
-
lastEnsuredDir = dir;
|
|
7946
|
-
} catch {}
|
|
7947
|
-
}
|
|
7948
|
-
function flush() {
|
|
7949
|
-
if (flushTimer) {
|
|
7950
|
-
clearTimeout(flushTimer);
|
|
7951
|
-
flushTimer = null;
|
|
7952
|
-
}
|
|
7953
|
-
if (buffer.length === 0)
|
|
7954
|
-
return;
|
|
7955
|
-
const data = buffer.join("");
|
|
7956
|
-
buffer = [];
|
|
7957
|
-
try {
|
|
7958
|
-
const logFile = getMagicContextLogPath();
|
|
7959
|
-
ensureDir(logFile);
|
|
7960
|
-
fs.appendFileSync(logFile, data);
|
|
7961
|
-
} catch {}
|
|
7962
|
-
}
|
|
7963
|
-
function scheduleFlush() {
|
|
7964
|
-
if (flushTimer)
|
|
7965
|
-
return;
|
|
7966
|
-
flushTimer = setTimeout(() => {
|
|
7967
|
-
flushTimer = null;
|
|
7968
|
-
flush();
|
|
7969
|
-
}, FLUSH_INTERVAL_MS);
|
|
7970
|
-
}
|
|
7971
|
-
function log(message, data) {
|
|
7972
|
-
if (isTestEnv)
|
|
7973
|
-
return;
|
|
7974
|
-
try {
|
|
7975
|
-
const timestamp = new Date().toISOString();
|
|
7976
|
-
const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
|
|
7977
|
-
${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
7978
|
-
buffer.push(`[${timestamp}] ${message}${serialized}
|
|
7979
|
-
`);
|
|
7980
|
-
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
7981
|
-
flush();
|
|
7982
|
-
} else {
|
|
7983
|
-
scheduleFlush();
|
|
7984
|
-
}
|
|
7985
|
-
} catch {}
|
|
7986
|
-
}
|
|
7987
|
-
function sessionLog(sessionId, message, data) {
|
|
7988
|
-
log(`[magic-context][${sessionId}] ${message}`, data);
|
|
7989
|
-
}
|
|
7990
|
-
if (!isTestEnv) {
|
|
7991
|
-
process.on("exit", flush);
|
|
7992
|
-
}
|
|
7992
|
+
// ../plugin/src/features/magic-context/storage-db.ts
|
|
7993
|
+
init_logger();
|
|
7993
7994
|
|
|
7994
7995
|
// ../plugin/src/shared/sqlite.ts
|
|
7995
7996
|
var isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
@@ -8045,6 +8046,7 @@ function closeQuietly(db) {
|
|
|
8045
8046
|
}
|
|
8046
8047
|
|
|
8047
8048
|
// ../plugin/src/features/magic-context/key-files/project-key-files.ts
|
|
8049
|
+
init_logger();
|
|
8048
8050
|
import { createHash } from "node:crypto";
|
|
8049
8051
|
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
8050
8052
|
import { join as join2, resolve, sep } from "node:path";
|
|
@@ -8161,6 +8163,7 @@ function isRelativeProjectFile(projectPath, relativePath) {
|
|
|
8161
8163
|
}
|
|
8162
8164
|
|
|
8163
8165
|
// ../plugin/src/features/magic-context/migrations.ts
|
|
8166
|
+
init_logger();
|
|
8164
8167
|
function tableExists(db, name) {
|
|
8165
8168
|
return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name));
|
|
8166
8169
|
}
|
|
@@ -8916,6 +8919,50 @@ var MIGRATIONS = [
|
|
|
8916
8919
|
cached_m0_model_key = NULL`).run();
|
|
8917
8920
|
}
|
|
8918
8921
|
}
|
|
8922
|
+
},
|
|
8923
|
+
{
|
|
8924
|
+
version: 31,
|
|
8925
|
+
description: "Nudge redesign: Channel 1 cadence (last_nudge_undropped) + Channel 2 ceiling lease " + "(channel2_nudge_state); zero legacy ctx_reduce-nudge sticky/anchor state (startup heal)",
|
|
8926
|
+
up: (db) => {
|
|
8927
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta' LIMIT 1").get();
|
|
8928
|
+
if (!hasSessionMeta)
|
|
8929
|
+
return;
|
|
8930
|
+
ensureColumn(db, "session_meta", "last_nudge_undropped", "INTEGER DEFAULT 0");
|
|
8931
|
+
ensureColumn(db, "session_meta", "channel2_nudge_state", "TEXT DEFAULT ''");
|
|
8932
|
+
const columns = new Set(db.prepare("PRAGMA table_info(session_meta)").all().map((column) => column.name));
|
|
8933
|
+
if (columns.has("sticky_turn_reminder_text")) {
|
|
8934
|
+
db.prepare(`UPDATE session_meta SET
|
|
8935
|
+
sticky_turn_reminder_text = '',
|
|
8936
|
+
sticky_turn_reminder_message_id = '',
|
|
8937
|
+
nudge_anchor_message_id = '',
|
|
8938
|
+
nudge_anchor_text = ''`).run();
|
|
8939
|
+
}
|
|
8940
|
+
}
|
|
8941
|
+
},
|
|
8942
|
+
{
|
|
8943
|
+
version: 32,
|
|
8944
|
+
description: "Protected tail boundary state, usage resolver fields, recovery escape, and drain quota",
|
|
8945
|
+
up: (db) => {
|
|
8946
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta' LIMIT 1").get();
|
|
8947
|
+
if (!hasSessionMeta)
|
|
8948
|
+
return;
|
|
8949
|
+
ensureColumn(db, "session_meta", "prior_boundary_ordinal", "INTEGER NOT NULL DEFAULT 1");
|
|
8950
|
+
ensureColumn(db, "session_meta", "protected_tail_policy_version", "INTEGER NOT NULL DEFAULT 0");
|
|
8951
|
+
ensureColumn(db, "session_meta", "protected_tail_drain_window_started_at", "INTEGER NOT NULL DEFAULT 0");
|
|
8952
|
+
ensureColumn(db, "session_meta", "protected_tail_drain_tokens", "INTEGER NOT NULL DEFAULT 0");
|
|
8953
|
+
ensureColumn(db, "session_meta", "recovery_no_eligible_head_count", "INTEGER NOT NULL DEFAULT 0");
|
|
8954
|
+
ensureColumn(db, "session_meta", "force_emergency_bypass_window_start", "INTEGER NOT NULL DEFAULT 0");
|
|
8955
|
+
ensureColumn(db, "session_meta", "force_emergency_bypass_used", "INTEGER NOT NULL DEFAULT 0");
|
|
8956
|
+
ensureColumn(db, "session_meta", "last_usage_context_limit", "INTEGER NOT NULL DEFAULT 0");
|
|
8957
|
+
db.prepare("UPDATE session_meta SET prior_boundary_ordinal = 1 WHERE prior_boundary_ordinal IS NULL OR prior_boundary_ordinal < 1").run();
|
|
8958
|
+
db.prepare("UPDATE session_meta SET protected_tail_policy_version = 0 WHERE protected_tail_policy_version IS NULL").run();
|
|
8959
|
+
db.prepare("UPDATE session_meta SET protected_tail_drain_window_started_at = 0 WHERE protected_tail_drain_window_started_at IS NULL").run();
|
|
8960
|
+
db.prepare("UPDATE session_meta SET protected_tail_drain_tokens = 0 WHERE protected_tail_drain_tokens IS NULL").run();
|
|
8961
|
+
db.prepare("UPDATE session_meta SET recovery_no_eligible_head_count = 0 WHERE recovery_no_eligible_head_count IS NULL").run();
|
|
8962
|
+
db.prepare("UPDATE session_meta SET force_emergency_bypass_window_start = 0 WHERE force_emergency_bypass_window_start IS NULL").run();
|
|
8963
|
+
db.prepare("UPDATE session_meta SET force_emergency_bypass_used = 0 WHERE force_emergency_bypass_used IS NULL").run();
|
|
8964
|
+
db.prepare("UPDATE session_meta SET last_usage_context_limit = 0 WHERE last_usage_context_limit IS NULL").run();
|
|
8965
|
+
}
|
|
8919
8966
|
}
|
|
8920
8967
|
];
|
|
8921
8968
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -141521,7 +141568,7 @@ var tokenizer = new src_default(exports_claude);
|
|
|
141521
141568
|
function estimateTokens(text) {
|
|
141522
141569
|
if (!text)
|
|
141523
141570
|
return 0;
|
|
141524
|
-
return tokenizer.
|
|
141571
|
+
return tokenizer.encode(text, "all").length;
|
|
141525
141572
|
}
|
|
141526
141573
|
function normalizeText(text) {
|
|
141527
141574
|
return text.replace(/\s+/g, " ").trim();
|
|
@@ -141631,6 +141678,8 @@ function loadToolDefinitionMeasurements(db) {
|
|
|
141631
141678
|
}
|
|
141632
141679
|
|
|
141633
141680
|
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
141681
|
+
init_data_path();
|
|
141682
|
+
init_logger();
|
|
141634
141683
|
import { existsSync as existsSync2 } from "node:fs";
|
|
141635
141684
|
import { join as join3 } from "node:path";
|
|
141636
141685
|
var LEASE_DURATION_MS = 5 * 60 * 1000;
|
|
@@ -141746,6 +141795,11 @@ function markSessionCompleted(db, sessionId, now) {
|
|
|
141746
141795
|
SET status = 'completed', completed_at = ?, lease_expires_at = NULL, last_error = NULL
|
|
141747
141796
|
WHERE session_id = ?`).run(now, sessionId);
|
|
141748
141797
|
}
|
|
141798
|
+
function markSessionPendingRetry(db, sessionId) {
|
|
141799
|
+
db.prepare(`UPDATE tool_owner_backfill_state
|
|
141800
|
+
SET status = 'pending', completed_at = NULL, lease_expires_at = NULL, last_error = NULL
|
|
141801
|
+
WHERE session_id = ?`).run(sessionId);
|
|
141802
|
+
}
|
|
141749
141803
|
function markSessionSkipped(db, sessionId, now, reason) {
|
|
141750
141804
|
db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, completed_at, last_error)
|
|
141751
141805
|
VALUES (?, 'skipped', ?, ?)
|
|
@@ -141822,12 +141876,18 @@ function applyOwnersForSession(db, sessionId, ownersByCallId) {
|
|
|
141822
141876
|
const updateRowStmt = db.prepare(`UPDATE tags
|
|
141823
141877
|
SET tool_owner_message_id = ?
|
|
141824
141878
|
WHERE id = ? AND tool_owner_message_id IS NULL`);
|
|
141879
|
+
const existingOwnerStmt = db.prepare(`SELECT 1 AS hit FROM tags
|
|
141880
|
+
WHERE session_id = ? AND message_id = ? AND type = 'tool'
|
|
141881
|
+
AND tool_owner_message_id = ?
|
|
141882
|
+
LIMIT 1`);
|
|
141825
141883
|
let rowsUpdated = 0;
|
|
141826
141884
|
db.transaction(() => {
|
|
141827
141885
|
for (const [callId, ownerId] of ownersByCallId) {
|
|
141828
141886
|
const orphan = findOrphanStmt.get(sessionId, callId);
|
|
141829
141887
|
if (!orphan)
|
|
141830
141888
|
continue;
|
|
141889
|
+
if (existingOwnerStmt.get(sessionId, callId, ownerId))
|
|
141890
|
+
continue;
|
|
141831
141891
|
const result = updateRowStmt.run(ownerId, orphan.id);
|
|
141832
141892
|
rowsUpdated += result.changes ?? 0;
|
|
141833
141893
|
}
|
|
@@ -141856,6 +141916,8 @@ function backfillToolOwnersInChunks(db, result) {
|
|
|
141856
141916
|
if (owners.size === 0) {
|
|
141857
141917
|
markSessionSkipped(db, sessionId, Date.now(), "no_oc_matches");
|
|
141858
141918
|
result.sessionsSkippedNoMatches += 1;
|
|
141919
|
+
} else if (rowsLeftNull > 0) {
|
|
141920
|
+
markSessionPendingRetry(db, sessionId);
|
|
141859
141921
|
} else {
|
|
141860
141922
|
markSessionCompleted(db, sessionId, Date.now());
|
|
141861
141923
|
result.sessionsCompleted += 1;
|
|
@@ -141878,7 +141940,7 @@ var databases = new Map;
|
|
|
141878
141940
|
var persistenceByDatabase = new WeakMap;
|
|
141879
141941
|
var persistenceErrorByDatabase = new WeakMap;
|
|
141880
141942
|
var lastSchemaFenceRejection = null;
|
|
141881
|
-
var LATEST_SUPPORTED_VERSION =
|
|
141943
|
+
var LATEST_SUPPORTED_VERSION = 32;
|
|
141882
141944
|
function resolveDatabasePath(dbPathOverride) {
|
|
141883
141945
|
if (dbPathOverride) {
|
|
141884
141946
|
return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
|
|
@@ -141980,9 +142042,9 @@ function runSqliteOptimize(db) {
|
|
|
141980
142042
|
} catch {}
|
|
141981
142043
|
}
|
|
141982
142044
|
function initializeDatabase(db) {
|
|
142045
|
+
db.exec("PRAGMA busy_timeout=5000");
|
|
141983
142046
|
db.exec("PRAGMA foreign_keys=ON");
|
|
141984
142047
|
db.exec("PRAGMA journal_mode=WAL");
|
|
141985
|
-
db.exec("PRAGMA busy_timeout=5000");
|
|
141986
142048
|
applySqliteTuningPragmas(db);
|
|
141987
142049
|
db.exec(`
|
|
141988
142050
|
CREATE TABLE IF NOT EXISTS tags (
|
|
@@ -141995,6 +142057,9 @@ function initializeDatabase(db) {
|
|
|
141995
142057
|
tag_number INTEGER,
|
|
141996
142058
|
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
141997
142059
|
entry_fingerprint TEXT,
|
|
142060
|
+
token_count INTEGER,
|
|
142061
|
+
input_token_count INTEGER,
|
|
142062
|
+
reasoning_token_count INTEGER,
|
|
141998
142063
|
UNIQUE(session_id, tag_number)
|
|
141999
142064
|
);
|
|
142000
142065
|
|
|
@@ -142284,6 +142349,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142284
142349
|
counter INTEGER DEFAULT 0,
|
|
142285
142350
|
last_nudge_tokens INTEGER DEFAULT 0,
|
|
142286
142351
|
last_nudge_band TEXT DEFAULT '',
|
|
142352
|
+
last_nudge_undropped INTEGER DEFAULT 0,
|
|
142353
|
+
last_nudge_level TEXT DEFAULT '',
|
|
142354
|
+
channel2_nudge_state TEXT DEFAULT '',
|
|
142355
|
+
channel2_nudge_claimed_at INTEGER DEFAULT 0,
|
|
142356
|
+
last_emergency_input_sample INTEGER DEFAULT 0,
|
|
142287
142357
|
last_transform_error TEXT DEFAULT '',
|
|
142288
142358
|
nudge_anchor_message_id TEXT DEFAULT '',
|
|
142289
142359
|
nudge_anchor_text TEXT DEFAULT '',
|
|
@@ -142340,6 +142410,14 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142340
142410
|
cached_m0_project_docs_hash TEXT,
|
|
142341
142411
|
cached_m1_bytes BLOB,
|
|
142342
142412
|
last_observed_model_key TEXT,
|
|
142413
|
+
last_usage_context_limit INTEGER NOT NULL DEFAULT 0,
|
|
142414
|
+
prior_boundary_ordinal INTEGER NOT NULL DEFAULT 1,
|
|
142415
|
+
protected_tail_policy_version INTEGER NOT NULL DEFAULT 0,
|
|
142416
|
+
protected_tail_drain_window_started_at INTEGER NOT NULL DEFAULT 0,
|
|
142417
|
+
protected_tail_drain_tokens INTEGER NOT NULL DEFAULT 0,
|
|
142418
|
+
recovery_no_eligible_head_count INTEGER NOT NULL DEFAULT 0,
|
|
142419
|
+
force_emergency_bypass_window_start INTEGER NOT NULL DEFAULT 0,
|
|
142420
|
+
force_emergency_bypass_used INTEGER NOT NULL DEFAULT 0,
|
|
142343
142421
|
cached_m0_materialized_at INTEGER,
|
|
142344
142422
|
cached_m0_session_facts_version INTEGER,
|
|
142345
142423
|
cached_m0_upgrade_state TEXT,
|
|
@@ -142450,6 +142528,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142450
142528
|
CREATE INDEX IF NOT EXISTS idx_message_history_index_updated_at ON message_history_index(updated_at);
|
|
142451
142529
|
`);
|
|
142452
142530
|
ensureColumn(db, "session_meta", "last_nudge_band", "TEXT DEFAULT ''");
|
|
142531
|
+
ensureColumn(db, "session_meta", "last_nudge_undropped", "INTEGER DEFAULT 0");
|
|
142532
|
+
ensureColumn(db, "session_meta", "last_nudge_level", "TEXT DEFAULT ''");
|
|
142533
|
+
ensureColumn(db, "session_meta", "channel2_nudge_state", "TEXT DEFAULT ''");
|
|
142534
|
+
ensureColumn(db, "session_meta", "channel2_nudge_claimed_at", "INTEGER DEFAULT 0");
|
|
142535
|
+
ensureColumn(db, "session_meta", "last_emergency_input_sample", "INTEGER DEFAULT 0");
|
|
142453
142536
|
ensureColumn(db, "session_meta", "last_transform_error", "TEXT DEFAULT ''");
|
|
142454
142537
|
ensureColumn(db, "session_meta", "nudge_anchor_message_id", "TEXT DEFAULT ''");
|
|
142455
142538
|
ensureColumn(db, "session_meta", "nudge_anchor_text", "TEXT DEFAULT ''");
|
|
@@ -142495,6 +142578,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142495
142578
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_tags_pi_adopt
|
|
142496
142579
|
ON tags(session_id, entry_fingerprint)
|
|
142497
142580
|
WHERE type='message' AND entry_fingerprint IS NOT NULL`);
|
|
142581
|
+
ensureColumn(db, "tags", "token_count", "INTEGER");
|
|
142582
|
+
ensureColumn(db, "tags", "input_token_count", "INTEGER");
|
|
142583
|
+
ensureColumn(db, "tags", "reasoning_token_count", "INTEGER");
|
|
142498
142584
|
ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
|
|
142499
142585
|
ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
|
|
142500
142586
|
ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
|
|
@@ -142535,6 +142621,14 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142535
142621
|
ensureColumn(db, "session_meta", "cached_m0_project_docs_hash", "TEXT");
|
|
142536
142622
|
ensureColumn(db, "session_meta", "cached_m1_bytes", "BLOB");
|
|
142537
142623
|
ensureColumn(db, "session_meta", "last_observed_model_key", "TEXT");
|
|
142624
|
+
ensureColumn(db, "session_meta", "last_usage_context_limit", "INTEGER NOT NULL DEFAULT 0");
|
|
142625
|
+
ensureColumn(db, "session_meta", "prior_boundary_ordinal", "INTEGER NOT NULL DEFAULT 1");
|
|
142626
|
+
ensureColumn(db, "session_meta", "protected_tail_policy_version", "INTEGER NOT NULL DEFAULT 0");
|
|
142627
|
+
ensureColumn(db, "session_meta", "protected_tail_drain_window_started_at", "INTEGER NOT NULL DEFAULT 0");
|
|
142628
|
+
ensureColumn(db, "session_meta", "protected_tail_drain_tokens", "INTEGER NOT NULL DEFAULT 0");
|
|
142629
|
+
ensureColumn(db, "session_meta", "recovery_no_eligible_head_count", "INTEGER NOT NULL DEFAULT 0");
|
|
142630
|
+
ensureColumn(db, "session_meta", "force_emergency_bypass_window_start", "INTEGER NOT NULL DEFAULT 0");
|
|
142631
|
+
ensureColumn(db, "session_meta", "force_emergency_bypass_used", "INTEGER NOT NULL DEFAULT 0");
|
|
142538
142632
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
142539
142633
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
142540
142634
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
@@ -142604,6 +142698,13 @@ function healAllNullColumns(db) {
|
|
|
142604
142698
|
healNullIntegerColumns(db);
|
|
142605
142699
|
healMissingMemoryBlockIds(db);
|
|
142606
142700
|
}
|
|
142701
|
+
var CHANNEL2_CLAIM_TTL_MS = 120000;
|
|
142702
|
+
function healWedgedChannel2Claims(db) {
|
|
142703
|
+
try {
|
|
142704
|
+
const staleBefore = Date.now() - CHANNEL2_CLAIM_TTL_MS;
|
|
142705
|
+
db.prepare("UPDATE session_meta SET channel2_nudge_state = 'pending', channel2_nudge_claimed_at = 0 WHERE channel2_nudge_state = 'claimed' AND (channel2_nudge_claimed_at IS NULL OR channel2_nudge_claimed_at = 0 OR channel2_nudge_claimed_at <= ?)").run(staleBefore);
|
|
142706
|
+
} catch {}
|
|
142707
|
+
}
|
|
142607
142708
|
function healMissingMemoryBlockIds(db) {
|
|
142608
142709
|
try {
|
|
142609
142710
|
db.prepare("UPDATE session_meta SET memory_block_cache = '' WHERE memory_block_cache != '' AND (memory_block_ids IS NULL OR memory_block_ids = '') AND memory_block_count > 0").run();
|
|
@@ -142613,6 +142714,7 @@ function healNullTextColumns(db) {
|
|
|
142613
142714
|
const columns = [
|
|
142614
142715
|
["cache_ttl", ""],
|
|
142615
142716
|
["last_nudge_band", ""],
|
|
142717
|
+
["last_nudge_level", ""],
|
|
142616
142718
|
["last_transform_error", ""],
|
|
142617
142719
|
["nudge_anchor_message_id", ""],
|
|
142618
142720
|
["nudge_anchor_text", ""],
|
|
@@ -142653,7 +142755,17 @@ function healNullIntegerColumns(db) {
|
|
|
142653
142755
|
["observed_safe_input_tokens", 0],
|
|
142654
142756
|
["cache_alert_sent", 0],
|
|
142655
142757
|
["new_work_tokens", 0],
|
|
142656
|
-
["total_input_tokens", 0]
|
|
142758
|
+
["total_input_tokens", 0],
|
|
142759
|
+
["last_emergency_input_sample", 0],
|
|
142760
|
+
["channel2_nudge_claimed_at", 0],
|
|
142761
|
+
["last_usage_context_limit", 0],
|
|
142762
|
+
["prior_boundary_ordinal", 1],
|
|
142763
|
+
["protected_tail_policy_version", 0],
|
|
142764
|
+
["protected_tail_drain_window_started_at", 0],
|
|
142765
|
+
["protected_tail_drain_tokens", 0],
|
|
142766
|
+
["recovery_no_eligible_head_count", 0],
|
|
142767
|
+
["force_emergency_bypass_window_start", 0],
|
|
142768
|
+
["force_emergency_bypass_used", 0]
|
|
142657
142769
|
];
|
|
142658
142770
|
for (const [column, fallback] of columns) {
|
|
142659
142771
|
try {
|
|
@@ -142692,6 +142804,7 @@ function openDatabase(dbPathOrOptions) {
|
|
|
142692
142804
|
if (!persistenceByDatabase.has(existing)) {
|
|
142693
142805
|
persistenceByDatabase.set(existing, true);
|
|
142694
142806
|
}
|
|
142807
|
+
healWedgedChannel2Claims(existing);
|
|
142695
142808
|
return existing;
|
|
142696
142809
|
}
|
|
142697
142810
|
try {
|
|
@@ -142717,6 +142830,7 @@ function openDatabase(dbPathOrOptions) {
|
|
|
142717
142830
|
log(`[magic-context] key-files orphan GC failed: ${getErrorMessage(error)}`);
|
|
142718
142831
|
}
|
|
142719
142832
|
}
|
|
142833
|
+
healWedgedChannel2Claims(db);
|
|
142720
142834
|
if (!explicitDbPath) {
|
|
142721
142835
|
try {
|
|
142722
142836
|
runToolOwnerBackfill(db);
|
|
@@ -142737,6 +142851,9 @@ function openDatabase(dbPathOrOptions) {
|
|
|
142737
142851
|
}
|
|
142738
142852
|
}
|
|
142739
142853
|
|
|
142854
|
+
// src/subagent-entry.ts
|
|
142855
|
+
init_logger();
|
|
142856
|
+
|
|
142740
142857
|
// ../plugin/src/config/prune-config-leaf.ts
|
|
142741
142858
|
function isPlainObject(value) {
|
|
142742
142859
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -142915,6 +143032,10 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
142915
143032
|
delete projectRaw.auto_update;
|
|
142916
143033
|
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
142917
143034
|
}
|
|
143035
|
+
if ("sqlite" in projectRaw) {
|
|
143036
|
+
delete projectRaw.sqlite;
|
|
143037
|
+
warnings.push("Ignoring sqlite.* from project config (security: SQLite cache/mmap PRAGMAs apply to the " + "process-global shared database handle; only user-level config may set them).");
|
|
143038
|
+
}
|
|
142918
143039
|
for (const agentKey of HIDDEN_AGENT_KEYS) {
|
|
142919
143040
|
const block = projectRaw[agentKey];
|
|
142920
143041
|
if (!isPlainObject2(block))
|
|
@@ -157273,7 +157394,6 @@ var AgentOverrideConfigSchema = exports_external.object({
|
|
|
157273
157394
|
});
|
|
157274
157395
|
|
|
157275
157396
|
// ../plugin/src/config/schema/magic-context.ts
|
|
157276
|
-
var DEFAULT_NUDGE_INTERVAL_TOKENS = 1e4;
|
|
157277
157397
|
var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
|
|
157278
157398
|
var EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 80% for cache safety: a single large agent step can overflow the context window before Magic Context can compact between turns, forcing OpenCode's native compaction (hard to recover from). 80% also leaves headroom below the 85%/95% emergency bands. Use a value between 20 and 80.";
|
|
157279
157399
|
var DEFAULT_HISTORIAN_TIMEOUT_MS = 300000;
|
|
@@ -157372,7 +157492,6 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
157372
157492
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
157373
157493
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
157374
157494
|
cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m").describe('Cache TTL: string (e.g. "5m") or per-model object ({ default: "5m", "model-id": "10m" })'),
|
|
157375
|
-
nudge_interval_tokens: exports_external.number().min(1000).default(DEFAULT_NUDGE_INTERVAL_TOKENS).describe("Minimum token growth between low-priority rolling nudges (default: DEFAULT_NUDGE_INTERVAL_TOKENS)"),
|
|
157376
157495
|
execute_threshold_percentage: exports_external.union([
|
|
157377
157496
|
exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE),
|
|
157378
157497
|
exports_external.object({ default: exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE) }).catchall(exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE))
|
|
@@ -157381,10 +157500,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
157381
157500
|
default: exports_external.number().min(5000).max(2000000).optional()
|
|
157382
157501
|
}).catchall(exports_external.number().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 80% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
|
|
157383
157502
|
protected_tags: exports_external.number().min(1).max(100).optional().describe("Number of recent tags to protect from dropping (min: 1, max: 100, default: 20)"),
|
|
157384
|
-
auto_drop_tool_age: exports_external.number().min(10).default(100).describe("Auto-drop tool outputs older than N tags during queue execution (default: 100)"),
|
|
157385
|
-
drop_tool_structure: exports_external.boolean().default(true).describe("When true, dropped tool parts are fully removed instead of truncated in place (default: true)"),
|
|
157386
157503
|
clear_reasoning_age: exports_external.number().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
|
|
157387
|
-
iteration_nudge_threshold: exports_external.number().min(5).default(15).describe("Number of consecutive assistant messages without user input to trigger iteration nudge (default: 15)"),
|
|
157388
157504
|
history_budget_percentage: exports_external.number().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
|
|
157389
157505
|
historian_timeout_ms: exports_external.number().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in milliseconds (default: 300000)"),
|
|
157390
157506
|
commit_cluster_trigger: exports_external.object({
|
|
@@ -157887,6 +158003,9 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
157887
158003
|
};
|
|
157888
158004
|
}
|
|
157889
158005
|
|
|
158006
|
+
// ../plugin/src/features/magic-context/memory/embedding.ts
|
|
158007
|
+
init_logger();
|
|
158008
|
+
|
|
157890
158009
|
// ../plugin/src/features/magic-context/memory/cosine-similarity.ts
|
|
157891
158010
|
function cosineSimilarity(a, b) {
|
|
157892
158011
|
if (a.length !== b.length) {
|
|
@@ -157942,6 +158061,8 @@ import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
|
157942
158061
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
157943
158062
|
import { dirname as dirname4, join as join6 } from "node:path";
|
|
157944
158063
|
import { pathToFileURL } from "node:url";
|
|
158064
|
+
init_data_path();
|
|
158065
|
+
init_logger();
|
|
157945
158066
|
var LOCK_POLL_MS = 150;
|
|
157946
158067
|
var STALE_LOCK_MS = 3 * 60000;
|
|
157947
158068
|
var MAX_LOCK_WAIT_MS = 5 * 60000;
|
|
@@ -158276,6 +158397,9 @@ class LocalEmbeddingProvider {
|
|
|
158276
158397
|
}
|
|
158277
158398
|
}
|
|
158278
158399
|
|
|
158400
|
+
// ../plugin/src/features/magic-context/memory/embedding-openai.ts
|
|
158401
|
+
init_logger();
|
|
158402
|
+
|
|
158279
158403
|
// ../plugin/src/features/magic-context/memory/embedding-ssrf.ts
|
|
158280
158404
|
var METADATA_HOSTNAMES = new Set(["metadata.google.internal", "metadata.goog"]);
|
|
158281
158405
|
var IPV6_METADATA_HOSTS = new Set(["fd00:ec2::254"]);
|
|
@@ -158627,6 +158751,7 @@ function getDistinctStoredModelIds(db, projectPath) {
|
|
|
158627
158751
|
|
|
158628
158752
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
158629
158753
|
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
158754
|
+
init_logger();
|
|
158630
158755
|
|
|
158631
158756
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
158632
158757
|
var saveStatements = new WeakMap;
|
|
@@ -159383,6 +159508,7 @@ function storedPathBelongsToIdentity(storedProjectPath, projectIdentity) {
|
|
|
159383
159508
|
|
|
159384
159509
|
// ../plugin/src/plugin/embedding-bootstrap-helpers.ts
|
|
159385
159510
|
import { createHash as createHash5 } from "node:crypto";
|
|
159511
|
+
init_logger();
|
|
159386
159512
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
159387
159513
|
"embedding.api_key",
|
|
159388
159514
|
"embedding.endpoint",
|
|
@@ -159480,7 +159606,6 @@ async function ensureProjectRegisteredFromPiDirectory(directory, db) {
|
|
|
159480
159606
|
};
|
|
159481
159607
|
registerProjectEmbeddingAndMaybeWipe(db, projectIdentity, detailed.config.embedding, features, directory);
|
|
159482
159608
|
}
|
|
159483
|
-
|
|
159484
159609
|
// ../plugin/src/features/magic-context/compartment-lease.ts
|
|
159485
159610
|
var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
159486
159611
|
var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
|
|
@@ -159578,6 +159703,14 @@ var SESSION_META_SELECT_COLUMNS = [
|
|
|
159578
159703
|
"cached_m0_tool_set_hash",
|
|
159579
159704
|
"cached_m0_model_key",
|
|
159580
159705
|
"last_observed_model_key",
|
|
159706
|
+
"last_usage_context_limit",
|
|
159707
|
+
"prior_boundary_ordinal",
|
|
159708
|
+
"protected_tail_policy_version",
|
|
159709
|
+
"protected_tail_drain_window_started_at",
|
|
159710
|
+
"protected_tail_drain_tokens",
|
|
159711
|
+
"recovery_no_eligible_head_count",
|
|
159712
|
+
"force_emergency_bypass_window_start",
|
|
159713
|
+
"force_emergency_bypass_used",
|
|
159581
159714
|
"upgrade_reminded_at",
|
|
159582
159715
|
"pi_stable_id_scheme"
|
|
159583
159716
|
];
|
|
@@ -159617,6 +159750,14 @@ var META_COLUMNS = {
|
|
|
159617
159750
|
cachedM0ToolSetHash: "cached_m0_tool_set_hash",
|
|
159618
159751
|
cachedM0ModelKey: "cached_m0_model_key",
|
|
159619
159752
|
lastObservedModelKey: "last_observed_model_key",
|
|
159753
|
+
lastUsageContextLimit: "last_usage_context_limit",
|
|
159754
|
+
priorBoundaryOrdinal: "prior_boundary_ordinal",
|
|
159755
|
+
protectedTailPolicyVersion: "protected_tail_policy_version",
|
|
159756
|
+
protectedTailDrainWindowStartedAt: "protected_tail_drain_window_started_at",
|
|
159757
|
+
protectedTailDrainTokens: "protected_tail_drain_tokens",
|
|
159758
|
+
recoveryNoEligibleHeadCount: "recovery_no_eligible_head_count",
|
|
159759
|
+
forceEmergencyBypassWindowStart: "force_emergency_bypass_window_start",
|
|
159760
|
+
forceEmergencyBypassUsed: "force_emergency_bypass_used",
|
|
159620
159761
|
upgradeRemindedAt: "upgrade_reminded_at",
|
|
159621
159762
|
piStableIdScheme: "pi_stable_id_scheme"
|
|
159622
159763
|
};
|
|
@@ -159658,7 +159799,7 @@ function isSessionMetaRow(row) {
|
|
|
159658
159799
|
if (row === null || typeof row !== "object")
|
|
159659
159800
|
return false;
|
|
159660
159801
|
const r = row;
|
|
159661
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
159802
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.last_usage_context_limit) && isNumberOrNull(r.prior_boundary_ordinal) && isNumberOrNull(r.protected_tail_policy_version) && isNumberOrNull(r.protected_tail_drain_window_started_at) && isNumberOrNull(r.protected_tail_drain_tokens) && isNumberOrNull(r.recovery_no_eligible_head_count) && isNumberOrNull(r.force_emergency_bypass_window_start) && isNumberOrNull(r.force_emergency_bypass_used) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
159662
159803
|
}
|
|
159663
159804
|
function getDefaultSessionMeta(sessionId) {
|
|
159664
159805
|
return {
|
|
@@ -159698,6 +159839,14 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
159698
159839
|
cachedM0ToolSetHash: null,
|
|
159699
159840
|
cachedM0ModelKey: null,
|
|
159700
159841
|
lastObservedModelKey: null,
|
|
159842
|
+
lastUsageContextLimit: 0,
|
|
159843
|
+
priorBoundaryOrdinal: 1,
|
|
159844
|
+
protectedTailPolicyVersion: 0,
|
|
159845
|
+
protectedTailDrainWindowStartedAt: 0,
|
|
159846
|
+
protectedTailDrainTokens: 0,
|
|
159847
|
+
recoveryNoEligibleHeadCount: 0,
|
|
159848
|
+
forceEmergencyBypassWindowStart: 0,
|
|
159849
|
+
forceEmergencyBypassUsed: 0,
|
|
159701
159850
|
upgradeRemindedAt: null,
|
|
159702
159851
|
piStableIdScheme: null
|
|
159703
159852
|
};
|
|
@@ -159752,6 +159901,14 @@ function toSessionMeta(row) {
|
|
|
159752
159901
|
cachedM0ToolSetHash: stringOrNull(row.cached_m0_tool_set_hash),
|
|
159753
159902
|
cachedM0ModelKey: stringOrNull(row.cached_m0_model_key),
|
|
159754
159903
|
lastObservedModelKey: stringOrNull(row.last_observed_model_key),
|
|
159904
|
+
lastUsageContextLimit: numOrZero(row.last_usage_context_limit),
|
|
159905
|
+
priorBoundaryOrdinal: Math.max(1, numOrZero(row.prior_boundary_ordinal) || 1),
|
|
159906
|
+
protectedTailPolicyVersion: numOrZero(row.protected_tail_policy_version),
|
|
159907
|
+
protectedTailDrainWindowStartedAt: numOrZero(row.protected_tail_drain_window_started_at),
|
|
159908
|
+
protectedTailDrainTokens: numOrZero(row.protected_tail_drain_tokens),
|
|
159909
|
+
recoveryNoEligibleHeadCount: numOrZero(row.recovery_no_eligible_head_count),
|
|
159910
|
+
forceEmergencyBypassWindowStart: numOrZero(row.force_emergency_bypass_window_start),
|
|
159911
|
+
forceEmergencyBypassUsed: numOrZero(row.force_emergency_bypass_used),
|
|
159755
159912
|
upgradeRemindedAt: numOrNull(row.upgrade_reminded_at),
|
|
159756
159913
|
piStableIdScheme: numOrNull(row.pi_stable_id_scheme)
|
|
159757
159914
|
};
|
|
@@ -159772,9 +159929,8 @@ function persistCachedM0(db, sessionId, payload) {
|
|
|
159772
159929
|
cached_m0_session_facts_version = ?,
|
|
159773
159930
|
cached_m0_upgrade_state = ?,
|
|
159774
159931
|
cached_m0_system_hash = ?,
|
|
159775
|
-
cached_m0_tool_set_hash = ?,
|
|
159776
159932
|
cached_m0_model_key = ?
|
|
159777
|
-
WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.projectMemoryEpoch, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.
|
|
159933
|
+
WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.projectMemoryEpoch, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.modelKey ?? "", sessionId);
|
|
159778
159934
|
}
|
|
159779
159935
|
function clearCachedM0M1(db, sessionId) {
|
|
159780
159936
|
ensureSessionMetaRow(db, sessionId);
|
|
@@ -159872,6 +160028,11 @@ function getLastCompartmentEndMessage(db, sessionId) {
|
|
|
159872
160028
|
const row = db.prepare("SELECT MAX(end_message) as max_end FROM compartments WHERE session_id = ?").get(sessionId);
|
|
159873
160029
|
return row?.max_end ?? -1;
|
|
159874
160030
|
}
|
|
160031
|
+
function getLastCompartmentEndMessageId(db, sessionId) {
|
|
160032
|
+
const row = db.prepare("SELECT end_message_id FROM compartments WHERE session_id = ? ORDER BY sequence DESC LIMIT 1").get(sessionId);
|
|
160033
|
+
const id = row?.end_message_id;
|
|
160034
|
+
return id && id.length > 0 ? id : null;
|
|
160035
|
+
}
|
|
159875
160036
|
function getCompartmentsByEndMessageId(db, sessionId, endMessageId) {
|
|
159876
160037
|
const rows = db.prepare("SELECT * FROM compartments WHERE session_id = ? AND end_message_id = ? ORDER BY sequence ASC").all(sessionId, endMessageId).filter(isCompartmentRow);
|
|
159877
160038
|
return rows.map(toCompartment);
|
|
@@ -159974,6 +160135,8 @@ function escapeXmlContent(s) {
|
|
|
159974
160135
|
}
|
|
159975
160136
|
|
|
159976
160137
|
// ../plugin/src/hooks/magic-context/read-session-db.ts
|
|
160138
|
+
init_data_path();
|
|
160139
|
+
init_logger();
|
|
159977
160140
|
import { existsSync as existsSync6 } from "node:fs";
|
|
159978
160141
|
import { join as join7 } from "node:path";
|
|
159979
160142
|
function getOpenCodeDbPath() {
|
|
@@ -160046,13 +160209,27 @@ function parseJsonUnknown(value) {
|
|
|
160046
160209
|
return null;
|
|
160047
160210
|
}
|
|
160048
160211
|
}
|
|
160212
|
+
function attachRawPartVersion(value, timeUpdated) {
|
|
160213
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
160214
|
+
return value;
|
|
160215
|
+
if (typeof timeUpdated !== "number")
|
|
160216
|
+
return value;
|
|
160217
|
+
try {
|
|
160218
|
+
Object.defineProperty(value, "__magicContextPartUpdatedAt", {
|
|
160219
|
+
value: timeUpdated,
|
|
160220
|
+
enumerable: false,
|
|
160221
|
+
configurable: true
|
|
160222
|
+
});
|
|
160223
|
+
} catch {}
|
|
160224
|
+
return value;
|
|
160225
|
+
}
|
|
160049
160226
|
function readRawSessionMessagesFromDb(db, sessionId) {
|
|
160050
|
-
const messageRows = db.prepare("SELECT id, data FROM message WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawMessageRow);
|
|
160051
|
-
const partRows = db.prepare("SELECT message_id, data FROM part WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawPartRow);
|
|
160227
|
+
const messageRows = db.prepare("SELECT id, data, time_updated FROM message WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawMessageRow);
|
|
160228
|
+
const partRows = db.prepare("SELECT message_id, data, time_updated FROM part WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawPartRow);
|
|
160052
160229
|
const partsByMessageId = new Map;
|
|
160053
160230
|
for (const part of partRows) {
|
|
160054
160231
|
const list = partsByMessageId.get(part.message_id) ?? [];
|
|
160055
|
-
list.push(parseJsonUnknown(part.data));
|
|
160232
|
+
list.push(attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated));
|
|
160056
160233
|
partsByMessageId.set(part.message_id, list);
|
|
160057
160234
|
}
|
|
160058
160235
|
const filtered = messageRows.filter((row) => {
|
|
@@ -160068,10 +160245,63 @@ function readRawSessionMessagesFromDb(db, sessionId) {
|
|
|
160068
160245
|
ordinal: index + 1,
|
|
160069
160246
|
id: row.id,
|
|
160070
160247
|
role,
|
|
160071
|
-
parts: partsByMessageId.get(row.id) ?? []
|
|
160248
|
+
parts: partsByMessageId.get(row.id) ?? [],
|
|
160249
|
+
version: row.time_updated ?? null
|
|
160072
160250
|
};
|
|
160073
160251
|
});
|
|
160074
160252
|
}
|
|
160253
|
+
function isAnchorRow(row) {
|
|
160254
|
+
return row !== null && typeof row === "object" && typeof row.time_created === "number" && typeof row.id === "string";
|
|
160255
|
+
}
|
|
160256
|
+
function readRawSessionTailFromDb(db, sessionId, baseOrdinal, anchorMessageId) {
|
|
160257
|
+
const anchorRow = db.prepare("SELECT time_created, id, data FROM message WHERE id = ? AND session_id = ?").get(anchorMessageId, sessionId);
|
|
160258
|
+
if (!isAnchorRow(anchorRow))
|
|
160259
|
+
return null;
|
|
160260
|
+
const anchorInfo = parseJsonRecord(anchorRow.data ?? "");
|
|
160261
|
+
if (anchorInfo?.summary === true && anchorInfo?.finish === "stop")
|
|
160262
|
+
return null;
|
|
160263
|
+
const messageRows = db.prepare(`SELECT id, data, time_updated FROM message
|
|
160264
|
+
WHERE session_id = ?
|
|
160265
|
+
AND (time_created > ? OR (time_created = ? AND id >= ?))
|
|
160266
|
+
ORDER BY time_created ASC, id ASC`).all(sessionId, anchorRow.time_created, anchorRow.time_created, anchorRow.id).filter(isRawMessageRow);
|
|
160267
|
+
const filtered = messageRows.filter((row) => {
|
|
160268
|
+
const info = parseJsonRecord(row.data);
|
|
160269
|
+
return !(info?.summary === true && info?.finish === "stop");
|
|
160270
|
+
});
|
|
160271
|
+
const ids = filtered.map((row) => row.id);
|
|
160272
|
+
const partsByMessageId = new Map;
|
|
160273
|
+
if (ids.length > 0) {
|
|
160274
|
+
const CHUNK = 800;
|
|
160275
|
+
for (let i = 0;i < ids.length; i += CHUNK) {
|
|
160276
|
+
const slice = ids.slice(i, i + CHUNK);
|
|
160277
|
+
const placeholders = slice.map(() => "?").join(",");
|
|
160278
|
+
const partRows = db.prepare(`SELECT message_id, data, time_updated FROM part WHERE session_id = ? AND message_id IN (${placeholders}) ORDER BY time_created ASC, id ASC`).all(sessionId, ...slice).filter(isRawPartRow);
|
|
160279
|
+
for (const part of partRows) {
|
|
160280
|
+
const list = partsByMessageId.get(part.message_id) ?? [];
|
|
160281
|
+
list.push(attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated));
|
|
160282
|
+
partsByMessageId.set(part.message_id, list);
|
|
160283
|
+
}
|
|
160284
|
+
}
|
|
160285
|
+
}
|
|
160286
|
+
const messages = [];
|
|
160287
|
+
let ord = baseOrdinal;
|
|
160288
|
+
for (const row of filtered) {
|
|
160289
|
+
const info = parseJsonRecord(row.data);
|
|
160290
|
+
if (!info) {
|
|
160291
|
+
ord += 1;
|
|
160292
|
+
continue;
|
|
160293
|
+
}
|
|
160294
|
+
messages.push({
|
|
160295
|
+
ordinal: ord,
|
|
160296
|
+
id: row.id,
|
|
160297
|
+
role: typeof info.role === "string" ? info.role : "unknown",
|
|
160298
|
+
parts: partsByMessageId.get(row.id) ?? [],
|
|
160299
|
+
version: row.time_updated ?? null
|
|
160300
|
+
});
|
|
160301
|
+
ord += 1;
|
|
160302
|
+
}
|
|
160303
|
+
return { messages, absoluteMessageCount: Math.max(0, ord - 1) };
|
|
160304
|
+
}
|
|
160075
160305
|
|
|
160076
160306
|
// ../plugin/src/hooks/magic-context/tag-content-primitives.ts
|
|
160077
160307
|
var encoder = new TextEncoder;
|
|
@@ -160216,6 +160446,7 @@ class ToolMutationBatch {
|
|
|
160216
160446
|
|
|
160217
160447
|
// ../plugin/src/hooks/magic-context/read-session-chunk.ts
|
|
160218
160448
|
var activeRawMessageCache = null;
|
|
160449
|
+
var activeAbsoluteCountCache = null;
|
|
160219
160450
|
var sessionProviders = new Map;
|
|
160220
160451
|
function setRawMessageProvider(sessionId, provider2) {
|
|
160221
160452
|
sessionProviders.set(sessionId, provider2);
|
|
@@ -160247,12 +160478,14 @@ function withRawSessionMessageCache(fn) {
|
|
|
160247
160478
|
const outerCache = activeRawMessageCache;
|
|
160248
160479
|
if (!outerCache) {
|
|
160249
160480
|
activeRawMessageCache = new Map;
|
|
160481
|
+
activeAbsoluteCountCache = new Map;
|
|
160250
160482
|
}
|
|
160251
160483
|
try {
|
|
160252
160484
|
return fn();
|
|
160253
160485
|
} finally {
|
|
160254
160486
|
if (!outerCache) {
|
|
160255
160487
|
activeRawMessageCache = null;
|
|
160488
|
+
activeAbsoluteCountCache = null;
|
|
160256
160489
|
}
|
|
160257
160490
|
}
|
|
160258
160491
|
}
|
|
@@ -160268,6 +160501,40 @@ function readRawSessionMessages(sessionId) {
|
|
|
160268
160501
|
}
|
|
160269
160502
|
return readRawSessionMessagesFromSource(sessionId);
|
|
160270
160503
|
}
|
|
160504
|
+
function primeTailRawMessageCache(args) {
|
|
160505
|
+
const { sessionId, lastCompartmentEnd, anchorMessageId } = args;
|
|
160506
|
+
if (!activeRawMessageCache)
|
|
160507
|
+
return false;
|
|
160508
|
+
if (activeRawMessageCache.has(sessionId))
|
|
160509
|
+
return false;
|
|
160510
|
+
if (sessionProviders.has(sessionId))
|
|
160511
|
+
return false;
|
|
160512
|
+
if (!openCodeDbExists())
|
|
160513
|
+
return false;
|
|
160514
|
+
if (lastCompartmentEnd < 1 || !anchorMessageId)
|
|
160515
|
+
return false;
|
|
160516
|
+
const result = withReadOnlySessionDb((db) => readRawSessionTailFromDb(db, sessionId, lastCompartmentEnd, anchorMessageId));
|
|
160517
|
+
if (!result)
|
|
160518
|
+
return false;
|
|
160519
|
+
activeRawMessageCache.set(sessionId, result.messages);
|
|
160520
|
+
activeAbsoluteCountCache?.set(sessionId, result.absoluteMessageCount);
|
|
160521
|
+
return true;
|
|
160522
|
+
}
|
|
160523
|
+
function getCachedAbsoluteMessageCount(sessionId) {
|
|
160524
|
+
return activeAbsoluteCountCache?.get(sessionId) ?? null;
|
|
160525
|
+
}
|
|
160526
|
+
function primeInMemoryTailRawMessageCache(args) {
|
|
160527
|
+
const { sessionId, messages, absoluteMessageCount } = args;
|
|
160528
|
+
if (!activeRawMessageCache)
|
|
160529
|
+
return false;
|
|
160530
|
+
if (activeRawMessageCache.has(sessionId))
|
|
160531
|
+
return false;
|
|
160532
|
+
if (sessionProviders.has(sessionId))
|
|
160533
|
+
return false;
|
|
160534
|
+
activeRawMessageCache.set(sessionId, messages);
|
|
160535
|
+
activeAbsoluteCountCache?.set(sessionId, absoluteMessageCount);
|
|
160536
|
+
return true;
|
|
160537
|
+
}
|
|
160271
160538
|
function readRawSessionMessagesFromSource(sessionId) {
|
|
160272
160539
|
const provider2 = sessionProviders.get(sessionId);
|
|
160273
160540
|
if (provider2)
|
|
@@ -160332,7 +160599,7 @@ function getRawSessionTagKeysThrough(sessionId, upToMessageIndex) {
|
|
|
160332
160599
|
return { messageFileKeys, toolObservations };
|
|
160333
160600
|
}
|
|
160334
160601
|
var PROTECTED_TAIL_USER_TURNS = 5;
|
|
160335
|
-
function
|
|
160602
|
+
function getLegacyProtectedTailStartOrdinal(sessionId) {
|
|
160336
160603
|
const messages = readRawSessionMessages(sessionId);
|
|
160337
160604
|
const userOrdinals = messages.filter((m) => m.role === "user" && hasMeaningfulUserText(m.parts)).map((m) => m.ordinal);
|
|
160338
160605
|
if (userOrdinals.length < PROTECTED_TAIL_USER_TURNS) {
|
|
@@ -160342,6 +160609,7 @@ function getProtectedTailStartOrdinal(sessionId) {
|
|
|
160342
160609
|
}
|
|
160343
160610
|
function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal) {
|
|
160344
160611
|
const messages = readRawSessionMessages(sessionId);
|
|
160612
|
+
const totalMessageCount = getCachedAbsoluteMessageCount(sessionId) ?? messages.length;
|
|
160345
160613
|
const startOrdinal = Math.max(1, offset);
|
|
160346
160614
|
const lines = [];
|
|
160347
160615
|
const lineMeta = [];
|
|
@@ -160469,7 +160737,7 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
160469
160737
|
endMessageId: lastMessageId,
|
|
160470
160738
|
messageCount: messagesProcessed,
|
|
160471
160739
|
tokenEstimate: totalTokens,
|
|
160472
|
-
hasMore: lastOrdinal < (eligibleEndOrdinal !== undefined ? Math.min(eligibleEndOrdinal - 1,
|
|
160740
|
+
hasMore: lastOrdinal < (eligibleEndOrdinal !== undefined ? Math.min(eligibleEndOrdinal - 1, totalMessageCount) : totalMessageCount),
|
|
160473
160741
|
text: lines.join(`
|
|
160474
160742
|
`),
|
|
160475
160743
|
lines: lineMeta,
|
|
@@ -160479,7 +160747,13 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
160479
160747
|
}
|
|
160480
160748
|
|
|
160481
160749
|
// ../plugin/src/tools/ctx-expand/constants.ts
|
|
160482
|
-
var CTX_EXPAND_DESCRIPTION =
|
|
160750
|
+
var CTX_EXPAND_DESCRIPTION = `Recover the original conversation from your compacted history.
|
|
160751
|
+
|
|
160752
|
+
Older parts of this session are summarized into <compartment> blocks inside <session-history> — e.g. <compartment start="120" end="245" title="Fixed tagger collision">. Each one replaces the raw messages in that ordinal range with a summary. When the summary isn't enough — you need exact wording, a specific value, an error message, or the reasoning behind a decision — expand the range:
|
|
160753
|
+
|
|
160754
|
+
ctx_expand(start=120, end=245) ← the compartment's own start/end attributes
|
|
160755
|
+
|
|
160756
|
+
Returns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results — expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail — already visible in context, not expandable.`;
|
|
160483
160757
|
var CTX_EXPAND_TOKEN_BUDGET = 15000;
|
|
160484
160758
|
|
|
160485
160759
|
// ../../node_modules/.bun/typebox@1.1.38/node_modules/typebox/build/system/memory/memory.mjs
|
|
@@ -164648,11 +164922,31 @@ function findLastModelKeyFromBranch(entries) {
|
|
|
164648
164922
|
}
|
|
164649
164923
|
return;
|
|
164650
164924
|
}
|
|
164925
|
+
function rawEntryVersion(entry) {
|
|
164926
|
+
const record4 = entry;
|
|
164927
|
+
const updated = record4.updatedAt ?? record4.updated_at ?? record4.timestamp;
|
|
164928
|
+
return typeof updated === "string" || typeof updated === "number" ? updated : entry.id;
|
|
164929
|
+
}
|
|
164930
|
+
function attachPiPartVersion(parts, version2) {
|
|
164931
|
+
return parts.map((part) => {
|
|
164932
|
+
if (part === null || typeof part !== "object" || Array.isArray(part))
|
|
164933
|
+
return part;
|
|
164934
|
+
try {
|
|
164935
|
+
Object.defineProperty(part, "__magicContextPartUpdatedAt", {
|
|
164936
|
+
value: version2,
|
|
164937
|
+
enumerable: false,
|
|
164938
|
+
configurable: true
|
|
164939
|
+
});
|
|
164940
|
+
} catch {}
|
|
164941
|
+
return part;
|
|
164942
|
+
});
|
|
164943
|
+
}
|
|
164651
164944
|
function convertEntriesToRawMessages(entries) {
|
|
164652
164945
|
const result = [];
|
|
164653
164946
|
let nextOrdinal = 1;
|
|
164654
164947
|
let pendingToolParts = [];
|
|
164655
164948
|
let pendingFirstRealId = "";
|
|
164949
|
+
let pendingFirstRealVersion = "";
|
|
164656
164950
|
for (const entry of entries) {
|
|
164657
164951
|
if (!isMessageEntry(entry)) {
|
|
164658
164952
|
continue;
|
|
@@ -164660,24 +164954,29 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164660
164954
|
const msg = entry.message;
|
|
164661
164955
|
const role = msg.role;
|
|
164662
164956
|
if (role === "toolResult") {
|
|
164663
|
-
|
|
164957
|
+
const version2 = rawEntryVersion(entry);
|
|
164958
|
+
pendingToolParts.push(...attachPiPartVersion(synthesizeToolResultParts(msg), version2));
|
|
164664
164959
|
if (pendingFirstRealId === "") {
|
|
164665
164960
|
pendingFirstRealId = entry.id;
|
|
164961
|
+
pendingFirstRealVersion = version2;
|
|
164666
164962
|
}
|
|
164667
164963
|
continue;
|
|
164668
164964
|
}
|
|
164669
164965
|
if (role === "user") {
|
|
164966
|
+
const version2 = rawEntryVersion(entry);
|
|
164670
164967
|
const parts = [
|
|
164671
164968
|
...pendingToolParts,
|
|
164672
|
-
...synthesizeUserParts(msg)
|
|
164969
|
+
...attachPiPartVersion(synthesizeUserParts(msg), version2)
|
|
164673
164970
|
];
|
|
164674
164971
|
pendingToolParts = [];
|
|
164675
164972
|
pendingFirstRealId = "";
|
|
164973
|
+
pendingFirstRealVersion = "";
|
|
164676
164974
|
result.push({
|
|
164677
164975
|
ordinal: nextOrdinal++,
|
|
164678
164976
|
id: entry.id,
|
|
164679
164977
|
role: "user",
|
|
164680
|
-
parts
|
|
164978
|
+
parts,
|
|
164979
|
+
version: version2
|
|
164681
164980
|
});
|
|
164682
164981
|
continue;
|
|
164683
164982
|
}
|
|
@@ -164687,16 +164986,20 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164687
164986
|
ordinal: nextOrdinal++,
|
|
164688
164987
|
id: `${SYNTH_USER_ID_PREFIX}${pendingFirstRealId}`,
|
|
164689
164988
|
role: "user",
|
|
164690
|
-
parts: pendingToolParts
|
|
164989
|
+
parts: pendingToolParts,
|
|
164990
|
+
version: pendingFirstRealVersion
|
|
164691
164991
|
});
|
|
164692
164992
|
pendingToolParts = [];
|
|
164693
164993
|
pendingFirstRealId = "";
|
|
164994
|
+
pendingFirstRealVersion = "";
|
|
164694
164995
|
}
|
|
164996
|
+
const version2 = rawEntryVersion(entry);
|
|
164695
164997
|
result.push({
|
|
164696
164998
|
ordinal: nextOrdinal++,
|
|
164697
164999
|
id: entry.id,
|
|
164698
165000
|
role: "assistant",
|
|
164699
|
-
parts: synthesizeAssistantParts(msg)
|
|
165001
|
+
parts: attachPiPartVersion(synthesizeAssistantParts(msg), version2),
|
|
165002
|
+
version: version2
|
|
164700
165003
|
});
|
|
164701
165004
|
continue;
|
|
164702
165005
|
}
|
|
@@ -164704,7 +165007,8 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164704
165007
|
ordinal: nextOrdinal++,
|
|
164705
165008
|
id: entry.id,
|
|
164706
165009
|
role: typeof role === "string" ? role : "unknown",
|
|
164707
|
-
parts: []
|
|
165010
|
+
parts: [],
|
|
165011
|
+
version: rawEntryVersion(entry)
|
|
164708
165012
|
});
|
|
164709
165013
|
}
|
|
164710
165014
|
if (pendingToolParts.length > 0) {
|
|
@@ -164712,7 +165016,8 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164712
165016
|
ordinal: nextOrdinal,
|
|
164713
165017
|
id: `${SYNTH_USER_ID_PREFIX}${pendingFirstRealId}`,
|
|
164714
165018
|
role: "user",
|
|
164715
|
-
parts: pendingToolParts
|
|
165019
|
+
parts: pendingToolParts,
|
|
165020
|
+
version: pendingFirstRealVersion
|
|
164716
165021
|
});
|
|
164717
165022
|
}
|
|
164718
165023
|
return result;
|
|
@@ -164869,6 +165174,13 @@ function createCtxExpandTool(deps) {
|
|
|
164869
165174
|
}
|
|
164870
165175
|
|
|
164871
165176
|
// ../plugin/src/features/magic-context/memory/constants.ts
|
|
165177
|
+
var V2_MEMORY_CATEGORIES = [
|
|
165178
|
+
"PROJECT_RULES",
|
|
165179
|
+
"ARCHITECTURE",
|
|
165180
|
+
"CONSTRAINTS",
|
|
165181
|
+
"CONFIG_VALUES",
|
|
165182
|
+
"NAMING"
|
|
165183
|
+
];
|
|
164872
165184
|
var PROMOTABLE_CATEGORIES = [
|
|
164873
165185
|
"PROJECT_RULES",
|
|
164874
165186
|
"ARCHITECTURE",
|
|
@@ -164908,6 +165220,7 @@ var CATEGORY_DEFAULT_TTL = {
|
|
|
164908
165220
|
KNOWN_ISSUES: 30 * 24 * 60 * 60 * 1000
|
|
164909
165221
|
};
|
|
164910
165222
|
// ../plugin/src/features/magic-context/memory/embedding-backfill.ts
|
|
165223
|
+
init_logger();
|
|
164911
165224
|
async function ensureMemoryEmbeddings(args) {
|
|
164912
165225
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
164913
165226
|
if (!snapshot?.enabled) {
|
|
@@ -164945,6 +165258,9 @@ async function ensureMemoryEmbeddings(args) {
|
|
|
164945
165258
|
}
|
|
164946
165259
|
return args.existingEmbeddings;
|
|
164947
165260
|
}
|
|
165261
|
+
// ../plugin/src/features/magic-context/memory/promotion.ts
|
|
165262
|
+
init_logger();
|
|
165263
|
+
|
|
164948
165264
|
// ../plugin/src/features/magic-context/memory/storage-memory.ts
|
|
164949
165265
|
var COLUMN_MAP = {
|
|
164950
165266
|
id: "id",
|
|
@@ -165856,6 +166172,7 @@ function getMaxMemoryMutationId(db, projectPath) {
|
|
|
165856
166172
|
return row?.max_id ?? null;
|
|
165857
166173
|
}
|
|
165858
166174
|
// ../plugin/src/features/magic-context/storage-meta-persisted.ts
|
|
166175
|
+
init_logger();
|
|
165859
166176
|
var CAS_RETRY_LIMIT = 5;
|
|
165860
166177
|
var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
165861
166178
|
"below-threshold",
|
|
@@ -165865,12 +166182,6 @@ var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
|
165865
166182
|
"stacked",
|
|
165866
166183
|
"too-short"
|
|
165867
166184
|
]);
|
|
165868
|
-
function isPersistedStickyTurnReminderRow(row) {
|
|
165869
|
-
if (row === null || typeof row !== "object")
|
|
165870
|
-
return false;
|
|
165871
|
-
const r = row;
|
|
165872
|
-
return typeof r.sticky_turn_reminder_text === "string" && typeof r.sticky_turn_reminder_message_id === "string";
|
|
165873
|
-
}
|
|
165874
166185
|
function isPersistedNoteNudgeRow(row) {
|
|
165875
166186
|
if (row === null || typeof row !== "object")
|
|
165876
166187
|
return false;
|
|
@@ -165936,6 +166247,139 @@ function getDefaultHistorianFailureState() {
|
|
|
165936
166247
|
lastFailureAt: null
|
|
165937
166248
|
};
|
|
165938
166249
|
}
|
|
166250
|
+
var DEFAULT_PROTECTED_TAIL_META = {
|
|
166251
|
+
priorBoundaryOrdinal: 1,
|
|
166252
|
+
protectedTailPolicyVersion: 0,
|
|
166253
|
+
protectedTailDrainWindowStartedAt: 0,
|
|
166254
|
+
protectedTailDrainTokens: 0,
|
|
166255
|
+
recoveryNoEligibleHeadCount: 0,
|
|
166256
|
+
forceEmergencyBypassWindowStart: 0,
|
|
166257
|
+
forceEmergencyBypassUsed: 0
|
|
166258
|
+
};
|
|
166259
|
+
function toProtectedTailMeta(row) {
|
|
166260
|
+
if (row === null || typeof row !== "object")
|
|
166261
|
+
return { ...DEFAULT_PROTECTED_TAIL_META };
|
|
166262
|
+
const r = row;
|
|
166263
|
+
const numberOr = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
166264
|
+
return {
|
|
166265
|
+
priorBoundaryOrdinal: Math.max(1, numberOr(r.prior_boundary_ordinal, 1)),
|
|
166266
|
+
protectedTailPolicyVersion: numberOr(r.protected_tail_policy_version, 0),
|
|
166267
|
+
protectedTailDrainWindowStartedAt: numberOr(r.protected_tail_drain_window_started_at, 0),
|
|
166268
|
+
protectedTailDrainTokens: numberOr(r.protected_tail_drain_tokens, 0),
|
|
166269
|
+
recoveryNoEligibleHeadCount: numberOr(r.recovery_no_eligible_head_count, 0),
|
|
166270
|
+
forceEmergencyBypassWindowStart: numberOr(r.force_emergency_bypass_window_start, 0),
|
|
166271
|
+
forceEmergencyBypassUsed: numberOr(r.force_emergency_bypass_used, 0)
|
|
166272
|
+
};
|
|
166273
|
+
}
|
|
166274
|
+
function loadProtectedTailMeta(db, sessionId) {
|
|
166275
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166276
|
+
const row = db.prepare(`SELECT prior_boundary_ordinal, protected_tail_policy_version,
|
|
166277
|
+
protected_tail_drain_window_started_at, protected_tail_drain_tokens,
|
|
166278
|
+
recovery_no_eligible_head_count, force_emergency_bypass_window_start,
|
|
166279
|
+
force_emergency_bypass_used
|
|
166280
|
+
FROM session_meta WHERE session_id = ?`).get(sessionId);
|
|
166281
|
+
return toProtectedTailMeta(row);
|
|
166282
|
+
}
|
|
166283
|
+
function markProtectedTailPolicyV3Seeded(db, sessionId, priorBoundaryOrdinal) {
|
|
166284
|
+
let seeded = false;
|
|
166285
|
+
db.transaction(() => {
|
|
166286
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166287
|
+
const existing = loadProtectedTailMeta(db, sessionId);
|
|
166288
|
+
if (existing.protectedTailPolicyVersion < 3) {
|
|
166289
|
+
db.prepare(`UPDATE session_meta
|
|
166290
|
+
SET prior_boundary_ordinal = ?, protected_tail_policy_version = 3
|
|
166291
|
+
WHERE session_id = ? AND protected_tail_policy_version < 3`).run(Math.max(1, Math.floor(priorBoundaryOrdinal)), sessionId);
|
|
166292
|
+
seeded = true;
|
|
166293
|
+
}
|
|
166294
|
+
})();
|
|
166295
|
+
return { ...loadProtectedTailMeta(db, sessionId), seeded };
|
|
166296
|
+
}
|
|
166297
|
+
function recordProtectedTailPublicationFloor(db, sessionId, floorOrdinal) {
|
|
166298
|
+
db.transaction(() => {
|
|
166299
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166300
|
+
db.prepare(`UPDATE session_meta
|
|
166301
|
+
SET prior_boundary_ordinal = MAX(COALESCE(prior_boundary_ordinal, 1), ?),
|
|
166302
|
+
recovery_no_eligible_head_count = 0
|
|
166303
|
+
WHERE session_id = ?`).run(Math.max(1, Math.floor(floorOrdinal)), sessionId);
|
|
166304
|
+
})();
|
|
166305
|
+
}
|
|
166306
|
+
function recordProtectedTailNoEligibleHead(db, sessionId) {
|
|
166307
|
+
db.transaction(() => {
|
|
166308
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166309
|
+
db.prepare(`UPDATE session_meta
|
|
166310
|
+
SET recovery_no_eligible_head_count = COALESCE(recovery_no_eligible_head_count, 0) + 1
|
|
166311
|
+
WHERE session_id = ?`).run(sessionId);
|
|
166312
|
+
})();
|
|
166313
|
+
return loadProtectedTailMeta(db, sessionId).recoveryNoEligibleHeadCount;
|
|
166314
|
+
}
|
|
166315
|
+
var DRAIN_WINDOW_MS = 10 * 60 * 1000;
|
|
166316
|
+
function protectedTailWindowBudget(usagePercentage, usable, perRunCap) {
|
|
166317
|
+
if (usagePercentage >= 95)
|
|
166318
|
+
return Math.min(1e6, Math.max(4 * perRunCap, Math.round(0.5 * usable)));
|
|
166319
|
+
if (usagePercentage >= 80)
|
|
166320
|
+
return Math.min(750000, Math.max(3 * perRunCap, Math.round(0.35 * usable)));
|
|
166321
|
+
return Math.min(500000, Math.max(perRunCap, Math.round(0.2 * usable)));
|
|
166322
|
+
}
|
|
166323
|
+
function reserveProtectedTailDrainTokens(args) {
|
|
166324
|
+
const now = args.now ?? Date.now();
|
|
166325
|
+
const requested = Math.max(0, Math.floor(args.trueRawTokens));
|
|
166326
|
+
if (requested === 0) {
|
|
166327
|
+
return { ok: true, reservedTokens: 0, overQuotaBypass: false, reservation: null };
|
|
166328
|
+
}
|
|
166329
|
+
let result = {
|
|
166330
|
+
ok: false,
|
|
166331
|
+
reservedTokens: 0,
|
|
166332
|
+
overQuotaBypass: false,
|
|
166333
|
+
reservation: null,
|
|
166334
|
+
skippedReason: "quota exhausted"
|
|
166335
|
+
};
|
|
166336
|
+
args.db.transaction(() => {
|
|
166337
|
+
ensureSessionMetaRow(args.db, args.sessionId);
|
|
166338
|
+
let meta3 = loadProtectedTailMeta(args.db, args.sessionId);
|
|
166339
|
+
if (now - meta3.protectedTailDrainWindowStartedAt > DRAIN_WINDOW_MS) {
|
|
166340
|
+
args.db.prepare(`UPDATE session_meta
|
|
166341
|
+
SET protected_tail_drain_window_started_at = ?, protected_tail_drain_tokens = 0,
|
|
166342
|
+
force_emergency_bypass_window_start = ?, force_emergency_bypass_used = 0
|
|
166343
|
+
WHERE session_id = ?`).run(now, now, args.sessionId);
|
|
166344
|
+
meta3 = loadProtectedTailMeta(args.db, args.sessionId);
|
|
166345
|
+
}
|
|
166346
|
+
const budget = protectedTailWindowBudget(args.usagePercentage, args.usable, args.perRunCap);
|
|
166347
|
+
const remaining = Math.max(0, budget - meta3.protectedTailDrainTokens);
|
|
166348
|
+
let reserved = Math.min(requested, args.perRunCap, remaining);
|
|
166349
|
+
let bypass = false;
|
|
166350
|
+
const bypassWindowExpired = now - meta3.forceEmergencyBypassWindowStart > DRAIN_WINDOW_MS;
|
|
166351
|
+
const bypassUsed = bypassWindowExpired ? 0 : meta3.forceEmergencyBypassUsed;
|
|
166352
|
+
if (reserved <= 0 && args.usagePercentage >= 95 && bypassUsed === 0) {
|
|
166353
|
+
reserved = Math.min(requested, args.perRunCap);
|
|
166354
|
+
bypass = true;
|
|
166355
|
+
}
|
|
166356
|
+
if (reserved <= 0)
|
|
166357
|
+
return;
|
|
166358
|
+
args.db.prepare(`UPDATE session_meta
|
|
166359
|
+
SET protected_tail_drain_window_started_at = CASE WHEN protected_tail_drain_window_started_at = 0 THEN ? ELSE protected_tail_drain_window_started_at END,
|
|
166360
|
+
protected_tail_drain_tokens = COALESCE(protected_tail_drain_tokens, 0) + ?,
|
|
166361
|
+
force_emergency_bypass_window_start = CASE WHEN ? THEN ? ELSE force_emergency_bypass_window_start END,
|
|
166362
|
+
force_emergency_bypass_used = CASE WHEN ? THEN 1 ELSE force_emergency_bypass_used END
|
|
166363
|
+
WHERE session_id = ?`).run(now, reserved, bypass ? 1 : 0, now, bypass ? 1 : 0, args.sessionId);
|
|
166364
|
+
result = {
|
|
166365
|
+
ok: true,
|
|
166366
|
+
reservedTokens: reserved,
|
|
166367
|
+
overQuotaBypass: bypass,
|
|
166368
|
+
reservation: { sessionId: args.sessionId, runId: args.runId, tokens: reserved }
|
|
166369
|
+
};
|
|
166370
|
+
})();
|
|
166371
|
+
return result;
|
|
166372
|
+
}
|
|
166373
|
+
function rollbackProtectedTailDrainReservation(db, reservation) {
|
|
166374
|
+
if (!reservation || reservation.tokens <= 0)
|
|
166375
|
+
return;
|
|
166376
|
+
db.transaction(() => {
|
|
166377
|
+
ensureSessionMetaRow(db, reservation.sessionId);
|
|
166378
|
+
db.prepare(`UPDATE session_meta
|
|
166379
|
+
SET protected_tail_drain_tokens = MAX(0, COALESCE(protected_tail_drain_tokens, 0) - ?)
|
|
166380
|
+
WHERE session_id = ?`).run(reservation.tokens, reservation.sessionId);
|
|
166381
|
+
})();
|
|
166382
|
+
}
|
|
165939
166383
|
function setPersistedReasoningWatermark(db, sessionId, tagNumber) {
|
|
165940
166384
|
ensureSessionMetaRow(db, sessionId);
|
|
165941
166385
|
db.prepare("UPDATE session_meta SET cleared_reasoning_through_tag = ? WHERE session_id = ?").run(tagNumber, sessionId);
|
|
@@ -165943,27 +166387,95 @@ function setPersistedReasoningWatermark(db, sessionId, tagNumber) {
|
|
|
165943
166387
|
function clearPersistedReasoningWatermark(db, sessionId) {
|
|
165944
166388
|
setPersistedReasoningWatermark(db, sessionId, 0);
|
|
165945
166389
|
}
|
|
165946
|
-
function
|
|
165947
|
-
|
|
165948
|
-
|
|
165949
|
-
|
|
165950
|
-
|
|
165951
|
-
|
|
165952
|
-
|
|
165953
|
-
|
|
165954
|
-
|
|
165955
|
-
|
|
165956
|
-
|
|
165957
|
-
};
|
|
166390
|
+
function isEmergencyInputSampleRow(row) {
|
|
166391
|
+
return typeof row === "object" && row !== null && typeof row.last_emergency_input_sample === "number";
|
|
166392
|
+
}
|
|
166393
|
+
function getEmergencyInputSample(db, sessionId) {
|
|
166394
|
+
const result = db.prepare("SELECT last_emergency_input_sample FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166395
|
+
return isEmergencyInputSampleRow(result) ? result.last_emergency_input_sample : 0;
|
|
166396
|
+
}
|
|
166397
|
+
function setEmergencyDropSample(db, sessionId, inputSample) {
|
|
166398
|
+
db.transaction(() => {
|
|
166399
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166400
|
+
db.prepare("UPDATE session_meta SET last_emergency_input_sample = ? WHERE session_id = ?").run(Math.max(0, Math.round(inputSample)), sessionId);
|
|
166401
|
+
})();
|
|
166402
|
+
}
|
|
166403
|
+
function clearEmergencyDropSample(db, sessionId) {
|
|
166404
|
+
db.transaction(() => {
|
|
166405
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166406
|
+
db.prepare("UPDATE session_meta SET last_emergency_input_sample = 0 WHERE session_id = ?").run(sessionId);
|
|
166407
|
+
})();
|
|
166408
|
+
}
|
|
166409
|
+
function isLastNudgeUndroppedRow(row) {
|
|
166410
|
+
return typeof row === "object" && row !== null && typeof row.last_nudge_undropped === "number";
|
|
166411
|
+
}
|
|
166412
|
+
function isLastNudgeLevelRow(row) {
|
|
166413
|
+
return typeof row === "object" && row !== null && typeof row.last_nudge_level === "string";
|
|
166414
|
+
}
|
|
166415
|
+
function normalizeLastNudgeLevel(value) {
|
|
166416
|
+
return value === "gentle" || value === "firm" || value === "urgent" ? value : "";
|
|
166417
|
+
}
|
|
166418
|
+
function getLastNudgeUndropped(db, sessionId) {
|
|
166419
|
+
const result = db.prepare("SELECT last_nudge_undropped FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166420
|
+
return isLastNudgeUndroppedRow(result) ? result.last_nudge_undropped : 0;
|
|
166421
|
+
}
|
|
166422
|
+
function setLastNudgeUndropped(db, sessionId, value) {
|
|
166423
|
+
db.transaction(() => {
|
|
166424
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166425
|
+
db.prepare("UPDATE session_meta SET last_nudge_undropped = ? WHERE session_id = ?").run(Math.max(0, Math.round(value)), sessionId);
|
|
166426
|
+
})();
|
|
166427
|
+
}
|
|
166428
|
+
function getLastNudgeLevel(db, sessionId) {
|
|
166429
|
+
const result = db.prepare("SELECT last_nudge_level FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166430
|
+
return isLastNudgeLevelRow(result) ? normalizeLastNudgeLevel(result.last_nudge_level) : "";
|
|
165958
166431
|
}
|
|
165959
|
-
function
|
|
166432
|
+
function setLastNudgeLevel(db, sessionId, value) {
|
|
165960
166433
|
db.transaction(() => {
|
|
165961
166434
|
ensureSessionMetaRow(db, sessionId);
|
|
165962
|
-
db.prepare("UPDATE session_meta SET
|
|
166435
|
+
db.prepare("UPDATE session_meta SET last_nudge_level = ? WHERE session_id = ?").run(normalizeLastNudgeLevel(value), sessionId);
|
|
165963
166436
|
})();
|
|
165964
166437
|
}
|
|
165965
|
-
function
|
|
165966
|
-
db.
|
|
166438
|
+
function resetLastNudgeCycle(db, sessionId) {
|
|
166439
|
+
db.transaction(() => {
|
|
166440
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166441
|
+
db.prepare("UPDATE session_meta SET last_nudge_undropped = 0, last_nudge_level = '' WHERE session_id = ?").run(sessionId);
|
|
166442
|
+
})();
|
|
166443
|
+
}
|
|
166444
|
+
function resetLastNudgeCycleIfTailShrank(db, sessionId, measuredUndropped) {
|
|
166445
|
+
let changed = false;
|
|
166446
|
+
db.transaction(() => {
|
|
166447
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166448
|
+
const result = db.prepare("UPDATE session_meta SET last_nudge_undropped = 0, last_nudge_level = '' WHERE session_id = ? AND last_nudge_undropped > ?").run(sessionId, Math.max(0, Math.round(measuredUndropped)));
|
|
166449
|
+
changed = (result.changes ?? 0) > 0;
|
|
166450
|
+
})();
|
|
166451
|
+
return changed;
|
|
166452
|
+
}
|
|
166453
|
+
function isChannel2StateRow(row) {
|
|
166454
|
+
return typeof row === "object" && row !== null && typeof row.channel2_nudge_state === "string";
|
|
166455
|
+
}
|
|
166456
|
+
function getChannel2NudgeState(db, sessionId) {
|
|
166457
|
+
const result = db.prepare("SELECT channel2_nudge_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166458
|
+
if (!isChannel2StateRow(result))
|
|
166459
|
+
return "";
|
|
166460
|
+
const raw = result.channel2_nudge_state;
|
|
166461
|
+
return raw === "pending" || raw === "claimed" || raw === "delivered" ? raw : "";
|
|
166462
|
+
}
|
|
166463
|
+
function setChannel2NudgeState(db, sessionId, state) {
|
|
166464
|
+
db.transaction(() => {
|
|
166465
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166466
|
+
const claimedAt = state === "claimed" ? Date.now() : 0;
|
|
166467
|
+
db.prepare("UPDATE session_meta SET channel2_nudge_state = ?, channel2_nudge_claimed_at = ? WHERE session_id = ?").run(state, claimedAt, sessionId);
|
|
166468
|
+
})();
|
|
166469
|
+
}
|
|
166470
|
+
function casChannel2NudgeState(db, sessionId, from, to) {
|
|
166471
|
+
let changed = false;
|
|
166472
|
+
db.transaction(() => {
|
|
166473
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166474
|
+
const claimedAt = to === "claimed" ? Date.now() : 0;
|
|
166475
|
+
const result = db.prepare("UPDATE session_meta SET channel2_nudge_state = ?, channel2_nudge_claimed_at = ? WHERE session_id = ? AND channel2_nudge_state = ?").run(to, claimedAt, sessionId, from);
|
|
166476
|
+
changed = (result.changes ?? 0) > 0;
|
|
166477
|
+
})();
|
|
166478
|
+
return changed;
|
|
165967
166479
|
}
|
|
165968
166480
|
function getPersistedNoteNudge(db, sessionId) {
|
|
165969
166481
|
const result = db.prepare("SELECT note_nudge_trigger_pending, note_nudge_trigger_message_id, note_nudge_sticky_text, note_nudge_sticky_message_id FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
@@ -166187,7 +166699,11 @@ function recordOverflowDetected(db, sessionId, reportedLimit) {
|
|
|
166187
166699
|
function clearEmergencyRecovery(db, sessionId) {
|
|
166188
166700
|
db.transaction(() => {
|
|
166189
166701
|
ensureSessionMetaRow(db, sessionId);
|
|
166190
|
-
|
|
166702
|
+
try {
|
|
166703
|
+
db.prepare("UPDATE session_meta SET needs_emergency_recovery = 0, recovery_no_eligible_head_count = 0 WHERE session_id = ?").run(sessionId);
|
|
166704
|
+
} catch {
|
|
166705
|
+
db.prepare("UPDATE session_meta SET needs_emergency_recovery = 0 WHERE session_id = ?").run(sessionId);
|
|
166706
|
+
}
|
|
166191
166707
|
})();
|
|
166192
166708
|
}
|
|
166193
166709
|
function clearDetectedContextLimit(db, sessionId) {
|
|
@@ -166350,6 +166866,7 @@ function setSessionWorkMetrics(db, sessionId, newWorkTokens, totalInputTokens) {
|
|
|
166350
166866
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
166351
166867
|
|
|
166352
166868
|
// ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
|
|
166869
|
+
init_logger();
|
|
166353
166870
|
function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
166354
166871
|
try {
|
|
166355
166872
|
return withReadOnlySessionDb((openCodeDb) => {
|
|
@@ -166568,7 +167085,8 @@ function updateNote(db, noteId, updates, scope) {
|
|
|
166568
167085
|
sets.push("session_id = ?");
|
|
166569
167086
|
params.push(updates.sessionId);
|
|
166570
167087
|
}
|
|
166571
|
-
|
|
167088
|
+
const smartConditionChanged = existing.type === "smart" && updates.surfaceCondition !== undefined && updates.surfaceCondition !== existing.surfaceCondition;
|
|
167089
|
+
if (updates.status !== undefined && !smartConditionChanged) {
|
|
166572
167090
|
sets.push("status = ?");
|
|
166573
167091
|
params.push(updates.status);
|
|
166574
167092
|
}
|
|
@@ -166581,17 +167099,21 @@ function updateNote(db, noteId, updates, scope) {
|
|
|
166581
167099
|
sets.push("surface_condition = ?");
|
|
166582
167100
|
params.push(updates.surfaceCondition);
|
|
166583
167101
|
}
|
|
166584
|
-
if (
|
|
166585
|
-
sets.push("last_checked_at =
|
|
166586
|
-
|
|
166587
|
-
|
|
166588
|
-
|
|
166589
|
-
|
|
166590
|
-
|
|
166591
|
-
|
|
166592
|
-
|
|
166593
|
-
|
|
166594
|
-
|
|
167102
|
+
if (smartConditionChanged) {
|
|
167103
|
+
sets.push("status = 'pending'", "last_checked_at = NULL", "ready_at = NULL", "ready_reason = NULL");
|
|
167104
|
+
} else {
|
|
167105
|
+
if (updates.lastCheckedAt !== undefined) {
|
|
167106
|
+
sets.push("last_checked_at = ?");
|
|
167107
|
+
params.push(updates.lastCheckedAt);
|
|
167108
|
+
}
|
|
167109
|
+
if (updates.readyAt !== undefined) {
|
|
167110
|
+
sets.push("ready_at = ?");
|
|
167111
|
+
params.push(updates.readyAt);
|
|
167112
|
+
}
|
|
167113
|
+
if (updates.readyReason !== undefined) {
|
|
167114
|
+
sets.push("ready_reason = ?");
|
|
167115
|
+
params.push(updates.readyReason);
|
|
167116
|
+
}
|
|
166595
167117
|
}
|
|
166596
167118
|
}
|
|
166597
167119
|
if (sets.length === 1) {
|
|
@@ -166618,6 +167140,7 @@ function markNoteChecked(db, noteId) {
|
|
|
166618
167140
|
db.prepare("UPDATE notes SET last_checked_at = ?, updated_at = ? WHERE id = ? AND type = 'smart'").run(now, now, noteId);
|
|
166619
167141
|
}
|
|
166620
167142
|
// ../plugin/src/features/magic-context/storage-ops.ts
|
|
167143
|
+
init_logger();
|
|
166621
167144
|
var queuePendingOpStatements = new WeakMap;
|
|
166622
167145
|
var getPendingOpsStatements = new WeakMap;
|
|
166623
167146
|
var clearPendingOpsStatements = new WeakMap;
|
|
@@ -166780,7 +167303,7 @@ var getTagNumberByMessageIdStatements = new WeakMap;
|
|
|
166780
167303
|
function getInsertTagStatement(db) {
|
|
166781
167304
|
let stmt = insertTagStatements.get(db);
|
|
166782
167305
|
if (!stmt) {
|
|
166783
|
-
stmt = db.prepare("INSERT INTO tags (session_id, message_id, type, byte_size, reasoning_byte_size, tag_number, tool_name, input_byte_size, harness, tool_owner_message_id, entry_fingerprint) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
167306
|
+
stmt = db.prepare("INSERT INTO tags (session_id, message_id, type, byte_size, reasoning_byte_size, tag_number, tool_name, input_byte_size, harness, tool_owner_message_id, entry_fingerprint, token_count, input_token_count, reasoning_token_count) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
166784
167307
|
insertTagStatements.set(db, stmt);
|
|
166785
167308
|
}
|
|
166786
167309
|
return stmt;
|
|
@@ -166822,9 +167345,95 @@ function getUpdateTagInputByteSizeStatement(db) {
|
|
|
166822
167345
|
function updateTagByteSize(db, sessionId, tagNumber, newByteSize) {
|
|
166823
167346
|
getUpdateTagByteSizeStatement(db).run(newByteSize, sessionId, tagNumber);
|
|
166824
167347
|
}
|
|
167348
|
+
var CONTENT_ID_SUFFIX = /:(?:p|file)\d+$/;
|
|
167349
|
+
function ownerMessageIdForTagRow(row) {
|
|
167350
|
+
if (row.type === "tool") {
|
|
167351
|
+
return row.tool_owner_message_id ?? row.message_id;
|
|
167352
|
+
}
|
|
167353
|
+
return row.message_id.replace(CONTENT_ID_SUFFIX, "");
|
|
167354
|
+
}
|
|
167355
|
+
function getActiveTagTokenAggregate(db, sessionId) {
|
|
167356
|
+
const row = db.prepare(`SELECT
|
|
167357
|
+
COALESCE(SUM(CASE WHEN type != 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)
|
|
167358
|
+
+ COALESCE(SUM(COALESCE(reasoning_token_count, 0)), 0) AS conversation,
|
|
167359
|
+
COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) + COALESCE(input_token_count, 0) ELSE 0 END), 0) AS tool_call,
|
|
167360
|
+
COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0) AS tool_output,
|
|
167361
|
+
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
167362
|
+
FROM tags
|
|
167363
|
+
WHERE session_id = ? AND status = 'active'`).get(sessionId);
|
|
167364
|
+
return {
|
|
167365
|
+
conversation: row?.conversation ?? 0,
|
|
167366
|
+
toolCall: row?.tool_call ?? 0,
|
|
167367
|
+
toolOutput: row?.tool_output ?? 0,
|
|
167368
|
+
nullCount: row?.null_count ?? 0
|
|
167369
|
+
};
|
|
167370
|
+
}
|
|
167371
|
+
function getTriggerTagTokenUpperBound(db, sessionId) {
|
|
167372
|
+
const row = db.prepare(`SELECT
|
|
167373
|
+
COALESCE(SUM(COALESCE(token_count, 0) + COALESCE(input_token_count, 0) + COALESCE(reasoning_token_count, 0)), 0) AS bound,
|
|
167374
|
+
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
167375
|
+
FROM tags
|
|
167376
|
+
WHERE session_id = ? AND status IN ('active', 'dropped')`).get(sessionId);
|
|
167377
|
+
return { bound: row?.bound ?? 0, nullCount: row?.null_count ?? 0 };
|
|
167378
|
+
}
|
|
166825
167379
|
function updateTagInputByteSize(db, sessionId, tagNumber, newInputByteSize) {
|
|
166826
167380
|
getUpdateTagInputByteSizeStatement(db).run(newInputByteSize, sessionId, tagNumber);
|
|
166827
167381
|
}
|
|
167382
|
+
var updateTagTokenCountStatements = new WeakMap;
|
|
167383
|
+
var updateTagInputTokenCountStatements = new WeakMap;
|
|
167384
|
+
function getUpdateTagTokenCountStatement(db) {
|
|
167385
|
+
let stmt = updateTagTokenCountStatements.get(db);
|
|
167386
|
+
if (!stmt) {
|
|
167387
|
+
stmt = db.prepare("UPDATE tags SET token_count = ? WHERE session_id = ? AND tag_number = ?");
|
|
167388
|
+
updateTagTokenCountStatements.set(db, stmt);
|
|
167389
|
+
}
|
|
167390
|
+
return stmt;
|
|
167391
|
+
}
|
|
167392
|
+
function getUpdateTagInputTokenCountStatement(db) {
|
|
167393
|
+
let stmt = updateTagInputTokenCountStatements.get(db);
|
|
167394
|
+
if (!stmt) {
|
|
167395
|
+
stmt = db.prepare("UPDATE tags SET input_token_count = ? WHERE session_id = ? AND tag_number = ?");
|
|
167396
|
+
updateTagInputTokenCountStatements.set(db, stmt);
|
|
167397
|
+
}
|
|
167398
|
+
return stmt;
|
|
167399
|
+
}
|
|
167400
|
+
function updateTagTokenCount(db, sessionId, tagNumber, newTokenCount) {
|
|
167401
|
+
getUpdateTagTokenCountStatement(db).run(newTokenCount, sessionId, tagNumber);
|
|
167402
|
+
}
|
|
167403
|
+
function getAllStatusTagTokenTotalsFlat(db, sessionId) {
|
|
167404
|
+
const rows = db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
167405
|
+
FROM tags
|
|
167406
|
+
WHERE session_id = ?`).all(sessionId);
|
|
167407
|
+
const totals = new Map;
|
|
167408
|
+
const nullMessageIds = new Set;
|
|
167409
|
+
for (const row of rows) {
|
|
167410
|
+
if (row.type === "tool" && row.tool_owner_message_id === null)
|
|
167411
|
+
continue;
|
|
167412
|
+
const owner = ownerMessageIdForTagRow(row);
|
|
167413
|
+
if (row.token_count === null) {
|
|
167414
|
+
nullMessageIds.add(owner);
|
|
167415
|
+
totals.delete(owner);
|
|
167416
|
+
continue;
|
|
167417
|
+
}
|
|
167418
|
+
if (nullMessageIds.has(owner))
|
|
167419
|
+
continue;
|
|
167420
|
+
const weight = (row.token_count ?? 0) + (row.input_token_count ?? 0) + (row.reasoning_token_count ?? 0);
|
|
167421
|
+
totals.set(owner, (totals.get(owner) ?? 0) + weight);
|
|
167422
|
+
}
|
|
167423
|
+
return { totals, nullMessageIds };
|
|
167424
|
+
}
|
|
167425
|
+
function updateTagInputTokenCount(db, sessionId, tagNumber, newInputTokenCount) {
|
|
167426
|
+
getUpdateTagInputTokenCountStatement(db).run(newInputTokenCount, sessionId, tagNumber);
|
|
167427
|
+
}
|
|
167428
|
+
function tagTokenCountIsNull(db, sessionId, tagNumber) {
|
|
167429
|
+
const row = db.prepare("SELECT token_count FROM tags WHERE session_id = ? AND tag_number = ?").get(sessionId, tagNumber);
|
|
167430
|
+
return row !== undefined && row.token_count === null;
|
|
167431
|
+
}
|
|
167432
|
+
function backfillTagTokenCounts(db, sessionId, tagNumber, counts) {
|
|
167433
|
+
db.prepare(`UPDATE tags
|
|
167434
|
+
SET token_count = ?, input_token_count = ?, reasoning_token_count = ?
|
|
167435
|
+
WHERE session_id = ? AND tag_number = ? AND token_count IS NULL`).run(counts.tokenCount ?? null, counts.inputTokenCount ?? null, counts.reasoningTokenCount ?? null, sessionId, tagNumber);
|
|
167436
|
+
}
|
|
166828
167437
|
function getMaxTagNumberBySessionStatement(db) {
|
|
166829
167438
|
let stmt = getMaxTagNumberBySessionStatements.get(db);
|
|
166830
167439
|
if (!stmt) {
|
|
@@ -166877,8 +167486,8 @@ function isMaxTagNumberRow(row) {
|
|
|
166877
167486
|
const r = row;
|
|
166878
167487
|
return typeof r.max_tag_number === "number";
|
|
166879
167488
|
}
|
|
166880
|
-
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null, entryFingerprint = null) {
|
|
166881
|
-
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId, entryFingerprint);
|
|
167489
|
+
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null, entryFingerprint = null, tokenCounts = null) {
|
|
167490
|
+
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId, entryFingerprint, tokenCounts?.tokenCount ?? null, tokenCounts?.inputTokenCount ?? null, tokenCounts?.reasoningTokenCount ?? null);
|
|
166882
167491
|
return tagNumber;
|
|
166883
167492
|
}
|
|
166884
167493
|
function updateTagStatus(db, sessionId, tagId, status) {
|
|
@@ -166946,13 +167555,6 @@ function getTagsByNumbers(db, sessionId, tagNumbers) {
|
|
|
166946
167555
|
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND tag_number IN (${placeholders}) ORDER BY tag_number ASC, id ASC`).all(sessionId, ...tagNumbers).filter(isTagRow);
|
|
166947
167556
|
return rows.map(toTagEntry);
|
|
166948
167557
|
}
|
|
166949
|
-
function getTopNBySize(db, sessionId, n) {
|
|
166950
|
-
if (n <= 0) {
|
|
166951
|
-
return [];
|
|
166952
|
-
}
|
|
166953
|
-
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND status = 'active' ORDER BY byte_size DESC, tag_number ASC LIMIT ?`).all(sessionId, n).filter(isTagRow);
|
|
166954
|
-
return rows.map(toTagEntry);
|
|
166955
|
-
}
|
|
166956
167558
|
var getToolTagNumberByOwnerStatements = new WeakMap;
|
|
166957
167559
|
var getNullOwnerToolTagStatements = new WeakMap;
|
|
166958
167560
|
var adoptNullOwnerToolTagStatements = new WeakMap;
|
|
@@ -167018,44 +167620,43 @@ var ERROR_CLASSES = new Set([
|
|
|
167018
167620
|
"permission_denied",
|
|
167019
167621
|
"unknown"
|
|
167020
167622
|
]);
|
|
167623
|
+
// src/tools/ctx-memory.ts
|
|
167624
|
+
init_logger();
|
|
167625
|
+
|
|
167626
|
+
// ../plugin/src/tools/ctx-memory/constants.ts
|
|
167627
|
+
var CTX_MEMORY_DESCRIPTION = `Durable project knowledge shared across every session on this project.
|
|
167628
|
+
|
|
167629
|
+
Your active memories are already visible in <project-memory> (each with its id), and every future session starts with them — write one when you learn something future sessions must know: a project rule, an architectural fact, a hard-won constraint, a config value, or a naming convention. Keep each memory one standalone fact, phrased to make sense without this session's context.
|
|
167630
|
+
|
|
167631
|
+
Actions:
|
|
167632
|
+
- write: save a new memory (content + category).
|
|
167633
|
+
- update: rewrite one memory whose fact changed (ids: [one], content).
|
|
167634
|
+
- archive: retire wrong or obsolete memories (ids: [one or more], optional reason).
|
|
167635
|
+
- merge: collapse duplicates into one memory (ids: [two or more], content).
|
|
167636
|
+
|
|
167637
|
+
Example: ctx_memory(action="write", category="CONSTRAINTS", content="Pi stores sessions as JSONL under ~/.pi/agent/sessions/, not SQLite")`;
|
|
167638
|
+
|
|
167021
167639
|
// src/tools/ctx-memory.ts
|
|
167022
167640
|
var DEFAULT_LIST_LIMIT = 10;
|
|
167023
|
-
var
|
|
167024
|
-
|
|
167025
|
-
return VALID_CATEGORIES.has(value);
|
|
167026
|
-
}
|
|
167027
|
-
var ALL_ACTIONS = [
|
|
167028
|
-
"write",
|
|
167029
|
-
"delete",
|
|
167030
|
-
"list",
|
|
167031
|
-
"update",
|
|
167032
|
-
"merge",
|
|
167033
|
-
"archive"
|
|
167034
|
-
];
|
|
167035
|
-
var DREAMER_ONLY_ACTIONS = new Set([
|
|
167036
|
-
"list",
|
|
167037
|
-
"update",
|
|
167038
|
-
"merge",
|
|
167039
|
-
"archive"
|
|
167040
|
-
]);
|
|
167641
|
+
var ALL_ACTIONS = ["write", "archive", "update", "merge", "list"];
|
|
167642
|
+
var DREAMER_ONLY_ACTIONS = new Set(["list"]);
|
|
167041
167643
|
var ParamsSchema2 = exports_typebox.Object({
|
|
167042
|
-
action: exports_typebox.Union(ALL_ACTIONS.map((a) => exports_typebox.Literal(a)), { description: "
|
|
167644
|
+
action: exports_typebox.Union(ALL_ACTIONS.map((a) => exports_typebox.Literal(a)), { description: "What to do: write, update, archive, or merge" }),
|
|
167043
167645
|
content: exports_typebox.Optional(exports_typebox.String({
|
|
167044
|
-
description: "
|
|
167045
|
-
})),
|
|
167046
|
-
category: exports_typebox.Optional(exports_typebox.String({
|
|
167047
|
-
description: "Memory category (required for write, optional filter for list, optional override for merge). One of: " + CATEGORY_PRIORITY.join(", ")
|
|
167646
|
+
description: "The memory text — one standalone fact (required for write, update, merge)"
|
|
167048
167647
|
})),
|
|
167049
|
-
|
|
167050
|
-
description: "
|
|
167648
|
+
category: exports_typebox.Optional(exports_typebox.Union(V2_MEMORY_CATEGORIES.map((c) => exports_typebox.Literal(c)), {
|
|
167649
|
+
description: "What kind of fact this is (required for write; optional merge override)"
|
|
167051
167650
|
})),
|
|
167052
167651
|
ids: exports_typebox.Optional(exports_typebox.Array(exports_typebox.Number(), {
|
|
167053
|
-
description: "
|
|
167652
|
+
description: "Target memory id(s) from <project-memory>: update takes exactly one, archive one or more, merge two or more"
|
|
167054
167653
|
})),
|
|
167055
167654
|
limit: exports_typebox.Optional(exports_typebox.Number({
|
|
167056
|
-
description: "
|
|
167655
|
+
description: "Max results for list (default: 10)"
|
|
167057
167656
|
})),
|
|
167058
|
-
reason: exports_typebox.Optional(exports_typebox.String({
|
|
167657
|
+
reason: exports_typebox.Optional(exports_typebox.String({
|
|
167658
|
+
description: "Why the memory is being archived (optional, recommended)"
|
|
167659
|
+
}))
|
|
167059
167660
|
});
|
|
167060
167661
|
function ok2(text) {
|
|
167061
167662
|
return { content: [{ type: "text", text }], details: undefined };
|
|
@@ -167102,6 +167703,12 @@ function formatMemoryList(memories) {
|
|
|
167102
167703
|
].join(`
|
|
167103
167704
|
`);
|
|
167104
167705
|
}
|
|
167706
|
+
function isPrimaryMutableMemory(memory2) {
|
|
167707
|
+
return (memory2.status === "active" || memory2.status === "permanent") && memory2.supersededByMemoryId === null;
|
|
167708
|
+
}
|
|
167709
|
+
function inactiveMemoryError(id, action2) {
|
|
167710
|
+
return `Error: Memory with ID ${id} is archived or superseded; restore it before ${action2}.`;
|
|
167711
|
+
}
|
|
167105
167712
|
function queueEmbedding(args) {
|
|
167106
167713
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
167107
167714
|
if (!snapshot?.enabled)
|
|
@@ -167122,7 +167729,8 @@ function queueEmbedding(args) {
|
|
|
167122
167729
|
}
|
|
167123
167730
|
function createCtxMemoryTool(deps) {
|
|
167124
167731
|
const dreamerAllowed = deps.allowDreamerActions === true;
|
|
167125
|
-
const description = dreamerAllowed ?
|
|
167732
|
+
const description = dreamerAllowed ? `${CTX_MEMORY_DESCRIPTION}
|
|
167733
|
+
- list: enumerate stored memories (maintenance sessions).` : CTX_MEMORY_DESCRIPTION;
|
|
167126
167734
|
return {
|
|
167127
167735
|
name: "ctx_memory",
|
|
167128
167736
|
label: "Magic Context: Memory",
|
|
@@ -167143,13 +167751,10 @@ function createCtxMemoryTool(deps) {
|
|
|
167143
167751
|
const content = params.content?.trim();
|
|
167144
167752
|
if (!content)
|
|
167145
167753
|
return err2("Error: 'content' is required when action is 'write'.");
|
|
167146
|
-
const rawCategory = params.category
|
|
167754
|
+
const rawCategory = params.category;
|
|
167147
167755
|
if (!rawCategory) {
|
|
167148
167756
|
return err2("Error: 'category' is required when action is 'write'.");
|
|
167149
167757
|
}
|
|
167150
|
-
if (!isMemoryCategory2(rawCategory)) {
|
|
167151
|
-
return err2(`Error: Unknown memory category '${rawCategory}'. Valid: ${CATEGORY_PRIORITY.join(", ")}`);
|
|
167152
|
-
}
|
|
167153
167758
|
const existing = getMemoryByHash(deps.db, projectIdentity, rawCategory, computeNormalizedHash(content));
|
|
167154
167759
|
if (existing) {
|
|
167155
167760
|
updateMemorySeenCount(deps.db, existing.id);
|
|
@@ -167165,42 +167770,29 @@ function createCtxMemoryTool(deps) {
|
|
|
167165
167770
|
queueEmbedding({ deps, projectIdentity, memoryId: memory2.id, content });
|
|
167166
167771
|
return ok2(`Saved memory [ID: ${memory2.id}] in ${rawCategory}.`);
|
|
167167
167772
|
}
|
|
167168
|
-
if (params.action === "delete") {
|
|
167169
|
-
if (typeof params.id !== "number" || !Number.isInteger(params.id)) {
|
|
167170
|
-
return err2("Error: 'id' is required when action is 'delete'.");
|
|
167171
|
-
}
|
|
167172
|
-
const memory2 = getMemoryById(deps.db, params.id);
|
|
167173
|
-
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
167174
|
-
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
167175
|
-
}
|
|
167176
|
-
deps.db.transaction(() => {
|
|
167177
|
-
archiveMemory(deps.db, params.id);
|
|
167178
|
-
queueMemoryMutation(deps.db, {
|
|
167179
|
-
projectPath: projectIdentity,
|
|
167180
|
-
mutationType: "delete",
|
|
167181
|
-
targetMemoryId: params.id
|
|
167182
|
-
});
|
|
167183
|
-
})();
|
|
167184
|
-
return ok2(`Archived memory [ID: ${params.id}].`);
|
|
167185
|
-
}
|
|
167186
167773
|
if (params.action === "list") {
|
|
167187
167774
|
const limit = normalizeLimit(params.limit);
|
|
167188
167775
|
const filtered = getMemoriesByProject(deps.db, projectIdentity);
|
|
167189
|
-
const category = params.category
|
|
167776
|
+
const category = params.category;
|
|
167190
167777
|
const filtered2 = category ? filtered.filter((m) => m.category === category) : filtered;
|
|
167191
167778
|
return ok2(formatMemoryList(filtered2.slice(0, limit)));
|
|
167192
167779
|
}
|
|
167193
167780
|
if (params.action === "update") {
|
|
167194
|
-
|
|
167195
|
-
|
|
167781
|
+
const updateIds = params.ids;
|
|
167782
|
+
if (!updateIds || updateIds.length !== 1 || !updateIds.every(Number.isInteger)) {
|
|
167783
|
+
return err2("Error: 'ids' must contain exactly one integer memory ID when action is 'update'.");
|
|
167196
167784
|
}
|
|
167785
|
+
const updateId = updateIds[0];
|
|
167197
167786
|
const content = params.content?.trim();
|
|
167198
167787
|
if (!content) {
|
|
167199
167788
|
return err2("Error: 'content' is required when action is 'update'.");
|
|
167200
167789
|
}
|
|
167201
|
-
const memory2 = getMemoryById(deps.db,
|
|
167790
|
+
const memory2 = getMemoryById(deps.db, updateId);
|
|
167202
167791
|
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
167203
|
-
return err2(`Error: Memory with ID ${
|
|
167792
|
+
return err2(`Error: Memory with ID ${updateId} was not found.`);
|
|
167793
|
+
}
|
|
167794
|
+
if (!dreamerAllowed && !isPrimaryMutableMemory(memory2)) {
|
|
167795
|
+
return err2(inactiveMemoryError(updateId, "updating"));
|
|
167204
167796
|
}
|
|
167205
167797
|
const normalizedHash = computeNormalizedHash(content);
|
|
167206
167798
|
const duplicate = getMemoryByHash(deps.db, projectIdentity, memory2.category, normalizedHash);
|
|
@@ -167221,9 +167813,12 @@ function createCtxMemoryTool(deps) {
|
|
|
167221
167813
|
return ok2(`Updated memory [ID: ${memory2.id}] in ${memory2.category}.`);
|
|
167222
167814
|
}
|
|
167223
167815
|
if (params.action === "merge") {
|
|
167224
|
-
const ids = params.ids
|
|
167225
|
-
if (!ids || ids.length < 2) {
|
|
167226
|
-
return err2("Error: 'ids' must include at least two memory IDs when action is 'merge'.");
|
|
167816
|
+
const ids = params.ids;
|
|
167817
|
+
if (!ids || ids.length < 2 || !ids.every(Number.isInteger)) {
|
|
167818
|
+
return err2("Error: 'ids' must include at least two integer memory IDs when action is 'merge'.");
|
|
167819
|
+
}
|
|
167820
|
+
if (new Set(ids).size !== ids.length) {
|
|
167821
|
+
return err2("Error: 'ids' must include at least two distinct memory IDs when action is 'merge'.");
|
|
167227
167822
|
}
|
|
167228
167823
|
const content = params.content?.trim();
|
|
167229
167824
|
if (!content) {
|
|
@@ -167233,11 +167828,17 @@ function createCtxMemoryTool(deps) {
|
|
|
167233
167828
|
if (sourceMemories.length !== ids.length) {
|
|
167234
167829
|
return err2("Error: One or more source memories were not found.");
|
|
167235
167830
|
}
|
|
167236
|
-
|
|
167237
|
-
|
|
167238
|
-
|
|
167831
|
+
if (!dreamerAllowed) {
|
|
167832
|
+
const foreign = sourceMemories.find((memory2) => !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity));
|
|
167833
|
+
if (foreign) {
|
|
167834
|
+
return err2(`Error: Memory with ID ${foreign.id} was not found.`);
|
|
167835
|
+
}
|
|
167836
|
+
const inactive = sourceMemories.find((memory2) => !isPrimaryMutableMemory(memory2));
|
|
167837
|
+
if (inactive) {
|
|
167838
|
+
return err2(inactiveMemoryError(inactive.id, "merging"));
|
|
167839
|
+
}
|
|
167239
167840
|
}
|
|
167240
|
-
const requestedCategoryTyped =
|
|
167841
|
+
const requestedCategoryTyped = params.category;
|
|
167241
167842
|
const fallbackCategory = sourceMemories[0]?.category;
|
|
167242
167843
|
const category = requestedCategoryTyped ?? fallbackCategory;
|
|
167243
167844
|
if (!category) {
|
|
@@ -167317,29 +167918,57 @@ function createCtxMemoryTool(deps) {
|
|
|
167317
167918
|
return ok2(`Merged memories [${ids.join(", ")}] into canonical memory [ID: ${canonicalMemory.id}] in ${category}; superseded [${supersededIds.join(", ")}].`);
|
|
167318
167919
|
}
|
|
167319
167920
|
if (params.action === "archive") {
|
|
167320
|
-
|
|
167321
|
-
|
|
167921
|
+
const archiveIds = params.ids;
|
|
167922
|
+
if (!archiveIds || archiveIds.length === 0 || !archiveIds.every(Number.isInteger)) {
|
|
167923
|
+
return err2("Error: 'ids' must contain at least one integer memory ID when action is 'archive'.");
|
|
167322
167924
|
}
|
|
167323
|
-
const
|
|
167324
|
-
|
|
167325
|
-
|
|
167925
|
+
for (const memoryId of archiveIds) {
|
|
167926
|
+
const memory2 = getMemoryById(deps.db, memoryId);
|
|
167927
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
167928
|
+
return err2(`Error: Memory with ID ${memoryId} was not found.`);
|
|
167929
|
+
}
|
|
167930
|
+
if (!dreamerAllowed && !isPrimaryMutableMemory(memory2)) {
|
|
167931
|
+
return err2(inactiveMemoryError(memoryId, "archiving"));
|
|
167932
|
+
}
|
|
167326
167933
|
}
|
|
167327
167934
|
deps.db.transaction(() => {
|
|
167328
|
-
|
|
167329
|
-
|
|
167330
|
-
|
|
167331
|
-
|
|
167332
|
-
|
|
167333
|
-
|
|
167935
|
+
for (const memoryId of archiveIds) {
|
|
167936
|
+
archiveMemory(deps.db, memoryId, params.reason);
|
|
167937
|
+
queueMemoryMutation(deps.db, {
|
|
167938
|
+
projectPath: projectIdentity,
|
|
167939
|
+
mutationType: "archive",
|
|
167940
|
+
targetMemoryId: memoryId
|
|
167941
|
+
});
|
|
167942
|
+
}
|
|
167334
167943
|
})();
|
|
167335
167944
|
const reasonSuffix = params.reason ? ` (${params.reason})` : "";
|
|
167336
|
-
|
|
167945
|
+
const idList = archiveIds.join(", ");
|
|
167946
|
+
const plural = archiveIds.length > 1 ? "memories" : "memory";
|
|
167947
|
+
return ok2(`Archived ${plural} [ID: ${idList}]${reasonSuffix}.`);
|
|
167337
167948
|
}
|
|
167338
167949
|
return err2("Error: Unknown action.");
|
|
167339
167950
|
}
|
|
167340
167951
|
};
|
|
167341
167952
|
}
|
|
167342
167953
|
|
|
167954
|
+
// ../plugin/src/tools/ctx-note/constants.ts
|
|
167955
|
+
var CTX_NOTE_DESCRIPTION = `Working notes for this session's future — reminders, follow-ups, and things to revisit later.
|
|
167956
|
+
|
|
167957
|
+
Use a note when something matters LATER but not in the next few steps: "revisit the retry logic after the release", "user wants the dashboard polish batched", "flaky test to investigate when touching CI". Don't use notes for active multi-step work (use todos) or for durable project knowledge that should outlive this session (use ctx_memory). Notes resurface automatically at natural work boundaries and whenever you read them.
|
|
167958
|
+
|
|
167959
|
+
Actions:
|
|
167960
|
+
- write: save a note (content). Add surface_condition to make it a smart note (below).
|
|
167961
|
+
- read: list notes, newest first. Default: latest active session notes + ready smart notes; page older ones with limit/offset, or inspect other states with filter.
|
|
167962
|
+
- update / dismiss: change or retire a note by note_id.
|
|
167963
|
+
|
|
167964
|
+
Smart notes: pass surface_condition and the note stays hidden until a background checker confirms the condition — using ONLY externally verifiable signals (GitHub state via gh, files on disk, git history, web pages). It cannot see this conversation, so the condition must be checkable from outside:
|
|
167965
|
+
✓ "When PR #42 in cortexkit/magic-context is merged"
|
|
167966
|
+
✓ "When the latest release tag is >= v0.22.0"
|
|
167967
|
+
✓ "When packages/plugin/src/foo.ts contains a function named bar"
|
|
167968
|
+
✗ "When the user mentions X" / "when we revisit Y" / "after we finish this refactor" — no external signal; write a regular note instead.
|
|
167969
|
+
|
|
167970
|
+
Example: ctx_note(action="write", content="Re-run the perf benchmark once the boundary rework ships", surface_condition="When the latest release tag is >= v0.23.0")`;
|
|
167971
|
+
|
|
167343
167972
|
// src/tools/ctx-note.ts
|
|
167344
167973
|
var FILTER_VALUES = [
|
|
167345
167974
|
"active",
|
|
@@ -167359,13 +167988,19 @@ var ParamsSchema3 = exports_typebox.Object({
|
|
|
167359
167988
|
})),
|
|
167360
167989
|
content: exports_typebox.Optional(exports_typebox.String({ description: "Note text to store when action is 'write'." })),
|
|
167361
167990
|
surface_condition: exports_typebox.Optional(exports_typebox.String({
|
|
167362
|
-
description: "
|
|
167991
|
+
description: "Externally verifiable condition for smart notes. A background checker verifies it using ONLY outside signals (GitHub state via gh, files on disk, git history, web) — it cannot see this conversation. Use for PR/issue state, release tags, file contents, workflow runs. NOT for 'when the user mentions X' / 'when we revisit Y' — write a regular note instead."
|
|
167363
167992
|
})),
|
|
167364
167993
|
note_id: exports_typebox.Optional(exports_typebox.Number({
|
|
167365
167994
|
description: "Note ID (required for 'dismiss' and 'update' actions)."
|
|
167366
167995
|
})),
|
|
167367
167996
|
filter: exports_typebox.Optional(exports_typebox.Union(FILTER_VALUES.map((value) => exports_typebox.Literal(value)), {
|
|
167368
167997
|
description: "Optional read filter. Defaults to active session notes + ready smart notes. Use 'all' to inspect every status or 'pending' to inspect unsurfaced smart notes."
|
|
167998
|
+
})),
|
|
167999
|
+
limit: exports_typebox.Optional(exports_typebox.Number({
|
|
168000
|
+
description: "Max notes per section for read, newest first (default: 25)"
|
|
168001
|
+
})),
|
|
168002
|
+
offset: exports_typebox.Optional(exports_typebox.Number({
|
|
168003
|
+
description: "Skip this many newest notes for read — page older ones (default: 0)"
|
|
167369
168004
|
}))
|
|
167370
168005
|
});
|
|
167371
168006
|
function ok3(text) {
|
|
@@ -167402,15 +168037,20 @@ function formatNoteLine(note) {
|
|
|
167402
168037
|
var DISMISS_FOOTER = `
|
|
167403
168038
|
|
|
167404
168039
|
To dismiss a stale note: ctx_note(action="dismiss", note_id=N)`;
|
|
168040
|
+
var DEFAULT_READ_LIMIT = 25;
|
|
168041
|
+
function paginateNewestFirst(notes, limit, offset) {
|
|
168042
|
+
const total = notes.length;
|
|
168043
|
+
const newestFirst = [...notes].reverse();
|
|
168044
|
+
const page = newestFirst.slice(offset, offset + limit);
|
|
168045
|
+
const remaining = total - offset - page.length;
|
|
168046
|
+
const footer = remaining > 0 ? `Showing ${page.length} of ${total} (newest first) — ${remaining} older: ctx_note(action="read", offset=${offset + page.length})` : null;
|
|
168047
|
+
return { page, total, footer };
|
|
168048
|
+
}
|
|
167405
168049
|
function createCtxNoteTool(deps) {
|
|
167406
168050
|
return {
|
|
167407
168051
|
name: "ctx_note",
|
|
167408
168052
|
label: "Magic Context: Notes",
|
|
167409
|
-
description:
|
|
167410
|
-
` + `Use this for short goals, constraints, decisions, or reminders worth carrying forward.
|
|
167411
|
-
|
|
167412
|
-
` + `Actions:
|
|
167413
|
-
` + "- `write`: Append one note. Optionally provide `surface_condition` to create a smart note.\n" + "- `read`: Show current notes. Defaults to active session notes + ready smart notes; use `filter` to inspect all, pending, ready, active, or dismissed notes.\n" + "- `dismiss`: Dismiss a note by `note_id`.\n" + "- `update`: Update a note by `note_id`.\n\n" + "**Smart Notes**: When `surface_condition` is provided with `write`, the note becomes a project-scoped smart note. " + "The dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met. " + 'Example: `ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")`',
|
|
168053
|
+
description: CTX_NOTE_DESCRIPTION,
|
|
167414
168054
|
parameters: ParamsSchema3,
|
|
167415
168055
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
167416
168056
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
@@ -167492,11 +168132,15 @@ function createCtxNoteTool(deps) {
|
|
|
167492
168132
|
- ${parts.join(`
|
|
167493
168133
|
- `)}`);
|
|
167494
168134
|
}
|
|
168135
|
+
const limit = typeof params.limit === "number" && params.limit > 0 ? Math.floor(params.limit) : DEFAULT_READ_LIMIT;
|
|
168136
|
+
const offset = typeof params.offset === "number" && params.offset > 0 ? Math.floor(params.offset) : 0;
|
|
167495
168137
|
const sections = readNotes({
|
|
167496
168138
|
db: deps.db,
|
|
167497
168139
|
sessionId,
|
|
167498
168140
|
cwd: ctx.cwd,
|
|
167499
|
-
filter: params.filter
|
|
168141
|
+
filter: params.filter,
|
|
168142
|
+
limit,
|
|
168143
|
+
offset
|
|
167500
168144
|
});
|
|
167501
168145
|
try {
|
|
167502
168146
|
setNoteLastReadAt(deps.db, sessionId);
|
|
@@ -167504,7 +168148,7 @@ function createCtxNoteTool(deps) {
|
|
|
167504
168148
|
if (sections.length === 0) {
|
|
167505
168149
|
return ok3(`## Notes
|
|
167506
168150
|
|
|
167507
|
-
No notes
|
|
168151
|
+
No session notes or smart notes.`);
|
|
167508
168152
|
}
|
|
167509
168153
|
const body = sections.join(`
|
|
167510
168154
|
|
|
@@ -167531,10 +168175,14 @@ function readNotes(args) {
|
|
|
167531
168175
|
}) : [];
|
|
167532
168176
|
const sections2 = [];
|
|
167533
168177
|
if (sessionNotes2.length > 0) {
|
|
168178
|
+
const { page, footer } = paginateNewestFirst(sessionNotes2, args.limit, args.offset);
|
|
168179
|
+
const lines = page.map(formatNoteLine).join(`
|
|
168180
|
+
`);
|
|
167534
168181
|
sections2.push(`## Session Notes
|
|
167535
168182
|
|
|
167536
|
-
${
|
|
167537
|
-
|
|
168183
|
+
${lines}${footer ? `
|
|
168184
|
+
|
|
168185
|
+
${footer}` : ""}`);
|
|
167538
168186
|
}
|
|
167539
168187
|
if (readySmartNotes.length > 0) {
|
|
167540
168188
|
sections2.push(`## \uD83D\uDD14 Ready Smart Notes
|
|
@@ -167565,17 +168213,25 @@ ${readySmartNotes.map(formatNoteLine).join(`
|
|
|
167565
168213
|
}) : [];
|
|
167566
168214
|
const sections = [];
|
|
167567
168215
|
if (sessionNotes.length > 0) {
|
|
168216
|
+
const { page, footer } = paginateNewestFirst(sessionNotes, args.limit, args.offset);
|
|
168217
|
+
const lines = page.map(formatNoteLine).join(`
|
|
168218
|
+
`);
|
|
167568
168219
|
sections.push(`## Session Notes
|
|
167569
168220
|
|
|
167570
|
-
${
|
|
167571
|
-
|
|
168221
|
+
${lines}${footer ? `
|
|
168222
|
+
|
|
168223
|
+
${footer}` : ""}`);
|
|
167572
168224
|
}
|
|
167573
168225
|
if (smartNotes.length > 0) {
|
|
168226
|
+
const { page, footer } = paginateNewestFirst(smartNotes, args.limit, args.offset);
|
|
168227
|
+
const lines = page.map(formatNoteLine).join(`
|
|
168228
|
+
|
|
168229
|
+
`);
|
|
167574
168230
|
sections.push(`## Smart Notes
|
|
167575
168231
|
|
|
167576
|
-
${
|
|
168232
|
+
${lines}${footer ? `
|
|
167577
168233
|
|
|
167578
|
-
`
|
|
168234
|
+
${footer}` : ""}`);
|
|
167579
168235
|
}
|
|
167580
168236
|
return sections;
|
|
167581
168237
|
}
|
|
@@ -167731,7 +168387,11 @@ function createCtxReduceTool(deps) {
|
|
|
167731
168387
|
};
|
|
167732
168388
|
}
|
|
167733
168389
|
|
|
168390
|
+
// ../plugin/src/features/magic-context/search.ts
|
|
168391
|
+
init_logger();
|
|
168392
|
+
|
|
167734
168393
|
// ../plugin/src/features/magic-context/git-commits/git-log-reader.ts
|
|
168394
|
+
init_logger();
|
|
167735
168395
|
import { execFile } from "node:child_process";
|
|
167736
168396
|
import { promisify } from "node:util";
|
|
167737
168397
|
var execFileAsync = promisify(execFile);
|
|
@@ -167815,7 +168475,11 @@ ${body}` : subject;
|
|
|
167815
168475
|
}
|
|
167816
168476
|
return commits;
|
|
167817
168477
|
}
|
|
168478
|
+
// ../plugin/src/features/magic-context/git-commits/indexer.ts
|
|
168479
|
+
init_logger();
|
|
168480
|
+
|
|
167818
168481
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
168482
|
+
init_logger();
|
|
167819
168483
|
var insertStatements = new WeakMap;
|
|
167820
168484
|
var existingShasStatements = new WeakMap;
|
|
167821
168485
|
var projectCountStatements = new WeakMap;
|
|
@@ -168028,6 +168692,7 @@ async function embedUnembeddedCommits(db, projectPath) {
|
|
|
168028
168692
|
}
|
|
168029
168693
|
}
|
|
168030
168694
|
// ../plugin/src/features/magic-context/git-commits/search-git-commits.ts
|
|
168695
|
+
init_logger();
|
|
168031
168696
|
var ftsStatements = new WeakMap;
|
|
168032
168697
|
var ftsPlainStatements = new WeakMap;
|
|
168033
168698
|
var getBySHAStatements = new WeakMap;
|
|
@@ -168698,6 +169363,9 @@ class BoundedSessionMap {
|
|
|
168698
169363
|
}
|
|
168699
169364
|
}
|
|
168700
169365
|
|
|
169366
|
+
// ../plugin/src/hooks/magic-context/inject-compartments.ts
|
|
169367
|
+
init_logger();
|
|
169368
|
+
|
|
168701
169369
|
// ../plugin/src/hooks/magic-context/decay-curve.ts
|
|
168702
169370
|
var H50 = 24;
|
|
168703
169371
|
var D = 25;
|
|
@@ -168980,6 +169648,7 @@ function isAftAvailable() {
|
|
|
168980
169648
|
}
|
|
168981
169649
|
|
|
168982
169650
|
// ../plugin/src/hooks/magic-context/key-files-block.ts
|
|
169651
|
+
init_logger();
|
|
168983
169652
|
var cachedKeyFilesBySession = new Map;
|
|
168984
169653
|
var staleUpdates = new Map;
|
|
168985
169654
|
function staleKey(update2) {
|
|
@@ -169233,6 +169902,21 @@ function renderMemoryBlockV2(memories, wrapper = "project-memory") {
|
|
|
169233
169902
|
`);
|
|
169234
169903
|
}
|
|
169235
169904
|
|
|
169905
|
+
// ../plugin/src/tools/ctx-search/constants.ts
|
|
169906
|
+
var CTX_SEARCH_DESCRIPTION = `Your long-term recall for this project — search everything that ever happened here, not just what's currently visible.
|
|
169907
|
+
|
|
169908
|
+
Reach for it when something feels familiar but isn't in view: "did we solve this before?", "what did we decide about X?", "when did this break?", "where does Y live?". Results only contain things you CANNOT currently see — memories already shown in <project-memory> and the live conversation tail are filtered out.
|
|
169909
|
+
|
|
169910
|
+
Sources (omit for a broad search across all):
|
|
169911
|
+
- memory: curated cross-session project knowledge — rules, constraints, conventions.
|
|
169912
|
+
- message: the raw conversation behind your compacted history. Hits include message ordinals — expand the surrounding exchange with ctx_expand(start=N-10, end=N+5).
|
|
169913
|
+
- git_commit: this repository's commit history.
|
|
169914
|
+
|
|
169915
|
+
Picking sources:
|
|
169916
|
+
- "when did this change / was this working before" → ["git_commit", "message"]
|
|
169917
|
+
- "did we discuss this earlier" → ["message"]
|
|
169918
|
+
- "what's our convention / rule for X" → ["memory"]`;
|
|
169919
|
+
|
|
169236
169920
|
// src/tools/ctx-search.ts
|
|
169237
169921
|
var DEFAULT_LIMIT = 10;
|
|
169238
169922
|
var ParamsSchema5 = exports_typebox.Object({
|
|
@@ -169316,18 +170000,7 @@ function createCtxSearchTool(deps) {
|
|
|
169316
170000
|
return {
|
|
169317
170001
|
name: "ctx_search",
|
|
169318
170002
|
label: "Magic Context: Search",
|
|
169319
|
-
description:
|
|
169320
|
-
|
|
169321
|
-
` + `Sources:
|
|
169322
|
-
` + `- memory: curated cross-session knowledge for this project
|
|
169323
|
-
` + `- message: raw user/assistant messages from older compartmentalized history
|
|
169324
|
-
` + `- git_commit: HEAD git commits (when git commit indexing is enabled)
|
|
169325
|
-
|
|
169326
|
-
` + "Narrow via the `sources` param when the question maps to a specific channel:\n" + `- "was this working before / when did this break" → ["git_commit", "message"]
|
|
169327
|
-
` + `- "when did we change this" → ["git_commit"]
|
|
169328
|
-
` + `- "what is our naming convention" → ["memory"]
|
|
169329
|
-
` + `- "did we discuss this earlier" → ["message"]
|
|
169330
|
-
` + "Omit sources for a broad search across all enabled channels.",
|
|
170003
|
+
description: CTX_SEARCH_DESCRIPTION,
|
|
169331
170004
|
parameters: ParamsSchema5,
|
|
169332
170005
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
169333
170006
|
const query = params.query?.trim();
|
|
@@ -169444,13 +170117,15 @@ function registerMagicContextTools(pi, opts) {
|
|
|
169444
170117
|
embeddingEnabled: opts.embeddingEnabled,
|
|
169445
170118
|
gitCommitsEnabled: opts.gitCommitsEnabled
|
|
169446
170119
|
}));
|
|
169447
|
-
|
|
169448
|
-
|
|
169449
|
-
|
|
169450
|
-
|
|
169451
|
-
|
|
169452
|
-
|
|
169453
|
-
|
|
170120
|
+
if (opts.memoryToolEnabled !== false) {
|
|
170121
|
+
pi.registerTool(createCtxMemoryTool({
|
|
170122
|
+
db: opts.db,
|
|
170123
|
+
ensureProjectRegistered: opts.ensureProjectRegistered,
|
|
170124
|
+
memoryEnabled: opts.memoryEnabled,
|
|
170125
|
+
embeddingEnabled: opts.embeddingEnabled,
|
|
170126
|
+
allowDreamerActions: opts.allowDreamerActions ?? false
|
|
170127
|
+
}));
|
|
170128
|
+
}
|
|
169454
170129
|
if (!opts.sessionScopedToolsDisabled) {
|
|
169455
170130
|
pi.registerTool(createCtxNoteTool({
|
|
169456
170131
|
db: opts.db,
|
|
@@ -169473,7 +170148,7 @@ var openedDb;
|
|
|
169473
170148
|
function magicContextSubagentExtension(pi) {
|
|
169474
170149
|
setHarness("pi");
|
|
169475
170150
|
pi.registerFlag(SUBAGENT_DREAMER_ACTIONS_FLAG, {
|
|
169476
|
-
description: "
|
|
170151
|
+
description: "Register ctx_memory with dreamer actions for Magic Context subagents.",
|
|
169477
170152
|
type: "boolean",
|
|
169478
170153
|
default: false
|
|
169479
170154
|
});
|
|
@@ -169491,10 +170166,11 @@ function magicContextSubagentExtension(pi) {
|
|
|
169491
170166
|
registerMagicContextTools(pi, {
|
|
169492
170167
|
db,
|
|
169493
170168
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
170169
|
+
memoryToolEnabled: dreamerActionsEnabled,
|
|
169494
170170
|
allowDreamerActions: dreamerActionsEnabled,
|
|
169495
170171
|
sessionScopedToolsDisabled: true
|
|
169496
170172
|
});
|
|
169497
|
-
log(`[pi-subagent] registered tools: ctx_search, ctx_memory` + ` (ctx_note/ctx_expand omitted: --no-session child;` + ` memory=${cfg.memory.enabled}, embedding=${cfg.embedding.provider !== "off"},` + ` git_commits=${cfg.memory.git_commit_indexing.enabled}, dreamer_actions=${dreamerActionsEnabled})`);
|
|
170173
|
+
log(`[pi-subagent] registered tools: ctx_search${dreamerActionsEnabled ? ", ctx_memory" : ""}` + ` (ctx_note/ctx_expand omitted: --no-session child;` + ` memory=${cfg.memory.enabled}, embedding=${cfg.embedding.provider !== "off"},` + ` git_commits=${cfg.memory.git_commit_indexing.enabled}, dreamer_actions=${dreamerActionsEnabled})`);
|
|
169498
170174
|
} catch (err5) {
|
|
169499
170175
|
const message = err5 instanceof Error ? err5.message : String(err5);
|
|
169500
170176
|
log(`[pi-subagent] startup failed: ${message}`);
|