@loreai/core 0.19.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bun/agents-file.d.ts.map +1 -1
- package/dist/bun/config.d.ts +1 -1
- package/dist/bun/config.d.ts.map +1 -1
- package/dist/bun/db.d.ts +13 -1
- package/dist/bun/db.d.ts.map +1 -1
- package/dist/bun/embedding.d.ts.map +1 -1
- package/dist/bun/git.d.ts.map +1 -1
- package/dist/bun/gradient.d.ts +39 -13
- package/dist/bun/gradient.d.ts.map +1 -1
- package/dist/bun/hosted.d.ts +36 -0
- package/dist/bun/hosted.d.ts.map +1 -0
- package/dist/bun/index.d.ts +3 -2
- package/dist/bun/index.d.ts.map +1 -1
- package/dist/bun/index.js +295 -235
- package/dist/bun/index.js.map +4 -4
- package/dist/bun/lat-reader.d.ts.map +1 -1
- package/dist/node/agents-file.d.ts.map +1 -1
- package/dist/node/config.d.ts +1 -1
- package/dist/node/config.d.ts.map +1 -1
- package/dist/node/db.d.ts +13 -1
- package/dist/node/db.d.ts.map +1 -1
- package/dist/node/embedding.d.ts.map +1 -1
- package/dist/node/git.d.ts.map +1 -1
- package/dist/node/gradient.d.ts +39 -13
- package/dist/node/gradient.d.ts.map +1 -1
- package/dist/node/hosted.d.ts +36 -0
- package/dist/node/hosted.d.ts.map +1 -0
- package/dist/node/index.d.ts +3 -2
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +295 -235
- package/dist/node/index.js.map +4 -4
- package/dist/node/lat-reader.d.ts.map +1 -1
- package/dist/types/agents-file.d.ts.map +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/db.d.ts +13 -1
- package/dist/types/db.d.ts.map +1 -1
- package/dist/types/embedding.d.ts.map +1 -1
- package/dist/types/git.d.ts.map +1 -1
- package/dist/types/gradient.d.ts +39 -13
- package/dist/types/gradient.d.ts.map +1 -1
- package/dist/types/hosted.d.ts +36 -0
- package/dist/types/hosted.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lat-reader.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/agents-file.ts +12 -0
- package/src/config.ts +14 -17
- package/src/db.ts +39 -6
- package/src/embedding.ts +43 -5
- package/src/git.ts +4 -0
- package/src/gradient.ts +167 -145
- package/src/hosted.ts +46 -0
- package/src/index.ts +9 -4
- package/src/lat-reader.ts +4 -0
package/dist/node/index.js
CHANGED
|
@@ -168,6 +168,17 @@ import { mkdirSync } from "fs";
|
|
|
168
168
|
|
|
169
169
|
// src/git.ts
|
|
170
170
|
import { execSync } from "child_process";
|
|
171
|
+
|
|
172
|
+
// src/hosted.ts
|
|
173
|
+
var _hostedMode = false;
|
|
174
|
+
function enableHostedMode() {
|
|
175
|
+
_hostedMode = true;
|
|
176
|
+
}
|
|
177
|
+
function isHostedMode() {
|
|
178
|
+
return _hostedMode;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/git.ts
|
|
171
182
|
function normalizeRemoteUrl(url2) {
|
|
172
183
|
let normalized = url2.trim();
|
|
173
184
|
const sshMatch = normalized.match(/^[\w.-]+@([\w.-]+):(.+)$/);
|
|
@@ -192,6 +203,7 @@ function clearGitRemoteCache() {
|
|
|
192
203
|
gitRemoteCache.clear();
|
|
193
204
|
}
|
|
194
205
|
function getGitRemote(path) {
|
|
206
|
+
if (isHostedMode()) return null;
|
|
195
207
|
const cached2 = gitRemoteCache.get(path);
|
|
196
208
|
if (cached2 !== void 0) return cached2;
|
|
197
209
|
try {
|
|
@@ -939,7 +951,7 @@ function close() {
|
|
|
939
951
|
instance = void 0;
|
|
940
952
|
}
|
|
941
953
|
}
|
|
942
|
-
function ensureProject(path, name) {
|
|
954
|
+
function ensureProject(path, name, suppliedGitRemote) {
|
|
943
955
|
if (!process.env.LORE_DB_PATH && /^\/test\//.test(path)) {
|
|
944
956
|
throw new Error(
|
|
945
957
|
`Refusing to create project with test path "${path}" in the production DB. Set LORE_DB_PATH to a temp path, or run tests via \`bun test\` from the repo root.`
|
|
@@ -948,22 +960,22 @@ function ensureProject(path, name) {
|
|
|
948
960
|
const existing = db().query("SELECT id, git_remote FROM projects WHERE path = ?").get(path);
|
|
949
961
|
if (existing) {
|
|
950
962
|
if (!existing.git_remote) {
|
|
951
|
-
const
|
|
952
|
-
if (
|
|
963
|
+
const resolvedRemote = suppliedGitRemote ?? getGitRemote(path);
|
|
964
|
+
if (resolvedRemote) {
|
|
953
965
|
const conflict = db().query(
|
|
954
966
|
"SELECT id FROM projects WHERE git_remote = ? AND id != ? LIMIT 1"
|
|
955
|
-
).get(
|
|
967
|
+
).get(resolvedRemote, existing.id);
|
|
956
968
|
if (conflict) {
|
|
957
969
|
mergeProjectInternal(conflict.id, existing.id);
|
|
958
970
|
}
|
|
959
|
-
db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(
|
|
971
|
+
db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(resolvedRemote, existing.id);
|
|
960
972
|
}
|
|
961
973
|
}
|
|
962
974
|
return existing.id;
|
|
963
975
|
}
|
|
964
976
|
const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
|
|
965
977
|
if (alias) return alias.project_id;
|
|
966
|
-
const gitRemote = getGitRemote(path);
|
|
978
|
+
const gitRemote = suppliedGitRemote ?? getGitRemote(path);
|
|
967
979
|
if (gitRemote) {
|
|
968
980
|
const byRemote = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
|
|
969
981
|
if (byRemote) {
|
|
@@ -991,6 +1003,20 @@ function projectId(path) {
|
|
|
991
1003
|
const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
|
|
992
1004
|
return alias?.project_id;
|
|
993
1005
|
}
|
|
1006
|
+
function resolveProjectByRemoteOrPath(gitRemote, path) {
|
|
1007
|
+
if (gitRemote) {
|
|
1008
|
+
const row = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
|
|
1009
|
+
if (row) return row.id;
|
|
1010
|
+
}
|
|
1011
|
+
if (path) {
|
|
1012
|
+
return projectId(path) ?? null;
|
|
1013
|
+
}
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
function projectPath(id) {
|
|
1017
|
+
const row = db().query("SELECT path FROM projects WHERE id = ?").get(id);
|
|
1018
|
+
return row?.path ?? null;
|
|
1019
|
+
}
|
|
994
1020
|
function projectName(id) {
|
|
995
1021
|
const row = db().query("SELECT name FROM projects WHERE id = ?").get(id);
|
|
996
1022
|
return row?.name ?? null;
|
|
@@ -999,13 +1025,13 @@ function isFirstRun() {
|
|
|
999
1025
|
const row = db().query("SELECT COUNT(*) as count FROM projects").get();
|
|
1000
1026
|
return row.count === 0;
|
|
1001
1027
|
}
|
|
1002
|
-
function getLastImportAt(
|
|
1003
|
-
const id = ensureProject(
|
|
1028
|
+
function getLastImportAt(projectPath2) {
|
|
1029
|
+
const id = ensureProject(projectPath2);
|
|
1004
1030
|
const row = db().query("SELECT last_import_at FROM projects WHERE id = ?").get(id);
|
|
1005
1031
|
return row?.last_import_at ?? null;
|
|
1006
1032
|
}
|
|
1007
|
-
function setLastImportAt(
|
|
1008
|
-
const id = ensureProject(
|
|
1033
|
+
function setLastImportAt(projectPath2, timestamp) {
|
|
1034
|
+
const id = ensureProject(projectPath2);
|
|
1009
1035
|
db().query("UPDATE projects SET last_import_at = ? WHERE id = ?").run(timestamp, id);
|
|
1010
1036
|
}
|
|
1011
1037
|
function loadForceMinLayer(sessionID) {
|
|
@@ -26603,19 +26629,11 @@ var LoreConfig = external_exports.object({
|
|
|
26603
26629
|
* cost-aware formula from targetCacheReadCostPerTurn. 0 = disabled
|
|
26604
26630
|
* (no cap, use full context). Default: undefined (use cost-aware auto). */
|
|
26605
26631
|
maxLayer0Tokens: external_exports.number().min(0).optional(),
|
|
26606
|
-
/**
|
|
26607
|
-
|
|
26608
|
-
|
|
26609
|
-
* For opus-4-6 ($6.25/M write): $1.00 → 160K cap.
|
|
26610
|
-
* For sonnet-4 ($3.75/M write): $1.00 → 267K (effectively uncapped at 200K).
|
|
26611
|
-
* The cap is further adjusted dynamically per session based on observed
|
|
26612
|
-
* bust rate (EMA) and break frequency. Default: 1.00. Set to 0 to disable. */
|
|
26613
|
-
targetBustCost: external_exports.number().min(0).default(1),
|
|
26614
|
-
/** Direct override for the total-context token cap at layer 1+. When set,
|
|
26615
|
-
* bypasses the cost-aware formula from targetBustCost. 0 = disabled.
|
|
26616
|
-
* Default: undefined (use cost-aware auto). */
|
|
26632
|
+
/** @deprecated Ignored. Tier-based bust-vs-continue replaces static cap. */
|
|
26633
|
+
targetBustCost: external_exports.number().min(0).default(1).optional(),
|
|
26634
|
+
/** @deprecated Ignored. Tier-based bust-vs-continue replaces static cap. */
|
|
26617
26635
|
maxContextTokens: external_exports.number().min(0).optional()
|
|
26618
|
-
}).default({ distilled: 0.25, raw: 0.4, output: 0.25, ltm: 0.05, targetCacheReadCostPerTurn: 0.1
|
|
26636
|
+
}).default({ distilled: 0.25, raw: 0.4, output: 0.25, ltm: 0.05, targetCacheReadCostPerTurn: 0.1 }),
|
|
26619
26637
|
/**
|
|
26620
26638
|
* Cold-cache idle-resume handling.
|
|
26621
26639
|
*
|
|
@@ -26791,11 +26809,13 @@ function config2() {
|
|
|
26791
26809
|
return current;
|
|
26792
26810
|
}
|
|
26793
26811
|
async function load(directory) {
|
|
26794
|
-
|
|
26795
|
-
|
|
26796
|
-
|
|
26797
|
-
|
|
26798
|
-
|
|
26812
|
+
if (!isHostedMode()) {
|
|
26813
|
+
const path = join5(directory, ".lore.json");
|
|
26814
|
+
if (existsSync2(path)) {
|
|
26815
|
+
const raw = JSON.parse(readFileSync(path, "utf8"));
|
|
26816
|
+
current = LoreConfig.parse(raw);
|
|
26817
|
+
return current;
|
|
26818
|
+
}
|
|
26799
26819
|
}
|
|
26800
26820
|
current = LoreConfig.parse({});
|
|
26801
26821
|
return current;
|
|
@@ -26835,6 +26855,14 @@ function vendorRegistration() {
|
|
|
26835
26855
|
|
|
26836
26856
|
// src/embedding.ts
|
|
26837
26857
|
var EMBED_TIMEOUT_MS = 1e4;
|
|
26858
|
+
var LOCAL_MAX_CHARS = 4096 * 4;
|
|
26859
|
+
function safeLocalTruncate(text4) {
|
|
26860
|
+
if (text4.length <= LOCAL_MAX_CHARS) return text4;
|
|
26861
|
+
let end = LOCAL_MAX_CHARS;
|
|
26862
|
+
const code2 = text4.charCodeAt(end - 1);
|
|
26863
|
+
if (code2 >= 55296 && code2 <= 56319) end--;
|
|
26864
|
+
return text4.slice(0, end);
|
|
26865
|
+
}
|
|
26838
26866
|
var VOYAGE_API_URL = "https://api.voyageai.com/v1/embeddings";
|
|
26839
26867
|
var VoyageProvider = class {
|
|
26840
26868
|
maxBatchSize = 128;
|
|
@@ -27017,8 +27045,9 @@ var LocalProvider = class {
|
|
|
27017
27045
|
localProviderKnownBroken = true;
|
|
27018
27046
|
if (!localProviderErrorLogged) {
|
|
27019
27047
|
localProviderErrorLogged = true;
|
|
27020
|
-
|
|
27021
|
-
`local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback
|
|
27048
|
+
error(
|
|
27049
|
+
`local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback.`,
|
|
27050
|
+
new Error(`embedding worker init failed: ${msg.error}`)
|
|
27022
27051
|
);
|
|
27023
27052
|
}
|
|
27024
27053
|
for (const [, p2] of this.pendingRequests) {
|
|
@@ -27033,6 +27062,7 @@ var LocalProvider = class {
|
|
|
27033
27062
|
this.worker.on("error", (err) => {
|
|
27034
27063
|
this.workerInitError = err.message;
|
|
27035
27064
|
this.workerReady = false;
|
|
27065
|
+
error("embedding worker crashed:", err);
|
|
27036
27066
|
for (const [, p2] of this.pendingRequests) {
|
|
27037
27067
|
p2.reject(new LocalProviderUnavailableError(err));
|
|
27038
27068
|
}
|
|
@@ -27042,6 +27072,10 @@ var LocalProvider = class {
|
|
|
27042
27072
|
this.worker.on("exit", (code2) => {
|
|
27043
27073
|
if (code2 !== 0 && !this.workerInitError) {
|
|
27044
27074
|
this.workerInitError = `embedding worker exited with code ${code2}`;
|
|
27075
|
+
error(
|
|
27076
|
+
this.workerInitError,
|
|
27077
|
+
new Error(this.workerInitError)
|
|
27078
|
+
);
|
|
27045
27079
|
}
|
|
27046
27080
|
this.workerReady = false;
|
|
27047
27081
|
for (const [, p2] of this.pendingRequests) {
|
|
@@ -27072,8 +27106,9 @@ var LocalProvider = class {
|
|
|
27072
27106
|
}
|
|
27073
27107
|
async embed(texts, inputType) {
|
|
27074
27108
|
await this.ensureWorker();
|
|
27109
|
+
const truncated = texts.map(safeLocalTruncate);
|
|
27075
27110
|
const prefix = inputType === "document" ? "search_document: " : "search_query: ";
|
|
27076
|
-
const prefixed =
|
|
27111
|
+
const prefixed = truncated.map((t2) => prefix + t2);
|
|
27077
27112
|
const id = this.nextRequestId++;
|
|
27078
27113
|
const priority = inputType === "query" && texts.length === 1 ? "high" : "normal";
|
|
27079
27114
|
return new Promise((resolve, reject) => {
|
|
@@ -27301,27 +27336,30 @@ function vectorSearchAllDistillations(queryEmbedding, projectId2, limit = 20) {
|
|
|
27301
27336
|
return scored.slice(0, limit);
|
|
27302
27337
|
}
|
|
27303
27338
|
function embedKnowledgeEntry(id, title, content3) {
|
|
27339
|
+
if (!isAvailable()) return;
|
|
27304
27340
|
const text4 = `${title}
|
|
27305
27341
|
${content3}`;
|
|
27306
27342
|
embed([text4], "document").then(([vec]) => {
|
|
27307
27343
|
db().query("UPDATE knowledge SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27308
27344
|
}).catch((err) => {
|
|
27309
|
-
|
|
27345
|
+
error("embedding failed for knowledge entry", id, ":", err);
|
|
27310
27346
|
});
|
|
27311
27347
|
}
|
|
27312
27348
|
function embedDistillation(id, observations) {
|
|
27349
|
+
if (!isAvailable()) return;
|
|
27313
27350
|
embed([observations], "document").then(([vec]) => {
|
|
27314
27351
|
db().query("UPDATE distillations SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27315
27352
|
}).catch((err) => {
|
|
27316
|
-
|
|
27353
|
+
error("embedding failed for distillation", id, ":", err);
|
|
27317
27354
|
});
|
|
27318
27355
|
}
|
|
27319
27356
|
function embedTemporalMessage(id, content3) {
|
|
27357
|
+
if (!isAvailable()) return;
|
|
27320
27358
|
if (content3.length < 50) return;
|
|
27321
27359
|
embed([content3], "document").then(([vec]) => {
|
|
27322
27360
|
db().query("UPDATE temporal_messages SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27323
27361
|
}).catch((err) => {
|
|
27324
|
-
|
|
27362
|
+
error("embedding failed for temporal message", id, ":", err);
|
|
27325
27363
|
});
|
|
27326
27364
|
}
|
|
27327
27365
|
function vectorSearchTemporal(queryEmbedding, projectId2, limit = 10, sessionId) {
|
|
@@ -27441,6 +27479,7 @@ ${r.content}` }));
|
|
|
27441
27479
|
}
|
|
27442
27480
|
} catch (err) {
|
|
27443
27481
|
error(`embedding backfill batch failed (${batch.length} items):`, err);
|
|
27482
|
+
if (err instanceof LocalProviderUnavailableError) break;
|
|
27444
27483
|
}
|
|
27445
27484
|
}
|
|
27446
27485
|
if (embedded > 0) {
|
|
@@ -27474,6 +27513,7 @@ async function backfillDistillationEmbeddings() {
|
|
|
27474
27513
|
}
|
|
27475
27514
|
} catch (err) {
|
|
27476
27515
|
error(`distillation embedding backfill batch failed (${batch.length} items):`, err);
|
|
27516
|
+
if (err instanceof LocalProviderUnavailableError) break;
|
|
27477
27517
|
}
|
|
27478
27518
|
if (embedded >= nextProgressAt) {
|
|
27479
27519
|
info(`embedding distillations: ${embedded}/${rows.length}\u2026`);
|
|
@@ -27563,14 +27603,14 @@ function store(input) {
|
|
|
27563
27603
|
embedTemporalMessage(input.info.id, content3);
|
|
27564
27604
|
}
|
|
27565
27605
|
}
|
|
27566
|
-
function undistilled(
|
|
27567
|
-
const pid = ensureProject(
|
|
27606
|
+
function undistilled(projectPath2, sessionID) {
|
|
27607
|
+
const pid = ensureProject(projectPath2);
|
|
27568
27608
|
const query = sessionID ? "SELECT * FROM temporal_messages WHERE project_id = ? AND session_id = ? AND distilled = 0 ORDER BY created_at ASC" : "SELECT * FROM temporal_messages WHERE project_id = ? AND distilled = 0 ORDER BY created_at ASC";
|
|
27569
27609
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27570
27610
|
return db().query(query).all(...params);
|
|
27571
27611
|
}
|
|
27572
|
-
function bySession(
|
|
27573
|
-
const pid = ensureProject(
|
|
27612
|
+
function bySession(projectPath2, sessionID) {
|
|
27613
|
+
const pid = ensureProject(projectPath2);
|
|
27574
27614
|
return db().query(
|
|
27575
27615
|
"SELECT * FROM temporal_messages WHERE project_id = ? AND session_id = ? ORDER BY created_at ASC"
|
|
27576
27616
|
).all(pid, sessionID);
|
|
@@ -27646,26 +27686,26 @@ function temporalCnorm(timestamps, now = Date.now()) {
|
|
|
27646
27686
|
const maxVariance = (n - 1) / (n * n);
|
|
27647
27687
|
return maxVariance === 0 ? 0 : variance / maxVariance;
|
|
27648
27688
|
}
|
|
27649
|
-
function count(
|
|
27650
|
-
const pid = ensureProject(
|
|
27689
|
+
function count(projectPath2, sessionID) {
|
|
27690
|
+
const pid = ensureProject(projectPath2);
|
|
27651
27691
|
const query = sessionID ? "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ? AND session_id = ?" : "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ?";
|
|
27652
27692
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27653
27693
|
return db().query(query).get(...params).count;
|
|
27654
27694
|
}
|
|
27655
|
-
function hasMessages(
|
|
27656
|
-
const pid = ensureProject(
|
|
27695
|
+
function hasMessages(projectPath2, sessionID) {
|
|
27696
|
+
const pid = ensureProject(projectPath2);
|
|
27657
27697
|
return !!db().query(
|
|
27658
27698
|
"SELECT 1 FROM temporal_messages WHERE project_id = ? AND session_id = ? LIMIT 1"
|
|
27659
27699
|
).get(pid, sessionID);
|
|
27660
27700
|
}
|
|
27661
|
-
function undistilledCount(
|
|
27662
|
-
const pid = ensureProject(
|
|
27701
|
+
function undistilledCount(projectPath2, sessionID) {
|
|
27702
|
+
const pid = ensureProject(projectPath2);
|
|
27663
27703
|
const query = sessionID ? "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ? AND session_id = ? AND distilled = 0" : "SELECT COUNT(*) as count FROM temporal_messages WHERE project_id = ? AND distilled = 0";
|
|
27664
27704
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27665
27705
|
return db().query(query).get(...params).count;
|
|
27666
27706
|
}
|
|
27667
|
-
function undistilledTokens(
|
|
27668
|
-
const pid = ensureProject(
|
|
27707
|
+
function undistilledTokens(projectPath2, sessionID) {
|
|
27708
|
+
const pid = ensureProject(projectPath2);
|
|
27669
27709
|
const query = sessionID ? "SELECT COALESCE(SUM(tokens), 0) as total FROM temporal_messages WHERE project_id = ? AND session_id = ? AND distilled = 0" : "SELECT COALESCE(SUM(tokens), 0) as total FROM temporal_messages WHERE project_id = ? AND distilled = 0";
|
|
27670
27710
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27671
27711
|
return db().query(query).get(...params).total;
|
|
@@ -28186,14 +28226,16 @@ function listMarkdownFiles(dir) {
|
|
|
28186
28226
|
function contentHash(content3) {
|
|
28187
28227
|
return sha256(content3);
|
|
28188
28228
|
}
|
|
28189
|
-
function hasLatDir(
|
|
28190
|
-
|
|
28229
|
+
function hasLatDir(projectPath2) {
|
|
28230
|
+
if (isHostedMode()) return false;
|
|
28231
|
+
const latDir = join6(projectPath2, "lat.md");
|
|
28191
28232
|
return existsSync3(latDir) && statSync2(latDir).isDirectory();
|
|
28192
28233
|
}
|
|
28193
|
-
function refresh(
|
|
28194
|
-
|
|
28234
|
+
function refresh(projectPath2) {
|
|
28235
|
+
if (isHostedMode()) return 0;
|
|
28236
|
+
const latDir = join6(projectPath2, "lat.md");
|
|
28195
28237
|
if (!existsSync3(latDir) || !statSync2(latDir).isDirectory()) return 0;
|
|
28196
|
-
const pid = ensureProject(
|
|
28238
|
+
const pid = ensureProject(projectPath2);
|
|
28197
28239
|
const files = listMarkdownFiles(latDir);
|
|
28198
28240
|
let upserted = 0;
|
|
28199
28241
|
const seenFiles = /* @__PURE__ */ new Set();
|
|
@@ -28208,7 +28250,7 @@ function refresh(projectPath) {
|
|
|
28208
28250
|
} catch {
|
|
28209
28251
|
continue;
|
|
28210
28252
|
}
|
|
28211
|
-
const fileRel = relative(
|
|
28253
|
+
const fileRel = relative(projectPath2, filePath);
|
|
28212
28254
|
seenFiles.add(fileRel);
|
|
28213
28255
|
const hash2 = contentHash(content3);
|
|
28214
28256
|
const existing = db().query("SELECT content_hash FROM lat_sections WHERE project_id = ? AND file = ? LIMIT 1").get(pid, fileRel.replace(/\.md$/, ""));
|
|
@@ -28216,7 +28258,7 @@ function refresh(projectPath) {
|
|
|
28216
28258
|
continue;
|
|
28217
28259
|
}
|
|
28218
28260
|
db().query("DELETE FROM lat_sections WHERE project_id = ? AND file = ?").run(pid, fileRel.replace(/\.md$/, ""));
|
|
28219
|
-
const sections = parseSections(filePath, content3,
|
|
28261
|
+
const sections = parseSections(filePath, content3, projectPath2);
|
|
28220
28262
|
const now = Date.now();
|
|
28221
28263
|
for (const section of sections) {
|
|
28222
28264
|
upsertStmt.run(
|
|
@@ -28266,9 +28308,9 @@ function searchScored2(input) {
|
|
|
28266
28308
|
return [];
|
|
28267
28309
|
}
|
|
28268
28310
|
}
|
|
28269
|
-
function scoreForSession(
|
|
28270
|
-
if (!hasLatDir(
|
|
28271
|
-
const pid = ensureProject(
|
|
28311
|
+
function scoreForSession(projectPath2, sessionContext, maxTokens) {
|
|
28312
|
+
if (!hasLatDir(projectPath2)) return [];
|
|
28313
|
+
const pid = ensureProject(projectPath2);
|
|
28272
28314
|
const terms = extractTopTerms(sessionContext);
|
|
28273
28315
|
if (!terms.length) return [];
|
|
28274
28316
|
const q = terms.map((t2) => `${t2}*`).join(" OR ");
|
|
@@ -28300,8 +28342,8 @@ function scoreForSession(projectPath, sessionContext, maxTokens) {
|
|
|
28300
28342
|
}
|
|
28301
28343
|
return packed;
|
|
28302
28344
|
}
|
|
28303
|
-
function count2(
|
|
28304
|
-
const pid = ensureProject(
|
|
28345
|
+
function count2(projectPath2) {
|
|
28346
|
+
const pid = ensureProject(projectPath2);
|
|
28305
28347
|
const row = db().query("SELECT COUNT(*) as cnt FROM lat_sections WHERE project_id = ?").get(pid);
|
|
28306
28348
|
return row.cnt;
|
|
28307
28349
|
}
|
|
@@ -28428,8 +28470,8 @@ function findFuzzyDuplicate(input) {
|
|
|
28428
28470
|
}
|
|
28429
28471
|
return null;
|
|
28430
28472
|
}
|
|
28431
|
-
function forProject(
|
|
28432
|
-
const pid = ensureProject(
|
|
28473
|
+
function forProject(projectPath2, includeCross = true) {
|
|
28474
|
+
const pid = ensureProject(projectPath2);
|
|
28433
28475
|
if (includeCross) {
|
|
28434
28476
|
return db().query(
|
|
28435
28477
|
`SELECT ${KNOWLEDGE_COLS} FROM knowledge
|
|
@@ -28477,8 +28519,8 @@ function scoreEntriesFTS(sessionContext) {
|
|
|
28477
28519
|
return /* @__PURE__ */ new Map();
|
|
28478
28520
|
}
|
|
28479
28521
|
}
|
|
28480
|
-
async function forSession(
|
|
28481
|
-
const pid = ensureProject(
|
|
28522
|
+
async function forSession(projectPath2, sessionID, maxTokens, options) {
|
|
28523
|
+
const pid = ensureProject(projectPath2);
|
|
28482
28524
|
const categoryFilter = options?.categories;
|
|
28483
28525
|
const excludeFilter = options?.excludeCategories;
|
|
28484
28526
|
let categoryClause = "";
|
|
@@ -28582,9 +28624,9 @@ async function forSession(projectPath, sessionID, maxTokens, options) {
|
|
|
28582
28624
|
result.push(entry);
|
|
28583
28625
|
used += cost;
|
|
28584
28626
|
}
|
|
28585
|
-
if (hasLatDir(
|
|
28627
|
+
if (hasLatDir(projectPath2) && used < maxTokens) {
|
|
28586
28628
|
const latSections = scoreForSession(
|
|
28587
|
-
|
|
28629
|
+
projectPath2,
|
|
28588
28630
|
sessionContext,
|
|
28589
28631
|
maxTokens - used
|
|
28590
28632
|
);
|
|
@@ -28807,8 +28849,8 @@ function cleanDeadRefs() {
|
|
|
28807
28849
|
}
|
|
28808
28850
|
return cleaned;
|
|
28809
28851
|
}
|
|
28810
|
-
function check2(
|
|
28811
|
-
const entries = forProject(
|
|
28852
|
+
function check2(projectPath2) {
|
|
28853
|
+
const entries = forProject(projectPath2, false);
|
|
28812
28854
|
const issues = [];
|
|
28813
28855
|
for (const entry of entries) {
|
|
28814
28856
|
if (entry.content.length > 1200) {
|
|
@@ -28963,10 +29005,10 @@ function _dedup(entries, dryRun, embeddingThreshold = EMBEDDING_DEDUP_THRESHOLD)
|
|
|
28963
29005
|
const entryTitles = new Map(entries.map((e) => [e.id, e.title]));
|
|
28964
29006
|
return { clusters: result, totalRemoved, pairSimilarities, entryTitles };
|
|
28965
29007
|
}
|
|
28966
|
-
async function deduplicate(
|
|
28967
|
-
const pid = ensureProject(
|
|
29008
|
+
async function deduplicate(projectPath2, opts) {
|
|
29009
|
+
const pid = ensureProject(projectPath2);
|
|
28968
29010
|
const threshold = loadCalibratedThreshold(pid) ?? EMBEDDING_DEDUP_THRESHOLD;
|
|
28969
|
-
const entries = forProject(
|
|
29011
|
+
const entries = forProject(projectPath2, false);
|
|
28970
29012
|
return _dedup(entries, opts?.dryRun ?? true, threshold);
|
|
28971
29013
|
}
|
|
28972
29014
|
async function deduplicateGlobal(opts) {
|
|
@@ -29191,8 +29233,8 @@ function setCache(fp, entry) {
|
|
|
29191
29233
|
"INSERT INTO kv_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = ?"
|
|
29192
29234
|
).run(key, value, value);
|
|
29193
29235
|
}
|
|
29194
|
-
function clearLoreFileCache(
|
|
29195
|
-
db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(
|
|
29236
|
+
function clearLoreFileCache(projectPath2) {
|
|
29237
|
+
db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(projectPath2, LORE_FILE));
|
|
29196
29238
|
}
|
|
29197
29239
|
function splitFile(fileContent) {
|
|
29198
29240
|
const spans = [];
|
|
@@ -29268,8 +29310,8 @@ function hashSection(section) {
|
|
|
29268
29310
|
}
|
|
29269
29311
|
return (h3 >>> 0).toString(16).padStart(8, "0");
|
|
29270
29312
|
}
|
|
29271
|
-
function buildSection(
|
|
29272
|
-
const entries = forProject(
|
|
29313
|
+
function buildSection(projectPath2) {
|
|
29314
|
+
const entries = forProject(projectPath2, false);
|
|
29273
29315
|
if (!entries.length) {
|
|
29274
29316
|
return "\n";
|
|
29275
29317
|
}
|
|
@@ -29301,6 +29343,7 @@ function buildSection(projectPath) {
|
|
|
29301
29343
|
return out.join("\n");
|
|
29302
29344
|
}
|
|
29303
29345
|
function exportToFile(input) {
|
|
29346
|
+
if (isHostedMode()) return;
|
|
29304
29347
|
exportLoreFile(input.projectPath);
|
|
29305
29348
|
const pointerBody = "\n## Long-term Knowledge\n\nFor long-term knowledge entries managed by [lore](https://github.com/BYK/loreai) (gotchas, patterns, decisions, architecture), see [`.lore.md`](.lore.md) in the project root.\n";
|
|
29306
29349
|
const newSection = LORE_SECTION_START + pointerBody + LORE_SECTION_END + "\n";
|
|
@@ -29318,6 +29361,7 @@ function exportToFile(input) {
|
|
|
29318
29361
|
writeFileSync(input.filePath, result, "utf8");
|
|
29319
29362
|
}
|
|
29320
29363
|
function shouldImport(input) {
|
|
29364
|
+
if (isHostedMode()) return false;
|
|
29321
29365
|
if (!existsSync4(input.filePath)) return false;
|
|
29322
29366
|
const fileContent = readFileSync3(input.filePath, "utf8");
|
|
29323
29367
|
const { section } = splitFile(fileContent);
|
|
@@ -29327,7 +29371,7 @@ function shouldImport(input) {
|
|
|
29327
29371
|
const expected = buildSection(input.projectPath);
|
|
29328
29372
|
return hashSection(section) !== hashSection(expected);
|
|
29329
29373
|
}
|
|
29330
|
-
function _importEntries(entries,
|
|
29374
|
+
function _importEntries(entries, projectPath2) {
|
|
29331
29375
|
const seenIds = /* @__PURE__ */ new Set();
|
|
29332
29376
|
for (const entry of entries) {
|
|
29333
29377
|
if (entry.id !== null) {
|
|
@@ -29339,7 +29383,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29339
29383
|
update(entry.id, { content: entry.content });
|
|
29340
29384
|
}
|
|
29341
29385
|
} else {
|
|
29342
|
-
const pid = ensureProject(
|
|
29386
|
+
const pid = ensureProject(projectPath2);
|
|
29343
29387
|
const fuzzyMatch = findFuzzyDuplicate({ title: entry.title, projectId: pid });
|
|
29344
29388
|
if (fuzzyMatch) {
|
|
29345
29389
|
if (fuzzyMatch.title !== entry.title || get(fuzzyMatch.id)?.content !== entry.content) {
|
|
@@ -29347,7 +29391,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29347
29391
|
}
|
|
29348
29392
|
} else {
|
|
29349
29393
|
create({
|
|
29350
|
-
projectPath,
|
|
29394
|
+
projectPath: projectPath2,
|
|
29351
29395
|
category: entry.category,
|
|
29352
29396
|
title: entry.title,
|
|
29353
29397
|
content: entry.content,
|
|
@@ -29358,13 +29402,13 @@ function _importEntries(entries, projectPath) {
|
|
|
29358
29402
|
}
|
|
29359
29403
|
}
|
|
29360
29404
|
} else {
|
|
29361
|
-
const existing = forProject(
|
|
29405
|
+
const existing = forProject(projectPath2, false);
|
|
29362
29406
|
const titleMatch = existing.find(
|
|
29363
29407
|
(e) => e.title.toLowerCase() === entry.title.toLowerCase()
|
|
29364
29408
|
);
|
|
29365
29409
|
if (!titleMatch) {
|
|
29366
29410
|
create({
|
|
29367
|
-
projectPath,
|
|
29411
|
+
projectPath: projectPath2,
|
|
29368
29412
|
category: entry.category,
|
|
29369
29413
|
title: entry.title,
|
|
29370
29414
|
content: entry.content,
|
|
@@ -29376,6 +29420,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29376
29420
|
}
|
|
29377
29421
|
}
|
|
29378
29422
|
function importFromFile(input) {
|
|
29423
|
+
if (isHostedMode()) return;
|
|
29379
29424
|
if (!existsSync4(input.filePath)) return;
|
|
29380
29425
|
const fileContent = readFileSync3(input.filePath, "utf8");
|
|
29381
29426
|
const { section } = splitFile(fileContent);
|
|
@@ -29384,14 +29429,16 @@ function importFromFile(input) {
|
|
|
29384
29429
|
if (!fileEntries.length) return;
|
|
29385
29430
|
_importEntries(fileEntries, input.projectPath);
|
|
29386
29431
|
}
|
|
29387
|
-
function loreFileExists(
|
|
29388
|
-
|
|
29432
|
+
function loreFileExists(projectPath2) {
|
|
29433
|
+
if (isHostedMode()) return false;
|
|
29434
|
+
return existsSync4(join7(projectPath2, LORE_FILE));
|
|
29389
29435
|
}
|
|
29390
|
-
function exportLoreFile(
|
|
29391
|
-
|
|
29436
|
+
function exportLoreFile(projectPath2) {
|
|
29437
|
+
if (isHostedMode()) return;
|
|
29438
|
+
const sectionBody = buildSection(projectPath2);
|
|
29392
29439
|
const content3 = LORE_FILE_HEADER + "\n" + sectionBody;
|
|
29393
29440
|
const contentHash2 = hashSection(content3);
|
|
29394
|
-
const fp = join7(
|
|
29441
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29395
29442
|
const cached2 = getCache(fp);
|
|
29396
29443
|
if (cached2 && cached2.hash === contentHash2) {
|
|
29397
29444
|
return;
|
|
@@ -29400,8 +29447,9 @@ function exportLoreFile(projectPath) {
|
|
|
29400
29447
|
const { mtimeMs } = statSync3(fp);
|
|
29401
29448
|
setCache(fp, { mtimeMs, hash: contentHash2 });
|
|
29402
29449
|
}
|
|
29403
|
-
function shouldImportLoreFile(
|
|
29404
|
-
|
|
29450
|
+
function shouldImportLoreFile(projectPath2) {
|
|
29451
|
+
if (isHostedMode()) return false;
|
|
29452
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29405
29453
|
if (!existsSync4(fp)) return false;
|
|
29406
29454
|
const { mtimeMs } = statSync3(fp);
|
|
29407
29455
|
const cached2 = getCache(fp);
|
|
@@ -29410,7 +29458,7 @@ function shouldImportLoreFile(projectPath) {
|
|
|
29410
29458
|
}
|
|
29411
29459
|
const fileContent = readFileSync3(fp, "utf8");
|
|
29412
29460
|
const fileHash = hashSection(fileContent);
|
|
29413
|
-
const expected = LORE_FILE_HEADER + "\n" + buildSection(
|
|
29461
|
+
const expected = LORE_FILE_HEADER + "\n" + buildSection(projectPath2);
|
|
29414
29462
|
const expectedHash = hashSection(expected);
|
|
29415
29463
|
if (fileHash === expectedHash) {
|
|
29416
29464
|
setCache(fp, { mtimeMs, hash: fileHash });
|
|
@@ -29418,13 +29466,14 @@ function shouldImportLoreFile(projectPath) {
|
|
|
29418
29466
|
}
|
|
29419
29467
|
return true;
|
|
29420
29468
|
}
|
|
29421
|
-
function importLoreFile(
|
|
29422
|
-
|
|
29469
|
+
function importLoreFile(projectPath2) {
|
|
29470
|
+
if (isHostedMode()) return;
|
|
29471
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29423
29472
|
if (!existsSync4(fp)) return;
|
|
29424
29473
|
const fileContent = readFileSync3(fp, "utf8");
|
|
29425
29474
|
const fileEntries = parseEntriesFromSection(fileContent);
|
|
29426
29475
|
if (!fileEntries.length) return;
|
|
29427
|
-
_importEntries(fileEntries,
|
|
29476
|
+
_importEntries(fileEntries, projectPath2);
|
|
29428
29477
|
try {
|
|
29429
29478
|
const { mtimeMs } = statSync3(fp);
|
|
29430
29479
|
setCache(fp, { mtimeMs, hash: hashSection(fileContent) });
|
|
@@ -29443,8 +29492,8 @@ function listProjects() {
|
|
|
29443
29492
|
FROM projects p ORDER BY p.created_at DESC`
|
|
29444
29493
|
).all();
|
|
29445
29494
|
}
|
|
29446
|
-
function listSessions(
|
|
29447
|
-
const pid = ensureProject(
|
|
29495
|
+
function listSessions(projectPath2, limit = 50) {
|
|
29496
|
+
const pid = ensureProject(projectPath2);
|
|
29448
29497
|
return db().query(
|
|
29449
29498
|
`SELECT
|
|
29450
29499
|
session_id,
|
|
@@ -29463,8 +29512,8 @@ function listSessions(projectPath, limit = 50) {
|
|
|
29463
29512
|
LIMIT ?`
|
|
29464
29513
|
).all(pid, limit);
|
|
29465
29514
|
}
|
|
29466
|
-
function listDistillations(
|
|
29467
|
-
const pid = ensureProject(
|
|
29515
|
+
function listDistillations(projectPath2, opts) {
|
|
29516
|
+
const pid = ensureProject(projectPath2);
|
|
29468
29517
|
const limit = opts?.limit ?? 50;
|
|
29469
29518
|
if (opts?.sessionId) {
|
|
29470
29519
|
return db().query(
|
|
@@ -29513,8 +29562,8 @@ function globalStats() {
|
|
|
29513
29562
|
}
|
|
29514
29563
|
return { ...row, db_size_bytes };
|
|
29515
29564
|
}
|
|
29516
|
-
function countForProject(
|
|
29517
|
-
const pid = projectId(
|
|
29565
|
+
function countForProject(projectPath2) {
|
|
29566
|
+
const pid = projectId(projectPath2);
|
|
29518
29567
|
if (!pid)
|
|
29519
29568
|
return { knowledge: 0, messages: 0, distillations: 0, sessions: 0 };
|
|
29520
29569
|
const row = db().query(
|
|
@@ -29526,8 +29575,8 @@ function countForProject(projectPath) {
|
|
|
29526
29575
|
).get(pid, pid, pid, pid);
|
|
29527
29576
|
return row;
|
|
29528
29577
|
}
|
|
29529
|
-
function clearProject(
|
|
29530
|
-
const pid = ensureProject(
|
|
29578
|
+
function clearProject(projectPath2) {
|
|
29579
|
+
const pid = ensureProject(projectPath2);
|
|
29531
29580
|
const database = db();
|
|
29532
29581
|
const counts = {
|
|
29533
29582
|
knowledge: database.query(
|
|
@@ -29558,9 +29607,9 @@ function clearProject(projectPath) {
|
|
|
29558
29607
|
database.exec("ROLLBACK");
|
|
29559
29608
|
throw e;
|
|
29560
29609
|
}
|
|
29561
|
-
if (existsSync5(
|
|
29610
|
+
if (existsSync5(projectPath2)) {
|
|
29562
29611
|
try {
|
|
29563
|
-
exportLoreFile(
|
|
29612
|
+
exportLoreFile(projectPath2);
|
|
29564
29613
|
} catch {
|
|
29565
29614
|
}
|
|
29566
29615
|
}
|
|
@@ -29623,30 +29672,30 @@ function renameProject(projectId2, newName) {
|
|
|
29623
29672
|
const result = db().query("UPDATE projects SET name = ? WHERE id = ?").run(newName.trim(), projectId2);
|
|
29624
29673
|
return result.changes > 0;
|
|
29625
29674
|
}
|
|
29626
|
-
function clearKnowledge(
|
|
29627
|
-
const pid = ensureProject(
|
|
29675
|
+
function clearKnowledge(projectPath2) {
|
|
29676
|
+
const pid = ensureProject(projectPath2);
|
|
29628
29677
|
const count3 = db().query(
|
|
29629
29678
|
"SELECT COUNT(*) as c FROM knowledge WHERE project_id = ?"
|
|
29630
29679
|
).get(pid).c;
|
|
29631
29680
|
db().query("DELETE FROM knowledge WHERE project_id = ?").run(pid);
|
|
29632
|
-
if (existsSync5(
|
|
29681
|
+
if (existsSync5(projectPath2)) {
|
|
29633
29682
|
try {
|
|
29634
|
-
exportLoreFile(
|
|
29683
|
+
exportLoreFile(projectPath2);
|
|
29635
29684
|
} catch {
|
|
29636
29685
|
}
|
|
29637
29686
|
}
|
|
29638
29687
|
return count3;
|
|
29639
29688
|
}
|
|
29640
|
-
function clearTemporal(
|
|
29641
|
-
const pid = ensureProject(
|
|
29689
|
+
function clearTemporal(projectPath2) {
|
|
29690
|
+
const pid = ensureProject(projectPath2);
|
|
29642
29691
|
const count3 = db().query(
|
|
29643
29692
|
"SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ?"
|
|
29644
29693
|
).get(pid).c;
|
|
29645
29694
|
db().query("DELETE FROM temporal_messages WHERE project_id = ?").run(pid);
|
|
29646
29695
|
return count3;
|
|
29647
29696
|
}
|
|
29648
|
-
function clearDistillations(
|
|
29649
|
-
const pid = ensureProject(
|
|
29697
|
+
function clearDistillations(projectPath2) {
|
|
29698
|
+
const pid = ensureProject(projectPath2);
|
|
29650
29699
|
const count3 = db().query(
|
|
29651
29700
|
"SELECT COUNT(*) as c FROM distillations WHERE project_id = ?"
|
|
29652
29701
|
).get(pid).c;
|
|
@@ -29665,8 +29714,8 @@ function deleteDistillation(id) {
|
|
|
29665
29714
|
db().query("DELETE FROM distillations WHERE id = ?").run(id);
|
|
29666
29715
|
return true;
|
|
29667
29716
|
}
|
|
29668
|
-
function deleteSession(
|
|
29669
|
-
const pid = ensureProject(
|
|
29717
|
+
function deleteSession(projectPath2, sessionId) {
|
|
29718
|
+
const pid = ensureProject(projectPath2);
|
|
29670
29719
|
const database = db();
|
|
29671
29720
|
const msgCount = database.query(
|
|
29672
29721
|
"SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ? AND session_id = ?"
|
|
@@ -29896,57 +29945,41 @@ function estimateMessage(msg) {
|
|
|
29896
29945
|
}
|
|
29897
29946
|
var contextLimit = 2e5;
|
|
29898
29947
|
var outputReserved = 32e3;
|
|
29899
|
-
var
|
|
29900
|
-
var
|
|
29901
|
-
var
|
|
29902
|
-
|
|
29903
|
-
|
|
29904
|
-
|
|
29905
|
-
return Math.max(MIN_CONTEXT_FLOOR, Math.floor(targetBustCost / cacheWriteCostPerToken));
|
|
29906
|
-
}
|
|
29907
|
-
function setMaxContextTokens(tokens) {
|
|
29908
|
-
maxContextTokensCeiling = Math.max(0, Math.floor(tokens));
|
|
29948
|
+
var TIER_BOUNDARIES = [2e5, 5e5];
|
|
29949
|
+
var cacheWriteCostPerToken = 0;
|
|
29950
|
+
var cacheReadCostPerToken = 0;
|
|
29951
|
+
function setCachePricing(writeCost, readCost) {
|
|
29952
|
+
cacheWriteCostPerToken = Math.max(0, writeCost);
|
|
29953
|
+
cacheReadCostPerToken = Math.max(0, readCost);
|
|
29909
29954
|
}
|
|
29910
|
-
function
|
|
29911
|
-
return
|
|
29955
|
+
function getCachePricing() {
|
|
29956
|
+
return { write: cacheWriteCostPerToken, read: cacheReadCostPerToken };
|
|
29912
29957
|
}
|
|
29913
|
-
|
|
29958
|
+
var maxLayer0Tokens = 0;
|
|
29959
|
+
var MIN_LAYER0_FLOOR = 4e4;
|
|
29960
|
+
function shouldCompress(currentTokens, compressedTokens, consecutiveBusts, threshold = 0.85) {
|
|
29961
|
+
if (consecutiveBusts >= 5) return false;
|
|
29962
|
+
if (cacheWriteCostPerToken <= 0 || cacheReadCostPerToken <= 0) return false;
|
|
29963
|
+
const bustCost = compressedTokens * cacheWriteCostPerToken;
|
|
29964
|
+
const continueCost = currentTokens * cacheReadCostPerToken;
|
|
29965
|
+
return bustCost < threshold * continueCost;
|
|
29966
|
+
}
|
|
29967
|
+
function getTier(tokens) {
|
|
29968
|
+
if (tokens <= TIER_BOUNDARIES[0]) return 0;
|
|
29969
|
+
if (tokens <= TIER_BOUNDARIES[1]) return 1;
|
|
29970
|
+
return 2;
|
|
29971
|
+
}
|
|
29972
|
+
function recordCacheUsage(cacheWrite, cacheRead, inputTokens, sessionID) {
|
|
29914
29973
|
if (!sessionID) return;
|
|
29915
29974
|
const state = getSessionState(sessionID);
|
|
29916
|
-
const total = cacheWrite + cacheRead;
|
|
29917
|
-
if (total
|
|
29918
|
-
|
|
29919
|
-
|
|
29920
|
-
|
|
29921
|
-
|
|
29922
|
-
|
|
29923
|
-
|
|
29924
|
-
state.interBustIntervalEMA = state.interBustIntervalEMA < 0 ? interval : state.interBustIntervalEMA * 0.7 + interval * 0.3;
|
|
29925
|
-
}
|
|
29926
|
-
state.lastBustAt = now;
|
|
29927
|
-
}
|
|
29928
|
-
adaptContextCap(state);
|
|
29929
|
-
}
|
|
29930
|
-
function adaptContextCap(state) {
|
|
29931
|
-
if (maxContextTokensCeiling <= 0) return;
|
|
29932
|
-
const cap = state.dynamicContextCap > 0 ? state.dynamicContextCap : maxContextTokensCeiling;
|
|
29933
|
-
let newCap = cap;
|
|
29934
|
-
if (state.bustRateEMA > 0.8) {
|
|
29935
|
-
newCap = Math.floor(cap * 0.9);
|
|
29936
|
-
} else if (state.bustRateEMA < 0.3) {
|
|
29937
|
-
newCap = Math.floor(cap * 1.05);
|
|
29938
|
-
}
|
|
29939
|
-
if (state.interBustIntervalEMA > 0) {
|
|
29940
|
-
if (state.interBustIntervalEMA < 2 * 6e4) {
|
|
29941
|
-
newCap = Math.floor(newCap * 0.95);
|
|
29942
|
-
} else if (state.interBustIntervalEMA > 10 * 6e4) {
|
|
29943
|
-
newCap = Math.floor(newCap * 1.03);
|
|
29944
|
-
}
|
|
29945
|
-
}
|
|
29946
|
-
state.dynamicContextCap = Math.max(
|
|
29947
|
-
MIN_CONTEXT_FLOOR,
|
|
29948
|
-
Math.min(maxContextTokensCeiling, newCap)
|
|
29949
|
-
);
|
|
29975
|
+
const total = inputTokens > 0 ? inputTokens : cacheWrite + cacheRead;
|
|
29976
|
+
if (total > 0) {
|
|
29977
|
+
if (cacheWrite / total > 0.5) {
|
|
29978
|
+
state.consecutiveBusts++;
|
|
29979
|
+
} else {
|
|
29980
|
+
state.consecutiveBusts = 0;
|
|
29981
|
+
}
|
|
29982
|
+
}
|
|
29950
29983
|
}
|
|
29951
29984
|
var FIRST_TURN_OVERHEAD = 15e3;
|
|
29952
29985
|
var calibratedOverhead = null;
|
|
@@ -29967,10 +30000,7 @@ function makeSessionState() {
|
|
|
29967
30000
|
cameOutOfIdle: false,
|
|
29968
30001
|
postIdleCompact: false,
|
|
29969
30002
|
consecutiveHighLayer: 0,
|
|
29970
|
-
|
|
29971
|
-
interBustIntervalEMA: -1,
|
|
29972
|
-
lastBustAt: 0,
|
|
29973
|
-
dynamicContextCap: 0,
|
|
30003
|
+
consecutiveBusts: 0,
|
|
29974
30004
|
distillationSnapshot: null
|
|
29975
30005
|
};
|
|
29976
30006
|
}
|
|
@@ -29982,13 +30012,10 @@ function getSessionState(sessionID) {
|
|
|
29982
30012
|
state.forceMinLayer = loadForceMinLayer(sessionID);
|
|
29983
30013
|
const persisted = loadSessionTracking(sessionID);
|
|
29984
30014
|
if (persisted && persisted.lastTurnAt > 0) {
|
|
29985
|
-
state.dynamicContextCap = persisted.dynamicContextCap;
|
|
29986
|
-
state.bustRateEMA = persisted.bustRateEMA;
|
|
29987
|
-
state.interBustIntervalEMA = persisted.interBustIntervalEMA;
|
|
29988
30015
|
state.lastLayer = persisted.lastLayer;
|
|
29989
30016
|
state.lastKnownInput = persisted.lastKnownInput;
|
|
29990
30017
|
state.lastTurnAt = persisted.lastTurnAt;
|
|
29991
|
-
state.
|
|
30018
|
+
state.consecutiveBusts = persisted.dynamicContextCap;
|
|
29992
30019
|
}
|
|
29993
30020
|
sessionStates.set(sessionID, state);
|
|
29994
30021
|
}
|
|
@@ -30024,9 +30051,9 @@ function setModelLimits(limits) {
|
|
|
30024
30051
|
function setMaxLayer0Tokens(tokens) {
|
|
30025
30052
|
maxLayer0Tokens = Math.max(0, Math.floor(tokens));
|
|
30026
30053
|
}
|
|
30027
|
-
function computeLayer0Cap(targetCostPerTurn,
|
|
30028
|
-
if (targetCostPerTurn <= 0 ||
|
|
30029
|
-
const rawCap = Math.floor(targetCostPerTurn /
|
|
30054
|
+
function computeLayer0Cap(targetCostPerTurn, cacheReadCostPerToken2) {
|
|
30055
|
+
if (targetCostPerTurn <= 0 || cacheReadCostPerToken2 <= 0) return 0;
|
|
30056
|
+
const rawCap = Math.floor(targetCostPerTurn / cacheReadCostPerToken2);
|
|
30030
30057
|
return Math.max(rawCap, MIN_LAYER0_FLOOR);
|
|
30031
30058
|
}
|
|
30032
30059
|
function setLtmTokens(tokens, sessionID) {
|
|
@@ -30069,6 +30096,11 @@ function getLastTransformedCount(sessionID) {
|
|
|
30069
30096
|
function getLastTransformEstimate(sessionID) {
|
|
30070
30097
|
return sessionStates.get(sessionID)?.lastTransformEstimate ?? 0;
|
|
30071
30098
|
}
|
|
30099
|
+
function getLastLayer(sessionID) {
|
|
30100
|
+
if (sessionID) return sessionStates.get(sessionID)?.lastLayer ?? 0;
|
|
30101
|
+
const first = sessionStates.values().next().value;
|
|
30102
|
+
return first?.lastLayer ?? 0;
|
|
30103
|
+
}
|
|
30072
30104
|
function setForceMinLayer(layer, sessionID) {
|
|
30073
30105
|
if (sessionID) {
|
|
30074
30106
|
getSessionState(sessionID).forceMinLayer = layer;
|
|
@@ -30089,7 +30121,8 @@ function inspectSessionState(sessionID) {
|
|
|
30089
30121
|
cameOutOfIdle: state.cameOutOfIdle,
|
|
30090
30122
|
postIdleCompact: state.postIdleCompact,
|
|
30091
30123
|
lastTurnAt: state.lastTurnAt,
|
|
30092
|
-
distillationSnapshot: state.distillationSnapshot
|
|
30124
|
+
distillationSnapshot: state.distillationSnapshot,
|
|
30125
|
+
consecutiveBusts: state.consecutiveBusts
|
|
30093
30126
|
};
|
|
30094
30127
|
}
|
|
30095
30128
|
function setLastTurnAtForTest(sessionID, ms) {
|
|
@@ -30099,22 +30132,21 @@ function saveGradientState(sessionID) {
|
|
|
30099
30132
|
const state = sessionStates.get(sessionID);
|
|
30100
30133
|
if (!state) return;
|
|
30101
30134
|
saveSessionTracking(sessionID, {
|
|
30102
|
-
dynamicContextCap: state.dynamicContextCap,
|
|
30103
|
-
bustRateEMA: state.bustRateEMA,
|
|
30104
|
-
interBustIntervalEMA: state.interBustIntervalEMA,
|
|
30105
30135
|
lastLayer: state.lastLayer,
|
|
30106
30136
|
lastKnownInput: state.lastKnownInput,
|
|
30107
30137
|
lastTurnAt: state.lastTurnAt,
|
|
30108
|
-
|
|
30138
|
+
// Repurpose the dead dynamicContextCap column (v24, always 0 now)
|
|
30139
|
+
// to persist consecutiveBusts — avoids a new DB migration.
|
|
30140
|
+
dynamicContextCap: state.consecutiveBusts
|
|
30109
30141
|
});
|
|
30110
30142
|
}
|
|
30111
|
-
function loadDistillations(
|
|
30112
|
-
const pid = ensureProject(
|
|
30143
|
+
function loadDistillations(projectPath2, sessionID) {
|
|
30144
|
+
const pid = ensureProject(projectPath2);
|
|
30113
30145
|
const query = sessionID ? "SELECT id, observations, generation, token_count, created_at, session_id FROM distillations WHERE project_id = ? AND session_id = ? AND archived = 0 ORDER BY created_at ASC" : "SELECT id, observations, generation, token_count, created_at, session_id FROM distillations WHERE project_id = ? AND archived = 0 ORDER BY created_at ASC";
|
|
30114
30146
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
30115
30147
|
return db().query(query).all(...params);
|
|
30116
30148
|
}
|
|
30117
|
-
function loadDistillationsCached(
|
|
30149
|
+
function loadDistillationsCached(projectPath2, sessionID, messages, sessState) {
|
|
30118
30150
|
let lastUserMsgId = null;
|
|
30119
30151
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
30120
30152
|
if (messages[i].info.role === "user") {
|
|
@@ -30126,7 +30158,7 @@ function loadDistillationsCached(projectPath, sessionID, messages, sessState) {
|
|
|
30126
30158
|
if (snapshot && snapshot.lastUserMsgId === lastUserMsgId) {
|
|
30127
30159
|
return snapshot.rows;
|
|
30128
30160
|
}
|
|
30129
|
-
const rows = loadDistillations(
|
|
30161
|
+
const rows = loadDistillations(projectPath2, sessionID);
|
|
30130
30162
|
sessState.distillationSnapshot = { rows, lastUserMsgId };
|
|
30131
30163
|
info(
|
|
30132
30164
|
`distillation refresh: ${rows.length} rows (user msg ${lastUserMsgId?.substring(0, 16) ?? "none"})`
|
|
@@ -30550,8 +30582,7 @@ function transformInner(input) {
|
|
|
30550
30582
|
0,
|
|
30551
30583
|
contextLimit - outputReserved - overhead - sessLtmTokens
|
|
30552
30584
|
);
|
|
30553
|
-
const
|
|
30554
|
-
const usable = effectiveCap > 0 && usableRaw > effectiveCap ? effectiveCap : usableRaw;
|
|
30585
|
+
const usable = usableRaw;
|
|
30555
30586
|
const distilledBudget = Math.floor(usable * cfg.budget.distilled);
|
|
30556
30587
|
let rawBudget = Math.floor(usable * cfg.budget.raw);
|
|
30557
30588
|
let effectiveMinLayer = sessState.forceMinLayer;
|
|
@@ -30572,8 +30603,7 @@ function transformInner(input) {
|
|
|
30572
30603
|
if (postIdleCompact) {
|
|
30573
30604
|
sessState.postIdleCompact = false;
|
|
30574
30605
|
effectiveMinLayer = Math.max(effectiveMinLayer, 1);
|
|
30575
|
-
|
|
30576
|
-
rawBudget = Math.floor(usable * postIdleRawFraction);
|
|
30606
|
+
rawBudget = Math.floor(usable * 0.2);
|
|
30577
30607
|
info(
|
|
30578
30608
|
`post-idle compact: session=${sid} rawBudget=${rawBudget} (${Math.floor(usable * cfg.budget.raw)}\u2192${rawBudget})`
|
|
30579
30609
|
);
|
|
@@ -30607,6 +30637,28 @@ function transformInner(input) {
|
|
|
30607
30637
|
refreshLtm: false
|
|
30608
30638
|
};
|
|
30609
30639
|
}
|
|
30640
|
+
if (effectiveMinLayer === 0 && layer0Input > layer0Ceiling && layer0Input <= maxInput && sid) {
|
|
30641
|
+
const busts = getSessionState(sid).consecutiveBusts;
|
|
30642
|
+
const compressedEstimate = distilledBudget + rawBudget;
|
|
30643
|
+
if (!shouldCompress(Math.round(layer0Input), compressedEstimate, busts)) {
|
|
30644
|
+
const messageTokens = calibrated ? expectedInput - (sessLtmTokens - sessState.lastKnownLtm) : expectedInput - overhead - sessLtmTokens;
|
|
30645
|
+
info(
|
|
30646
|
+
`tier gate: session=${sid} skipping compression \u2014 bustCost not justified (input=${Math.round(layer0Input)} compressed=${compressedEstimate} busts=${busts})`
|
|
30647
|
+
);
|
|
30648
|
+
return {
|
|
30649
|
+
messages: input.messages,
|
|
30650
|
+
layer: 0,
|
|
30651
|
+
distilledTokens: 0,
|
|
30652
|
+
rawTokens: Math.max(0, messageTokens),
|
|
30653
|
+
totalTokens: Math.max(0, messageTokens),
|
|
30654
|
+
usable,
|
|
30655
|
+
distilledBudget,
|
|
30656
|
+
rawBudget,
|
|
30657
|
+
refreshLtm: false,
|
|
30658
|
+
unsustainable: busts >= 5
|
|
30659
|
+
};
|
|
30660
|
+
}
|
|
30661
|
+
}
|
|
30610
30662
|
const turnStart = currentTurnStart(input.messages);
|
|
30611
30663
|
const dedupMessages = deduplicateToolOutputs(input.messages, turnStart);
|
|
30612
30664
|
const distillations = sid ? loadDistillationsCached(input.projectPath, sid, input.messages, sessState) : [];
|
|
@@ -30690,6 +30742,7 @@ function transformInner(input) {
|
|
|
30690
30742
|
}
|
|
30691
30743
|
const nuclearRaw = [...olderMessages, ...currentTurn];
|
|
30692
30744
|
const nuclearRawTokens = olderTokens + currentTurnTokens;
|
|
30745
|
+
const unsustainable = sid ? getSessionState(sid).consecutiveBusts >= 5 : false;
|
|
30693
30746
|
return {
|
|
30694
30747
|
messages: [...nuclearPrefix, ...nuclearRaw],
|
|
30695
30748
|
layer: 4,
|
|
@@ -30699,7 +30752,8 @@ function transformInner(input) {
|
|
|
30699
30752
|
usable,
|
|
30700
30753
|
distilledBudget,
|
|
30701
30754
|
rawBudget,
|
|
30702
|
-
refreshLtm: true
|
|
30755
|
+
refreshLtm: true,
|
|
30756
|
+
unsustainable
|
|
30703
30757
|
};
|
|
30704
30758
|
}
|
|
30705
30759
|
function transform2(input) {
|
|
@@ -30724,7 +30778,7 @@ function transform2(input) {
|
|
|
30724
30778
|
state.consecutiveHighLayer = 0;
|
|
30725
30779
|
}
|
|
30726
30780
|
info(
|
|
30727
|
-
`gradient: session=${sid} layer=${result.layer} tokens=${result.totalTokens} (distilled=${result.distilledTokens} raw=${result.rawTokens}) usable=${result.usable}
|
|
30781
|
+
`gradient: session=${sid} layer=${result.layer} tokens=${result.totalTokens} (distilled=${result.distilledTokens} raw=${result.rawTokens}) usable=${result.usable} tier=${getTier(result.totalTokens)} l0cap=${maxLayer0Tokens || "off"}`
|
|
30728
30782
|
);
|
|
30729
30783
|
}
|
|
30730
30784
|
return result;
|
|
@@ -31110,18 +31164,18 @@ function parseDistillationResult(text4) {
|
|
|
31110
31164
|
if (!observations) return null;
|
|
31111
31165
|
return { observations };
|
|
31112
31166
|
}
|
|
31113
|
-
function latestObservations(
|
|
31114
|
-
const pid = ensureProject(
|
|
31167
|
+
function latestObservations(projectPath2, sessionID) {
|
|
31168
|
+
const pid = ensureProject(projectPath2);
|
|
31115
31169
|
const row = db().query(
|
|
31116
31170
|
"SELECT observations FROM distillations WHERE project_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 1"
|
|
31117
31171
|
).get(pid, sessionID);
|
|
31118
31172
|
return row?.observations || void 0;
|
|
31119
31173
|
}
|
|
31120
|
-
function latestMetaObservations(
|
|
31121
|
-
return latestMeta(
|
|
31174
|
+
function latestMetaObservations(projectPath2, sessionID) {
|
|
31175
|
+
return latestMeta(projectPath2, sessionID)?.observations;
|
|
31122
31176
|
}
|
|
31123
|
-
function latestMeta(
|
|
31124
|
-
const pid = ensureProject(
|
|
31177
|
+
function latestMeta(projectPath2, sessionID) {
|
|
31178
|
+
const pid = ensureProject(projectPath2);
|
|
31125
31179
|
const row = db().query(
|
|
31126
31180
|
`SELECT observations, generation FROM distillations
|
|
31127
31181
|
WHERE project_id = ? AND session_id = ? AND generation > 0
|
|
@@ -31139,8 +31193,8 @@ function parseSourceIds(raw) {
|
|
|
31139
31193
|
return [];
|
|
31140
31194
|
}
|
|
31141
31195
|
}
|
|
31142
|
-
function loadForSession(
|
|
31143
|
-
const pid = ensureProject(
|
|
31196
|
+
function loadForSession(projectPath2, sessionID, includeArchived = false) {
|
|
31197
|
+
const pid = ensureProject(projectPath2);
|
|
31144
31198
|
const sql = includeArchived ? "SELECT id, project_id, session_id, observations, source_ids, generation, token_count, created_at, r_compression, c_norm FROM distillations WHERE project_id = ? AND session_id = ? ORDER BY created_at ASC" : "SELECT id, project_id, session_id, observations, source_ids, generation, token_count, created_at, r_compression, c_norm FROM distillations WHERE project_id = ? AND session_id = ? AND archived = 0 ORDER BY created_at ASC";
|
|
31145
31199
|
const rows = db().query(sql).all(pid, sessionID);
|
|
31146
31200
|
return rows.map((r) => ({
|
|
@@ -31175,14 +31229,14 @@ function storeDistillation(input) {
|
|
|
31175
31229
|
);
|
|
31176
31230
|
return id;
|
|
31177
31231
|
}
|
|
31178
|
-
function gen0Count(
|
|
31179
|
-
const pid = ensureProject(
|
|
31232
|
+
function gen0Count(projectPath2, sessionID) {
|
|
31233
|
+
const pid = ensureProject(projectPath2);
|
|
31180
31234
|
return db().query(
|
|
31181
31235
|
"SELECT COUNT(*) as count FROM distillations WHERE project_id = ? AND session_id = ? AND generation = 0 AND archived = 0"
|
|
31182
31236
|
).get(pid, sessionID).count;
|
|
31183
31237
|
}
|
|
31184
|
-
function loadGen0(
|
|
31185
|
-
const pid = ensureProject(
|
|
31238
|
+
function loadGen0(projectPath2, sessionID) {
|
|
31239
|
+
const pid = ensureProject(projectPath2);
|
|
31186
31240
|
const rows = db().query(
|
|
31187
31241
|
"SELECT id, project_id, session_id, observations, source_ids, generation, token_count, created_at, r_compression, c_norm FROM distillations WHERE project_id = ? AND session_id = ? AND generation = 0 AND archived = 0 ORDER BY created_at ASC"
|
|
31188
31242
|
).all(pid, sessionID);
|
|
@@ -31198,8 +31252,8 @@ function archiveDistillations(ids) {
|
|
|
31198
31252
|
`UPDATE distillations SET archived = 1 WHERE id IN (${placeholders})`
|
|
31199
31253
|
).run(...ids);
|
|
31200
31254
|
}
|
|
31201
|
-
function resetOrphans(
|
|
31202
|
-
const pid = ensureProject(
|
|
31255
|
+
function resetOrphans(projectPath2, sessionID) {
|
|
31256
|
+
const pid = ensureProject(projectPath2);
|
|
31203
31257
|
const rows = db().query(
|
|
31204
31258
|
"SELECT source_ids FROM distillations WHERE project_id = ? AND session_id = ?"
|
|
31205
31259
|
).all(pid, sessionID);
|
|
@@ -31831,11 +31885,11 @@ function clearProviders() {
|
|
|
31831
31885
|
}
|
|
31832
31886
|
|
|
31833
31887
|
// src/import/detect.ts
|
|
31834
|
-
function detectAll(
|
|
31888
|
+
function detectAll(projectPath2) {
|
|
31835
31889
|
const results = [];
|
|
31836
31890
|
for (const provider of getProviders()) {
|
|
31837
31891
|
try {
|
|
31838
|
-
const sessions = provider.detect(
|
|
31892
|
+
const sessions = provider.detect(projectPath2);
|
|
31839
31893
|
if (sessions.length > 0) {
|
|
31840
31894
|
results.push({
|
|
31841
31895
|
agentName: provider.name,
|
|
@@ -31924,8 +31978,8 @@ async function extractKnowledge(input) {
|
|
|
31924
31978
|
}
|
|
31925
31979
|
|
|
31926
31980
|
// src/import/history.ts
|
|
31927
|
-
function isImported(
|
|
31928
|
-
const projectId2 = ensureProject(
|
|
31981
|
+
function isImported(projectPath2, agentName, sourceId, sourceHash) {
|
|
31982
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31929
31983
|
const row = db().query(
|
|
31930
31984
|
`SELECT * FROM import_history
|
|
31931
31985
|
WHERE project_id = ? AND agent_name = ? AND source_id = ?`
|
|
@@ -31934,8 +31988,8 @@ function isImported(projectPath, agentName, sourceId, sourceHash) {
|
|
|
31934
31988
|
if (row.source_hash !== sourceHash) return null;
|
|
31935
31989
|
return row;
|
|
31936
31990
|
}
|
|
31937
|
-
function recordImport(
|
|
31938
|
-
const projectId2 = ensureProject(
|
|
31991
|
+
function recordImport(projectPath2, agentName, sourceId, sourceHash, stats) {
|
|
31992
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31939
31993
|
db().query(
|
|
31940
31994
|
`INSERT OR REPLACE INTO import_history
|
|
31941
31995
|
(id, project_id, agent_name, source_id, source_hash, entries_created, entries_updated, imported_at)
|
|
@@ -31951,8 +32005,8 @@ function recordImport(projectPath, agentName, sourceId, sourceHash, stats) {
|
|
|
31951
32005
|
Date.now()
|
|
31952
32006
|
);
|
|
31953
32007
|
}
|
|
31954
|
-
function listImports(
|
|
31955
|
-
const projectId2 = ensureProject(
|
|
32008
|
+
function listImports(projectPath2) {
|
|
32009
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31956
32010
|
return db().query(
|
|
31957
32011
|
`SELECT * FROM import_history
|
|
31958
32012
|
WHERE project_id = ? AND source_id != '__declined__'
|
|
@@ -31970,8 +32024,8 @@ import { homedir as homedir2 } from "os";
|
|
|
31970
32024
|
var CLAUDE_DIR = join8(homedir2(), ".claude", "projects");
|
|
31971
32025
|
var MAX_TOOL_OUTPUT_CHARS = 500;
|
|
31972
32026
|
var DEFAULT_MAX_TOKENS = 12288;
|
|
31973
|
-
function manglePath(
|
|
31974
|
-
return
|
|
32027
|
+
function manglePath(projectPath2) {
|
|
32028
|
+
return projectPath2.replace(/\//g, "-");
|
|
31975
32029
|
}
|
|
31976
32030
|
function estimateTokens4(text4) {
|
|
31977
32031
|
return Math.ceil(text4.length / 3);
|
|
@@ -32085,8 +32139,8 @@ function getSessionMetadata(filePath) {
|
|
|
32085
32139
|
var claudeCodeProvider = {
|
|
32086
32140
|
name: "claude-code",
|
|
32087
32141
|
displayName: "Claude Code",
|
|
32088
|
-
detect(
|
|
32089
|
-
const mangled = manglePath(
|
|
32142
|
+
detect(projectPath2) {
|
|
32143
|
+
const mangled = manglePath(projectPath2);
|
|
32090
32144
|
const dir = join8(CLAUDE_DIR, mangled);
|
|
32091
32145
|
let entries;
|
|
32092
32146
|
try {
|
|
@@ -32284,7 +32338,7 @@ function getSessionMeta(filePath) {
|
|
|
32284
32338
|
var codexProvider = {
|
|
32285
32339
|
name: "codex",
|
|
32286
32340
|
displayName: "Codex",
|
|
32287
|
-
detect(
|
|
32341
|
+
detect(projectPath2) {
|
|
32288
32342
|
const sessions = [];
|
|
32289
32343
|
const allFiles = [
|
|
32290
32344
|
...findJsonlFiles(SESSIONS_DIR),
|
|
@@ -32293,7 +32347,7 @@ var codexProvider = {
|
|
|
32293
32347
|
for (const filePath of allFiles) {
|
|
32294
32348
|
const meta3 = getSessionMeta(filePath);
|
|
32295
32349
|
if (!meta3) continue;
|
|
32296
|
-
if (meta3.cwd !==
|
|
32350
|
+
if (meta3.cwd !== projectPath2) continue;
|
|
32297
32351
|
if (meta3.messageCount < 3) continue;
|
|
32298
32352
|
const ts = new Date(meta3.timestamp).getTime();
|
|
32299
32353
|
const estimatedTokens = Math.ceil(meta3.fileSize / 5);
|
|
@@ -32425,14 +32479,14 @@ function partsToConversationText(parts) {
|
|
|
32425
32479
|
var opencodeProvider = {
|
|
32426
32480
|
name: "opencode",
|
|
32427
32481
|
displayName: "OpenCode",
|
|
32428
|
-
detect(
|
|
32482
|
+
detect(projectPath2) {
|
|
32429
32483
|
const database = openDB();
|
|
32430
32484
|
if (!database) return [];
|
|
32431
32485
|
try {
|
|
32432
32486
|
if (!tableExists(database, "project") || !tableExists(database, "session") || !tableExists(database, "message")) {
|
|
32433
32487
|
return [];
|
|
32434
32488
|
}
|
|
32435
|
-
const project = database.query("SELECT id FROM project WHERE worktree = ?").get(
|
|
32489
|
+
const project = database.query("SELECT id FROM project WHERE worktree = ?").get(projectPath2);
|
|
32436
32490
|
if (!project) return [];
|
|
32437
32491
|
const sessions = database.query(
|
|
32438
32492
|
`SELECT s.id, s.title, s.time_created, s.time_updated,
|
|
@@ -32597,7 +32651,7 @@ function findGlobalStorageDirs() {
|
|
|
32597
32651
|
}
|
|
32598
32652
|
return dirs;
|
|
32599
32653
|
}
|
|
32600
|
-
function loadTaskHistory(storageDir,
|
|
32654
|
+
function loadTaskHistory(storageDir, projectPath2) {
|
|
32601
32655
|
const paths = [
|
|
32602
32656
|
join11(storageDir, "state", "taskHistory.json"),
|
|
32603
32657
|
join11(storageDir, "taskHistory.json")
|
|
@@ -32609,7 +32663,7 @@ function loadTaskHistory(storageDir, projectPath) {
|
|
|
32609
32663
|
const items = JSON.parse(raw);
|
|
32610
32664
|
if (!Array.isArray(items)) continue;
|
|
32611
32665
|
return items.filter(
|
|
32612
|
-
(item) => item.cwdOnTaskInitialization ===
|
|
32666
|
+
(item) => item.cwdOnTaskInitialization === projectPath2
|
|
32613
32667
|
);
|
|
32614
32668
|
} catch {
|
|
32615
32669
|
continue;
|
|
@@ -32662,11 +32716,11 @@ function messageToText(msg) {
|
|
|
32662
32716
|
var clineProvider = {
|
|
32663
32717
|
name: "cline",
|
|
32664
32718
|
displayName: "Cline",
|
|
32665
|
-
detect(
|
|
32719
|
+
detect(projectPath2) {
|
|
32666
32720
|
const sessions = [];
|
|
32667
32721
|
const storageDirs = findGlobalStorageDirs();
|
|
32668
32722
|
for (const storageDir of storageDirs) {
|
|
32669
|
-
const tasks = loadTaskHistory(storageDir,
|
|
32723
|
+
const tasks = loadTaskHistory(storageDir, projectPath2);
|
|
32670
32724
|
for (const task of tasks) {
|
|
32671
32725
|
const taskDir = join11(storageDir, "tasks", task.id);
|
|
32672
32726
|
if (!existsSync8(taskDir)) continue;
|
|
@@ -32814,11 +32868,11 @@ function historyItemToText(item) {
|
|
|
32814
32868
|
var continueProvider = {
|
|
32815
32869
|
name: "continue",
|
|
32816
32870
|
displayName: "Continue",
|
|
32817
|
-
detect(
|
|
32871
|
+
detect(projectPath2) {
|
|
32818
32872
|
const sessions = [];
|
|
32819
32873
|
const index2 = loadSessionIndex();
|
|
32820
32874
|
for (const meta3 of index2) {
|
|
32821
|
-
if (meta3.workspaceDirectory !==
|
|
32875
|
+
if (meta3.workspaceDirectory !== projectPath2) continue;
|
|
32822
32876
|
const session = loadSession(meta3.sessionId);
|
|
32823
32877
|
if (!session || !session.history || session.history.length < 3) continue;
|
|
32824
32878
|
const ts = new Date(meta3.dateCreated).getTime();
|
|
@@ -32850,7 +32904,7 @@ var continueProvider = {
|
|
|
32850
32904
|
if (existingIds.has(sessionId)) continue;
|
|
32851
32905
|
const session = loadSession(sessionId);
|
|
32852
32906
|
if (!session) continue;
|
|
32853
|
-
if (session.workspaceDirectory !==
|
|
32907
|
+
if (session.workspaceDirectory !== projectPath2) continue;
|
|
32854
32908
|
if (!session.history || session.history.length < 3) continue;
|
|
32855
32909
|
const dateStr = session.title ? truncate5(session.title, 60) : sessionId.slice(0, 8);
|
|
32856
32910
|
sessions.push({
|
|
@@ -32999,8 +33053,8 @@ function getSessionMeta2(filePath) {
|
|
|
32999
33053
|
var piProvider = {
|
|
33000
33054
|
name: "pi",
|
|
33001
33055
|
displayName: "Pi",
|
|
33002
|
-
detect(
|
|
33003
|
-
const encoded = encodeCwd(
|
|
33056
|
+
detect(projectPath2) {
|
|
33057
|
+
const encoded = encodeCwd(projectPath2);
|
|
33004
33058
|
const dir = join13(PI_DIR, encoded);
|
|
33005
33059
|
let entries;
|
|
33006
33060
|
try {
|
|
@@ -33138,8 +33192,8 @@ function parseAiderHistory(content3) {
|
|
|
33138
33192
|
var aiderProvider = {
|
|
33139
33193
|
name: "aider",
|
|
33140
33194
|
displayName: "Aider",
|
|
33141
|
-
detect(
|
|
33142
|
-
const filePath = join14(
|
|
33195
|
+
detect(projectPath2) {
|
|
33196
|
+
const filePath = join14(projectPath2, HISTORY_FILE);
|
|
33143
33197
|
if (!existsSync11(filePath)) return [];
|
|
33144
33198
|
let stat;
|
|
33145
33199
|
try {
|
|
@@ -33168,7 +33222,7 @@ var aiderProvider = {
|
|
|
33168
33222
|
}
|
|
33169
33223
|
];
|
|
33170
33224
|
},
|
|
33171
|
-
readChunks(
|
|
33225
|
+
readChunks(projectPath2, sessionIds, maxTokens = DEFAULT_MAX_TOKENS7) {
|
|
33172
33226
|
const chunks = [];
|
|
33173
33227
|
for (const filePath of sessionIds) {
|
|
33174
33228
|
let content3;
|
|
@@ -33463,7 +33517,7 @@ async function searchRecall(input) {
|
|
|
33463
33517
|
const {
|
|
33464
33518
|
query,
|
|
33465
33519
|
scope = "all",
|
|
33466
|
-
projectPath,
|
|
33520
|
+
projectPath: projectPath2,
|
|
33467
33521
|
sessionID,
|
|
33468
33522
|
knowledgeEnabled = true,
|
|
33469
33523
|
llm,
|
|
@@ -33490,7 +33544,7 @@ async function searchRecall(input) {
|
|
|
33490
33544
|
if (knowledgeEnabled && scope !== "session") {
|
|
33491
33545
|
try {
|
|
33492
33546
|
knowledgeResults.push(
|
|
33493
|
-
...searchScored3({ query: q, projectPath, limit })
|
|
33547
|
+
...searchScored3({ query: q, projectPath: projectPath2, limit })
|
|
33494
33548
|
);
|
|
33495
33549
|
} catch (err) {
|
|
33496
33550
|
error("recall: knowledge search failed:", err);
|
|
@@ -33501,7 +33555,7 @@ async function searchRecall(input) {
|
|
|
33501
33555
|
try {
|
|
33502
33556
|
distillationResults.push(
|
|
33503
33557
|
...searchDistillationsScored({
|
|
33504
|
-
projectPath,
|
|
33558
|
+
projectPath: projectPath2,
|
|
33505
33559
|
query: q,
|
|
33506
33560
|
sessionID: scope === "session" ? sessionID : void 0,
|
|
33507
33561
|
limit
|
|
@@ -33516,7 +33570,7 @@ async function searchRecall(input) {
|
|
|
33516
33570
|
try {
|
|
33517
33571
|
temporalResults.push(
|
|
33518
33572
|
...searchScored({
|
|
33519
|
-
projectPath,
|
|
33573
|
+
projectPath: projectPath2,
|
|
33520
33574
|
query: q,
|
|
33521
33575
|
sessionID: scope === "session" ? sessionID : void 0,
|
|
33522
33576
|
limit
|
|
@@ -33610,7 +33664,7 @@ async function searchRecall(input) {
|
|
|
33610
33664
|
}
|
|
33611
33665
|
}
|
|
33612
33666
|
if (scope !== "knowledge") {
|
|
33613
|
-
const pid = ensureProject(
|
|
33667
|
+
const pid = ensureProject(projectPath2);
|
|
33614
33668
|
const temporalVectorHits = vectorSearchTemporal(
|
|
33615
33669
|
queryVec,
|
|
33616
33670
|
pid,
|
|
@@ -33638,11 +33692,11 @@ async function searchRecall(input) {
|
|
|
33638
33692
|
info("recall: vector search failed:", err);
|
|
33639
33693
|
}
|
|
33640
33694
|
}
|
|
33641
|
-
if (scope !== "session" && hasLatDir(
|
|
33695
|
+
if (scope !== "session" && hasLatDir(projectPath2)) {
|
|
33642
33696
|
try {
|
|
33643
33697
|
const latResults = searchScored2({
|
|
33644
33698
|
query,
|
|
33645
|
-
projectPath,
|
|
33699
|
+
projectPath: projectPath2,
|
|
33646
33700
|
limit
|
|
33647
33701
|
});
|
|
33648
33702
|
if (latResults.length) {
|
|
@@ -33662,7 +33716,7 @@ async function searchRecall(input) {
|
|
|
33662
33716
|
try {
|
|
33663
33717
|
const crossProjectResults = searchScoredOtherProjects({
|
|
33664
33718
|
query,
|
|
33665
|
-
excludeProjectPath:
|
|
33719
|
+
excludeProjectPath: projectPath2,
|
|
33666
33720
|
limit
|
|
33667
33721
|
});
|
|
33668
33722
|
if (crossProjectResults.length) {
|
|
@@ -33852,7 +33906,6 @@ export {
|
|
|
33852
33906
|
clearGitRemoteCache,
|
|
33853
33907
|
clearLoreFileCache,
|
|
33854
33908
|
close,
|
|
33855
|
-
computeContextCap,
|
|
33856
33909
|
computeLayer0Cap,
|
|
33857
33910
|
config2 as config,
|
|
33858
33911
|
consolidationUser,
|
|
@@ -33868,6 +33921,7 @@ export {
|
|
|
33868
33921
|
distillationUser,
|
|
33869
33922
|
embedding_exports as embedding,
|
|
33870
33923
|
embedding_vendor_exports as embeddingVendor,
|
|
33924
|
+
enableHostedMode,
|
|
33871
33925
|
ensureProject,
|
|
33872
33926
|
exactTermMatchRank,
|
|
33873
33927
|
expandQuery,
|
|
@@ -33879,17 +33933,19 @@ export {
|
|
|
33879
33933
|
ftsQuery,
|
|
33880
33934
|
ftsQueryOr,
|
|
33881
33935
|
ftsQueryRelaxed,
|
|
33936
|
+
getCachePricing,
|
|
33882
33937
|
getGitRemote,
|
|
33883
33938
|
getInstanceId,
|
|
33884
33939
|
getKV,
|
|
33885
33940
|
getLastImportAt,
|
|
33941
|
+
getLastLayer,
|
|
33886
33942
|
getLastTransformEstimate,
|
|
33887
33943
|
getLastTransformedCount,
|
|
33888
33944
|
getLastTurnAt,
|
|
33889
33945
|
getLtmBudget,
|
|
33890
33946
|
getLtmTokens,
|
|
33891
|
-
getMaxContextTokens,
|
|
33892
33947
|
getMeta,
|
|
33948
|
+
getTier,
|
|
33893
33949
|
h,
|
|
33894
33950
|
importFromFile,
|
|
33895
33951
|
importLoreFile,
|
|
@@ -33897,6 +33953,7 @@ export {
|
|
|
33897
33953
|
inspectSessionState,
|
|
33898
33954
|
instruction_detect_exports as instructionDetect,
|
|
33899
33955
|
isFirstRun,
|
|
33956
|
+
isHostedMode,
|
|
33900
33957
|
isReasoningPart,
|
|
33901
33958
|
isTextPart,
|
|
33902
33959
|
isToolPart,
|
|
@@ -33922,10 +33979,13 @@ export {
|
|
|
33922
33979
|
pattern_extract_exports as patternExtract,
|
|
33923
33980
|
projectId,
|
|
33924
33981
|
projectName,
|
|
33982
|
+
projectPath,
|
|
33925
33983
|
recallById,
|
|
33926
33984
|
reciprocalRankFusion,
|
|
33985
|
+
recordCacheUsage,
|
|
33927
33986
|
recursiveUser,
|
|
33928
33987
|
renderMarkdown,
|
|
33988
|
+
resolveProjectByRemoteOrPath,
|
|
33929
33989
|
root2 as root,
|
|
33930
33990
|
runRecall,
|
|
33931
33991
|
sanitizeSurrogates,
|
|
@@ -33935,15 +33995,16 @@ export {
|
|
|
33935
33995
|
saveSessionTracking,
|
|
33936
33996
|
searchRecall,
|
|
33937
33997
|
serialize,
|
|
33998
|
+
setCachePricing,
|
|
33938
33999
|
setForceMinLayer,
|
|
33939
34000
|
setKV,
|
|
33940
34001
|
setLastImportAt,
|
|
33941
34002
|
setLastTurnAtForTest,
|
|
33942
34003
|
setLtmTokens,
|
|
33943
|
-
setMaxContextTokens,
|
|
33944
34004
|
setMaxLayer0Tokens,
|
|
33945
34005
|
setMeta,
|
|
33946
34006
|
setModelLimits,
|
|
34007
|
+
shouldCompress,
|
|
33947
34008
|
shouldImport,
|
|
33948
34009
|
shouldImportLoreFile,
|
|
33949
34010
|
strong2 as strong,
|
|
@@ -33953,7 +34014,6 @@ export {
|
|
|
33953
34014
|
transform2 as transform,
|
|
33954
34015
|
ul,
|
|
33955
34016
|
unescapeMarkdown,
|
|
33956
|
-
updateBustRate,
|
|
33957
34017
|
worker_model_exports as workerModel,
|
|
33958
34018
|
workerSessionIDs
|
|
33959
34019
|
};
|