@cortexkit/pi-magic-context 0.22.4 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/dist/index.js +3854 -1137
- package/dist/subagent-entry.js +1302 -358
- 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 ''");
|
|
@@ -142476,6 +142559,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142476
142559
|
ensureColumn(db, "session_meta", "system_prompt_hash", "TEXT DEFAULT ''");
|
|
142477
142560
|
ensureColumn(db, "session_meta", "cleared_reasoning_through_tag", "INTEGER DEFAULT 0");
|
|
142478
142561
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
142562
|
+
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
142479
142563
|
ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
|
|
142480
142564
|
ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
|
|
142481
142565
|
ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
|
|
@@ -142494,6 +142578,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142494
142578
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_tags_pi_adopt
|
|
142495
142579
|
ON tags(session_id, entry_fingerprint)
|
|
142496
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");
|
|
142497
142584
|
ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
|
|
142498
142585
|
ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
|
|
142499
142586
|
ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
|
|
@@ -142534,6 +142621,14 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
142534
142621
|
ensureColumn(db, "session_meta", "cached_m0_project_docs_hash", "TEXT");
|
|
142535
142622
|
ensureColumn(db, "session_meta", "cached_m1_bytes", "BLOB");
|
|
142536
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");
|
|
142537
142632
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
142538
142633
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
142539
142634
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
@@ -142603,6 +142698,13 @@ function healAllNullColumns(db) {
|
|
|
142603
142698
|
healNullIntegerColumns(db);
|
|
142604
142699
|
healMissingMemoryBlockIds(db);
|
|
142605
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
|
+
}
|
|
142606
142708
|
function healMissingMemoryBlockIds(db) {
|
|
142607
142709
|
try {
|
|
142608
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();
|
|
@@ -142612,6 +142714,7 @@ function healNullTextColumns(db) {
|
|
|
142612
142714
|
const columns = [
|
|
142613
142715
|
["cache_ttl", ""],
|
|
142614
142716
|
["last_nudge_band", ""],
|
|
142717
|
+
["last_nudge_level", ""],
|
|
142615
142718
|
["last_transform_error", ""],
|
|
142616
142719
|
["nudge_anchor_message_id", ""],
|
|
142617
142720
|
["nudge_anchor_text", ""],
|
|
@@ -142626,6 +142729,7 @@ function healNullTextColumns(db) {
|
|
|
142626
142729
|
["todo_synthetic_state_json", ""],
|
|
142627
142730
|
["system_prompt_hash", ""],
|
|
142628
142731
|
["stripped_placeholder_ids", ""],
|
|
142732
|
+
["stale_reduce_stripped_ids", ""],
|
|
142629
142733
|
["memory_block_cache", ""],
|
|
142630
142734
|
["memory_block_ids", ""],
|
|
142631
142735
|
["compaction_marker_state", ""],
|
|
@@ -142651,7 +142755,17 @@ function healNullIntegerColumns(db) {
|
|
|
142651
142755
|
["observed_safe_input_tokens", 0],
|
|
142652
142756
|
["cache_alert_sent", 0],
|
|
142653
142757
|
["new_work_tokens", 0],
|
|
142654
|
-
["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]
|
|
142655
142769
|
];
|
|
142656
142770
|
for (const [column, fallback] of columns) {
|
|
142657
142771
|
try {
|
|
@@ -142690,6 +142804,7 @@ function openDatabase(dbPathOrOptions) {
|
|
|
142690
142804
|
if (!persistenceByDatabase.has(existing)) {
|
|
142691
142805
|
persistenceByDatabase.set(existing, true);
|
|
142692
142806
|
}
|
|
142807
|
+
healWedgedChannel2Claims(existing);
|
|
142693
142808
|
return existing;
|
|
142694
142809
|
}
|
|
142695
142810
|
try {
|
|
@@ -142715,6 +142830,7 @@ function openDatabase(dbPathOrOptions) {
|
|
|
142715
142830
|
log(`[magic-context] key-files orphan GC failed: ${getErrorMessage(error)}`);
|
|
142716
142831
|
}
|
|
142717
142832
|
}
|
|
142833
|
+
healWedgedChannel2Claims(db);
|
|
142718
142834
|
if (!explicitDbPath) {
|
|
142719
142835
|
try {
|
|
142720
142836
|
runToolOwnerBackfill(db);
|
|
@@ -142735,6 +142851,34 @@ function openDatabase(dbPathOrOptions) {
|
|
|
142735
142851
|
}
|
|
142736
142852
|
}
|
|
142737
142853
|
|
|
142854
|
+
// src/subagent-entry.ts
|
|
142855
|
+
init_logger();
|
|
142856
|
+
|
|
142857
|
+
// ../plugin/src/config/prune-config-leaf.ts
|
|
142858
|
+
function isPlainObject(value) {
|
|
142859
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
142860
|
+
}
|
|
142861
|
+
function pruneNestedConfigLeaf(block, relativePath) {
|
|
142862
|
+
if (relativePath.length === 0)
|
|
142863
|
+
return null;
|
|
142864
|
+
const result = { ...block };
|
|
142865
|
+
let cursor = result;
|
|
142866
|
+
for (let i = 0;i < relativePath.length - 1; i++) {
|
|
142867
|
+
const seg = String(relativePath[i]);
|
|
142868
|
+
const child = cursor[seg];
|
|
142869
|
+
if (!isPlainObject(child))
|
|
142870
|
+
return null;
|
|
142871
|
+
const clonedChild = { ...child };
|
|
142872
|
+
cursor[seg] = clonedChild;
|
|
142873
|
+
cursor = clonedChild;
|
|
142874
|
+
}
|
|
142875
|
+
const leaf = String(relativePath[relativePath.length - 1]);
|
|
142876
|
+
if (!(leaf in cursor))
|
|
142877
|
+
return null;
|
|
142878
|
+
delete cursor[leaf];
|
|
142879
|
+
return { block: result, removed: relativePath.map(String).join(".") };
|
|
142880
|
+
}
|
|
142881
|
+
|
|
142738
142882
|
// src/config/index.ts
|
|
142739
142883
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
|
|
142740
142884
|
import { homedir as homedir3 } from "node:os";
|
|
@@ -142876,6 +143020,74 @@ function migrateLegacyExperimental(rawConfig, warnings) {
|
|
|
142876
143020
|
return patched;
|
|
142877
143021
|
}
|
|
142878
143022
|
|
|
143023
|
+
// ../plugin/src/config/project-security.ts
|
|
143024
|
+
var HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
|
|
143025
|
+
var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
|
|
143026
|
+
function isPlainObject2(value) {
|
|
143027
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
143028
|
+
}
|
|
143029
|
+
function stripUnsafeProjectConfigFields(projectRaw) {
|
|
143030
|
+
const warnings = [];
|
|
143031
|
+
if ("auto_update" in projectRaw) {
|
|
143032
|
+
delete projectRaw.auto_update;
|
|
143033
|
+
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
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
|
+
}
|
|
143039
|
+
for (const agentKey of HIDDEN_AGENT_KEYS) {
|
|
143040
|
+
const block = projectRaw[agentKey];
|
|
143041
|
+
if (!isPlainObject2(block))
|
|
143042
|
+
continue;
|
|
143043
|
+
const removed = [];
|
|
143044
|
+
for (const field of AGENT_ESCALATION_FIELDS) {
|
|
143045
|
+
if (field in block) {
|
|
143046
|
+
delete block[field];
|
|
143047
|
+
removed.push(field);
|
|
143048
|
+
}
|
|
143049
|
+
}
|
|
143050
|
+
if (removed.length > 0) {
|
|
143051
|
+
warnings.push(`Ignoring ${agentKey}.${removed.join("/")} from project config ` + "(security: a repository cannot reprogram or re-permission hidden agents).");
|
|
143052
|
+
}
|
|
143053
|
+
}
|
|
143054
|
+
return warnings;
|
|
143055
|
+
}
|
|
143056
|
+
function normalizeEndpoint(value) {
|
|
143057
|
+
if (typeof value !== "string")
|
|
143058
|
+
return;
|
|
143059
|
+
const trimmed = value.trim().replace(/\/+$/, "");
|
|
143060
|
+
return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;
|
|
143061
|
+
}
|
|
143062
|
+
function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
|
|
143063
|
+
const projectEmbedding = projectRaw.embedding;
|
|
143064
|
+
if (!isPlainObject2(projectEmbedding))
|
|
143065
|
+
return [];
|
|
143066
|
+
const redirectsEndpoint = "endpoint" in projectEmbedding;
|
|
143067
|
+
if (!redirectsEndpoint)
|
|
143068
|
+
return [];
|
|
143069
|
+
const userEmbedding = userRaw?.embedding;
|
|
143070
|
+
if (isPlainObject2(userEmbedding)) {
|
|
143071
|
+
const projectEndpoint = normalizeEndpoint(projectEmbedding.endpoint);
|
|
143072
|
+
const userEndpoint = normalizeEndpoint(userEmbedding.endpoint);
|
|
143073
|
+
if (projectEndpoint !== undefined && projectEndpoint === userEndpoint) {
|
|
143074
|
+
return [];
|
|
143075
|
+
}
|
|
143076
|
+
}
|
|
143077
|
+
const providesOwnKey = typeof projectEmbedding.api_key === "string" && projectEmbedding.api_key.length > 0;
|
|
143078
|
+
if (providesOwnKey)
|
|
143079
|
+
return [];
|
|
143080
|
+
const mergedEmbedding = mergedRaw.embedding;
|
|
143081
|
+
if (!isPlainObject2(mergedEmbedding))
|
|
143082
|
+
return [];
|
|
143083
|
+
if (!("api_key" in mergedEmbedding))
|
|
143084
|
+
return [];
|
|
143085
|
+
delete mergedEmbedding.api_key;
|
|
143086
|
+
return [
|
|
143087
|
+
"Dropped inherited user embedding api_key because project config redirected " + "embedding.endpoint without supplying its own key (security: prevents key " + "exfiltration to a repository-chosen endpoint)."
|
|
143088
|
+
];
|
|
143089
|
+
}
|
|
143090
|
+
|
|
142879
143091
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
142880
143092
|
var exports_external = {};
|
|
142881
143093
|
__export(exports_external, {
|
|
@@ -143507,7 +143719,7 @@ __export(exports_util, {
|
|
|
143507
143719
|
jsonStringifyReplacer: () => jsonStringifyReplacer,
|
|
143508
143720
|
joinValues: () => joinValues,
|
|
143509
143721
|
issue: () => issue,
|
|
143510
|
-
isPlainObject: () =>
|
|
143722
|
+
isPlainObject: () => isPlainObject3,
|
|
143511
143723
|
isObject: () => isObject,
|
|
143512
143724
|
hexToUint8Array: () => hexToUint8Array,
|
|
143513
143725
|
getSizableOrigin: () => getSizableOrigin,
|
|
@@ -143689,7 +143901,7 @@ var allowsEval = /* @__PURE__ */ cached(() => {
|
|
|
143689
143901
|
return false;
|
|
143690
143902
|
}
|
|
143691
143903
|
});
|
|
143692
|
-
function
|
|
143904
|
+
function isPlainObject3(o) {
|
|
143693
143905
|
if (isObject(o) === false)
|
|
143694
143906
|
return false;
|
|
143695
143907
|
const ctor = o.constructor;
|
|
@@ -143706,7 +143918,7 @@ function isPlainObject(o) {
|
|
|
143706
143918
|
return true;
|
|
143707
143919
|
}
|
|
143708
143920
|
function shallowClone(o) {
|
|
143709
|
-
if (
|
|
143921
|
+
if (isPlainObject3(o))
|
|
143710
143922
|
return { ...o };
|
|
143711
143923
|
if (Array.isArray(o))
|
|
143712
143924
|
return [...o];
|
|
@@ -143910,7 +144122,7 @@ function omit(schema, mask) {
|
|
|
143910
144122
|
return clone(schema, def);
|
|
143911
144123
|
}
|
|
143912
144124
|
function extend(schema, shape) {
|
|
143913
|
-
if (!
|
|
144125
|
+
if (!isPlainObject3(shape)) {
|
|
143914
144126
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
143915
144127
|
}
|
|
143916
144128
|
const checks = schema._zod.def.checks;
|
|
@@ -143933,7 +144145,7 @@ function extend(schema, shape) {
|
|
|
143933
144145
|
return clone(schema, def);
|
|
143934
144146
|
}
|
|
143935
144147
|
function safeExtend(schema, shape) {
|
|
143936
|
-
if (!
|
|
144148
|
+
if (!isPlainObject3(shape)) {
|
|
143937
144149
|
throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
143938
144150
|
}
|
|
143939
144151
|
const def = mergeDefs(schema._zod.def, {
|
|
@@ -146276,7 +146488,7 @@ function mergeValues(a, b) {
|
|
|
146276
146488
|
if (a instanceof Date && b instanceof Date && +a === +b) {
|
|
146277
146489
|
return { valid: true, data: a };
|
|
146278
146490
|
}
|
|
146279
|
-
if (
|
|
146491
|
+
if (isPlainObject3(a) && isPlainObject3(b)) {
|
|
146280
146492
|
const bKeys = Object.keys(b);
|
|
146281
146493
|
const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
|
|
146282
146494
|
const newObj = { ...a, ...b };
|
|
@@ -146462,7 +146674,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
146462
146674
|
$ZodType.init(inst, def);
|
|
146463
146675
|
inst._zod.parse = (payload, ctx) => {
|
|
146464
146676
|
const input = payload.value;
|
|
146465
|
-
if (!
|
|
146677
|
+
if (!isPlainObject3(input)) {
|
|
146466
146678
|
payload.issues.push({
|
|
146467
146679
|
expected: "record",
|
|
146468
146680
|
code: "invalid_type",
|
|
@@ -157182,7 +157394,6 @@ var AgentOverrideConfigSchema = exports_external.object({
|
|
|
157182
157394
|
});
|
|
157183
157395
|
|
|
157184
157396
|
// ../plugin/src/config/schema/magic-context.ts
|
|
157185
|
-
var DEFAULT_NUDGE_INTERVAL_TOKENS = 1e4;
|
|
157186
157397
|
var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
|
|
157187
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.";
|
|
157188
157399
|
var DEFAULT_HISTORIAN_TIMEOUT_MS = 300000;
|
|
@@ -157281,7 +157492,6 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
157281
157492
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
157282
157493
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
157283
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" })'),
|
|
157284
|
-
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)"),
|
|
157285
157495
|
execute_threshold_percentage: exports_external.union([
|
|
157286
157496
|
exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE),
|
|
157287
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))
|
|
@@ -157290,10 +157500,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
157290
157500
|
default: exports_external.number().min(5000).max(2000000).optional()
|
|
157291
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."),
|
|
157292
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)"),
|
|
157293
|
-
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)"),
|
|
157294
|
-
drop_tool_structure: exports_external.boolean().default(true).describe("When true, dropped tool parts are fully removed instead of truncated in place (default: true)"),
|
|
157295
157503
|
clear_reasoning_age: exports_external.number().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
|
|
157296
|
-
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)"),
|
|
157297
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)"),
|
|
157298
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)"),
|
|
157299
157506
|
commit_cluster_trigger: exports_external.object({
|
|
@@ -157416,6 +157623,21 @@ function stripJsonComments(content) {
|
|
|
157416
157623
|
// ../plugin/src/config/variable.ts
|
|
157417
157624
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
157418
157625
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
157626
|
+
function sensitiveFilePathReason(resolvedPath) {
|
|
157627
|
+
const home = homedir2();
|
|
157628
|
+
const sensitiveDirs = [
|
|
157629
|
+
{ dir: resolve2(home, ".ssh"), label: "SSH keys" },
|
|
157630
|
+
{ dir: resolve2(home, ".aws"), label: "AWS credentials" },
|
|
157631
|
+
{ dir: resolve2(home, ".gnupg"), label: "GnuPG keyring" },
|
|
157632
|
+
{ dir: resolve2(home, ".config", "gh"), label: "GitHub CLI auth" }
|
|
157633
|
+
];
|
|
157634
|
+
for (const { dir, label } of sensitiveDirs) {
|
|
157635
|
+
if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
|
|
157636
|
+
return label;
|
|
157637
|
+
}
|
|
157638
|
+
}
|
|
157639
|
+
return null;
|
|
157640
|
+
}
|
|
157419
157641
|
function substituteConfigVariables(input) {
|
|
157420
157642
|
const warnings = [];
|
|
157421
157643
|
let text = input.text;
|
|
@@ -157469,6 +157691,10 @@ function substituteConfigVariables(input) {
|
|
|
157469
157691
|
} else if (!isAbsolute(filePath)) {
|
|
157470
157692
|
filePath = resolve2(configDir, filePath);
|
|
157471
157693
|
}
|
|
157694
|
+
const sensitiveReason = sensitiveFilePathReason(filePath);
|
|
157695
|
+
if (sensitiveReason) {
|
|
157696
|
+
warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
|
|
157697
|
+
}
|
|
157472
157698
|
if (!existsSync4(filePath)) {
|
|
157473
157699
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
157474
157700
|
continue;
|
|
@@ -157507,7 +157733,8 @@ function loadConfigFile(path3, scope) {
|
|
|
157507
157733
|
const rawText = readFileSync3(path3, "utf-8");
|
|
157508
157734
|
const substituted = substituteConfigVariables({
|
|
157509
157735
|
text: rawText,
|
|
157510
|
-
configPath: path3
|
|
157736
|
+
configPath: path3,
|
|
157737
|
+
isProjectConfig: scope === "project"
|
|
157511
157738
|
});
|
|
157512
157739
|
return {
|
|
157513
157740
|
path: path3,
|
|
@@ -157549,14 +157776,14 @@ function redactConfigValue(value) {
|
|
|
157549
157776
|
}
|
|
157550
157777
|
return typeof value;
|
|
157551
157778
|
}
|
|
157552
|
-
function
|
|
157779
|
+
function isPlainObject4(value) {
|
|
157553
157780
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
157554
157781
|
}
|
|
157555
157782
|
function mergeRawConfigs(base, override) {
|
|
157556
157783
|
const merged = { ...base };
|
|
157557
157784
|
for (const [key, overrideValue] of Object.entries(override)) {
|
|
157558
157785
|
const baseValue = merged[key];
|
|
157559
|
-
merged[key] =
|
|
157786
|
+
merged[key] = isPlainObject4(baseValue) && isPlainObject4(overrideValue) ? mergeRawConfigs(baseValue, overrideValue) : overrideValue;
|
|
157560
157787
|
}
|
|
157561
157788
|
return merged;
|
|
157562
157789
|
}
|
|
@@ -157570,10 +157797,15 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
157570
157797
|
}
|
|
157571
157798
|
const defaults = MagicContextConfigSchema.parse({});
|
|
157572
157799
|
const errorPaths = new Set;
|
|
157800
|
+
const issuePathsByKey = new Map;
|
|
157573
157801
|
for (const issue2 of parsed.error.issues) {
|
|
157574
157802
|
const topKey = issue2.path[0];
|
|
157575
157803
|
if (topKey !== undefined) {
|
|
157576
|
-
|
|
157804
|
+
const key = String(topKey);
|
|
157805
|
+
errorPaths.add(key);
|
|
157806
|
+
const paths = issuePathsByKey.get(key) ?? [];
|
|
157807
|
+
paths.push([...issue2.path]);
|
|
157808
|
+
issuePathsByKey.set(key, paths);
|
|
157577
157809
|
}
|
|
157578
157810
|
}
|
|
157579
157811
|
const patched = { ...migrated };
|
|
@@ -157581,11 +157813,32 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
157581
157813
|
for (const key of errorPaths) {
|
|
157582
157814
|
recoveredTopLevelKeys.push(key);
|
|
157583
157815
|
const isAgentConfig = key === "historian" || key === "dreamer" || key === "sidekick";
|
|
157584
|
-
delete patched[key];
|
|
157585
157816
|
if (isAgentConfig) {
|
|
157817
|
+
delete patched[key];
|
|
157586
157818
|
warnings.push(`"${key}": invalid agent configuration, ignoring. Check your magic-context.jsonc.`);
|
|
157587
157819
|
continue;
|
|
157588
157820
|
}
|
|
157821
|
+
const issuePaths = issuePathsByKey.get(key) ?? [];
|
|
157822
|
+
const rawValue = migrated[key];
|
|
157823
|
+
const allNested = issuePaths.length > 0 && issuePaths.every((p) => p.length >= 2) && typeof rawValue === "object" && rawValue !== null && !Array.isArray(rawValue);
|
|
157824
|
+
if (allNested) {
|
|
157825
|
+
let prunedBlock = {
|
|
157826
|
+
...rawValue
|
|
157827
|
+
};
|
|
157828
|
+
const prunedLeaves = [];
|
|
157829
|
+
for (const p of issuePaths) {
|
|
157830
|
+
const relative = p.slice(1);
|
|
157831
|
+
const result = pruneNestedConfigLeaf(prunedBlock, relative);
|
|
157832
|
+
if (result) {
|
|
157833
|
+
prunedBlock = result.block;
|
|
157834
|
+
prunedLeaves.push(result.removed);
|
|
157835
|
+
}
|
|
157836
|
+
}
|
|
157837
|
+
patched[key] = prunedBlock;
|
|
157838
|
+
warnings.push(`"${key}": invalid nested field(s) ${prunedLeaves.map((l) => `"${l}"`).join(", ")}, using defaults for those.`);
|
|
157839
|
+
continue;
|
|
157840
|
+
}
|
|
157841
|
+
delete patched[key];
|
|
157589
157842
|
const defaultValue = defaults[key];
|
|
157590
157843
|
warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultValue)}.`);
|
|
157591
157844
|
}
|
|
@@ -157618,10 +157871,22 @@ function loadPiConfig(opts = {}) {
|
|
|
157618
157871
|
return 0;
|
|
157619
157872
|
return a.scope === "user" ? -1 : 1;
|
|
157620
157873
|
});
|
|
157874
|
+
const userRaw = mergeFiles.find((f) => f.scope === "user")?.config;
|
|
157621
157875
|
for (const loaded of mergeFiles) {
|
|
157622
157876
|
const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
|
|
157623
157877
|
warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
|
|
157624
|
-
|
|
157878
|
+
if (loaded.scope === "project") {
|
|
157879
|
+
const projectRaw = { ...loaded.config };
|
|
157880
|
+
for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
|
|
157881
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157882
|
+
}
|
|
157883
|
+
rawConfig = mergeRawConfigs(rawConfig, projectRaw);
|
|
157884
|
+
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
|
|
157885
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157886
|
+
}
|
|
157887
|
+
} else {
|
|
157888
|
+
rawConfig = mergeRawConfigs(rawConfig, loaded.config);
|
|
157889
|
+
}
|
|
157625
157890
|
}
|
|
157626
157891
|
const parsed = parsePiConfig(rawConfig);
|
|
157627
157892
|
warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
|
|
@@ -157696,10 +157961,22 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
157696
157961
|
return 0;
|
|
157697
157962
|
return a.scope === "user" ? -1 : 1;
|
|
157698
157963
|
});
|
|
157964
|
+
const userRaw = mergeFiles.find((f) => f.scope === "user")?.config;
|
|
157699
157965
|
for (const loaded of mergeFiles) {
|
|
157700
157966
|
const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
|
|
157701
157967
|
warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
|
|
157702
|
-
|
|
157968
|
+
if (loaded.scope === "project") {
|
|
157969
|
+
const projectRaw = { ...loaded.config };
|
|
157970
|
+
for (const warning of stripUnsafeProjectConfigFields(projectRaw)) {
|
|
157971
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157972
|
+
}
|
|
157973
|
+
rawConfig = mergeRawConfigs(rawConfig, projectRaw);
|
|
157974
|
+
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
|
|
157975
|
+
warnings.push(`${prefix} ${warning}`);
|
|
157976
|
+
}
|
|
157977
|
+
} else {
|
|
157978
|
+
rawConfig = mergeRawConfigs(rawConfig, loaded.config);
|
|
157979
|
+
}
|
|
157703
157980
|
}
|
|
157704
157981
|
const recoveredTopLevelKeys = [];
|
|
157705
157982
|
const parsed = parsePiConfig(rawConfig, recoveredTopLevelKeys);
|
|
@@ -157726,6 +158003,9 @@ function loadPiConfigDetailed(opts = {}) {
|
|
|
157726
158003
|
};
|
|
157727
158004
|
}
|
|
157728
158005
|
|
|
158006
|
+
// ../plugin/src/features/magic-context/memory/embedding.ts
|
|
158007
|
+
init_logger();
|
|
158008
|
+
|
|
157729
158009
|
// ../plugin/src/features/magic-context/memory/cosine-similarity.ts
|
|
157730
158010
|
function cosineSimilarity(a, b) {
|
|
157731
158011
|
if (a.length !== b.length) {
|
|
@@ -157754,7 +158034,7 @@ function computeNormalizedHash(content) {
|
|
|
157754
158034
|
}
|
|
157755
158035
|
|
|
157756
158036
|
// ../plugin/src/features/magic-context/memory/embedding-identity.ts
|
|
157757
|
-
function
|
|
158037
|
+
function normalizeEndpoint2(endpoint) {
|
|
157758
158038
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
157759
158039
|
}
|
|
157760
158040
|
function getEmbeddingProviderIdentity(config2) {
|
|
@@ -157764,7 +158044,7 @@ function getEmbeddingProviderIdentity(config2) {
|
|
|
157764
158044
|
const identityInput = config2.provider === "openai-compatible" ? {
|
|
157765
158045
|
provider: "openai-compatible",
|
|
157766
158046
|
model: config2.model.trim(),
|
|
157767
|
-
endpoint:
|
|
158047
|
+
endpoint: normalizeEndpoint2(config2.endpoint),
|
|
157768
158048
|
apiKeyPresent: Boolean(config2.api_key?.trim()),
|
|
157769
158049
|
inputType: config2.input_type?.trim() || ""
|
|
157770
158050
|
} : {
|
|
@@ -157781,6 +158061,8 @@ import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
|
157781
158061
|
import { open, stat, unlink, writeFile } from "node:fs/promises";
|
|
157782
158062
|
import { dirname as dirname4, join as join6 } from "node:path";
|
|
157783
158063
|
import { pathToFileURL } from "node:url";
|
|
158064
|
+
init_data_path();
|
|
158065
|
+
init_logger();
|
|
157784
158066
|
var LOCK_POLL_MS = 150;
|
|
157785
158067
|
var STALE_LOCK_MS = 3 * 60000;
|
|
157786
158068
|
var MAX_LOCK_WAIT_MS = 5 * 60000;
|
|
@@ -158116,7 +158398,63 @@ class LocalEmbeddingProvider {
|
|
|
158116
158398
|
}
|
|
158117
158399
|
|
|
158118
158400
|
// ../plugin/src/features/magic-context/memory/embedding-openai.ts
|
|
158119
|
-
|
|
158401
|
+
init_logger();
|
|
158402
|
+
|
|
158403
|
+
// ../plugin/src/features/magic-context/memory/embedding-ssrf.ts
|
|
158404
|
+
var METADATA_HOSTNAMES = new Set(["metadata.google.internal", "metadata.goog"]);
|
|
158405
|
+
var IPV6_METADATA_HOSTS = new Set(["fd00:ec2::254"]);
|
|
158406
|
+
function isLinkLocalIpv4(host) {
|
|
158407
|
+
return /^169\.254\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
158408
|
+
}
|
|
158409
|
+
function ipv4FromMappedIpv6(host) {
|
|
158410
|
+
const m = /^::ffff:(.+)$/.exec(host);
|
|
158411
|
+
if (!m)
|
|
158412
|
+
return null;
|
|
158413
|
+
const tail = m[1];
|
|
158414
|
+
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(tail))
|
|
158415
|
+
return tail;
|
|
158416
|
+
const hex3 = /^([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(tail);
|
|
158417
|
+
if (hex3) {
|
|
158418
|
+
const hi = Number.parseInt(hex3[1], 16);
|
|
158419
|
+
const lo = Number.parseInt(hex3[2], 16);
|
|
158420
|
+
if (Number.isNaN(hi) || Number.isNaN(lo))
|
|
158421
|
+
return null;
|
|
158422
|
+
return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
|
|
158423
|
+
}
|
|
158424
|
+
return null;
|
|
158425
|
+
}
|
|
158426
|
+
function blockedEmbeddingEndpointReason(endpoint) {
|
|
158427
|
+
const trimmed = endpoint.trim();
|
|
158428
|
+
if (trimmed.length === 0)
|
|
158429
|
+
return null;
|
|
158430
|
+
let url2;
|
|
158431
|
+
try {
|
|
158432
|
+
url2 = new URL(trimmed);
|
|
158433
|
+
} catch {
|
|
158434
|
+
return `embedding endpoint is not a valid URL: ${trimmed}`;
|
|
158435
|
+
}
|
|
158436
|
+
const host = url2.hostname.toLowerCase().replace(/^\[/, "").replace(/\]$/, "");
|
|
158437
|
+
if (METADATA_HOSTNAMES.has(host)) {
|
|
158438
|
+
return `embedding endpoint host ${host} is a cloud metadata service (blocked)`;
|
|
158439
|
+
}
|
|
158440
|
+
if (IPV6_METADATA_HOSTS.has(host)) {
|
|
158441
|
+
return `embedding endpoint host ${host} is the AWS IPv6 metadata service (blocked)`;
|
|
158442
|
+
}
|
|
158443
|
+
if (isLinkLocalIpv4(host)) {
|
|
158444
|
+
return `embedding endpoint host ${host} is link-local / cloud metadata (blocked)`;
|
|
158445
|
+
}
|
|
158446
|
+
const mappedV4 = ipv4FromMappedIpv6(host);
|
|
158447
|
+
if (mappedV4 && isLinkLocalIpv4(mappedV4)) {
|
|
158448
|
+
return `embedding endpoint host ${host} (IPv4-mapped ${mappedV4}) is link-local / cloud metadata (blocked)`;
|
|
158449
|
+
}
|
|
158450
|
+
if (host.startsWith("fe80:")) {
|
|
158451
|
+
return `embedding endpoint host ${host} is link-local / cloud metadata (blocked)`;
|
|
158452
|
+
}
|
|
158453
|
+
return null;
|
|
158454
|
+
}
|
|
158455
|
+
|
|
158456
|
+
// ../plugin/src/features/magic-context/memory/embedding-openai.ts
|
|
158457
|
+
function normalizeEndpoint3(endpoint) {
|
|
158120
158458
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
158121
158459
|
}
|
|
158122
158460
|
var FAILURE_THRESHOLD = 3;
|
|
@@ -158137,7 +158475,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
158137
158475
|
openLogged = false;
|
|
158138
158476
|
halfOpenProbeInFlight = false;
|
|
158139
158477
|
constructor(options) {
|
|
158140
|
-
this.endpoint =
|
|
158478
|
+
this.endpoint = normalizeEndpoint3(options.endpoint);
|
|
158141
158479
|
this.model = options.model?.trim() ?? "";
|
|
158142
158480
|
this.apiKey = options.apiKey?.trim() ?? "";
|
|
158143
158481
|
this.inputType = options.inputType?.trim() ?? "";
|
|
@@ -158157,6 +158495,12 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
158157
158495
|
this.initialized = false;
|
|
158158
158496
|
return false;
|
|
158159
158497
|
}
|
|
158498
|
+
const blockedReason = blockedEmbeddingEndpointReason(this.endpoint);
|
|
158499
|
+
if (blockedReason) {
|
|
158500
|
+
log(`[magic-context] embedding endpoint blocked: ${blockedReason}`);
|
|
158501
|
+
this.initialized = false;
|
|
158502
|
+
return false;
|
|
158503
|
+
}
|
|
158160
158504
|
this.initialized = true;
|
|
158161
158505
|
return true;
|
|
158162
158506
|
}
|
|
@@ -158202,6 +158546,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
158202
158546
|
...this.inputType ? { input_type: this.inputType } : {},
|
|
158203
158547
|
...this.truncate ? { truncate: this.truncate } : {}
|
|
158204
158548
|
}),
|
|
158549
|
+
redirect: "error",
|
|
158205
158550
|
signal: internalController.signal
|
|
158206
158551
|
});
|
|
158207
158552
|
if (!response.ok) {
|
|
@@ -158406,6 +158751,7 @@ function getDistinctStoredModelIds(db, projectPath) {
|
|
|
158406
158751
|
|
|
158407
158752
|
// ../plugin/src/features/magic-context/project-embedding-registry.ts
|
|
158408
158753
|
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
158754
|
+
init_logger();
|
|
158409
158755
|
|
|
158410
158756
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
158411
158757
|
var saveStatements = new WeakMap;
|
|
@@ -158681,11 +159027,15 @@ function resolveEmbeddingConfig(config2) {
|
|
|
158681
159027
|
}
|
|
158682
159028
|
if (config2.provider === "openai-compatible") {
|
|
158683
159029
|
const apiKey = config2.api_key?.trim();
|
|
159030
|
+
const inputType = config2.input_type?.trim();
|
|
159031
|
+
const truncate = config2.truncate?.trim();
|
|
158684
159032
|
return {
|
|
158685
159033
|
provider: "openai-compatible",
|
|
158686
159034
|
model: config2.model.trim(),
|
|
158687
159035
|
endpoint: config2.endpoint.trim(),
|
|
158688
|
-
...apiKey ? { api_key: apiKey } : {}
|
|
159036
|
+
...apiKey ? { api_key: apiKey } : {},
|
|
159037
|
+
...inputType ? { input_type: inputType } : {},
|
|
159038
|
+
...truncate ? { truncate } : {}
|
|
158689
159039
|
};
|
|
158690
159040
|
}
|
|
158691
159041
|
return { provider: "off" };
|
|
@@ -158701,7 +159051,9 @@ function createProvider(config2) {
|
|
|
158701
159051
|
return new OpenAICompatibleEmbeddingProvider({
|
|
158702
159052
|
endpoint: config2.endpoint,
|
|
158703
159053
|
model: config2.model,
|
|
158704
|
-
apiKey: config2.api_key
|
|
159054
|
+
apiKey: config2.api_key,
|
|
159055
|
+
inputType: config2.input_type,
|
|
159056
|
+
truncate: config2.truncate
|
|
158705
159057
|
});
|
|
158706
159058
|
}
|
|
158707
159059
|
return new LocalEmbeddingProvider(config2.model);
|
|
@@ -159140,17 +159492,41 @@ function hasGitDir(canonical) {
|
|
|
159140
159492
|
return false;
|
|
159141
159493
|
}
|
|
159142
159494
|
}
|
|
159495
|
+
function normalizeStoredProjectPath(rawOrStored) {
|
|
159496
|
+
if (rawOrStored.startsWith("git:") || rawOrStored.startsWith("dir:")) {
|
|
159497
|
+
return rawOrStored;
|
|
159498
|
+
}
|
|
159499
|
+
try {
|
|
159500
|
+
return resolveProjectIdentity(rawOrStored);
|
|
159501
|
+
} catch {
|
|
159502
|
+
return directoryFallback(rawOrStored);
|
|
159503
|
+
}
|
|
159504
|
+
}
|
|
159505
|
+
function storedPathBelongsToIdentity(storedProjectPath, projectIdentity) {
|
|
159506
|
+
return storedProjectPath === projectIdentity || normalizeStoredProjectPath(storedProjectPath) === projectIdentity;
|
|
159507
|
+
}
|
|
159143
159508
|
|
|
159144
159509
|
// ../plugin/src/plugin/embedding-bootstrap-helpers.ts
|
|
159145
159510
|
import { createHash as createHash5 } from "node:crypto";
|
|
159511
|
+
init_logger();
|
|
159146
159512
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
159147
159513
|
"embedding.api_key",
|
|
159148
159514
|
"embedding.endpoint",
|
|
159149
159515
|
"embedding.model",
|
|
159150
|
-
"embedding.provider"
|
|
159516
|
+
"embedding.provider",
|
|
159517
|
+
"embedding.input_type",
|
|
159518
|
+
"embedding.truncate"
|
|
159151
159519
|
]);
|
|
159152
159520
|
var EMBEDDING_AFFECTING_TOP_LEVEL_KEYS = new Set(["embedding", "memory", "experimental"]);
|
|
159153
|
-
var EMBEDDING_WARNING_TERMS = [
|
|
159521
|
+
var EMBEDDING_WARNING_TERMS = [
|
|
159522
|
+
"api_key",
|
|
159523
|
+
"endpoint",
|
|
159524
|
+
"model",
|
|
159525
|
+
"provider",
|
|
159526
|
+
"embedding",
|
|
159527
|
+
"input_type",
|
|
159528
|
+
"truncate"
|
|
159529
|
+
];
|
|
159154
159530
|
var loggedFailureSignatures = new Map;
|
|
159155
159531
|
function sha256Prefix2(value, length = 16) {
|
|
159156
159532
|
return createHash5("sha256").update(value).digest("hex").slice(0, length);
|
|
@@ -159230,7 +159606,6 @@ async function ensureProjectRegisteredFromPiDirectory(directory, db) {
|
|
|
159230
159606
|
};
|
|
159231
159607
|
registerProjectEmbeddingAndMaybeWipe(db, projectIdentity, detailed.config.embedding, features, directory);
|
|
159232
159608
|
}
|
|
159233
|
-
|
|
159234
159609
|
// ../plugin/src/features/magic-context/compartment-lease.ts
|
|
159235
159610
|
var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
159236
159611
|
var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
|
|
@@ -159328,6 +159703,14 @@ var SESSION_META_SELECT_COLUMNS = [
|
|
|
159328
159703
|
"cached_m0_tool_set_hash",
|
|
159329
159704
|
"cached_m0_model_key",
|
|
159330
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",
|
|
159331
159714
|
"upgrade_reminded_at",
|
|
159332
159715
|
"pi_stable_id_scheme"
|
|
159333
159716
|
];
|
|
@@ -159367,6 +159750,14 @@ var META_COLUMNS = {
|
|
|
159367
159750
|
cachedM0ToolSetHash: "cached_m0_tool_set_hash",
|
|
159368
159751
|
cachedM0ModelKey: "cached_m0_model_key",
|
|
159369
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",
|
|
159370
159761
|
upgradeRemindedAt: "upgrade_reminded_at",
|
|
159371
159762
|
piStableIdScheme: "pi_stable_id_scheme"
|
|
159372
159763
|
};
|
|
@@ -159408,7 +159799,7 @@ function isSessionMetaRow(row) {
|
|
|
159408
159799
|
if (row === null || typeof row !== "object")
|
|
159409
159800
|
return false;
|
|
159410
159801
|
const r = row;
|
|
159411
|
-
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);
|
|
159412
159803
|
}
|
|
159413
159804
|
function getDefaultSessionMeta(sessionId) {
|
|
159414
159805
|
return {
|
|
@@ -159448,6 +159839,14 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
159448
159839
|
cachedM0ToolSetHash: null,
|
|
159449
159840
|
cachedM0ModelKey: null,
|
|
159450
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,
|
|
159451
159850
|
upgradeRemindedAt: null,
|
|
159452
159851
|
piStableIdScheme: null
|
|
159453
159852
|
};
|
|
@@ -159502,6 +159901,14 @@ function toSessionMeta(row) {
|
|
|
159502
159901
|
cachedM0ToolSetHash: stringOrNull(row.cached_m0_tool_set_hash),
|
|
159503
159902
|
cachedM0ModelKey: stringOrNull(row.cached_m0_model_key),
|
|
159504
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),
|
|
159505
159912
|
upgradeRemindedAt: numOrNull(row.upgrade_reminded_at),
|
|
159506
159913
|
piStableIdScheme: numOrNull(row.pi_stable_id_scheme)
|
|
159507
159914
|
};
|
|
@@ -159586,12 +159993,6 @@ function isCompartmentRow(row) {
|
|
|
159586
159993
|
const candidate = row;
|
|
159587
159994
|
return typeof candidate.id === "number" && typeof candidate.session_id === "string" && typeof candidate.sequence === "number" && typeof candidate.start_message === "number" && typeof candidate.end_message === "number" && typeof candidate.start_message_id === "string" && typeof candidate.end_message_id === "string" && typeof candidate.title === "string" && typeof candidate.content === "string" && isStringOrNullish(candidate.p1) && isStringOrNullish(candidate.p2) && isStringOrNullish(candidate.p3) && isStringOrNullish(candidate.p4) && isNumberOrNullish(candidate.importance) && isStringOrNullish(candidate.episode_type) && isNumberOrNullish(candidate.legacy) && typeof candidate.created_at === "number";
|
|
159588
159995
|
}
|
|
159589
|
-
function isSessionFactRow(row) {
|
|
159590
|
-
if (row === null || typeof row !== "object")
|
|
159591
|
-
return false;
|
|
159592
|
-
const candidate = row;
|
|
159593
|
-
return typeof candidate.id === "number" && typeof candidate.session_id === "string" && typeof candidate.category === "string" && typeof candidate.content === "string" && typeof candidate.created_at === "number" && typeof candidate.updated_at === "number";
|
|
159594
|
-
}
|
|
159595
159996
|
function insertCompartmentRows(db, sessionId, compartments, now) {
|
|
159596
159997
|
const stmt = getInsertCompartmentStatement(db);
|
|
159597
159998
|
for (const compartment of compartments) {
|
|
@@ -159620,16 +160021,6 @@ function toCompartment(row) {
|
|
|
159620
160021
|
createdAt: row.created_at
|
|
159621
160022
|
};
|
|
159622
160023
|
}
|
|
159623
|
-
function toSessionFact(row) {
|
|
159624
|
-
return {
|
|
159625
|
-
id: row.id,
|
|
159626
|
-
sessionId: row.session_id,
|
|
159627
|
-
category: row.category,
|
|
159628
|
-
content: row.content,
|
|
159629
|
-
createdAt: row.created_at,
|
|
159630
|
-
updatedAt: row.updated_at
|
|
159631
|
-
};
|
|
159632
|
-
}
|
|
159633
160024
|
function getCompartments(db, sessionId) {
|
|
159634
160025
|
const rows = db.prepare("SELECT * FROM compartments WHERE session_id = ? ORDER BY sequence ASC").all(sessionId).filter(isCompartmentRow);
|
|
159635
160026
|
return rows.map(toCompartment);
|
|
@@ -159638,6 +160029,11 @@ function getLastCompartmentEndMessage(db, sessionId) {
|
|
|
159638
160029
|
const row = db.prepare("SELECT MAX(end_message) as max_end FROM compartments WHERE session_id = ?").get(sessionId);
|
|
159639
160030
|
return row?.max_end ?? -1;
|
|
159640
160031
|
}
|
|
160032
|
+
function getLastCompartmentEndMessageId(db, sessionId) {
|
|
160033
|
+
const row = db.prepare("SELECT end_message_id FROM compartments WHERE session_id = ? ORDER BY sequence DESC LIMIT 1").get(sessionId);
|
|
160034
|
+
const id = row?.end_message_id;
|
|
160035
|
+
return id && id.length > 0 ? id : null;
|
|
160036
|
+
}
|
|
159641
160037
|
function getCompartmentsByEndMessageId(db, sessionId, endMessageId) {
|
|
159642
160038
|
const rows = db.prepare("SELECT * FROM compartments WHERE session_id = ? AND end_message_id = ? ORDER BY sequence ASC").all(sessionId, endMessageId).filter(isCompartmentRow);
|
|
159643
160039
|
return rows.map(toCompartment);
|
|
@@ -159650,10 +160046,6 @@ function appendCompartments(db, sessionId, compartments) {
|
|
|
159650
160046
|
insertCompartmentRows(db, sessionId, compartments, now);
|
|
159651
160047
|
})();
|
|
159652
160048
|
}
|
|
159653
|
-
function getSessionFacts(db, sessionId) {
|
|
159654
|
-
const rows = db.prepare("SELECT * FROM session_facts WHERE session_id = ? ORDER BY category ASC, id ASC").all(sessionId).filter(isSessionFactRow);
|
|
159655
|
-
return rows.map(toSessionFact);
|
|
159656
|
-
}
|
|
159657
160049
|
function saveRecompStagingPass(db, sessionId, passNumber, compartments, facts) {
|
|
159658
160050
|
const now = Date.now();
|
|
159659
160051
|
db.transaction(() => {
|
|
@@ -159697,14 +160089,6 @@ function getRecompStaging(db, sessionId) {
|
|
|
159697
160089
|
lastEndMessage: lastEnd
|
|
159698
160090
|
};
|
|
159699
160091
|
}
|
|
159700
|
-
function invalidateAllMemoryBlockCaches(db) {
|
|
159701
|
-
try {
|
|
159702
|
-
const rows = db.prepare("SELECT session_id FROM session_meta").all();
|
|
159703
|
-
for (const row of rows) {
|
|
159704
|
-
clearCachedM0M1(db, row.session_id);
|
|
159705
|
-
}
|
|
159706
|
-
} catch {}
|
|
159707
|
-
}
|
|
159708
160092
|
function clearRecompStaging(db, sessionId) {
|
|
159709
160093
|
db.transaction(() => {
|
|
159710
160094
|
db.prepare("DELETE FROM recomp_compartments WHERE session_id = ?").run(sessionId);
|
|
@@ -159752,6 +160136,8 @@ function escapeXmlContent(s) {
|
|
|
159752
160136
|
}
|
|
159753
160137
|
|
|
159754
160138
|
// ../plugin/src/hooks/magic-context/read-session-db.ts
|
|
160139
|
+
init_data_path();
|
|
160140
|
+
init_logger();
|
|
159755
160141
|
import { existsSync as existsSync6 } from "node:fs";
|
|
159756
160142
|
import { join as join7 } from "node:path";
|
|
159757
160143
|
function getOpenCodeDbPath() {
|
|
@@ -159824,13 +160210,27 @@ function parseJsonUnknown(value) {
|
|
|
159824
160210
|
return null;
|
|
159825
160211
|
}
|
|
159826
160212
|
}
|
|
160213
|
+
function attachRawPartVersion(value, timeUpdated) {
|
|
160214
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
160215
|
+
return value;
|
|
160216
|
+
if (typeof timeUpdated !== "number")
|
|
160217
|
+
return value;
|
|
160218
|
+
try {
|
|
160219
|
+
Object.defineProperty(value, "__magicContextPartUpdatedAt", {
|
|
160220
|
+
value: timeUpdated,
|
|
160221
|
+
enumerable: false,
|
|
160222
|
+
configurable: true
|
|
160223
|
+
});
|
|
160224
|
+
} catch {}
|
|
160225
|
+
return value;
|
|
160226
|
+
}
|
|
159827
160227
|
function readRawSessionMessagesFromDb(db, sessionId) {
|
|
159828
|
-
const messageRows = db.prepare("SELECT id, data FROM message WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawMessageRow);
|
|
159829
|
-
const partRows = db.prepare("SELECT message_id, data FROM part WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawPartRow);
|
|
160228
|
+
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);
|
|
160229
|
+
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);
|
|
159830
160230
|
const partsByMessageId = new Map;
|
|
159831
160231
|
for (const part of partRows) {
|
|
159832
160232
|
const list = partsByMessageId.get(part.message_id) ?? [];
|
|
159833
|
-
list.push(parseJsonUnknown(part.data));
|
|
160233
|
+
list.push(attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated));
|
|
159834
160234
|
partsByMessageId.set(part.message_id, list);
|
|
159835
160235
|
}
|
|
159836
160236
|
const filtered = messageRows.filter((row) => {
|
|
@@ -159846,10 +160246,63 @@ function readRawSessionMessagesFromDb(db, sessionId) {
|
|
|
159846
160246
|
ordinal: index + 1,
|
|
159847
160247
|
id: row.id,
|
|
159848
160248
|
role,
|
|
159849
|
-
parts: partsByMessageId.get(row.id) ?? []
|
|
160249
|
+
parts: partsByMessageId.get(row.id) ?? [],
|
|
160250
|
+
version: row.time_updated ?? null
|
|
159850
160251
|
};
|
|
159851
160252
|
});
|
|
159852
160253
|
}
|
|
160254
|
+
function isAnchorRow(row) {
|
|
160255
|
+
return row !== null && typeof row === "object" && typeof row.time_created === "number" && typeof row.id === "string";
|
|
160256
|
+
}
|
|
160257
|
+
function readRawSessionTailFromDb(db, sessionId, baseOrdinal, anchorMessageId) {
|
|
160258
|
+
const anchorRow = db.prepare("SELECT time_created, id, data FROM message WHERE id = ? AND session_id = ?").get(anchorMessageId, sessionId);
|
|
160259
|
+
if (!isAnchorRow(anchorRow))
|
|
160260
|
+
return null;
|
|
160261
|
+
const anchorInfo = parseJsonRecord(anchorRow.data ?? "");
|
|
160262
|
+
if (anchorInfo?.summary === true && anchorInfo?.finish === "stop")
|
|
160263
|
+
return null;
|
|
160264
|
+
const messageRows = db.prepare(`SELECT id, data, time_updated FROM message
|
|
160265
|
+
WHERE session_id = ?
|
|
160266
|
+
AND (time_created > ? OR (time_created = ? AND id >= ?))
|
|
160267
|
+
ORDER BY time_created ASC, id ASC`).all(sessionId, anchorRow.time_created, anchorRow.time_created, anchorRow.id).filter(isRawMessageRow);
|
|
160268
|
+
const filtered = messageRows.filter((row) => {
|
|
160269
|
+
const info = parseJsonRecord(row.data);
|
|
160270
|
+
return !(info?.summary === true && info?.finish === "stop");
|
|
160271
|
+
});
|
|
160272
|
+
const ids = filtered.map((row) => row.id);
|
|
160273
|
+
const partsByMessageId = new Map;
|
|
160274
|
+
if (ids.length > 0) {
|
|
160275
|
+
const CHUNK = 800;
|
|
160276
|
+
for (let i = 0;i < ids.length; i += CHUNK) {
|
|
160277
|
+
const slice = ids.slice(i, i + CHUNK);
|
|
160278
|
+
const placeholders = slice.map(() => "?").join(",");
|
|
160279
|
+
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);
|
|
160280
|
+
for (const part of partRows) {
|
|
160281
|
+
const list = partsByMessageId.get(part.message_id) ?? [];
|
|
160282
|
+
list.push(attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated));
|
|
160283
|
+
partsByMessageId.set(part.message_id, list);
|
|
160284
|
+
}
|
|
160285
|
+
}
|
|
160286
|
+
}
|
|
160287
|
+
const messages = [];
|
|
160288
|
+
let ord = baseOrdinal;
|
|
160289
|
+
for (const row of filtered) {
|
|
160290
|
+
const info = parseJsonRecord(row.data);
|
|
160291
|
+
if (!info) {
|
|
160292
|
+
ord += 1;
|
|
160293
|
+
continue;
|
|
160294
|
+
}
|
|
160295
|
+
messages.push({
|
|
160296
|
+
ordinal: ord,
|
|
160297
|
+
id: row.id,
|
|
160298
|
+
role: typeof info.role === "string" ? info.role : "unknown",
|
|
160299
|
+
parts: partsByMessageId.get(row.id) ?? [],
|
|
160300
|
+
version: row.time_updated ?? null
|
|
160301
|
+
});
|
|
160302
|
+
ord += 1;
|
|
160303
|
+
}
|
|
160304
|
+
return { messages, absoluteMessageCount: Math.max(0, ord - 1) };
|
|
160305
|
+
}
|
|
159853
160306
|
|
|
159854
160307
|
// ../plugin/src/hooks/magic-context/tag-content-primitives.ts
|
|
159855
160308
|
var encoder = new TextEncoder;
|
|
@@ -159994,6 +160447,7 @@ class ToolMutationBatch {
|
|
|
159994
160447
|
|
|
159995
160448
|
// ../plugin/src/hooks/magic-context/read-session-chunk.ts
|
|
159996
160449
|
var activeRawMessageCache = null;
|
|
160450
|
+
var activeAbsoluteCountCache = null;
|
|
159997
160451
|
var sessionProviders = new Map;
|
|
159998
160452
|
function setRawMessageProvider(sessionId, provider2) {
|
|
159999
160453
|
sessionProviders.set(sessionId, provider2);
|
|
@@ -160025,12 +160479,14 @@ function withRawSessionMessageCache(fn) {
|
|
|
160025
160479
|
const outerCache = activeRawMessageCache;
|
|
160026
160480
|
if (!outerCache) {
|
|
160027
160481
|
activeRawMessageCache = new Map;
|
|
160482
|
+
activeAbsoluteCountCache = new Map;
|
|
160028
160483
|
}
|
|
160029
160484
|
try {
|
|
160030
160485
|
return fn();
|
|
160031
160486
|
} finally {
|
|
160032
160487
|
if (!outerCache) {
|
|
160033
160488
|
activeRawMessageCache = null;
|
|
160489
|
+
activeAbsoluteCountCache = null;
|
|
160034
160490
|
}
|
|
160035
160491
|
}
|
|
160036
160492
|
}
|
|
@@ -160046,6 +160502,40 @@ function readRawSessionMessages(sessionId) {
|
|
|
160046
160502
|
}
|
|
160047
160503
|
return readRawSessionMessagesFromSource(sessionId);
|
|
160048
160504
|
}
|
|
160505
|
+
function primeTailRawMessageCache(args) {
|
|
160506
|
+
const { sessionId, lastCompartmentEnd, anchorMessageId } = args;
|
|
160507
|
+
if (!activeRawMessageCache)
|
|
160508
|
+
return false;
|
|
160509
|
+
if (activeRawMessageCache.has(sessionId))
|
|
160510
|
+
return false;
|
|
160511
|
+
if (sessionProviders.has(sessionId))
|
|
160512
|
+
return false;
|
|
160513
|
+
if (!openCodeDbExists())
|
|
160514
|
+
return false;
|
|
160515
|
+
if (lastCompartmentEnd < 1 || !anchorMessageId)
|
|
160516
|
+
return false;
|
|
160517
|
+
const result = withReadOnlySessionDb((db) => readRawSessionTailFromDb(db, sessionId, lastCompartmentEnd, anchorMessageId));
|
|
160518
|
+
if (!result)
|
|
160519
|
+
return false;
|
|
160520
|
+
activeRawMessageCache.set(sessionId, result.messages);
|
|
160521
|
+
activeAbsoluteCountCache?.set(sessionId, result.absoluteMessageCount);
|
|
160522
|
+
return true;
|
|
160523
|
+
}
|
|
160524
|
+
function getCachedAbsoluteMessageCount(sessionId) {
|
|
160525
|
+
return activeAbsoluteCountCache?.get(sessionId) ?? null;
|
|
160526
|
+
}
|
|
160527
|
+
function primeInMemoryTailRawMessageCache(args) {
|
|
160528
|
+
const { sessionId, messages, absoluteMessageCount } = args;
|
|
160529
|
+
if (!activeRawMessageCache)
|
|
160530
|
+
return false;
|
|
160531
|
+
if (activeRawMessageCache.has(sessionId))
|
|
160532
|
+
return false;
|
|
160533
|
+
if (sessionProviders.has(sessionId))
|
|
160534
|
+
return false;
|
|
160535
|
+
activeRawMessageCache.set(sessionId, messages);
|
|
160536
|
+
activeAbsoluteCountCache?.set(sessionId, absoluteMessageCount);
|
|
160537
|
+
return true;
|
|
160538
|
+
}
|
|
160049
160539
|
function readRawSessionMessagesFromSource(sessionId) {
|
|
160050
160540
|
const provider2 = sessionProviders.get(sessionId);
|
|
160051
160541
|
if (provider2)
|
|
@@ -160110,7 +160600,7 @@ function getRawSessionTagKeysThrough(sessionId, upToMessageIndex) {
|
|
|
160110
160600
|
return { messageFileKeys, toolObservations };
|
|
160111
160601
|
}
|
|
160112
160602
|
var PROTECTED_TAIL_USER_TURNS = 5;
|
|
160113
|
-
function
|
|
160603
|
+
function getLegacyProtectedTailStartOrdinal(sessionId) {
|
|
160114
160604
|
const messages = readRawSessionMessages(sessionId);
|
|
160115
160605
|
const userOrdinals = messages.filter((m) => m.role === "user" && hasMeaningfulUserText(m.parts)).map((m) => m.ordinal);
|
|
160116
160606
|
if (userOrdinals.length < PROTECTED_TAIL_USER_TURNS) {
|
|
@@ -160120,6 +160610,7 @@ function getProtectedTailStartOrdinal(sessionId) {
|
|
|
160120
160610
|
}
|
|
160121
160611
|
function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal) {
|
|
160122
160612
|
const messages = readRawSessionMessages(sessionId);
|
|
160613
|
+
const totalMessageCount = getCachedAbsoluteMessageCount(sessionId) ?? messages.length;
|
|
160123
160614
|
const startOrdinal = Math.max(1, offset);
|
|
160124
160615
|
const lines = [];
|
|
160125
160616
|
const lineMeta = [];
|
|
@@ -160247,7 +160738,7 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
160247
160738
|
endMessageId: lastMessageId,
|
|
160248
160739
|
messageCount: messagesProcessed,
|
|
160249
160740
|
tokenEstimate: totalTokens,
|
|
160250
|
-
hasMore: lastOrdinal < (eligibleEndOrdinal !== undefined ? Math.min(eligibleEndOrdinal - 1,
|
|
160741
|
+
hasMore: lastOrdinal < (eligibleEndOrdinal !== undefined ? Math.min(eligibleEndOrdinal - 1, totalMessageCount) : totalMessageCount),
|
|
160251
160742
|
text: lines.join(`
|
|
160252
160743
|
`),
|
|
160253
160744
|
lines: lineMeta,
|
|
@@ -160257,7 +160748,13 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
160257
160748
|
}
|
|
160258
160749
|
|
|
160259
160750
|
// ../plugin/src/tools/ctx-expand/constants.ts
|
|
160260
|
-
var CTX_EXPAND_DESCRIPTION =
|
|
160751
|
+
var CTX_EXPAND_DESCRIPTION = `Recover the original conversation from your compacted history.
|
|
160752
|
+
|
|
160753
|
+
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:
|
|
160754
|
+
|
|
160755
|
+
ctx_expand(start=120, end=245) ← the compartment's own start/end attributes
|
|
160756
|
+
|
|
160757
|
+
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.`;
|
|
160261
160758
|
var CTX_EXPAND_TOKEN_BUDGET = 15000;
|
|
160262
160759
|
|
|
160263
160760
|
// ../../node_modules/.bun/typebox@1.1.38/node_modules/typebox/build/system/memory/memory.mjs
|
|
@@ -164426,11 +164923,31 @@ function findLastModelKeyFromBranch(entries) {
|
|
|
164426
164923
|
}
|
|
164427
164924
|
return;
|
|
164428
164925
|
}
|
|
164926
|
+
function rawEntryVersion(entry) {
|
|
164927
|
+
const record4 = entry;
|
|
164928
|
+
const updated = record4.updatedAt ?? record4.updated_at ?? record4.timestamp;
|
|
164929
|
+
return typeof updated === "string" || typeof updated === "number" ? updated : entry.id;
|
|
164930
|
+
}
|
|
164931
|
+
function attachPiPartVersion(parts, version2) {
|
|
164932
|
+
return parts.map((part) => {
|
|
164933
|
+
if (part === null || typeof part !== "object" || Array.isArray(part))
|
|
164934
|
+
return part;
|
|
164935
|
+
try {
|
|
164936
|
+
Object.defineProperty(part, "__magicContextPartUpdatedAt", {
|
|
164937
|
+
value: version2,
|
|
164938
|
+
enumerable: false,
|
|
164939
|
+
configurable: true
|
|
164940
|
+
});
|
|
164941
|
+
} catch {}
|
|
164942
|
+
return part;
|
|
164943
|
+
});
|
|
164944
|
+
}
|
|
164429
164945
|
function convertEntriesToRawMessages(entries) {
|
|
164430
164946
|
const result = [];
|
|
164431
164947
|
let nextOrdinal = 1;
|
|
164432
164948
|
let pendingToolParts = [];
|
|
164433
164949
|
let pendingFirstRealId = "";
|
|
164950
|
+
let pendingFirstRealVersion = "";
|
|
164434
164951
|
for (const entry of entries) {
|
|
164435
164952
|
if (!isMessageEntry(entry)) {
|
|
164436
164953
|
continue;
|
|
@@ -164438,24 +164955,29 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164438
164955
|
const msg = entry.message;
|
|
164439
164956
|
const role = msg.role;
|
|
164440
164957
|
if (role === "toolResult") {
|
|
164441
|
-
|
|
164958
|
+
const version2 = rawEntryVersion(entry);
|
|
164959
|
+
pendingToolParts.push(...attachPiPartVersion(synthesizeToolResultParts(msg), version2));
|
|
164442
164960
|
if (pendingFirstRealId === "") {
|
|
164443
164961
|
pendingFirstRealId = entry.id;
|
|
164962
|
+
pendingFirstRealVersion = version2;
|
|
164444
164963
|
}
|
|
164445
164964
|
continue;
|
|
164446
164965
|
}
|
|
164447
164966
|
if (role === "user") {
|
|
164967
|
+
const version2 = rawEntryVersion(entry);
|
|
164448
164968
|
const parts = [
|
|
164449
164969
|
...pendingToolParts,
|
|
164450
|
-
...synthesizeUserParts(msg)
|
|
164970
|
+
...attachPiPartVersion(synthesizeUserParts(msg), version2)
|
|
164451
164971
|
];
|
|
164452
164972
|
pendingToolParts = [];
|
|
164453
164973
|
pendingFirstRealId = "";
|
|
164974
|
+
pendingFirstRealVersion = "";
|
|
164454
164975
|
result.push({
|
|
164455
164976
|
ordinal: nextOrdinal++,
|
|
164456
164977
|
id: entry.id,
|
|
164457
164978
|
role: "user",
|
|
164458
|
-
parts
|
|
164979
|
+
parts,
|
|
164980
|
+
version: version2
|
|
164459
164981
|
});
|
|
164460
164982
|
continue;
|
|
164461
164983
|
}
|
|
@@ -164465,16 +164987,20 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164465
164987
|
ordinal: nextOrdinal++,
|
|
164466
164988
|
id: `${SYNTH_USER_ID_PREFIX}${pendingFirstRealId}`,
|
|
164467
164989
|
role: "user",
|
|
164468
|
-
parts: pendingToolParts
|
|
164990
|
+
parts: pendingToolParts,
|
|
164991
|
+
version: pendingFirstRealVersion
|
|
164469
164992
|
});
|
|
164470
164993
|
pendingToolParts = [];
|
|
164471
164994
|
pendingFirstRealId = "";
|
|
164995
|
+
pendingFirstRealVersion = "";
|
|
164472
164996
|
}
|
|
164997
|
+
const version2 = rawEntryVersion(entry);
|
|
164473
164998
|
result.push({
|
|
164474
164999
|
ordinal: nextOrdinal++,
|
|
164475
165000
|
id: entry.id,
|
|
164476
165001
|
role: "assistant",
|
|
164477
|
-
parts: synthesizeAssistantParts(msg)
|
|
165002
|
+
parts: attachPiPartVersion(synthesizeAssistantParts(msg), version2),
|
|
165003
|
+
version: version2
|
|
164478
165004
|
});
|
|
164479
165005
|
continue;
|
|
164480
165006
|
}
|
|
@@ -164482,7 +165008,8 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164482
165008
|
ordinal: nextOrdinal++,
|
|
164483
165009
|
id: entry.id,
|
|
164484
165010
|
role: typeof role === "string" ? role : "unknown",
|
|
164485
|
-
parts: []
|
|
165011
|
+
parts: [],
|
|
165012
|
+
version: rawEntryVersion(entry)
|
|
164486
165013
|
});
|
|
164487
165014
|
}
|
|
164488
165015
|
if (pendingToolParts.length > 0) {
|
|
@@ -164490,7 +165017,8 @@ function convertEntriesToRawMessages(entries) {
|
|
|
164490
165017
|
ordinal: nextOrdinal,
|
|
164491
165018
|
id: `${SYNTH_USER_ID_PREFIX}${pendingFirstRealId}`,
|
|
164492
165019
|
role: "user",
|
|
164493
|
-
parts: pendingToolParts
|
|
165020
|
+
parts: pendingToolParts,
|
|
165021
|
+
version: pendingFirstRealVersion
|
|
164494
165022
|
});
|
|
164495
165023
|
}
|
|
164496
165024
|
return result;
|
|
@@ -164647,6 +165175,13 @@ function createCtxExpandTool(deps) {
|
|
|
164647
165175
|
}
|
|
164648
165176
|
|
|
164649
165177
|
// ../plugin/src/features/magic-context/memory/constants.ts
|
|
165178
|
+
var V2_MEMORY_CATEGORIES = [
|
|
165179
|
+
"PROJECT_RULES",
|
|
165180
|
+
"ARCHITECTURE",
|
|
165181
|
+
"CONSTRAINTS",
|
|
165182
|
+
"CONFIG_VALUES",
|
|
165183
|
+
"NAMING"
|
|
165184
|
+
];
|
|
164650
165185
|
var PROMOTABLE_CATEGORIES = [
|
|
164651
165186
|
"PROJECT_RULES",
|
|
164652
165187
|
"ARCHITECTURE",
|
|
@@ -164686,6 +165221,7 @@ var CATEGORY_DEFAULT_TTL = {
|
|
|
164686
165221
|
KNOWN_ISSUES: 30 * 24 * 60 * 60 * 1000
|
|
164687
165222
|
};
|
|
164688
165223
|
// ../plugin/src/features/magic-context/memory/embedding-backfill.ts
|
|
165224
|
+
init_logger();
|
|
164689
165225
|
async function ensureMemoryEmbeddings(args) {
|
|
164690
165226
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
164691
165227
|
if (!snapshot?.enabled) {
|
|
@@ -164723,6 +165259,9 @@ async function ensureMemoryEmbeddings(args) {
|
|
|
164723
165259
|
}
|
|
164724
165260
|
return args.existingEmbeddings;
|
|
164725
165261
|
}
|
|
165262
|
+
// ../plugin/src/features/magic-context/memory/promotion.ts
|
|
165263
|
+
init_logger();
|
|
165264
|
+
|
|
164726
165265
|
// ../plugin/src/features/magic-context/memory/storage-memory.ts
|
|
164727
165266
|
var COLUMN_MAP = {
|
|
164728
165267
|
id: "id",
|
|
@@ -165394,7 +165933,7 @@ function indexMessagesAfterOrdinal(db, sessionId, messages, lastIndexedOrdinal,
|
|
|
165394
165933
|
}
|
|
165395
165934
|
// ../plugin/src/features/magic-context/project-docs-hash.ts
|
|
165396
165935
|
import { createHash as createHash6 } from "node:crypto";
|
|
165397
|
-
import { readFileSync as readFileSync4, statSync as statSync2 } from "node:fs";
|
|
165936
|
+
import { lstatSync, readFileSync as readFileSync4, statSync as statSync2 } from "node:fs";
|
|
165398
165937
|
import path4 from "node:path";
|
|
165399
165938
|
var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
165400
165939
|
var PROJECT_DOCS_DELIMITER = `
|
|
@@ -165402,6 +165941,7 @@ var PROJECT_DOCS_DELIMITER = `
|
|
|
165402
165941
|
---
|
|
165403
165942
|
|
|
165404
165943
|
`;
|
|
165944
|
+
var MAX_PROJECT_DOC_BYTES = 256 * 1024;
|
|
165405
165945
|
var docsCache = new Map;
|
|
165406
165946
|
function canonicalizeDocContent(raw) {
|
|
165407
165947
|
return raw.replace(/^\uFEFF/, "").replace(/\r\n/g, `
|
|
@@ -165411,9 +165951,10 @@ function canonicalizeDocContent(raw) {
|
|
|
165411
165951
|
}
|
|
165412
165952
|
function fingerprintFile(filePath) {
|
|
165413
165953
|
try {
|
|
165414
|
-
const stat2 =
|
|
165954
|
+
const stat2 = lstatSync(filePath);
|
|
165955
|
+
const isReadableDoc = stat2.isFile() && stat2.size <= MAX_PROJECT_DOC_BYTES;
|
|
165415
165956
|
return {
|
|
165416
|
-
exists:
|
|
165957
|
+
exists: isReadableDoc,
|
|
165417
165958
|
mtimeMs: stat2.mtimeMs,
|
|
165418
165959
|
size: stat2.size
|
|
165419
165960
|
};
|
|
@@ -165456,6 +165997,16 @@ function readCanonicalPieces(projectDirectory, files) {
|
|
|
165456
165997
|
if (!fingerprint?.exists) {
|
|
165457
165998
|
continue;
|
|
165458
165999
|
}
|
|
166000
|
+
let safeToRead = false;
|
|
166001
|
+
try {
|
|
166002
|
+
const st = lstatSync(filePath);
|
|
166003
|
+
safeToRead = st.isFile() && st.size <= MAX_PROJECT_DOC_BYTES;
|
|
166004
|
+
} catch {
|
|
166005
|
+
safeToRead = false;
|
|
166006
|
+
}
|
|
166007
|
+
if (!safeToRead) {
|
|
166008
|
+
continue;
|
|
166009
|
+
}
|
|
165459
166010
|
const canonicalContent = canonicalizeDocContent(readFileSync4(filePath, "utf8"));
|
|
165460
166011
|
hashPieces.push(`file:${filename}
|
|
165461
166012
|
${canonicalContent}`);
|
|
@@ -165622,6 +166173,7 @@ function getMaxMemoryMutationId(db, projectPath) {
|
|
|
165622
166173
|
return row?.max_id ?? null;
|
|
165623
166174
|
}
|
|
165624
166175
|
// ../plugin/src/features/magic-context/storage-meta-persisted.ts
|
|
166176
|
+
init_logger();
|
|
165625
166177
|
var CAS_RETRY_LIMIT = 5;
|
|
165626
166178
|
var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
165627
166179
|
"below-threshold",
|
|
@@ -165631,12 +166183,6 @@ var AUTO_SEARCH_NO_HINT_REASONS = new Set([
|
|
|
165631
166183
|
"stacked",
|
|
165632
166184
|
"too-short"
|
|
165633
166185
|
]);
|
|
165634
|
-
function isPersistedStickyTurnReminderRow(row) {
|
|
165635
|
-
if (row === null || typeof row !== "object")
|
|
165636
|
-
return false;
|
|
165637
|
-
const r = row;
|
|
165638
|
-
return typeof r.sticky_turn_reminder_text === "string" && typeof r.sticky_turn_reminder_message_id === "string";
|
|
165639
|
-
}
|
|
165640
166186
|
function isPersistedNoteNudgeRow(row) {
|
|
165641
166187
|
if (row === null || typeof row !== "object")
|
|
165642
166188
|
return false;
|
|
@@ -165702,6 +166248,139 @@ function getDefaultHistorianFailureState() {
|
|
|
165702
166248
|
lastFailureAt: null
|
|
165703
166249
|
};
|
|
165704
166250
|
}
|
|
166251
|
+
var DEFAULT_PROTECTED_TAIL_META = {
|
|
166252
|
+
priorBoundaryOrdinal: 1,
|
|
166253
|
+
protectedTailPolicyVersion: 0,
|
|
166254
|
+
protectedTailDrainWindowStartedAt: 0,
|
|
166255
|
+
protectedTailDrainTokens: 0,
|
|
166256
|
+
recoveryNoEligibleHeadCount: 0,
|
|
166257
|
+
forceEmergencyBypassWindowStart: 0,
|
|
166258
|
+
forceEmergencyBypassUsed: 0
|
|
166259
|
+
};
|
|
166260
|
+
function toProtectedTailMeta(row) {
|
|
166261
|
+
if (row === null || typeof row !== "object")
|
|
166262
|
+
return { ...DEFAULT_PROTECTED_TAIL_META };
|
|
166263
|
+
const r = row;
|
|
166264
|
+
const numberOr = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
166265
|
+
return {
|
|
166266
|
+
priorBoundaryOrdinal: Math.max(1, numberOr(r.prior_boundary_ordinal, 1)),
|
|
166267
|
+
protectedTailPolicyVersion: numberOr(r.protected_tail_policy_version, 0),
|
|
166268
|
+
protectedTailDrainWindowStartedAt: numberOr(r.protected_tail_drain_window_started_at, 0),
|
|
166269
|
+
protectedTailDrainTokens: numberOr(r.protected_tail_drain_tokens, 0),
|
|
166270
|
+
recoveryNoEligibleHeadCount: numberOr(r.recovery_no_eligible_head_count, 0),
|
|
166271
|
+
forceEmergencyBypassWindowStart: numberOr(r.force_emergency_bypass_window_start, 0),
|
|
166272
|
+
forceEmergencyBypassUsed: numberOr(r.force_emergency_bypass_used, 0)
|
|
166273
|
+
};
|
|
166274
|
+
}
|
|
166275
|
+
function loadProtectedTailMeta(db, sessionId) {
|
|
166276
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166277
|
+
const row = db.prepare(`SELECT prior_boundary_ordinal, protected_tail_policy_version,
|
|
166278
|
+
protected_tail_drain_window_started_at, protected_tail_drain_tokens,
|
|
166279
|
+
recovery_no_eligible_head_count, force_emergency_bypass_window_start,
|
|
166280
|
+
force_emergency_bypass_used
|
|
166281
|
+
FROM session_meta WHERE session_id = ?`).get(sessionId);
|
|
166282
|
+
return toProtectedTailMeta(row);
|
|
166283
|
+
}
|
|
166284
|
+
function markProtectedTailPolicyV3Seeded(db, sessionId, priorBoundaryOrdinal) {
|
|
166285
|
+
let seeded = false;
|
|
166286
|
+
db.transaction(() => {
|
|
166287
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166288
|
+
const existing = loadProtectedTailMeta(db, sessionId);
|
|
166289
|
+
if (existing.protectedTailPolicyVersion < 3) {
|
|
166290
|
+
db.prepare(`UPDATE session_meta
|
|
166291
|
+
SET prior_boundary_ordinal = ?, protected_tail_policy_version = 3
|
|
166292
|
+
WHERE session_id = ? AND protected_tail_policy_version < 3`).run(Math.max(1, Math.floor(priorBoundaryOrdinal)), sessionId);
|
|
166293
|
+
seeded = true;
|
|
166294
|
+
}
|
|
166295
|
+
})();
|
|
166296
|
+
return { ...loadProtectedTailMeta(db, sessionId), seeded };
|
|
166297
|
+
}
|
|
166298
|
+
function recordProtectedTailPublicationFloor(db, sessionId, floorOrdinal) {
|
|
166299
|
+
db.transaction(() => {
|
|
166300
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166301
|
+
db.prepare(`UPDATE session_meta
|
|
166302
|
+
SET prior_boundary_ordinal = MAX(COALESCE(prior_boundary_ordinal, 1), ?),
|
|
166303
|
+
recovery_no_eligible_head_count = 0
|
|
166304
|
+
WHERE session_id = ?`).run(Math.max(1, Math.floor(floorOrdinal)), sessionId);
|
|
166305
|
+
})();
|
|
166306
|
+
}
|
|
166307
|
+
function recordProtectedTailNoEligibleHead(db, sessionId) {
|
|
166308
|
+
db.transaction(() => {
|
|
166309
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166310
|
+
db.prepare(`UPDATE session_meta
|
|
166311
|
+
SET recovery_no_eligible_head_count = COALESCE(recovery_no_eligible_head_count, 0) + 1
|
|
166312
|
+
WHERE session_id = ?`).run(sessionId);
|
|
166313
|
+
})();
|
|
166314
|
+
return loadProtectedTailMeta(db, sessionId).recoveryNoEligibleHeadCount;
|
|
166315
|
+
}
|
|
166316
|
+
var DRAIN_WINDOW_MS = 10 * 60 * 1000;
|
|
166317
|
+
function protectedTailWindowBudget(usagePercentage, usable, perRunCap) {
|
|
166318
|
+
if (usagePercentage >= 95)
|
|
166319
|
+
return Math.min(1e6, Math.max(4 * perRunCap, Math.round(0.5 * usable)));
|
|
166320
|
+
if (usagePercentage >= 80)
|
|
166321
|
+
return Math.min(750000, Math.max(3 * perRunCap, Math.round(0.35 * usable)));
|
|
166322
|
+
return Math.min(500000, Math.max(perRunCap, Math.round(0.2 * usable)));
|
|
166323
|
+
}
|
|
166324
|
+
function reserveProtectedTailDrainTokens(args) {
|
|
166325
|
+
const now = args.now ?? Date.now();
|
|
166326
|
+
const requested = Math.max(0, Math.floor(args.trueRawTokens));
|
|
166327
|
+
if (requested === 0) {
|
|
166328
|
+
return { ok: true, reservedTokens: 0, overQuotaBypass: false, reservation: null };
|
|
166329
|
+
}
|
|
166330
|
+
let result = {
|
|
166331
|
+
ok: false,
|
|
166332
|
+
reservedTokens: 0,
|
|
166333
|
+
overQuotaBypass: false,
|
|
166334
|
+
reservation: null,
|
|
166335
|
+
skippedReason: "quota exhausted"
|
|
166336
|
+
};
|
|
166337
|
+
args.db.transaction(() => {
|
|
166338
|
+
ensureSessionMetaRow(args.db, args.sessionId);
|
|
166339
|
+
let meta3 = loadProtectedTailMeta(args.db, args.sessionId);
|
|
166340
|
+
if (now - meta3.protectedTailDrainWindowStartedAt > DRAIN_WINDOW_MS) {
|
|
166341
|
+
args.db.prepare(`UPDATE session_meta
|
|
166342
|
+
SET protected_tail_drain_window_started_at = ?, protected_tail_drain_tokens = 0,
|
|
166343
|
+
force_emergency_bypass_window_start = ?, force_emergency_bypass_used = 0
|
|
166344
|
+
WHERE session_id = ?`).run(now, now, args.sessionId);
|
|
166345
|
+
meta3 = loadProtectedTailMeta(args.db, args.sessionId);
|
|
166346
|
+
}
|
|
166347
|
+
const budget = protectedTailWindowBudget(args.usagePercentage, args.usable, args.perRunCap);
|
|
166348
|
+
const remaining = Math.max(0, budget - meta3.protectedTailDrainTokens);
|
|
166349
|
+
let reserved = Math.min(requested, args.perRunCap, remaining);
|
|
166350
|
+
let bypass = false;
|
|
166351
|
+
const bypassWindowExpired = now - meta3.forceEmergencyBypassWindowStart > DRAIN_WINDOW_MS;
|
|
166352
|
+
const bypassUsed = bypassWindowExpired ? 0 : meta3.forceEmergencyBypassUsed;
|
|
166353
|
+
if (reserved <= 0 && args.usagePercentage >= 95 && bypassUsed === 0) {
|
|
166354
|
+
reserved = Math.min(requested, args.perRunCap);
|
|
166355
|
+
bypass = true;
|
|
166356
|
+
}
|
|
166357
|
+
if (reserved <= 0)
|
|
166358
|
+
return;
|
|
166359
|
+
args.db.prepare(`UPDATE session_meta
|
|
166360
|
+
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,
|
|
166361
|
+
protected_tail_drain_tokens = COALESCE(protected_tail_drain_tokens, 0) + ?,
|
|
166362
|
+
force_emergency_bypass_window_start = CASE WHEN ? THEN ? ELSE force_emergency_bypass_window_start END,
|
|
166363
|
+
force_emergency_bypass_used = CASE WHEN ? THEN 1 ELSE force_emergency_bypass_used END
|
|
166364
|
+
WHERE session_id = ?`).run(now, reserved, bypass ? 1 : 0, now, bypass ? 1 : 0, args.sessionId);
|
|
166365
|
+
result = {
|
|
166366
|
+
ok: true,
|
|
166367
|
+
reservedTokens: reserved,
|
|
166368
|
+
overQuotaBypass: bypass,
|
|
166369
|
+
reservation: { sessionId: args.sessionId, runId: args.runId, tokens: reserved }
|
|
166370
|
+
};
|
|
166371
|
+
})();
|
|
166372
|
+
return result;
|
|
166373
|
+
}
|
|
166374
|
+
function rollbackProtectedTailDrainReservation(db, reservation) {
|
|
166375
|
+
if (!reservation || reservation.tokens <= 0)
|
|
166376
|
+
return;
|
|
166377
|
+
db.transaction(() => {
|
|
166378
|
+
ensureSessionMetaRow(db, reservation.sessionId);
|
|
166379
|
+
db.prepare(`UPDATE session_meta
|
|
166380
|
+
SET protected_tail_drain_tokens = MAX(0, COALESCE(protected_tail_drain_tokens, 0) - ?)
|
|
166381
|
+
WHERE session_id = ?`).run(reservation.tokens, reservation.sessionId);
|
|
166382
|
+
})();
|
|
166383
|
+
}
|
|
165705
166384
|
function setPersistedReasoningWatermark(db, sessionId, tagNumber) {
|
|
165706
166385
|
ensureSessionMetaRow(db, sessionId);
|
|
165707
166386
|
db.prepare("UPDATE session_meta SET cleared_reasoning_through_tag = ? WHERE session_id = ?").run(tagNumber, sessionId);
|
|
@@ -165709,27 +166388,95 @@ function setPersistedReasoningWatermark(db, sessionId, tagNumber) {
|
|
|
165709
166388
|
function clearPersistedReasoningWatermark(db, sessionId) {
|
|
165710
166389
|
setPersistedReasoningWatermark(db, sessionId, 0);
|
|
165711
166390
|
}
|
|
165712
|
-
function
|
|
165713
|
-
|
|
165714
|
-
|
|
165715
|
-
|
|
165716
|
-
|
|
165717
|
-
|
|
165718
|
-
|
|
165719
|
-
|
|
165720
|
-
|
|
165721
|
-
|
|
165722
|
-
|
|
165723
|
-
};
|
|
166391
|
+
function isEmergencyInputSampleRow(row) {
|
|
166392
|
+
return typeof row === "object" && row !== null && typeof row.last_emergency_input_sample === "number";
|
|
166393
|
+
}
|
|
166394
|
+
function getEmergencyInputSample(db, sessionId) {
|
|
166395
|
+
const result = db.prepare("SELECT last_emergency_input_sample FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166396
|
+
return isEmergencyInputSampleRow(result) ? result.last_emergency_input_sample : 0;
|
|
166397
|
+
}
|
|
166398
|
+
function setEmergencyDropSample(db, sessionId, inputSample) {
|
|
166399
|
+
db.transaction(() => {
|
|
166400
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166401
|
+
db.prepare("UPDATE session_meta SET last_emergency_input_sample = ? WHERE session_id = ?").run(Math.max(0, Math.round(inputSample)), sessionId);
|
|
166402
|
+
})();
|
|
165724
166403
|
}
|
|
165725
|
-
function
|
|
166404
|
+
function clearEmergencyDropSample(db, sessionId) {
|
|
165726
166405
|
db.transaction(() => {
|
|
165727
166406
|
ensureSessionMetaRow(db, sessionId);
|
|
165728
|
-
db.prepare("UPDATE session_meta SET
|
|
166407
|
+
db.prepare("UPDATE session_meta SET last_emergency_input_sample = 0 WHERE session_id = ?").run(sessionId);
|
|
165729
166408
|
})();
|
|
165730
166409
|
}
|
|
165731
|
-
function
|
|
165732
|
-
|
|
166410
|
+
function isLastNudgeUndroppedRow(row) {
|
|
166411
|
+
return typeof row === "object" && row !== null && typeof row.last_nudge_undropped === "number";
|
|
166412
|
+
}
|
|
166413
|
+
function isLastNudgeLevelRow(row) {
|
|
166414
|
+
return typeof row === "object" && row !== null && typeof row.last_nudge_level === "string";
|
|
166415
|
+
}
|
|
166416
|
+
function normalizeLastNudgeLevel(value) {
|
|
166417
|
+
return value === "gentle" || value === "firm" || value === "urgent" ? value : "";
|
|
166418
|
+
}
|
|
166419
|
+
function getLastNudgeUndropped(db, sessionId) {
|
|
166420
|
+
const result = db.prepare("SELECT last_nudge_undropped FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166421
|
+
return isLastNudgeUndroppedRow(result) ? result.last_nudge_undropped : 0;
|
|
166422
|
+
}
|
|
166423
|
+
function setLastNudgeUndropped(db, sessionId, value) {
|
|
166424
|
+
db.transaction(() => {
|
|
166425
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166426
|
+
db.prepare("UPDATE session_meta SET last_nudge_undropped = ? WHERE session_id = ?").run(Math.max(0, Math.round(value)), sessionId);
|
|
166427
|
+
})();
|
|
166428
|
+
}
|
|
166429
|
+
function getLastNudgeLevel(db, sessionId) {
|
|
166430
|
+
const result = db.prepare("SELECT last_nudge_level FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166431
|
+
return isLastNudgeLevelRow(result) ? normalizeLastNudgeLevel(result.last_nudge_level) : "";
|
|
166432
|
+
}
|
|
166433
|
+
function setLastNudgeLevel(db, sessionId, value) {
|
|
166434
|
+
db.transaction(() => {
|
|
166435
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166436
|
+
db.prepare("UPDATE session_meta SET last_nudge_level = ? WHERE session_id = ?").run(normalizeLastNudgeLevel(value), sessionId);
|
|
166437
|
+
})();
|
|
166438
|
+
}
|
|
166439
|
+
function resetLastNudgeCycle(db, sessionId) {
|
|
166440
|
+
db.transaction(() => {
|
|
166441
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166442
|
+
db.prepare("UPDATE session_meta SET last_nudge_undropped = 0, last_nudge_level = '' WHERE session_id = ?").run(sessionId);
|
|
166443
|
+
})();
|
|
166444
|
+
}
|
|
166445
|
+
function resetLastNudgeCycleIfTailShrank(db, sessionId, measuredUndropped) {
|
|
166446
|
+
let changed = false;
|
|
166447
|
+
db.transaction(() => {
|
|
166448
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166449
|
+
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)));
|
|
166450
|
+
changed = (result.changes ?? 0) > 0;
|
|
166451
|
+
})();
|
|
166452
|
+
return changed;
|
|
166453
|
+
}
|
|
166454
|
+
function isChannel2StateRow(row) {
|
|
166455
|
+
return typeof row === "object" && row !== null && typeof row.channel2_nudge_state === "string";
|
|
166456
|
+
}
|
|
166457
|
+
function getChannel2NudgeState(db, sessionId) {
|
|
166458
|
+
const result = db.prepare("SELECT channel2_nudge_state FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166459
|
+
if (!isChannel2StateRow(result))
|
|
166460
|
+
return "";
|
|
166461
|
+
const raw = result.channel2_nudge_state;
|
|
166462
|
+
return raw === "pending" || raw === "claimed" || raw === "delivered" ? raw : "";
|
|
166463
|
+
}
|
|
166464
|
+
function setChannel2NudgeState(db, sessionId, state) {
|
|
166465
|
+
db.transaction(() => {
|
|
166466
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166467
|
+
const claimedAt = state === "claimed" ? Date.now() : 0;
|
|
166468
|
+
db.prepare("UPDATE session_meta SET channel2_nudge_state = ?, channel2_nudge_claimed_at = ? WHERE session_id = ?").run(state, claimedAt, sessionId);
|
|
166469
|
+
})();
|
|
166470
|
+
}
|
|
166471
|
+
function casChannel2NudgeState(db, sessionId, from, to) {
|
|
166472
|
+
let changed = false;
|
|
166473
|
+
db.transaction(() => {
|
|
166474
|
+
ensureSessionMetaRow(db, sessionId);
|
|
166475
|
+
const claimedAt = to === "claimed" ? Date.now() : 0;
|
|
166476
|
+
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);
|
|
166477
|
+
changed = (result.changes ?? 0) > 0;
|
|
166478
|
+
})();
|
|
166479
|
+
return changed;
|
|
165733
166480
|
}
|
|
165734
166481
|
function getPersistedNoteNudge(db, sessionId) {
|
|
165735
166482
|
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);
|
|
@@ -165776,7 +166523,8 @@ function casUpdateJsonArrayColumn(db, sessionId, column, validator, mutate, opti
|
|
|
165776
166523
|
}
|
|
165777
166524
|
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
165778
166525
|
const row = db.prepare(`SELECT ${column} FROM session_meta WHERE session_id = ?`).get(sessionId);
|
|
165779
|
-
const
|
|
166526
|
+
const rawCurrent = row?.[column] ?? null;
|
|
166527
|
+
const currentBlob = rawCurrent ?? "[]";
|
|
165780
166528
|
const current = parseJsonArray(currentBlob, validator);
|
|
165781
166529
|
const next = mutate(current);
|
|
165782
166530
|
if (next === null)
|
|
@@ -165784,7 +166532,7 @@ function casUpdateJsonArrayColumn(db, sessionId, column, validator, mutate, opti
|
|
|
165784
166532
|
const nextBlob = stableStringify(next);
|
|
165785
166533
|
if (nextBlob === currentBlob)
|
|
165786
166534
|
return true;
|
|
165787
|
-
const result = db.prepare(`UPDATE session_meta SET ${column} = ? WHERE session_id = ? AND ${column}
|
|
166535
|
+
const result = db.prepare(`UPDATE session_meta SET ${column} = ? WHERE session_id = ? AND ${column} IS ?`).run(nextBlob, sessionId, rawCurrent);
|
|
165788
166536
|
if (result.changes > 0)
|
|
165789
166537
|
return true;
|
|
165790
166538
|
}
|
|
@@ -165913,14 +166661,16 @@ function getHistorianFailureState(db, sessionId) {
|
|
|
165913
166661
|
};
|
|
165914
166662
|
}
|
|
165915
166663
|
function incrementHistorianFailure(db, sessionId, error51) {
|
|
166664
|
+
let nextCount = 1;
|
|
165916
166665
|
db.transaction(() => {
|
|
165917
166666
|
ensureSessionMetaRow(db, sessionId);
|
|
165918
166667
|
const current = getHistorianFailureState(db, sessionId);
|
|
165919
|
-
|
|
166668
|
+
nextCount = current.failureCount + 1;
|
|
165920
166669
|
db.prepare("UPDATE session_meta SET historian_failure_count = ?, historian_last_error = ?, historian_last_failure_at = ? WHERE session_id = ?").run(nextCount, error51, Date.now(), sessionId);
|
|
165921
166670
|
const reason = error51.replace(/\s+/g, " ").trim().slice(0, 300);
|
|
165922
166671
|
sessionLog(sessionId, `historian failure recorded: count=${nextCount} reason="${reason}"`);
|
|
165923
166672
|
})();
|
|
166673
|
+
return nextCount;
|
|
165924
166674
|
}
|
|
165925
166675
|
function clearHistorianFailureState(db, sessionId) {
|
|
165926
166676
|
db.transaction(() => {
|
|
@@ -165950,7 +166700,11 @@ function recordOverflowDetected(db, sessionId, reportedLimit) {
|
|
|
165950
166700
|
function clearEmergencyRecovery(db, sessionId) {
|
|
165951
166701
|
db.transaction(() => {
|
|
165952
166702
|
ensureSessionMetaRow(db, sessionId);
|
|
165953
|
-
|
|
166703
|
+
try {
|
|
166704
|
+
db.prepare("UPDATE session_meta SET needs_emergency_recovery = 0, recovery_no_eligible_head_count = 0 WHERE session_id = ?").run(sessionId);
|
|
166705
|
+
} catch {
|
|
166706
|
+
db.prepare("UPDATE session_meta SET needs_emergency_recovery = 0 WHERE session_id = ?").run(sessionId);
|
|
166707
|
+
}
|
|
165954
166708
|
})();
|
|
165955
166709
|
}
|
|
165956
166710
|
function clearDetectedContextLimit(db, sessionId) {
|
|
@@ -165989,10 +166743,39 @@ function getStrippedPlaceholderIds(db, sessionId) {
|
|
|
165989
166743
|
} catch {}
|
|
165990
166744
|
return new Set;
|
|
165991
166745
|
}
|
|
165992
|
-
function
|
|
166746
|
+
function applyStrippedPlaceholderDelta(db, sessionId, delta) {
|
|
166747
|
+
const add = delta.add ? [...delta.add] : [];
|
|
166748
|
+
const remove = delta.remove ? [...delta.remove] : [];
|
|
166749
|
+
if (add.length === 0 && remove.length === 0)
|
|
166750
|
+
return true;
|
|
165993
166751
|
ensureSessionMetaRow(db, sessionId);
|
|
165994
|
-
|
|
165995
|
-
|
|
166752
|
+
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
166753
|
+
const row = db.prepare("SELECT stripped_placeholder_ids FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
166754
|
+
const rawStored = row ? row.stripped_placeholder_ids ?? null : null;
|
|
166755
|
+
const current = new Set(parseStrippedBlob(rawStored));
|
|
166756
|
+
for (const id of add)
|
|
166757
|
+
current.add(id);
|
|
166758
|
+
for (const id of remove)
|
|
166759
|
+
current.delete(id);
|
|
166760
|
+
const nextBlob = current.size > 0 ? JSON.stringify([...current]) : "";
|
|
166761
|
+
if (nextBlob === (rawStored ?? ""))
|
|
166762
|
+
return true;
|
|
166763
|
+
const result = db.prepare("UPDATE session_meta SET stripped_placeholder_ids = ? WHERE session_id = ? AND stripped_placeholder_ids IS ?").run(nextBlob, sessionId, rawStored);
|
|
166764
|
+
if (result.changes > 0)
|
|
166765
|
+
return true;
|
|
166766
|
+
}
|
|
166767
|
+
sessionLog(sessionId, `stripped_placeholder_ids CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
|
|
166768
|
+
return false;
|
|
166769
|
+
}
|
|
166770
|
+
function parseStrippedBlob(raw) {
|
|
166771
|
+
if (!raw || raw.length === 0)
|
|
166772
|
+
return [];
|
|
166773
|
+
try {
|
|
166774
|
+
const parsed = JSON.parse(raw);
|
|
166775
|
+
if (Array.isArray(parsed))
|
|
166776
|
+
return parsed.filter((v) => typeof v === "string");
|
|
166777
|
+
} catch {}
|
|
166778
|
+
return [];
|
|
165996
166779
|
}
|
|
165997
166780
|
function isPendingCompactionMarker(value) {
|
|
165998
166781
|
return typeof value === "object" && value !== null && typeof value.ordinal === "number" && typeof value.endMessageId === "string" && typeof value.publishedAt === "number";
|
|
@@ -166084,6 +166867,7 @@ function setSessionWorkMetrics(db, sessionId, newWorkTokens, totalInputTokens) {
|
|
|
166084
166867
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
166085
166868
|
|
|
166086
166869
|
// ../plugin/src/features/magic-context/resolve-subagent-fallback.ts
|
|
166870
|
+
init_logger();
|
|
166087
166871
|
function resolveIsSubagentFromOpenCodeDb(sessionId) {
|
|
166088
166872
|
try {
|
|
166089
166873
|
return withReadOnlySessionDb((openCodeDb) => {
|
|
@@ -166302,7 +167086,8 @@ function updateNote(db, noteId, updates, scope) {
|
|
|
166302
167086
|
sets.push("session_id = ?");
|
|
166303
167087
|
params.push(updates.sessionId);
|
|
166304
167088
|
}
|
|
166305
|
-
|
|
167089
|
+
const smartConditionChanged = existing.type === "smart" && updates.surfaceCondition !== undefined && updates.surfaceCondition !== existing.surfaceCondition;
|
|
167090
|
+
if (updates.status !== undefined && !smartConditionChanged) {
|
|
166306
167091
|
sets.push("status = ?");
|
|
166307
167092
|
params.push(updates.status);
|
|
166308
167093
|
}
|
|
@@ -166315,17 +167100,21 @@ function updateNote(db, noteId, updates, scope) {
|
|
|
166315
167100
|
sets.push("surface_condition = ?");
|
|
166316
167101
|
params.push(updates.surfaceCondition);
|
|
166317
167102
|
}
|
|
166318
|
-
if (
|
|
166319
|
-
sets.push("last_checked_at =
|
|
166320
|
-
|
|
166321
|
-
|
|
166322
|
-
|
|
166323
|
-
|
|
166324
|
-
|
|
166325
|
-
|
|
166326
|
-
|
|
166327
|
-
|
|
166328
|
-
|
|
167103
|
+
if (smartConditionChanged) {
|
|
167104
|
+
sets.push("status = 'pending'", "last_checked_at = NULL", "ready_at = NULL", "ready_reason = NULL");
|
|
167105
|
+
} else {
|
|
167106
|
+
if (updates.lastCheckedAt !== undefined) {
|
|
167107
|
+
sets.push("last_checked_at = ?");
|
|
167108
|
+
params.push(updates.lastCheckedAt);
|
|
167109
|
+
}
|
|
167110
|
+
if (updates.readyAt !== undefined) {
|
|
167111
|
+
sets.push("ready_at = ?");
|
|
167112
|
+
params.push(updates.readyAt);
|
|
167113
|
+
}
|
|
167114
|
+
if (updates.readyReason !== undefined) {
|
|
167115
|
+
sets.push("ready_reason = ?");
|
|
167116
|
+
params.push(updates.readyReason);
|
|
167117
|
+
}
|
|
166329
167118
|
}
|
|
166330
167119
|
}
|
|
166331
167120
|
if (sets.length === 1) {
|
|
@@ -166352,6 +167141,7 @@ function markNoteChecked(db, noteId) {
|
|
|
166352
167141
|
db.prepare("UPDATE notes SET last_checked_at = ?, updated_at = ? WHERE id = ? AND type = 'smart'").run(now, now, noteId);
|
|
166353
167142
|
}
|
|
166354
167143
|
// ../plugin/src/features/magic-context/storage-ops.ts
|
|
167144
|
+
init_logger();
|
|
166355
167145
|
var queuePendingOpStatements = new WeakMap;
|
|
166356
167146
|
var getPendingOpsStatements = new WeakMap;
|
|
166357
167147
|
var clearPendingOpsStatements = new WeakMap;
|
|
@@ -166514,7 +167304,7 @@ var getTagNumberByMessageIdStatements = new WeakMap;
|
|
|
166514
167304
|
function getInsertTagStatement(db) {
|
|
166515
167305
|
let stmt = insertTagStatements.get(db);
|
|
166516
167306
|
if (!stmt) {
|
|
166517
|
-
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
167307
|
+
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
166518
167308
|
insertTagStatements.set(db, stmt);
|
|
166519
167309
|
}
|
|
166520
167310
|
return stmt;
|
|
@@ -166556,9 +167346,95 @@ function getUpdateTagInputByteSizeStatement(db) {
|
|
|
166556
167346
|
function updateTagByteSize(db, sessionId, tagNumber, newByteSize) {
|
|
166557
167347
|
getUpdateTagByteSizeStatement(db).run(newByteSize, sessionId, tagNumber);
|
|
166558
167348
|
}
|
|
167349
|
+
var CONTENT_ID_SUFFIX = /:(?:p|file)\d+$/;
|
|
167350
|
+
function ownerMessageIdForTagRow(row) {
|
|
167351
|
+
if (row.type === "tool") {
|
|
167352
|
+
return row.tool_owner_message_id ?? row.message_id;
|
|
167353
|
+
}
|
|
167354
|
+
return row.message_id.replace(CONTENT_ID_SUFFIX, "");
|
|
167355
|
+
}
|
|
167356
|
+
function getActiveTagTokenAggregate(db, sessionId) {
|
|
167357
|
+
const row = db.prepare(`SELECT
|
|
167358
|
+
COALESCE(SUM(CASE WHEN type != 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0)
|
|
167359
|
+
+ COALESCE(SUM(COALESCE(reasoning_token_count, 0)), 0) AS conversation,
|
|
167360
|
+
COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) + COALESCE(input_token_count, 0) ELSE 0 END), 0) AS tool_call,
|
|
167361
|
+
COALESCE(SUM(CASE WHEN type = 'tool' THEN COALESCE(token_count, 0) ELSE 0 END), 0) AS tool_output,
|
|
167362
|
+
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
167363
|
+
FROM tags
|
|
167364
|
+
WHERE session_id = ? AND status = 'active'`).get(sessionId);
|
|
167365
|
+
return {
|
|
167366
|
+
conversation: row?.conversation ?? 0,
|
|
167367
|
+
toolCall: row?.tool_call ?? 0,
|
|
167368
|
+
toolOutput: row?.tool_output ?? 0,
|
|
167369
|
+
nullCount: row?.null_count ?? 0
|
|
167370
|
+
};
|
|
167371
|
+
}
|
|
167372
|
+
function getTriggerTagTokenUpperBound(db, sessionId) {
|
|
167373
|
+
const row = db.prepare(`SELECT
|
|
167374
|
+
COALESCE(SUM(COALESCE(token_count, 0) + COALESCE(input_token_count, 0) + COALESCE(reasoning_token_count, 0)), 0) AS bound,
|
|
167375
|
+
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
167376
|
+
FROM tags
|
|
167377
|
+
WHERE session_id = ? AND status IN ('active', 'dropped')`).get(sessionId);
|
|
167378
|
+
return { bound: row?.bound ?? 0, nullCount: row?.null_count ?? 0 };
|
|
167379
|
+
}
|
|
166559
167380
|
function updateTagInputByteSize(db, sessionId, tagNumber, newInputByteSize) {
|
|
166560
167381
|
getUpdateTagInputByteSizeStatement(db).run(newInputByteSize, sessionId, tagNumber);
|
|
166561
167382
|
}
|
|
167383
|
+
var updateTagTokenCountStatements = new WeakMap;
|
|
167384
|
+
var updateTagInputTokenCountStatements = new WeakMap;
|
|
167385
|
+
function getUpdateTagTokenCountStatement(db) {
|
|
167386
|
+
let stmt = updateTagTokenCountStatements.get(db);
|
|
167387
|
+
if (!stmt) {
|
|
167388
|
+
stmt = db.prepare("UPDATE tags SET token_count = ? WHERE session_id = ? AND tag_number = ?");
|
|
167389
|
+
updateTagTokenCountStatements.set(db, stmt);
|
|
167390
|
+
}
|
|
167391
|
+
return stmt;
|
|
167392
|
+
}
|
|
167393
|
+
function getUpdateTagInputTokenCountStatement(db) {
|
|
167394
|
+
let stmt = updateTagInputTokenCountStatements.get(db);
|
|
167395
|
+
if (!stmt) {
|
|
167396
|
+
stmt = db.prepare("UPDATE tags SET input_token_count = ? WHERE session_id = ? AND tag_number = ?");
|
|
167397
|
+
updateTagInputTokenCountStatements.set(db, stmt);
|
|
167398
|
+
}
|
|
167399
|
+
return stmt;
|
|
167400
|
+
}
|
|
167401
|
+
function updateTagTokenCount(db, sessionId, tagNumber, newTokenCount) {
|
|
167402
|
+
getUpdateTagTokenCountStatement(db).run(newTokenCount, sessionId, tagNumber);
|
|
167403
|
+
}
|
|
167404
|
+
function getAllStatusTagTokenTotalsFlat(db, sessionId) {
|
|
167405
|
+
const rows = db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
167406
|
+
FROM tags
|
|
167407
|
+
WHERE session_id = ?`).all(sessionId);
|
|
167408
|
+
const totals = new Map;
|
|
167409
|
+
const nullMessageIds = new Set;
|
|
167410
|
+
for (const row of rows) {
|
|
167411
|
+
if (row.type === "tool" && row.tool_owner_message_id === null)
|
|
167412
|
+
continue;
|
|
167413
|
+
const owner = ownerMessageIdForTagRow(row);
|
|
167414
|
+
if (row.token_count === null) {
|
|
167415
|
+
nullMessageIds.add(owner);
|
|
167416
|
+
totals.delete(owner);
|
|
167417
|
+
continue;
|
|
167418
|
+
}
|
|
167419
|
+
if (nullMessageIds.has(owner))
|
|
167420
|
+
continue;
|
|
167421
|
+
const weight = (row.token_count ?? 0) + (row.input_token_count ?? 0) + (row.reasoning_token_count ?? 0);
|
|
167422
|
+
totals.set(owner, (totals.get(owner) ?? 0) + weight);
|
|
167423
|
+
}
|
|
167424
|
+
return { totals, nullMessageIds };
|
|
167425
|
+
}
|
|
167426
|
+
function updateTagInputTokenCount(db, sessionId, tagNumber, newInputTokenCount) {
|
|
167427
|
+
getUpdateTagInputTokenCountStatement(db).run(newInputTokenCount, sessionId, tagNumber);
|
|
167428
|
+
}
|
|
167429
|
+
function tagTokenCountIsNull(db, sessionId, tagNumber) {
|
|
167430
|
+
const row = db.prepare("SELECT token_count FROM tags WHERE session_id = ? AND tag_number = ?").get(sessionId, tagNumber);
|
|
167431
|
+
return row !== undefined && row.token_count === null;
|
|
167432
|
+
}
|
|
167433
|
+
function backfillTagTokenCounts(db, sessionId, tagNumber, counts) {
|
|
167434
|
+
db.prepare(`UPDATE tags
|
|
167435
|
+
SET token_count = ?, input_token_count = ?, reasoning_token_count = ?
|
|
167436
|
+
WHERE session_id = ? AND tag_number = ? AND token_count IS NULL`).run(counts.tokenCount ?? null, counts.inputTokenCount ?? null, counts.reasoningTokenCount ?? null, sessionId, tagNumber);
|
|
167437
|
+
}
|
|
166562
167438
|
function getMaxTagNumberBySessionStatement(db) {
|
|
166563
167439
|
let stmt = getMaxTagNumberBySessionStatements.get(db);
|
|
166564
167440
|
if (!stmt) {
|
|
@@ -166611,8 +167487,8 @@ function isMaxTagNumberRow(row) {
|
|
|
166611
167487
|
const r = row;
|
|
166612
167488
|
return typeof r.max_tag_number === "number";
|
|
166613
167489
|
}
|
|
166614
|
-
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null, entryFingerprint = null) {
|
|
166615
|
-
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId, entryFingerprint);
|
|
167490
|
+
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null, entryFingerprint = null, tokenCounts = null) {
|
|
167491
|
+
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId, entryFingerprint, tokenCounts?.tokenCount ?? null, tokenCounts?.inputTokenCount ?? null, tokenCounts?.reasoningTokenCount ?? null);
|
|
166616
167492
|
return tagNumber;
|
|
166617
167493
|
}
|
|
166618
167494
|
function updateTagStatus(db, sessionId, tagId, status) {
|
|
@@ -166680,13 +167556,6 @@ function getTagsByNumbers(db, sessionId, tagNumbers) {
|
|
|
166680
167556
|
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);
|
|
166681
167557
|
return rows.map(toTagEntry);
|
|
166682
167558
|
}
|
|
166683
|
-
function getTopNBySize(db, sessionId, n) {
|
|
166684
|
-
if (n <= 0) {
|
|
166685
|
-
return [];
|
|
166686
|
-
}
|
|
166687
|
-
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);
|
|
166688
|
-
return rows.map(toTagEntry);
|
|
166689
|
-
}
|
|
166690
167559
|
var getToolTagNumberByOwnerStatements = new WeakMap;
|
|
166691
167560
|
var getNullOwnerToolTagStatements = new WeakMap;
|
|
166692
167561
|
var adoptNullOwnerToolTagStatements = new WeakMap;
|
|
@@ -166752,44 +167621,43 @@ var ERROR_CLASSES = new Set([
|
|
|
166752
167621
|
"permission_denied",
|
|
166753
167622
|
"unknown"
|
|
166754
167623
|
]);
|
|
167624
|
+
// src/tools/ctx-memory.ts
|
|
167625
|
+
init_logger();
|
|
167626
|
+
|
|
167627
|
+
// ../plugin/src/tools/ctx-memory/constants.ts
|
|
167628
|
+
var CTX_MEMORY_DESCRIPTION = `Durable project knowledge shared across every session on this project.
|
|
167629
|
+
|
|
167630
|
+
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.
|
|
167631
|
+
|
|
167632
|
+
Actions:
|
|
167633
|
+
- write: save a new memory (content + category).
|
|
167634
|
+
- update: rewrite one memory whose fact changed (ids: [one], content).
|
|
167635
|
+
- archive: retire wrong or obsolete memories (ids: [one or more], optional reason).
|
|
167636
|
+
- merge: collapse duplicates into one memory (ids: [two or more], content).
|
|
167637
|
+
|
|
167638
|
+
Example: ctx_memory(action="write", category="CONSTRAINTS", content="Pi stores sessions as JSONL under ~/.pi/agent/sessions/, not SQLite")`;
|
|
167639
|
+
|
|
166755
167640
|
// src/tools/ctx-memory.ts
|
|
166756
167641
|
var DEFAULT_LIST_LIMIT = 10;
|
|
166757
|
-
var
|
|
166758
|
-
|
|
166759
|
-
return VALID_CATEGORIES.has(value);
|
|
166760
|
-
}
|
|
166761
|
-
var ALL_ACTIONS = [
|
|
166762
|
-
"write",
|
|
166763
|
-
"delete",
|
|
166764
|
-
"list",
|
|
166765
|
-
"update",
|
|
166766
|
-
"merge",
|
|
166767
|
-
"archive"
|
|
166768
|
-
];
|
|
166769
|
-
var DREAMER_ONLY_ACTIONS = new Set([
|
|
166770
|
-
"list",
|
|
166771
|
-
"update",
|
|
166772
|
-
"merge",
|
|
166773
|
-
"archive"
|
|
166774
|
-
]);
|
|
167642
|
+
var ALL_ACTIONS = ["write", "archive", "update", "merge", "list"];
|
|
167643
|
+
var DREAMER_ONLY_ACTIONS = new Set(["list"]);
|
|
166775
167644
|
var ParamsSchema2 = exports_typebox.Object({
|
|
166776
|
-
action: exports_typebox.Union(ALL_ACTIONS.map((a) => exports_typebox.Literal(a)), { description: "
|
|
167645
|
+
action: exports_typebox.Union(ALL_ACTIONS.map((a) => exports_typebox.Literal(a)), { description: "What to do: write, update, archive, or merge" }),
|
|
166777
167646
|
content: exports_typebox.Optional(exports_typebox.String({
|
|
166778
|
-
description: "
|
|
166779
|
-
})),
|
|
166780
|
-
category: exports_typebox.Optional(exports_typebox.String({
|
|
166781
|
-
description: "Memory category (required for write, optional filter for list, optional override for merge). One of: " + CATEGORY_PRIORITY.join(", ")
|
|
167647
|
+
description: "The memory text — one standalone fact (required for write, update, merge)"
|
|
166782
167648
|
})),
|
|
166783
|
-
|
|
166784
|
-
description: "
|
|
167649
|
+
category: exports_typebox.Optional(exports_typebox.Union(V2_MEMORY_CATEGORIES.map((c) => exports_typebox.Literal(c)), {
|
|
167650
|
+
description: "What kind of fact this is (required for write; optional merge override)"
|
|
166785
167651
|
})),
|
|
166786
167652
|
ids: exports_typebox.Optional(exports_typebox.Array(exports_typebox.Number(), {
|
|
166787
|
-
description: "
|
|
167653
|
+
description: "Target memory id(s) from <project-memory>: update takes exactly one, archive one or more, merge two or more"
|
|
166788
167654
|
})),
|
|
166789
167655
|
limit: exports_typebox.Optional(exports_typebox.Number({
|
|
166790
|
-
description: "
|
|
167656
|
+
description: "Max results for list (default: 10)"
|
|
166791
167657
|
})),
|
|
166792
|
-
reason: exports_typebox.Optional(exports_typebox.String({
|
|
167658
|
+
reason: exports_typebox.Optional(exports_typebox.String({
|
|
167659
|
+
description: "Why the memory is being archived (optional, recommended)"
|
|
167660
|
+
}))
|
|
166793
167661
|
});
|
|
166794
167662
|
function ok2(text) {
|
|
166795
167663
|
return { content: [{ type: "text", text }], details: undefined };
|
|
@@ -166836,6 +167704,12 @@ function formatMemoryList(memories) {
|
|
|
166836
167704
|
].join(`
|
|
166837
167705
|
`);
|
|
166838
167706
|
}
|
|
167707
|
+
function isPrimaryMutableMemory(memory2) {
|
|
167708
|
+
return (memory2.status === "active" || memory2.status === "permanent") && memory2.supersededByMemoryId === null;
|
|
167709
|
+
}
|
|
167710
|
+
function inactiveMemoryError(id, action2) {
|
|
167711
|
+
return `Error: Memory with ID ${id} is archived or superseded; restore it before ${action2}.`;
|
|
167712
|
+
}
|
|
166839
167713
|
function queueEmbedding(args) {
|
|
166840
167714
|
const snapshot = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
166841
167715
|
if (!snapshot?.enabled)
|
|
@@ -166856,7 +167730,8 @@ function queueEmbedding(args) {
|
|
|
166856
167730
|
}
|
|
166857
167731
|
function createCtxMemoryTool(deps) {
|
|
166858
167732
|
const dreamerAllowed = deps.allowDreamerActions === true;
|
|
166859
|
-
const description = dreamerAllowed ?
|
|
167733
|
+
const description = dreamerAllowed ? `${CTX_MEMORY_DESCRIPTION}
|
|
167734
|
+
- list: enumerate stored memories (maintenance sessions).` : CTX_MEMORY_DESCRIPTION;
|
|
166860
167735
|
return {
|
|
166861
167736
|
name: "ctx_memory",
|
|
166862
167737
|
label: "Magic Context: Memory",
|
|
@@ -166877,13 +167752,10 @@ function createCtxMemoryTool(deps) {
|
|
|
166877
167752
|
const content = params.content?.trim();
|
|
166878
167753
|
if (!content)
|
|
166879
167754
|
return err2("Error: 'content' is required when action is 'write'.");
|
|
166880
|
-
const rawCategory = params.category
|
|
167755
|
+
const rawCategory = params.category;
|
|
166881
167756
|
if (!rawCategory) {
|
|
166882
167757
|
return err2("Error: 'category' is required when action is 'write'.");
|
|
166883
167758
|
}
|
|
166884
|
-
if (!isMemoryCategory2(rawCategory)) {
|
|
166885
|
-
return err2(`Error: Unknown memory category '${rawCategory}'. Valid: ${CATEGORY_PRIORITY.join(", ")}`);
|
|
166886
|
-
}
|
|
166887
167759
|
const existing = getMemoryByHash(deps.db, projectIdentity, rawCategory, computeNormalizedHash(content));
|
|
166888
167760
|
if (existing) {
|
|
166889
167761
|
updateMemorySeenCount(deps.db, existing.id);
|
|
@@ -166897,45 +167769,31 @@ function createCtxMemoryTool(deps) {
|
|
|
166897
167769
|
sourceType: dreamerAllowed ? "dreamer" : "agent"
|
|
166898
167770
|
});
|
|
166899
167771
|
queueEmbedding({ deps, projectIdentity, memoryId: memory2.id, content });
|
|
166900
|
-
invalidateAllMemoryBlockCaches(deps.db);
|
|
166901
167772
|
return ok2(`Saved memory [ID: ${memory2.id}] in ${rawCategory}.`);
|
|
166902
167773
|
}
|
|
166903
|
-
if (params.action === "delete") {
|
|
166904
|
-
if (typeof params.id !== "number" || !Number.isInteger(params.id)) {
|
|
166905
|
-
return err2("Error: 'id' is required when action is 'delete'.");
|
|
166906
|
-
}
|
|
166907
|
-
const memory2 = getMemoryById(deps.db, params.id);
|
|
166908
|
-
if (!memory2 || memory2.projectPath !== projectIdentity) {
|
|
166909
|
-
return err2(`Error: Memory with ID ${params.id} was not found.`);
|
|
166910
|
-
}
|
|
166911
|
-
deps.db.transaction(() => {
|
|
166912
|
-
archiveMemory(deps.db, params.id);
|
|
166913
|
-
queueMemoryMutation(deps.db, {
|
|
166914
|
-
projectPath: projectIdentity,
|
|
166915
|
-
mutationType: "delete",
|
|
166916
|
-
targetMemoryId: params.id
|
|
166917
|
-
});
|
|
166918
|
-
})();
|
|
166919
|
-
return ok2(`Archived memory [ID: ${params.id}].`);
|
|
166920
|
-
}
|
|
166921
167774
|
if (params.action === "list") {
|
|
166922
167775
|
const limit = normalizeLimit(params.limit);
|
|
166923
167776
|
const filtered = getMemoriesByProject(deps.db, projectIdentity);
|
|
166924
|
-
const category = params.category
|
|
167777
|
+
const category = params.category;
|
|
166925
167778
|
const filtered2 = category ? filtered.filter((m) => m.category === category) : filtered;
|
|
166926
167779
|
return ok2(formatMemoryList(filtered2.slice(0, limit)));
|
|
166927
167780
|
}
|
|
166928
167781
|
if (params.action === "update") {
|
|
166929
|
-
|
|
166930
|
-
|
|
167782
|
+
const updateIds = params.ids;
|
|
167783
|
+
if (!updateIds || updateIds.length !== 1 || !updateIds.every(Number.isInteger)) {
|
|
167784
|
+
return err2("Error: 'ids' must contain exactly one integer memory ID when action is 'update'.");
|
|
166931
167785
|
}
|
|
167786
|
+
const updateId = updateIds[0];
|
|
166932
167787
|
const content = params.content?.trim();
|
|
166933
167788
|
if (!content) {
|
|
166934
167789
|
return err2("Error: 'content' is required when action is 'update'.");
|
|
166935
167790
|
}
|
|
166936
|
-
const memory2 = getMemoryById(deps.db,
|
|
166937
|
-
if (!memory2 || memory2.projectPath
|
|
166938
|
-
return err2(`Error: Memory with ID ${
|
|
167791
|
+
const memory2 = getMemoryById(deps.db, updateId);
|
|
167792
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
167793
|
+
return err2(`Error: Memory with ID ${updateId} was not found.`);
|
|
167794
|
+
}
|
|
167795
|
+
if (!dreamerAllowed && !isPrimaryMutableMemory(memory2)) {
|
|
167796
|
+
return err2(inactiveMemoryError(updateId, "updating"));
|
|
166939
167797
|
}
|
|
166940
167798
|
const normalizedHash = computeNormalizedHash(content);
|
|
166941
167799
|
const duplicate = getMemoryByHash(deps.db, projectIdentity, memory2.category, normalizedHash);
|
|
@@ -166956,9 +167814,12 @@ function createCtxMemoryTool(deps) {
|
|
|
166956
167814
|
return ok2(`Updated memory [ID: ${memory2.id}] in ${memory2.category}.`);
|
|
166957
167815
|
}
|
|
166958
167816
|
if (params.action === "merge") {
|
|
166959
|
-
const ids = params.ids
|
|
166960
|
-
if (!ids || ids.length < 2) {
|
|
166961
|
-
return err2("Error: 'ids' must include at least two memory IDs when action is 'merge'.");
|
|
167817
|
+
const ids = params.ids;
|
|
167818
|
+
if (!ids || ids.length < 2 || !ids.every(Number.isInteger)) {
|
|
167819
|
+
return err2("Error: 'ids' must include at least two integer memory IDs when action is 'merge'.");
|
|
167820
|
+
}
|
|
167821
|
+
if (new Set(ids).size !== ids.length) {
|
|
167822
|
+
return err2("Error: 'ids' must include at least two distinct memory IDs when action is 'merge'.");
|
|
166962
167823
|
}
|
|
166963
167824
|
const content = params.content?.trim();
|
|
166964
167825
|
if (!content) {
|
|
@@ -166968,14 +167829,17 @@ function createCtxMemoryTool(deps) {
|
|
|
166968
167829
|
if (sourceMemories.length !== ids.length) {
|
|
166969
167830
|
return err2("Error: One or more source memories were not found.");
|
|
166970
167831
|
}
|
|
166971
|
-
if (
|
|
166972
|
-
|
|
166973
|
-
|
|
166974
|
-
|
|
166975
|
-
|
|
166976
|
-
|
|
167832
|
+
if (!dreamerAllowed) {
|
|
167833
|
+
const foreign = sourceMemories.find((memory2) => !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity));
|
|
167834
|
+
if (foreign) {
|
|
167835
|
+
return err2(`Error: Memory with ID ${foreign.id} was not found.`);
|
|
167836
|
+
}
|
|
167837
|
+
const inactive = sourceMemories.find((memory2) => !isPrimaryMutableMemory(memory2));
|
|
167838
|
+
if (inactive) {
|
|
167839
|
+
return err2(inactiveMemoryError(inactive.id, "merging"));
|
|
167840
|
+
}
|
|
166977
167841
|
}
|
|
166978
|
-
const requestedCategoryTyped =
|
|
167842
|
+
const requestedCategoryTyped = params.category;
|
|
166979
167843
|
const fallbackCategory = sourceMemories[0]?.category;
|
|
166980
167844
|
const category = requestedCategoryTyped ?? fallbackCategory;
|
|
166981
167845
|
if (!category) {
|
|
@@ -167029,7 +167893,7 @@ function createCtxMemoryTool(deps) {
|
|
|
167029
167893
|
}
|
|
167030
167894
|
supersededMemory(deps.db, memory2.id, canonicalMemory.id);
|
|
167031
167895
|
queueMemoryMutation(deps.db, {
|
|
167032
|
-
projectPath: memory2.projectPath,
|
|
167896
|
+
projectPath: normalizeStoredProjectPath(memory2.projectPath),
|
|
167033
167897
|
mutationType: "superseded",
|
|
167034
167898
|
targetMemoryId: memory2.id,
|
|
167035
167899
|
supersededById: canonicalMemory.id
|
|
@@ -167037,7 +167901,7 @@ function createCtxMemoryTool(deps) {
|
|
|
167037
167901
|
}
|
|
167038
167902
|
if (canonicalExisting && canonicalContentChanged) {
|
|
167039
167903
|
queueMemoryMutation(deps.db, {
|
|
167040
|
-
projectPath: canonicalMemory.projectPath,
|
|
167904
|
+
projectPath: normalizeStoredProjectPath(canonicalMemory.projectPath),
|
|
167041
167905
|
mutationType: "update",
|
|
167042
167906
|
targetMemoryId: canonicalMemory.id,
|
|
167043
167907
|
category,
|
|
@@ -167055,29 +167919,57 @@ function createCtxMemoryTool(deps) {
|
|
|
167055
167919
|
return ok2(`Merged memories [${ids.join(", ")}] into canonical memory [ID: ${canonicalMemory.id}] in ${category}; superseded [${supersededIds.join(", ")}].`);
|
|
167056
167920
|
}
|
|
167057
167921
|
if (params.action === "archive") {
|
|
167058
|
-
|
|
167059
|
-
|
|
167922
|
+
const archiveIds = params.ids;
|
|
167923
|
+
if (!archiveIds || archiveIds.length === 0 || !archiveIds.every(Number.isInteger)) {
|
|
167924
|
+
return err2("Error: 'ids' must contain at least one integer memory ID when action is 'archive'.");
|
|
167060
167925
|
}
|
|
167061
|
-
const
|
|
167062
|
-
|
|
167063
|
-
|
|
167926
|
+
for (const memoryId of archiveIds) {
|
|
167927
|
+
const memory2 = getMemoryById(deps.db, memoryId);
|
|
167928
|
+
if (!memory2 || !storedPathBelongsToIdentity(memory2.projectPath, projectIdentity)) {
|
|
167929
|
+
return err2(`Error: Memory with ID ${memoryId} was not found.`);
|
|
167930
|
+
}
|
|
167931
|
+
if (!dreamerAllowed && !isPrimaryMutableMemory(memory2)) {
|
|
167932
|
+
return err2(inactiveMemoryError(memoryId, "archiving"));
|
|
167933
|
+
}
|
|
167064
167934
|
}
|
|
167065
167935
|
deps.db.transaction(() => {
|
|
167066
|
-
|
|
167067
|
-
|
|
167068
|
-
|
|
167069
|
-
|
|
167070
|
-
|
|
167071
|
-
|
|
167936
|
+
for (const memoryId of archiveIds) {
|
|
167937
|
+
archiveMemory(deps.db, memoryId, params.reason);
|
|
167938
|
+
queueMemoryMutation(deps.db, {
|
|
167939
|
+
projectPath: projectIdentity,
|
|
167940
|
+
mutationType: "archive",
|
|
167941
|
+
targetMemoryId: memoryId
|
|
167942
|
+
});
|
|
167943
|
+
}
|
|
167072
167944
|
})();
|
|
167073
167945
|
const reasonSuffix = params.reason ? ` (${params.reason})` : "";
|
|
167074
|
-
|
|
167946
|
+
const idList = archiveIds.join(", ");
|
|
167947
|
+
const plural = archiveIds.length > 1 ? "memories" : "memory";
|
|
167948
|
+
return ok2(`Archived ${plural} [ID: ${idList}]${reasonSuffix}.`);
|
|
167075
167949
|
}
|
|
167076
167950
|
return err2("Error: Unknown action.");
|
|
167077
167951
|
}
|
|
167078
167952
|
};
|
|
167079
167953
|
}
|
|
167080
167954
|
|
|
167955
|
+
// ../plugin/src/tools/ctx-note/constants.ts
|
|
167956
|
+
var CTX_NOTE_DESCRIPTION = `Working notes for this session's future — reminders, follow-ups, and things to revisit later.
|
|
167957
|
+
|
|
167958
|
+
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.
|
|
167959
|
+
|
|
167960
|
+
Actions:
|
|
167961
|
+
- write: save a note (content). Add surface_condition to make it a smart note (below).
|
|
167962
|
+
- 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.
|
|
167963
|
+
- update / dismiss: change or retire a note by note_id.
|
|
167964
|
+
|
|
167965
|
+
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:
|
|
167966
|
+
✓ "When PR #42 in cortexkit/magic-context is merged"
|
|
167967
|
+
✓ "When the latest release tag is >= v0.22.0"
|
|
167968
|
+
✓ "When packages/plugin/src/foo.ts contains a function named bar"
|
|
167969
|
+
✗ "When the user mentions X" / "when we revisit Y" / "after we finish this refactor" — no external signal; write a regular note instead.
|
|
167970
|
+
|
|
167971
|
+
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")`;
|
|
167972
|
+
|
|
167081
167973
|
// src/tools/ctx-note.ts
|
|
167082
167974
|
var FILTER_VALUES = [
|
|
167083
167975
|
"active",
|
|
@@ -167097,13 +167989,19 @@ var ParamsSchema3 = exports_typebox.Object({
|
|
|
167097
167989
|
})),
|
|
167098
167990
|
content: exports_typebox.Optional(exports_typebox.String({ description: "Note text to store when action is 'write'." })),
|
|
167099
167991
|
surface_condition: exports_typebox.Optional(exports_typebox.String({
|
|
167100
|
-
description: "
|
|
167992
|
+
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."
|
|
167101
167993
|
})),
|
|
167102
167994
|
note_id: exports_typebox.Optional(exports_typebox.Number({
|
|
167103
167995
|
description: "Note ID (required for 'dismiss' and 'update' actions)."
|
|
167104
167996
|
})),
|
|
167105
167997
|
filter: exports_typebox.Optional(exports_typebox.Union(FILTER_VALUES.map((value) => exports_typebox.Literal(value)), {
|
|
167106
167998
|
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."
|
|
167999
|
+
})),
|
|
168000
|
+
limit: exports_typebox.Optional(exports_typebox.Number({
|
|
168001
|
+
description: "Max notes per section for read, newest first (default: 25)"
|
|
168002
|
+
})),
|
|
168003
|
+
offset: exports_typebox.Optional(exports_typebox.Number({
|
|
168004
|
+
description: "Skip this many newest notes for read — page older ones (default: 0)"
|
|
167107
168005
|
}))
|
|
167108
168006
|
});
|
|
167109
168007
|
function ok3(text) {
|
|
@@ -167140,15 +168038,20 @@ function formatNoteLine(note) {
|
|
|
167140
168038
|
var DISMISS_FOOTER = `
|
|
167141
168039
|
|
|
167142
168040
|
To dismiss a stale note: ctx_note(action="dismiss", note_id=N)`;
|
|
168041
|
+
var DEFAULT_READ_LIMIT = 25;
|
|
168042
|
+
function paginateNewestFirst(notes, limit, offset) {
|
|
168043
|
+
const total = notes.length;
|
|
168044
|
+
const newestFirst = [...notes].reverse();
|
|
168045
|
+
const page = newestFirst.slice(offset, offset + limit);
|
|
168046
|
+
const remaining = total - offset - page.length;
|
|
168047
|
+
const footer = remaining > 0 ? `Showing ${page.length} of ${total} (newest first) — ${remaining} older: ctx_note(action="read", offset=${offset + page.length})` : null;
|
|
168048
|
+
return { page, total, footer };
|
|
168049
|
+
}
|
|
167143
168050
|
function createCtxNoteTool(deps) {
|
|
167144
168051
|
return {
|
|
167145
168052
|
name: "ctx_note",
|
|
167146
168053
|
label: "Magic Context: Notes",
|
|
167147
|
-
description:
|
|
167148
|
-
` + `Use this for short goals, constraints, decisions, or reminders worth carrying forward.
|
|
167149
|
-
|
|
167150
|
-
` + `Actions:
|
|
167151
|
-
` + "- `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")`',
|
|
168054
|
+
description: CTX_NOTE_DESCRIPTION,
|
|
167152
168055
|
parameters: ParamsSchema3,
|
|
167153
168056
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
167154
168057
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
@@ -167230,11 +168133,15 @@ function createCtxNoteTool(deps) {
|
|
|
167230
168133
|
- ${parts.join(`
|
|
167231
168134
|
- `)}`);
|
|
167232
168135
|
}
|
|
168136
|
+
const limit = typeof params.limit === "number" && params.limit > 0 ? Math.floor(params.limit) : DEFAULT_READ_LIMIT;
|
|
168137
|
+
const offset = typeof params.offset === "number" && params.offset > 0 ? Math.floor(params.offset) : 0;
|
|
167233
168138
|
const sections = readNotes({
|
|
167234
168139
|
db: deps.db,
|
|
167235
168140
|
sessionId,
|
|
167236
168141
|
cwd: ctx.cwd,
|
|
167237
|
-
filter: params.filter
|
|
168142
|
+
filter: params.filter,
|
|
168143
|
+
limit,
|
|
168144
|
+
offset
|
|
167238
168145
|
});
|
|
167239
168146
|
try {
|
|
167240
168147
|
setNoteLastReadAt(deps.db, sessionId);
|
|
@@ -167242,7 +168149,7 @@ function createCtxNoteTool(deps) {
|
|
|
167242
168149
|
if (sections.length === 0) {
|
|
167243
168150
|
return ok3(`## Notes
|
|
167244
168151
|
|
|
167245
|
-
No notes
|
|
168152
|
+
No session notes or smart notes.`);
|
|
167246
168153
|
}
|
|
167247
168154
|
const body = sections.join(`
|
|
167248
168155
|
|
|
@@ -167269,10 +168176,14 @@ function readNotes(args) {
|
|
|
167269
168176
|
}) : [];
|
|
167270
168177
|
const sections2 = [];
|
|
167271
168178
|
if (sessionNotes2.length > 0) {
|
|
168179
|
+
const { page, footer } = paginateNewestFirst(sessionNotes2, args.limit, args.offset);
|
|
168180
|
+
const lines = page.map(formatNoteLine).join(`
|
|
168181
|
+
`);
|
|
167272
168182
|
sections2.push(`## Session Notes
|
|
167273
168183
|
|
|
167274
|
-
${
|
|
167275
|
-
|
|
168184
|
+
${lines}${footer ? `
|
|
168185
|
+
|
|
168186
|
+
${footer}` : ""}`);
|
|
167276
168187
|
}
|
|
167277
168188
|
if (readySmartNotes.length > 0) {
|
|
167278
168189
|
sections2.push(`## \uD83D\uDD14 Ready Smart Notes
|
|
@@ -167303,17 +168214,25 @@ ${readySmartNotes.map(formatNoteLine).join(`
|
|
|
167303
168214
|
}) : [];
|
|
167304
168215
|
const sections = [];
|
|
167305
168216
|
if (sessionNotes.length > 0) {
|
|
168217
|
+
const { page, footer } = paginateNewestFirst(sessionNotes, args.limit, args.offset);
|
|
168218
|
+
const lines = page.map(formatNoteLine).join(`
|
|
168219
|
+
`);
|
|
167306
168220
|
sections.push(`## Session Notes
|
|
167307
168221
|
|
|
167308
|
-
${
|
|
167309
|
-
|
|
168222
|
+
${lines}${footer ? `
|
|
168223
|
+
|
|
168224
|
+
${footer}` : ""}`);
|
|
167310
168225
|
}
|
|
167311
168226
|
if (smartNotes.length > 0) {
|
|
168227
|
+
const { page, footer } = paginateNewestFirst(smartNotes, args.limit, args.offset);
|
|
168228
|
+
const lines = page.map(formatNoteLine).join(`
|
|
168229
|
+
|
|
168230
|
+
`);
|
|
167312
168231
|
sections.push(`## Smart Notes
|
|
167313
168232
|
|
|
167314
|
-
${
|
|
168233
|
+
${lines}${footer ? `
|
|
167315
168234
|
|
|
167316
|
-
`
|
|
168235
|
+
${footer}` : ""}`);
|
|
167317
168236
|
}
|
|
167318
168237
|
return sections;
|
|
167319
168238
|
}
|
|
@@ -167321,7 +168240,7 @@ ${smartNotes.map(formatNoteLine).join(`
|
|
|
167321
168240
|
// ../plugin/src/features/magic-context/range-parser.ts
|
|
167322
168241
|
function parseRangeString(input) {
|
|
167323
168242
|
const maxRangeElements = 1000;
|
|
167324
|
-
const trimmed = input.trim();
|
|
168243
|
+
const trimmed = input.replace(/§/g, "").trim();
|
|
167325
168244
|
if (trimmed === "") {
|
|
167326
168245
|
throw new Error("Range string must not be empty");
|
|
167327
168246
|
}
|
|
@@ -167469,7 +168388,11 @@ function createCtxReduceTool(deps) {
|
|
|
167469
168388
|
};
|
|
167470
168389
|
}
|
|
167471
168390
|
|
|
168391
|
+
// ../plugin/src/features/magic-context/search.ts
|
|
168392
|
+
init_logger();
|
|
168393
|
+
|
|
167472
168394
|
// ../plugin/src/features/magic-context/git-commits/git-log-reader.ts
|
|
168395
|
+
init_logger();
|
|
167473
168396
|
import { execFile } from "node:child_process";
|
|
167474
168397
|
import { promisify } from "node:util";
|
|
167475
168398
|
var execFileAsync = promisify(execFile);
|
|
@@ -167553,7 +168476,11 @@ ${body}` : subject;
|
|
|
167553
168476
|
}
|
|
167554
168477
|
return commits;
|
|
167555
168478
|
}
|
|
168479
|
+
// ../plugin/src/features/magic-context/git-commits/indexer.ts
|
|
168480
|
+
init_logger();
|
|
168481
|
+
|
|
167556
168482
|
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
168483
|
+
init_logger();
|
|
167557
168484
|
var insertStatements = new WeakMap;
|
|
167558
168485
|
var existingShasStatements = new WeakMap;
|
|
167559
168486
|
var projectCountStatements = new WeakMap;
|
|
@@ -167766,6 +168693,7 @@ async function embedUnembeddedCommits(db, projectPath) {
|
|
|
167766
168693
|
}
|
|
167767
168694
|
}
|
|
167768
168695
|
// ../plugin/src/features/magic-context/git-commits/search-git-commits.ts
|
|
168696
|
+
init_logger();
|
|
167769
168697
|
var ftsStatements = new WeakMap;
|
|
167770
168698
|
var ftsPlainStatements = new WeakMap;
|
|
167771
168699
|
var getBySHAStatements = new WeakMap;
|
|
@@ -168436,6 +169364,9 @@ class BoundedSessionMap {
|
|
|
168436
169364
|
}
|
|
168437
169365
|
}
|
|
168438
169366
|
|
|
169367
|
+
// ../plugin/src/hooks/magic-context/inject-compartments.ts
|
|
169368
|
+
init_logger();
|
|
169369
|
+
|
|
168439
169370
|
// ../plugin/src/hooks/magic-context/decay-curve.ts
|
|
168440
169371
|
var H50 = 24;
|
|
168441
169372
|
var D = 25;
|
|
@@ -168499,6 +169430,9 @@ function escapeXmlAttr2(s) {
|
|
|
168499
169430
|
function escapeXmlContent2(s) {
|
|
168500
169431
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
168501
169432
|
}
|
|
169433
|
+
function isTieredRow(c) {
|
|
169434
|
+
return typeof c.p1 === "string" && c.p1.length > 0;
|
|
169435
|
+
}
|
|
168502
169436
|
function tierBody(c, tier2) {
|
|
168503
169437
|
const tiers = [c.p1, c.p2, c.p3, c.p4];
|
|
168504
169438
|
const requested = tiers[tier2 - 1];
|
|
@@ -168528,12 +169462,13 @@ function renderOneCompartment(c, tier2) {
|
|
|
168528
169462
|
const baseAttrs = `start="${c.startMessage}" end="${c.endMessage}" title="${escapeXmlAttr2(c.title)}"`;
|
|
168529
169463
|
if (tier2 >= 5)
|
|
168530
169464
|
return "";
|
|
168531
|
-
if (c.legacy === 1) {
|
|
168532
|
-
|
|
169465
|
+
if (c.legacy === 1 || !isTieredRow(c)) {
|
|
169466
|
+
const flat = (c.content ?? "").trim();
|
|
169467
|
+
if (tier2 >= 4 || flat.length === 0)
|
|
168533
169468
|
return `<compartment ${baseAttrs} />`;
|
|
168534
169469
|
return [
|
|
168535
169470
|
`<compartment ${baseAttrs}>`,
|
|
168536
|
-
escapeXmlContent2(legacyBodyForTier(
|
|
169471
|
+
escapeXmlContent2(legacyBodyForTier(flat, tier2)),
|
|
168537
169472
|
"</compartment>"
|
|
168538
169473
|
].join(`
|
|
168539
169474
|
`);
|
|
@@ -168714,6 +169649,7 @@ function isAftAvailable() {
|
|
|
168714
169649
|
}
|
|
168715
169650
|
|
|
168716
169651
|
// ../plugin/src/hooks/magic-context/key-files-block.ts
|
|
169652
|
+
init_logger();
|
|
168717
169653
|
var cachedKeyFilesBySession = new Map;
|
|
168718
169654
|
var staleUpdates = new Map;
|
|
168719
169655
|
function staleKey(update2) {
|
|
@@ -168967,6 +169903,21 @@ function renderMemoryBlockV2(memories, wrapper = "project-memory") {
|
|
|
168967
169903
|
`);
|
|
168968
169904
|
}
|
|
168969
169905
|
|
|
169906
|
+
// ../plugin/src/tools/ctx-search/constants.ts
|
|
169907
|
+
var CTX_SEARCH_DESCRIPTION = `Your long-term recall for this project — search everything that ever happened here, not just what's currently visible.
|
|
169908
|
+
|
|
169909
|
+
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.
|
|
169910
|
+
|
|
169911
|
+
Sources (omit for a broad search across all):
|
|
169912
|
+
- memory: curated cross-session project knowledge — rules, constraints, conventions.
|
|
169913
|
+
- 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).
|
|
169914
|
+
- git_commit: this repository's commit history.
|
|
169915
|
+
|
|
169916
|
+
Picking sources:
|
|
169917
|
+
- "when did this change / was this working before" → ["git_commit", "message"]
|
|
169918
|
+
- "did we discuss this earlier" → ["message"]
|
|
169919
|
+
- "what's our convention / rule for X" → ["memory"]`;
|
|
169920
|
+
|
|
168970
169921
|
// src/tools/ctx-search.ts
|
|
168971
169922
|
var DEFAULT_LIMIT = 10;
|
|
168972
169923
|
var ParamsSchema5 = exports_typebox.Object({
|
|
@@ -169050,18 +170001,7 @@ function createCtxSearchTool(deps) {
|
|
|
169050
170001
|
return {
|
|
169051
170002
|
name: "ctx_search",
|
|
169052
170003
|
label: "Magic Context: Search",
|
|
169053
|
-
description:
|
|
169054
|
-
|
|
169055
|
-
` + `Sources:
|
|
169056
|
-
` + `- memory: curated cross-session knowledge for this project
|
|
169057
|
-
` + `- message: raw user/assistant messages from older compartmentalized history
|
|
169058
|
-
` + `- git_commit: HEAD git commits (when git commit indexing is enabled)
|
|
169059
|
-
|
|
169060
|
-
` + "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"]
|
|
169061
|
-
` + `- "when did we change this" → ["git_commit"]
|
|
169062
|
-
` + `- "what is our naming convention" → ["memory"]
|
|
169063
|
-
` + `- "did we discuss this earlier" → ["message"]
|
|
169064
|
-
` + "Omit sources for a broad search across all enabled channels.",
|
|
170004
|
+
description: CTX_SEARCH_DESCRIPTION,
|
|
169065
170005
|
parameters: ParamsSchema5,
|
|
169066
170006
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
169067
170007
|
const query = params.query?.trim();
|
|
@@ -169080,6 +170020,7 @@ function createCtxSearchTool(deps) {
|
|
|
169080
170020
|
const embeddingEnabled = snapshot ? snapshot.enabled || snapshot.gitCommitEnabled : deps.embeddingEnabled;
|
|
169081
170021
|
const gitCommitsEnabled = snapshot?.gitCommitEnabled ?? deps.gitCommitsEnabled ?? false;
|
|
169082
170022
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
170023
|
+
const messageOrdinalCutoff = lastCompartmentEnd >= 0 ? lastCompartmentEnd : 0;
|
|
169083
170024
|
const visibleMemoryIds = getVisibleMemoryIds(deps.db, sessionId);
|
|
169084
170025
|
const results = await unifiedSearch(deps.db, sessionId, projectIdentity, query, {
|
|
169085
170026
|
limit: normalizeLimit3(params.limit),
|
|
@@ -169090,7 +170031,7 @@ function createCtxSearchTool(deps) {
|
|
|
169090
170031
|
return result?.vector ?? null;
|
|
169091
170032
|
},
|
|
169092
170033
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
169093
|
-
maxMessageOrdinal:
|
|
170034
|
+
maxMessageOrdinal: messageOrdinalCutoff,
|
|
169094
170035
|
gitCommitsEnabled,
|
|
169095
170036
|
sources: params.sources,
|
|
169096
170037
|
visibleMemoryIds,
|
|
@@ -169177,13 +170118,15 @@ function registerMagicContextTools(pi, opts) {
|
|
|
169177
170118
|
embeddingEnabled: opts.embeddingEnabled,
|
|
169178
170119
|
gitCommitsEnabled: opts.gitCommitsEnabled
|
|
169179
170120
|
}));
|
|
169180
|
-
|
|
169181
|
-
|
|
169182
|
-
|
|
169183
|
-
|
|
169184
|
-
|
|
169185
|
-
|
|
169186
|
-
|
|
170121
|
+
if (opts.memoryToolEnabled !== false) {
|
|
170122
|
+
pi.registerTool(createCtxMemoryTool({
|
|
170123
|
+
db: opts.db,
|
|
170124
|
+
ensureProjectRegistered: opts.ensureProjectRegistered,
|
|
170125
|
+
memoryEnabled: opts.memoryEnabled,
|
|
170126
|
+
embeddingEnabled: opts.embeddingEnabled,
|
|
170127
|
+
allowDreamerActions: opts.allowDreamerActions ?? false
|
|
170128
|
+
}));
|
|
170129
|
+
}
|
|
169187
170130
|
if (!opts.sessionScopedToolsDisabled) {
|
|
169188
170131
|
pi.registerTool(createCtxNoteTool({
|
|
169189
170132
|
db: opts.db,
|
|
@@ -169206,7 +170149,7 @@ var openedDb;
|
|
|
169206
170149
|
function magicContextSubagentExtension(pi) {
|
|
169207
170150
|
setHarness("pi");
|
|
169208
170151
|
pi.registerFlag(SUBAGENT_DREAMER_ACTIONS_FLAG, {
|
|
169209
|
-
description: "
|
|
170152
|
+
description: "Register ctx_memory with dreamer actions for Magic Context subagents.",
|
|
169210
170153
|
type: "boolean",
|
|
169211
170154
|
default: false
|
|
169212
170155
|
});
|
|
@@ -169224,10 +170167,11 @@ function magicContextSubagentExtension(pi) {
|
|
|
169224
170167
|
registerMagicContextTools(pi, {
|
|
169225
170168
|
db,
|
|
169226
170169
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
170170
|
+
memoryToolEnabled: dreamerActionsEnabled,
|
|
169227
170171
|
allowDreamerActions: dreamerActionsEnabled,
|
|
169228
170172
|
sessionScopedToolsDisabled: true
|
|
169229
170173
|
});
|
|
169230
|
-
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})`);
|
|
170174
|
+
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})`);
|
|
169231
170175
|
} catch (err5) {
|
|
169232
170176
|
const message = err5 instanceof Error ? err5.message : String(err5);
|
|
169233
170177
|
log(`[pi-subagent] startup failed: ${message}`);
|